/// <summary> /// Demonstrates the sequence functionality. /// </summary> /// <param name="accelerator">The target accelerator.</param> static void Sequence(Accelerator accelerator) { using (var buffer = accelerator.Allocate <int>(64)) { // Creates a sequence (from 0 to buffer.Length / 2 - 1). // Note that in this case, the sequencer uses the default accelerator stream. accelerator.Sequence(buffer.View.GetSubView(0, buffer.Length / 2), new Int32Sequencer()); // Creates a sequence (from 0 to buffer.Length / 2 - 1). // Note that this overload requires an explicit accelerator stream. accelerator.Sequence(accelerator.DefaultStream, buffer.View.GetSubView(buffer.Length / 2), new Int32Sequencer()); accelerator.Synchronize(); var data = buffer.GetAsArray(); for (int i = 0, e = data.Length; i < e; ++i) { Console.WriteLine($"Data[{i}] = {data[i]}"); } } // Custom sequencer using (var buffer = accelerator.Allocate <CustomStruct>(64)) { accelerator.Sequence(buffer.View, new CustomSequencer(32)); accelerator.Synchronize(); var data = buffer.GetAsArray(); for (int i = 0, e = data.Length; i < e; ++i) { Console.WriteLine($"CustomData[{i}] = {data[i]}"); } } // Calling the convenient Sequence function on the lightning context // involves internal heap allocations. This can be avoided by constructing // a sequencer explicitly: var sequencer = accelerator.CreateSequencer <CustomStruct, CustomSequencer>(); using (var buffer = accelerator.Allocate <CustomStruct>(64)) { sequencer( accelerator.DefaultStream, buffer.View, new CustomSequencer(64)); accelerator.Synchronize(); var data = buffer.GetAsArray(); for (int i = 0, e = data.Length; i < e; ++i) { Console.WriteLine($"CustomDataSpecialized[{i}] = {data[i]}"); } } }
/// <summary> /// Computes a new sequence of values from 0 to view.Length - 1 and writes /// the computed values to the given view. /// </summary> /// <typeparam name="T">The element type.</typeparam> /// <typeparam name="TSequencer">The type of the sequencer to use.</typeparam> /// <param name="accelerator">The accelerator.</param> /// <param name="stream">The accelerator stream.</param> /// <param name="view">The target view.</param> /// <param name="sequencer">The used sequencer.</param> public static void Sequence <T, TSequencer>( this Accelerator accelerator, AcceleratorStream stream, ArrayView <T> view, TSequencer sequencer) where T : unmanaged where TSequencer : struct, ISequencer <T> => accelerator.CreateSequencer <T, Stride1D.Dense, TSequencer>()( stream, view, sequencer);
/// <summary> /// Demonstrates the sequence functionality. /// </summary> /// <param name="accelerator">The target accelerator.</param> static void Sequence(Accelerator accelerator) { using (var buffer = accelerator.Allocate1D <int>(64)) { // Creates a sequence (from 0 to buffer.Length - 1). accelerator.Sequence(accelerator.DefaultStream, buffer.View, new Int32Sequencer()); // Reads data from the GPU buffer into a new CPU array. // Implicitly calls accelerator.DefaultStream.Synchronize() to ensure // that the kernel and memory copy are completed first. var data = buffer.GetAsArray1D(); for (int i = 0, e = data.Length; i < e; ++i) { Console.WriteLine($"Data[{i}] = {data[i]}"); } } // Custom sequencer using (var buffer = accelerator.Allocate1D <CustomStruct>(64)) { accelerator.Sequence(accelerator.DefaultStream, buffer.View, new CustomSequencer(32)); // Reads data from the GPU buffer into a new CPU array. // Implicitly calls accelerator.DefaultStream.Synchronize() to ensure // that the kernel and memory copy are completed first. var data = buffer.GetAsArray1D(); for (int i = 0, e = data.Length; i < e; ++i) { Console.WriteLine($"CustomData[{i}] = {data[i]}"); } } // Calling the convenient Sequence function on the accelerator // involves internal heap allocations. This can be avoided by constructing // a sequencer explicitly: var sequencer = accelerator.CreateSequencer <CustomStruct, Stride1D.Dense, CustomSequencer>(); using (var buffer = accelerator.Allocate1D <CustomStruct>(64)) { sequencer( accelerator.DefaultStream, buffer.View, new CustomSequencer(64)); // Reads data from the GPU buffer into a new CPU array. // Implicitly calls accelerator.DefaultStream.Synchronize() to ensure // that the kernel and memory copy are completed first. var data = buffer.GetAsArray1D(); for (int i = 0, e = data.Length; i < e; ++i) { Console.WriteLine($"CustomDataSpecialized[{i}] = {data[i]}"); } } }
/// <summary> /// Computes a new sequence of values from 0 to view.Length - 1 and writes /// the computed values to the given view. /// </summary> /// <typeparam name="T">The element type.</typeparam> /// <typeparam name="TSequencer">The type of the sequencer to use.</typeparam> /// <param name="accelerator">The accelerator.</param> /// <param name="stream">The accelerator stream.</param> /// <param name="view">The target view.</param> /// <param name="sequencer">The used sequencer.</param> public static void Sequence <T, TSequencer>( this Accelerator accelerator, AcceleratorStream stream, ArrayView <T> view, TSequencer sequencer) where T : struct where TSequencer : struct, ISequencer <T> { accelerator.CreateSequencer <T, TSequencer>()( stream, view, sequencer); }