using Misaki.HighPerformance.Jobs; using System.Numerics; namespace Misaki.HighPerformance.Mathematics.SPMD; /// /// A job interface for Single Program Multiple Data (SPMD) execution, allowing for efficient parallel processing of data across multiple lanes. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. public interface IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { void Execute(int baseIndex, ref readonly JobExecutionContext ctx) where TLane0 : unmanaged, ISPMDLane; } internal struct SPMDJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { innerJob.Execute>(baseIndex, in ctx); } else { for (var j = 0; j < remaining; j++) { innerJob.Execute>(baseIndex + j, in ctx); } } } } internal struct SPMDScalerJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { innerJob.Execute>(loopIndex, in ctx); } } /// /// A job interface for Single Program Multiple Data (SPMD) execution, allowing for efficient parallel processing of data across multiple lanes. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. public interface IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { void Execute(int baseIndex, ref readonly JobExecutionContext ctx) where TLane0 : unmanaged, ISPMDLane where TLane1 : unmanaged, ISPMDLane; } internal struct SPMDJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { innerJob.Execute, WideLane>(baseIndex, in ctx); } else { for (var j = 0; j < remaining; j++) { innerJob.Execute, ScalarLane>(baseIndex + j, in ctx); } } } } internal struct SPMDScalerJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { innerJob.Execute, ScalarLane>(loopIndex, in ctx); } } /// /// A job interface for Single Program Multiple Data (SPMD) execution, allowing for efficient parallel processing of data across multiple lanes. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. public interface IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { void Execute(int baseIndex, ref readonly JobExecutionContext ctx) where TLane0 : unmanaged, ISPMDLane where TLane1 : unmanaged, ISPMDLane where TLane2 : unmanaged, ISPMDLane; } internal struct SPMDJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { innerJob.Execute, WideLane, WideLane>(baseIndex, in ctx); } else { for (var j = 0; j < remaining; j++) { innerJob.Execute, ScalarLane, ScalarLane>(baseIndex + j, in ctx); } } } } internal struct SPMDScalerJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { innerJob.Execute, ScalarLane, ScalarLane>(loopIndex, in ctx); } } /// /// A job interface for Single Program Multiple Data (SPMD) execution, allowing for efficient parallel processing of data across multiple lanes. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. public interface IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { void Execute(int baseIndex, ref readonly JobExecutionContext ctx) where TLane0 : unmanaged, ISPMDLane where TLane1 : unmanaged, ISPMDLane where TLane2 : unmanaged, ISPMDLane where TLane3 : unmanaged, ISPMDLane; } internal struct SPMDJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { innerJob.Execute, WideLane, WideLane, WideLane>(baseIndex, in ctx); } else { for (var j = 0; j < remaining; j++) { innerJob.Execute, ScalarLane, ScalarLane, ScalarLane>(baseIndex + j, in ctx); } } } } internal struct SPMDScalerJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { innerJob.Execute, ScalarLane, ScalarLane, ScalarLane>(loopIndex, in ctx); } } /// /// A job interface for Single Program Multiple Data (SPMD) execution, allowing for efficient parallel processing of data across multiple lanes. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. public interface IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { void Execute(int baseIndex, ref readonly JobExecutionContext ctx) where TLane0 : unmanaged, ISPMDLane where TLane1 : unmanaged, ISPMDLane where TLane2 : unmanaged, ISPMDLane where TLane3 : unmanaged, ISPMDLane where TLane4 : unmanaged, ISPMDLane; } internal struct SPMDJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { innerJob.Execute, WideLane, WideLane, WideLane, WideLane>(baseIndex, in ctx); } else { for (var j = 0; j < remaining; j++) { innerJob.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(baseIndex + j, in ctx); } } } } internal struct SPMDScalerJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { innerJob.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(loopIndex, in ctx); } } /// /// A job interface for Single Program Multiple Data (SPMD) execution, allowing for efficient parallel processing of data across multiple lanes. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. public interface IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber5 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { void Execute(int baseIndex, ref readonly JobExecutionContext ctx) where TLane0 : unmanaged, ISPMDLane where TLane1 : unmanaged, ISPMDLane where TLane2 : unmanaged, ISPMDLane where TLane3 : unmanaged, ISPMDLane where TLane4 : unmanaged, ISPMDLane where TLane5 : unmanaged, ISPMDLane; } internal struct SPMDJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber5 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { innerJob.Execute, WideLane, WideLane, WideLane, WideLane, WideLane>(baseIndex, in ctx); } else { for (var j = 0; j < remaining; j++) { innerJob.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(baseIndex + j, in ctx); } } } } internal struct SPMDScalerJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber5 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { innerJob.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(loopIndex, in ctx); } } /// /// A job interface for Single Program Multiple Data (SPMD) execution, allowing for efficient parallel processing of data across multiple lanes. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. public interface IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber5 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber6 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { void Execute(int baseIndex, ref readonly JobExecutionContext ctx) where TLane0 : unmanaged, ISPMDLane where TLane1 : unmanaged, ISPMDLane where TLane2 : unmanaged, ISPMDLane where TLane3 : unmanaged, ISPMDLane where TLane4 : unmanaged, ISPMDLane where TLane5 : unmanaged, ISPMDLane where TLane6 : unmanaged, ISPMDLane; } internal struct SPMDJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber5 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber6 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { innerJob.Execute, WideLane, WideLane, WideLane, WideLane, WideLane, WideLane>(baseIndex, in ctx); } else { for (var j = 0; j < remaining; j++) { innerJob.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(baseIndex + j, in ctx); } } } } internal struct SPMDScalerJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber5 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber6 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { innerJob.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(loopIndex, in ctx); } } /// /// A job interface for Single Program Multiple Data (SPMD) execution, allowing for efficient parallel processing of data across multiple lanes. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. public interface IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber5 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber6 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber7 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { void Execute(int baseIndex, ref readonly JobExecutionContext ctx) where TLane0 : unmanaged, ISPMDLane where TLane1 : unmanaged, ISPMDLane where TLane2 : unmanaged, ISPMDLane where TLane3 : unmanaged, ISPMDLane where TLane4 : unmanaged, ISPMDLane where TLane5 : unmanaged, ISPMDLane where TLane6 : unmanaged, ISPMDLane where TLane7 : unmanaged, ISPMDLane; } internal struct SPMDJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber5 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber6 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber7 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { innerJob.Execute, WideLane, WideLane, WideLane, WideLane, WideLane, WideLane, WideLane>(baseIndex, in ctx); } else { for (var j = 0; j < remaining; j++) { innerJob.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(baseIndex + j, in ctx); } } } } internal struct SPMDScalerJobWrapper : IJobParallelFor where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber5 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber6 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber7 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { public T innerJob; public int totalIteration; public void Execute(int loopIndex, ref readonly JobExecutionContext ctx) { innerJob.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(loopIndex, in ctx); } } public static class IJobParallelForSPMDExtensions { /// /// Run the SPMD job with the specified total count and job execution context directly on the calling thread. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. /// The SPMD job to run. /// The total number of iterations to execute across all lanes. /// The job execution context providing information about the current execution environment. public static void Run(this ref T job, int totalIteration, ref readonly JobExecutionContext ctx) where T : struct, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; for (var loopIndex = 0; loopIndex < iterations; loopIndex++) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { job.Execute>(baseIndex, in ctx); } else { for (var i = 0; i < remaining; i++) { job.Execute>(baseIndex + i, in ctx); } } } } else { for (var loopIndex = 0; loopIndex < totalIteration; loopIndex++) { job.Execute>(loopIndex, in ctx); } } } /// /// Schedule the SPMD job for parallel execution across multiple threads, with the specified total count, batch size, and job execution context. /// /// The first numeric type used in the SPMD job. /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The job scheduler to use for scheduling the job. /// The SPMD job to schedule. /// The total number of iterations to execute across all lanes. /// The number of iterations to execute in each batch for parallel execution. /// Whether to prefer scheduling the job on the local thread for better cache locality. /// The priority of the job. /// Any job handles that this job depends on, which must complete before this job can start. public static JobHandle ScheduleParallelSPDM(this JobScheduler jobScheduler, ref T job, int totalIteration, int batchSize, bool preferLocal, JobPriority priority, params ReadOnlySpan dependencies) where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var warper = new SPMDJobWrapper { innerJob = job, totalIteration = totalIteration, }; var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; return jobScheduler.ScheduleParallelFor(ref warper, iterations, batchSize, preferLocal, priority, dependencies); } else { var warper = new SPMDScalerJobWrapper { innerJob = job, totalIteration = totalIteration, }; return jobScheduler.ScheduleParallelFor(ref warper, totalIteration, batchSize, preferLocal, priority, dependencies); } } /// /// Run the SPMD job with the specified total count and job execution context directly on the calling thread. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The SPMD job to run. /// The total number of iterations to execute across all lanes. /// The job execution context providing information about the current execution environment. public static void Run(this ref T job, int totalIteration, ref readonly JobExecutionContext ctx) where T : struct, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; for (var loopIndex = 0; loopIndex < iterations; loopIndex++) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { job.Execute, WideLane>(baseIndex, in ctx); } else { for (var i = 0; i < remaining; i++) { job.Execute, ScalarLane>(baseIndex + i, in ctx); } } } } else { for (var loopIndex = 0; loopIndex < totalIteration; loopIndex++) { job.Execute, ScalarLane>(loopIndex, in ctx); } } } /// /// Schedule the SPMD job for parallel execution across multiple threads, with the specified total count, batch size, and job execution context. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The job scheduler to use for scheduling the job. /// The SPMD job to schedule. /// The total number of iterations to execute across all lanes. /// The number of iterations to execute in each batch for parallel execution. /// Whether to prefer scheduling the job on the local thread for better cache locality. /// The priority of the job. /// Any job handles that this job depends on, which must complete before this job can start. public static JobHandle ScheduleParallelSPDM(this JobScheduler jobScheduler, ref T job, int totalIteration, int batchSize, bool preferLocal, JobPriority priority, params ReadOnlySpan dependencies) where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var warper = new SPMDJobWrapper { innerJob = job, totalIteration = totalIteration, }; var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; return jobScheduler.ScheduleParallelFor(ref warper, iterations, batchSize, preferLocal, priority, dependencies); } else { var warper = new SPMDScalerJobWrapper { innerJob = job, totalIteration = totalIteration, }; return jobScheduler.ScheduleParallelFor(ref warper, totalIteration, batchSize, preferLocal, priority, dependencies); } } /// /// Run the SPMD job with the specified total count and job execution context directly on the calling thread. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The SPMD job to run. /// The total number of iterations to execute across all lanes. /// The job execution context providing information about the current execution environment. public static void Run(this ref T job, int totalIteration, ref readonly JobExecutionContext ctx) where T : struct, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; for (var loopIndex = 0; loopIndex < iterations; loopIndex++) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { job.Execute, WideLane, WideLane>(baseIndex, in ctx); } else { for (var i = 0; i < remaining; i++) { job.Execute, ScalarLane, ScalarLane>(baseIndex + i, in ctx); } } } } else { for (var loopIndex = 0; loopIndex < totalIteration; loopIndex++) { job.Execute, ScalarLane, ScalarLane>(loopIndex, in ctx); } } } /// /// Schedule the SPMD job for parallel execution across multiple threads, with the specified total count, batch size, and job execution context. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The job scheduler to use for scheduling the job. /// The SPMD job to schedule. /// The total number of iterations to execute across all lanes. /// The number of iterations to execute in each batch for parallel execution. /// Whether to prefer scheduling the job on the local thread for better cache locality. /// The priority of the job. /// Any job handles that this job depends on, which must complete before this job can start. public static JobHandle ScheduleParallelSPDM(this JobScheduler jobScheduler, ref T job, int totalIteration, int batchSize, bool preferLocal, JobPriority priority, params ReadOnlySpan dependencies) where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var warper = new SPMDJobWrapper { innerJob = job, totalIteration = totalIteration, }; var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; return jobScheduler.ScheduleParallelFor(ref warper, iterations, batchSize, preferLocal, priority, dependencies); } else { var warper = new SPMDScalerJobWrapper { innerJob = job, totalIteration = totalIteration, }; return jobScheduler.ScheduleParallelFor(ref warper, totalIteration, batchSize, preferLocal, priority, dependencies); } } /// /// Run the SPMD job with the specified total count and job execution context directly on the calling thread. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The SPMD job to run. /// The total number of iterations to execute across all lanes. /// The job execution context providing information about the current execution environment. public static void Run(this ref T job, int totalIteration, ref readonly JobExecutionContext ctx) where T : struct, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; for (var loopIndex = 0; loopIndex < iterations; loopIndex++) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { job.Execute, WideLane, WideLane, WideLane>(baseIndex, in ctx); } else { for (var i = 0; i < remaining; i++) { job.Execute, ScalarLane, ScalarLane, ScalarLane>(baseIndex + i, in ctx); } } } } else { for (var loopIndex = 0; loopIndex < totalIteration; loopIndex++) { job.Execute, ScalarLane, ScalarLane, ScalarLane>(loopIndex, in ctx); } } } /// /// Schedule the SPMD job for parallel execution across multiple threads, with the specified total count, batch size, and job execution context. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The job scheduler to use for scheduling the job. /// The SPMD job to schedule. /// The total number of iterations to execute across all lanes. /// The number of iterations to execute in each batch for parallel execution. /// Whether to prefer scheduling the job on the local thread for better cache locality. /// The priority of the job. /// Any job handles that this job depends on, which must complete before this job can start. public static JobHandle ScheduleParallelSPDM(this JobScheduler jobScheduler, ref T job, int totalIteration, int batchSize, bool preferLocal, JobPriority priority, params ReadOnlySpan dependencies) where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var warper = new SPMDJobWrapper { innerJob = job, totalIteration = totalIteration, }; var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; return jobScheduler.ScheduleParallelFor(ref warper, iterations, batchSize, preferLocal, priority, dependencies); } else { var warper = new SPMDScalerJobWrapper { innerJob = job, totalIteration = totalIteration, }; return jobScheduler.ScheduleParallelFor(ref warper, totalIteration, batchSize, preferLocal, priority, dependencies); } } /// /// Run the SPMD job with the specified total count and job execution context directly on the calling thread. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The SPMD job to run. /// The total number of iterations to execute across all lanes. /// The job execution context providing information about the current execution environment. public static void Run(this ref T job, int totalIteration, ref readonly JobExecutionContext ctx) where T : struct, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; for (var loopIndex = 0; loopIndex < iterations; loopIndex++) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { job.Execute, WideLane, WideLane, WideLane, WideLane>(baseIndex, in ctx); } else { for (var i = 0; i < remaining; i++) { job.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(baseIndex + i, in ctx); } } } } else { for (var loopIndex = 0; loopIndex < totalIteration; loopIndex++) { job.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(loopIndex, in ctx); } } } /// /// Schedule the SPMD job for parallel execution across multiple threads, with the specified total count, batch size, and job execution context. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The job scheduler to use for scheduling the job. /// The SPMD job to schedule. /// The total number of iterations to execute across all lanes. /// The number of iterations to execute in each batch for parallel execution. /// Whether to prefer scheduling the job on the local thread for better cache locality. /// The priority of the job. /// Any job handles that this job depends on, which must complete before this job can start. public static JobHandle ScheduleParallelSPDM(this JobScheduler jobScheduler, ref T job, int totalIteration, int batchSize, bool preferLocal, JobPriority priority, params ReadOnlySpan dependencies) where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var warper = new SPMDJobWrapper { innerJob = job, totalIteration = totalIteration, }; var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; return jobScheduler.ScheduleParallelFor(ref warper, iterations, batchSize, preferLocal, priority, dependencies); } else { var warper = new SPMDScalerJobWrapper { innerJob = job, totalIteration = totalIteration, }; return jobScheduler.ScheduleParallelFor(ref warper, totalIteration, batchSize, preferLocal, priority, dependencies); } } /// /// Run the SPMD job with the specified total count and job execution context directly on the calling thread. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The SPMD job to run. /// The total number of iterations to execute across all lanes. /// The job execution context providing information about the current execution environment. public static void Run(this ref T job, int totalIteration, ref readonly JobExecutionContext ctx) where T : struct, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber5 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; for (var loopIndex = 0; loopIndex < iterations; loopIndex++) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { job.Execute, WideLane, WideLane, WideLane, WideLane, WideLane>(baseIndex, in ctx); } else { for (var i = 0; i < remaining; i++) { job.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(baseIndex + i, in ctx); } } } } else { for (var loopIndex = 0; loopIndex < totalIteration; loopIndex++) { job.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(loopIndex, in ctx); } } } /// /// Schedule the SPMD job for parallel execution across multiple threads, with the specified total count, batch size, and job execution context. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The job scheduler to use for scheduling the job. /// The SPMD job to schedule. /// The total number of iterations to execute across all lanes. /// The number of iterations to execute in each batch for parallel execution. /// Whether to prefer scheduling the job on the local thread for better cache locality. /// The priority of the job. /// Any job handles that this job depends on, which must complete before this job can start. public static JobHandle ScheduleParallelSPDM(this JobScheduler jobScheduler, ref T job, int totalIteration, int batchSize, bool preferLocal, JobPriority priority, params ReadOnlySpan dependencies) where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber5 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var warper = new SPMDJobWrapper { innerJob = job, totalIteration = totalIteration, }; var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; return jobScheduler.ScheduleParallelFor(ref warper, iterations, batchSize, preferLocal, priority, dependencies); } else { var warper = new SPMDScalerJobWrapper { innerJob = job, totalIteration = totalIteration, }; return jobScheduler.ScheduleParallelFor(ref warper, totalIteration, batchSize, preferLocal, priority, dependencies); } } /// /// Run the SPMD job with the specified total count and job execution context directly on the calling thread. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The SPMD job to run. /// The total number of iterations to execute across all lanes. /// The job execution context providing information about the current execution environment. public static void Run(this ref T job, int totalIteration, ref readonly JobExecutionContext ctx) where T : struct, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber5 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber6 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; for (var loopIndex = 0; loopIndex < iterations; loopIndex++) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { job.Execute, WideLane, WideLane, WideLane, WideLane, WideLane, WideLane>(baseIndex, in ctx); } else { for (var i = 0; i < remaining; i++) { job.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(baseIndex + i, in ctx); } } } } else { for (var loopIndex = 0; loopIndex < totalIteration; loopIndex++) { job.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(loopIndex, in ctx); } } } /// /// Schedule the SPMD job for parallel execution across multiple threads, with the specified total count, batch size, and job execution context. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The job scheduler to use for scheduling the job. /// The SPMD job to schedule. /// The total number of iterations to execute across all lanes. /// The number of iterations to execute in each batch for parallel execution. /// Whether to prefer scheduling the job on the local thread for better cache locality. /// The priority of the job. /// Any job handles that this job depends on, which must complete before this job can start. public static JobHandle ScheduleParallelSPDM(this JobScheduler jobScheduler, ref T job, int totalIteration, int batchSize, bool preferLocal, JobPriority priority, params ReadOnlySpan dependencies) where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber5 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber6 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var warper = new SPMDJobWrapper { innerJob = job, totalIteration = totalIteration, }; var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; return jobScheduler.ScheduleParallelFor(ref warper, iterations, batchSize, preferLocal, priority, dependencies); } else { var warper = new SPMDScalerJobWrapper { innerJob = job, totalIteration = totalIteration, }; return jobScheduler.ScheduleParallelFor(ref warper, totalIteration, batchSize, preferLocal, priority, dependencies); } } /// /// Run the SPMD job with the specified total count and job execution context directly on the calling thread. /// /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The SPMD job to run. /// The total number of iterations to execute across all lanes. /// The job execution context providing information about the current execution environment. public static void Run(this ref T job, int totalIteration, ref readonly JobExecutionContext ctx) where T : struct, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber5 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber6 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber7 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; for (var loopIndex = 0; loopIndex < iterations; loopIndex++) { var baseIndex = loopIndex * WideLane.LaneWidth; var remaining = totalIteration - baseIndex; if (remaining >= WideLane.LaneWidth) { job.Execute, WideLane, WideLane, WideLane, WideLane, WideLane, WideLane, WideLane>(baseIndex, in ctx); } else { for (var i = 0; i < remaining; i++) { job.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(baseIndex + i, in ctx); } } } } else { for (var loopIndex = 0; loopIndex < totalIteration; loopIndex++) { job.Execute, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane, ScalarLane>(loopIndex, in ctx); } } } /// /// Schedule the SPMD job for parallel execution across multiple threads, with the specified total count, batch size, and job execution context. /// /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// The first numeric type used in the SPMD job. /// /// Always use TNumber0 as the primary type for determining lane width and job scheduling, even if it's not used in the job execution. /// /// The job scheduler to use for scheduling the job. /// The SPMD job to schedule. /// The total number of iterations to execute across all lanes. /// The number of iterations to execute in each batch for parallel execution. /// Whether to prefer scheduling the job on the local thread for better cache locality. /// The priority of the job. /// Any job handles that this job depends on, which must complete before this job can start. public static JobHandle ScheduleParallelSPDM(this JobScheduler jobScheduler, ref T job, int totalIteration, int batchSize, bool preferLocal, JobPriority priority, params ReadOnlySpan dependencies) where T : unmanaged, IJobSPMD where TNumber0 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber1 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber2 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber3 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber4 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber5 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber6 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators where TNumber7 : unmanaged, INumber, IBinaryNumber, IMinMaxValue, IBitwiseOperators { if (WideLane.IsSupported) { var warper = new SPMDJobWrapper { innerJob = job, totalIteration = totalIteration, }; var iterations = (totalIteration + WideLane.LaneWidth - 1) / WideLane.LaneWidth; return jobScheduler.ScheduleParallelFor(ref warper, iterations, batchSize, preferLocal, priority, dependencies); } else { var warper = new SPMDScalerJobWrapper { innerJob = job, totalIteration = totalIteration, }; return jobScheduler.ScheduleParallelFor(ref warper, totalIteration, batchSize, preferLocal, priority, dependencies); } } }