/// <summary>
        /// Creates a new context on a collection of devices.
        /// </summary>
        /// <param name="devices"> A collection of devices to associate with the context. </param>
        /// <param name="properties"> A list of context properties of the context. </param>
        /// <param name="notify"> A delegate instance that refers to a notification routine. This routine is a callback function that will be used by the OpenCL implementation to report information on errors that occur in the context. The callback function may be called asynchronously by the OpenCL implementation. It is the application's responsibility to ensure that the callback function is thread-safe and that the delegate instance doesn't get collected by the Garbage Collector until context is disposed. If <paramref name="notify"/> is <c>null</c>, no callback function is registered. </param>
        /// <param name="notifyDataPtr"> Optional user data that will be passed to <paramref name="notify"/>. </param>
        public IComputeContext CreateContext(ICollection <IComputeDevice> devices, List <ComputeContextProperty> properties,
                                             ComputeContextNotifier notify, IntPtr notifyDataPtr)
        {
            var context       = new ComputeContext120();
            var deviceHandles = ComputeTools.ExtractHandles(devices, out int handleCount);
            var propertyArray = context.ToIntPtrArray(properties);

            context.Handle = OpenCL120.CreateContext(
                propertyArray,
                handleCount,
                deviceHandles,
                notify,
                notifyDataPtr,
                out ComputeErrorCode error);
            ComputeException.ThrowOnError(error);

            context.SetID(context.Handle.Value);
            var platformProperty = context.GetByName(properties, ComputeContextPropertyName.Platform);

            context.Platform = ComputePlatform.GetByHandle(platformProperty.Value);
            context.Devices  = context.GetDevices();

            logger.Info("Create " + this + " in Thread(" + Thread.CurrentThread.ManagedThreadId + ").", "Information");
            return(context);
        }
