Skip to content

Commit

Permalink
Vectorizes IndexOfMin/Max/Magnitude (#93469)
Browse files Browse the repository at this point in the history
* resolved merge conflicts

* net core full done

* minor code cleanup

* NetStandard and PR fixes.

* minor pr changes

* Fix IndexOfMaxMagnitudeOperator

* Fix IndexOfMaxMagnitudeOperator on netcore

* updates from PR comments

* netcore fixed

* net standard updated

* add reference assembly exclusions

* made naive approach better

* resolved PR comments

* minor comment changes

* minor formatting fixes

* added inlining

* fixes from PR comments

* comments from pr

* fixed spacing

---------

Co-authored-by: Eric StJohn <ericstj@microsoft.com>
  • Loading branch information
michaelgsharp and ericstj authored Oct 20, 2023
1 parent 2f90038 commit f3f0af8
Show file tree
Hide file tree
Showing 5 changed files with 1,226 additions and 129 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
M:System.Numerics.Tensors.TensorPrimitives.ConvertToHalf(System.ReadOnlySpan{System.Single},System.Span{System.Half})
M:System.Numerics.Tensors.TensorPrimitives.ConvertToSingle(System.ReadOnlySpan{System.Half},System.Span{System.Single})
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
Once this package has shipped a stable version, the following line
should be removed in order to re-enable validation. -->
<DisablePackageBaselineValidation>true</DisablePackageBaselineValidation>
<GenAPIExcludeApiList>ReferenceAssemblyExclusions.txt</GenAPIExcludeApiList>
</PropertyGroup>

<ItemGroup>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -316,39 +316,12 @@ public static void Exp(ReadOnlySpan<float> x, Span<float> destination) =>
/// </remarks>
public static int IndexOfMax(ReadOnlySpan<float> x)
{
int result = -1;

if (!x.IsEmpty)
if (x.IsEmpty)
{
result = 0;
float max = float.NegativeInfinity;

for (int i = 0; i < x.Length; i++)
{
float current = x[i];

if (current != max)
{
if (float.IsNaN(current))
{
return i;
}

if (max < current)
{
result = i;
max = current;
}
}
else if (IsNegative(max) && !IsNegative(current))
{
result = i;
max = current;
}
}
return -1;
}

return result;
return IndexOfMinMaxCore<IndexOfMaxOperator>(x);
}

/// <summary>Searches for the index of the single-precision floating-point number with the largest magnitude in the specified tensor.</summary>
Expand All @@ -367,43 +340,12 @@ public static int IndexOfMax(ReadOnlySpan<float> x)
/// </remarks>
public static int IndexOfMaxMagnitude(ReadOnlySpan<float> x)
{
int result = -1;

if (!x.IsEmpty)
if (x.IsEmpty)
{
result = 0;
float max = float.NegativeInfinity;
float maxMag = float.NegativeInfinity;

for (int i = 0; i < x.Length; i++)
{
float current = x[i];
float currentMag = Math.Abs(current);

if (currentMag != maxMag)
{
if (float.IsNaN(currentMag))
{
return i;
}

if (maxMag < currentMag)
{
result = i;
max = current;
maxMag = currentMag;
}
}
else if (IsNegative(max) && !IsNegative(current))
{
result = i;
max = current;
maxMag = currentMag;
}
}
return -1;
}

return result;
return IndexOfMinMaxCore<IndexOfMaxMagnitudeOperator>(x);
}

/// <summary>Searches for the index of the smallest single-precision floating-point number in the specified tensor.</summary>
Expand All @@ -421,39 +363,12 @@ public static int IndexOfMaxMagnitude(ReadOnlySpan<float> x)
/// </remarks>
public static int IndexOfMin(ReadOnlySpan<float> x)
{
int result = -1;

if (!x.IsEmpty)
if (x.IsEmpty)
{
result = 0;
float min = float.PositiveInfinity;

for (int i = 0; i < x.Length; i++)
{
float current = x[i];

if (current != min)
{
if (float.IsNaN(current))
{
return i;
}

if (current < min)
{
result = i;
min = current;
}
}
else if (IsNegative(current) && !IsNegative(min))
{
result = i;
min = current;
}
}
return -1;
}

return result;
return IndexOfMinMaxCore<IndexOfMinOperator>(x);
}

/// <summary>Searches for the index of the single-precision floating-point number with the smallest magnitude in the specified tensor.</summary>
Expand All @@ -472,43 +387,12 @@ public static int IndexOfMin(ReadOnlySpan<float> x)
/// </remarks>
public static int IndexOfMinMagnitude(ReadOnlySpan<float> x)
{
int result = -1;

if (!x.IsEmpty)
if (x.IsEmpty)
{
result = 0;
float min = float.PositiveInfinity;
float minMag = float.PositiveInfinity;

for (int i = 0; i < x.Length; i++)
{
float current = x[i];
float currentMag = Math.Abs(current);

if (currentMag != minMag)
{
if (float.IsNaN(currentMag))
{
return i;
}

if (currentMag < minMag)
{
result = i;
min = current;
minMag = currentMag;
}
}
else if (IsNegative(current) && !IsNegative(min))
{
result = i;
min = current;
minMag = currentMag;
}
}
return -1;
}

return result;
return IndexOfMinMaxCore<IndexOfMinMagnitudeOperator>(x);
}

/// <summary>Computes the element-wise natural (base <c>e</c>) logarithm of single-precision floating-point numbers in the specified tensor.</summary>
Expand Down
Loading

0 comments on commit f3f0af8

Please sign in to comment.