예제 #1
0
        internal OpenCLDevice(OpenCLPlatform platform, CLDeviceHandle handle)
        {
            Handle = handle;
            SetID(Handle.Value);

            this.Platform = platform;
        }
예제 #2
0
        /// <summary>
        /// Creates a new <see cref="OpenCLContext"/> on all the <see cref="OpenCLDevice"/>s that match the specified <see cref="OpenCLDeviceTypes"/>.
        /// </summary>
        /// <param name="deviceType"> A bit-field that identifies the type of <see cref="OpenCLDevice"/> to associate with the <see cref="OpenCLContext"/>. </param>
        /// <param name="properties"> A <see cref="OpenCLContextPropertyList"/> of the <see cref="OpenCLContext"/>. </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 <see cref="OpenCLContext"/>. 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 <see cref="OpenCLContext"/> 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 OpenCLContext(OpenCLDeviceType deviceType, OpenCLContextPropertyList properties, OpenCLContextNotifier notify, IntPtr userDataPtr)
        {
            IntPtr[] propertyArray = (properties != null) ? properties.ToIntPtrArray() : null;
            callback = notify;

            OpenCLErrorCode error = OpenCLErrorCode.Success;

            Handle = CL10.CreateContextFromType(propertyArray, deviceType, notify, userDataPtr, out error);
            OpenCLException.ThrowOnError(error);

            SetID(Handle.Value);

            this.properties = properties;
            OpenCLContextProperty platformProperty = properties.GetByName(OpenCLContextProperties.Platform);

            this.platform = OpenCLPlatform.GetByHandle(platformProperty.Value);
            this.devices  = GetDevices();

            //Trace.WriteLine("Create " + this + " in Thread(" + Thread.CurrentThread.ManagedThreadId + ").", "Information");
        }
예제 #3
0
        /// <summary>
        /// Creates a new <see cref="OpenCLContext"/> on a collection of <see cref="OpenCLDevice"/>s.
        /// </summary>
        /// <param name="devices"> A collection of <see cref="OpenCLDevice"/>s to associate with the <see cref="OpenCLContext"/>. </param>
        /// <param name="properties"> A <see cref="OpenCLContextPropertyList"/> of the <see cref="OpenCLContext"/>. </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 <see cref="OpenCLContext"/>. 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 <see cref="OpenCLContext"/> 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 OpenCLContext(List <OpenCLDevice> devices, OpenCLContextPropertyList properties, OpenCLContextNotifier notify, IntPtr notifyDataPtr)
        {
            int handleCount;

            CLDeviceHandle[] deviceHandles = OpenCLTools.ExtractHandles(devices, out handleCount);
            IntPtr[]         propertyArray = (properties != null) ? properties.ToIntPtrArray() : null;
            callback = notify;

            OpenCLErrorCode error = OpenCLErrorCode.Success;

            Handle = CL10.CreateContext(propertyArray, handleCount, deviceHandles, notify, notifyDataPtr, out error);
            OpenCLException.ThrowOnError(error);

            SetID(Handle.Value);

            this.properties = properties;
            OpenCLContextProperty platformProperty = properties.GetByName(OpenCLContextProperties.Platform);

            this.platform = OpenCLPlatform.GetByHandle(platformProperty.Value);
            this.devices  = GetDevices();

            //Trace.WriteLine("Create " + this + " in Thread(" + Thread.CurrentThread.ManagedThreadId + ").", "Information");
        }
예제 #4
0
        /// <summary>
        /// Creates a new <see cref="OpenCLContext"/> on all the <see cref="OpenCLDevice"/>s that match the specified <see cref="OpenCLDeviceTypes"/>.
        /// </summary>
        /// <param name="deviceType"> A bit-field that identifies the type of <see cref="OpenCLDevice"/> to associate with the <see cref="OpenCLContext"/>. </param>
        /// <param name="properties"> A <see cref="OpenCLContextPropertyList"/> of the <see cref="OpenCLContext"/>. </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 <see cref="OpenCLContext"/>. 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 <see cref="OpenCLContext"/> 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 OpenCLContext(OpenCLDeviceType deviceType, OpenCLContextPropertyList properties, OpenCLContextNotifier notify, IntPtr userDataPtr)
        {
            IntPtr[] propertyArray = (properties != null) ? properties.ToIntPtrArray() : null;
            callback = notify;

            OpenCLErrorCode error = OpenCLErrorCode.Success;
            Handle = CL10.CreateContextFromType(propertyArray, deviceType, notify, userDataPtr, out error);
            OpenCLException.ThrowOnError(error);

            SetID(Handle.Value);

            this.properties = properties;
            OpenCLContextProperty platformProperty = properties.GetByName(OpenCLContextProperties.Platform);
            this.platform = OpenCLPlatform.GetByHandle(platformProperty.Value);
            this.devices = GetDevices();

            //Trace.WriteLine("Create " + this + " in Thread(" + Thread.CurrentThread.ManagedThreadId + ").", "Information");
        }
