### Get Preferred Device and Create Accelerator Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/02_Beginner/01_Context-and-Accelerators.md Demonstrates how to get the preferred device (CPU or GPU) and create an accelerator from it. Also shows how to iterate through all preferred devices and create accelerators. ```csharp using System; using ILGPU; using ILGPU.Runtime; public static class Program { static void Main() { using Context context = Context.Create(builder => builder.AllAccelerators()); Console.WriteLine("Context: " + context.ToString()); Device d = context.GetPreferredDevice(preferCPU: false); Accelerator a = d.CreateAccelerator(context); a.PrintInformation(); a.Dispose(); foreach(Device device in context.GetPreferredDevices(preferCPU: false, matchingDevicesOnly: false)) { Accelerator accelerator = device.CreateAccelerator(context); accelerator.PrintInformation(); accelerator.Dispose(); } } } ``` -------------------------------- ### Full Example: ILGPU Kernel Execution Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/02_Beginner/03_Kernels-and-Simple-Programs.md A complete example demonstrating ILGPU kernel execution, including context creation, device memory allocation, kernel loading, execution, synchronization, and data retrieval. ```c# using ILGPU; using ILGPU.Runtime; using System; public static class Program { static void Kernel(Index1D i, ArrayView data, ArrayView output) { output[i] = data[i % data.Length]; } static void Main() { // Initialize ILGPU. Context context = Context.CreateDefault(); Accelerator accelerator = context.GetPreferredDevice(preferCPU: false) .CreateAccelerator(context); // Load the data. MemoryBuffer1D deviceData = accelerator.Allocate1D(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); MemoryBuffer1D deviceOutput = accelerator.Allocate1D(10_000); // load / precompile the kernel Action, ArrayView> loadedKernel = accelerator.LoadAutoGroupedStreamKernel, ArrayView>(Kernel); // finish compiling and tell the accelerator to start computing the kernel loadedKernel((int)deviceOutput.Length, deviceData.View, deviceOutput.View); // wait for the accelerator to be finished with whatever it's doing // in this case it just waits for the kernel to finish. accelerator.Synchronize(); // moved output data from the GPU to the CPU for output to console int[] hostOutput = deviceOutput.GetAsArray1D(); for(int i = 0; i < 50; i++) { Console.Write(hostOutput[i]); Console.Write(" "); } accelerator.Dispose(); context.Dispose(); } } ``` -------------------------------- ### Create New .Net Project and Install ILGPU Source: https://github.com/m4rs-mt/ilgpu/wiki/Getting-Started Use these commands to create a new console project and install the ILGPU NuGet package. Ensure your project targets .Net Framework 4.7.X or higher, or .Net Standard 2.1 (e.g., .Net Core 3.1). ```bash dotnet new console nuget install ILGPU ``` -------------------------------- ### ILGPU Kernel Example Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/01_Primers/02_A-GPU-Is-Not-A-CPU.md Illustrates parallel execution on a GPU using ILGPU kernels. Requires ILGPU.Runtime and ILGPU.Runtime.CPU. ```csharp using ILGPU; using ILGPU.Runtime; using ILGPU.Runtime.CPU; public static class Program { static void Main() { // Initialize ILGPU. Context context = Context.CreateDefault(); Accelerator accelerator = context.CreateCPUAccelerator(0); // Load the data. var deviceData = accelerator.Allocate1D(new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }); var deviceOutput = accelerator.Allocate1D(10_000); // load / compile the kernel var loadedKernel = accelerator.LoadAutoGroupedStreamKernel( (Index1D i, ArrayView data, ArrayView output) => { output[i] = data[i % data.Length]; }); // tell the accelerator to start computing the kernel loadedKernel((int)deviceOutput.Length, deviceData.View, deviceOutput.View); // wait for the accelerator to be finished with whatever it's doing // in this case it just waits for the kernel to finish. accelerator.Synchronize(); accelerator.Dispose(); context.Dispose(); } } ``` -------------------------------- ### ILGPU Scan (Prefix Sum) Example Source: https://context7.com/m4rs-mt/ilgpu/llms.txt Demonstrates inclusive and exclusive scan operations using ILGPU.Algorithms. Ensure the ILGPU.Algorithms namespace is enabled in the context. ```csharp using ILGPU; using ILGPU.Algorithms; using ILGPU.Algorithms.ScanReduceOperations; using ILGPU.Runtime; using System; public class Program { static void Main() { using Context context = Context.Create(builder => builder.Default().EnableAlgorithms()); using Accelerator accelerator = context.GetPreferredDevice(false).CreateAccelerator(context); using var sourceBuffer = accelerator.Allocate1D(8); using var targetBuffer = accelerator.Allocate1D(8); // Initialize all elements to 2 accelerator.Initialize(accelerator.DefaultStream, sourceBuffer.View, 2); // Create inclusive scan (running sum including current element) var inclusiveScan = accelerator.CreateScan(ScanKind.Inclusive); // Allocate temporary storage var tempMemSize = accelerator.ComputeScanTempStorageSize(targetBuffer.Length); using var tempBuffer = accelerator.Allocate1D(tempMemSize); inclusiveScan(accelerator.DefaultStream, sourceBuffer.View, targetBuffer.View, tempBuffer.View); int[] inclusiveResult = targetBuffer.GetAsArray1D(); Console.WriteLine("Inclusive Scan (input all 2s):"); for (int i = 0; i < inclusiveResult.Length; i++) Console.WriteLine($" [{i}] = {inclusiveResult[i]}"); // 2, 4, 6, 8, 10, 12, 14, 16 // Create exclusive scan (running sum excluding current element) var exclusiveScan = accelerator.CreateScan(ScanKind.Exclusive); exclusiveScan(accelerator.DefaultStream, sourceBuffer.View, targetBuffer.View, tempBuffer.View); int[] exclusiveResult = targetBuffer.GetAsArray1D(); Console.WriteLine("Exclusive Scan:"); for (int i = 0; i < exclusiveResult.Length; i++) Console.WriteLine($" [{i}] = {exclusiveResult[i]}"); // 0, 2, 4, 6, 8, 10, 12, 14 } } ``` -------------------------------- ### Install ILGPU via NuGet Source: https://context7.com/m4rs-mt/ilgpu/llms.txt Add the ILGPU package and optionally the Algorithms library to your .NET project using the dotnet CLI. ```bash dotnet add package ILGPU dotnet add package ILGPU.Algorithms # Optional: for standard algorithms ``` -------------------------------- ### Install Project Dependencies with Bundler Source: https://github.com/m4rs-mt/ilgpu/blob/master/Site/DOCUMENTATION.md Install all Ruby dependencies listed in the Gemfile using the bundle command. ```shell bundle # or bundle install ``` -------------------------------- ### CPU Parallel.For Example Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/01_Primers/02_A-GPU-Is-Not-A-CPU.md Demonstrates parallel execution on CPU cores using C# Parallel.For. Requires System.Threading.Tasks. ```csharp using System; using System.Threading.Tasks; public static class Program { static void Main(string[] args) { //Load the data int[] data = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; int[] output = new int[10_000]; //Load the action and execute Parallel.For(0, output.Length, (int i) => { output[i] = data[i % data.Length]; }); } } ``` -------------------------------- ### ILGPU Radix Sort Example Source: https://context7.com/m4rs-mt/ilgpu/llms.txt Demonstrates ascending and descending radix sort operations using ILGPU.Algorithms. Ensure the ILGPU.Algorithms namespace is enabled in the context. ```csharp using ILGPU; using ILGPU.Algorithms; using ILGPU.Algorithms.RadixSortOperations; using ILGPU.Runtime; using System; public class Program { static void Main() { using Context context = Context.Create(builder => builder.Default().EnableAlgorithms()); using Accelerator accelerator = context.GetPreferredDevice(false).CreateAccelerator(context); // Create unsorted data int[] unsortedData = { 42, 17, 89, 3, 56, 12, 78, 25 }; using var buffer = accelerator.Allocate1D(unsortedData.Length); buffer.CopyFromCPU(unsortedData); // Create ascending radix sort var ascendingSort = accelerator.CreateRadixSort(); // Allocate temporary storage var tempMemSize = accelerator.ComputeRadixSortTempStorageSize((Index1D)buffer.Length); using var tempBuffer = accelerator.Allocate1D(tempMemSize); // Sort ascending ascendingSort(accelerator.DefaultStream, buffer.View, tempBuffer.View); int[] ascendingResult = buffer.GetAsArray1D(); Console.WriteLine("Ascending sort:"); Console.WriteLine(string.Join(", ", ascendingResult)); // 3, 12, 17, 25, 42, 56, 78, 89 // Sort descending buffer.CopyFromCPU(unsortedData); // Reset data var descendingSort = accelerator.CreateRadixSort(); var descTempSize = accelerator.ComputeRadixSortTempStorageSize((Index1D)buffer.Length); using var descTempBuffer = accelerator.Allocate1D(descTempSize); descendingSort(accelerator.DefaultStream, buffer.View, descTempBuffer.View); int[] descendingResult = buffer.GetAsArray1D(); Console.WriteLine("Descending sort:"); Console.WriteLine(string.Join(", ", descendingResult)); // 89, 78, 56, 42, 25, 17, 12, 3 } } ``` -------------------------------- ### ILGPU Algorithms Reduce Operation Example Source: https://context7.com/m4rs-mt/ilgpu/llms.txt Utilizes the ILGPU.Algorithms library to perform parallel reduce operations like sum and max. Requires enabling algorithms in the context. ```csharp using ILGPU; using ILGPU.Algorithms; using ILGPU.Algorithms.ScanReduceOperations; using ILGPU.Algorithms.Sequencers; using ILGPU.Runtime; using System; public class Program { static void Main() { // Enable algorithms library in context using Context context = Context.Create(builder => builder.Default().EnableAlgorithms()); using Accelerator accelerator = context.GetPreferredDevice(false).CreateAccelerator(context); // Create and fill buffer with sequence 0, 1, 2, ..., 63 using var buffer = accelerator.Allocate1D(64); using var result = accelerator.Allocate1D(1); accelerator.Sequence(accelerator.DefaultStream, buffer.View, new Int32Sequencer()); // Reduce with sum operation accelerator.Reduce( accelerator.DefaultStream, buffer.View, result.View); int[] sumResult = result.GetAsArray1D(); Console.WriteLine($"Sum of 0..63: {sumResult[0]}"); // 2016 // Custom reduce with max accelerator.Reduce( accelerator.DefaultStream, buffer.View, result.View); int[] maxResult = result.GetAsArray1D(); Console.WriteLine($"Max of 0..63: {maxResult[0]}"); // 63 } } ``` -------------------------------- ### ILGPU Warp Shuffle Operations Example Source: https://context7.com/m4rs-mt/ilgpu/llms.txt Demonstrates ShuffleDown, ShuffleXor, and Broadcast operations for inter-thread communication within a warp. Requires ILGPU runtime. ```csharp using ILGPU; using ILGPU.Runtime; using System; public class Program { static void ShuffleDownKernel(ArrayView dataView) { int value = Group.IdxX; // Shuffle down by 2 lanes: each thread gets value from thread + 2 value = Warp.ShuffleDown(value, 2); dataView[Grid.GlobalIndex.X] = value; } static void ShuffleXorKernel(ArrayView dataView) { int value = Group.IdxX; // XOR shuffle: exchange with lane XOR'd by mask value = Warp.ShuffleXor(value, 1); // Exchange with neighbor dataView[Grid.GlobalIndex.X] = value; } static void BroadcastKernel(ArrayView dataView, int sourceValue) { // Broadcast from lane 0 to all lanes in warp int value = Warp.Shuffle(sourceValue, 0); dataView[Grid.GlobalIndex.X] = value; } static void Main() { using Context context = Context.CreateDefault(); using Accelerator accelerator = context.GetPreferredDevice(false).CreateAccelerator(context); int warpSize = accelerator.WarpSize; KernelConfig config = (1, warpSize); // 1 group, warpSize threads using var buffer = accelerator.Allocate1D(warpSize); // Shuffle down kernel var shuffleDown = accelerator.LoadStreamKernel>(ShuffleDownKernel); shuffleDown(config, buffer.View); int[] results = buffer.GetAsArray1D(); Console.WriteLine($"ShuffleDown by 2:"); for (int i = 0; i < Math.Min(8, warpSize); i++) Console.WriteLine($" Lane {i}: {results[i]}"); // Lane i gets value from lane i+2 // Broadcast kernel var broadcast = accelerator.LoadStreamKernel, int>(BroadcastKernel); broadcast(config, buffer.View, 42); results = buffer.GetAsArray1D(); Console.WriteLine($"Broadcast from lane 0 (all should be 42): {results[0]}, {results[warpSize / 2]}"); } } ``` -------------------------------- ### Create and Inspect Accelerators Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/02_Beginner/01_Context-and-Accelerators.md Demonstrates creating a context with various accelerator types (all, CPU, Cuda, OpenCL) and then iterating through and printing information for each available accelerator. Requires specific runtime namespaces like 'ILGPU.Runtime.CPU', 'ILGPU.Runtime.Cuda', and 'ILGPU.Runtime.OpenCL'. ```csharp using ILGPU; using ILGPU.Runtime; using ILGPU.Runtime.CPU; using ILGPU.Runtime.Cuda; using ILGPU.Runtime.OpenCL; using System; using System.IO; public static class Program { public static void Main() { // Builds a context that has all possible accelerators. using Context context = Context.CreateDefault(); // Builds a context that only has CPU accelerators. //using Context context = Context.Create(builder => builder.CPU()); // Builds a context that only has Cuda accelerators. //using Context context = Context.Create(builder => builder.Cuda()); // Builds a context that only has OpenCL accelerators. //using Context context = Context.Create(builder => builder.OpenCL()); // Builds a context with only OpenCL and Cuda acclerators. //using Context context = Context.Create(builder => //{ // builder // .OpenCL() // .Cuda(); //}); // Prints all accelerators. foreach (Device d in context) { using Accelerator accelerator = d.CreateAccelerator(context); Console.WriteLine(accelerator); Console.WriteLine(GetInfoString(accelerator)); } // Prints all CPU accelerators. foreach (CPUDevice d in context.GetCPUDevices()) { using CPUAccelerator accelerator = (CPUAccelerator)d.CreateAccelerator(context); Console.WriteLine(accelerator); Console.WriteLine(GetInfoString(accelerator)); } // Prints all Cuda accelerators. foreach (Device d in context.GetCudaDevices()) { using Accelerator accelerator = d.CreateAccelerator(context); Console.WriteLine(accelerator); Console.WriteLine(GetInfoString(accelerator)); } // Prints all OpenCL accelerators. foreach (Device d in context.GetCLDevices()) { using Accelerator accelerator = d.CreateAccelerator(context); Console.WriteLine(accelerator); Console.WriteLine(GetInfoString(accelerator)); } } private static string GetInfoString(Accelerator a) { StringWriter infoString = new StringWriter(); a.PrintInformation(infoString); return infoString.ToString(); } } ``` -------------------------------- ### Install Python Dependencies Source: https://github.com/m4rs-mt/ilgpu/blob/master/Site/DOCUMENTATION.md Install the necessary Python packages required for the build scripts using pip. ```shell # 1. install requirements pip install -r scripts/requirements.txt ``` -------------------------------- ### Initialize and Use Accelerators Source: https://github.com/m4rs-mt/ilgpu/wiki/Accelerators-and-Streams Initializes a Context and demonstrates creating and using CPU and CUDA accelerators. It also shows how to iterate over all available accelerators and create them by ID. Ensure accelerators are disposed of properly. ```csharp class ... { static void Main(string[] args) { // Initialize a new ILGPU context using var context = new Context(); using (var cpuAccelerator = new CPUAccelerator(context); // Perform operations on the CPU using var cudaAccelerator = new CudaAccelerator(context); // Perform operations on the default Cuda device // Iterate over all available accelerators foreach (var acceleratorId in Accelerator.Accelerators) { using (var accl = Accelerator.Create(context, acceleratorId)) { // Perform operations } } } } ``` -------------------------------- ### Immediate Kernel Launching Source: https://github.com/m4rs-mt/ilgpu/wiki/Kernels Shows how to immediately compile and launch kernels using `Launch` and `LaunchAutoGrouped` methods. These methods support both default and specified streams for kernel execution. ```csharp class ... { static void MyKernel(...) { } static void MyImplicitKernel(Index1 index, ...) { } static void Main(string[] args) { // ... // Launch explicitly grouped MyKernel using the default stream accl.Launch(MyKernel, < MyKernelConfig >, ...); // Launch explicitly grouped MyKernel using the given stream accl.Launch(stream, MyKernel, < MyKernelConfig >, ...); // Launch implicitly grouped MyKernel using the default stream accl.LaunchAutoGrouped(MyImplicitKernel, new Index1(...), ...); // Launch implicitly grouped MyKernel using the given stream accl.LaunchAutoGrouped(stream, MyImplicitKernel, new Index1(...), ...); } } ``` -------------------------------- ### Direct Kernel Launching with `Launch` Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/03_Advanced/07_Inside-ILGPU.md Use the `Launch` method for direct kernel dispatch. Arguments are boxed, so typed launchers are recommended for performance. Ensure accelerator synchronization after launching. ```csharp class ... { static void MyKernel(Index1D index, ArrayView data, int c) { data[index] = index + c; } static void Main(string[] args) { ... var buffer = accelerator.Allocate(1024); // Load a sample kernel MyKernel var compiledKernel = backend.Compile(...); using (var k = accelerator.LoadAutoGroupedKernel(compiledKernel)) { k.Launch(buffer.Extent, buffer.View, 1); ... accelerator.Synchronize(); } ... } } ``` -------------------------------- ### Get Compiled Kernel Instance Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/03_Advanced/02_Kernels.md Retrieve the underlying CompiledKernel instance from a kernel launcher. This allows access to accelerator-specific properties. ```csharp var compiledKernel = launcher.GetCompiledKernel(); ``` -------------------------------- ### Load and Launch Kernels with High-Level API Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/03_Advanced/02_Kernels.md Demonstrates loading kernels using `LoadAutoGroupedStreamKernel` and `LoadAutoGroupedKernel`. These methods simplify kernel management and execution. ```csharp class ... { static void MyKernel(Index1D index, ArrayView data, int c) { data[index] = index + c; } static void Main(string[] args) { ... var buffer = accelerator.Allocate1D(1024); // Load a sample kernel MyKernel using one of the available overloads var kernelWithDefaultStream = accelerator.LoadAutoGroupedStreamKernel< Index1D, ArrayView, int>(MyKernel); kernelWithDefaultStream(buffer.Extent, buffer.View, 1); // Load a sample kernel MyKernel using one of the available overloads var kernelWithStream = accelerator.LoadAutoGroupedKernel< Index1D, ArrayView, int>(MyKernel); kernelWithStream(someStream, buffer.Extent, buffer.View, 1); ... } } ``` -------------------------------- ### Configure ILGPU Context with Builder Source: https://context7.com/m4rs-mt/ilgpu/llms.txt Demonstrates various configurations for the ILGPU Context Builder, including specific accelerator types, enabling algorithms, fast math, and debugging features. ```csharp using ILGPU; using ILGPU.Runtime; public class Program { static void Main() { // Create context with specific accelerators only using Context cudaContext = Context.Create(builder => builder.Cuda()); // Create context with all accelerators using Context allContext = Context.Create(builder => builder.AllAccelerators()); // Create context with algorithms library and fast math using Context fastContext = Context.Create(builder => builder .Default() .EnableAlgorithms() .Math(MathMode.Fast)); // Create context with debugging enabled using Context debugContext = Context.Create(builder => builder .Default() .DebugSymbols() .Assertions() .IOOperations()); // Enable Interop.Write for printf-style debugging // Iterate all available devices foreach (Device device in allContext) { Console.WriteLine($"Found device: {device.Name} ({device.AcceleratorType})"); } } } ``` -------------------------------- ### Navigate to Site Directory Source: https://github.com/m4rs-mt/ilgpu/blob/master/Site/DOCUMENTATION.md Change the current directory to the 'Site' folder to begin build operations. ```shell cd ./Site ``` -------------------------------- ### Compare Old and New Kernel Launchers in ILGPU Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/04_Upgrade-Guides/03_v0.7.X-to-v0.8.X.md Demonstrates the syntax difference between the old GroupedIndex-based kernel launching and the new approach using static Grid and Group properties. The new method simplifies access to grid and group indices. ```csharp static void OldKernel(GroupedIndex index, ArrayView data) { var globalIndex = index.ComputeGlobalIndex(); data[globalIndex] = 42; } ``` ```csharp static void NewKernel(ArrayView data) { var globalIndex = Grid.GlobalIndex.X; // or var globalIndex = Group.IdxX + Grid.IdxX * Group.DimX; data[globalIndex] = 42; } ``` ```csharp static void ...(...) { using var context = new Context(); using var accl = new CudaAccelerator(context); // Old way var oldKernel = accl.LoadStreamKernel>(OldKernel); ... oldKernel(new GroupedIndex(, ), buffer.View); // New way var newKernel = accl.LoadStreamKernel>(NewKernel); ... newKernel((, ), buffer.View); // Or newKernel(new KernelConfig(, ), buffer.View); // Or (using dynamic shared memory) var sharedMemConfig = SharedMemoryConfig.RequestDynamic(); newKernel((, , sharedMemConfig), buffer.View); ... } ``` -------------------------------- ### Create ILGPU Context and Accelerator Source: https://context7.com/m4rs-mt/ilgpu/llms.txt Initializes the ILGPU context and selects a preferred non-CPU accelerator. Prints device information. ```csharp using ILGPU; using ILGPU.Runtime; using System; public class Program { static void Main() { // Create default context with all available accelerators using Context context = Context.CreateDefault(); // Get the preferred (most powerful) non-CPU device Device device = context.GetPreferredDevice(preferCPU: false); // Create accelerator for the device using Accelerator accelerator = device.CreateAccelerator(context); // Print device information accelerator.PrintInformation(); Console.WriteLine($"Device: {accelerator.Name}"); Console.WriteLine($"Max threads per group: {accelerator.MaxNumThreadsPerGroup}"); Console.WriteLine($"Warp size: {accelerator.WarpSize}"); } } ``` -------------------------------- ### Initialize ILGPU Context and Accelerator Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/02_Beginner/03_Kernels-and-Simple-Programs.md Creates a default ILGPU context and obtains an accelerator, preferably from a GPU device. Ensure the context and accelerator are disposed after use. ```c# Context context = Context.CreateDefault(); Accelerator accelerator = context.GetPreferredDevice(preferCPU: false) .CreateAccelerator(context); ``` -------------------------------- ### Immediate Kernel Launching with Accelerator Methods Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/03_Advanced/02_Kernels.md Shows how to immediately compile and launch kernels using `Launch` and `LaunchAutoGrouped` methods. This feature is available from ILGPU v0.10.0 and uses a strong-reference based kernel cache. ```csharp class ... { static void MyKernel(...) { } static void MyImplicitKernel(Index1D index, ...) { } static void Main(string[] args) { // ... // Launch explicitly grouped MyKernel using the default stream accl.Launch(MyKernel, < MyKernelConfig >, ...); // Launch explicitly grouped MyKernel using the given stream accl.Launch(stream, MyKernel, < MyKernelConfig >, ...); // Launch implicitly grouped MyKernel using the default stream accl.LaunchAutoGrouped(MyImplicitKernel, new Index1D(...), ...); // Launch implicitly grouped MyKernel using the given stream accl.LaunchAutoGrouped(stream, MyImplicitKernel, new Index1D(...), ...); } } ``` -------------------------------- ### Create and Use Typed Kernel Launcher Source: https://github.com/m4rs-mt/ilgpu/wiki/Inside-ILGPU Demonstrates creating a typed kernel launcher delegate for a kernel and invoking it with an `AcceleratorStream`. Ensure the kernel parameters match the delegate signature. ```csharp class ... { static void MyKernel(Index index, ArrayView data, int c) { data[index] = index + c; } static void Main(string[] args) { ... var buffer = accelerator.Allocate(1024); // Load a sample kernel MyKernel var compiledKernel = backend.Compile(...); using (var k = accelerator.LoadAutoGroupedKernel(compiledKernel)) { var launcherWithCustomAcceleratorStream = k.CreateLauncherDelegate>(); launcherWithCustomAcceleratorStream(someStream, buffer.Extent, buffer.View, 1); ... } ... } } ``` -------------------------------- ### ILGPU Kernel and Main Execution Flow Source: https://github.com/m4rs-mt/ilgpu/wiki/Home This C# code demonstrates a simple ILGPU kernel for element-wise addition and the main function to set up the ILGPU context, load the kernel, allocate memory, launch the kernel on a CUDA accelerator, synchronize, and retrieve the results. ```csharp class ... { static void MyKernel( Index1 index, // The global thread index (1D in this case) ArrayView dataView, // A view to a chunk of memory (1D in this case) int constant) // A sample uniform constant { dataView[index] = index + constant; } public static void Main(string[] args) { // Create the required ILGPU context using var context = new Context(); using var accelerator = new CudaAccelerator(context); // accelerator.LoadAutoGroupedStreamKernel creates a typed launcher // that implicitly uses the default accelerator stream. // In order to create a launcher that receives a custom accelerator stream // use: accelerator.LoadAutoGroupedKernel int>(...) var myKernel = accelerator.LoadAutoGroupedStreamKernel< Index1, ArrayView, int>(MyKernel); // Allocate some memory using var buffer = accelerator.Allocate(1024); // Launch buffer.Length many threads and pass a view to buffer myKernel(buffer.Length, buffer.View, 42); // Wait for the kernel to finish... accelerator.Synchronize(); // Resolve data var data = buffer.GetAsArray(); // ... } } ``` -------------------------------- ### Load and Launch Kernels with Default Stream Source: https://github.com/m4rs-mt/ilgpu/wiki/Kernels Demonstrates loading a kernel using `LoadAutoGroupedStreamKernel` which utilizes the default accelerator stream. The kernel is then invoked with specific parameters. ```csharp class ... { static void MyKernel(Index index, ArrayView data, int c) { data[index] = index + c; } static void Main(string[] args) { ... var buffer = accelerator.Allocate(1024); // Load a sample kernel MyKernel using one of the available overloads var kernelWithDefaultStream = accelerator.LoadAutoGroupedStreamKernel< Index, ArrayView, int>(MyKernel); kernelWithDefaultStream(buffer.Extent, buffer.View, 1); // Load a sample kernel MyKernel using one of the available overloads var kernelWithStream = accelerator.LoadAutoGroupedKernel< Index, ArrayView, int>(MyKernel); kernelWithStream(someStream, buffer.Extent, buffer.View, 1); ... } } ``` -------------------------------- ### Direct Kernel Launching with Boxing Source: https://github.com/m4rs-mt/ilgpu/wiki/Inside-ILGPU Launch a loaded kernel using the generic Launch method. Note that arguments are boxed, leading to potential performance overhead and lack of type safety. Typed launchers are recommended for performance. ```csharp class ... { static void MyKernel(Index index, ArrayView data, int c) { data[index] = index + c; } static void Main(string[] args) { ... var buffer = accelerator.Allocate(1024); // Load a sample kernel MyKernel var compiledKernel = backend.Compile(...); using (var k = accelerator.LoadAutoGroupedKernel(compiledKernel)) { k.Launch(buffer.Extent, buffer.View, 1); ... accelerator.Synchronize(); } ... } } ``` -------------------------------- ### Create Default IL Backend Source: https://github.com/m4rs-mt/ilgpu/wiki/Inside-ILGPU Instantiates a user-defined MSIL backend for .NET code generation within a given ILGPU context. Ensure the context and backend are disposed properly. ```csharp using (var context = new Context()) { // Creats a user-defined MSIL backend for .Net code generation using (var cpuBackend = new DefaultILBackend(context)) { // Use custom backend } // Creates a user-defined backend for NVIDIA GPUs using compute capability 5.0 using (var ptxBackend = new PTXBackend( context, PTXArchitecture.SM_50, TargetPlatform.X64)) { // Use custom backend } } ``` -------------------------------- ### Create and Synchronize Accelerator Streams Source: https://github.com/m4rs-mt/ilgpu/wiki/Accelerators-and-Streams Demonstrates creating a second accelerator stream and synchronizing both the default and the custom stream to manage asynchronous operations. ```csharp class ... { static void Main(string[] args) { ... var defaultStream = accelerator.DefaultStream; using (var secondStream = accelerator.CreateStream()) { // Perform actions using default stream... // Perform actions on second stream... // Wait for results from the first stream. defaultStream.Synchronize(); // Use results async compared to operations on the second stream... // Wait for results from the second stream secondStream.Synchronize(); ... } } } ``` -------------------------------- ### Create and Use Array Views Source: https://github.com/m4rs-mt/ilgpu/wiki/Memory-Buffers-and-Views Shows how to create an ArrayView from a memory buffer and obtain sub-views. ArrayViews simplify index computations and can be passed to kernels. Accesses are bounds-checked in Debug mode. ```csharp class ... { static void MyKernel(Index index, ArrayView view1, ArrayView view2) { ConvertToFloatSample( view1.GetSubView(0, view1.Length / 2), view2.GetSubView(0, view2.Length / 2)); } static void ConvertToFloatSample(ArrayView source, ArrayView target) { for (Index i = 0, e = source.Extent; i < e; ++i) target[i] = source[i]; } static void Main(string[] args) { ... using (var buffer = accelerator.Allocat<...>(...)) { var mainView = buffer.View; var subView = mainView.GetSubView(0, 1024); } } } ``` -------------------------------- ### Basic Memory Management with MemoryBuffer in C# Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/02_Beginner/02_MemoryBuffers-and-ArrayViews.md Illustrates allocating host and device memory, copying data between them using CopyFromCPU and CopyToCPU, and accessing device memory via ArrayView. Note that direct host access to device memory is not permitted and will cause a crash. ```csharp using System; using ILGPU; using ILGPU.Runtime; using ILGPU.Runtime.CPU; public static class Program { public static readonly bool debug = false; static void Main() { // We still need the Context and Accelerator boiler plate. Context context = Context.CreateDefault(); Accelerator accelerator = context.CreateCPUAccelerator(0); // Gets array of 1000 doubles on host. double[] doubles = new double[1000]; // Gets MemoryBuffer on device with same size and contents as doubles. MemoryBuffer1D doublesOnDevice = accelerator.Allocate1D(doubles); // What if we change the doubles on the host and need to update the device side memory? for (int i = 0; i < doubles.Length; i++) { doubles[i] = i * Math.PI; } // We call MemoryBuffer.CopyFrom which copies any linear slice of doubles into the device side memory. doublesOnDevice.CopyFromCPU(doubles); // What if we change the doublesOnDevice and need to write that data into host memory? doublesOnDevice.CopyToCPU(doubles); // You can copy data to and from MemoryBuffers into any array / span / memorybuffer that allocates the same // type. for example: double[] doubles2 = new double[doublesOnDevice.Length]; doublesOnDevice.CopyFromCPU(doubles2); // There are also helper functions, but be aware of what a function does. // As an example this function is shorthand for the above two lines. // This completely allocates a new double[] on the host. This is slow. double[] doubles3 = doublesOnDevice.GetAsArray1D(); // Notice that you cannot access memory in a MemoryBuffer or an ArrayView from host code. // If you uncomment the following lines they should crash. // doublesOnDevice[1] = 0; // double d = doublesOnDevice[1]; // There is not much we can show with ArrayViews currently, but in the // Kernels Tutorial it will go over much more. ArrayView1D doublesArrayView = doublesOnDevice.View; // do not forget to dispose of everything in the reverse order you constructed it. doublesOnDevice.Dispose(); // note the doublesArrayView is now invalid, but does not need to be disposed. accelerator.Dispose(); context.Dispose(); } } ``` -------------------------------- ### Enable ILGPU Algorithms Library Source: https://github.com/m4rs-mt/ilgpu/wiki/Getting-Started Shows how to enable the ILGPU.Algorithms library in C# to utilize extensions like scan, reduce, and sort. This must be called before instantiating Accelerator objects. ```csharp using ILGPU.Algorithms; class ... { static void ...(...) { using var context = new Context(); // Enable all algorithms and extension methods context.EnableAlgorithms(); ... } } ``` -------------------------------- ### Deprecated LightningContext Initialize vs. New Accelerator Initialize Source: https://github.com/m4rs-mt/ilgpu/wiki/Upgrade-v0.1.X-to-v0.2.X Shows the old method of initializing a target view using LightningContext and the new, equivalent method using an Accelerator instance. ```csharp var lc = LightningContext.Create(context, ...); lp.Initialize(targetView); ``` ```csharp var accl = Accelerator.Create(context, acceleratorId); accl.Initialize(targetView); ``` -------------------------------- ### Initialize ILGPU Context Source: https://github.com/m4rs-mt/ilgpu/wiki/Getting-Started Demonstrates the basic structure for initializing and managing an ILGPU Context within a C# application. Remember to dispose of all child objects before disposing of the main context, as operations are not thread-safe. ```csharp class ... { static void Main(string[] args) { using var context = new Context(); // ILGPU-specific functionality goes here // Dispose all other classes before disposing the ILGPU context } } ``` -------------------------------- ### Launch Auto-Grouped Kernel with ILGPU Source: https://context7.com/m4rs-mt/ilgpu/llms.txt Shows how to define a simple kernel that operates on a 1D array view and launch it using ILGPU's auto-grouped thread configuration. The first parameter of the kernel is always the thread index. ```csharp using ILGPU; using ILGPU.Runtime; using System; public class Program { // Kernel: first parameter is always the index, followed by data views and constants static void MyKernel(Index1D index, ArrayView data, int constant) { data[index] = index + constant; } static void Main() { using Context context = Context.CreateDefault(); using Accelerator accelerator = context.GetPreferredDevice(false).CreateAccelerator(context); // Allocate buffer using var buffer = accelerator.Allocate1D(1024); // Load kernel with auto-grouped thread configuration var kernel = accelerator.LoadAutoGroupedStreamKernel, int>(MyKernel); // Launch kernel: first param is extent (number of threads), then kernel params kernel((int)buffer.Length, buffer.View, 42); // Synchronize and get results accelerator.Synchronize(); int[] results = buffer.GetAsArray1D(); // Verify: results[i] should equal i + 42 Console.WriteLine($"results[0] = {results[0]}"); // 42 Console.WriteLine($"results[100] = {results[100]}"); // 142 Console.WriteLine($"results[1023] = {results[1023]}"); // 1065 } } ``` -------------------------------- ### Create and Use Array Views Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/03_Advanced/01_Memory-Buffers-and-Views.md Demonstrates creating an ArrayView from a MemoryBuffer and obtaining sub-views. Accesses are bounds-checked in Debug mode and can be enabled in Release builds. ```csharp class ... { static void MyKernel(Index1D index, ArrayView view1, ArrayView view2) { ConvertToFloatSample( view1.GetSubView(0, view1.Length / 2), view2.GetSubView(0, view2.Length / 2)); } static void ConvertToFloatSample(ArrayView source, ArrayView target) { for (Index i = 0, e = source.Extent; i < e; ++i) target[i] = source[i]; } static void Main(string[] args) { ... using (var buffer = accelerator.Allocate1D<...>(...)) { var mainView = buffer.View; var subView = mainView.SubView(0, 1024); } } } ``` -------------------------------- ### Serve Jekyll Site Locally Source: https://github.com/m4rs-mt/ilgpu/blob/master/Site/DOCUMENTATION.md Run the Jekyll server to preview the site locally. Use specific configuration files for development. ```shell # run site locally bundle exec jekyll serve --config _config.yml,_config.development.yml ``` -------------------------------- ### Migrating LightningContext to Accelerator in C# Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/04_Upgrade-Guides/06_v0.1.X-to-v0.2.X.md Demonstrates the transition from deprecated LightningContext creation to the new Accelerator-based approach. Use Accelerator.Create for new projects. ```csharp class ... { public static void Main(string[] args) { // Create the required ILGPU context using (var context = new Context()) { // Deprecated code snippets for creating a LightningContext var ... = LightningContext.CreateCPUContext(context); var ... = LightningContext.CreateCudaContext(context); var ... = LightningContext.Create(context, acceleratorId); // New version: use default ILGPU accelerators and perform // all required operations on an accelerator instance. var ... = new CPUAccelerator(context); var ... = new CudaAccelerator(context); var ... = Accelerator.Create(context, acceleratorId); // Old sample for an Initialize command var lc = LightningContext.Create(context, ...); lc.Initialize(targetView); // New version var accl = Accelerator.Create(context, acceleratorId); accl.Initialize(targetView); } } } ``` -------------------------------- ### Enable ILGPU Algorithms and Extensions Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/04_Upgrade-Guides/04_v0.6.X-to-v0.7.X.md To use algorithms and extension methods from the ILGPU.Algorithms library, you must enable them within the ILGPU context. This sets up the necessary hooks and code generators. ```csharp using ILGPU.Algorithms; class ... { static void ...(...) { using var context = new Context(); // Enable all algorithms and extension methods context.EnableAlgorithms(); ... } } ``` -------------------------------- ### Optimized 32-bit and 64-bit Memory Accesses (Assembly) Source: https://github.com/m4rs-mt/ilgpu/wiki/Memory-Buffers-and-Views Illustrates assembly sequences for 32-bit and 64-bit memory offset calculations in ILGPU kernels. The choice impacts performance and potential overflow issues with 32-bit offsets. ```asm mul.wide.u32 %rd4, %r1, 4; add.u64 %rd3, %rd1, %rd4; ``` ```asm mad.lo.u64 %rd4, %rd3, 4, %rd1; ``` -------------------------------- ### List All ILGPU Devices Source: https://github.com/m4rs-mt/ilgpu/blob/master/Docs/02_Beginner/01_Context-and-Accelerators.md Iterates through all devices ILGPU can utilize, printing each one. Requires 'using ILGPU;' and 'using ILGPU.Runtime;'. ```csharp using ILGPU; using ILGPU.Runtime; using System; public static class Program { static void Main() { Context context = Context.Create(builder => builder.AllAccelerators()); foreach (Device device in context) { Console.WriteLine(device); } } } ```