SPMD API overhaul: gather/scatter, job & packaging updates
- ISPMDLane: add MaskGather, MaskStore, Scatter, MaskScatter; update MaskLoad/Gather signatures for hardware parity - WideLane/ScalarLane: implement new methods with HW/fallback logic - MathV: gather/mask-gather now delegate to lane methods - Vector2/3/4: add CompressStore, Scatter, MaskScatter - SPMD jobs/tests/README: migrate to new APIs for correctness - Use Unsafe.BitCast instead of Unsafe.As/AsRef - Add SPMDUtility for gather index extraction - Job system: add ICustomJob<TSelf>, ScheduleCustom overload - FreeList concurrency obsolete; always thread-safe - NuGet: include LICENSE/README, set license/readme in .csproj - Docs: update SPMD usage, clarify safety notes - Minor: doc fixes, CompressStore test improvements
This commit is contained in:
@@ -67,22 +67,10 @@ public static unsafe partial class MathV
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
Unsafe.SkipInit(out TLane <#= components[i] #>);
|
||||
var p<#= components[i] #> = (<#= TNumber #>*)&<#= components[i] #>;
|
||||
<# } #>
|
||||
|
||||
for (var i = 0; i < TLane.LaneWidth; i++)
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
p<#= components[i] #>[i] = pSrc[i * <#= dimension #> + <#= i #>];
|
||||
<# } #>
|
||||
}
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = <#= components[i] #>,
|
||||
<#= components[i] #> = <#= TLane #>.Load(pSrc + <#= i #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
@@ -95,6 +83,27 @@ public static unsafe partial class MathV
|
||||
return LoadVector<#= dimension #><<#= GenericParameters #>>((<#= TNumber #>*)Unsafe.AsPointer(ref src));
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> MaskLoadVector<#= dimension #><<#= GenericParameters #>>(<#= TNumber #>* pSrc, <#= TLane #> mask)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = <#= TLane #>.MaskLoad(pSrc + <#= i #>, mask),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> MaskLoadVector<#= dimension #><<#= GenericParameters #>>(ref <#= TNumber #> src, <#= TLane #> mask)
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
return MaskLoadVector<#= dimension #><<#= GenericParameters #>>((<#= TNumber #>*)Unsafe.AsPointer(ref src), mask);
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public static <#= vectorType #> Load<<#= GenericParameters #>>(<#= ForEachDimension(dimension, i => $"TNumber* p{components[i]}") #>)
|
||||
<#= TLaneRestrictions #>
|
||||
@@ -127,108 +136,10 @@ public static unsafe partial class MathV
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
if (Avx2.IsSupported)
|
||||
{
|
||||
if (TLane.LaneWidth == Vector128<TNumber>.Count)
|
||||
{
|
||||
if (sizeof(TNumber) == sizeof(uint))
|
||||
{
|
||||
ref var v = ref Unsafe.As<TLane, Vector128<TNumber>>(ref indices);
|
||||
var vidx = v.AsInt32();
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherVector128((uint*)(pData + <#= i #>), vidx, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector128<uint>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
if (sizeof(TNumber) == sizeof(ulong))
|
||||
{
|
||||
ref var v = ref Unsafe.As<TLane, Vector128<TNumber>>(ref indices);
|
||||
var vidx = v.AsInt64();
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherVector128((ulong*)(pData + <#= i #>), vidx, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector128<ulong>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (TLane.LaneWidth == Vector256<TNumber>.Count)
|
||||
{
|
||||
if (sizeof(TNumber) == sizeof(uint))
|
||||
{
|
||||
ref var v = ref Unsafe.As<TLane, Vector256<TNumber>>(ref indices);
|
||||
var vidx = v.AsInt32();
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherVector256((uint*)(pData + <#= i #>), vidx, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector256<uint>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
if (sizeof(TNumber) == sizeof(ulong))
|
||||
{
|
||||
ref var v = ref Unsafe.As<TLane, Vector256<TNumber>>(ref indices);
|
||||
var vidx = v.AsInt64();
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherVector256((ulong*)(pData + <#= i #>), vidx, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector256<ulong>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
Unsafe.SkipInit(out TLane <#= components[i] #>);
|
||||
var p<#= components[i] #> = (<#= TNumber #>*)&<#= components[i] #>;
|
||||
<# } #>
|
||||
|
||||
for (var i = 0; i < TLane.LaneWidth; i++)
|
||||
{
|
||||
var scalarIdx = int.CreateTruncating(indices[i]);
|
||||
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
p<#= components[i] #>[i] = *(TNumber*)((byte*)pData + ((scalarIdx + <#= i #>) * scale));
|
||||
<# } #>
|
||||
}
|
||||
|
||||
return new Vector<#= dimension #><TLane, TNumber>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = <#= components[i] #>,
|
||||
<#= components[i] #> = <#= TLane #>.Gather(pData + <#= i #>, indices, scale),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
@@ -238,104 +149,10 @@ public static unsafe partial class MathV
|
||||
<#= TLaneRestrictions #>
|
||||
<#= TNumberRestrictions #>
|
||||
{
|
||||
if (Avx2.IsSupported)
|
||||
{
|
||||
if (TLane.LaneWidth == Vector128<TNumber>.Count)
|
||||
{
|
||||
if (sizeof(TNumber) == sizeof(uint))
|
||||
{
|
||||
var vidx = Vector128.Load(pIndices);
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherVector128((uint*)(pData + <#= i #>), vidx, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector128<uint>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
if (sizeof(TNumber) == sizeof(ulong))
|
||||
{
|
||||
var vidx = Vector128.Load(pIndices);
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherVector128((ulong*)(pData + <#= i #>), vidx, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector128<ulong>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (TLane.LaneWidth == Vector256<TNumber>.Count)
|
||||
{
|
||||
if (sizeof(TNumber) == sizeof(uint))
|
||||
{
|
||||
var vidx = Vector256.Load(pIndices);
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherVector256((uint*)(pData + <#= i #>), vidx, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector256<uint>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
if (sizeof(TNumber) == sizeof(ulong))
|
||||
{
|
||||
var vidx = Vector128.Load(pIndices);
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherVector256((ulong*)(pData + <#= i #>), vidx, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector256<ulong>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
Unsafe.SkipInit(out TLane <#= components[i] #>);
|
||||
var p<#= components[i] #> = (<#= TNumber #>*)&<#= components[i] #>;
|
||||
<# } #>
|
||||
|
||||
for (var i = 0; i < TLane.LaneWidth; i++)
|
||||
{
|
||||
var scalerIdx = pIndices[i];
|
||||
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
p<#= components[i] #>[i] = *(TNumber*)((byte*)pData + ((scalerIdx + <#= i #>) * scale));
|
||||
<# } #>
|
||||
}
|
||||
|
||||
return new Vector<#= dimension #><TLane, TNumber>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = <#= components[i] #>,
|
||||
<#= components[i] #> = <#= TLane #>.Gather(pData + <#= i #>, pIndices, scale),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
@@ -361,113 +178,10 @@ public static unsafe partial class MathV
|
||||
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
if (Avx2.IsSupported)
|
||||
{
|
||||
if (TLane.LaneWidth == Vector128<TNumber>.Count)
|
||||
{
|
||||
if (sizeof(TNumber) == sizeof(uint))
|
||||
{
|
||||
ref var vidx = ref Unsafe.As<TLane, Vector128<int>>(ref indices);
|
||||
ref var vmask = ref Unsafe.As<TLane, Vector128<uint>>(ref mask);
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherMaskVector128(Vector128<uint>.Zero, (uint*)(pData + <#= i #>), vidx, vmask, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector128<uint>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
if (sizeof(TNumber) == sizeof(ulong))
|
||||
{
|
||||
ref var vidx = ref Unsafe.As<TLane, Vector128<int>>(ref indices);
|
||||
var vmask = Unsafe.As<TLane, Vector128<ulong>>(ref mask);
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherMaskVector128(Vector128<ulong>.Zero, (ulong*)(pData + <#= i #>), vidx, vmask, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector128<ulong>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (TLane.LaneWidth == Vector256<TNumber>.Count)
|
||||
{
|
||||
if (sizeof(TNumber) == sizeof(uint))
|
||||
{
|
||||
ref var vidx = ref Unsafe.As<TLane, Vector256<int>>(ref indices);
|
||||
var vmask = Unsafe.As<TLane, Vector256<uint>>(ref mask);
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherMaskVector256(Vector256<uint>.Zero, (uint*)(pData + <#= i #>), vidx, vmask, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector256<uint>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
if (sizeof(TNumber) == sizeof(ulong))
|
||||
{
|
||||
ref var vidx = ref Unsafe.As<TLane, Vector128<int>>(ref indices);
|
||||
var vmask = Unsafe.As<TLane, Vector256<ulong>>(ref mask);
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherMaskVector256(Vector256<ulong>.Zero, (ulong*)(pData + <#= i #>), vidx, vmask, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector256<ulong>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
Unsafe.SkipInit(out TLane <#= components[i] #>);
|
||||
var p<#= components[i] #> = (<#= TNumber #>*)&<#= components[i] #>;
|
||||
<# } #>
|
||||
|
||||
for (var i = 0; i < TLane.LaneWidth; i++)
|
||||
{
|
||||
if (mask[i] == TNumber.Zero)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var scalerIdx = int.CreateTruncating(indices[i]);
|
||||
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
p<#= components[i] #>[i] = *(TNumber*)((byte*)pData + ((scalerIdx + <#= i #>) * scale));
|
||||
<# } #>
|
||||
}
|
||||
|
||||
return new Vector<#= dimension #><TLane, TNumber>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = <#= components[i] #>,
|
||||
<#= components[i] #> = <#= TLane #>.MaskGather(pData + <#= i #>, indices, mask, scale),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
@@ -477,113 +191,10 @@ public static unsafe partial class MathV
|
||||
where TLane : unmanaged, ISPMDLane<TLane, TNumber>
|
||||
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
|
||||
{
|
||||
if (Avx2.IsSupported)
|
||||
{
|
||||
if (TLane.LaneWidth == Vector128<TNumber>.Count)
|
||||
{
|
||||
if (sizeof(TNumber) == sizeof(uint))
|
||||
{
|
||||
var vidx = Vector128.Load(pIndices);
|
||||
ref var vmask = ref Unsafe.As<TLane, Vector128<uint>>(ref mask);
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherMaskVector128(Vector128<uint>.Zero, (uint*)(pData + <#= i #>), vidx, vmask, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector128<uint>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
if (sizeof(TNumber) == sizeof(ulong))
|
||||
{
|
||||
var vidx = Vector128.Load(pIndices);
|
||||
var vmask = Unsafe.As<TLane, Vector128<ulong>>(ref mask);
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherMaskVector128(Vector128<ulong>.Zero, (ulong*)(pData + <#= i #>), vidx, vmask, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector128<ulong>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
}
|
||||
else if (TLane.LaneWidth == Vector256<TNumber>.Count)
|
||||
{
|
||||
if (sizeof(TNumber) == sizeof(uint))
|
||||
{
|
||||
var vidx = Vector256.Load(pIndices);
|
||||
var vmask = Unsafe.As<TLane, Vector256<uint>>(ref mask);
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherMaskVector256(Vector256<uint>.Zero, (uint*)(pData + <#= i #>), vidx, vmask, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector256<uint>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
if (sizeof(TNumber) == sizeof(ulong))
|
||||
{
|
||||
var vidx = Vector128.Load(pIndices);
|
||||
var vmask = Unsafe.As<TLane, Vector256<ulong>>(ref mask);
|
||||
|
||||
#pragma warning disable CA1857 // A constant is expected for the parameter
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
var v<#= components[i] #> = Avx2.GatherMaskVector256(Vector256<ulong>.Zero, (ulong*)(pData + <#= i #>), vidx, vmask, scale);
|
||||
<# } #>
|
||||
#pragma warning restore CA1857 // A constant is expected for the parameter
|
||||
|
||||
return new <#= vectorType #>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = Unsafe.As<Vector256<ulong>, TLane>(ref v<#= components[i] #>),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
Unsafe.SkipInit(out TLane <#= components[i] #>);
|
||||
var p<#= components[i] #> = (<#= TNumber #>*)&<#= components[i] #>;
|
||||
<# } #>
|
||||
|
||||
for (var i = 0; i < TLane.LaneWidth; i++)
|
||||
{
|
||||
if (mask[i] == TNumber.Zero)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var scalerIdx = pIndices[i];
|
||||
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
p<#= components[i] #>[i] = *(TNumber*)((byte*)pData + ((scalerIdx + <#= i #>) * scale));
|
||||
<# } #>
|
||||
}
|
||||
|
||||
return new Vector<#= dimension #><TLane, TNumber>
|
||||
{
|
||||
<# for (int i = 0; i < dimension; i++) { #>
|
||||
<#= components[i] #> = <#= components[i] #>,
|
||||
<#= components[i] #> = <#= TLane #>.MaskGather(pData + <#= i #>, pIndices, mask, scale),
|
||||
<# } #>
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user