Array features are always views of a pre-allocated array or buffer. As such, creating an array feature will never allocate tensor memory.
Creating the Feature
The array feature can be created from any numeric array or buffer representation:
From a Managed Array
///<summary>/// Create an array feature.///</summary>///<paramname="data">Feature data.</param>///<paramname="shape">Feature shape.</param>MLArrayFeature(T[]data,int[]shape=null);
An array feature can be created from a managed array. In rare cases where it is useful to fully specify the feature type, there is an overload which accepts the array type:
///<summary>/// Create an array feature.///</summary>///<paramname="data">Feature data.</param>///<paramname="type">Feature type.</param>MLArrayFeature(T[]data,MLArrayTypetype);
From a Native Array
The array feature provides variants of the managed array constructors where the data argument is a NativeArray<T>. This can be useful for working with certain performance-critical Unity API's like Burst:
Similarly, in cases where it is necessary to explicitly specify the array feature type, there is a corresponding overload:
From a Native Buffer
The array feature provides variants of the managed array constructors where the data argument is a typed native buffer. These can be useful for making predictions on arrays from native code or external libraries like OpenCV:
There is a corresponding constructor for specifying the feature type:
The data buffer MUST remain valid for the lifetime of the array feature.
From an Edge Feature
An array feature can be created from an MLEdgeFeature. This is useful for making predictions with an MLEdgeModel .
The feature MUST have a numeric data type.
From a Cloud Feature
The array feature can be created from an MLCloudFeature. This is useful for making predictions with an MLCloudModel .
The feature MUST have a numeric data type.
Inspecting the Feature
The array feature provides information about its shape.
Feature Type
Refer to the Inspecting the Feature section of the MLFeature class for more information.
The feature shape is a convenience property which provides the shape from the feature type.
The shape can be null if the feature was created with no shape.
Element Count
The element count is a convenience property which provides the element count from the feature type.
The elementCount will be zero when the feature does not have a shape.
Accessing Feature Data
The array feature provides accessors for reading and writing feature data.
Multi-Indexing
The array feature provides support for multi-indexing. This is a common pattern for working with tensors in machine learning:
Multiple indexing requires the array feature to have a valid shape, but linear indexing (i.e. indexing with a single number) does not.
The array feature does not perform bounds checking for performance, so make sure to always index correctly.
The array feature also supports linear indexing, in which case it accesses the elements of the feature assuming a flat shape:
Copying
The array feature can copy it data into another array feature.
This method copies destination.elementCount * sizeof(U) bytes into the destination feature.
This method does not respect any permutations that have been applied to the array feature.
To copy data into a managed array, native buffer, or other destination, first create an MLArrayFeature to wrap the destination, then use the CopyTo method.
Converting to Array
The array feature can copy its data into an array and return the array. The destination array type can also be specified:
This method does not respect any permutations that have been applied to the array feature.
Pinning
The array feature supports pinning, allowing direct access to the underlying feature data while bypassing all checks. This can be used in unsafe context with the fixed statement:
Pinning is mostly used for bulk read or write operations. Use multi-indexing for individual element access.
Do not use pinning unless you know exactly what you are doing. Mistakes are almost guaranteed to result in segmentation faults and hard crashes.
Viewing Operations
The array feature supports viewing operations. Each of these operations do not allocate any memory; they simply return a shallow feature that has the proper shape.
Permute
The array feature's dimensions can be permuted, allowing different dimensions to be swapped (like transposing):
View
The array feature supports creating a view of the feature data with a different shape:
The element count of the view shape must match the element count of the feature.
/// <summary>
/// Create an array feature from an Edge ML feature.
/// Note that this does NOT take ownership of the edge feature.
/// As such the edge feature must be explicitly disposed by the client.
/// </summary>
/// <param name="feature">Edge ML feature. This MUST be an array feature.</param>
MLArrayFeature (MLEdgeFeature feature);
/// <summary>
/// Create an array feature from a cloud feature.
/// </summary>
/// <param name="feature">Cloud feature.</param>
MLArrayFeature (MLCloudFeature feature);
/// <summary>
/// Feature element count.
/// </summary>
int elementCount { get; }
/// <summary>
/// Get or set a value at a specified multi-index.
/// </summary>
/// <param name="idx">Multi-index.</param>
T this [params int[] idx] { get; set; }
// With an array feature
var feature = new MLArrayFeature<float>(...);
// You can index across multiple dimensions
var logit = feature[0,12,29,1];
// You can also index linearly, disregarding the shape
var logit = feature[392];
/// <summary>
/// Copy the array feature into another feature.
/// This copies `destination.elementCount * sizeof(U)` elements.
/// </summary>
/// <param name="destination">Feature to copy data into.</destination>
void CopyTo<U> (MLArrayFeature<U> destination) where U : unmanaged;
/// <summary>
/// Convert the array feature to a flattened array.
/// </summary>
/// <returns>Result array.</returns>
T[] ToArray ();
/// <summary>
/// Convert the array feature to a flattened array.
/// This method always returns a copy of the array feature data.
/// </summary>
/// <returns>Result array.</returns>
U[] ToArray<U> () where U : unmanaged;
/// <summary>
/// Pin the array feature.
/// </summary>
ref T GetPinnableReference ();
// Given an array feature
MLArrayFeature<float> feature = ...;
// Manually set the 12th element in the feature by pinning
fixed (float* featureData = feature)
featureData[11] = 420.69;
/// <summary>
/// Permute the dimensions of this array feature.
/// This operation is a generalization of the transpose operation.
/// </summary>
/// <param name="dims">Permuted dimensions.</param>
/// <returns>Array feature with permuted dimensions.</returns>
MLArrayFeature<T> Permute (params int[] dims);
// Create an array feature with shape (3,5)
var feature = new MLArrayFeature<float>(..., new [] { 3, 5 });
Debug.Log(feature.shape); // (3,5)
// Transpose it by permuting dimensions
var transposedFeature = feature.Permute(1, 0);
Debug.Log(transposedFeature.shape); // (5,3)
/// <summary>
/// Create a view of this array feature with a different shape.
/// The element count of the new shape MUST match that of the feature.
/// </summary>
/// <param name="shape">New shape.</param>
/// <returns>Array feature with new shape.</returns>
MLArrayFeature<T> View (params int[] shape);
// Create an array feature
var feature = new MLArrayFeature<float>(..., new [] { 5, 30 });
Debug.Log(feature.shape); // (5,30)
// View the feature with a different shape
var viewedFeature = feature.View(5, 10, 3);
Debug.Log(viewedFeature.shape); // (5,10,3)
/// <summary>
/// Create an edge feature that is ready for prediction with edge models.
/// </summary>
/// <param name="type">Feature type used to create the edge feature.</param>
/// <returns>Edge feature.</returns>
MLEdgeFeature IMLEdgeFeature.Create (MLFeatureType type);
/// <summary>
/// Create a cloud feature that is ready for prediction with cloud models.
/// </summary>
/// <param name="type">Feature type used to create the cloud feature.</param>
/// <returns>Cloud feature.</returns>
MLCloudFeature IMLCloudFeature.Create (MLFeatureType type)