Example #2
0
        public List <byte[]> GetBinaries()
        {
            var binaryLengths = GetArrayInfo <CLProgramHandle, ComputeProgramInfo, IntPtr>(
                Handle,
                ComputeProgramInfo.BinarySizes,
                OpenCL120.GetProgramInfoWrapper);

            var      binariesGCHandles    = new GCHandle[binaryLengths.Length];
            var      binariesPtrs         = new IntPtr[binaryLengths.Length];
            var      binaries             = new List <byte[]>();
            GCHandle binariesPtrsGCHandle = GCHandle.Alloc(binariesPtrs, GCHandleType.Pinned);

            try
            {
                for (int i = 0; i < binaryLengths.Length; i++)
                {
                    byte[] binary = new byte[binaryLengths[i].ToInt64()];
                    binariesGCHandles[i] = GCHandle.Alloc(binary, GCHandleType.Pinned);
                    binariesPtrs[i]      = binariesGCHandles[i].AddrOfPinnedObject();
                    binaries.Add(binary);
                }
                OpenCL120.GetProgramInfoWrapper(Handle, ComputeProgramInfo.Binaries, new IntPtr(binariesPtrs.Length * IntPtr.Size),
                                                binariesPtrsGCHandle.AddrOfPinnedObject(), out IntPtr sizeRet);
            }
            finally
            {
                for (int i = 0; i < binaryLengths.Length; i++)
                {
                    binariesGCHandles[i].Free();
                }
                binariesPtrsGCHandle.Free();
            }
            return(binaries);
        }
        /// <summary>
        /// Sets an argument of the kernel (no argument tracking).
        /// </summary>
        /// <param name="index"> The argument index. </param>
        /// <param name="dataSize"> The size of the argument data in bytes. </param>
        /// <param name="dataAddr"> A pointer to the data that should be used as the argument value. </param>
        /// <remarks>
        /// Arguments to the kernel are referred by indices that go from 0 for the leftmost argument to n-1, where n is the total number of arguments declared by the kernel.
        /// <br/>
        /// Note that this method does not provide argument tracking. It is up to the user to reference the kernel arguments (i.e. prevent them from being garbage collected) until the kernel has finished execution.
        /// </remarks>
        public void SetArgument(int index, IntPtr dataSize, IntPtr dataAddr)
        {
            var error = OpenCL120.SetKernelArg(
                Handle,
                index,
                dataSize,
                dataAddr);

            ComputeException.ThrowOnError(error);
        }
        /// <summary>
        /// Creates a new program from an array of source code strings.
        /// </summary>
        /// <param name="context"> A context. </param>
        /// <param name="source"> The source code lines for the program. </param>
        /// <remarks> The created program is associated with the devices. </remarks>
        public IComputeProgram BuildComputeProgram(IComputeContext context, string[] source)
        {
            var program = new ComputeProgram120();

            program.Handle = OpenCL120.CreateProgramWithSource(
                context.Handle,
                source.Length,
                source,
                null,
                out ComputeErrorCode error);
            ComputeException.ThrowOnError(error);
            logger.Info("Create " + this + " in Thread(" + Thread.CurrentThread.ManagedThreadId + ").", "Information");
            return(program);
        }
        /// <summary>
        /// Creates a new program from a specified list of binaries.
        /// </summary>
        /// <param name="context"> A context. </param>
        /// <param name="binaries"> A list of binaries, one for each item in <paramref name="devices"/>. </param>
        /// <param name="devices"> A subset of the context devices. If <paramref name="devices"/> is <c>null</c>, OpenCL will associate every binary from binaries with a corresponding device from devices. </param>
        public IComputeProgram BuildComputeProgram(IComputeContext context, IList <byte[]> binaries, IList <IComputeDevice> devices)
        {
            var program = new ComputeProgram120();
            int count;

            CLDeviceHandle[] deviceHandles;
            if (devices != null)
            {
                deviceHandles = ComputeTools.ExtractHandles(devices, out count);
            }
            else
            {
                deviceHandles = ComputeTools.ExtractHandles(context.Devices, out count);
            }

            IntPtr[]   binariesPtrs      = new IntPtr[count];
            IntPtr[]   binariesLengths   = new IntPtr[count];
            int[]      binariesStats     = new int[count];
            GCHandle[] binariesGCHandles = new GCHandle[count];

            try
            {
                for (int i = 0; i < count; i++)
                {
                    binariesGCHandles[i] = GCHandle.Alloc(binaries[i], GCHandleType.Pinned);
                    binariesPtrs[i]      = binariesGCHandles[i].AddrOfPinnedObject();
                    binariesLengths[i]   = new IntPtr(binaries[i].Length);
                }

                program.Handle = OpenCL120.CreateProgramWithBinary(
                    context.Handle,
                    count,
                    deviceHandles,
                    binariesLengths,
                    binariesPtrs,
                    binariesStats,
                    out ComputeErrorCode error);
                ComputeException.ThrowOnError(error);
            }
            finally
            {
                for (int i = 0; i < count; i++)
                {
                    binariesGCHandles[i].Free();
                }
            }
            logger.Info("Create " + this + " in Thread(" + Thread.CurrentThread.ManagedThreadId + ").", "Information");
            return(program);
        }
        /// <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);
        }
