public void SetKernelArgumentVal(int index, object value) { // Checks if the index is positive, if not, then an exception is thrown if (index < 0) { throw new OpenClArgumentIndexOutOfRangeException( $"The specified index {index} is invalid. The index of the argument must always be greater or equal to 0." ); } // The set kernel argument method needs a pointer to the pointer, therefore the pointer is pinned, so that the garbage collector can not move it in memory GCHandle garbageCollectorHandle = GCHandle.Alloc(value, GCHandleType.Pinned); try { // Sets the kernel argument and checks if it was successful, if not, then an exception is thrown Result result = KernelsNativeApi.SetKernelArgument( Handle, (uint)index, new UIntPtr((uint)Marshal.SizeOf(value)), garbageCollectorHandle.AddrOfPinnedObject() ); if (result != Result.Success) { throw new OpenClException($"The kernel argument with the index {index} could not be set.", result); } } finally { garbageCollectorHandle.Free(); } }
/// <summary> /// Retrieves the specified information about the OpenCL kernel. /// </summary> /// <typeparam name="T"> /// The type of the data that is to be returned.</param> /// <param name="kernelInformation">The kind of information that is to be retrieved.</param> /// <exception cref="OpenClException"> /// If the information could not be retrieved, then an <see cref="OpenClException" /> /// is thrown. /// </exception> /// <returns>Returns the specified information.</returns> private T GetKernelInformation <T>(KernelInformation kernelInformation) { // Retrieves the size of the return value in bytes, this is used to later get the full information Result result = KernelsNativeApi.GetKernelInformation( Handle, kernelInformation, UIntPtr.Zero, null, out UIntPtr returnValueSize ); if (result != Result.Success) { throw new OpenClException("The kernel information could not be retrieved.", result); } // Allocates enough memory for the return value and retrieves it byte[] output = new byte[returnValueSize.ToUInt32()]; result = KernelsNativeApi.GetKernelInformation( Handle, kernelInformation, new UIntPtr((uint)output.Length), output, out returnValueSize ); if (result != Result.Success) { throw new OpenClException("The kernel information could not be retrieved.", result); } // Returns the output return(InteropConverter.To <T>(output)); }
public void SetKernelArg(string kernelName, uint idx, MemoryAllocation mem) { GCHandle garbageCollectorHandle = GCHandle.Alloc(mem.buffer, GCHandleType.Pinned); var errCode = KernelsNativeApi.SetKernelArgument(kernels[kernelName], idx, new UIntPtr((uint)Marshal.SizeOf(mem.buffer)), garbageCollectorHandle.AddrOfPinnedObject()); garbageCollectorHandle.Free(); ThrowOnError(errCode, String.Format("Failed to set arg #{0} for kernel {1}", idx, kernelName)); }
/// <summary> /// Disposes of the resources that have been acquired by the kernel. /// </summary> /// <param name="disposing">Determines whether managed object or managed and unmanaged resources should be disposed of.</param> public override void Dispose() { // Checks if the kernel has already been disposed of, if not, then it is disposed of if (!IsDisposed) { KernelsNativeApi.ReleaseKernel(Handle); } // Makes sure that the base class can execute its dispose logic base.Dispose(); }
/// <summary> /// Disposes of the resources that have been acquired by the kernel. /// </summary> /// <param name="disposing">Determines whether managed object or managed and unmanaged resources should be disposed of.</param> protected override void Dispose(bool disposing) { // Checks if the kernel has already been disposed of, if not, then it is disposed of if (!this.IsDisposed) { KernelsNativeApi.ReleaseKernel(this.Handle); } // Makes sure that the base class can execute its dispose logic base.Dispose(disposing); }
/// <summary> /// Creates a kernel with the specified name from the program. /// </summary> /// <param name="kernelName">The name of the kernel that is defined in the program.</param> /// <exception cref="OpenClException">If the kernel could not be created, then an <see cref="OpenClException" /> is thrown.</exception> /// <returns>Returns the created kernel.</returns> public Kernel CreateKernel(string kernelName) { // Allocates enough memory for the return value and retrieves it Result result; IntPtr kernelPointer = KernelsNativeApi.CreateKernel(Handle, kernelName, out result); if (result != Result.Success) { throw new OpenClException("The kernel could not be created.", result); } // Creates a new kernel object from the kernel pointer and returns it return(new Kernel(kernelPointer)); }
private void InitCL(String[] kernelSource, String[] kernelNames, string compileArguments) { lock (lockObj) { if (!hasClInitialized && clDevice != null) { Result err; var devicesArray = new IntPtr[] { clDevice }; clContext = ContextsNativeApi.CreateContext(IntPtr.Zero, 1, devicesArray, IntPtr.Zero, IntPtr.Zero, out err); if (err != Result.Success) { throw new OpenClException("Failed to create context!", err); } commandQueue = CommandQueuesNativeApi.CreateCommandQueue(clContext, clDevice, CommandQueueProperty.None, out err); if (err != Result.Success) { throw new OpenClException("Failed to create command queue!", err); } IntPtr[] sourceList = kernelSource.Select(source => Marshal.StringToHGlobalAnsi(source)).ToArray(); clProgram = ProgramsNativeApi.CreateProgramWithSource(clContext, 1, sourceList, null, out err); if (err != Result.Success) { throw new OpenClException("Failed to create program!", err); } err = ProgramsNativeApi.BuildProgram(clProgram, 1, new IntPtr[] { clDevice }, compileArguments, IntPtr.Zero, IntPtr.Zero); if (err != Result.Success) { var infoBuffer = GetProgramBuildInformation <string>(clProgram, clDevice, ProgramBuildInformation.Log); if (err != Result.Success) { throw new OpenClException("Failed to build program! " + (infoBuffer == null ? "?" : infoBuffer.ToString()), err); } } foreach (var item in kernelNames) { kernels[item] = KernelsNativeApi.CreateKernel(clProgram, item, out err); if (err != Result.Success) { throw new OpenClException("Failed to create kernel: " + item, err); } } hasClInitialized = true; } } }
public void CleanupCLResources() { if (hasClInitialized) { FlushWorkingCache(); foreach (var item in kernels) { KernelsNativeApi.ReleaseKernel(item.Value); } kernels.Clear(); ProgramsNativeApi.ReleaseProgram(clProgram); CommandQueuesNativeApi.ReleaseCommandQueue(commandQueue); ContextsNativeApi.ReleaseContext(clContext); hasClInitialized = false; } }