예제 #5
0
        /// <summary>
        /// Creates a new <see cref="OpenCLContext"/> on a collection of <see cref="OpenCLDevice"/>s.
        /// </summary>
        /// <param name="devices"> A collection of <see cref="OpenCLDevice"/>s to associate with the <see cref="OpenCLContext"/>. </param>
        /// <param name="properties"> A <see cref="OpenCLContextPropertyList"/> of the <see cref="OpenCLContext"/>. </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 <see cref="OpenCLContext"/>. 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 <see cref="OpenCLContext"/> 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 OpenCLContext(List<OpenCLDevice> devices, OpenCLContextPropertyList properties, OpenCLContextNotifier notify, IntPtr notifyDataPtr)
        {
            int handleCount;
            CLDeviceHandle[] deviceHandles = OpenCLTools.ExtractHandles(devices, out handleCount);
            IntPtr[] propertyArray = (properties != null) ? properties.ToIntPtrArray() : null;
            callback = notify;

            OpenCLErrorCode error = OpenCLErrorCode.Success;
            Handle = CL10.CreateContext(propertyArray, handleCount, deviceHandles, notify, notifyDataPtr, out error);
            OpenCLException.ThrowOnError(error);
            
            SetID(Handle.Value);
            
            this.properties = properties;
            OpenCLContextProperty platformProperty = properties.GetByName(OpenCLContextProperties.Platform);
            this.platform = OpenCLPlatform.GetByHandle(platformProperty.Value);
            this.devices = GetDevices();

            //Trace.WriteLine("Create " + this + " in Thread(" + Thread.CurrentThread.ManagedThreadId + ").", "Information");
        }
 /// <summary>
 /// Creates a new <see cref="OpenCLContextPropertyList"/> which contains a single item specifying a <see cref="OpenCLPlatform"/>.
 /// </summary>
 /// <param name="platform"> A <see cref="OpenCLPlatform"/>. </param>
 public OpenCLContextPropertyList(OpenCLPlatform platform)
 {
     properties = new List <OpenCLContextProperty>();
     properties.Add(new OpenCLContextProperty(OpenCLContextProperties.Platform, platform.Handle.Value));
 }
        private static void RunKernel(OpenCLPlatform platform, OpenCLDevice device)
        {
            var context = new OpenCLContext(new List<OpenCLDevice> {device}, new OpenCLContextPropertyList(platform), null, IntPtr.Zero);
            var program = LoadProgram(context, device, "ReductionUsingFSCLOpenCLManagedWrapper.reduction.cl");
            var kernel1 = program.CreateKernel("reductionVector");
            var kernel2 = program.CreateKernel("reductionComplete");

            const int numValues = 1024 * 1024;
            const int numValuesPerWorkItem = 4;
            var globalWorkSize = numValues / numValuesPerWorkItem;
            const int localWorkSize = 32;
            var initialNumWorkGroups = globalWorkSize/localWorkSize;
            const int value = 42;
            var data = Enumerable.Repeat(value, numValues).Select(n => (float)n).ToArray();

            var commandQueue = new OpenCLCommandQueue(context, device, OpenCLCommandQueueProperties.None);

            var floatType = typeof (float);
            var floatSize = sizeof (float);

            var dataBuffer1 = new OpenCLBuffer(context, OpenCLMemoryFlags.ReadWrite | OpenCLMemoryFlags.AllocateHostPointer, floatType, new long[] {numValues});
            var dataBuffer2 = new OpenCLBuffer(context, OpenCLMemoryFlags.ReadWrite | OpenCLMemoryFlags.AllocateHostPointer, floatType, new long[] {initialNumWorkGroups*numValuesPerWorkItem});
            var sumBuffer = new OpenCLBuffer(context, OpenCLMemoryFlags.WriteOnly | OpenCLMemoryFlags.AllocateHostPointer, floatType, new long[] { 1 });
            var resultDataBuffer = dataBuffer2;

            using (var pinnedData = new PinnedObject(data))
            {
                commandQueue.WriteToBuffer(pinnedData, dataBuffer1, true, 0L, numValues);
            }

            foreach (var index in Enumerable.Range(0, int.MaxValue))
            {
                var dataBufferIn = index%2 == 0 ? dataBuffer1 : dataBuffer2;
                var dataBufferOut = index%2 == 0 ? dataBuffer2 : dataBuffer1;
                resultDataBuffer = dataBufferOut;

                kernel1.SetMemoryArgument(0, dataBufferIn);
                kernel1.SetMemoryArgument(1, dataBufferOut);
                kernel1.SetLocalArgument(2, localWorkSize*numValuesPerWorkItem*floatSize);

                Console.WriteLine($"Calling commandQueue.Execute(kernel1) with globalWorkSize: {globalWorkSize}; localWorkSize: {localWorkSize}; num work groups: {globalWorkSize / localWorkSize}");

                commandQueue.Execute(kernel1, null, new long[] {globalWorkSize}, new long[] {localWorkSize});

                globalWorkSize /= localWorkSize;
                if (globalWorkSize <= localWorkSize) break;
            }

            kernel2.SetMemoryArgument(0, resultDataBuffer);
            kernel2.SetLocalArgument(1, globalWorkSize*numValuesPerWorkItem*floatSize);
            kernel2.SetMemoryArgument(2, sumBuffer);

            Console.WriteLine($"Calling commandQueue.Execute(kernel2) with globalWorkSize: {globalWorkSize}; localWorkSize: {globalWorkSize}");

            commandQueue.Execute(kernel2, null, new long[] { globalWorkSize }, new long[] { globalWorkSize });

            commandQueue.Finish();

            var sum = new float[1];
            using (var pinnedSum = new PinnedObject(sum))
            {
                commandQueue.ReadFromBuffer(sumBuffer, pinnedSum, true, 0L, 1L);
            }

            const int correctAnswer = numValues * value;

            Console.WriteLine($"OpenCL final answer: {Math.Truncate(sum[0]):N0}; Correct answer: {correctAnswer:N0}");
        }