Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 8 additions & 3 deletions src/benchmarks/micro/MicroBenchmarks.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,10 @@
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
<PackageReference Include="System.Threading.Tasks.Extensions" Version="4.5.4" />
</ItemGroup>
<ItemGroup Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(_TargetFrameworkVersionWithoutV)' &gt;= '8.0'">
<!-- we want both net8.0 and net9.0 targets to use the 9.0.0 version of the NuGet package (since this is where the generic math APIs were first added) -->
<PackageReference Include="System.Numerics.Tensors" Version="$(SystemThreadingChannelsPackageVersion)" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\harness\BenchmarkDotNet.Extensions\BenchmarkDotNet.Extensions.csproj" />
Expand Down Expand Up @@ -212,9 +216,10 @@
</ItemGroup>

<ItemGroup Condition=" '$(TargetFrameworkIdentifier)' == '.NETFramework' Or ('$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(_TargetFrameworkVersionWithoutV)' &lt; '8.0')">
<Compile Remove="libraries\System.Buffers\SearchValuesByteTests.cs" />
<Compile Remove="libraries\System.Buffers\SearchValuesCharTests.cs" />
<Compile Remove="libraries\System.Text.Encoding\Perf.Ascii.cs" />
<Compile Remove="libraries\System.Buffers\SearchValuesByteTests.cs" />
<Compile Remove="libraries\System.Buffers\SearchValuesCharTests.cs" />
<Compile Remove="libraries\System.Text.Encoding\Perf.Ascii.cs" />
<Compile Remove="libraries\System.Numerics.Tensors\*.cs" />
</ItemGroup>

<!-- This is not removing things from older Net versions, it is removing from newer Net versions -->
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// 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 BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Extensions;
using MicroBenchmarks;

