diff --git a/Samples/CudaIPC/CudaIPC.Child/App.config b/Samples/CudaIPC/CudaIPC.Child/App.config new file mode 100644 index 000000000..9d2c7adf3 --- /dev/null +++ b/Samples/CudaIPC/CudaIPC.Child/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/Samples/CudaIPC/CudaIPC.Child/AssemblyAttributes.cs b/Samples/CudaIPC/CudaIPC.Child/AssemblyAttributes.cs new file mode 100644 index 000000000..8c114539a --- /dev/null +++ b/Samples/CudaIPC/CudaIPC.Child/AssemblyAttributes.cs @@ -0,0 +1,3 @@ +using System; + +[assembly: CLSCompliant(true)] diff --git a/Samples/CudaIPC/CudaIPC.Child/CudaIPC.Child.csproj b/Samples/CudaIPC/CudaIPC.Child/CudaIPC.Child.csproj new file mode 100644 index 000000000..727baf959 --- /dev/null +++ b/Samples/CudaIPC/CudaIPC.Child/CudaIPC.Child.csproj @@ -0,0 +1,16 @@ + + + $(LibrarySamplesTargetFrameworks) + Exe + 8.0 + + + + true + AllEnabledByDefault + + + + + + \ No newline at end of file diff --git a/Samples/CudaIPC/CudaIPC.Child/Program.cs b/Samples/CudaIPC/CudaIPC.Child/Program.cs new file mode 100644 index 000000000..399d9e8c7 --- /dev/null +++ b/Samples/CudaIPC/CudaIPC.Child/Program.cs @@ -0,0 +1,70 @@ +// --------------------------------------------------------------------------------------- +// ILGPU Samples +// Copyright (c) 2021-2022 ILGPU Project +// www.ilgpu.net +// +// File: Program.cs +// +// This file is part of ILGPU and is distributed under the University of Illinois Open +// Source License. See LICENSE.txt for details. +// --------------------------------------------------------------------------------------- + +using ILGPU; +using ILGPU.Runtime; +using ILGPU.Runtime.Cuda; +using System; +using System.Globalization; + +namespace CudaIPC.Child +{ + class Program + { + /// + /// A simple kernel writing the index to the data view. + /// + /// The current thread index. + /// The view pointing to our memory buffer. + static void SimpleKernel( + Index1D index, + ArrayView dataView) + { + dataView[index] = index; + } + + /// + /// Accepts a cuda device id, an ipc memory handle as hexstring and its length as arguments. + /// It then maps that memory and executes a simple kernel on it. + /// + static void Main(string[] args) + { + if (args.Length != 3) + { + Console.WriteLine("There should be 3 arguments:"); + Console.WriteLine(" "); + return; + } + + // Parse arguments + int deviceId = int.Parse(args[0], CultureInfo.InvariantCulture); + CudaIpcMemHandle ipcMemHandle = new CudaIpcMemHandle(Convert.FromHexString(args[1])); + int length = int.Parse(args[2], CultureInfo.InvariantCulture); + + // Set up the correct accelerator + using Context context = Context.CreateDefault(); + CudaDevice device = context.GetCudaDevice(deviceId); + using CudaAccelerator accelerator = device.CreateCudaAccelerator(context); + // device.PrintInformation(); + + // Map exported memory + MemoryBuffer cudaIpcMemoryBuffer = + accelerator.MapFromIpcMemHandle(ipcMemHandle, length, sizeof(int), CudaIpcMemFlags.LazyEnablePeerAccess); + ArrayView arrayView = cudaIpcMemoryBuffer.AsArrayView(0, length); + + // load and execute kernel + Action> loadedSimpleKernel = + accelerator.LoadAutoGroupedStreamKernel>( + SimpleKernel); + loadedSimpleKernel(arrayView.IntExtent, arrayView); + } + } +} diff --git a/Samples/CudaIPC/CudaIPC.Host/App.config b/Samples/CudaIPC/CudaIPC.Host/App.config new file mode 100644 index 000000000..9d2c7adf3 --- /dev/null +++ b/Samples/CudaIPC/CudaIPC.Host/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/Samples/CudaIPC/CudaIPC.Host/AssemblyAttributes.cs b/Samples/CudaIPC/CudaIPC.Host/AssemblyAttributes.cs new file mode 100644 index 000000000..8c114539a --- /dev/null +++ b/Samples/CudaIPC/CudaIPC.Host/AssemblyAttributes.cs @@ -0,0 +1,3 @@ +using System; + +[assembly: CLSCompliant(true)] diff --git a/Samples/CudaIPC/CudaIPC.Host/CudaIPC.Host.csproj b/Samples/CudaIPC/CudaIPC.Host/CudaIPC.Host.csproj new file mode 100644 index 000000000..41848ecd5 --- /dev/null +++ b/Samples/CudaIPC/CudaIPC.Host/CudaIPC.Host.csproj @@ -0,0 +1,17 @@ + + + $(LibrarySamplesTargetFrameworks) + Exe + 8.0 + + + + true + AllEnabledByDefault + + + + + + + \ No newline at end of file diff --git a/Samples/CudaIPC/CudaIPC.Host/Program.cs b/Samples/CudaIPC/CudaIPC.Host/Program.cs new file mode 100644 index 000000000..41c61e0cf --- /dev/null +++ b/Samples/CudaIPC/CudaIPC.Host/Program.cs @@ -0,0 +1,64 @@ +// --------------------------------------------------------------------------------------- +// ILGPU Samples +// Copyright (c) 2021-2022 ILGPU Project +// www.ilgpu.net +// +// File: Program.cs +// +// This file is part of ILGPU and is distributed under the University of Illinois Open +// Source License. See LICENSE.txt for details. +// --------------------------------------------------------------------------------------- + +using ILGPU; +using ILGPU.Runtime; +using ILGPU.Runtime.Cuda; +using System; +using System.Diagnostics; + +namespace CudaIPC.Host +{ + class Program + { + /// + /// Exports memory for other processes using CUDA IPC. + /// + static void Main() + { + // Create main context + using var context = Context.CreateDefault(); + + // For each available CUDA device... + foreach (var device in context.GetCudaDevices()) + { + // Create accelerator for the given device + using CudaAccelerator accelerator = device.CreateCudaAccelerator(context); + + if (!device.HasIpcSupport) + { + Console.WriteLine($"{device.Name} does not support inter process comunication!"); + continue; + } + + using MemoryBuffer1D buffer = accelerator.Allocate1D(64); + + // Export memory for other processes + CudaIpcMemHandle cudaIpcMemHandle = accelerator.GetIpcMemoryHandle(buffer); + string handleHex = Convert.ToHexString(cudaIpcMemHandle); + + // Launch CudaIPC.Child + var arguments = $"{device.DeviceId} {handleHex} {buffer.Length}"; + Console.WriteLine(arguments); + var childProcess = Process.Start( + OperatingSystem.IsWindows() ? + "CudaIPC.Child.exe" : "CudaIPC.Child", + arguments + ); + childProcess?.WaitForExit(); + + // Gets changed buffer data onto the CPU and print it. + int[] bufferData = buffer.GetAsArray1D(); + Console.WriteLine(String.Join(" ", bufferData)); + } + } + } +} diff --git a/Samples/ILGPU.Samples.sln b/Samples/ILGPU.Samples.sln index ce9098eb9..1595f331a 100644 --- a/Samples/ILGPU.Samples.sln +++ b/Samples/ILGPU.Samples.sln @@ -135,6 +135,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ILGPU.Analyzers", "..\Src\I EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InterleaveFields", "InterleaveFields\InterleaveFields.csproj", "{1E6D0BC6-CFA1-4F52-9EB9-CAA62DD2F33A}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CudaIPC.Host", "CudaIPC\CudaIPC.Host\CudaIPC.Host.csproj", "{CD0EB089-13B7-4229-AAC1-A8E586E46146}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CudaIPC.Child", "CudaIPC\CudaIPC.Child\CudaIPC.Child.csproj", "{6CFF471A-6CAB-481C-AEB8-464EF3700910}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -381,6 +385,14 @@ Global {1E6D0BC6-CFA1-4F52-9EB9-CAA62DD2F33A}.Debug|Any CPU.Build.0 = Debug|Any CPU {1E6D0BC6-CFA1-4F52-9EB9-CAA62DD2F33A}.Release|Any CPU.ActiveCfg = Release|Any CPU {1E6D0BC6-CFA1-4F52-9EB9-CAA62DD2F33A}.Release|Any CPU.Build.0 = Release|Any CPU + {CD0EB089-13B7-4229-AAC1-A8E586E46146}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {CD0EB089-13B7-4229-AAC1-A8E586E46146}.Debug|Any CPU.Build.0 = Debug|Any CPU + {CD0EB089-13B7-4229-AAC1-A8E586E46146}.Release|Any CPU.ActiveCfg = Release|Any CPU + {CD0EB089-13B7-4229-AAC1-A8E586E46146}.Release|Any CPU.Build.0 = Release|Any CPU + {6CFF471A-6CAB-481C-AEB8-464EF3700910}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6CFF471A-6CAB-481C-AEB8-464EF3700910}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6CFF471A-6CAB-481C-AEB8-464EF3700910}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6CFF471A-6CAB-481C-AEB8-464EF3700910}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -449,6 +461,8 @@ Global {70B69CE3-24A9-463C-B14C-E2934988BBEE} = {25BA2234-5778-40BC-9386-9CE87AB87D1F} {1C5E9E39-3C14-4B52-8D97-04555D5F6331} = {03FCC663-945D-4982-90D8-B14BE52D8FCD} {1E6D0BC6-CFA1-4F52-9EB9-CAA62DD2F33A} = {C1D99632-ED4A-4B08-A14D-4C8DB375934F} + {CD0EB089-13B7-4229-AAC1-A8E586E46146} = {C1D99632-ED4A-4B08-A14D-4C8DB375934F} + {6CFF471A-6CAB-481C-AEB8-464EF3700910} = {C1D99632-ED4A-4B08-A14D-4C8DB375934F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {30E502BD-3826-417F-888F-1CE19CF5C6DA}