Esempio n. 1
0
        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();
            }
        }
Esempio n. 2
0
        /// <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));
        }
Esempio n. 4
0
        /// <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();
        }
Esempio n. 5
0
        /// <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);
        }
Esempio n. 6
0
        /// <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;
            }
        }