forked from microsoft/onnxruntime
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Copy System.Numerics.Tensors sources from dotnet/corefx into onnxrunt…
…ime (microsoft#1605) Copy System.Numerics.Tensors sources from dotnet/corefx into onnxruntime
- Loading branch information
Showing
26 changed files
with
22,257 additions
and
84 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
csharp/src/Microsoft.ML.OnnxRuntime/Tensors/ArrayTensorExtensions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// 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 | ||
{ | ||
public static class ArrayTensorExtensions | ||
{ | ||
/// <summary> | ||
/// Creates a copy of this single-dimensional array as a DenseTensor<T> | ||
/// </summary> | ||
/// <typeparam name="T">Type contained in the array to copy to the DenseTensor<T>.</typeparam> | ||
/// <param name="array">The array to create a DenseTensor<T> from.</param> | ||
/// <returns>A 1-dimensional DenseTensor<T> with the same length and content as <paramref name="array"/>.</returns> | ||
public static DenseTensor<T> ToTensor<T>(this T[] array) | ||
{ | ||
return new DenseTensor<T>(array); | ||
} | ||
|
||
/// <summary> | ||
/// Creates a copy of this two-dimensional array as a DenseTensor<T> | ||
/// </summary> | ||
/// <typeparam name="T">Type contained in the array to copy to the DenseTensor<T>.</typeparam> | ||
/// <param name="array">The array to create a DenseTensor<T> from.</param> | ||
/// <param name="reverseStride">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.</param> | ||
/// <returns>A 2-dimensional DenseTensor<T> with the same dimensions and content as <paramref name="array"/>.</returns> | ||
public static DenseTensor<T> ToTensor<T>(this T[,] array, bool reverseStride = false) | ||
{ | ||
return new DenseTensor<T>(array, reverseStride); | ||
} | ||
|
||
/// <summary> | ||
/// Creates a copy of this three-dimensional array as a DenseTensor<T> | ||
/// </summary> | ||
/// <typeparam name="T">Type contained in the array to copy to the DenseTensor<T>.</typeparam> | ||
/// <param name="array">The array to create a DenseTensor<T> from.</param> | ||
/// <param name="reverseStride">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.</param> | ||
/// <returns>A 3-dimensional DenseTensor<T> with the same dimensions and content as <paramref name="array"/>.</returns> | ||
public static DenseTensor<T> ToTensor<T>(this T[,,] array, bool reverseStride = false) | ||
{ | ||
return new DenseTensor<T>(array, reverseStride); | ||
} | ||
|
||
/// <summary> | ||
/// Creates a copy of this n-dimensional array as a DenseTensor<T> | ||
/// </summary> | ||
/// <typeparam name="T">Type contained in the array to copy to the DenseTensor<T>.</typeparam> | ||
/// <param name="array">The array to create a DenseTensor<T> from.</param> | ||
/// <param name="reverseStride">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.</param> | ||
/// <returns>A n-dimensional DenseTensor<T> with the same dimensions and content as <paramref name="array"/>.</returns> | ||
public static DenseTensor<T> ToTensor<T>(this Array array, bool reverseStride = false) | ||
{ | ||
return new DenseTensor<T>(array, reverseStride); | ||
} | ||
} | ||
} |
227 changes: 227 additions & 0 deletions
227
csharp/src/Microsoft.ML.OnnxRuntime/Tensors/ArrayUtilities.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,227 @@ | ||
// 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/ArrayUtilities.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.Diagnostics; | ||
using System; | ||
|
||
namespace Microsoft.ML.OnnxRuntime.Tensors | ||
{ | ||
internal static class ArrayUtilities | ||
{ | ||
public const int StackallocMax = 16; | ||
|
||
public static long GetProduct(ReadOnlySpan<int> dimensions, int startIndex = 0) | ||
{ | ||
if (dimensions.Length == 0) | ||
{ | ||
return 0; | ||
} | ||
|
||
long product = 1; | ||
for (int i = startIndex; i < dimensions.Length; i++) | ||
{ | ||
if (dimensions[i] < 0) | ||
{ | ||
throw new ArgumentOutOfRangeException($"{nameof(dimensions)}[{i}]"); | ||
} | ||
|
||
// we use a long which should be much larger than is ever used here, | ||
// but still force checked | ||
checked | ||
{ | ||
product *= dimensions[i]; | ||
} | ||
} | ||
|
||
return product; | ||
} | ||
|
||
public static bool IsAscending(ReadOnlySpan<int> values) | ||
{ | ||
for (int i = 1; i < values.Length; i++) | ||
{ | ||
if (values[i] < values[i - 1]) | ||
{ | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
public static bool IsDescending(ReadOnlySpan<int> values) | ||
{ | ||
for (int i = 1; i < values.Length; i++) | ||
{ | ||
if (values[i] > values[i - 1]) | ||
{ | ||
return false; | ||
} | ||
} | ||
|
||
return true; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the set of strides that can be used to calculate the offset of n-dimensions in a 1-dimensional layout | ||
/// </summary> | ||
/// <param name="dimensions"></param> | ||
/// <param name="reverseStride"></param> | ||
/// <returns></returns> | ||
public static int[] GetStrides(ReadOnlySpan<int> dimensions, bool reverseStride = false) | ||
{ | ||
int[] strides = new int[dimensions.Length]; | ||
|
||
int stride = 1; | ||
if (reverseStride) | ||
{ | ||
for (int i = 0; i < strides.Length; i++) | ||
{ | ||
strides[i] = stride; | ||
stride *= dimensions[i]; | ||
} | ||
} | ||
else | ||
{ | ||
for (int i = strides.Length - 1; i >= 0; i--) | ||
{ | ||
strides[i] = stride; | ||
stride *= dimensions[i]; | ||
} | ||
} | ||
|
||
return strides; | ||
} | ||
|
||
public static void SplitStrides(int[] strides, int[] splitAxes, int[] newStrides, int stridesOffset, int[] splitStrides, int splitStridesOffset) | ||
{ | ||
int newStrideIndex = 0; | ||
for (int i = 0; i < strides.Length; i++) | ||
{ | ||
int stride = strides[i]; | ||
bool isSplit = false; | ||
for (int j = 0; j < splitAxes.Length; j++) | ||
{ | ||
if (splitAxes[j] == i) | ||
{ | ||
splitStrides[splitStridesOffset + j] = stride; | ||
isSplit = true; | ||
break; | ||
} | ||
} | ||
|
||
if (!isSplit) | ||
{ | ||
newStrides[stridesOffset + newStrideIndex++] = stride; | ||
} | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Calculates the 1-d index for n-d indices in layout specified by strides. | ||
/// </summary> | ||
/// <param name="strides"></param> | ||
/// <param name="indices"></param> | ||
/// <param name="startFromDimension"></param> | ||
/// <returns></returns> | ||
public static int GetIndex(int[] strides, ReadOnlySpan<int> indices, int startFromDimension = 0) | ||
{ | ||
Debug.Assert(strides.Length == indices.Length); | ||
|
||
int index = 0; | ||
for (int i = startFromDimension; i < indices.Length; i++) | ||
{ | ||
index += strides[i] * indices[i]; | ||
} | ||
|
||
return index; | ||
} | ||
|
||
/// <summary> | ||
/// Calculates the n-d indices from the 1-d index in a layout specificed by strides | ||
/// </summary> | ||
/// <param name="strides"></param> | ||
/// <param name="reverseStride"></param> | ||
/// <param name="index"></param> | ||
/// <param name="indices"></param> | ||
/// <param name="startFromDimension"></param> | ||
public static void GetIndices(ReadOnlySpan<int> strides, bool reverseStride, int index, int[] indices, int startFromDimension = 0) | ||
{ | ||
Debug.Assert(reverseStride ? IsAscending(strides) : IsDescending(strides), "Index decomposition requires ordered strides"); | ||
Debug.Assert(strides.Length == indices.Length); | ||
|
||
int remainder = index; | ||
for (int i = startFromDimension; i < strides.Length; i++) | ||
{ | ||
// reverse the index for reverseStride so that we divide by largest stride first | ||
var nIndex = reverseStride ? strides.Length - 1 - i : i; | ||
|
||
var stride = strides[nIndex]; | ||
indices[nIndex] = remainder / stride; | ||
remainder %= stride; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Calculates the n-d indices from the 1-d index in a layout specificed by strides | ||
/// </summary> | ||
/// <param name="strides"></param> | ||
/// <param name="reverseStride"></param> | ||
/// <param name="index"></param> | ||
/// <param name="indices"></param> | ||
/// <param name="startFromDimension"></param> | ||
public static void GetIndices(ReadOnlySpan<int> strides, bool reverseStride, int index, Span<int> indices, int startFromDimension = 0) | ||
{ | ||
Debug.Assert(reverseStride ? IsAscending(strides) : IsDescending(strides), "Index decomposition requires ordered strides"); | ||
Debug.Assert(strides.Length == indices.Length); | ||
|
||
int remainder = index; | ||
for (int i = startFromDimension; i < strides.Length; i++) | ||
{ | ||
// reverse the index for reverseStride so that we divide by largest stride first | ||
var nIndex = reverseStride ? strides.Length - 1 - i : i; | ||
|
||
var stride = strides[nIndex]; | ||
indices[nIndex] = remainder / stride; | ||
remainder %= stride; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Takes an 1-d index over n-d sourceStrides and recalculates it assuming same n-d coordinates over a different n-d strides | ||
/// </summary> | ||
public static int TransformIndexByStrides(int index, int[] sourceStrides, bool sourceReverseStride, int[] transformStrides) | ||
{ | ||
Debug.Assert(index >= 0); | ||
Debug.Assert(sourceReverseStride ? IsAscending(sourceStrides) : IsDescending(sourceStrides), "Index decomposition requires ordered strides"); | ||
Debug.Assert(sourceStrides.Length == transformStrides.Length); | ||
|
||
int transformIndex = 0; | ||
int remainder = index; | ||
|
||
for (int i = 0; i < sourceStrides.Length; i++) | ||
{ | ||
// reverse the index for reverseStride so that we divide by largest stride first | ||
var nIndex = sourceReverseStride ? sourceStrides.Length - 1 - i: i; | ||
|
||
var sourceStride = sourceStrides[nIndex]; | ||
var transformStride = transformStrides[nIndex]; | ||
|
||
transformIndex += transformStride * (remainder / sourceStride); | ||
remainder %= sourceStride; | ||
} | ||
|
||
return transformIndex; | ||
} | ||
} | ||
} |
Oops, something went wrong.