// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.
// This file is copied and adapted from the following git repository -
// https://github.com/dotnet/corefx
// Commit ID: bdd0814360d4c3a58860919f292a306242f27da1
// Path: /src/System.Numerics.Tensors/src/System/Numerics/Tensors/ArrayTensorExtensions.cs
// Original license statement below -
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.
using System;
namespace Microsoft.ML.OnnxRuntime.Tensors
{
///
/// A static class that houses static DenseTensor extension methods
///
public static class ArrayTensorExtensions
{
///
/// Creates a copy of this single-dimensional array as a DenseTensor<T>
///
/// Type contained in the array to copy to the DenseTensor<T>.
/// The array to create a DenseTensor<T> from.
/// A 1-dimensional DenseTensor<T> with the same length and content as .
public static DenseTensor ToTensor(this T[] array)
{
// DenseTensor(Array, ...) is not efficient so do the copy here.
var dimensions = new int[] { array.Length };
T[] copy = new T[array.Length];
array.CopyTo(copy, 0);
return new DenseTensor(new Memory(copy), dimensions);
}
///
/// Creates a copy of this two-dimensional array as a DenseTensor<T>
///
/// Type contained in the array to copy to the DenseTensor<T>.
/// The array to create a DenseTensor<T> from.
/// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): row-major. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): column-major.
/// A 2-dimensional DenseTensor<T> with the same dimensions and content as .
public static DenseTensor ToTensor(this T[,] array, bool reverseStride = false)
{
if (reverseStride)
{
// we need logic from the DenseTensor ctor to be applied during copying
return new DenseTensor(array, reverseStride);
}
else
{
// it's more efficient to copy and flatten to 1D T[] and construct DenseTensor with Memory
T[] copy = new T[array.Length];
var dimensions = new int[] { array.GetLength(0), array.GetLength(1) };
long idx = 0;
foreach (var item in array)
{
copy[idx++] = item;
}
return new DenseTensor(new Memory(copy), dimensions);
}
}
///
/// Creates a copy of this three-dimensional array as a DenseTensor<T>
///
/// Type contained in the array to copy to the DenseTensor<T>.
/// The array to create a DenseTensor<T> from.
/// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor.
/// A 3-dimensional DenseTensor<T> with the same dimensions and content as .
public static DenseTensor ToTensor(this T[,,] array, bool reverseStride = false)
{
if (reverseStride)
{
// we need logic from the DenseTensor ctor to be applied during copying
return new DenseTensor(array, reverseStride);
}
else
{
// it's more efficient to copy and flatten to 1D T[] and construct DenseTensor with Memory
T[] copy = new T[array.Length];
var dimensions = new int[] { array.GetLength(0), array.GetLength(1), array.GetLength(2) };
long idx = 0;
foreach (var item in array)
{
copy[idx++] = item;
}
return new DenseTensor(new Memory(copy), dimensions);
}
}
///
/// Creates a copy of this four-dimensional array as a DenseTensor<T>
///
/// Type contained in the array to copy to the DenseTensor<T>.
/// The array to create a DenseTensor<T> from.
/// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor.
/// A 4-dimensional DenseTensor<T> with the same dimensions and content as .
public static DenseTensor ToTensor(this T[,,,] array, bool reverseStride = false)
{
if (reverseStride)
{
// we need logic from the DenseTensor ctor to be applied during copying
return new DenseTensor(array, reverseStride);
}
else
{
// it's more efficient to copy and flatten to 1D T[] and construct DenseTensor with Memory
T[] copy = new T[array.Length];
var dimensions = new int[] {
array.GetLength(0), array.GetLength(1), array.GetLength(2), array.GetLength(3) };
long idx = 0;
foreach (var item in array)
{
copy[idx++] = item;
}
return new DenseTensor(new Memory(copy), dimensions);
}
}
///
/// Creates a copy of this n-dimensional array as a DenseTensor<T>
///
/// Type contained in the array to copy to the DenseTensor<T>.
/// The array to create a DenseTensor<T> from.
/// False (default) to indicate that the first dimension is most major (farthest apart) and the last dimension is most minor (closest together): akin to row-major in a rank-2 tensor. True to indicate that the last dimension is most major (farthest apart) and the first dimension is most minor (closest together): akin to column-major in a rank-2 tensor.
/// A n-dimensional DenseTensor<T> with the same dimensions and content as .
public static DenseTensor ToTensor(this Array array, bool reverseStride = false)
{
return new DenseTensor(array, reverseStride);
}
}
}