Files
Misaki.HighPerformance/Misaki.HighPerformance.Mathematics.SPMD/Templates/WideLane.tt
Misaki 155d7b0fbd 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
2026-05-04 13:56:49 +09:00

57 lines
2.3 KiB
Plaintext

<#@ template debug="false" hostspecific="false" language="C#" #>
<#@ assembly name="System.Core" #>
<#@ import namespace="System.Linq" #>
<#@ import namespace="System.Text" #>
<#@ import namespace="System.Collections.Generic" #>
<#@ output extension=".gen.cs" #>
using System.Numerics;
using System.Runtime.CompilerServices;
namespace Misaki.HighPerformance.Mathematics.SPMD;
<#
var conversions = new CastRoute[]
{
new CastRoute { From = "float", To = "int", Method = "Vector.ConvertToInt32" },
new CastRoute { From = "float", To = "uint", Method = "Vector.ConvertToUInt32" },
new CastRoute { From = "double", To = "long", Method = "Vector.ConvertToInt64" },
new CastRoute { From = "double", To = "ulong", Method = "Vector.ConvertToUInt64" },
new CastRoute { From = "int", To = "float", Method = "Vector.ConvertToSingle" },
new CastRoute { From = "uint", To = "float", Method = "Vector.ConvertToSingle" },
new CastRoute { From = "long", To = "double", Method = "Vector.ConvertToDouble" },
new CastRoute { From = "ulong", To = "double", Method = "Vector.ConvertToDouble" },
};
#>
public readonly unsafe partial struct WideLane<TNumber> : ISPMDLane<WideLane<TNumber>, TNumber>
where TNumber : unmanaged, INumber<TNumber>, IBinaryNumber<TNumber>, IMinMaxValue<TNumber>, IBitwiseOperators<TNumber, TNumber, TNumber>
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public TOther Cast<TOther, TOtherNumber>()
where TOther : ISPMDLane<TOther, TOtherNumber>
where TOtherNumber : unmanaged, INumber<TOtherNumber>, IBinaryNumber<TOtherNumber>, IMinMaxValue<TOtherNumber>, IBitwiseOperators<TOtherNumber, TOtherNumber, TOtherNumber>
{
<# foreach (var c in conversions) { #>
if (typeof(TNumber) == typeof(<#= c.From #>) && typeof(TOtherNumber) == typeof(<#= c.To #>))
{
return Unsafe.BitCast<Vector<<#= c.To #>>, TOther>(<#= c.Method #>(Unsafe.BitCast<Vector<TNumber>, Vector<<#= c.From #>>>(value)));
}
<# } #>
var casted = stackalloc TOtherNumber[LaneWidth];
for (var i = 0; (i < LaneWidth) && (i < TOther.LaneWidth); i++)
{
casted[i] = TOtherNumber.CreateTruncating(value[i]);
}
return TOther.Load(casted);
}
}
<#+
public struct CastRoute
{
public string From;
public string To;
public string Method;
}
#>