Refactor SPMD lane abstraction and add gather support

- Rename ISPMD interfaces to ISPMDLane for clarity
- Add gather and mask load methods to ISPMDLane, implement for ScalarLane and WideLane
- Add GetUnsafePtr() for direct pointer access
- Update MathV and vector types to use new interface and gather methods
- Update SPMD job interfaces and implementations to ISPMDLane
- Improve hash codes, range checks, and safety checks in vector types
- Update codegen templates for new interface/methods
- Refactor SPMD jobs to use gather methods for efficient vectorized access
This commit is contained in:
2026-04-25 11:50:51 +09:00
parent cfd01eb9b6
commit 9f7507ba71
18 changed files with 772 additions and 300 deletions

View File

@@ -14,7 +14,7 @@ public interface IJobSPMD<TNumber0>
where TNumber0 : unmanaged, INumber<TNumber0>, IBinaryNumber<TNumber0>, IMinMaxValue<TNumber0>, IBitwiseOperators<TNumber0, TNumber0, TNumber0>
{
void Execute<TLane0>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane0 : unmanaged, ISPMD<TLane0, TNumber0>;
where TLane0 : unmanaged, ISPMDLane<TLane0, TNumber0>;
}
internal struct SPMDJobWrapper<T, TNumber0> : IJobParallelFor
@@ -69,8 +69,8 @@ public interface IJobSPMD<TNumber0, TNumber1>
where TNumber1 : unmanaged, INumber<TNumber1>, IBinaryNumber<TNumber1>, IMinMaxValue<TNumber1>, IBitwiseOperators<TNumber1, TNumber1, TNumber1>
{
void Execute<TLane0, TLane1>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane0 : unmanaged, ISPMD<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMD<TLane1, TNumber1>;
where TLane0 : unmanaged, ISPMDLane<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMDLane<TLane1, TNumber1>;
}
internal struct SPMDJobWrapper<T, TNumber0, TNumber1> : IJobParallelFor
@@ -129,9 +129,9 @@ public interface IJobSPMD<TNumber0, TNumber1, TNumber2>
where TNumber2 : unmanaged, INumber<TNumber2>, IBinaryNumber<TNumber2>, IMinMaxValue<TNumber2>, IBitwiseOperators<TNumber2, TNumber2, TNumber2>
{
void Execute<TLane0, TLane1, TLane2>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane0 : unmanaged, ISPMD<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMD<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMD<TLane2, TNumber2>;
where TLane0 : unmanaged, ISPMDLane<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMDLane<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMDLane<TLane2, TNumber2>;
}
internal struct SPMDJobWrapper<T, TNumber0, TNumber1, TNumber2> : IJobParallelFor
@@ -194,10 +194,10 @@ public interface IJobSPMD<TNumber0, TNumber1, TNumber2, TNumber3>
where TNumber3 : unmanaged, INumber<TNumber3>, IBinaryNumber<TNumber3>, IMinMaxValue<TNumber3>, IBitwiseOperators<TNumber3, TNumber3, TNumber3>
{
void Execute<TLane0, TLane1, TLane2, TLane3>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane0 : unmanaged, ISPMD<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMD<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMD<TLane2, TNumber2>
where TLane3 : unmanaged, ISPMD<TLane3, TNumber3>;
where TLane0 : unmanaged, ISPMDLane<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMDLane<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMDLane<TLane2, TNumber2>
where TLane3 : unmanaged, ISPMDLane<TLane3, TNumber3>;
}
internal struct SPMDJobWrapper<T, TNumber0, TNumber1, TNumber2, TNumber3> : IJobParallelFor
@@ -264,11 +264,11 @@ public interface IJobSPMD<TNumber0, TNumber1, TNumber2, TNumber3, TNumber4>
where TNumber4 : unmanaged, INumber<TNumber4>, IBinaryNumber<TNumber4>, IMinMaxValue<TNumber4>, IBitwiseOperators<TNumber4, TNumber4, TNumber4>
{
void Execute<TLane0, TLane1, TLane2, TLane3, TLane4>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane0 : unmanaged, ISPMD<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMD<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMD<TLane2, TNumber2>
where TLane3 : unmanaged, ISPMD<TLane3, TNumber3>
where TLane4 : unmanaged, ISPMD<TLane4, TNumber4>;
where TLane0 : unmanaged, ISPMDLane<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMDLane<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMDLane<TLane2, TNumber2>
where TLane3 : unmanaged, ISPMDLane<TLane3, TNumber3>
where TLane4 : unmanaged, ISPMDLane<TLane4, TNumber4>;
}
internal struct SPMDJobWrapper<T, TNumber0, TNumber1, TNumber2, TNumber3, TNumber4> : IJobParallelFor
@@ -339,12 +339,12 @@ public interface IJobSPMD<TNumber0, TNumber1, TNumber2, TNumber3, TNumber4, TNum
where TNumber5 : unmanaged, INumber<TNumber5>, IBinaryNumber<TNumber5>, IMinMaxValue<TNumber5>, IBitwiseOperators<TNumber5, TNumber5, TNumber5>
{
void Execute<TLane0, TLane1, TLane2, TLane3, TLane4, TLane5>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane0 : unmanaged, ISPMD<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMD<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMD<TLane2, TNumber2>
where TLane3 : unmanaged, ISPMD<TLane3, TNumber3>
where TLane4 : unmanaged, ISPMD<TLane4, TNumber4>
where TLane5 : unmanaged, ISPMD<TLane5, TNumber5>;
where TLane0 : unmanaged, ISPMDLane<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMDLane<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMDLane<TLane2, TNumber2>
where TLane3 : unmanaged, ISPMDLane<TLane3, TNumber3>
where TLane4 : unmanaged, ISPMDLane<TLane4, TNumber4>
where TLane5 : unmanaged, ISPMDLane<TLane5, TNumber5>;
}
internal struct SPMDJobWrapper<T, TNumber0, TNumber1, TNumber2, TNumber3, TNumber4, TNumber5> : IJobParallelFor
@@ -419,13 +419,13 @@ public interface IJobSPMD<TNumber0, TNumber1, TNumber2, TNumber3, TNumber4, TNum
where TNumber6 : unmanaged, INumber<TNumber6>, IBinaryNumber<TNumber6>, IMinMaxValue<TNumber6>, IBitwiseOperators<TNumber6, TNumber6, TNumber6>
{
void Execute<TLane0, TLane1, TLane2, TLane3, TLane4, TLane5, TLane6>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane0 : unmanaged, ISPMD<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMD<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMD<TLane2, TNumber2>
where TLane3 : unmanaged, ISPMD<TLane3, TNumber3>
where TLane4 : unmanaged, ISPMD<TLane4, TNumber4>
where TLane5 : unmanaged, ISPMD<TLane5, TNumber5>
where TLane6 : unmanaged, ISPMD<TLane6, TNumber6>;
where TLane0 : unmanaged, ISPMDLane<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMDLane<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMDLane<TLane2, TNumber2>
where TLane3 : unmanaged, ISPMDLane<TLane3, TNumber3>
where TLane4 : unmanaged, ISPMDLane<TLane4, TNumber4>
where TLane5 : unmanaged, ISPMDLane<TLane5, TNumber5>
where TLane6 : unmanaged, ISPMDLane<TLane6, TNumber6>;
}
internal struct SPMDJobWrapper<T, TNumber0, TNumber1, TNumber2, TNumber3, TNumber4, TNumber5, TNumber6> : IJobParallelFor
@@ -504,14 +504,14 @@ public interface IJobSPMD<TNumber0, TNumber1, TNumber2, TNumber3, TNumber4, TNum
where TNumber7 : unmanaged, INumber<TNumber7>, IBinaryNumber<TNumber7>, IMinMaxValue<TNumber7>, IBitwiseOperators<TNumber7, TNumber7, TNumber7>
{
void Execute<TLane0, TLane1, TLane2, TLane3, TLane4, TLane5, TLane6, TLane7>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane0 : unmanaged, ISPMD<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMD<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMD<TLane2, TNumber2>
where TLane3 : unmanaged, ISPMD<TLane3, TNumber3>
where TLane4 : unmanaged, ISPMD<TLane4, TNumber4>
where TLane5 : unmanaged, ISPMD<TLane5, TNumber5>
where TLane6 : unmanaged, ISPMD<TLane6, TNumber6>
where TLane7 : unmanaged, ISPMD<TLane7, TNumber7>;
where TLane0 : unmanaged, ISPMDLane<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMDLane<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMDLane<TLane2, TNumber2>
where TLane3 : unmanaged, ISPMDLane<TLane3, TNumber3>
where TLane4 : unmanaged, ISPMDLane<TLane4, TNumber4>
where TLane5 : unmanaged, ISPMDLane<TLane5, TNumber5>
where TLane6 : unmanaged, ISPMDLane<TLane6, TNumber6>
where TLane7 : unmanaged, ISPMDLane<TLane7, TNumber7>;
}
internal struct SPMDJobWrapper<T, TNumber0, TNumber1, TNumber2, TNumber3, TNumber4, TNumber5, TNumber6, TNumber7> : IJobParallelFor

