Ejemplo n.º 1
0
        public IntPtr CreateAndCompileProgram(string source)
        {
            ErrorCode error;
            IntPtr    programId;

            programId = CL.CreateProgramWithSource(ContextId, 1, new string[] { source }, null, &error);
            if (error != ErrorCode.Success)
            {
                throw new System.InvalidOperationException(String.Format("Error calling CreateProgramWithSource: {0}", error));
            }
            error = (ErrorCode)CL.BuildProgram(programId, 0, (IntPtr[])null, null, IntPtr.Zero, IntPtr.Zero);
            if (error != ErrorCode.Success)
            {
                uint parmSize;
                CL.GetProgramBuildInfo(programId, DeviceId, ProgramBuildInfo.ProgramBuildLog, IntPtr.Zero, IntPtr.Zero, (IntPtr *)&parmSize);
                byte[] value = new byte[parmSize];
                fixed(byte *valuePtr = value)
                {
                    error = (ErrorCode)CL.GetProgramBuildInfo(programId, DeviceId, ProgramBuildInfo.ProgramBuildLog, new IntPtr(&parmSize), new IntPtr(valuePtr), (IntPtr *)IntPtr.Zero.ToPointer());
                }

                if (error != ErrorCode.Success)
                {
                    throw new System.InvalidOperationException(String.Format("Error calling GetProgramBuildInfo: {0}", error));
                }
                throw new System.InvalidOperationException(Encoding.ASCII.GetString(value).Trim('\0'));
            }
            return(programId);
        }
Ejemplo n.º 2
0
        private unsafe void BuildProgram()
        {
            int errorCode;

            fixed(byte *kernelSourcePtr = KernelSource)
            {
                _program = _cl.CreateProgramWithSource(_context, 1, kernelSourcePtr, (nuint)KernelSource.Length, out errorCode);
                CheckSuccess(errorCode);
            }

            var res = _cl.BuildProgram(_program, 1, _deviceId, 0, NotifyCallback, null);

            CheckSuccess(res);

            _kernelHandle = _cl.CreateKernel(_program, KernelName, out errorCode);
            CheckSuccess(errorCode);
        }
