/// <summary> /// Creates a kernel for every <c>kernel</c> function in program. /// </summary> /// <returns> The collection of created kernels. </returns> /// <remarks> kernels are not created for any <c>kernel</c> functions in program that do not have the same function definition across all devices for which a program executable has been successfully built. </remarks> public ICollection <IComputeKernel> CreateAllKernels(IComputeProgram program) { var kernels = new Collection <IComputeKernel>(); var error = OpenCL110.CreateKernelsInProgram( program.Handle, 0, null, out int kernelsCount); ComputeException.ThrowOnError(error); var kernelHandles = new CLKernelHandle[kernelsCount]; error = OpenCL110.CreateKernelsInProgram( program.Handle, kernelsCount, kernelHandles, out kernelsCount); ComputeException.ThrowOnError(error); for (int i = 0; i < kernelsCount; i++) { kernels.Add(CreateKernel(kernelHandles[i])); } return(kernels); }
/// <summary> /// Creates a kernel for every <c>kernel</c> function in program. /// </summary> /// <returns> The collection of created kernels. </returns> /// <remarks> kernels are not created for any <c>kernel</c> functions in program that do not have the same function definition across all devices for which a program executable has been successfully built. </remarks> public ICollection <IComputeKernel> CreateAllKernels(IComputeProgram program) { var kernels = new Collection <IComputeKernel>(); OpenCL110.CreateKernelsInProgramWrapper(program.Handle, 0, null, out int kernelsCount); var kernelHandles = new CLKernelHandle[kernelsCount]; OpenCL110.CreateKernelsInProgramWrapper(program.Handle, kernelsCount, kernelHandles, out kernelsCount); for (int i = 0; i < kernelsCount; i++) { kernels.Add(CreateKernel(kernelHandles[i])); } return(kernels); }
/// <summary> /// Creates a kernel for a kernel function of a specified name. /// </summary> /// <returns> The created kernel. </returns> public IComputeKernel CreateKernel(IComputeProgram program, string functionName) { var kernel = new ComputeKernel120(); kernel.Handle = OpenCL120.CreateKernel( program.Handle, functionName, out ComputeErrorCode error); ComputeException.ThrowOnError(error); kernel.SetID(kernel.Handle.Value); kernel.FunctionName = functionName; logger.Info("Create " + this + " in Thread(" + Thread.CurrentThread.ManagedThreadId + ").", "Information"); return(kernel); }
public void Run(IComputeContext context, TextWriter log) { this.log = log; var builder = new OpenCL100Factory(); try { program = builder.BuildComputeProgram(context, clSource); program.Build(null, null, notify, IntPtr.Zero); } catch (Exception e) { log.WriteLine(e.ToString()); } }
public void Run(IComputeContext context, TextWriter log) { var builder = new OpenCL100Factory(); try { // Create the arrays and fill them with random data. int count = 10; float[] arrA = new float[count]; float[] arrB = new float[count]; float[] arrC = new float[count]; Random rand = new Random(); for (int i = 0; i < count; i++) { arrA[i] = (float)(rand.NextDouble() * 100); arrB[i] = (float)(rand.NextDouble() * 100); } // Create the input buffers and fill them with data from the arrays. // Access modifiers should match those in a kernel. // CopyHostPointer means the buffer should be filled with the data provided in the last argument. var a = new ComputeBuffer <float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, arrA); var b = new ComputeBuffer <float>(context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.CopyHostPointer, arrB); // The output buffer doesn't need any data from the host. Only its size is specified (arrC.Length). var c = new ComputeBuffer <float>(context, ComputeMemoryFlags.WriteOnly, arrC.Length); // Create and build the opencl program. program = builder.BuildComputeProgram(context, clProgramSource); program.Build(null, null, null, IntPtr.Zero); // Create the kernel function and set its arguments. var kernel = builder.CreateKernel(program, "VectorAdd"); kernel.SetMemoryArgument(0, a); kernel.SetMemoryArgument(1, b); kernel.SetMemoryArgument(2, c); // Create the event wait list. An event list is not really needed for this example but it is important to see how it works. // Note that events (like everything else) consume OpenCL resources and creating a lot of them may slow down execution. // For this reason their use should be avoided if possible. var eventList = new List <IComputeEvent>(); // Create the command queue. This is used to control kernel execution and manage read/write/copy operations. var commands = new ComputeCommandQueue(context, context.Devices[0], ComputeCommandQueueFlags.None); // Execute the kernel "count" times. After this call returns, "eventList" will contain an event associated with this command. // If eventList == null or typeof(eventList) == ReadOnlyCollection<ComputeEventBase>, a new event will not be created. commands.Execute(kernel, null, new long[] { count }, null, eventList); // Read back the results. If the command-queue has out-of-order execution enabled (default is off), ReadFromBuffer // will not execute until any previous events in eventList (in our case only eventList[0]) are marked as complete // by OpenCL. By default the command-queue will execute the commands in the same order as they are issued from the host. // eventList will contain two events after this method returns. commands.ReadFromBuffer(c, ref arrC, false, eventList); // A blocking "ReadFromBuffer" (if 3rd argument is true) will wait for itself and any previous commands // in the command queue or eventList to finish execution. Otherwise an explicit wait for all the opencl commands // to finish has to be issued before "arrC" can be used. // This explicit synchronization can be achieved in two ways: // 1) Wait for the events in the list to finish, //eventList.Wait(); // 2) Or simply use commands.Finish(); // Print the results to a log/console. for (int i = 0; i < count; i++) { log.WriteLine("{0} + {1} = {2}", arrA[i], arrB[i], arrC[i]); } } catch (Exception e) { log.WriteLine(e.ToString()); } }