View File

@@ -15,7 +15,7 @@ const string TLane = "TLane";
const string TNumber = "TNumber";
const string GenericParameters = $"{TLane}, {TNumber}";
var TLaneRestrictions = $@"where {TLane} : ISPMD<{TLane}, {TNumber}>";
var TLaneRestrictions = $@"where {TLane} : ISPMDLane<{TLane}, {TNumber}>";
var TNumberRestrictions = $@"where {TNumber} : unmanaged, INumber<{TNumber}>, IBinaryNumber<{TNumber}>, IMinMaxValue<{TNumber}>, IBitwiseOperators<{TNumber}, {TNumber}, {TNumber}>";
for (var i = 0; i < 8; i++) { #>
@@ -192,7 +192,7 @@ public string GetTLaneRestrictions(int dimension, string space = " ")
var sb = new StringBuilder();
for (var i = 0; i < dimension; i++)
{
sb.Append(space + $@"where TLane{i} : unmanaged, ISPMD<TLane{i}, TNumber{i}>");
sb.Append(space + $@"where TLane{i} : unmanaged, ISPMDLane<TLane{i}, TNumber{i}>");
if (i < dimension - 1)
{
sb.AppendLine();

View File

@@ -11,13 +11,13 @@ namespace Misaki.HighPerformance.Mathematics.SPMD;
public static unsafe partial class MathV
{
#region Vector2
# region Vector2
// Creation Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Create<TLane, TNumber>(in TLane x, in TLane y)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector2<TLane, TNumber>
@@ -29,7 +29,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> CreateVector2<TLane, TNumber>(in TLane value)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector2<TLane, TNumber>
@@ -41,7 +41,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> LoadVector2<TLane, TNumber>(TNumber* pSrc)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var width = TLane.LaneWidth;
@@ -64,7 +64,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> LoadVector2<TLane, TNumber>(ref TNumber src)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return LoadVector2<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref src));
@@ -72,7 +72,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Load<TLane, TNumber>(TNumber* px, TNumber* py)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector2<TLane, TNumber>
@@ -84,7 +84,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Load<TLane, TNumber>(ref TNumber x, ref TNumber y)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector2<TLane, TNumber>
@@ -94,11 +94,93 @@ public static unsafe partial class MathV
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> GatherVector2<TLane, TNumber>(TNumber* pData, TLane indices, int scale)
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var buffer = stackalloc TNumber[TLane.LaneWidth * 2];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = int.CreateTruncating(indices[i]);
buffer[0 * TLane.LaneWidth + i] = pData[scalarIdx + 0 * scale];
buffer[1 * TLane.LaneWidth + i] = pData[scalarIdx + 1 * scale];
}
return new Vector2<TLane, TNumber>
{
x = TLane.Load(buffer + 0 * TLane.LaneWidth),
y = TLane.Load(buffer + 1 * TLane.LaneWidth),
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> GatherVector2<TLane, TNumber>(TNumber* pData, int* pIndices, int scale)
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var buffer = stackalloc TNumber[TLane.LaneWidth * 2];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = pIndices[i];
buffer[0 * TLane.LaneWidth + i] = pData[scalarIdx + 0 * scale];
buffer[1 * TLane.LaneWidth + i] = pData[scalarIdx + 1 * scale];
}
return new Vector2<TLane, TNumber>
{
x = TLane.Load(buffer + 0 * TLane.LaneWidth),
y = TLane.Load(buffer + 1 * TLane.LaneWidth),
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> GatherVector2<TLane, TNumber>(ref TNumber baseAddress, TLane indices, int scale)
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var buffer = stackalloc TNumber[TLane.LaneWidth * 2];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = int.CreateTruncating(indices[i]);
buffer[0 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale);
buffer[1 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale);
}
return new Vector2<TLane, TNumber>
{
x = TLane.Load(buffer + 0 * TLane.LaneWidth),
y = TLane.Load(buffer + 1 * TLane.LaneWidth),
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> GatherVector2<TLane, TNumber>(ref TNumber baseAddress, ref int baseIndex, int scale)
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var buffer = stackalloc TNumber[TLane.LaneWidth * 2];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = Unsafe.Add(ref baseIndex, i);
buffer[0 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale);
buffer[1 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale);
}
return new Vector2<TLane, TNumber>
{
x = TLane.Load(buffer + 0 * TLane.LaneWidth),
y = TLane.Load(buffer + 1 * TLane.LaneWidth),
};
}
// Math Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Abs<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector2<TLane, TNumber>
@@ -110,7 +192,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Dot<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return a.x * b.x + a.y * b.y;
@@ -118,7 +200,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Sqrt<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector2<TLane, TNumber>
@@ -130,7 +212,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Rsqrt<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector2<TLane, TNumber>
@@ -142,7 +224,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Normalize<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return vector * TLane.Rsqrt(Dot(vector, vector));
@@ -150,7 +232,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Reflect<TLane, TNumber>(in Vector2<TLane, TNumber> incident, in Vector2<TLane, TNumber> normal)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var dot = Dot(incident, normal);
@@ -159,7 +241,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Min<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector2<TLane, TNumber>
@@ -171,7 +253,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Max<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector2<TLane, TNumber>
@@ -183,7 +265,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Clamp<TLane, TNumber>(in Vector2<TLane, TNumber> value, in Vector2<TLane, TNumber> min, in Vector2<TLane, TNumber> max)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return Min(Max(value, min), max);
@@ -191,7 +273,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Saturate<TLane, TNumber>(in Vector2<TLane, TNumber> value)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return Clamp(value, CreateVector2<TLane, TNumber>(TLane.Zero), CreateVector2<TLane, TNumber>(TLane.One));
@@ -199,7 +281,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Lerp<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b, TLane t)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return a + (b - a) * t;
@@ -207,15 +289,15 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Length<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return TLane.Sqrt(Dot(vector, vector));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane LengthSquared<TLane, TNumber>(in Vector2<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return Dot(vector, vector);
@@ -223,7 +305,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Distance<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var diff = b - a;
@@ -232,7 +314,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane DistanceSquared<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var diff = b - a;
@@ -241,7 +323,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Step<TLane, TNumber>(in Vector2<TLane, TNumber> edge, in Vector2<TLane, TNumber> value)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return Select(value >= edge, Vector2<TLane, TNumber>.One, Vector2<TLane, TNumber>.Zero);
@@ -249,7 +331,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Smoothstep<TLane, TNumber>(Vector2<TLane, TNumber> xMin, Vector2<TLane, TNumber> xMax, Vector2<TLane, TNumber> x)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var t = Saturate((x - xMin) / (xMax - xMin));
@@ -261,7 +343,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Select<TLane, TNumber>(TLane condition, in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector2<TLane, TNumber>
@@ -273,7 +355,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Select<TLane, TNumber>(Vector2<TLane, TNumber> condition, in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector2<TLane, TNumber>
@@ -283,15 +365,15 @@ public static unsafe partial class MathV
};
}
#endregion
# endregion
#region Vector3
# region Vector3
// Creation Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Create<TLane, TNumber>(in TLane x, in TLane y, in TLane z)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector3<TLane, TNumber>
@@ -304,7 +386,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> CreateVector3<TLane, TNumber>(in TLane value)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector3<TLane, TNumber>
@@ -317,7 +399,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> LoadVector3<TLane, TNumber>(TNumber* pSrc)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var width = TLane.LaneWidth;
@@ -343,7 +425,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> LoadVector3<TLane, TNumber>(ref TNumber src)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return LoadVector3<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref src));
@@ -351,7 +433,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Load<TLane, TNumber>(TNumber* px, TNumber* py, TNumber* pz)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector3<TLane, TNumber>
@@ -364,7 +446,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Load<TLane, TNumber>(ref TNumber x, ref TNumber y, ref TNumber z)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector3<TLane, TNumber>
@@ -375,11 +457,101 @@ public static unsafe partial class MathV
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> GatherVector3<TLane, TNumber>(TNumber* pData, TLane indices, int scale)
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var buffer = stackalloc TNumber[TLane.LaneWidth * 3];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = int.CreateTruncating(indices[i]);
buffer[0 * TLane.LaneWidth + i] = pData[scalarIdx + 0 * scale];
buffer[1 * TLane.LaneWidth + i] = pData[scalarIdx + 1 * scale];
buffer[2 * TLane.LaneWidth + i] = pData[scalarIdx + 2 * scale];
}
return new Vector3<TLane, TNumber>
{
x = TLane.Load(buffer + 0 * TLane.LaneWidth),
y = TLane.Load(buffer + 1 * TLane.LaneWidth),
z = TLane.Load(buffer + 2 * TLane.LaneWidth),
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> GatherVector3<TLane, TNumber>(TNumber* pData, int* pIndices, int scale)
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var buffer = stackalloc TNumber[TLane.LaneWidth * 3];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = pIndices[i];
buffer[0 * TLane.LaneWidth + i] = pData[scalarIdx + 0 * scale];
buffer[1 * TLane.LaneWidth + i] = pData[scalarIdx + 1 * scale];
buffer[2 * TLane.LaneWidth + i] = pData[scalarIdx + 2 * scale];
}
return new Vector3<TLane, TNumber>
{
x = TLane.Load(buffer + 0 * TLane.LaneWidth),
y = TLane.Load(buffer + 1 * TLane.LaneWidth),
z = TLane.Load(buffer + 2 * TLane.LaneWidth),
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> GatherVector3<TLane, TNumber>(ref TNumber baseAddress, TLane indices, int scale)
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var buffer = stackalloc TNumber[TLane.LaneWidth * 3];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = int.CreateTruncating(indices[i]);
buffer[0 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale);
buffer[1 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale);
buffer[2 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale);
}
return new Vector3<TLane, TNumber>
{
x = TLane.Load(buffer + 0 * TLane.LaneWidth),
y = TLane.Load(buffer + 1 * TLane.LaneWidth),
z = TLane.Load(buffer + 2 * TLane.LaneWidth),
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> GatherVector3<TLane, TNumber>(ref TNumber baseAddress, ref int baseIndex, int scale)
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var buffer = stackalloc TNumber[TLane.LaneWidth * 3];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = Unsafe.Add(ref baseIndex, i);
buffer[0 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale);
buffer[1 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale);
buffer[2 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale);
}
return new Vector3<TLane, TNumber>
{
x = TLane.Load(buffer + 0 * TLane.LaneWidth),
y = TLane.Load(buffer + 1 * TLane.LaneWidth),
z = TLane.Load(buffer + 2 * TLane.LaneWidth),
};
}
// Math Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Abs<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector3<TLane, TNumber>
@@ -392,7 +564,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Dot<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return a.x * b.x + a.y * b.y + a.z * b.z;
@@ -400,7 +572,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Sqrt<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector3<TLane, TNumber>
@@ -413,7 +585,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Rsqrt<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector3<TLane, TNumber>
@@ -426,7 +598,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Normalize<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return vector * TLane.Rsqrt(Dot(vector, vector));
@@ -434,7 +606,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Reflect<TLane, TNumber>(in Vector3<TLane, TNumber> incident, in Vector3<TLane, TNumber> normal)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var dot = Dot(incident, normal);
@@ -443,7 +615,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Min<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector3<TLane, TNumber>
@@ -456,7 +628,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Max<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector3<TLane, TNumber>
@@ -469,7 +641,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Clamp<TLane, TNumber>(in Vector3<TLane, TNumber> value, in Vector3<TLane, TNumber> min, in Vector3<TLane, TNumber> max)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return Min(Max(value, min), max);
@@ -477,7 +649,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Saturate<TLane, TNumber>(in Vector3<TLane, TNumber> value)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return Clamp(value, CreateVector3<TLane, TNumber>(TLane.Zero), CreateVector3<TLane, TNumber>(TLane.One));
@@ -485,7 +657,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Lerp<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b, TLane t)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return a + (b - a) * t;
@@ -493,15 +665,15 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Length<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return TLane.Sqrt(Dot(vector, vector));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane LengthSquared<TLane, TNumber>(in Vector3<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return Dot(vector, vector);
@@ -509,7 +681,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Distance<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var diff = b - a;
@@ -518,7 +690,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane DistanceSquared<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var diff = b - a;
@@ -527,7 +699,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Step<TLane, TNumber>(in Vector3<TLane, TNumber> edge, in Vector3<TLane, TNumber> value)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return Select(value >= edge, Vector3<TLane, TNumber>.One, Vector3<TLane, TNumber>.Zero);
@@ -535,7 +707,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Smoothstep<TLane, TNumber>(Vector3<TLane, TNumber> xMin, Vector3<TLane, TNumber> xMax, Vector3<TLane, TNumber> x)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var t = Saturate((x - xMin) / (xMax - xMin));
@@ -547,7 +719,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Select<TLane, TNumber>(TLane condition, in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector3<TLane, TNumber>
@@ -560,7 +732,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Select<TLane, TNumber>(Vector3<TLane, TNumber> condition, in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector3<TLane, TNumber>
@@ -571,15 +743,15 @@ public static unsafe partial class MathV
};
}
#endregion
# endregion
#region Vector4
# region Vector4
// Creation Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Create<TLane, TNumber>(in TLane x, in TLane y, in TLane z, in TLane w)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector4<TLane, TNumber>
@@ -593,7 +765,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> CreateVector4<TLane, TNumber>(in TLane value)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector4<TLane, TNumber>
@@ -607,7 +779,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> LoadVector4<TLane, TNumber>(TNumber* pSrc)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var width = TLane.LaneWidth;
@@ -636,7 +808,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> LoadVector4<TLane, TNumber>(ref TNumber src)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return LoadVector4<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref src));
@@ -644,7 +816,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Load<TLane, TNumber>(TNumber* px, TNumber* py, TNumber* pz, TNumber* pw)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector4<TLane, TNumber>
@@ -658,7 +830,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Load<TLane, TNumber>(ref TNumber x, ref TNumber y, ref TNumber z, ref TNumber w)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector4<TLane, TNumber>
@@ -670,11 +842,109 @@ public static unsafe partial class MathV
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> GatherVector4<TLane, TNumber>(TNumber* pData, TLane indices, int scale)
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var buffer = stackalloc TNumber[TLane.LaneWidth * 4];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = int.CreateTruncating(indices[i]);
buffer[0 * TLane.LaneWidth + i] = pData[scalarIdx + 0 * scale];
buffer[1 * TLane.LaneWidth + i] = pData[scalarIdx + 1 * scale];
buffer[2 * TLane.LaneWidth + i] = pData[scalarIdx + 2 * scale];
buffer[3 * TLane.LaneWidth + i] = pData[scalarIdx + 3 * scale];
}
return new Vector4<TLane, TNumber>
{
x = TLane.Load(buffer + 0 * TLane.LaneWidth),
y = TLane.Load(buffer + 1 * TLane.LaneWidth),
z = TLane.Load(buffer + 2 * TLane.LaneWidth),
w = TLane.Load(buffer + 3 * TLane.LaneWidth),
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> GatherVector4<TLane, TNumber>(TNumber* pData, int* pIndices, int scale)
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var buffer = stackalloc TNumber[TLane.LaneWidth * 4];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = pIndices[i];
buffer[0 * TLane.LaneWidth + i] = pData[scalarIdx + 0 * scale];
buffer[1 * TLane.LaneWidth + i] = pData[scalarIdx + 1 * scale];
buffer[2 * TLane.LaneWidth + i] = pData[scalarIdx + 2 * scale];
buffer[3 * TLane.LaneWidth + i] = pData[scalarIdx + 3 * scale];
}
return new Vector4<TLane, TNumber>
{
x = TLane.Load(buffer + 0 * TLane.LaneWidth),
y = TLane.Load(buffer + 1 * TLane.LaneWidth),
z = TLane.Load(buffer + 2 * TLane.LaneWidth),
w = TLane.Load(buffer + 3 * TLane.LaneWidth),
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> GatherVector4<TLane, TNumber>(ref TNumber baseAddress, TLane indices, int scale)
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var buffer = stackalloc TNumber[TLane.LaneWidth * 4];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = int.CreateTruncating(indices[i]);
buffer[0 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale);
buffer[1 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale);
buffer[2 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale);
buffer[3 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 3 * scale);
}
return new Vector4<TLane, TNumber>
{
x = TLane.Load(buffer + 0 * TLane.LaneWidth),
y = TLane.Load(buffer + 1 * TLane.LaneWidth),
z = TLane.Load(buffer + 2 * TLane.LaneWidth),
w = TLane.Load(buffer + 3 * TLane.LaneWidth),
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> GatherVector4<TLane, TNumber>(ref TNumber baseAddress, ref int baseIndex, int scale)
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var buffer = stackalloc TNumber[TLane.LaneWidth * 4];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = Unsafe.Add(ref baseIndex, i);
buffer[0 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 0 * scale);
buffer[1 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 1 * scale);
buffer[2 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 2 * scale);
buffer[3 * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + 3 * scale);
}
return new Vector4<TLane, TNumber>
{
x = TLane.Load(buffer + 0 * TLane.LaneWidth),
y = TLane.Load(buffer + 1 * TLane.LaneWidth),
z = TLane.Load(buffer + 2 * TLane.LaneWidth),
w = TLane.Load(buffer + 3 * TLane.LaneWidth),
};
}
// Math Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Abs<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector4<TLane, TNumber>
@@ -688,7 +958,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Dot<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
@@ -696,7 +966,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Sqrt<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector4<TLane, TNumber>
@@ -710,7 +980,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Rsqrt<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector4<TLane, TNumber>
@@ -724,7 +994,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Normalize<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return vector * TLane.Rsqrt(Dot(vector, vector));
@@ -732,7 +1002,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Reflect<TLane, TNumber>(in Vector4<TLane, TNumber> incident, in Vector4<TLane, TNumber> normal)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var dot = Dot(incident, normal);
@@ -741,7 +1011,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Min<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector4<TLane, TNumber>
@@ -755,7 +1025,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Max<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector4<TLane, TNumber>
@@ -769,7 +1039,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Clamp<TLane, TNumber>(in Vector4<TLane, TNumber> value, in Vector4<TLane, TNumber> min, in Vector4<TLane, TNumber> max)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return Min(Max(value, min), max);
@@ -777,7 +1047,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Saturate<TLane, TNumber>(in Vector4<TLane, TNumber> value)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return Clamp(value, CreateVector4<TLane, TNumber>(TLane.Zero), CreateVector4<TLane, TNumber>(TLane.One));
@@ -785,7 +1055,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Lerp<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b, TLane t)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return a + (b - a) * t;
@@ -793,15 +1063,15 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Length<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return TLane.Sqrt(Dot(vector, vector));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane LengthSquared<TLane, TNumber>(in Vector4<TLane, TNumber> vector)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return Dot(vector, vector);
@@ -809,7 +1079,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Distance<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var diff = b - a;
@@ -818,7 +1088,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane DistanceSquared<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var diff = b - a;
@@ -827,7 +1097,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Step<TLane, TNumber>(in Vector4<TLane, TNumber> edge, in Vector4<TLane, TNumber> value)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return Select(value >= edge, Vector4<TLane, TNumber>.One, Vector4<TLane, TNumber>.Zero);
@@ -835,7 +1105,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Smoothstep<TLane, TNumber>(Vector4<TLane, TNumber> xMin, Vector4<TLane, TNumber> xMax, Vector4<TLane, TNumber> x)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
var t = Saturate((x - xMin) / (xMax - xMin));
@@ -847,7 +1117,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Select<TLane, TNumber>(TLane condition, in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector4<TLane, TNumber>
@@ -861,7 +1131,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Select<TLane, TNumber>(Vector4<TLane, TNumber> condition, in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector4<TLane, TNumber>
@@ -873,14 +1143,14 @@ public static unsafe partial class MathV
};
}
#endregion
# endregion
#region Vector3 Specific
# region Vector3 Specific
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Cross<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b)
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
return new Vector3<TLane, TNumber>
@@ -891,6 +1161,6 @@ public static unsafe partial class MathV
};
}
#endregion
# endregion
}

