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

@@ -5,7 +5,7 @@ namespace Misaki.HighPerformance.Mathematics.SPMD;
/// <summary> /// <summary>
/// Common marker interface for SPMD lane types. /// Common marker interface for SPMD lane types.
/// </summary> /// </summary>
public interface ISPMD public interface ISPMDLane
{ {
/// <summary> /// <summary>
/// Gets the number of lanes (vector width) for the SPMD implementation. /// Gets the number of lanes (vector width) for the SPMD implementation.
@@ -29,8 +29,8 @@ public interface ISPMD
/// </summary> /// </summary>
/// <typeparam name="TSelf">The concrete SPMD lane type implementing this interface.</typeparam> /// <typeparam name="TSelf">The concrete SPMD lane type implementing this interface.</typeparam>
/// <typeparam name="TNumber">The underlying numeric element type.</typeparam> /// <typeparam name="TNumber">The underlying numeric element type.</typeparam>
public interface ISPMD<TSelf, TNumber> : ISPMD, IEquatable<TSelf> public unsafe interface ISPMDLane<TSelf, TNumber> : ISPMDLane, IEquatable<TSelf>
where TSelf : ISPMD<TSelf, TNumber> where TSelf : ISPMDLane<TSelf, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
/// <summary> /// <summary>
@@ -116,7 +116,15 @@ public interface ISPMD<TSelf, TNumber> : ISPMD, IEquatable<TSelf>
/// <remarks> /// <remarks>
/// Unsafe pointer overloads are provided for scenarios where sequential lane data is already contiguous in memory. /// Unsafe pointer overloads are provided for scenarios where sequential lane data is already contiguous in memory.
/// </remarks> /// </remarks>
static abstract unsafe TSelf Load(TNumber* pValue); static abstract TSelf Load(TNumber* pValue);
static abstract TSelf MaskLoad(TSelf mask, ref TNumber value);
static abstract TSelf MaskLoad(TSelf mask, TNumber* pValue);
static abstract TSelf Gather(TNumber* pData, TSelf indices, int scale);
static abstract TSelf Gather(TNumber* pData, int* pIndices, int scale);
static abstract TSelf Gather(ref TNumber baseAddress, TSelf indices, int scale);
static abstract TSelf Gather(ref TNumber baseAddress, ref int baseIndex, int scale);
/// <summary> /// <summary>
/// Stores the lane value to the specified reference. /// Stores the lane value to the specified reference.
@@ -127,7 +135,7 @@ public interface ISPMD<TSelf, TNumber> : ISPMD, IEquatable<TSelf>
/// Stores the lane value to the specified pointer. /// Stores the lane value to the specified pointer.
/// </summary> /// </summary>
/// <param name="pDestination">The pointer to store to.</param> /// <param name="pDestination">The pointer to store to.</param>
unsafe void Store(TNumber* pDestination); void Store(TNumber* pDestination);
/// <summary> /// <summary>
/// Compresses the data specified by the given mask and stores the compressed result in the provided destination /// Compresses the data specified by the given mask and stores the compressed result in the provided destination
/// variable. /// variable.
@@ -149,7 +157,7 @@ public interface ISPMD<TSelf, TNumber> : ISPMD, IEquatable<TSelf>
/// <remarks> /// <remarks>
/// Implementations may use hardware-specific shuffle tables to reorder the selected lanes before storing, falling back to a scalar loop otherwise. /// Implementations may use hardware-specific shuffle tables to reorder the selected lanes before storing, falling back to a scalar loop otherwise.
/// </remarks> /// </remarks>
unsafe int CompressStore(TSelf mask, TNumber* pDestination); int CompressStore(TSelf mask, TNumber* pDestination);
/// <summary> /// <summary>
/// Converts the lane value to a vector. /// Converts the lane value to a vector.
@@ -157,6 +165,8 @@ public interface ISPMD<TSelf, TNumber> : ISPMD, IEquatable<TSelf>
/// <returns>The backing vector representation.</returns> /// <returns>The backing vector representation.</returns>
Vector<TNumber> AsVector(); Vector<TNumber> AsVector();
TNumber* GetUnsafePtr();
/// <summary> /// <summary>
/// Casts the lane value to another SPMD lane type with a different underlying numeric type. /// Casts the lane value to another SPMD lane type with a different underlying numeric type.
/// </summary> /// </summary>
@@ -164,7 +174,7 @@ public interface ISPMD<TSelf, TNumber> : ISPMD, IEquatable<TSelf>
/// <typeparam name="TOtherNumber">The underlying numeric type of the other SPMD lane.</typeparam> /// <typeparam name="TOtherNumber">The underlying numeric type of the other SPMD lane.</typeparam>
/// <returns>The casted lane value.</returns> /// <returns>The casted lane value.</returns>
TOther Cast<TOther, TOtherNumber>() 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>; where TOtherNumber : unmanaged, INumber<TOtherNumber>, IBinaryNumber<TOtherNumber>, IMinMaxValue<TOtherNumber>, IBitwiseOperators<TOtherNumber, TOtherNumber, TOtherNumber>;
/// <summary> /// <summary>
@@ -174,7 +184,7 @@ public interface ISPMD<TSelf, TNumber> : ISPMD, IEquatable<TSelf>
/// <typeparam name="TOtherNumber">The underlying numeric type of the other SPMD lane.</typeparam> /// <typeparam name="TOtherNumber">The underlying numeric type of the other SPMD lane.</typeparam>
/// <returns>The bit-cast lane value.</returns> /// <returns>The bit-cast lane value.</returns>
TOther BitCast<TOther, TOtherNumber>() TOther BitCast<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>; where TOtherNumber : unmanaged, INumber<TOtherNumber>, IBinaryNumber<TOtherNumber>, IMinMaxValue<TOtherNumber>, IBitwiseOperators<TOtherNumber, TOtherNumber, TOtherNumber>;
/// <summary> /// <summary>

View File

@@ -21,8 +21,8 @@ This package is intended for code that wants to express vectorized work in a way
## Main types ## Main types
- `ISPMD` - `ISPMDLane`
- `ISPMD<TSelf, TNumber>` - `ISPMDLane<TSelf, TNumber>`
- `ScalerLane` - `ScalerLane`
- `WideLane` - `WideLane`
- `IJobSPMD` - `IJobSPMD`

View File

@@ -5,7 +5,7 @@ using System.Runtime.InteropServices;
namespace Misaki.HighPerformance.Mathematics.SPMD; namespace Misaki.HighPerformance.Mathematics.SPMD;
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
public readonly unsafe struct ScalarLane<TNumber> : ISPMD<ScalarLane<TNumber>, TNumber> public readonly unsafe struct ScalarLane<TNumber> : ISPMDLane<ScalarLane<TNumber>, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
public readonly TNumber value; public readonly TNumber value;
@@ -19,25 +19,25 @@ public readonly unsafe struct ScalarLane<TNumber> : ISPMD<ScalarLane<TNumber>, T
public static ScalarLane<TNumber> Zero public static ScalarLane<TNumber> Zero
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new(TNumber.Zero); get => new ScalarLane<TNumber>(TNumber.Zero);
} }
public static ScalarLane<TNumber> One public static ScalarLane<TNumber> One
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new(TNumber.One); get => new ScalarLane<TNumber>(TNumber.One);
} }
public static ScalarLane<TNumber> MinValue public static ScalarLane<TNumber> MinValue
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new(TNumber.MinValue); get => new ScalarLane<TNumber>(TNumber.MinValue);
} }
public static ScalarLane<TNumber> MaxValue public static ScalarLane<TNumber> MaxValue
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new(TNumber.MaxValue); get => new ScalarLane<TNumber>(TNumber.MaxValue);
} }
public readonly TNumber this[int index] public readonly TNumber this[int index]
@@ -54,39 +54,76 @@ public readonly unsafe struct ScalarLane<TNumber> : ISPMD<ScalarLane<TNumber>, T
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Create(TNumber value) public static ScalarLane<TNumber> Create(TNumber value)
{ {
return new(value); return new ScalarLane<TNumber>(value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Create(params ReadOnlySpan<TNumber> values) public static ScalarLane<TNumber> Create(params ReadOnlySpan<TNumber> values)
{ {
return new(values[0]); return new ScalarLane<TNumber>(values[0]);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Create(Vector<TNumber> value) public static ScalarLane<TNumber> Create(Vector<TNumber> value)
{ {
return new(value[0]); return new ScalarLane<TNumber>(value[0]);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Sequence(TNumber start, TNumber step) public static ScalarLane<TNumber> Sequence(TNumber start, TNumber step)
{ {
return new(start); return new ScalarLane<TNumber>(start);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Load(ref TNumber value) public static ScalarLane<TNumber> Load(ref TNumber value)
{ {
return new(value); return new ScalarLane<TNumber>(value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Load(TNumber* pValue) public static ScalarLane<TNumber> Load(TNumber* pValue)
{ {
return new(*pValue); return new ScalarLane<TNumber>(*pValue);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> MaskLoad(ScalarLane<TNumber> mask, ref TNumber value)
{
return new ScalarLane<TNumber>(mask.value != TNumber.Zero ? value : TNumber.Zero);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> MaskLoad(ScalarLane<TNumber> mask, TNumber* pValue)
{
return new ScalarLane<TNumber>(mask.value != TNumber.Zero ? *pValue : TNumber.Zero);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Gather(TNumber* pData, ScalarLane<TNumber> indices, int scale)
{
return new ScalarLane<TNumber>(pData[int.CreateTruncating(indices.value) * scale / sizeof(TNumber)]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Gather(TNumber* pData, int* pIndices, int scale)
{
return new ScalarLane<TNumber>(pData[pIndices[0] * scale / sizeof(TNumber)]);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Gather(ref TNumber baseAddress, ScalarLane<TNumber> indices, int scale)
{
return new ScalarLane<TNumber>(Unsafe.Add(ref baseAddress, int.CreateTruncating(indices.value) * scale / sizeof(TNumber)));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Gather(ref TNumber baseAddress, ref int baseIndex, int scale)
{
return new ScalarLane<TNumber>(Unsafe.Add(ref baseAddress, int.CreateTruncating(baseIndex) * scale / sizeof(TNumber)));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly void Store(ref TNumber destination) public readonly void Store(ref TNumber destination)
{ {
@@ -123,9 +160,15 @@ public readonly unsafe struct ScalarLane<TNumber> : ISPMD<ScalarLane<TNumber>, T
return Vector.Create(value); return Vector.Create(value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly TNumber* GetUnsafePtr()
{
return (TNumber*)Unsafe.AsPointer(ref Unsafe.AsRef(in value));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public TOther Cast<TOther, TOtherNumber>() 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> where TOtherNumber : unmanaged, INumber<TOtherNumber>, IBinaryNumber<TOtherNumber>, IMinMaxValue<TOtherNumber>, IBitwiseOperators<TOtherNumber, TOtherNumber, TOtherNumber>
{ {
return TOther.Create(TOtherNumber.CreateChecked(value)); return TOther.Create(TOtherNumber.CreateChecked(value));
@@ -133,7 +176,7 @@ public readonly unsafe struct ScalarLane<TNumber> : ISPMD<ScalarLane<TNumber>, T
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public TOther BitCast<TOther, TOtherNumber>() public TOther BitCast<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> where TOtherNumber : unmanaged, INumber<TOtherNumber>, IBinaryNumber<TOtherNumber>, IMinMaxValue<TOtherNumber>, IBitwiseOperators<TOtherNumber, TOtherNumber, TOtherNumber>
{ {
return Unsafe.BitCast<ScalarLane<TNumber>, TOther>(this); return Unsafe.BitCast<ScalarLane<TNumber>, TOther>(this);
@@ -142,61 +185,61 @@ public readonly unsafe struct ScalarLane<TNumber> : ISPMD<ScalarLane<TNumber>, T
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> operator +(ScalarLane<TNumber> a, ScalarLane<TNumber> b) public static ScalarLane<TNumber> operator +(ScalarLane<TNumber> a, ScalarLane<TNumber> b)
{ {
return new(a.value + b.value); return new ScalarLane<TNumber>(a.value + b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> operator -(ScalarLane<TNumber> a, ScalarLane<TNumber> b) public static ScalarLane<TNumber> operator -(ScalarLane<TNumber> a, ScalarLane<TNumber> b)
{ {
return new(a.value - b.value); return new ScalarLane<TNumber>(a.value - b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> operator *(ScalarLane<TNumber> a, ScalarLane<TNumber> b) public static ScalarLane<TNumber> operator *(ScalarLane<TNumber> a, ScalarLane<TNumber> b)
{ {
return new(a.value * b.value); return new ScalarLane<TNumber>(a.value * b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> operator /(ScalarLane<TNumber> a, ScalarLane<TNumber> b) public static ScalarLane<TNumber> operator /(ScalarLane<TNumber> a, ScalarLane<TNumber> b)
{ {
return new(a.value / b.value); return new ScalarLane<TNumber>(a.value / b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> operator %(ScalarLane<TNumber> a, ScalarLane<TNumber> b) public static ScalarLane<TNumber> operator %(ScalarLane<TNumber> a, ScalarLane<TNumber> b)
{ {
return new(a.value % b.value); return new ScalarLane<TNumber>(a.value % b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> operator -(ScalarLane<TNumber> a) public static ScalarLane<TNumber> operator -(ScalarLane<TNumber> a)
{ {
return new(-a.value); return new ScalarLane<TNumber>(-a.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> operator &(ScalarLane<TNumber> a, ScalarLane<TNumber> b) public static ScalarLane<TNumber> operator &(ScalarLane<TNumber> a, ScalarLane<TNumber> b)
{ {
return new(a.value & b.value); return new ScalarLane<TNumber>(a.value & b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> operator |(ScalarLane<TNumber> a, ScalarLane<TNumber> b) public static ScalarLane<TNumber> operator |(ScalarLane<TNumber> a, ScalarLane<TNumber> b)
{ {
return new(a.value | b.value); return new ScalarLane<TNumber>(a.value | b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> operator ^(ScalarLane<TNumber> a, ScalarLane<TNumber> b) public static ScalarLane<TNumber> operator ^(ScalarLane<TNumber> a, ScalarLane<TNumber> b)
{ {
return new(a.value ^ b.value); return new ScalarLane<TNumber>(a.value ^ b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> operator ~(ScalarLane<TNumber> a) public static ScalarLane<TNumber> operator ~(ScalarLane<TNumber> a)
{ {
return new(~a.value); return new ScalarLane<TNumber>(~a.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -240,7 +283,7 @@ public readonly unsafe struct ScalarLane<TNumber> : ISPMD<ScalarLane<TNumber>, T
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static implicit operator ScalarLane<TNumber>(TNumber value) public static implicit operator ScalarLane<TNumber>(TNumber value)
{ {
return new(value); return new ScalarLane<TNumber>(value);
} }
@@ -248,7 +291,7 @@ public readonly unsafe struct ScalarLane<TNumber> : ISPMD<ScalarLane<TNumber>, T
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Abs(ScalarLane<TNumber> value) public static ScalarLane<TNumber> Abs(ScalarLane<TNumber> value)
{ {
return new(TNumber.Abs(value.value)); return new ScalarLane<TNumber>(TNumber.Abs(value.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -276,7 +319,7 @@ public readonly unsafe struct ScalarLane<TNumber> : ISPMD<ScalarLane<TNumber>, T
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Frac(ScalarLane<TNumber> value) public static ScalarLane<TNumber> Frac(ScalarLane<TNumber> value)
{ {
return new(value.value - TNumber.CreateTruncating(value.value)); return new ScalarLane<TNumber>(value.value - TNumber.CreateTruncating(value.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -301,37 +344,37 @@ public readonly unsafe struct ScalarLane<TNumber> : ISPMD<ScalarLane<TNumber>, T
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Lerp(ScalarLane<TNumber> a, ScalarLane<TNumber> b, ScalarLane<TNumber> t) public static ScalarLane<TNumber> Lerp(ScalarLane<TNumber> a, ScalarLane<TNumber> b, ScalarLane<TNumber> t)
{ {
return new(a.value + (b.value - a.value) * t.value); return new ScalarLane<TNumber>(a.value + (b.value - a.value) * t.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> MultipleAdd(ScalarLane<TNumber> a, ScalarLane<TNumber> b, ScalarLane<TNumber> c) public static ScalarLane<TNumber> MultipleAdd(ScalarLane<TNumber> a, ScalarLane<TNumber> b, ScalarLane<TNumber> c)
{ {
return new(TNumber.MultiplyAddEstimate(a.value, b.value, c.value)); return new ScalarLane<TNumber>(TNumber.MultiplyAddEstimate(a.value, b.value, c.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Min(ScalarLane<TNumber> a, ScalarLane<TNumber> b) public static ScalarLane<TNumber> Min(ScalarLane<TNumber> a, ScalarLane<TNumber> b)
{ {
return new(TNumber.Min(a.value, b.value)); return new ScalarLane<TNumber>(TNumber.Min(a.value, b.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Max(ScalarLane<TNumber> a, ScalarLane<TNumber> b) public static ScalarLane<TNumber> Max(ScalarLane<TNumber> a, ScalarLane<TNumber> b)
{ {
return new(TNumber.Max(a.value, b.value)); return new ScalarLane<TNumber>(TNumber.Max(a.value, b.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Clamp(ScalarLane<TNumber> value, ScalarLane<TNumber> min, ScalarLane<TNumber> max) public static ScalarLane<TNumber> Clamp(ScalarLane<TNumber> value, ScalarLane<TNumber> min, ScalarLane<TNumber> max)
{ {
return new(TNumber.Clamp(value.value, min.value, max.value)); return new ScalarLane<TNumber>(TNumber.Clamp(value.value, min.value, max.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Saturate(ScalarLane<TNumber> value) public static ScalarLane<TNumber> Saturate(ScalarLane<TNumber> value)
{ {
return Clamp(value, new(TNumber.Zero), new(TNumber.One)); return Clamp(value, new ScalarLane<TNumber>(TNumber.Zero), new ScalarLane<TNumber>(TNumber.One));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -638,19 +681,19 @@ public readonly unsafe struct ScalarLane<TNumber> : ISPMD<ScalarLane<TNumber>, T
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Sign(ScalarLane<TNumber> value) public static ScalarLane<TNumber> Sign(ScalarLane<TNumber> value)
{ {
return new((value.value > TNumber.Zero) ? TNumber.One : (value.value < TNumber.Zero) ? ~TNumber.Zero : TNumber.Zero); return new ScalarLane<TNumber>((value.value > TNumber.Zero) ? TNumber.One : (value.value < TNumber.Zero) ? ~TNumber.Zero : TNumber.Zero);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> CopySign(ScalarLane<TNumber> magnitude, ScalarLane<TNumber> sign) public static ScalarLane<TNumber> CopySign(ScalarLane<TNumber> magnitude, ScalarLane<TNumber> sign)
{ {
return new(TNumber.CopySign(magnitude.value, sign.value)); return new ScalarLane<TNumber>(TNumber.CopySign(magnitude.value, sign.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Rcp(ScalarLane<TNumber> value) public static ScalarLane<TNumber> Rcp(ScalarLane<TNumber> value)
{ {
return new(TNumber.One / value.value); return new ScalarLane<TNumber>(TNumber.One / value.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -662,37 +705,37 @@ public readonly unsafe struct ScalarLane<TNumber> : ISPMD<ScalarLane<TNumber>, T
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Select(ScalarLane<TNumber> conditionMask, ScalarLane<TNumber> ifTrue, ScalarLane<TNumber> ifFalse) public static ScalarLane<TNumber> Select(ScalarLane<TNumber> conditionMask, ScalarLane<TNumber> ifTrue, ScalarLane<TNumber> ifFalse)
{ {
return new(conditionMask.value != TNumber.Zero ? ifTrue.value : ifFalse.value); return new ScalarLane<TNumber>(conditionMask.value != TNumber.Zero ? ifTrue.value : ifFalse.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> GreaterThan(ScalarLane<TNumber> a, ScalarLane<TNumber> b) public static ScalarLane<TNumber> GreaterThan(ScalarLane<TNumber> a, ScalarLane<TNumber> b)
{ {
return new(a.value > b.value ? ~TNumber.Zero : TNumber.Zero); return new ScalarLane<TNumber>(a.value > b.value ? ~TNumber.Zero : TNumber.Zero);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> GreaterThanOrEqual(ScalarLane<TNumber> a, ScalarLane<TNumber> b) public static ScalarLane<TNumber> GreaterThanOrEqual(ScalarLane<TNumber> a, ScalarLane<TNumber> b)
{ {
return new(a.value >= b.value ? ~TNumber.Zero : TNumber.Zero); return new ScalarLane<TNumber>(a.value >= b.value ? ~TNumber.Zero : TNumber.Zero);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> LessThan(ScalarLane<TNumber> a, ScalarLane<TNumber> b) public static ScalarLane<TNumber> LessThan(ScalarLane<TNumber> a, ScalarLane<TNumber> b)
{ {
return new(a.value < b.value ? ~TNumber.Zero : TNumber.Zero); return new ScalarLane<TNumber>(a.value < b.value ? ~TNumber.Zero : TNumber.Zero);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> LessThanOrEqual(ScalarLane<TNumber> a, ScalarLane<TNumber> b) public static ScalarLane<TNumber> LessThanOrEqual(ScalarLane<TNumber> a, ScalarLane<TNumber> b)
{ {
return new(a.value <= b.value ? ~TNumber.Zero : TNumber.Zero); return new ScalarLane<TNumber>(a.value <= b.value ? ~TNumber.Zero : TNumber.Zero);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static ScalarLane<TNumber> Equal(ScalarLane<TNumber> a, ScalarLane<TNumber> b) public static ScalarLane<TNumber> Equal(ScalarLane<TNumber> a, ScalarLane<TNumber> b)
{ {
return new(a.value == b.value ? ~TNumber.Zero : TNumber.Zero); return new ScalarLane<TNumber>(a.value == b.value ? ~TNumber.Zero : TNumber.Zero);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]

View File

@@ -14,7 +14,7 @@ public interface IJobSPMD<TNumber0>
where TNumber0 : unmanaged, INumber<TNumber0>, IBinaryNumber<TNumber0>, IMinMaxValue<TNumber0>, IBitwiseOperators<TNumber0, TNumber0, TNumber0> where TNumber0 : unmanaged, INumber<TNumber0>, IBinaryNumber<TNumber0>, IMinMaxValue<TNumber0>, IBitwiseOperators<TNumber0, TNumber0, TNumber0>
{ {
void Execute<TLane0>(int baseIndex, ref readonly JobExecutionContext ctx) 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 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> where TNumber1 : unmanaged, INumber<TNumber1>, IBinaryNumber<TNumber1>, IMinMaxValue<TNumber1>, IBitwiseOperators<TNumber1, TNumber1, TNumber1>
{ {
void Execute<TLane0, TLane1>(int baseIndex, ref readonly JobExecutionContext ctx) void Execute<TLane0, TLane1>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane0 : unmanaged, ISPMD<TLane0, TNumber0> where TLane0 : unmanaged, ISPMDLane<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMD<TLane1, TNumber1>; where TLane1 : unmanaged, ISPMDLane<TLane1, TNumber1>;
} }
internal struct SPMDJobWrapper<T, TNumber0, TNumber1> : IJobParallelFor 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> where TNumber2 : unmanaged, INumber<TNumber2>, IBinaryNumber<TNumber2>, IMinMaxValue<TNumber2>, IBitwiseOperators<TNumber2, TNumber2, TNumber2>
{ {
void Execute<TLane0, TLane1, TLane2>(int baseIndex, ref readonly JobExecutionContext ctx) void Execute<TLane0, TLane1, TLane2>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane0 : unmanaged, ISPMD<TLane0, TNumber0> where TLane0 : unmanaged, ISPMDLane<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMD<TLane1, TNumber1> where TLane1 : unmanaged, ISPMDLane<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMD<TLane2, TNumber2>; where TLane2 : unmanaged, ISPMDLane<TLane2, TNumber2>;
} }
internal struct SPMDJobWrapper<T, TNumber0, TNumber1, TNumber2> : IJobParallelFor 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> 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) void Execute<TLane0, TLane1, TLane2, TLane3>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane0 : unmanaged, ISPMD<TLane0, TNumber0> where TLane0 : unmanaged, ISPMDLane<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMD<TLane1, TNumber1> where TLane1 : unmanaged, ISPMDLane<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMD<TLane2, TNumber2> where TLane2 : unmanaged, ISPMDLane<TLane2, TNumber2>
where TLane3 : unmanaged, ISPMD<TLane3, TNumber3>; where TLane3 : unmanaged, ISPMDLane<TLane3, TNumber3>;
} }
internal struct SPMDJobWrapper<T, TNumber0, TNumber1, TNumber2, TNumber3> : IJobParallelFor 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> 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) void Execute<TLane0, TLane1, TLane2, TLane3, TLane4>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane0 : unmanaged, ISPMD<TLane0, TNumber0> where TLane0 : unmanaged, ISPMDLane<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMD<TLane1, TNumber1> where TLane1 : unmanaged, ISPMDLane<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMD<TLane2, TNumber2> where TLane2 : unmanaged, ISPMDLane<TLane2, TNumber2>
where TLane3 : unmanaged, ISPMD<TLane3, TNumber3> where TLane3 : unmanaged, ISPMDLane<TLane3, TNumber3>
where TLane4 : unmanaged, ISPMD<TLane4, TNumber4>; where TLane4 : unmanaged, ISPMDLane<TLane4, TNumber4>;
} }
internal struct SPMDJobWrapper<T, TNumber0, TNumber1, TNumber2, TNumber3, TNumber4> : IJobParallelFor 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> 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) void Execute<TLane0, TLane1, TLane2, TLane3, TLane4, TLane5>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane0 : unmanaged, ISPMD<TLane0, TNumber0> where TLane0 : unmanaged, ISPMDLane<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMD<TLane1, TNumber1> where TLane1 : unmanaged, ISPMDLane<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMD<TLane2, TNumber2> where TLane2 : unmanaged, ISPMDLane<TLane2, TNumber2>
where TLane3 : unmanaged, ISPMD<TLane3, TNumber3> where TLane3 : unmanaged, ISPMDLane<TLane3, TNumber3>
where TLane4 : unmanaged, ISPMD<TLane4, TNumber4> where TLane4 : unmanaged, ISPMDLane<TLane4, TNumber4>
where TLane5 : unmanaged, ISPMD<TLane5, TNumber5>; where TLane5 : unmanaged, ISPMDLane<TLane5, TNumber5>;
} }
internal struct SPMDJobWrapper<T, TNumber0, TNumber1, TNumber2, TNumber3, TNumber4, TNumber5> : IJobParallelFor 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> 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) void Execute<TLane0, TLane1, TLane2, TLane3, TLane4, TLane5, TLane6>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane0 : unmanaged, ISPMD<TLane0, TNumber0> where TLane0 : unmanaged, ISPMDLane<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMD<TLane1, TNumber1> where TLane1 : unmanaged, ISPMDLane<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMD<TLane2, TNumber2> where TLane2 : unmanaged, ISPMDLane<TLane2, TNumber2>
where TLane3 : unmanaged, ISPMD<TLane3, TNumber3> where TLane3 : unmanaged, ISPMDLane<TLane3, TNumber3>
where TLane4 : unmanaged, ISPMD<TLane4, TNumber4> where TLane4 : unmanaged, ISPMDLane<TLane4, TNumber4>
where TLane5 : unmanaged, ISPMD<TLane5, TNumber5> where TLane5 : unmanaged, ISPMDLane<TLane5, TNumber5>
where TLane6 : unmanaged, ISPMD<TLane6, TNumber6>; where TLane6 : unmanaged, ISPMDLane<TLane6, TNumber6>;
} }
internal struct SPMDJobWrapper<T, TNumber0, TNumber1, TNumber2, TNumber3, TNumber4, TNumber5, TNumber6> : IJobParallelFor 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> 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) void Execute<TLane0, TLane1, TLane2, TLane3, TLane4, TLane5, TLane6, TLane7>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane0 : unmanaged, ISPMD<TLane0, TNumber0> where TLane0 : unmanaged, ISPMDLane<TLane0, TNumber0>
where TLane1 : unmanaged, ISPMD<TLane1, TNumber1> where TLane1 : unmanaged, ISPMDLane<TLane1, TNumber1>
where TLane2 : unmanaged, ISPMD<TLane2, TNumber2> where TLane2 : unmanaged, ISPMDLane<TLane2, TNumber2>
where TLane3 : unmanaged, ISPMD<TLane3, TNumber3> where TLane3 : unmanaged, ISPMDLane<TLane3, TNumber3>
where TLane4 : unmanaged, ISPMD<TLane4, TNumber4> where TLane4 : unmanaged, ISPMDLane<TLane4, TNumber4>
where TLane5 : unmanaged, ISPMD<TLane5, TNumber5> where TLane5 : unmanaged, ISPMDLane<TLane5, TNumber5>
where TLane6 : unmanaged, ISPMD<TLane6, TNumber6> where TLane6 : unmanaged, ISPMDLane<TLane6, TNumber6>
where TLane7 : unmanaged, ISPMD<TLane7, TNumber7>; where TLane7 : unmanaged, ISPMDLane<TLane7, TNumber7>;
} }
internal struct SPMDJobWrapper<T, TNumber0, TNumber1, TNumber2, TNumber3, TNumber4, TNumber5, TNumber6, TNumber7> : IJobParallelFor 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 TNumber = "TNumber";
const string GenericParameters = $"{TLane}, {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}>"; var TNumberRestrictions = $@"where {TNumber} : unmanaged, INumber<{TNumber}>, IBinaryNumber<{TNumber}>, IMinMaxValue<{TNumber}>, IBitwiseOperators<{TNumber}, {TNumber}, {TNumber}>";
for (var i = 0; i < 8; i++) { #> for (var i = 0; i < 8; i++) { #>
@@ -192,7 +192,7 @@ public string GetTLaneRestrictions(int dimension, string space = " ")
var sb = new StringBuilder(); var sb = new StringBuilder();
for (var i = 0; i < dimension; i++) 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) if (i < dimension - 1)
{ {
sb.AppendLine(); sb.AppendLine();

View File

@@ -11,13 +11,13 @@ namespace Misaki.HighPerformance.Mathematics.SPMD;
public static unsafe partial class MathV public static unsafe partial class MathV
{ {
#region Vector2 # region Vector2
// Creation Functions // Creation Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Create<TLane, TNumber>(in TLane x, in TLane y) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector2<TLane, TNumber> return new Vector2<TLane, TNumber>
@@ -29,7 +29,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> CreateVector2<TLane, TNumber>(in TLane value) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector2<TLane, TNumber> return new Vector2<TLane, TNumber>
@@ -41,7 +41,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> LoadVector2<TLane, TNumber>(TNumber* pSrc) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
var width = TLane.LaneWidth; var width = TLane.LaneWidth;
@@ -64,7 +64,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> LoadVector2<TLane, TNumber>(ref TNumber src) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return LoadVector2<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref src)); return LoadVector2<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref src));
@@ -72,7 +72,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Load<TLane, TNumber>(TNumber* px, TNumber* py) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector2<TLane, TNumber> return new Vector2<TLane, TNumber>
@@ -84,7 +84,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Load<TLane, TNumber>(ref TNumber x, ref TNumber y) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector2<TLane, 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 // Math Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Abs<TLane, TNumber>(in Vector2<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector2<TLane, TNumber> return new Vector2<TLane, TNumber>
@@ -110,7 +192,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Dot<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return a.x * b.x + a.y * b.y; return a.x * b.x + a.y * b.y;
@@ -118,7 +200,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Sqrt<TLane, TNumber>(in Vector2<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector2<TLane, TNumber> return new Vector2<TLane, TNumber>
@@ -130,7 +212,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Rsqrt<TLane, TNumber>(in Vector2<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector2<TLane, TNumber> return new Vector2<TLane, TNumber>
@@ -142,7 +224,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Normalize<TLane, TNumber>(in Vector2<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return vector * TLane.Rsqrt(Dot(vector, vector)); return vector * TLane.Rsqrt(Dot(vector, vector));
@@ -150,7 +232,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Reflect<TLane, TNumber>(in Vector2<TLane, TNumber> incident, in Vector2<TLane, TNumber> normal) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
var dot = Dot(incident, normal); var dot = Dot(incident, normal);
@@ -159,7 +241,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Min<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector2<TLane, TNumber> return new Vector2<TLane, TNumber>
@@ -171,7 +253,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Max<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector2<TLane, TNumber> return new Vector2<TLane, TNumber>
@@ -183,7 +265,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return Min(Max(value, min), max); return Min(Max(value, min), max);
@@ -191,7 +273,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Saturate<TLane, TNumber>(in Vector2<TLane, TNumber> value) 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> 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)); 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)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Lerp<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b, TLane t) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return a + (b - a) * t; return a + (b - a) * t;
@@ -207,15 +289,15 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Length<TLane, TNumber>(in Vector2<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return TLane.Sqrt(Dot(vector, vector)); return TLane.Sqrt(Dot(vector, vector));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane LengthSquared<TLane, TNumber>(in Vector2<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return Dot(vector, vector); return Dot(vector, vector);
@@ -223,7 +305,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Distance<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
var diff = b - a; var diff = b - a;
@@ -232,7 +314,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane DistanceSquared<TLane, TNumber>(in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
var diff = b - a; var diff = b - a;
@@ -241,7 +323,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Step<TLane, TNumber>(in Vector2<TLane, TNumber> edge, in Vector2<TLane, TNumber> value) 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> 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); 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)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Smoothstep<TLane, TNumber>(Vector2<TLane, TNumber> xMin, Vector2<TLane, TNumber> xMax, Vector2<TLane, TNumber> x) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
var t = Saturate((x - xMin) / (xMax - xMin)); var t = Saturate((x - xMin) / (xMax - xMin));
@@ -261,7 +343,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector2<TLane, TNumber> Select<TLane, TNumber>(TLane condition, in Vector2<TLane, TNumber> a, in Vector2<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector2<TLane, TNumber> return new Vector2<TLane, TNumber>
@@ -273,7 +355,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector2<TLane, TNumber> return new Vector2<TLane, TNumber>
@@ -283,15 +365,15 @@ public static unsafe partial class MathV
}; };
} }
#endregion # endregion
#region Vector3 # region Vector3
// Creation Functions // Creation Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Create<TLane, TNumber>(in TLane x, in TLane y, in TLane z) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector3<TLane, TNumber> return new Vector3<TLane, TNumber>
@@ -304,7 +386,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> CreateVector3<TLane, TNumber>(in TLane value) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector3<TLane, TNumber> return new Vector3<TLane, TNumber>
@@ -317,7 +399,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> LoadVector3<TLane, TNumber>(TNumber* pSrc) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
var width = TLane.LaneWidth; var width = TLane.LaneWidth;
@@ -343,7 +425,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> LoadVector3<TLane, TNumber>(ref TNumber src) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return LoadVector3<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref src)); return LoadVector3<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref src));
@@ -351,7 +433,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Load<TLane, TNumber>(TNumber* px, TNumber* py, TNumber* pz) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector3<TLane, TNumber> return new Vector3<TLane, TNumber>
@@ -364,7 +446,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Load<TLane, TNumber>(ref TNumber x, ref TNumber y, ref TNumber z) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector3<TLane, 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 // Math Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Abs<TLane, TNumber>(in Vector3<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector3<TLane, TNumber> return new Vector3<TLane, TNumber>
@@ -392,7 +564,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Dot<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b) 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> 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; 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)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Sqrt<TLane, TNumber>(in Vector3<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector3<TLane, TNumber> return new Vector3<TLane, TNumber>
@@ -413,7 +585,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Rsqrt<TLane, TNumber>(in Vector3<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector3<TLane, TNumber> return new Vector3<TLane, TNumber>
@@ -426,7 +598,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Normalize<TLane, TNumber>(in Vector3<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return vector * TLane.Rsqrt(Dot(vector, vector)); return vector * TLane.Rsqrt(Dot(vector, vector));
@@ -434,7 +606,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Reflect<TLane, TNumber>(in Vector3<TLane, TNumber> incident, in Vector3<TLane, TNumber> normal) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
var dot = Dot(incident, normal); var dot = Dot(incident, normal);
@@ -443,7 +615,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Min<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector3<TLane, TNumber> return new Vector3<TLane, TNumber>
@@ -456,7 +628,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Max<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector3<TLane, TNumber> return new Vector3<TLane, TNumber>
@@ -469,7 +641,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return Min(Max(value, min), max); return Min(Max(value, min), max);
@@ -477,7 +649,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Saturate<TLane, TNumber>(in Vector3<TLane, TNumber> value) 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> 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)); 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)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Lerp<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b, TLane t) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return a + (b - a) * t; return a + (b - a) * t;
@@ -493,15 +665,15 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Length<TLane, TNumber>(in Vector3<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return TLane.Sqrt(Dot(vector, vector)); return TLane.Sqrt(Dot(vector, vector));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane LengthSquared<TLane, TNumber>(in Vector3<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return Dot(vector, vector); return Dot(vector, vector);
@@ -509,7 +681,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Distance<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
var diff = b - a; var diff = b - a;
@@ -518,7 +690,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane DistanceSquared<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
var diff = b - a; var diff = b - a;
@@ -527,7 +699,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Step<TLane, TNumber>(in Vector3<TLane, TNumber> edge, in Vector3<TLane, TNumber> value) 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> 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); 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)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Smoothstep<TLane, TNumber>(Vector3<TLane, TNumber> xMin, Vector3<TLane, TNumber> xMax, Vector3<TLane, TNumber> x) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
var t = Saturate((x - xMin) / (xMax - xMin)); var t = Saturate((x - xMin) / (xMax - xMin));
@@ -547,7 +719,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Select<TLane, TNumber>(TLane condition, in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector3<TLane, TNumber> return new Vector3<TLane, TNumber>
@@ -560,7 +732,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector3<TLane, TNumber> return new Vector3<TLane, TNumber>
@@ -571,15 +743,15 @@ public static unsafe partial class MathV
}; };
} }
#endregion # endregion
#region Vector4 # region Vector4
// Creation Functions // Creation Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Create<TLane, TNumber>(in TLane x, in TLane y, in TLane z, in TLane w) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector4<TLane, TNumber> return new Vector4<TLane, TNumber>
@@ -593,7 +765,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> CreateVector4<TLane, TNumber>(in TLane value) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector4<TLane, TNumber> return new Vector4<TLane, TNumber>
@@ -607,7 +779,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> LoadVector4<TLane, TNumber>(TNumber* pSrc) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
var width = TLane.LaneWidth; var width = TLane.LaneWidth;
@@ -636,7 +808,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> LoadVector4<TLane, TNumber>(ref TNumber src) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return LoadVector4<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref src)); return LoadVector4<TLane, TNumber>((TNumber*)Unsafe.AsPointer(ref src));
@@ -644,7 +816,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Load<TLane, TNumber>(TNumber* px, TNumber* py, TNumber* pz, TNumber* pw) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector4<TLane, TNumber> return new Vector4<TLane, TNumber>
@@ -658,7 +830,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Load<TLane, TNumber>(ref TNumber x, ref TNumber y, ref TNumber z, ref TNumber w) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector4<TLane, 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 // Math Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Abs<TLane, TNumber>(in Vector4<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector4<TLane, TNumber> return new Vector4<TLane, TNumber>
@@ -688,7 +958,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Dot<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b) 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> 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; 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)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Sqrt<TLane, TNumber>(in Vector4<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector4<TLane, TNumber> return new Vector4<TLane, TNumber>
@@ -710,7 +980,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Rsqrt<TLane, TNumber>(in Vector4<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector4<TLane, TNumber> return new Vector4<TLane, TNumber>
@@ -724,7 +994,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Normalize<TLane, TNumber>(in Vector4<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return vector * TLane.Rsqrt(Dot(vector, vector)); return vector * TLane.Rsqrt(Dot(vector, vector));
@@ -732,7 +1002,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Reflect<TLane, TNumber>(in Vector4<TLane, TNumber> incident, in Vector4<TLane, TNumber> normal) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
var dot = Dot(incident, normal); var dot = Dot(incident, normal);
@@ -741,7 +1011,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Min<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector4<TLane, TNumber> return new Vector4<TLane, TNumber>
@@ -755,7 +1025,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Max<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector4<TLane, TNumber> return new Vector4<TLane, TNumber>
@@ -769,7 +1039,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return Min(Max(value, min), max); return Min(Max(value, min), max);
@@ -777,7 +1047,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Saturate<TLane, TNumber>(in Vector4<TLane, TNumber> value) 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> 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)); 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)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Lerp<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b, TLane t) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return a + (b - a) * t; return a + (b - a) * t;
@@ -793,15 +1063,15 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Length<TLane, TNumber>(in Vector4<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return TLane.Sqrt(Dot(vector, vector)); return TLane.Sqrt(Dot(vector, vector));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane LengthSquared<TLane, TNumber>(in Vector4<TLane, TNumber> vector) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return Dot(vector, vector); return Dot(vector, vector);
@@ -809,7 +1079,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane Distance<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
var diff = b - a; var diff = b - a;
@@ -818,7 +1088,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static TLane DistanceSquared<TLane, TNumber>(in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
var diff = b - a; var diff = b - a;
@@ -827,7 +1097,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Step<TLane, TNumber>(in Vector4<TLane, TNumber> edge, in Vector4<TLane, TNumber> value) 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> 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); 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)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Smoothstep<TLane, TNumber>(Vector4<TLane, TNumber> xMin, Vector4<TLane, TNumber> xMax, Vector4<TLane, TNumber> x) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
var t = Saturate((x - xMin) / (xMax - xMin)); var t = Saturate((x - xMin) / (xMax - xMin));
@@ -847,7 +1117,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector4<TLane, TNumber> Select<TLane, TNumber>(TLane condition, in Vector4<TLane, TNumber> a, in Vector4<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector4<TLane, TNumber> return new Vector4<TLane, TNumber>
@@ -861,7 +1131,7 @@ public static unsafe partial class MathV
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector4<TLane, 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)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static Vector3<TLane, TNumber> Cross<TLane, TNumber>(in Vector3<TLane, TNumber> a, in Vector3<TLane, TNumber> b) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
return new Vector3<TLane, 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 dimensions = new int[] { 2, 3, 4 };
var components = new char[] { 'x', 'y', 'z', 'w' }; 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}>"; 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 // Creation Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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 #> <#= TLaneRestrictions #>
<#= TNumberRestrictions #> <#= TNumberRestrictions #>
{ {
@@ -48,7 +48,7 @@ public static unsafe partial class MathV
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static <#= vectorType #> CreateVector<#= dimension #><<#= GenericParameters #>>(in TLane value) public static <#= vectorType #> CreateVector<#= dimension #><<#= GenericParameters #>>(in <#= TLane #> value)
<#= TLaneRestrictions #> <#= TLaneRestrictions #>
<#= TNumberRestrictions #> <#= TNumberRestrictions #>
{ {
@@ -61,14 +61,14 @@ public static unsafe partial class MathV
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static <#= vectorType #> LoadVector<#= dimension #><<#= GenericParameters #>>(TNumber* pSrc) public static <#= vectorType #> LoadVector<#= dimension #><<#= GenericParameters #>>(<#= TNumber #>* pSrc)
<#= TLaneRestrictions #> <#= TLaneRestrictions #>
<#= TNumberRestrictions #> <#= TNumberRestrictions #>
{ {
var width = TLane.LaneWidth; var width = TLane.LaneWidth;
<# for (int i = 0; i < dimension; i++) { #> <# 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++) for (var i = 0; i < width; i++)
@@ -87,11 +87,11 @@ public static unsafe partial class MathV
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static <#= vectorType #> LoadVector<#= dimension #><<#= GenericParameters #>>(ref TNumber src) public static <#= vectorType #> LoadVector<#= dimension #><<#= GenericParameters #>>(ref <#= TNumber #> src)
<#= TLaneRestrictions #> <#= TLaneRestrictions #>
<#= TNumberRestrictions #> <#= TNumberRestrictions #>
{ {
return LoadVector<#= dimension #><<#= GenericParameters #>>((TNumber*)Unsafe.AsPointer(ref src)); return LoadVector<#= dimension #><<#= GenericParameters #>>((<#= TNumber #>*)Unsafe.AsPointer(ref src));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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 // Math Functions
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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 #> <#= TLaneRestrictions #>
<#= TNumberRestrictions #> <#= TNumberRestrictions #>
{ {

View File

@@ -6,7 +6,7 @@ using System.Runtime.CompilerServices;
namespace Misaki.HighPerformance.Mathematics.SPMD; namespace Misaki.HighPerformance.Mathematics.SPMD;
public unsafe struct Vector2<TLane, TNumber> : IEquatable<Vector2<TLane, TNumber>> 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
public TLane x; public TLane x;
@@ -49,7 +49,7 @@ public unsafe struct Vector2<TLane, TNumber> : IEquatable<Vector2<TLane, TNumber
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_COLLECTION_CHECKS")] [Conditional("MHP_ENABLE_SAFETY_CHECKS")]
private static void RangeCheck(int index) private static void RangeCheck(int index)
{ {
if (index < 0 || index >= 2) if (index < 0 || index >= 2)
@@ -420,8 +420,11 @@ public unsafe struct Vector2<TLane, TNumber> : IEquatable<Vector2<TLane, TNumber
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [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; namespace Misaki.HighPerformance.Mathematics.SPMD;
public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber>> 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
public TLane x; public TLane x;
@@ -52,12 +52,12 @@ public unsafe struct Vector3<TLane, TNumber> : IEquatable<Vector3<TLane, TNumber
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_COLLECTION_CHECKS")] [Conditional("MHP_ENABLE_SAFETY_CHECKS")]
private static void RangeCheck(int index) private static void RangeCheck(int index)
{ {
if (index < 0 || index >= 3) 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)] [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; namespace Misaki.HighPerformance.Mathematics.SPMD;
public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber>> 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
public TLane x; public TLane x;
@@ -55,12 +55,12 @@ public unsafe struct Vector4<TLane, TNumber> : IEquatable<Vector4<TLane, TNumber
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional("ENABLE_COLLECTION_CHECKS")] [Conditional("MHP_ENABLE_SAFETY_CHECKS")]
private static void RangeCheck(int index) private static void RangeCheck(int index)
{ {
if (index < 0 || index >= 4) 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)] [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 TLane = "TLane";
private const string TNumber = "TNumber"; 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 string TNumberRestrictions = $@"where {TNumber} : unmanaged, INumber<{TNumber}>, IBinaryNumber<{TNumber}>, IMinMaxValue<{TNumber}>, IBitwiseOperators<{TNumber}, {TNumber}, {TNumber}>";
private int[] dimensions = new int[] { 2, 3, 4 }; private int[] dimensions = new int[] { 2, 3, 4 };
@@ -83,12 +83,12 @@ public unsafe struct {typeName} : IEquatable<{typeName}>
}} }}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
[Conditional(""ENABLE_COLLECTION_CHECKS"")] [Conditional(""MHP_ENABLE_SAFETY_CHECKS"")]
private static void RangeCheck(int index) private static void RangeCheck(int index)
{{ {{
if (index < 0 || index >= {dimension}) 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)] [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; 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public TOther Cast<TOther, TOtherNumber>() 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> where TOtherNumber : unmanaged, INumber<TOtherNumber>, IBinaryNumber<TOtherNumber>, IMinMaxValue<TOtherNumber>, IBitwiseOperators<TOtherNumber, TOtherNumber, TOtherNumber>
{ {
if (typeof(TNumber) == typeof(float) && typeof(TOtherNumber) == typeof(int)) 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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public TOther Cast<TOther, TOtherNumber>() 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> where TOtherNumber : unmanaged, INumber<TOtherNumber>, IBinaryNumber<TOtherNumber>, IMinMaxValue<TOtherNumber>, IBitwiseOperators<TOtherNumber, TOtherNumber, TOtherNumber>
{ {
<# foreach (var c in conversions) { #> <# foreach (var c in conversions) { #>

View File

@@ -32,7 +32,7 @@ public static unsafe class WideLane
} }
[StructLayout(LayoutKind.Sequential)] [StructLayout(LayoutKind.Sequential)]
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> where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{ {
private static readonly Vector<TNumber> s_indices; private static readonly Vector<TNumber> s_indices;
@@ -48,13 +48,13 @@ public readonly unsafe partial struct WideLane<TNumber> : ISPMD<WideLane<TNumber
public static WideLane<TNumber> Zero public static WideLane<TNumber> Zero
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new(Vector<TNumber>.Zero); get => new WideLane<TNumber>(Vector<TNumber>.Zero);
} }
public static WideLane<TNumber> One public static WideLane<TNumber> One
{ {
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
get => new(Vector<TNumber>.One); get => new WideLane<TNumber>(Vector<TNumber>.One);
} }
public static WideLane<TNumber> MinValue public static WideLane<TNumber> MinValue
@@ -134,39 +134,102 @@ public readonly unsafe partial struct WideLane<TNumber> : ISPMD<WideLane<TNumber
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Create(TNumber value) public static WideLane<TNumber> Create(TNumber value)
{ {
return new(Vector.Create(value)); return new WideLane<TNumber>(Vector.Create(value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Create(params ReadOnlySpan<TNumber> values) public static WideLane<TNumber> Create(params ReadOnlySpan<TNumber> values)
{ {
return new(Vector.Create(values)); return new WideLane<TNumber>(Vector.Create(values));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Create(Vector<TNumber> value) public static WideLane<TNumber> Create(Vector<TNumber> value)
{ {
return new(value); return new WideLane<TNumber>(value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Sequence(TNumber start, TNumber step) public static WideLane<TNumber> Sequence(TNumber start, TNumber step)
{ {
return new(Vector.Create(start) + (Vector.Create(step) * s_indices)); return new WideLane<TNumber>(Vector.Create(start) + (Vector.Create(step) * s_indices));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Load(ref TNumber value) public static WideLane<TNumber> Load(ref TNumber value)
{ {
return new(Vector.LoadUnsafe(ref value)); return new WideLane<TNumber>(Vector.LoadUnsafe(ref value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Load(TNumber* pValue) public static WideLane<TNumber> Load(TNumber* pValue)
{ {
return new(Vector.Load(pValue)); return new WideLane<TNumber>(Vector.Load(pValue));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> MaskLoad(WideLane<TNumber> mask, ref TNumber value)
{
return MaskLoad(mask, (TNumber*)Unsafe.AsPointer(ref value));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> MaskLoad(WideLane<TNumber> mask, TNumber* pValue)
{
var vector = Vector.Load(pValue);
return new WideLane<TNumber>(Vector.ConditionalSelect(mask.value, vector, Vector<TNumber>.Zero));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Gather(TNumber* pData, WideLane<TNumber> indices, int scale)
{
var buffer = stackalloc TNumber[LaneWidth];
for (var i = 0; i < LaneWidth; i++)
{
buffer[i] = pData[int.CreateTruncating(indices[i]) * scale / sizeof(TNumber)];
}
return new WideLane<TNumber>(Vector.Load(buffer));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Gather(TNumber* pData, int* pIndices, int scale)
{
var buffer = stackalloc TNumber[LaneWidth];
for (var i = 0; i < LaneWidth; i++)
{
buffer[i] = pData[pIndices[i] * scale / sizeof(TNumber)];
}
return new WideLane<TNumber>(Vector.Load(buffer));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Gather(ref TNumber baseAddress, WideLane<TNumber> indices, int scale)
{
var buffer = stackalloc TNumber[LaneWidth];
for (var i = 0; i < LaneWidth; i++)
{
buffer[i] = Unsafe.Add(ref baseAddress, int.CreateTruncating(indices[i]) * scale / sizeof(TNumber));
}
return new WideLane<TNumber>(Vector.Load(buffer));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Gather(ref TNumber baseAddress, ref int baseIndex, int scale)
{
var buffer = stackalloc TNumber[LaneWidth];
for (var i = 0; i < LaneWidth; i++)
{
buffer[i] = Unsafe.Add(ref baseAddress, Unsafe.Add(ref baseIndex, i) * scale / sizeof(TNumber));
}
return new WideLane<TNumber>(Vector.Load(buffer));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly void Store(ref TNumber destination) public readonly void Store(ref TNumber destination)
{ {
@@ -301,9 +364,15 @@ public readonly unsafe partial struct WideLane<TNumber> : ISPMD<WideLane<TNumber
return value; return value;
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public readonly TNumber* GetUnsafePtr()
{
return (TNumber*)Unsafe.AsPointer(ref Unsafe.AsRef(in value));
}
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public TOther BitCast<TOther, TOtherNumber>() public TOther BitCast<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> where TOtherNumber : unmanaged, INumber<TOtherNumber>, IBinaryNumber<TOtherNumber>, IMinMaxValue<TOtherNumber>, IBitwiseOperators<TOtherNumber, TOtherNumber, TOtherNumber>
{ {
return Unsafe.BitCast<WideLane<TNumber>, TOther>(this); return Unsafe.BitCast<WideLane<TNumber>, TOther>(this);
@@ -313,61 +382,61 @@ public readonly unsafe partial struct WideLane<TNumber> : ISPMD<WideLane<TNumber
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> operator +(WideLane<TNumber> a, WideLane<TNumber> b) public static WideLane<TNumber> operator +(WideLane<TNumber> a, WideLane<TNumber> b)
{ {
return new(a.value + b.value); return new WideLane<TNumber>(a.value + b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> operator -(WideLane<TNumber> a, WideLane<TNumber> b) public static WideLane<TNumber> operator -(WideLane<TNumber> a, WideLane<TNumber> b)
{ {
return new(a.value - b.value); return new WideLane<TNumber>(a.value - b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> operator *(WideLane<TNumber> a, WideLane<TNumber> b) public static WideLane<TNumber> operator *(WideLane<TNumber> a, WideLane<TNumber> b)
{ {
return new(a.value * b.value); return new WideLane<TNumber>(a.value * b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> operator /(WideLane<TNumber> a, WideLane<TNumber> b) public static WideLane<TNumber> operator /(WideLane<TNumber> a, WideLane<TNumber> b)
{ {
return new(a.value / b.value); return new WideLane<TNumber>(a.value / b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> operator %(WideLane<TNumber> a, WideLane<TNumber> b) public static WideLane<TNumber> operator %(WideLane<TNumber> a, WideLane<TNumber> b)
{ {
return new(a.value - VectorFloor(a.value / b.value) * b.value); return new WideLane<TNumber>(a.value - VectorFloor(a.value / b.value) * b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> operator -(WideLane<TNumber> a) public static WideLane<TNumber> operator -(WideLane<TNumber> a)
{ {
return new(-a.value); return new WideLane<TNumber>(-a.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> operator &(WideLane<TNumber> a, WideLane<TNumber> b) public static WideLane<TNumber> operator &(WideLane<TNumber> a, WideLane<TNumber> b)
{ {
return new(a.value & b.value); return new WideLane<TNumber>(a.value & b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> operator |(WideLane<TNumber> a, WideLane<TNumber> b) public static WideLane<TNumber> operator |(WideLane<TNumber> a, WideLane<TNumber> b)
{ {
return new(a.value | b.value); return new WideLane<TNumber>(a.value | b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> operator ^(WideLane<TNumber> a, WideLane<TNumber> b) public static WideLane<TNumber> operator ^(WideLane<TNumber> a, WideLane<TNumber> b)
{ {
return new(a.value ^ b.value); return new WideLane<TNumber>(a.value ^ b.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> operator ~(WideLane<TNumber> a) public static WideLane<TNumber> operator ~(WideLane<TNumber> a)
{ {
return new(~a.value); return new WideLane<TNumber>(~a.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -417,7 +486,7 @@ public readonly unsafe partial struct WideLane<TNumber> : ISPMD<WideLane<TNumber
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Abs(WideLane<TNumber> value) public static WideLane<TNumber> Abs(WideLane<TNumber> value)
{ {
return new(Vector.Abs(value.value)); return new WideLane<TNumber>(Vector.Abs(value.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -442,19 +511,19 @@ public readonly unsafe partial struct WideLane<TNumber> : ISPMD<WideLane<TNumber
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Frac(WideLane<TNumber> value) public static WideLane<TNumber> Frac(WideLane<TNumber> value)
{ {
return new(value.value - VectorFloor(value.value)); return new WideLane<TNumber>(value.value - VectorFloor(value.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Sqrt(WideLane<TNumber> value) public static WideLane<TNumber> Sqrt(WideLane<TNumber> value)
{ {
return new(Vector.SquareRoot(value.value)); return new WideLane<TNumber>(Vector.SquareRoot(value.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Lerp(WideLane<TNumber> a, WideLane<TNumber> b, WideLane<TNumber> t) public static WideLane<TNumber> Lerp(WideLane<TNumber> a, WideLane<TNumber> b, WideLane<TNumber> t)
{ {
return new(a.value + (b.value - a.value) * t.value); return new WideLane<TNumber>(a.value + (b.value - a.value) * t.value);
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -478,26 +547,26 @@ public readonly unsafe partial struct WideLane<TNumber> : ISPMD<WideLane<TNumber
} }
else else
{ {
return new((a.value * b.value) + c.value); return new WideLane<TNumber>((a.value * b.value) + c.value);
} }
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Min(WideLane<TNumber> a, WideLane<TNumber> b) public static WideLane<TNumber> Min(WideLane<TNumber> a, WideLane<TNumber> b)
{ {
return new(Vector.Min(a.value, b.value)); return new WideLane<TNumber>(Vector.Min(a.value, b.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Max(WideLane<TNumber> a, WideLane<TNumber> b) public static WideLane<TNumber> Max(WideLane<TNumber> a, WideLane<TNumber> b)
{ {
return new(Vector.Max(a.value, b.value)); return new WideLane<TNumber>(Vector.Max(a.value, b.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Clamp(WideLane<TNumber> value, WideLane<TNumber> min, WideLane<TNumber> max) public static WideLane<TNumber> Clamp(WideLane<TNumber> value, WideLane<TNumber> min, WideLane<TNumber> max)
{ {
return new(Vector.Clamp(value.value, min.value, max.value)); return new WideLane<TNumber>(Vector.Clamp(value.value, min.value, max.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -826,7 +895,7 @@ public readonly unsafe partial struct WideLane<TNumber> : ISPMD<WideLane<TNumber
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> CopySign(WideLane<TNumber> magnitude, WideLane<TNumber> sign) public static WideLane<TNumber> CopySign(WideLane<TNumber> magnitude, WideLane<TNumber> sign)
{ {
return new(Vector.CopySign(magnitude.value, sign.value)); return new WideLane<TNumber>(Vector.CopySign(magnitude.value, sign.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -878,7 +947,7 @@ public readonly unsafe partial struct WideLane<TNumber> : ISPMD<WideLane<TNumber
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Select(WideLane<TNumber> conditionMask, WideLane<TNumber> ifTrue, WideLane<TNumber> ifFalse) public static WideLane<TNumber> Select(WideLane<TNumber> conditionMask, WideLane<TNumber> ifTrue, WideLane<TNumber> ifFalse)
{ {
return new(Vector.ConditionalSelect( return new WideLane<TNumber>(Vector.ConditionalSelect(
conditionMask.value, conditionMask.value,
ifTrue.value, ifTrue.value,
ifFalse.value)); ifFalse.value));
@@ -887,31 +956,31 @@ public readonly unsafe partial struct WideLane<TNumber> : ISPMD<WideLane<TNumber
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> GreaterThan(WideLane<TNumber> a, WideLane<TNumber> b) public static WideLane<TNumber> GreaterThan(WideLane<TNumber> a, WideLane<TNumber> b)
{ {
return new(Vector.GreaterThan(a.value, b.value)); return new WideLane<TNumber>(Vector.GreaterThan(a.value, b.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> GreaterThanOrEqual(WideLane<TNumber> a, WideLane<TNumber> b) public static WideLane<TNumber> GreaterThanOrEqual(WideLane<TNumber> a, WideLane<TNumber> b)
{ {
return new(Vector.GreaterThanOrEqual(a.value, b.value)); return new WideLane<TNumber>(Vector.GreaterThanOrEqual(a.value, b.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> LessThan(WideLane<TNumber> a, WideLane<TNumber> b) public static WideLane<TNumber> LessThan(WideLane<TNumber> a, WideLane<TNumber> b)
{ {
return new(Vector.LessThan(a.value, b.value)); return new WideLane<TNumber>(Vector.LessThan(a.value, b.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> LessThanOrEqual(WideLane<TNumber> a, WideLane<TNumber> b) public static WideLane<TNumber> LessThanOrEqual(WideLane<TNumber> a, WideLane<TNumber> b)
{ {
return new(Vector.LessThanOrEqual(a.value, b.value)); return new WideLane<TNumber>(Vector.LessThanOrEqual(a.value, b.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static WideLane<TNumber> Equal(WideLane<TNumber> a, WideLane<TNumber> b) public static WideLane<TNumber> Equal(WideLane<TNumber> a, WideLane<TNumber> b)
{ {
return new(Vector.Equals(a.value, b.value)); return new WideLane<TNumber>(Vector.Equals(a.value, b.value));
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]

View File

@@ -1,4 +1,4 @@
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using static Misaki.HighPerformance.Mathematics.math; using static Misaki.HighPerformance.Mathematics.math;
@@ -711,53 +711,53 @@ public struct random
return t; return t;
} }
[Conditional("ENABLE_COLLECTION_CHECKS")] [Conditional("MHP_ENABLE_SAFETY_CHECKS")]
private void CheckInitState() private void CheckInitState()
{ {
#if ENABLE_COLLECTION_CHECKS #if MHP_ENABLE_SAFETY_CHECKS
if (state == 0) if (state == 0)
throw new System.ArgumentException("Seed must be non-zero"); throw new System.ArgumentException("Seed must be non-zero");
#endif #endif
} }
[Conditional("ENABLE_COLLECTION_CHECKS")] [Conditional("MHP_ENABLE_SAFETY_CHECKS")]
private static void CheckIndexForHash(uint index) private static void CheckIndexForHash(uint index)
{ {
if (index == uint.MaxValue) if (index == uint.MaxValue)
throw new System.ArgumentException("Index must not be uint.MaxValue"); throw new System.ArgumentException("Index must not be uint.MaxValue");
} }
[Conditional("ENABLE_COLLECTION_CHECKS")] [Conditional("MHP_ENABLE_SAFETY_CHECKS")]
private void CheckState() private void CheckState()
{ {
#if ENABLE_COLLECTION_CHECKS #if MHP_ENABLE_SAFETY_CHECKS
if(state == 0) if(state == 0)
throw new System.ArgumentException("Invalid state 0. Random object has not been properly initialized"); throw new System.ArgumentException("Invalid state 0. Random object has not been properly initialized");
#endif #endif
} }
[Conditional("ENABLE_COLLECTION_CHECKS")] [Conditional("MHP_ENABLE_SAFETY_CHECKS")]
private void CheckNextIntMax(int max) private void CheckNextIntMax(int max)
{ {
#if ENABLE_COLLECTION_CHECKS #if MHP_ENABLE_SAFETY_CHECKS
if (max < 0) if (max < 0)
throw new System.ArgumentException("max must be positive"); throw new System.ArgumentException("max must be positive");
#endif #endif
} }
[Conditional("ENABLE_COLLECTION_CHECKS")] [Conditional("MHP_ENABLE_SAFETY_CHECKS")]
private void CheckNextIntMinMax(int min, int max) private void CheckNextIntMinMax(int min, int max)
{ {
#if ENABLE_COLLECTION_CHECKS #if MHP_ENABLE_SAFETY_CHECKS
if (min > max) if (min > max)
throw new System.ArgumentException("min must be less than or equal to max"); throw new System.ArgumentException("min must be less than or equal to max");
#endif #endif
} }
[Conditional("ENABLE_COLLECTION_CHECKS")] [Conditional("MHP_ENABLE_SAFETY_CHECKS")]
private void CheckNextUIntMinMax(uint min, uint max) private void CheckNextUIntMinMax(uint min, uint max)
{ {
#if ENABLE_COLLECTION_CHECKS #if MHP_ENABLE_SAFETY_CHECKS
if (min > max) if (min > max)
throw new System.ArgumentException("min must be less than or equal to max"); throw new System.ArgumentException("min must be less than or equal to max");
#endif #endif

View File

@@ -20,8 +20,8 @@ internal unsafe struct MipLevel
} }
internal unsafe struct GGXMipGenerationJobSPMD<TFloat, TInt> : IJobParallelFor internal unsafe struct GGXMipGenerationJobSPMD<TFloat, TInt> : IJobParallelFor
where TFloat : unmanaged, ISPMD<TFloat, float> where TFloat : unmanaged, ISPMDLane<TFloat, float>
where TInt : unmanaged, ISPMD<TInt, int> where TInt : unmanaged, ISPMDLane<TInt, int>
{ {
public const uint SAMPLE_COUNT = 1024u; public const uint SAMPLE_COUNT = 1024u;
@@ -104,34 +104,12 @@ internal unsafe struct GGXMipGenerationJobSPMD<TFloat, TInt> : IJobParallelFor
var py = (uv.y * (h - 1.0f)).Cast<TInt, int>(); var py = (uv.y * (h - 1.0f)).Cast<TInt, int>();
// Clamp // Clamp
px = TInt.Clamp(px, TInt.Zero, TInt.Create(w - 1)); px = TInt.Clamp(px, TInt.Zero, w - 1);
py = TInt.Clamp(py, TInt.Zero, TInt.Create(h - 1)); py = TInt.Clamp(py, TInt.Zero, h - 1);
// Assuming float RGB array format // Assuming float RGB array format
var idx = (py * w + px) * 3; var idx = (py * w + px) * 3;
return MathV.GatherVector3<TFloat, float>(img, idx.GetUnsafePtr(), 1);
var laneWidth = TFloat.LaneWidth;
var rBuffer = stackalloc float[laneWidth];
var gBuffer = stackalloc float[laneWidth];
var bBuffer = stackalloc float[laneWidth];
// Gather operation: extract scalar indices, perform random memory reads, and construct SoA buffers
for (var i = 0; i < laneWidth; i++)
{
var scalarIdx = idx[i];
rBuffer[i] = img[scalarIdx];
gBuffer[i] = img[scalarIdx + 1];
bBuffer[i] = img[scalarIdx + 2];
}
// Load the gathered contiguous arrays back into TLane types
var rLane = TFloat.Load(rBuffer);
var gLane = TFloat.Load(gBuffer);
var bLane = TFloat.Load(bBuffer);
return MathV.Create<TFloat, float>(rLane, gLane, bLane);
} }
public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) public void Execute(int loopIndex, ref readonly JobExecutionContext ctx)
@@ -179,9 +157,10 @@ internal unsafe struct GGXMipGenerationJobSPMD<TFloat, TInt> : IJobParallelFor
TFloat.Create(V.z) TFloat.Create(V.z)
); );
var vPrefilteredColorX = TFloat.Zero; //var vPrefilteredColorX = TFloat.Zero;
var vPrefilteredColorY = TFloat.Zero; //var vPrefilteredColorY = TFloat.Zero;
var vPrefilteredColorZ = TFloat.Zero; //var vPrefilteredColorZ = TFloat.Zero;
var vPrefilteredColor = Vector3<TFloat, float>.Zero;
var vTotalWeight = TFloat.Zero; var vTotalWeight = TFloat.Zero;
// 3. Monte Carlo Integration Loop // 3. Monte Carlo Integration Loop
@@ -219,10 +198,7 @@ internal unsafe struct GGXMipGenerationJobSPMD<TFloat, TInt> : IJobParallelFor
var fireflyWeight = TFloat.One / (TFloat.One + luma); var fireflyWeight = TFloat.One / (TFloat.One + luma);
var finalWeight = NdotL * fireflyWeight; var finalWeight = NdotL * fireflyWeight;
vPrefilteredColorX += sampleColor.x * finalWeight; vPrefilteredColor += sampleColor * finalWeight;
vPrefilteredColorY += sampleColor.y * finalWeight;
vPrefilteredColorZ += sampleColor.z * finalWeight;
vTotalWeight += finalWeight; vTotalWeight += finalWeight;
} }
@@ -231,9 +207,9 @@ internal unsafe struct GGXMipGenerationJobSPMD<TFloat, TInt> : IJobParallelFor
for (var i = 0; i < TFloat.LaneWidth; i++) for (var i = 0; i < TFloat.LaneWidth; i++)
{ {
prefilteredColor.x += vPrefilteredColorX[i]; prefilteredColor.x += vPrefilteredColor.x[i];
prefilteredColor.y += vPrefilteredColorY[i]; prefilteredColor.y += vPrefilteredColor.y[i];
prefilteredColor.z += vPrefilteredColorZ[i]; prefilteredColor.z += vPrefilteredColor.z[i];
totalWeight += vTotalWeight[i]; totalWeight += vTotalWeight[i];
} }

View File

@@ -239,7 +239,7 @@ internal unsafe struct NoiseJobMathSPMD : IJobSPMD<float>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
private static T GradDot<T>(T ix, T iy, T fx, T fy) private static T GradDot<T>(T ix, T iy, T fx, T fy)
where T : unmanaged, ISPMD<T, float> where T : unmanaged, ISPMDLane<T, float>
{ {
var c289 = T.Create(289f); var c289 = T.Create(289f);
var c34 = T.Create(34f); var c34 = T.Create(34f);
@@ -267,7 +267,7 @@ internal unsafe struct NoiseJobMathSPMD : IJobSPMD<float>
[MethodImpl(MethodImplOptions.AggressiveInlining)] [MethodImpl(MethodImplOptions.AggressiveInlining)]
public static T Noise<T>(T uvX, T uvY) public static T Noise<T>(T uvX, T uvY)
where T : unmanaged, ISPMD<T, float> where T : unmanaged, ISPMDLane<T, float>
{ {
var c1 = T.Create(1f); var c1 = T.Create(1f);
var c6 = T.Create(6f); var c6 = T.Create(6f);
@@ -292,7 +292,7 @@ internal unsafe struct NoiseJobMathSPMD : IJobSPMD<float>
} }
public readonly void Execute<TLane>(int baseIndex, ref readonly JobExecutionContext ctx) public readonly void Execute<TLane>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane : unmanaged, ISPMD<TLane, float> where TLane : unmanaged, ISPMDLane<TLane, float>
{ {
var indices = TLane.Sequence(baseIndex, 1f); var indices = TLane.Sequence(baseIndex, 1f);
var w = TLane.Create(width); var w = TLane.Create(width);

View File

@@ -13,7 +13,7 @@ internal unsafe struct DotProductJob : IJobSPMD<float>
public float* results; // output array (dot products) public float* results; // output array (dot products)
public readonly void Execute<TLane>(int baseIndex, ref readonly JobExecutionContext ctx) public readonly void Execute<TLane>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane : unmanaged, ISPMD<TLane, float> where TLane : unmanaged, ISPMDLane<TLane, float>
{ {
var vecA = MathV.LoadVector3<TLane, float>((float*)(arrayA + baseIndex)); var vecA = MathV.LoadVector3<TLane, float>((float*)(arrayA + baseIndex));
var vecB = MathV.LoadVector3<TLane, float>((float*)(arrayB + baseIndex)); var vecB = MathV.LoadVector3<TLane, float>((float*)(arrayB + baseIndex));
@@ -30,7 +30,7 @@ internal unsafe struct Vector2LerpJob : IJobSPMD<float>
public float[] results; public float[] results;
public readonly void Execute<TLane>(int baseIndex, ref readonly JobExecutionContext ctx) public readonly void Execute<TLane>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane : unmanaged, ISPMD<TLane, float> where TLane : unmanaged, ISPMDLane<TLane, float>
{ {
var a = MathV.LoadVector2<TLane, float>(ref arrayA[baseIndex].x); var a = MathV.LoadVector2<TLane, float>(ref arrayA[baseIndex].x);
var b = MathV.LoadVector2<TLane, float>(ref arrayB[baseIndex].x); var b = MathV.LoadVector2<TLane, float>(ref arrayB[baseIndex].x);
@@ -49,7 +49,7 @@ internal unsafe struct Vector4NormalizeJob : IJobSPMD<float>
public float4[] output; public float4[] output;
public readonly void Execute<TLane>(int baseIndex, ref readonly JobExecutionContext ctx) public readonly void Execute<TLane>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane : unmanaged, ISPMD<TLane, float> where TLane : unmanaged, ISPMDLane<TLane, float>
{ {
var vec = MathV.LoadVector4<TLane, float>(ref input[baseIndex].x); var vec = MathV.LoadVector4<TLane, float>(ref input[baseIndex].x);
var normalized = MathV.Normalize(vec); var normalized = MathV.Normalize(vec);
@@ -64,7 +64,7 @@ internal unsafe struct Vector3CrossJob : IJobSPMD<float>
public float3[] results; public float3[] results;
public readonly void Execute<TLane>(int baseIndex, ref readonly JobExecutionContext ctx) public readonly void Execute<TLane>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane : unmanaged, ISPMD<TLane, float> where TLane : unmanaged, ISPMDLane<TLane, float>
{ {
var a = MathV.LoadVector3<TLane, float>(ref arrayA[baseIndex].x); var a = MathV.LoadVector3<TLane, float>(ref arrayA[baseIndex].x);
var b = MathV.LoadVector3<TLane, float>(ref arrayB[baseIndex].x); var b = MathV.LoadVector3<TLane, float>(ref arrayB[baseIndex].x);
@@ -82,7 +82,7 @@ internal unsafe struct MinMaxClampJob : IJobSPMD<float>
public float3[] results; public float3[] results;
public readonly void Execute<TLane>(int baseIndex, ref readonly JobExecutionContext ctx) public readonly void Execute<TLane>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane : unmanaged, ISPMD<TLane, float> where TLane : unmanaged, ISPMDLane<TLane, float>
{ {
var val = MathV.LoadVector3<TLane, float>(ref values[baseIndex].x); var val = MathV.LoadVector3<TLane, float>(ref values[baseIndex].x);
var min = MathV.LoadVector3<TLane, float>(ref mins[baseIndex].x); var min = MathV.LoadVector3<TLane, float>(ref mins[baseIndex].x);
@@ -100,7 +100,7 @@ internal unsafe struct DistanceJob : IJobSPMD<float>
public float[] results; public float[] results;
public readonly void Execute<TLane>(int baseIndex, ref readonly JobExecutionContext ctx) public readonly void Execute<TLane>(int baseIndex, ref readonly JobExecutionContext ctx)
where TLane : unmanaged, ISPMD<TLane, float> where TLane : unmanaged, ISPMDLane<TLane, float>
{ {
var a = MathV.LoadVector3<TLane, float>(ref arrayA[baseIndex].x); var a = MathV.LoadVector3<TLane, float>(ref arrayA[baseIndex].x);
var b = MathV.LoadVector3<TLane, float>(ref arrayB[baseIndex].x); var b = MathV.LoadVector3<TLane, float>(ref arrayB[baseIndex].x);