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;
}
}
}