Skip to content

Commit

Permalink
Copy System.Numerics.Tensors sources from dotnet/corefx into onnxrunt…
Browse files Browse the repository at this point in the history
…ime (microsoft#1605)

 Copy System.Numerics.Tensors sources from dotnet/corefx into onnxruntime
  • Loading branch information
shahasad authored Aug 16, 2019
1 parent 0044be6 commit c9eb13a
Show file tree
Hide file tree
Showing 26 changed files with 22,257 additions and 84 deletions.
10 changes: 5 additions & 5 deletions csharp/OnnxRuntime.CSharp.proj
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,19 @@ CMake creates a target to this project
<Message Importance="High" Text="Restoring NuGet packages for CSharp projects..." />
<MSBuild Projects="src\Microsoft.ML.OnnxRuntime\Microsoft.ML.OnnxRuntime.csproj"
Targets="Restore"
Properties="Platform=AnyCPU;RestoreConfigFile=$(MSBuildThisFileDirectory)\NuGet.CSharp.config;MSBuildWarningsAsMessages=NU1503;RestoreIgnoreFailedSource=true"
Properties="Platform=AnyCPU;RestorePackagesPath=$(MSBuildThisFileDirectory)\packages;RestoreConfigFile=$(MSBuildThisFileDirectory)\NuGet.CSharp.config;MSBuildWarningsAsMessages=NU1503;RestoreIgnoreFailedSource=true"
/>
<MSBuild Projects="sample\Microsoft.ML.OnnxRuntime.InferenceSample\Microsoft.ML.OnnxRuntime.InferenceSample.csproj"
Targets="Restore"
Properties="Platform=AnyCPU;RestoreConfigFile=$(MSBuildThisFileDirectory)\NuGet.CSharp.config;MSBuildWarningsAsMessages=NU1503;RestoreIgnoreFailedSource=true"
Properties="Platform=AnyCPU;RestorePackagesPath=$(MSBuildThisFileDirectory)\packages;RestoreConfigFile=$(MSBuildThisFileDirectory)\NuGet.CSharp.config;MSBuildWarningsAsMessages=NU1503;RestoreIgnoreFailedSource=true"
/>
<MSBuild Projects="test\Microsoft.ML.OnnxRuntime.Tests\Microsoft.ML.OnnxRuntime.Tests.csproj"
Targets="Restore"
Properties="RestoreConfigFile=$(MSBuildThisFileDirectory)\NuGet.CSharp.config;MSBuildWarningsAsMessages=NU1503;RestoreIgnoreFailedSource=true"
Properties="RestorePackagesPath=$(MSBuildThisFileDirectory)\packages;RestoreConfigFile=$(MSBuildThisFileDirectory)\NuGet.CSharp.config;MSBuildWarningsAsMessages=NU1503;RestoreIgnoreFailedSource=true"
/>
<MSBuild Projects="tools\Microsoft.ML.OnnxRuntime.PerfTool\Microsoft.ML.OnnxRuntime.PerfTool.csproj"
Targets="Restore"
Properties="Platform=AnyCPU;RestoreConfigFile=$(MSBuildThisFileDirectory)\NuGet.CSharp.config;MSBuildWarningsAsMessages=NU1503;RestoreIgnoreFailedSource=true"
Properties="Platform=AnyCPU;RestorePackagesPath=$(MSBuildThisFileDirectory)\packages;RestoreConfigFile=$(MSBuildThisFileDirectory)\NuGet.CSharp.config;MSBuildWarningsAsMessages=NU1503;RestoreIgnoreFailedSource=true"
/>
</Target>

Expand All @@ -54,7 +54,7 @@ CMake creates a target to this project
/>
</Target>

<Target Name="RunTest" AfterTargets="Build">
<Target Name="RunTest">
<Message Importance="High" Text="Running CSharp tests..." />
<Exec Command="$(DotNetExe) test test\Microsoft.ML.OnnxRuntime.Tests\Microsoft.ML.OnnxRuntime.Tests.csproj -c $(Configuration) --no-build" ConsoleToMSBuild="true">
<Output TaskParameter="ConsoleOutput" PropertyName="OutputOfExec" />
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
using System.Text;
using System.IO;
using Microsoft.ML.OnnxRuntime;
using System.Numerics.Tensors;
using Microsoft.ML.OnnxRuntime.Tensors;

namespace CSharpUsage
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

using System;
using System.Collections.Generic;
using System.Numerics.Tensors;
using Microsoft.ML.OnnxRuntime.Tensors;
using System.Runtime.InteropServices;


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<Platforms>AnyCPU;x86</Platforms>
<LangVersion>7.2</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<SignAssembly>true</SignAssembly>
<DelaySign>false</DelaySign>
<AssemblyOriginatorKeyFile>OnnxRuntime.snk</AssemblyOriginatorKeyFile>
<AssemblyOriginatorKeyFile>..\..\OnnxRuntime.snk</AssemblyOriginatorKeyFile>

<!--internal build related properties-->
<OnnxRuntimeCsharpRoot>..\..</OnnxRuntimeCsharpRoot>
Expand All @@ -24,12 +25,11 @@
<PackageLicenseFile>LICENSE.txt</PackageLicenseFile>
<PackageIconUrl>https://go.microsoft.com/fwlink/?linkid=2049168</PackageIconUrl>
<PackageReleaseNotes>
Release Def:
Release Def:
Branch: $(BUILD_SOURCEBRANCH)
Commit: $(BUILD_SOURCEVERSION)
Build: https://aiinfra.visualstudio.com/Lotus/_build/results?buildId=$(BUILD_BUILDID)
</PackageReleaseNotes>

<!-- sourcelink flags -->
<PublishRepositoryUrl>true</PublishRepositoryUrl>
<!-- Optional: Embed source files that are not tracked by the source control manager in the PDB -->
Expand All @@ -39,6 +39,7 @@

<!--TODO: this works for single platform only. Need separate packaging scripts for multi-target packaging -->
<!--TODO: Find a way to bundle the native symbol files properly -->

<ItemGroup>
<None Include="$(OnnxRuntimeCsharpRoot)\..\include\onnxruntime\core\session\onnxruntime_*.h"
PackagePath="\build\native\include"
Expand Down Expand Up @@ -147,8 +148,8 @@
</Target>

<ItemGroup>
<PackageReference Include="System.Numerics.Tensors" Version="0.1.0" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.0-beta-63127-02" PrivateAssets="All"/>
<PackageReference Include="System.Memory" Version="4.5.3" />
</ItemGroup>

</Project>
Expand Down
2 changes: 1 addition & 1 deletion csharp/src/Microsoft.ML.OnnxRuntime/NamedOnnxValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Numerics.Tensors;
using Microsoft.ML.OnnxRuntime.Tensors;
using System.Buffers;
using System.Collections;
using System.Diagnostics;
Expand Down
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&lt;T&gt;
/// </summary>
/// <typeparam name="T">Type contained in the array to copy to the DenseTensor&lt;T&gt;.</typeparam>
/// <param name="array">The array to create a DenseTensor&lt;T&gt; from.</param>
/// <returns>A 1-dimensional DenseTensor&lt;T&gt; 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&lt;T&gt;
/// </summary>
/// <typeparam name="T">Type contained in the array to copy to the DenseTensor&lt;T&gt;.</typeparam>
/// <param name="array">The array to create a DenseTensor&lt;T&gt; 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&lt;T&gt; 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&lt;T&gt;
/// </summary>
/// <typeparam name="T">Type contained in the array to copy to the DenseTensor&lt;T&gt;.</typeparam>
/// <param name="array">The array to create a DenseTensor&lt;T&gt; 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&lt;T&gt; 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&lt;T&gt;
/// </summary>
/// <typeparam name="T">Type contained in the array to copy to the DenseTensor&lt;T&gt;.</typeparam>
/// <param name="array">The array to create a DenseTensor&lt;T&gt; 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&lt;T&gt; 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 csharp/src/Microsoft.ML.OnnxRuntime/Tensors/ArrayUtilities.cs
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;
}
}
}
Loading

0 comments on commit c9eb13a

Please sign in to comment.