namespace System.Numerics.Tensors.Tests
{
[BenchmarkCategory(Categories.Libraries, Categories.SIMD, Categories.JIT)]
[GenericTypeArguments(typeof(int))]
public class Perf_BinaryIntegerTensorPrimitives<T>
where T : unmanaged, IBinaryInteger<T>
{
[Params(128, 6 * 512 + 7)]
public int BufferLength;

private T[] _source1;
private T[] _destination;

[GlobalSetup]
public void Init()
{
_source1 = ValuesGenerator.Array<T>(BufferLength, seed: 42);
_destination = new T[BufferLength];
}

#region Unary Operations
[Benchmark]
public void LeadingZeroCount() => TensorPrimitives.LeadingZeroCount<T>(_source1, _destination);

[Benchmark]
public void OnesComplement() => TensorPrimitives.OnesComplement<T>(_source1, _destination);

[Benchmark]
public void PopCount() => TensorPrimitives.PopCount<T>(_source1, _destination);

[Benchmark]
public void ShiftLeft() => TensorPrimitives.ShiftLeft<T>(_source1, shiftAmount: 3, _destination);

[Benchmark]
public void TrailingZeroCount() => TensorPrimitives.TrailingZeroCount<T>(_source1, _destination);
#endregion
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
// 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 BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Extensions;
using MicroBenchmarks;
using System.Linq;

namespace System.Numerics.Tensors.Tests
{
[BenchmarkCategory(Categories.Libraries, Categories.SIMD, Categories.JIT)]
[GenericTypeArguments(typeof(float))]
[GenericTypeArguments(typeof(double))]
public class Perf_FloatingPointTensorPrimitives<T>
where T : unmanaged, IFloatingPointIeee754<T>
{
[Params(128, 6 * 512 + 7)]
public int BufferLength;

private T[] _source1;
private T[] _source2;
private T[] _source3;
private T _scalar1;
private T[] _ones;
private T[] _destination;

[GlobalSetup]
public void Init()
{
_source1 = ValuesGenerator.Array<T>(BufferLength, seed: 42);
_source2 = ValuesGenerator.Array<T>(BufferLength, seed: 43);
_source3 = ValuesGenerator.Array<T>(BufferLength, seed: 44);
_scalar1 = ValuesGenerator.Value<T>(seed: 45);
_ones = Enumerable.Repeat(T.One, BufferLength).ToArray();
_destination = new T[BufferLength];
}

#region Unary Operations
[Benchmark]
public void AtanPi() => TensorPrimitives.AtanPi<T>(_source1, _destination);

[Benchmark]
public void Exp() => TensorPrimitives.Exp<T>(_source1, _destination);

[Benchmark]
public void Log() => TensorPrimitives.Log<T>(_source1, _destination);

[Benchmark]
public void Round() => TensorPrimitives.Round<T>(_source1, _destination);

[Benchmark]
public void Sin() => TensorPrimitives.Sin<T>(_source1, _destination);

[Benchmark]
public void Sinh() => TensorPrimitives.Sinh<T>(_source1, _destination);

[Benchmark]
public void Sigmoid() => TensorPrimitives.Sigmoid<T>(_source1, _destination);

[Benchmark]
public void Sqrt() => TensorPrimitives.Sqrt<T>(_source1, _destination);

[Benchmark]
public void Truncate() => TensorPrimitives.Truncate<T>(_source1, _destination);
#endregion

#region Binary/Ternary Operations
[Benchmark]
public void FusedMultiplyAdd_Vectors() => TensorPrimitives.FusedMultiplyAdd<T>(_source1, _source2, _source3, _destination);

[Benchmark]
public void FusedMultiplyAdd_ScalarAddend() => TensorPrimitives.FusedMultiplyAdd(_source1, _scalar1, _source2, _destination);

[Benchmark]
public void FusedMultiplyAdd_ScalarMultiplier() => TensorPrimitives.FusedMultiplyAdd(_source1, _source2, _scalar1, _destination);

[Benchmark]
public void Ieee754Remainder_Vector() => TensorPrimitives.Ieee754Remainder<T>(_source1, _source2, _destination);

[Benchmark]
public void Ieee754Remainder_ScalarDividend() => TensorPrimitives.Ieee754Remainder(_scalar1, _source1, _destination);

[Benchmark]
public void Ieee754Remainder_ScalarDivisor() => TensorPrimitives.Ieee754Remainder(_source1, _scalar1, _destination);

[Benchmark]
public void Pow_Vectors() => TensorPrimitives.Pow<T>(_source1, _ones, _destination);

[Benchmark]
public void Pow_ScalarBase() => TensorPrimitives.Pow(_scalar1, _ones, _destination);

[Benchmark]
public void Pow_ScalarExponent() => TensorPrimitives.Pow(_source1, T.One, _destination);
#endregion

#region Reducers
[Benchmark]
public T CosineSimilarity() => TensorPrimitives.CosineSimilarity<T>(_source1, _source2);

[Benchmark]
public T Distance() => TensorPrimitives.Distance<T>(_source1, _source2);
#endregion
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// 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 BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Extensions;
using MicroBenchmarks;
using System.Linq;

namespace System.Numerics.Tensors.Tests
{
[BenchmarkCategory(Categories.Libraries, Categories.SIMD, Categories.JIT)]
[GenericTypeArguments(typeof(int))]
[GenericTypeArguments(typeof(float))]
[GenericTypeArguments(typeof(double))]
public class Perf_NumberTensorPrimitives<T>
where T : INumber<T>, IBitwiseOperators<T, T, T>
{
[Params(128, 6 * 512 + 7)]
public int BufferLength;

private T[] _source1;
private T[] _source2;
private T[] _source3;
private T _scalar1;
private T[] _ones;
private T[] _destination;

[GlobalSetup]
public void Init()
{
_source1 = ValuesGenerator.Array<T>(BufferLength, seed: 42);
_source2 = ValuesGenerator.Array<T>(BufferLength, seed: 43);
_source3 = ValuesGenerator.Array<T>(BufferLength, seed: 44);
_scalar1 = ValuesGenerator.Value<T>(seed: 45);
_ones = Enumerable.Repeat(T.One, BufferLength).ToArray();
_destination = new T[BufferLength];
}

#region Unary Operations
[Benchmark]
public void Abs() => TensorPrimitives.Abs<T>(_source1, _destination);

[Benchmark]
public void Negate() => TensorPrimitives.Abs<T>(_source1, _destination);
#endregion

#region Binary/Ternary Operations
[Benchmark]
public void Add_Vector() => TensorPrimitives.Add<T>(_source1, _source2, _destination);

[Benchmark]
public void Add_Scalar() => TensorPrimitives.Add(_source1, _scalar1, _destination);

[Benchmark]
public void AddMultiply_Vectors() => TensorPrimitives.AddMultiply<T>(_source1, _source2, _source3, _destination);

[Benchmark]
public void AddMultiply_ScalarAddend() => TensorPrimitives.AddMultiply(_source1, _scalar1, _source2, _destination);

[Benchmark]
public void AddMultiply_ScalarMultiplier() => TensorPrimitives.AddMultiply(_source1, _source2, _scalar1, _destination);

[Benchmark]
public void BitwiseAnd_Vector() => TensorPrimitives.BitwiseAnd<T>(_source1, _source2, _destination);

[Benchmark]
public void BitwiseAnd_Scalar() => TensorPrimitives.BitwiseAnd(_source1, _scalar1, _destination);

[Benchmark]
public void Divide_Vector() => TensorPrimitives.Divide<T>(_source1, _ones, _destination);

[Benchmark]
public void Divide_Scalar() => TensorPrimitives.Divide(_source1, T.One, _destination);

[Benchmark]
public void Max_Vector() => TensorPrimitives.Max<T>(_source1, _source2, _destination);

[Benchmark]
public void Max_Scalar() => TensorPrimitives.Max(_source1, _scalar1, _destination);

[Benchmark]
public void MaxMagnitude_Vector() => TensorPrimitives.MaxMagnitude<T>(_source1, _source2, _destination);

[Benchmark]
public void MaxMagnitude_Scalar() => TensorPrimitives.MaxMagnitude(_source1, _scalar1, _destination);
#endregion

#region Reducers
[Benchmark]
public T Max() => TensorPrimitives.Max<T>(_source1);

[Benchmark]
public T SumOfMagnitudes() => TensorPrimitives.SumOfMagnitudes<T>(_ones);

[Benchmark]
public T SumOfSquares() => TensorPrimitives.SumOfSquares<T>(_ones);

[Benchmark]
public int IndexOfMax() => TensorPrimitives.IndexOfMax<T>(_source1);
#endregion
}
}
10 changes: 8 additions & 2 deletions src/harness/BenchmarkDotNet.Extensions/ValuesGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,11 +67,11 @@ public static T[] ArrayOfUniqueValues<T>(int count)
/// For byte and sbyte values are built from Random.NextBytes, for other types GenerateValue is used
/// to generate a random value in the appropriate range
/// </summary>
public static T[] Array<T>(int count)
public static T[] Array<T>(int count, int? seed = null)
{
var result = new T[count];

var random = new Random(Seed);
var random = new Random(seed ?? Seed);

if (typeof(T) == typeof(byte) || typeof(T) == typeof(sbyte))
{
Expand All @@ -88,6 +88,12 @@ public static T[] Array<T>(int count)
return result;
}

public static T Value<T>(int? seed = null)
{
var random = new Random(seed ?? Seed);
return GenerateValue<T>(random);
}

public static readonly byte[] s_encodingMap = {
65, 66, 67, 68, 69, 70, 71, 72, //A..H
73, 74, 75, 76, 77, 78, 79, 80, //I..P
Expand Down