Ejemplo n.º 3
0
        public static void Main()
        {
            const int cnBlockSize    = 4;
            const int cnBlocks       = 3;
            IntPtr    cnDimension    = new IntPtr(cnBlocks * cnBlockSize);
            string    sProgramSource = @"
__kernel void
vectorAdd(__global const float * a,
          __global const float * b,
          __global       float * c)
{
    // Vector element index
    int nIndex = get_global_id(0);
    c[nIndex] = a[nIndex] + b[nIndex];
}
";

            ErrorCode error;

            // create OpenCL device & context
            cl_context hContext;

            unsafe { hContext = CL.CreateContextFromType((ContextProperties *)null, DeviceTypeFlags.DeviceTypeDefault, IntPtr.Zero, IntPtr.Zero, &error); }

            // query all devices available to the context
            IntPtr nContextDescriptorSize;

            CL.GetContextInfo(hContext, ContextInfo.ContextDevices, IntPtr.Zero, IntPtr.Zero, out nContextDescriptorSize);
            cl_device_id[] aDevices = new cl_device_id[nContextDescriptorSize.ToInt32()];
            unsafe
            {
                fixed(cl_device_id *ptr = aDevices)
                {
                    IntPtr ret;

                    CL.GetContextInfo(hContext, ContextInfo.ContextDevices, nContextDescriptorSize, new IntPtr(ptr), out ret);
                }
            }


            // create a command queue for first device the context reported
            cl_command_queue hCmdQueue = CL.CreateCommandQueue(hContext, aDevices[0], (CommandQueueFlags)0, out error);
            // create & compile program
            cl_program hProgram;

            unsafe { hProgram = CL.CreateProgramWithSource(hContext, 1, new string[] { sProgramSource }, null, &error); }
            CL.BuildProgram(hProgram, 0, (IntPtr[])null, null, IntPtr.Zero, IntPtr.Zero);

            // create kernel
            cl_kernel hKernel = CL.CreateKernel(hProgram, "vectorAdd", out error);

            // allocate host  vectors
            float[] A = new  float[cnDimension.ToInt32()];
            float[] B = new float[cnDimension.ToInt32()];
            float[] C = new float[cnDimension.ToInt32()];
            // initialize host memory
            Random rand = new Random();

            for (int i = 0; i < A.Length; i++)
            {
                A[i] = rand.Next() % 256;
                B[i] = rand.Next() % 256;
            }

            // allocate device memory
            unsafe
            {
                fixed(float *pA = A)
                fixed(float *pB = B)
                fixed(float *pC = C)
                {
                    cl_mem hDeviceMemA, hDeviceMemB, hDeviceMemC;

                    hDeviceMemA = CL.CreateBuffer(hContext,
                                                  MemFlags.MemReadOnly | MemFlags.MemCopyHostPtr,
                                                  new IntPtr(cnDimension.ToInt32() * sizeof(float)),
                                                  new IntPtr(pA),
                                                  out error);
                    hDeviceMemB = CL.CreateBuffer(hContext,
                                                  MemFlags.MemReadOnly | MemFlags.MemCopyHostPtr,
                                                  new IntPtr(cnDimension.ToInt32() * sizeof(float)),
                                                  new IntPtr(pA),
                                                  out error);
                    hDeviceMemC = CL.CreateBuffer(hContext,
                                                  MemFlags.MemWriteOnly,
                                                  new IntPtr(cnDimension.ToInt32() * sizeof(float)),
                                                  IntPtr.Zero,
                                                  out error);

                    // setup parameter values
                    CL.SetKernelArg(hKernel, 0, new IntPtr(sizeof(cl_mem)), new IntPtr(&hDeviceMemA));
                    CL.SetKernelArg(hKernel, 1, new IntPtr(sizeof(cl_mem)), new IntPtr(&hDeviceMemB));
                    CL.SetKernelArg(hKernel, 2, new IntPtr(sizeof(cl_mem)), new IntPtr(&hDeviceMemC));

                    // write data from host to device
                    CL.EnqueueWriteBuffer(hCmdQueue, hDeviceMemA, true, IntPtr.Zero,
                                          new IntPtr(cnDimension.ToInt32() * sizeof(float)),
                                          new IntPtr(pA), 0, null, (IntPtr[])null);
                    CL.EnqueueWriteBuffer(hCmdQueue, hDeviceMemB, true, IntPtr.Zero,
                                          new IntPtr(cnDimension.ToInt32() * sizeof(float)),
                                          new IntPtr(pB), 0, null, (IntPtr[])null);

                    // execute kernel
                    error = (ErrorCode)CL.EnqueueNDRangeKernel(hCmdQueue, hKernel, 1, null, &cnDimension, null, 0, null, null);
                    if (error != ErrorCode.Success)
                    {
                        throw new Exception(error.ToString());
                    }

                    // copy results from device back to host
                    IntPtr event_handle = IntPtr.Zero;

                    error = (ErrorCode)CL.EnqueueReadBuffer(hCmdQueue, hDeviceMemC, true, IntPtr.Zero,
                                                            new IntPtr(cnDimension.ToInt32() * sizeof(float)),
                                                            new IntPtr(pC), 0, null, (IntPtr[])null);
                    if (error != ErrorCode.Success)
                    {
                        throw new Exception(error.ToString());
                    }

                    CL.Finish(hCmdQueue);

                    CL.ReleaseMemObject(hDeviceMemA);
                    CL.ReleaseMemObject(hDeviceMemB);
                    CL.ReleaseMemObject(hDeviceMemC);
                }
            }

            for (int i = 0; i < A.Length; i++)
            {
                System.Diagnostics.Trace.WriteLine(String.Format("{0} + {1} = {2}", A[i], B[i], C[i]));
            }
        }
