Skip to content

Commit cb48e75

Browse files
Vectorizes IndexOfMin/Max/Magnitude (dotnet#93469)
* 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 <[email protected]>
1 parent f86414a commit cb48e75

File tree

5 files changed

+1226
-129
lines changed

5 files changed

+1226
-129
lines changed
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
M:System.Numerics.Tensors.TensorPrimitives.ConvertToHalf(System.ReadOnlySpan{System.Single},System.Span{System.Half})
2+
M:System.Numerics.Tensors.TensorPrimitives.ConvertToSingle(System.ReadOnlySpan{System.Half},System.Span{System.Single})

src/libraries/System.Numerics.Tensors/src/System.Numerics.Tensors.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
Once this package has shipped a stable version, the following line
1010
should be removed in order to re-enable validation. -->
1111
<DisablePackageBaselineValidation>true</DisablePackageBaselineValidation>
12+
<GenAPIExcludeApiList>ReferenceAssemblyExclusions.txt</GenAPIExcludeApiList>
1213
</PropertyGroup>
1314

1415
<ItemGroup>

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.cs

Lines changed: 12 additions & 128 deletions
Original file line numberDiff line numberDiff line change
@@ -316,39 +316,12 @@ public static void Exp(ReadOnlySpan<float> x, Span<float> destination) =>
316316
/// </remarks>
317317
public static int IndexOfMax(ReadOnlySpan<float> x)
318318
{
319-
int result = -1;
320-
321-
if (!x.IsEmpty)
319+
if (x.IsEmpty)
322320
{
323-
result = 0;
324-
float max = float.NegativeInfinity;
325-
326-
for (int i = 0; i < x.Length; i++)
327-
{
328-
float current = x[i];
329-
330-
if (current != max)
331-
{
332-
if (float.IsNaN(current))
333-
{
334-
return i;
335-
}
336-
337-
if (max < current)
338-
{
339-
result = i;
340-
max = current;
341-
}
342-
}
343-
else if (IsNegative(max) && !IsNegative(current))
344-
{
345-
result = i;
346-
max = current;
347-
}
348-
}
321+
return -1;
349322
}
350323

351-
return result;
324+
return IndexOfMinMaxCore<IndexOfMaxOperator>(x);
352325
}
353326

354327
/// <summary>Searches for the index of the single-precision floating-point number with the largest magnitude in the specified tensor.</summary>
@@ -367,43 +340,12 @@ public static int IndexOfMax(ReadOnlySpan<float> x)
367340
/// </remarks>
368341
public static int IndexOfMaxMagnitude(ReadOnlySpan<float> x)
369342
{
370-
int result = -1;
371-
372-
if (!x.IsEmpty)
343+
if (x.IsEmpty)
373344
{
374-
result = 0;
375-
float max = float.NegativeInfinity;
376-
float maxMag = float.NegativeInfinity;
377-
378-
for (int i = 0; i < x.Length; i++)
379-
{
380-
float current = x[i];
381-
float currentMag = Math.Abs(current);
382-
383-
if (currentMag != maxMag)
384-
{
385-
if (float.IsNaN(currentMag))
386-
{
387-
return i;
388-
}
389-
390-
if (maxMag < currentMag)
391-
{
392-
result = i;
393-
max = current;
394-
maxMag = currentMag;
395-
}
396-
}
397-
else if (IsNegative(max) && !IsNegative(current))
398-
{
399-
result = i;
400-
max = current;
401-
maxMag = currentMag;
402-
}
403-
}
345+
return -1;
404346
}
405347

406-
return result;
348+
return IndexOfMinMaxCore<IndexOfMaxMagnitudeOperator>(x);
407349
}
408350

409351
/// <summary>Searches for the index of the smallest single-precision floating-point number in the specified tensor.</summary>
@@ -421,39 +363,12 @@ public static int IndexOfMaxMagnitude(ReadOnlySpan<float> x)
421363
/// </remarks>
422364
public static int IndexOfMin(ReadOnlySpan<float> x)
423365
{
424-
int result = -1;
425-
426-
if (!x.IsEmpty)
366+
if (x.IsEmpty)
427367
{
428-
result = 0;
429-
float min = float.PositiveInfinity;
430-
431-
for (int i = 0; i < x.Length; i++)
432-
{
433-
float current = x[i];
434-
435-
if (current != min)
436-
{
437-
if (float.IsNaN(current))
438-
{
439-
return i;
440-
}
441-
442-
if (current < min)
443-
{
444-
result = i;
445-
min = current;
446-
}
447-
}
448-
else if (IsNegative(current) && !IsNegative(min))
449-
{
450-
result = i;
451-
min = current;
452-
}
453-
}
368+
return -1;
454369
}
455370

456-
return result;
371+
return IndexOfMinMaxCore<IndexOfMinOperator>(x);
457372
}
458373

459374
/// <summary>Searches for the index of the single-precision floating-point number with the smallest magnitude in the specified tensor.</summary>
@@ -472,43 +387,12 @@ public static int IndexOfMin(ReadOnlySpan<float> x)
472387
/// </remarks>
473388
public static int IndexOfMinMagnitude(ReadOnlySpan<float> x)
474389
{
475-
int result = -1;
476-
477-
if (!x.IsEmpty)
390+
if (x.IsEmpty)
478391
{
479-
result = 0;
480-
float min = float.PositiveInfinity;
481-
float minMag = float.PositiveInfinity;
482-
483-
for (int i = 0; i < x.Length; i++)
484-
{
485-
float current = x[i];
486-
float currentMag = Math.Abs(current);
487-
488-
if (currentMag != minMag)
489-
{
490-
if (float.IsNaN(currentMag))
491-
{
492-
return i;
493-
}
494-
495-
if (currentMag < minMag)
496-
{
497-
result = i;
498-
min = current;
499-
minMag = currentMag;
500-
}
501-
}
502-
else if (IsNegative(current) && !IsNegative(min))
503-
{
504-
result = i;
505-
min = current;
506-
minMag = currentMag;
507-
}
508-
}
392+
return -1;
509393
}
510394

511-
return result;
395+
return IndexOfMinMaxCore<IndexOfMinMagnitudeOperator>(x);
512396
}
513397

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

0 commit comments

Comments
 (0)