View File

@@ -21,7 +21,7 @@ const string GenericParameters = $"{TLane}, {TNumber}";
var dimensions = new int[] { 2, 3, 4 };
var components = new char[] { 'x', 'y', 'z', 'w' };
var TLaneRestrictions = $@"where {TLane} : ISPMD<{TLane}, {TNumber}>";
var TLaneRestrictions = $@"where {TLane} : ISPMDLane<{TLane}, {TNumber}>";
var TNumberRestrictions = $@"where {TNumber} : unmanaged, INumber<{TNumber}>, IBinaryNumber<{TNumber}>, IMinMaxValue<{TNumber}>, IBitwiseOperators<{TNumber}, {TNumber}, {TNumber}>";
#>
@@ -35,7 +35,7 @@ public static unsafe partial class MathV
// Creation Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static <#= vectorType #> Create<<#= GenericParameters #>>(<#= ForEachDimension(dimension, i => $"in TLane {components[i]}") #>)
public static <#= vectorType #> Create<<#= GenericParameters #>>(<#= ForEachDimension(dimension, i => $"in {TLane} {components[i]}") #>)
<#= TLaneRestrictions #>
<#= TNumberRestrictions #>
{
@@ -48,7 +48,7 @@ public static unsafe partial class MathV
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static <#= vectorType #> CreateVector<#= dimension #><<#= GenericParameters #>>(in TLane value)
public static <#= vectorType #> CreateVector<#= dimension #><<#= GenericParameters #>>(in <#= TLane #> value)
<#= TLaneRestrictions #>
<#= TNumberRestrictions #>
{
@@ -61,14 +61,14 @@ public static unsafe partial class MathV
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static <#= vectorType #> LoadVector<#= dimension #><<#= GenericParameters #>>(TNumber* pSrc)
public static <#= vectorType #> LoadVector<#= dimension #><<#= GenericParameters #>>(<#= TNumber #>* pSrc)
<#= TLaneRestrictions #>
<#= TNumberRestrictions #>
{
var width = TLane.LaneWidth;
<# for (int i = 0; i < dimension; i++) { #>
var <#= components[i] #> = stackalloc TNumber[width];
var <#= components[i] #> = stackalloc <#= TNumber #>[width];
<# } #>
for (var i = 0; i < width; i++)
@@ -87,11 +87,11 @@ public static unsafe partial class MathV
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static <#= vectorType #> LoadVector<#= dimension #><<#= GenericParameters #>>(ref TNumber src)
public static <#= vectorType #> LoadVector<#= dimension #><<#= GenericParameters #>>(ref <#= TNumber #> src)
<#= TLaneRestrictions #>
<#= TNumberRestrictions #>
{
return LoadVector<#= dimension #><<#= GenericParameters #>>((TNumber*)Unsafe.AsPointer(ref src));
return LoadVector<#= dimension #><<#= GenericParameters #>>((<#= TNumber #>*)Unsafe.AsPointer(ref src));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -120,10 +120,100 @@ public static unsafe partial class MathV
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static <#= vectorType #> GatherVector<#= dimension #><<#= GenericParameters #>>(<#= TNumber #>* pData, <#= TLane #> indices, int scale)
<#= TLaneRestrictions #>
<#= TNumberRestrictions #>
{
var buffer = stackalloc <#= TNumber #>[TLane.LaneWidth * <#= dimension #>];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = int.CreateTruncating(indices[i]);
<# for (int i = 0; i < dimension; i++) { #>
buffer[<#= i #> * TLane.LaneWidth + i] = pData[scalarIdx + <#= i #> * scale];
<# } #>
}
return new <#= vectorType #>
{
<# for (int i = 0; i < dimension; i++) { #>
<#= components[i] #> = TLane.Load(buffer + <#= i #> * TLane.LaneWidth),
<# } #>
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static <#= vectorType #> GatherVector<#= dimension #><<#= GenericParameters #>>(<#= TNumber #>* pData, int* pIndices, int scale)
<#= TLaneRestrictions #>
<#= TNumberRestrictions #>
{
var buffer = stackalloc <#= TNumber #>[TLane.LaneWidth * <#= dimension #>];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = pIndices[i];
<# for (int i = 0; i < dimension; i++) { #>
buffer[<#= i #> * TLane.LaneWidth + i] = pData[scalarIdx + <#= i #> * scale];
<# } #>
}
return new <#= vectorType #>
{
<# for (int i = 0; i < dimension; i++) { #>
<#= components[i] #> = TLane.Load(buffer + <#= i #> * TLane.LaneWidth),
<# } #>
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static <#= vectorType #> GatherVector<#= dimension #><<#= GenericParameters #>>(ref <#= TNumber #> baseAddress, <#= TLane #> indices, int scale)
<#= TLaneRestrictions #>
<#= TNumberRestrictions #>
{
var buffer = stackalloc <#= TNumber #>[TLane.LaneWidth * <#= dimension #>];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = int.CreateTruncating(indices[i]);
<# for (int i = 0; i < dimension; i++) { #>
buffer[<#= i #> * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + <#= i #> * scale);
<# } #>
}
return new <#= vectorType #>
{
<# for (int i = 0; i < dimension; i++) { #>
<#= components[i] #> = TLane.Load(buffer + <#= i #> * TLane.LaneWidth),
<# } #>
};
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static <#= vectorType #> GatherVector<#= dimension #><<#= GenericParameters #>>(ref <#= TNumber #> baseAddress, ref int baseIndex, int scale)
<#= TLaneRestrictions #>
<#= TNumberRestrictions #>
{
var buffer = stackalloc <#= TNumber #>[TLane.LaneWidth * <#= dimension #>];
for (var i = 0; i < TLane.LaneWidth; i++)
{
var scalarIdx = Unsafe.Add(ref baseIndex, i);
<# for (int i = 0; i < dimension; i++) { #>
buffer[<#= i #> * TLane.LaneWidth + i] = Unsafe.Add(ref baseAddress, scalarIdx + <#= i #> * scale);
<# } #>
}
return new <#= vectorType #>
{
<# for (int i = 0; i < dimension; i++) { #>
<#= components[i] #> = TLane.Load(buffer + <#= i #> * TLane.LaneWidth),
<# } #>
};
}
// Math Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static <#= vectorType #> Abs<<#= GenericParameters #>>(in Vector<#= dimension #><TLane, TNumber> vector)
public static <#= vectorType #> Abs<<#= GenericParameters #>>(in Vector<#= dimension #><TLane, <#= TNumber #>> vector)
<#= TLaneRestrictions #>
<#= TNumberRestrictions #>
{

View File

@@ -6,7 +6,7 @@ using System.Runtime.CompilerServices;
namespace Misaki.HighPerformance.Mathematics.SPMD;
public unsafe struct Vector2<TLane, TNumber> : IEquatable<Vector2<TLane, TNumber>>
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
public TLane x;
@@ -49,7 +49,7 @@ public unsafe struct Vector2<TLane, TNumber> : IEquatable<Vector2<TLane, TNumber
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_COLLECTION_CHECKS")]
[Conditional("MHP_ENABLE_SAFETY_CHECKS")]
private static void RangeCheck(int index)
{
if (index < 0 || index >= 2)
@@ -420,8 +420,11 @@ public unsafe struct Vector2<TLane, TNumber> : IEquatable<Vector2<TLane, TNumber
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode()
public override readonly int GetHashCode()
{
throw new NotImplementedException();
var hash = new HashCode();
hash.Add(x);
hash.Add(y);
return hash.ToHashCode();
}
}

View File

@@ -6,7 +6,7 @@ using System.Runtime.CompilerServices;
namespace Misaki.HighPerformance.Mathematics.SPMD;
public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber>>
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
public TLane x;
@@ -52,12 +52,12 @@ public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_COLLECTION_CHECKS")]
[Conditional("MHP_ENABLE_SAFETY_CHECKS")]
private static void RangeCheck(int index)
{
if (index < 0 || index >= 3)
{
throw new IndexOutOfRangeException($"Index {index} is out of range for Vector2.");
throw new IndexOutOfRangeException($"Index {index} is out of range for Vector3.");
}
}
@@ -459,8 +459,12 @@ public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode()
public override readonly int GetHashCode()
{
throw new NotImplementedException();
var hash = new HashCode();
hash.Add(x);
hash.Add(y);
hash.Add(z);
return hash.ToHashCode();
}
}

View File

@@ -6,7 +6,7 @@ using System.Runtime.CompilerServices;
namespace Misaki.HighPerformance.Mathematics.SPMD;
public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber>>
where TLane : ISPMD<TLane, TNumber>
where TLane : ISPMDLane<TLane, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
public TLane x;
@@ -55,12 +55,12 @@ public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_COLLECTION_CHECKS")]
[Conditional("MHP_ENABLE_SAFETY_CHECKS")]
private static void RangeCheck(int index)
{
if (index < 0 || index >= 4)
{
throw new IndexOutOfRangeException($"Index {index} is out of range for Vector2.");
throw new IndexOutOfRangeException($"Index {index} is out of range for Vector4.");
}
}
@@ -498,8 +498,13 @@ public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode()
public override readonly int GetHashCode()
{
throw new NotImplementedException();
var hash = new HashCode();
hash.Add(x);
hash.Add(y);
hash.Add(z);
hash.Add(w);
return hash.ToHashCode();
}
}

View File

@@ -3,7 +3,7 @@
private const string TLane = "TLane";
private const string TNumber = "TNumber";
private string TLaneRestrictions = $@"where {TLane} : ISPMD<{TLane}, {TNumber}>";
private string TLaneRestrictions = $@"where {TLane} : ISPMDLane<{TLane}, {TNumber}>";
private string TNumberRestrictions = $@"where {TNumber} : unmanaged, INumber<{TNumber}>, IBinaryNumber<{TNumber}>, IMinMaxValue<{TNumber}>, IBitwiseOperators<{TNumber}, {TNumber}, {TNumber}>";
private int[] dimensions = new int[] { 2, 3, 4 };
@@ -83,12 +83,12 @@ public unsafe struct {typeName} : IEquatable<{typeName}>
}}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional(""ENABLE_COLLECTION_CHECKS"")]
[Conditional(""MHP_ENABLE_SAFETY_CHECKS"")]
private static void RangeCheck(int index)
{{
if (index < 0 || index >= {dimension})
{{
throw new IndexOutOfRangeException($""Index {{index}} is out of range for Vector2."");
throw new IndexOutOfRangeException($""Index {{index}} is out of range for Vector{dimension}."");
}}
}}
@@ -418,9 +418,11 @@ public unsafe struct {typeName} : IEquatable<{typeName}>
}}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override int GetHashCode()
public override readonly int GetHashCode()
{{
throw new NotImplementedException();
var hash = new HashCode();
{ForEachDimension(dimension, 8, Environment.NewLine, (dim, sb) => sb.Append($"hash.Add({components[dim]});"))}
return hash.ToHashCode();
}}
}}");

View File

@@ -3,12 +3,12 @@ using System.Runtime.CompilerServices;
namespace Misaki.HighPerformance.Mathematics.SPMD;
public readonly unsafe partial struct WideLane<TNumber> : ISPMD<WideLane<TNumber>, TNumber>
public readonly unsafe partial struct WideLane<TNumber> : ISPMDLane<WideLane<TNumber>, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TOther Cast<TOther, TOtherNumber>()
where TOther : ISPMD<TOther, TOtherNumber>
where TOther : ISPMDLane<TOther, TOtherNumber>
where TOtherNumber : unmanaged, INumber<TOtherNumber>, IBinaryNumber<TOtherNumber>, IMinMaxValue<TOtherNumber>, IBitwiseOperators<TOtherNumber, TOtherNumber, TOtherNumber>
{
if (typeof(TNumber) == typeof(float) && typeof(TOtherNumber) == typeof(int))

View File

@@ -22,12 +22,12 @@ var conversions = new CastRoute[]
};
#>
public readonly unsafe partial struct WideLane<TNumber> : ISPMD<WideLane<TNumber>, TNumber>
public readonly unsafe partial struct WideLane<TNumber> : ISPMDLane<WideLane<TNumber>, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TOther Cast<TOther, TOtherNumber>()
where TOther : ISPMD<TOther, TOtherNumber>
where TOther : ISPMDLane<TOther, TOtherNumber>
where TOtherNumber : unmanaged, INumber<TOtherNumber>, IBinaryNumber<TOtherNumber>, IMinMaxValue<TOtherNumber>, IBitwiseOperators<TOtherNumber, TOtherNumber, TOtherNumber>
{
<# foreach (var c in conversions) { #>