Ejemplo n.º 4
0
        static void Main(string[] args)
        {
            ToGrayscale.ConvertToGrayscale("image.jpg");

            //Get the ids of available opencl platforms

            CL.GetPlatformIds(0, null, out uint platformCount);
            CLPlatform[] platformIds = new CLPlatform[platformCount];
            CL.GetPlatformIds(platformCount, platformIds, out _);

            Console.WriteLine(platformIds.Length);
            foreach (CLPlatform platform in platformIds)
            {
                Console.WriteLine(platform.Handle);
                CL.GetPlatformInfo(platform, PlatformInfo.Name, out byte[] val);
            }

            //Get the device ids for each platform
            foreach (IntPtr platformId in platformIds)
            {
                CL.GetDeviceIds(new CLPlatform(platformId), DeviceType.All, out CLDevice[] deviceIds);

                CLContext context = CL.CreateContext(IntPtr.Zero, (uint)deviceIds.Length, deviceIds, IntPtr.Zero,
                                                     IntPtr.Zero, out CLResultCode result);
                if (result != CLResultCode.Success)
                {
                    throw new Exception("The context couldn't be created.");
                }

                string code = @"
                __kernel void add(__global float* A, __global float* B,__global float* result, const float mul)
                {
                    int i = get_global_id(0);
                    result[i] = (A[i] + B[i])*mul;
                }";

                CLProgram program = CL.CreateProgramWithSource(context, code, out result);

                CL.BuildProgram(program, (uint)deviceIds.Length, deviceIds, null, IntPtr.Zero, IntPtr.Zero);

                CLKernel kernel = CL.CreateKernel(program, "add", out result);

                int     arraySize = 20;
                float[] A         = new float[arraySize];
                float[] B         = new float[arraySize];

                for (int i = 0; i < arraySize; i++)
                {
                    A[i] = 1;
                    B[i] = i;
                }

                CLBuffer bufferA = CL.CreateBuffer(context, MemoryFlags.ReadOnly | MemoryFlags.CopyHostPtr, A,
                                                   out result);
                CLBuffer bufferB = CL.CreateBuffer(context, MemoryFlags.ReadOnly | MemoryFlags.CopyHostPtr, B,
                                                   out result);

                float[] pattern = new float[] { 1, 3, 5, 7 };

                CLBuffer resultBuffer = new CLBuffer(CL.CreateBuffer(context, MemoryFlags.WriteOnly,
                                                                     new UIntPtr((uint)(arraySize * sizeof(float))), IntPtr.Zero, out result));

                try
                {
                    CL.SetKernelArg(kernel, 0, bufferA);
                    CL.SetKernelArg(kernel, 1, bufferB);
                    CL.SetKernelArg(kernel, 2, resultBuffer);
                    CL.SetKernelArg(kernel, 3, -1f);

                    CLCommandQueue commandQueue = new CLCommandQueue(
                        CL.CreateCommandQueueWithProperties(context, deviceIds[0], IntPtr.Zero, out result));

                    CL.EnqueueFillBuffer(commandQueue, bufferB, pattern, UIntPtr.Zero, (UIntPtr)(arraySize * sizeof(float)), null,
                                         out _);

                    //CL.EnqueueNDRangeKernel(commandQueue, kernel, 1, null, new UIntPtr[] {new UIntPtr((uint)A.Length)},
                    //	null, 0, null,  out CLEvent eventHandle);

                    CL.EnqueueNDRangeKernel(commandQueue, kernel, 1, null, new UIntPtr[] { new UIntPtr((uint)A.Length) },
                                            null, 0, null, out CLEvent eventHandle);


                    CL.Finish(commandQueue);

                    CL.SetEventCallback(eventHandle, (int)CommandExecutionStatus.Complete, (waitEvent, data) =>
                    {
                        float[] resultValues = new float[arraySize];
                        CL.EnqueueReadBuffer(commandQueue, resultBuffer, true, UIntPtr.Zero, resultValues, null, out _);

                        StringBuilder line = new StringBuilder();
                        foreach (float res in resultValues)
                        {
                            line.Append(res);
                            line.Append(", ");
                        }

                        Console.WriteLine(line.ToString());
                    });

                    //get rid of the buffers because we no longer need them
                    CL.ReleaseMemoryObject(bufferA);
                    CL.ReleaseMemoryObject(bufferB);
                    CL.ReleaseMemoryObject(resultBuffer);

                    //Release the program kernels and queues
                    CL.ReleaseProgram(program);
                    CL.ReleaseKernel(kernel);
                    CL.ReleaseCommandQueue(commandQueue);
                    CL.ReleaseContext(context);
                    CL.ReleaseEvent(eventHandle);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                    throw;
                }
            }
        }
