/// <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());
            }
        }
Example #5
0
        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());
            }
        }