<MPSHandle>(3)

NAME
<MPSHandle>

SYNOPSIS

#include <MPSNNGraphNodes.h>

Detailed Description

MPSNNGraphNodes.h MetalPerformanceShaders

Created by Ian Ollmann on 10/19/16.

Copyright:
    Copyright © 2016 Apple. All rights reserved.

This header describes building blocks to prepare a graph of MPS images, kernels and state objects. You should prepare your graph by creating a MPSNNImageNode for each of the graph input textures. These are then used as inputs to MPSNNFilterNode subclasses. These in turn produce more image nodes as results, which can be linked to more MPSNNFilterNodes as inputs. When the graph representation is complete, make a MPSNNGraph object to interpret and optimize the graph. The MPSNNGraph may be used to encode the entire graph on a MTLCommandBuffer.

Objects presented here are generally light weight. They do not have a MTLDevice reference, and so can not create MTLResource objects. In the few cases when data is expected to be large (e.g. convolution weights), the nodes are designed to defer allocation of storage, preferring to leave them on disk or network or other persistent storage to hold the data until it is actually needed to initialize a MPSKernel object. Not until the MPSNNGraph is constructed does the heavy lifting begin. MPSNNGraphs in contrast can be extremely heavy. A large graph may use most of the memory available to your system! Nearly all of this is due to convolution weights. Construct your <MPSCNNConvolutionDataSource> to only load data when it is needed.

MPS resource identification Most of the time, there is only one image and one or fewer states needed as input to a graph, so the order of the images and states passed to [MPSNNGraph encodeToCommandBuffer:sourceImages:] or [MPSNNGraph encodeToCommandBuffer:sourceImages:sourceStates:intermediateImages:destinationStates:] is clear. There is only one order. However, sometimes graphs have more than one input image or state. What order should they appear in the NSArray passed to these methods?

Each MPSNNImageNode or MPSNNStateNode can be tagged with a MPSHandle. MPSNNGraph keeps track of these. You can request that the MPSNNGraph return them to you in an array in the same order as needed to encode the MPSNNGraph, using MPSNNGraph.sourceImageHandles and MPSNNGraph.sourceStateHandles.

Example:

@interface MyHandle : NSObject <MPSHandle>
    // Add a method for my use to get the image needed based on the handle to it.
    // This isn't part of the MPSHandle protocol, but we need it for MyEncodeGraph
    // below. Since it is my code calling my object, we can add whatever we want like this.
    -(MPSImage*__nonnull) image;    // return the MPSImage corresponding to the handle
    // required by MPSHandle protocol
    -(NSString * __nullable) label;
    // MPSHandle implies NSSecureCoding too
    +(BOOL) supportsSecureCoding;
    - (void)encodeWithCoder:(NSCoder * __nonnull )aCoder;
    - (nullable instancetype)initWithCoder:(NSCoder * __nonnull )aDecoder; // NS_DESIGNATED_INITIALIZER
@end
// Encode a graph to cmdBuf using handles for images
// Here we assume that the MPSNNImageNodes that are graph inputs (not produced
// by the graph) are tagged with a unique instance of MyHandle that can be used
// to get the appropriate image for that node.
static void MyEncodeGraph( MPSNNGraph * graph, id <MTLCommandBuffer> cmdBuf )
{
    @autoreleasepool{
        // prepare an array of source images, using the handles
        NSArray<MyHandle*> * handles = graph.sourceImageHandles;
        unsigned long count = handles.count;
        NSMutableArray<MPSImage*> * __nonnull images = [NSMutableArray arrayWithCapacity: count];
        for( unsigned long i = 0; i < count; i++ )
            images[i] = handles[i].image;
        // encode the graph using the array
        [ graph encodeToCommandBuffer: cmdBuf
                         sourceImages: images ];
    }
}

Author

Generated automatically by Doxygen for MetalPerformanceShaders.framework from the source code.