Ejemplo n.º 5
0
        public static void Add()
        {
            CLResultCode error = CLResultCode.Success;

            CLPlatform[] platforms = new CLPlatform[1];
            CL.GetPlatformIds(1, platforms, out _);

            CLDevice[] devices = new CLDevice[1];
            CL.GetDeviceIds(platforms[0], DeviceType.All, 1, devices, out _);

            CLContext context = CL.CreateContext(IntPtr.Zero, devices, IntPtr.Zero, IntPtr.Zero, out _);


            CLProgram program =
                CL.CreateProgramWithSource(context, File.ReadAllText("Kernels/add_arrays.cl"), out error);

            error = CL.BuildProgram(program, 1, devices, null, IntPtr.Zero, IntPtr.Zero);

            if (error != CLResultCode.Success)
            {
                throw new Exception(error.ToString());
            }

            CLKernel kernel = CL.CreateKernel(program, "add", out error);

            Span <float> inputA = new float[]
            {
                1, 24, 5, 43, 41, 56
            };
            Span <float> inputB = new float[]
            {
                72, -323, -1, 43, -41, -26
            };
            Span <float> output = stackalloc float[inputA.Length];

            CLBuffer bufferA = CL.CreateBuffer(context, MemoryFlags.ReadOnly | MemoryFlags.CopyHostPtr, inputA, out _);
            CLBuffer bufferB = CL.CreateBuffer(context, MemoryFlags.ReadOnly | MemoryFlags.CopyHostPtr, inputB, out _);

            CLBuffer outputBuffer = CL.CreateBuffer(context, MemoryFlags.WriteOnly, (UIntPtr)(output.Length * sizeof(float)), IntPtr.Zero, out _);

            //For outputs I wouldn't use that also enqueueing a ReadBuffer is needed regardless
            //CLBuffer outputBuffer = CL.CreateBuffer(context, MemoryFlags.WriteOnly | MemoryFlags.UseHostPtr, output, out _);

            CL.SetKernelArg(kernel, 0, bufferA);
            CL.SetKernelArg(kernel, 1, bufferB);
            CL.SetKernelArg(kernel, 2, outputBuffer);

            CLCommandQueue queue = CL.CreateCommandQueueWithProperties(context, devices[0], IntPtr.Zero, out error);

            CL.EnqueueNDRangeKernel(queue, kernel, 1, null,
                                    new[] { (UIntPtr)inputA.Length }, null, 0, null, out _);

            CL.EnqueueReadBuffer(queue, outputBuffer, true, UIntPtr.Zero, output, null, out _);

            foreach (float f in output)
            {
                Console.WriteLine(f);
            }


            CL.ReleaseMemoryObject(bufferA);
            CL.ReleaseMemoryObject(bufferB);
            CL.ReleaseMemoryObject(outputBuffer);
            CL.ReleaseCommandQueue(queue);
            CL.ReleaseKernel(kernel);
            CL.ReleaseProgram(program);
            CL.ReleaseContext(context);
        }