Example #7
0
        /// <summary>
        /// Builds (compiles and links) a program executable from the program source or binary for all or some of the devices.
        /// </summary>
        /// <param name="devices"> A subset or all of devices. If devices is <c>null</c>, the executable is built for every item of devices for which a source or a binary has been loaded. </param>
        /// <param name="options"> A set of options for the OpenCL compiler. </param>
        /// <param name="notify"> A delegate instance that represents a reference to a notification routine. This routine is a callback function that an application can register and which will be called when the program executable has been built (successfully or unsuccessfully). If <paramref name="notify"/> is not <c>null</c>, build does not need to wait for the build to complete and can return immediately. If <paramref name="notify"/> is <c>null</c>, build does not return until the build has completed. The callback function may be called asynchronously by the OpenCL implementation. It is the application's responsibility to ensure that the callback function is thread-safe and that the delegate instance doesn't get collected by the Garbage Collector until the build operation triggers the callback. </param>
        /// <param name="notifyDataPtr"> Optional user data that will be passed to <paramref name="notify"/>. </param>
        public void Build(ICollection <IComputeDevice> devices, string options,
                          ComputeProgramBuildNotifier notify, IntPtr notifyDataPtr)
        {
            var deviceHandles = ComputeTools.ExtractHandles(devices, out int handleCount);
            var BuildOptions  = options ?? "";
            var error         = OpenCL120.BuildProgram(
                Handle,
                handleCount,
                deviceHandles,
                options,
                notify,
                notifyDataPtr);

            ComputeException.ThrowOnError(error);
        }
        /// <summary>
        /// Creates a new sampler.
        /// </summary>
        /// <param name="context"> A context. </param>
        /// <param name="normalizedCoords"> The usage state of normalized coordinates when accessing a image in a kernel. </param>
        /// <param name="addressing"> The <see cref="ComputeImageAddressing"/> mode of the sampler. Specifies how out-of-range image coordinates are handled while reading. </param>
        /// <param name="filtering"> The <see cref="ComputeImageFiltering"/> mode of the sampler. Specifies the type of filter that must be applied when reading data from an image. </param>
        public IComputeSampler CreateSampler(IComputeContext context, bool normalizedCoords,
                                             ComputeImageAddressing addressing, ComputeImageFiltering filtering)
        {
            var sampler = new ComputeSampler120();

            sampler.Handle = OpenCL120.CreateSampler(context.Handle, normalizedCoords, addressing, filtering, out ComputeErrorCode error);
            ComputeException.ThrowOnError(error);

            sampler.SetID(sampler.Handle.Value);

            sampler.Addressing       = addressing;
            sampler.Filtering        = filtering;
            sampler.NormalizedCoords = normalizedCoords;

            logger.Info("Create " + this + " in Thread(" + Thread.CurrentThread.ManagedThreadId + ").", "Information");
            return(sampler);
        }
        private bool disposedValue = false; // Для определения избыточных вызовов

        public void Dispose(bool disposing)
        {
            if (!disposedValue)
            {
                if (disposing)
                {
                    // TODO: освободить управляемое состояние (управляемые объекты).
                }
                // TODO: освободить неуправляемые ресурсы (неуправляемые объекты) и переопределить ниже метод завершения.
                // TODO: задать большим полям значение NULL.
                if (Handle.IsValid)
                {
                    logger.Info("Dispose " + this + " in Thread(" + Thread.CurrentThread.ManagedThreadId + ").", "Information");
                    OpenCL120.ReleaseSampler(Handle);
                    Handle.Invalidate();
                }
                disposedValue = true;
            }
        }
        /// <summary>
        /// Creates a new context on all the devices that match the specified <see cref="ComputeDeviceTypes"/>.
        /// </summary>
        /// <param name="deviceType"> A bit-field that identifies the type of device to associate with the context. </param>
        /// <param name="properties"> A list of context properties of the context. </param>
        /// <param name="notify"> A delegate instance that refers to a notification routine. This routine is a callback function that will be used by the OpenCL implementation to report information on errors that occur in the context. The callback function may be called asynchronously by the OpenCL implementation. It is the application's responsibility to ensure that the callback function is thread-safe and that the delegate instance doesn't get collected by the Garbage Collector until context is disposed. If <paramref name="notify"/> is <c>null</c>, no callback function is registered. </param>
        /// <param name="userDataPtr"> Optional user data that will be passed to <paramref name="notify"/>. </param>
        public IComputeContext CreateContext(ComputeDeviceTypes deviceType, List <ComputeContextProperty> properties,
                                             ComputeContextNotifier notify, IntPtr userDataPtr)
        {
            var context       = new ComputeContext120();
            var propertyArray = context.ToIntPtrArray(properties);

            context.Handle = OpenCL120.CreateContextFromType(
                propertyArray,
                deviceType,
                notify,
                userDataPtr,
                out ComputeErrorCode error);
            ComputeException.ThrowOnError(error);

            context.SetID(context.Handle.Value);
            var platformProperty = context.GetByName(properties, ComputeContextPropertyName.Platform);

            context.Platform = ComputePlatform.GetByHandle(platformProperty.Value);
            context.Devices  = context.GetDevices();
            logger.Info("Create " + this + " in Thread(" + Thread.CurrentThread.ManagedThreadId + ").", "Information");
            return(context);
        }