Skip to content

Commit

Permalink
Cleanup and improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
aalmada committed Mar 24, 2024
1 parent e617bc6 commit 5ab252c
Show file tree
Hide file tree
Showing 44 changed files with 1,629 additions and 1,224 deletions.
10 changes: 8 additions & 2 deletions docs/articles/Extending-the-library.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,10 +253,12 @@ public interface IAggregationOperator<T, TResult>
=> Throw.NotSupportedException<TResult>();

static abstract TResult Invoke(TResult x, TResult y);

static abstract TResult Invoke(TResult x, ref readonly Vector<TResult> y);
}
```

Each operator must provide a property returning the seed value, initializing the aggregation process. Additionally, operators must implement the required `Invoke` methods by the `IBinaryOperator<T1, T2, TResult>` interface, along with an extra `Invoke` method that aggregates the final result.
Each operator must provide a property returning the seed value, initializing the aggregation process. Additionally, operators must implement the required `Invoke` methods by the `IBinaryOperator<T1, T2, TResult>` interface, along with two extra `Invoke` methods that aggregates the final result. On the last `Invoke` it's guaranteed that the parameters will not contain `NaN`.

For example, consider an operation calculating the sum of all elements in the source. It employs the following aggregation operator:

Expand All @@ -275,10 +277,14 @@ readonly struct SumOperator<T>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector<T> Invoke(ref readonly Vector<T> x, ref readonly Vector<T> y)
=> x + y;

[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T Invoke(T x, ref readonly Vector<T> y)
=> x + Vector.Sum(y);
}
```

This operator adheres to the `IAggregationOperator<T, T>` interface. The generic type `T` is constrained to `struct`, `IAdditiveIdentity<T, T>`, and `IAdditionOperators<T, T, T>`, indicating that only value types with both the additive identity and the `+` operator implemented are suitable. The `Seed` initializes the sum using the additive identity. The `Invoke()` methods straightforwardly perform the addition operation for either a single `T` value or a `Vector<T>` of values.
This operator adheres to the `IAggregationOperator<T, T>` interface. The generic type `T` is constrained to `struct`, `IAdditiveIdentity<T, T>`, and `IAdditionOperators<T, T, T>`, indicating that only value types with both the additive identity and the `+` operator implemented are suitable. The `Seed` initializes the sum using the additive identity. The two first `Invoke()` methods straightforwardly perform the addition operation for either a single `T` value or a `Vector<T>` of values. The last `Invoke`, sums the aggregated value to the sum of the elements in the aggregated vector.

The `Sum()` operation can be utilized as follows:

Expand Down
2 changes: 1 addition & 1 deletion src/NetFabric.Numerics.Tensors.Benchmarks/AddBenchmarks.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class AddBenchmarks
float[]? sourceFloat, otherFloat, resultFloat;
double[]? sourceDouble, otherDouble, resultDouble;

[Params(5, 100)]
[Params(100)]
public int Count { get; set; }

[GlobalSetup]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class AddMultiplyBenchmarks
float[]? sourceFloat, otherFloat, anotherFloat, resultFloat;
double[]? sourceDouble, otherDouble, anotherDouble, resultDouble;

[Params(5, 100)]
[Params(100)]
public int Count { get; set; }

[GlobalSetup]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class AddValueBenchmarks
float[]? sourceFloat, resultFloat;
double[]? sourceDouble, resultDouble;

[Params(5, 100)]
[Params(100)]
public int Count { get; set; }

[GlobalSetup]
Expand Down
65 changes: 58 additions & 7 deletions src/NetFabric.Numerics.Tensors.Benchmarks/Baseline.cs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,19 @@ public static void AddMultiply<T>(ReadOnlySpan<T> source, ReadOnlySpan<T> other,
}

public static T Sum<T>(ReadOnlySpan<T> source)
where T : struct, INumber<T>, IAdditionOperators<T, T, T>
{
var sum = T.AdditiveIdentity;
foreach (var item in source)
{
if (T.IsNaN(item))
return item;
sum += item;
}
return sum;
}

public static T SumNumber<T>(ReadOnlySpan<T> source)
where T : struct, IAdditiveIdentity<T, T>, IAdditionOperators<T, T, T>
{
var sum = T.AdditiveIdentity;
Expand Down Expand Up @@ -123,7 +136,18 @@ public static T Min<T>(ReadOnlySpan<T> source)
if (T.IsNaN(item))
return item;

if (item < min)
min = T.Min(min, item);
}
return min;
}