Ejemplo n.º 6
0
        public static void ConvertToGrayscale(string inputPath)
        {
            CLResultCode error = CLResultCode.Success;

            //Get a platform
            CLPlatform[] platforms = new CLPlatform[1];
            CL.GetPlatformIds(1, platforms, out _);

            //Get a device
            CLDevice[] devices = new CLDevice[1];
            CL.GetDeviceIds(platforms[0], DeviceType.Gpu, 1, devices, out _);

            //Create a context
            CLContext context = CL.CreateContext(IntPtr.Zero, devices, IntPtr.Zero, IntPtr.Zero, out error);

            if (error != CLResultCode.Success)
            {
                throw new Exception("Error on creating a context");
            }

            //Create the program from source
            CLProgram program =
                CL.CreateProgramWithSource(context, File.ReadAllText("Kernels/grayscale.cl"), out error);

            error = CL.BuildProgram(program, 1, devices, null, IntPtr.Zero, IntPtr.Zero);

            if (error != CLResultCode.Success)
            {
                throw new Exception($"Error on building program: {error}");
            }


            //Get the kernel which we will use
            CLKernel kernel = CL.CreateKernel(program, "grayscale", out error);

            ImageFormat inputImageFormat = new ImageFormat
            {
                ChannelOrder = ChannelOrder.Bgra,
                ChannelType  = ChannelType.UnsignedInteger8
            };

            Bitmap     inputBitmap = new Bitmap(inputPath);
            BitmapData inputData   = inputBitmap.LockBits(new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height),
                                                          ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

            ImageDescription imageDescription = new ImageDescription()
            {
                ImageType = MemoryObjectType.Image2D,
                Width     = (UIntPtr)inputBitmap.Width,
                Height    = (UIntPtr)inputBitmap.Height,
                Depth     = (UIntPtr)1
            };

            CLImage inputImage = CL.CreateImage(context, MemoryFlags.ReadOnly | MemoryFlags.CopyHostPtr,
                                                ref inputImageFormat, ref imageDescription, inputData.Scan0, out error);

            Bitmap     outputBitmap = new Bitmap(inputBitmap.Width, inputBitmap.Height, PixelFormat.Format32bppArgb);
            BitmapData outputData   = outputBitmap.LockBits(new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height),
                                                            ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);

            CLImage outputImage = CL.CreateImage(context, MemoryFlags.WriteOnly | MemoryFlags.UseHostPtr,
                                                 ref inputImageFormat, ref imageDescription, outputData.Scan0, out error);

            CL.SetKernelArg(kernel, 0, rFact);
            CL.SetKernelArg(kernel, 1, gFact);
            CL.SetKernelArg(kernel, 2, bFact);

            CL.SetKernelArg(kernel, 3, inputImage);
            CL.SetKernelArg(kernel, 4, outputImage);

            CLCommandQueue queue = CL.CreateCommandQueueWithProperties(context, devices[0], IntPtr.Zero, out error);

            CL.EnqueueNDRangeKernel(queue, kernel, 2, new UIntPtr[] { UIntPtr.Zero, UIntPtr.Zero, }, new[]
            {
                (UIntPtr)inputBitmap.Width,
                (UIntPtr)inputBitmap.Height,
            }, null, 0, null, out _);

            CL.EnqueueReadImage(queue, outputImage, 1, new UIntPtr[] { UIntPtr.Zero, UIntPtr.Zero, },
                                new UIntPtr[]
            {
                (UIntPtr)inputBitmap.Width,
                (UIntPtr)inputBitmap.Height,
                (UIntPtr)1,
            }, UIntPtr.Zero, UIntPtr.Zero, outputData.Scan0, 0, null, out _);

            outputBitmap.UnlockBits(outputData);

            outputBitmap.Save("grayscale.png", System.Drawing.Imaging.ImageFormat.Png);

            //Dispose of all things
            inputBitmap.Dispose();
            outputBitmap.Dispose();

            CL.ReleaseMemoryObject(inputImage);
            CL.ReleaseMemoryObject(outputImage);

            CL.ReleaseCommandQueue(queue);
            CL.ReleaseKernel(kernel);
            CL.ReleaseProgram(program);
            CL.ReleaseContext(context);
        }