/// <summary> /// Compiles a given compile unit with the specified entry point. /// </summary> /// <param name="unit">The compile unit to compile.</param> /// <param name="entry">The desired entry point.</param> /// <param name="specialization">The kernel specialization.</param> /// <returns>The compiled kernel that represents the compilation result.</returns> public override CompiledKernel Compile( CompileUnit unit, MethodInfo entry, KernelSpecialization specialization) { var entryPoint = new EntryPoint(entry, unit, specialization); CheckMethod(unit, entry, entryPoint); return(new CompiledKernel(Context, entry, new byte[] { }, entry.Name, entryPoint)); }
/// <summary cref="Backend.Compile(CompileUnit, MethodInfo)"/> public override CompiledKernel Compile(CompileUnit unit, MethodInfo entry, KernelSpecialization specialization) { if (unit == null) { throw new ArgumentNullException(nameof(unit)); } if (entry == null) { throw new ArgumentNullException(nameof(entry)); } var entryPoint = new EntryPoint(entry, unit, specialization); // Ensure that the entry point is contained in the lib var backendEntry = CreateEntry(unit, entryPoint, out string entryPointName); PrepareModuleLowering?.Invoke(this, new LLVMBackendEventArgs(unit, unit.LLVMModule)); var targetModule = CloneModule(unit.LLVMModule); try { // Resolve the cloned version of our entry point var targetEntry = GetNamedFunction(targetModule, entryPointName); PrepareModule(unit, targetModule, entryPoint, targetEntry); #if DEBUG if (VerifyModule( targetModule, LLVMVerifierFailureAction.LLVMReturnStatusAction, out IntPtr errorMessage).Value != 0) { throw new InvalidOperationException(string.Format( ErrorMessages.LLVMModuleVerificationFailed, Marshal.PtrToStringAnsi(errorMessage))); } #endif RunPassManager(Context.KernelModulePassManager, targetModule); KernelModuleLowered?.Invoke(this, new LLVMBackendEventArgs(unit, targetModule)); var binaryKernelData = Link(targetModule, targetEntry); return(new CompiledKernel(Context, entry, binaryKernelData, entryPointName, entryPoint)); } finally { // Set the entry function to internal linkage // to avoid further occurances later on SetLinkage(backendEntry, LLVMLinkage.LLVMInternalLinkage); DisposeModule(targetModule); } }
/// <summary> /// Compiles a given compile unit with the specified entry point using /// the given kernel specialization. /// </summary> /// <param name="unit">The compile unit to compile.</param> /// <param name="entry">The desired entry point.</param> /// <param name="specialization">The kernel specialization.</param> /// <returns>The compiled kernel that represents the compilation result.</returns> public abstract CompiledKernel Compile( CompileUnit unit, MethodInfo entry, KernelSpecialization specialization);
public static void Main2() { using (var context = new Context()) { foreach (var acceleratorId in Accelerator.Accelerators) { if (acceleratorId.AcceleratorType == AcceleratorType.CPU) { continue; } using (var accelerator = Accelerator.Create(context, acceleratorId)) { CompiledKernel compiledKernel; using (Backend b = new CLBackend(context, ILGPU.Runtime.OpenCL.CLAcceleratorVendor.AMD)) { MethodInfo methodInfo = typeof(GPU).GetMethod("PixelKernel"); KernelSpecialization spec = KernelSpecialization.Empty; compiledKernel = b.Compile(EntryPointDescription.FromImplicitlyGroupedKernel(methodInfo), spec); // debug: check kernel.Source for source text } var kernel = accelerator.LoadAutoGroupedKernel(compiledKernel); // var kernel = accelerator.LoadAutoGroupedStreamKernel<Index2, ArrayView2D<FSMUnit>>(MathKernel); // kernel = accelerator.LoadAutoGroupedStreamKernel<Index2, ArrayView2D<Color3>, ArrayView<byte>, ArrayView2D<Neuron>>(PixelKernel); MemoryBuffer2D <Color3> buffer = accelerator.Allocate <Color3>(pixelMap.GetLength(0), pixelMap.GetLength(1)); MemoryBuffer <byte> buffer2 = accelerator.Allocate <byte>(imageBytes.Length); MemoryBuffer2D <Neuron> buffer3 = accelerator.Allocate <Neuron>(nrn.GetLength(0), nrn.GetLength(1)); buffer3.CopyFrom(nrn, new LongIndex2(0, 0), new LongIndex2(0, 0), new LongIndex2(nrn.GetLength(0), nrn.GetLength(1))); while (running == true) { Stopwatch sw = new Stopwatch(); sw.Start(); Index2 gridSize = new Index2(pixelMap.GetLength(0), pixelMap.GetLength(1)); //kernel(gridSize, buffer.View, buffer2.View, buffer3.View); sw.OutputDelta("Kernel"); accelerator.Synchronize(); sw.OutputDelta("Sync"); // imageBytes = buffer2.GetAsArray(); buffer2.CopyTo(imageBytes, 0, 0, imageBytes.Length); sw.OutputDelta("Copy ImageBytes"); // Resolve and verify data //pixelMap = buffer.GetAs2DArray(); // buffer.CopyTo(pixelMap, new LongIndex2(0, 0), new LongIndex2(0, 0), new LongIndex2(pixelMap.GetLength(0), pixelMap.GetLength(1))); // Color3[] pixelMap1D = buffer.GetAsArray(); //Copy1DTo2DArray(pixelMap1D, pixelMap); // ~36ms, a bit faster //Array.Copy(pixelMap1D, imageBytes, pixelMap1D.Length); // fails //Buffer.BlockCopy(pixelMap1D, 0, pixelMap, 0, pixelMap1D.Length * Marshal.SizeOf(typeof(Color3))); // fails // pixelMap = Make2DArray(pixelMap1D, pixelMap.GetLength(0), pixelMap.GetLength(1)); // still slow //sw.OutputDelta("Copy PixelMap"); // MainForm.form.DrawPixels(pixelMap); MainForm.form.DrawPixels(imageBytes, pixelMap.GetLength(0), pixelMap.GetLength(1)); Application.DoEvents(); //Debugger.Break(); sw.OutputDelta("DrawPixels"); } buffer.Dispose(); buffer2.Dispose(); buffer3.Dispose(); Application.Exit(); //Debugger.Break(); } } } }
/// <summary> /// Constructs a new entry point targeting the given method. /// </summary> /// <param name="methodInfo">The targeted method.</param> /// <param name="unit">The unit in the current context.</param> /// <param name="specialization">The kernel specialization.</param> public EntryPoint( MethodInfo methodInfo, CompileUnit unit, KernelSpecialization specialization) { MethodInfo = methodInfo; NumDynamicallySizedSharedMemoryVariables = 0; Specialization = specialization; if (!methodInfo.IsStatic) { throw new NotSupportedException(ErrorMessages.InvalidEntryPointInstanceKernelMethod); } var @params = methodInfo.GetParameters(); if (@params.Length < 1) { throw new ArgumentException(ErrorMessages.InvalidEntryPointIndexParameter); } KernelIndexType = UngroupedIndexType = @params[0].ParameterType; Type = KernelIndexType.GetIndexType(); if (Type == IndexType.None) { throw new NotSupportedException(ErrorMessages.InvalidEntryPointIndexParameterOfWrongType); } UngroupedIndexType = Type.GetUngroupedIndexType().GetManagedIndexType(); // Compute the number of actual parameters var uniformVariables = new List <UniformVariable>(@params.Length - 1 + (methodInfo.IsStatic ? 1 : 0)); var sharedMemoryVariables = new List <SharedMemoryVariable>(@params.Length - 1); if (!methodInfo.IsStatic) { uniformVariables.Add( new UniformVariable(0, methodInfo.DeclaringType.MakePointerType(), unit.IntPtrType.SizeOf())); } for (int i = 1, e = @params.Length; i < e; ++i) { var param = @params[i]; if (SharedMemoryAttribute.TryGetSharedMemoryCount(param, out int?count)) { var elementType = GetSharedVariableElementType(param.ParameterType, out bool isArray); var paramSize = elementType.SizeOf(); if (!isArray && count != null && count.Value != 1) { throw new NotSupportedException(ErrorMessages.InvalidUseOfVariableViewsInSharedMemory); } int sharedMemoryVariableIndex = -1; if (isArray && count == null) { sharedMemoryVariableIndex = NumDynamicallySizedSharedMemoryVariables; NumDynamicallySizedSharedMemoryVariables += 1; } sharedMemoryVariables.Add( new SharedMemoryVariable(i, sharedMemoryVariableIndex, param.ParameterType, elementType, isArray, count, paramSize)); } else { var paramSize = param.ParameterType.SizeOf(); uniformVariables.Add( new UniformVariable(i, param.ParameterType, paramSize)); } } UniformVariables = uniformVariables.ToArray(); SharedMemoryVariables = sharedMemoryVariables.ToArray(); if (Type < IndexType.GroupedIndex1D && SharedMemoryVariables.Length > 0) { throw new NotSupportedException(ErrorMessages.NotSupportedUseOfSharedMemory); } foreach (var variable in uniformVariables) { if (variable.VariableType != variable.VariableType.GetLLVMTypeRepresentation()) { throw new NotSupportedException(string.Format( ErrorMessages.NotSupportedKernelParameterType, variable)); } } }