public static T MinNumber<T>(ReadOnlySpan<T> source)
where T : struct, IComparisonOperators<T, T, bool>, IMinMaxValue<T>
{
var min = T.MaxValue;
foreach (var item in source)
{
if(min > item)
min = item;
}
return min;
Expand All @@ -140,7 +164,25 @@ public static int IndexOfMin<T>(ReadOnlySpan<T> source)
if (T.IsNaN(item))
return index;

if (item < min)
var value = T.Min(min, item);
if (value.Equals(item))
{
min = item;
minIndex = index;
}
}
return minIndex;
}

public static int IndexOfMinNumber<T>(ReadOnlySpan<T> source)
where T : struct, IComparisonOperators<T, T, bool>, IMinMaxValue<T>
{
var min = T.MaxValue;
var minIndex = -1;
for (var index = 0; index < source.Length; index++)
{
var item = source[index];
if (min > item)
{
min = item;
minIndex = index;
Expand All @@ -159,12 +201,21 @@ public static (T Min, T Max) MinMax<T>(ReadOnlySpan<T> source)
if (T.IsNaN(item))
return (item, item);

if (item < min)
min = item;

if (item > max)
max = item;
min = T.Min(min, item);
max = T.Max(max, item);
}
return (min, max);
}

public static int IndexOfGreaterThan<T>(ReadOnlySpan<T> source, T value)
where T : struct, INumber<T>, IMinMaxValue<T>
{
for (var index = 0; index < source.Length; index++)
{
if (source[index] > value)
return index;
}
return -1;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class CeilingBenchmarks
float[]? sourceFloat, resultFloat;
double[]? sourceDouble, resultDouble;

[Params(5, 100)]
[Params(100)]
public int Count { get; set; }

[GlobalSetup]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public class DegreesToRadiansBenchmarks
float[]? sourceFloat, resultFloat;
double[]? sourceDouble, resultDouble;

[Params(5, 100)]
[Params(100)]
public int Count { get; set; }

[GlobalSetup]
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Configs;
using System.Numerics.Tensors;

namespace NetFabric.Numerics.Tensors.Benchmarks;

[Config(typeof(VectorizationConfig))]
[GroupBenchmarksBy(BenchmarkLogicalGroupRule.ByCategory)]
[CategoriesColumn]
public class IndexOfGreaterThanBenchmarks
{
short[]? arrayShort;
int[]? arrayInt;
long[]? arrayLong;
Half[]? arrayHalf;
float[]? arrayFloat;
double[]? arrayDouble;

[Params(100)]
public int Count { get; set; }

[GlobalSetup]
public void GlobalSetup()
{
arrayShort = new short[Count];
arrayInt = new int[Count];
arrayLong = new long[Count];
arrayHalf = new Half[Count];
arrayFloat = new float[Count];
arrayDouble = new double[Count];

var random = new Random(42);
for(var index = 0; index < Count; index++)
{
var value = random.Next(100) - 50;
arrayShort[index] = (short)value;
arrayInt[index] = value;
arrayLong[index] = value;
arrayHalf[index] = (Half)value;
arrayFloat[index] = value;
arrayDouble[index] = value;
}
}

[BenchmarkCategory("Short")]
[Benchmark(Baseline = true)]
public int Baseline_Short()
=> Baseline.IndexOfGreaterThan<short>(arrayShort!, 0);

// [BenchmarkCategory("Short")]
// [Benchmark]
// public int System_Short()
// => TensorPrimitives.IndexOfGreaterThan<short>(arrayShort!, 0);

[BenchmarkCategory("Short")]
[Benchmark]
public int NetFabric_Short()
=> TensorOperations.IndexOfGreaterThan<short>(arrayShort!, 0);

[BenchmarkCategory("Int")]
[Benchmark(Baseline = true)]
public int Baseline_Int()
=> Baseline.IndexOfGreaterThan<int>(arrayInt!, 0);

// [BenchmarkCategory("Int")]
// [Benchmark]
// public int System_Int()
// => TensorPrimitives.IndexOfGreaterThan<int>(arrayInt!, 0);

[BenchmarkCategory("Int")]
[Benchmark]
public int NetFabric_Int()
=> TensorOperations.IndexOfGreaterThan(arrayInt!, 0);

[BenchmarkCategory("Long")]
[Benchmark(Baseline = true)]
public int Baseline_Long()
=> Baseline.IndexOfGreaterThan<long>(arrayLong!, 0);

// [BenchmarkCategory("Long")]
// [Benchmark]
// public int System_Long()
// => TensorPrimitives.IndexOfGreaterThan<long>(arrayLong!, 0);

[BenchmarkCategory("Long")]
[Benchmark]
public int NetFabric_Long()
=> TensorOperations.IndexOfGreaterThan(arrayLong!, 0L);

[BenchmarkCategory("Half")]
[Benchmark(Baseline = true)]
public int Baseline_Half()
=> Baseline.IndexOfGreaterThan<Half>(arrayHalf!, (Half)0);

// [BenchmarkCategory("Half")]
// [Benchmark]
// public int System_Half()
// => TensorPrimitives.IndexOfGreaterThan<Half>(arrayHalf!, (Half)0);

[BenchmarkCategory("Half")]
[Benchmark]
public int NetFabric_Half()
=> TensorOperations.IndexOfGreaterThan<Half>(arrayHalf!, (Half)0);

[BenchmarkCategory("Float")]
[Benchmark(Baseline = true)]
public int Baseline_Float()
=> Baseline.IndexOfGreaterThan<float>(arrayFloat!, 0.0f);

// [BenchmarkCategory("Float")]
// [Benchmark]
// public int System_Float()
// => TensorPrimitives.IndexOfGreaterThan(arrayFloat!, 0.0f);

[BenchmarkCategory("Float")]
[Benchmark]
public int NetFabric_Float()
=> TensorOperations.IndexOfGreaterThan<float>(arrayFloat!, 0.0f);

[BenchmarkCategory("Double")]
[Benchmark(Baseline = true)]
public int Baseline_Double()
=> Baseline.IndexOfGreaterThan<double>(arrayDouble!, 0.0);

// [BenchmarkCategory("Double")]
// [Benchmark]
// public int System_Double()
// => TensorPrimitives.IndexOfGreaterThan<double>(arrayDouble!);

[BenchmarkCategory("Double")]
[Benchmark]
public int NetFabric_Double()
=> TensorOperations.IndexOfGreaterThan(arrayDouble!, 0.0);
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class IndexOfMinAggregateBenchmarks
float[]? arrayFloat;
double[]? arrayDouble;

[Params(5, 100)]
[Params(100)]
public int Count { get; set; }

[GlobalSetup]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class MinAggregateBenchmarks
float[]? arrayFloat;
double[]? arrayDouble;

[Params(5, 100)]
[Params(100)]
public int Count { get; set; }

[GlobalSetup]
Expand Down Expand Up @@ -48,11 +48,6 @@ public void GlobalSetup()
public short Baseline_Short()
=> Baseline.Min<short>(arrayShort!);

[BenchmarkCategory("Short")]
[Benchmark]
public short LINQ_Short()
=> Enumerable.Aggregate(arrayShort!, (short)0, (sum, item) => (short)(sum + item));

[BenchmarkCategory("Short")]
[Benchmark]
public short System_Short()
Expand All @@ -68,11 +63,6 @@ public short NetFabric_Short()
public int Baseline_Int()
=> Baseline.Min<int>(arrayInt!);

[BenchmarkCategory("Int")]
[Benchmark]
public int LINQ_Int()
=> Enumerable.Min(arrayInt!);

[BenchmarkCategory("Int")]
[Benchmark]
public int System_Int()
Expand All @@ -88,11 +78,6 @@ public int NetFabric_Int()
public long Baseline_Long()
=> Baseline.Min<long>(arrayLong!);

[BenchmarkCategory("Long")]
[Benchmark]
public long LINQ_Long()
=> Enumerable.Min(arrayLong!);

[BenchmarkCategory("Long")]
[Benchmark]
public long System_Long()
Expand All @@ -108,11 +93,6 @@ public long NetFabric_Long()
public Half Baseline_Half()
=> Baseline.Min<Half>(arrayHalf!);

[BenchmarkCategory("Half")]
[Benchmark]
public Half LINQ_Half()
=> Enumerable.Aggregate(arrayHalf!, (Half)0, (sum, item) => (Half)(sum + item));

[BenchmarkCategory("Half")]
[Benchmark]
public Half System_Half()
Expand All @@ -128,11 +108,6 @@ public Half NetFabric_Half()
public float Baseline_Float()
=> Baseline.Min<float>(arrayFloat!);

[BenchmarkCategory("Float")]
[Benchmark]
public float LINQ_Float()
=> Enumerable.Min(arrayFloat!);

[BenchmarkCategory("Float")]
[Benchmark]
public float System_Float()
Expand All @@ -148,11 +123,6 @@ public float NetFabric_Float()
public double Baseline_Double()
=> Baseline.Min<double>(arrayDouble!);

[BenchmarkCategory("Double")]
[Benchmark]
public double LINQ_Double()
=> Enumerable.Min(arrayDouble!);

[BenchmarkCategory("Double")]
[Benchmark]
public double System_Double()
Expand Down
Loading

0 comments on commit 5ab252c

Please sign in to comment.