using System.Diagnostics; using System; namespace Microsoft.ML.OnnxRuntime.Tensors { /// /// This class contains utilities for useful calculations with shape. /// public static class ShapeUtils { /// /// Returns a number of elements in the tensor from the given shape /// /// /// size /// public static long GetSizeForShape(ReadOnlySpan shape) { long product = 1; foreach (var dim in shape) { if (dim < 0) { throw new ArgumentOutOfRangeException($"Shape must not have negative elements: {dim}"); } checked { product *= dim; } } return product; } /// /// Gets the set of strides that can be used to calculate the offset of n-dimensions in a 1-dimensional layout /// /// /// an array of strides public static long[] GetStrides(ReadOnlySpan dimensions) { long[] strides = new long[dimensions.Length]; if (dimensions.Length == 0) { return strides; } long stride = 1; for (int i = strides.Length - 1; i >= 0; i--) { strides[i] = stride; if (dimensions[i] < 0) { throw new ArgumentException($"Dimension {i} is negative"); } stride *= dimensions[i]; } return strides; } /// /// Calculates the 1-d index for n-d indices in layout specified by strides. /// /// pre-calculated strides /// Indices. Must have the same length as strides /// /// A 1-d index into the tensor buffer public static long GetIndex(ReadOnlySpan strides, ReadOnlySpan indices, int startFromDimension = 0) { Debug.Assert(strides.Length == indices.Length); long index = 0; for (int i = startFromDimension; i < indices.Length; i++) { index += strides[i] * indices[i]; } return index; } } }