Skip to content
Draft
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
124 changes: 124 additions & 0 deletions Benchmarks/BenchExp2.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
namespace Benchmarks;

/// <summary>Benchmarks for simd_math.Exp2 — float and double, all SIMD widths.</summary>
[DisassemblyDiagnoser]
public class BenchExp2
{
// 1 024 random-ish floats in [-60, 60]
private static readonly float[] _f32 = GenerateF32();
private static readonly double[] _f64 = GenerateF64();

private static float[] GenerateF32()
{
const int n = 1024;
var a = new float[n];
for (var i = 0; i < n; i++)
a[i] = (i - n / 2) * (120f / n); // spans [-60, 60]
return a;
}

private static double[] GenerateF64()
{
const int n = 1024;
var a = new double[n];
for (var i = 0; i < n; i++)
a[i] = (i - n / 2) * (1200.0 / n); // spans [-600, 600]
return a;
}

// ── float ──────────────────────────────────────────────────────────────

[Benchmark(Description = "Exp2 float×2 (Vector64)")]
public float Exp2_f32x2()
{
var acc = Vector64<float>.Zero;
for (var i = 0; i < _f32.Length - 1; i += 2)
{
var v = Vector64.Create(_f32[i], _f32[i + 1]);
acc += simd_math.Exp2(v);
}
return acc.GetElement(0);
}

[Benchmark(Description = "Exp2 float×4 (Vector128)", Baseline = true)]
public float Exp2_f32x4()
{
var acc = Vector128<float>.Zero;
for (var i = 0; i < _f32.Length - 3; i += 4)
{
var v = Vector128.Create(_f32[i], _f32[i + 1], _f32[i + 2], _f32[i + 3]);
acc += simd_math.Exp2(v);
}
return acc.GetElement(0);
}

[Benchmark(Description = "Exp2 float×8 (Vector256)")]
public float Exp2_f32x8()
{
var acc = Vector256<float>.Zero;
for (var i = 0; i < _f32.Length - 7; i += 8)
{
var v = Vector256.Create(
_f32[i], _f32[i + 1], _f32[i + 2], _f32[i + 3],
_f32[i + 4], _f32[i + 5], _f32[i + 6], _f32[i + 7]);
acc += simd_math.Exp2(v);
}
return acc.GetElement(0);
}

[Benchmark(Description = "Exp2 float×16 (Vector512)")]
public float Exp2_f32x16()
{
var acc = Vector512<float>.Zero;
for (var i = 0; i < _f32.Length - 15; i += 16)
{
var v = Vector512.Create(
_f32[i], _f32[i + 1], _f32[i + 2], _f32[i + 3],
_f32[i + 4], _f32[i + 5], _f32[i + 6], _f32[i + 7],
_f32[i + 8], _f32[i + 9], _f32[i + 10], _f32[i + 11],
_f32[i + 12], _f32[i + 13], _f32[i + 14], _f32[i + 15]);
acc += simd_math.Exp2(v);
}
return acc.GetElement(0);
}

// ── double ─────────────────────────────────────────────────────────────

[Benchmark(Description = "Exp2 double×2 (Vector128)")]
public double Exp2_f64x2()
{
var acc = Vector128<double>.Zero;
for (var i = 0; i < _f64.Length - 1; i += 2)
{
var v = Vector128.Create(_f64[i], _f64[i + 1]);
acc += simd_math.Exp2(v);
}
return acc.GetElement(0);
}

[Benchmark(Description = "Exp2 double×4 (Vector256)")]
public double Exp2_f64x4()
{
var acc = Vector256<double>.Zero;
for (var i = 0; i < _f64.Length - 3; i += 4)
{
var v = Vector256.Create(_f64[i], _f64[i + 1], _f64[i + 2], _f64[i + 3]);
acc += simd_math.Exp2(v);
}
return acc.GetElement(0);
}

[Benchmark(Description = "Exp2 double×8 (Vector512)")]
public double Exp2_f64x8()
{
var acc = Vector512<double>.Zero;
for (var i = 0; i < _f64.Length - 7; i += 8)
{
var v = Vector512.Create(
_f64[i], _f64[i + 1], _f64[i + 2], _f64[i + 3],
_f64[i + 4], _f64[i + 5], _f64[i + 6], _f64[i + 7]);
acc += simd_math.Exp2(v);
}
return acc.GetElement(0);
}
}
28 changes: 28 additions & 0 deletions Benchmarks/Benchmarks.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>13.0</LangVersion>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Optimize>true</Optimize>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.14.0" />
</ItemGroup>

<ItemGroup>
<Using Include="BenchmarkDotNet.Attributes"/>
<Using Include="Coplt.Mathematics.Simd"/>
<Using Include="System.Runtime.Intrinsics"/>
<Using Include="Coplt.Mathematics"/>
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Coplt.Mathematics\Coplt.Mathematics.csproj" />
</ItemGroup>

</Project>
3 changes: 3 additions & 0 deletions Benchmarks/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
using BenchmarkDotNet.Running;

BenchmarkSwitcher.FromAssembly(typeof(Program).Assembly).Run(args);
61 changes: 61 additions & 0 deletions Coplt.Mathematics.sln
Original file line number Diff line number Diff line change
Expand Up @@ -10,31 +10,92 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SourceGenerator", "SourceGe
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Coplt.Mathematics.Simt", "Coplt.Mathematics.Simt\Coplt.Mathematics.Simt.csproj", "{18B7AA4D-1D2F-406F-9C77-5FA06A592895}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmarks", "Benchmarks\Benchmarks.csproj", "{98399753-5721-4E8E-BB2C-53A4F9E79A80}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{5745D85D-B9C1-43B8-90A0-D820184CBBBB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{5745D85D-B9C1-43B8-90A0-D820184CBBBB}.Debug|Any CPU.Build.0 = Debug|Any CPU
{5745D85D-B9C1-43B8-90A0-D820184CBBBB}.Debug|x64.ActiveCfg = Debug|Any CPU
{5745D85D-B9C1-43B8-90A0-D820184CBBBB}.Debug|x64.Build.0 = Debug|Any CPU
{5745D85D-B9C1-43B8-90A0-D820184CBBBB}.Debug|x86.ActiveCfg = Debug|Any CPU
{5745D85D-B9C1-43B8-90A0-D820184CBBBB}.Debug|x86.Build.0 = Debug|Any CPU
{5745D85D-B9C1-43B8-90A0-D820184CBBBB}.Release|Any CPU.ActiveCfg = Release|Any CPU
{5745D85D-B9C1-43B8-90A0-D820184CBBBB}.Release|Any CPU.Build.0 = Release|Any CPU
{5745D85D-B9C1-43B8-90A0-D820184CBBBB}.Release|x64.ActiveCfg = Release|Any CPU
{5745D85D-B9C1-43B8-90A0-D820184CBBBB}.Release|x64.Build.0 = Release|Any CPU
{5745D85D-B9C1-43B8-90A0-D820184CBBBB}.Release|x86.ActiveCfg = Release|Any CPU
{5745D85D-B9C1-43B8-90A0-D820184CBBBB}.Release|x86.Build.0 = Release|Any CPU
{EAEDC447-AA5D-48D6-B285-425C5E8D52B6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EAEDC447-AA5D-48D6-B285-425C5E8D52B6}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EAEDC447-AA5D-48D6-B285-425C5E8D52B6}.Debug|x64.ActiveCfg = Debug|Any CPU
{EAEDC447-AA5D-48D6-B285-425C5E8D52B6}.Debug|x64.Build.0 = Debug|Any CPU
{EAEDC447-AA5D-48D6-B285-425C5E8D52B6}.Debug|x86.ActiveCfg = Debug|Any CPU
{EAEDC447-AA5D-48D6-B285-425C5E8D52B6}.Debug|x86.Build.0 = Debug|Any CPU
{EAEDC447-AA5D-48D6-B285-425C5E8D52B6}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EAEDC447-AA5D-48D6-B285-425C5E8D52B6}.Release|Any CPU.Build.0 = Release|Any CPU
{EAEDC447-AA5D-48D6-B285-425C5E8D52B6}.Release|x64.ActiveCfg = Release|Any CPU
{EAEDC447-AA5D-48D6-B285-425C5E8D52B6}.Release|x64.Build.0 = Release|Any CPU
{EAEDC447-AA5D-48D6-B285-425C5E8D52B6}.Release|x86.ActiveCfg = Release|Any CPU
{EAEDC447-AA5D-48D6-B285-425C5E8D52B6}.Release|x86.Build.0 = Release|Any CPU
{A8E41063-557E-4421-88A4-4DE59E49295B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{A8E41063-557E-4421-88A4-4DE59E49295B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{A8E41063-557E-4421-88A4-4DE59E49295B}.Debug|x64.ActiveCfg = Debug|Any CPU
{A8E41063-557E-4421-88A4-4DE59E49295B}.Debug|x64.Build.0 = Debug|Any CPU
{A8E41063-557E-4421-88A4-4DE59E49295B}.Debug|x86.ActiveCfg = Debug|Any CPU
{A8E41063-557E-4421-88A4-4DE59E49295B}.Debug|x86.Build.0 = Debug|Any CPU
{A8E41063-557E-4421-88A4-4DE59E49295B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{A8E41063-557E-4421-88A4-4DE59E49295B}.Release|Any CPU.Build.0 = Release|Any CPU
{A8E41063-557E-4421-88A4-4DE59E49295B}.Release|x64.ActiveCfg = Release|Any CPU
{A8E41063-557E-4421-88A4-4DE59E49295B}.Release|x64.Build.0 = Release|Any CPU
{A8E41063-557E-4421-88A4-4DE59E49295B}.Release|x86.ActiveCfg = Release|Any CPU
{A8E41063-557E-4421-88A4-4DE59E49295B}.Release|x86.Build.0 = Release|Any CPU
{D7F6B482-EFD3-46E0-964E-4E2CC53CCE0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D7F6B482-EFD3-46E0-964E-4E2CC53CCE0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D7F6B482-EFD3-46E0-964E-4E2CC53CCE0B}.Debug|x64.ActiveCfg = Debug|Any CPU
{D7F6B482-EFD3-46E0-964E-4E2CC53CCE0B}.Debug|x64.Build.0 = Debug|Any CPU
{D7F6B482-EFD3-46E0-964E-4E2CC53CCE0B}.Debug|x86.ActiveCfg = Debug|Any CPU
{D7F6B482-EFD3-46E0-964E-4E2CC53CCE0B}.Debug|x86.Build.0 = Debug|Any CPU
{D7F6B482-EFD3-46E0-964E-4E2CC53CCE0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D7F6B482-EFD3-46E0-964E-4E2CC53CCE0B}.Release|Any CPU.Build.0 = Release|Any CPU
{D7F6B482-EFD3-46E0-964E-4E2CC53CCE0B}.Release|x64.ActiveCfg = Release|Any CPU
{D7F6B482-EFD3-46E0-964E-4E2CC53CCE0B}.Release|x64.Build.0 = Release|Any CPU
{D7F6B482-EFD3-46E0-964E-4E2CC53CCE0B}.Release|x86.ActiveCfg = Release|Any CPU
{D7F6B482-EFD3-46E0-964E-4E2CC53CCE0B}.Release|x86.Build.0 = Release|Any CPU
{18B7AA4D-1D2F-406F-9C77-5FA06A592895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{18B7AA4D-1D2F-406F-9C77-5FA06A592895}.Debug|Any CPU.Build.0 = Debug|Any CPU
{18B7AA4D-1D2F-406F-9C77-5FA06A592895}.Debug|x64.ActiveCfg = Debug|Any CPU
{18B7AA4D-1D2F-406F-9C77-5FA06A592895}.Debug|x64.Build.0 = Debug|Any CPU
{18B7AA4D-1D2F-406F-9C77-5FA06A592895}.Debug|x86.ActiveCfg = Debug|Any CPU
{18B7AA4D-1D2F-406F-9C77-5FA06A592895}.Debug|x86.Build.0 = Debug|Any CPU
{18B7AA4D-1D2F-406F-9C77-5FA06A592895}.Release|Any CPU.ActiveCfg = Release|Any CPU
{18B7AA4D-1D2F-406F-9C77-5FA06A592895}.Release|Any CPU.Build.0 = Release|Any CPU
{18B7AA4D-1D2F-406F-9C77-5FA06A592895}.Release|x64.ActiveCfg = Release|Any CPU
{18B7AA4D-1D2F-406F-9C77-5FA06A592895}.Release|x64.Build.0 = Release|Any CPU
{18B7AA4D-1D2F-406F-9C77-5FA06A592895}.Release|x86.ActiveCfg = Release|Any CPU
{18B7AA4D-1D2F-406F-9C77-5FA06A592895}.Release|x86.Build.0 = Release|Any CPU
{98399753-5721-4E8E-BB2C-53A4F9E79A80}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{98399753-5721-4E8E-BB2C-53A4F9E79A80}.Debug|Any CPU.Build.0 = Debug|Any CPU
{98399753-5721-4E8E-BB2C-53A4F9E79A80}.Debug|x64.ActiveCfg = Debug|Any CPU
{98399753-5721-4E8E-BB2C-53A4F9E79A80}.Debug|x64.Build.0 = Debug|Any CPU
{98399753-5721-4E8E-BB2C-53A4F9E79A80}.Debug|x86.ActiveCfg = Debug|Any CPU
{98399753-5721-4E8E-BB2C-53A4F9E79A80}.Debug|x86.Build.0 = Debug|Any CPU
{98399753-5721-4E8E-BB2C-53A4F9E79A80}.Release|Any CPU.ActiveCfg = Release|Any CPU
{98399753-5721-4E8E-BB2C-53A4F9E79A80}.Release|Any CPU.Build.0 = Release|Any CPU
{98399753-5721-4E8E-BB2C-53A4F9E79A80}.Release|x64.ActiveCfg = Release|Any CPU
{98399753-5721-4E8E-BB2C-53A4F9E79A80}.Release|x64.Build.0 = Release|Any CPU
{98399753-5721-4E8E-BB2C-53A4F9E79A80}.Release|x86.ActiveCfg = Release|Any CPU
{98399753-5721-4E8E-BB2C-53A4F9E79A80}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
EndGlobal
133 changes: 133 additions & 0 deletions Tests/TestAsinhAcoshNew.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
using System.Runtime.Intrinsics;
using Coplt.Mathematics;

#if NET8_0_OR_GREATER
using Coplt.Mathematics.Simd;

namespace Tests;

[Parallelizable]
public class TestAsinhAcoshNew
{
[Test]
[Parallelizable]
public void FloatTestAsinh()
{
Utils.AssertUlpRate(nameof(FloatTestAsinh), 1000, 0.9, 100,
(-10f, 10f),
x => simd_math.Asinh(new float4(x).UnsafeGetInner()).GetElement(0),
MathF.Asinh
);
}

[Test]
[Parallelizable]
public void FloatTestAsinh_vec_2_4([Random(-10f, 10.0f, 1000)] float v)
{
var a = simd_math.Asinh(new float4(v).UnsafeGetInner()).GetElement(0);
var b = simd_math.Asinh(new float2(v).UnsafeGetInner()).GetElement(0);
Assert.That(a, Is.EqualTo(b));
}

[Test]
[Parallelizable]
public void DoubleTestAsinh()
{
Utils.AssertUlpRate(nameof(DoubleTestAsinh), 1000, 0.9, 700,
(-10.0, 10.0),
x => simd_math.Asinh(new double4(x).UnsafeGetInner()).GetElement(0),
Math.Asinh
);
}

[Test]
[Parallelizable]
public void DoubleTestAsinh_vec_2_4([Random(-10.0, 10.0, 1000)] double v)
{
var a = simd_math.Asinh(new double4(v).UnsafeGetInner()).GetElement(0);
var b = simd_math.Asinh(new double2(v).UnsafeGetInner()).GetElement(0);
Assert.That(a, Is.EqualTo(b));
}

[Test]
[Parallelizable]
public void FloatTestAcosh()
{
Utils.AssertUlpRate(nameof(FloatTestAcosh), 1000, 0.9, 2,
(1f, 10f),
x => simd_math.Acosh(new float4(x).UnsafeGetInner()).GetElement(0),
MathF.Acosh
);
}

[Test]
[Parallelizable]
public void FloatTestAcosh_vec_2_4([Random(1f, 10.0f, 1000)] float v)
{
var a = simd_math.Acosh(new float4(v).UnsafeGetInner()).GetElement(0);
var b = simd_math.Acosh(new float2(v).UnsafeGetInner()).GetElement(0);
Assert.That(a, Is.EqualTo(b));
}

[Test]
[Parallelizable]
public void DoubleTestAcosh()
{
Utils.AssertUlpRate(nameof(DoubleTestAcosh), 1000, 0.9, 16,
(1.0, 10.0),
x => simd_math.Acosh(new double4(x).UnsafeGetInner()).GetElement(0),
Math.Acosh
);
}

[Test]
[Parallelizable]
public void DoubleTestAcosh_vec_2_4([Random(1.0, 10.0, 1000)] double v)
{
var a = simd_math.Acosh(new double4(v).UnsafeGetInner()).GetElement(0);
var b = simd_math.Acosh(new double2(v).UnsafeGetInner()).GetElement(0);
Assert.That(a, Is.EqualTo(b));
}

[Test]
[Parallelizable]
public void FloatTestAtanh()
{
Utils.AssertUlpRate(nameof(FloatTestAtanh), 1000, 0.9, 4,
(-1f, 1f),
x => simd_math.Atanh(new float4(x).UnsafeGetInner()).GetElement(0),
MathF.Atanh
);
}

[Test]
[Parallelizable]
public void FloatTestAtanh_vec_2_4([Random(-1f, 1.0f, 1000)] float v)
{
var a = simd_math.Atanh(new float4(v).UnsafeGetInner()).GetElement(0);
var b = simd_math.Atanh(new float2(v).UnsafeGetInner()).GetElement(0);
Assert.That(a, Is.EqualTo(b));
}

[Test]
[Parallelizable]
public void DoubleTestAtanh()
{
Utils.AssertUlpRate(nameof(DoubleTestAtanh), 1000, 0.9, 4,
(-1.0, 1.0),
x => simd_math.Atanh(new double4(x).UnsafeGetInner()).GetElement(0),
Math.Atanh
);
}

[Test]
[Parallelizable]
public void DoubleTestAtanh_vec_2_4([Random(-1.0, 1.0, 1000)] double v)
{
var a = simd_math.Atanh(new double4(v).UnsafeGetInner()).GetElement(0);
var b = simd_math.Atanh(new double2(v).UnsafeGetInner()).GetElement(0);
Assert.That(a, Is.EqualTo(b));
}
}

#endif
Loading
Loading