public void CommandQueueAPI() { ErrorCode error; using (CommandQueue commandQueue = Cl.CreateCommandQueue(_context, _device, CommandQueueProperties.OutOfOrderExecModeEnable, out error)) { Assert.AreEqual(ErrorCode.Success, error); Assert.AreEqual(1, Cl.GetCommandQueueInfo(commandQueue, CommandQueueInfo.ReferenceCount, out error).CastTo <uint>()); Cl.RetainCommandQueue(commandQueue); Assert.AreEqual(2, Cl.GetCommandQueueInfo(commandQueue, CommandQueueInfo.ReferenceCount, out error).CastTo <uint>()); Cl.ReleaseCommandQueue(commandQueue); Assert.AreEqual(1, Cl.GetCommandQueueInfo(commandQueue, CommandQueueInfo.ReferenceCount, out error).CastTo <uint>()); Assert.AreEqual(Cl.GetCommandQueueInfo(commandQueue, CommandQueueInfo.Context, out error).CastTo <Context>(), _context); Assert.AreEqual(Cl.GetCommandQueueInfo(commandQueue, CommandQueueInfo.Device, out error).CastTo <Device>(), _device); Assert.AreEqual(Cl.GetCommandQueueInfo(commandQueue, CommandQueueInfo.Properties, out error).CastTo <CommandQueueProperties>(), CommandQueueProperties.OutOfOrderExecModeEnable); } }
public OpenClCompiler(Device device, string source) { _device = device; _ctx = device.CreateContext(); Source = source; _program = new Program(Cl.CreateProgramWithSource(_ctx, 1, new string[] { source }, null, out ErrorCode error)); Cl.BuildProgram(_program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero); KernelCount = _program.NumKernels; Methodes = _program.KernelNames; _kernels = new Kernel[KernelCount]; if ((error = Cl.CreateKernelsInProgram(_program, KernelCount, _kernels, out _)) != ErrorCode.Success) { throw new Exception($"{error}"); } _queue = Cl.CreateCommandQueue(_ctx, _device, CommandQueueProperties.None, out _); }
private void ready() { ErrorCode error; context = Cl.CreateContext(null, 1, new[] { device }, null, IntPtr.Zero, out error); string source = System.IO.File.ReadAllText("kernels.cl"); program = Cl.CreateProgramWithSource(context, 1, new[] { source }, null, out error); error = Cl.BuildProgram(program, 1, new[] { device }, string.Empty, null, IntPtr.Zero); InfoBuffer buildStatus = Cl.GetProgramBuildInfo(program, device, ProgramBuildInfo.Status, out error); if (buildStatus.CastTo <BuildStatus>() != BuildStatus.Success) { throw new Exception($"OpenCL could not build the kernel successfully: {buildStatus.CastTo<BuildStatus>()}"); } allGood(error); Kernel[] kernels = Cl.CreateKernelsInProgram(program, out error); kernel = kernels[0]; allGood(error); queue = Cl.CreateCommandQueue(context, device, CommandQueueProperties.None, out error); allGood(error); dataOut = Cl.CreateBuffer(context, MemFlags.WriteOnly, (IntPtr)(globalSize * sizeof(int)), out error); allGood(error); var intSizePtr = new IntPtr(Marshal.SizeOf(typeof(int))); error |= Cl.SetKernelArg(kernel, 2, new IntPtr(Marshal.SizeOf(typeof(IntPtr))), dataOut); error |= Cl.SetKernelArg(kernel, 3, intSizePtr, new IntPtr(worldSeed)); error |= Cl.SetKernelArg(kernel, 4, intSizePtr, new IntPtr(globalSize)); allGood(error); }
// Partially from OpenTK demo - Submitted by "mfagerlund" public void AddArrayAddsCorrectly() { const string correctSource = @" // Simple test; c[i] = a[i] + b[i] __kernel void add_array(__global float *a, __global float *b, __global float *c) { int xid = get_global_id(0); c[xid] = a[xid] + b[xid]; } __kernel void sub_array(__global float *a, __global float *b, __global float *c) { int xid = get_global_id(0); c[xid] = a[xid] - b[xid]; } "; ErrorCode error; using (Program program = Cl.CreateProgramWithSource(_context, 1, new[] { correctSource }, null, out error)) { Assert.AreEqual(error, ErrorCode.Success); error = Cl.BuildProgram(program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero); Assert.AreEqual(ErrorCode.Success, error); Assert.AreEqual(Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <BuildStatus>(), BuildStatus.Success); Kernel[] kernels = Cl.CreateKernelsInProgram(program, out error); Kernel kernel = kernels[0]; const int cnBlockSize = 4; const int cnBlocks = 3; IntPtr cnDimension = new IntPtr(cnBlocks * cnBlockSize); // 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; } //Cl.IMem hDeviceMemA = Cl.CreateBuffer(_context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadOnly, (IntPtr)(sizeof(float) * cnDimension.ToInt32()), A, out error); //Assert.AreEqual(Cl.ErrorCode.Success, error); IMem <float> hDeviceMemA = Cl.CreateBuffer(_context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, A, out error); Assert.AreEqual(ErrorCode.Success, error); IMem hDeviceMemB = Cl.CreateBuffer(_context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, (IntPtr)(sizeof(float) * cnDimension.ToInt32()), B, out error); Assert.AreEqual(ErrorCode.Success, error); IMem hDeviceMemC = Cl.CreateBuffer(_context, MemFlags.WriteOnly, (IntPtr)(sizeof(float) * cnDimension.ToInt32()), IntPtr.Zero, out error); Assert.AreEqual(ErrorCode.Success, error); CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error); Event clevent; int intPtrSize = 0; intPtrSize = Marshal.SizeOf(typeof(IntPtr)); // setup parameter values error = Cl.SetKernelArg(kernel, 0, new IntPtr(intPtrSize), hDeviceMemA); Assert.AreEqual(ErrorCode.Success, error); error = Cl.SetKernelArg(kernel, 1, new IntPtr(intPtrSize), hDeviceMemB); Assert.AreEqual(ErrorCode.Success, error); error = Cl.SetKernelArg(kernel, 2, new IntPtr(intPtrSize), hDeviceMemC); Assert.AreEqual(ErrorCode.Success, error); // write data from host to device error = Cl.EnqueueWriteBuffer(cmdQueue, hDeviceMemA, Bool.True, IntPtr.Zero, new IntPtr(cnDimension.ToInt32() * sizeof(float)), A, 0, null, out clevent); Assert.AreEqual(ErrorCode.Success, error); error = Cl.EnqueueWriteBuffer(cmdQueue, hDeviceMemB, Bool.True, IntPtr.Zero, new IntPtr(cnDimension.ToInt32() * sizeof(float)), B, 0, null, out clevent); Assert.AreEqual(ErrorCode.Success, error); // execute kernel error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 1, null, new IntPtr[] { cnDimension }, null, 0, null, out clevent); Assert.AreEqual(ErrorCode.Success, error, error.ToString()); // copy results from device back to host IntPtr event_handle = IntPtr.Zero; error = Cl.EnqueueReadBuffer(cmdQueue, hDeviceMemC, Bool.True, 0, C.Length, C, 0, null, out clevent); Assert.AreEqual(ErrorCode.Success, error, error.ToString()); for (int i = 0; i < A.Length; i++) { Assert.That(A[i] + B[i], Is.EqualTo(C[i])); } Cl.Finish(cmdQueue); Cl.ReleaseMemObject(hDeviceMemA); Cl.ReleaseMemObject(hDeviceMemB); Cl.ReleaseMemObject(hDeviceMemC); } }
public Bitmap GPUMandel(Bitmap inputBitmap) { ErrorCode error; //Load and compile kernel source code. string programPath = System.Environment.CurrentDirectory + "/../../program.cl"; //The path to the source file may vary if (!System.IO.File.Exists(programPath)) { Console.WriteLine("Program doesn't exist at path " + programPath); return(inputBitmap); } string programSource = System.IO.File.ReadAllText(programPath); using (Program program = Cl.CreateProgramWithSource(_context, 1, new[] { programSource }, null, out error)) { CheckErr(error, "Cl.CreateProgramWithSource"); //Compile kernel source error = Cl.BuildProgram(program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero); CheckErr(error, "Cl.BuildProgram"); //Check for any compilation errors if (Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <BuildStatus>() != BuildStatus.Success) { CheckErr(error, "Cl.GetProgramBuildInfo"); Console.WriteLine("Cl.GetProgramBuildInfo != Success"); Console.WriteLine(Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Log, out error)); return(inputBitmap); } //Create the required kernel (entry function) Kernel kernel = Cl.CreateKernel(program, "Mandelbrot", out error); CheckErr(error, "Cl.CreateKernel"); //Unmanaged output image's raw RGBA byte[] array BitmapData bitmapData = inputBitmap.LockBits(new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb); int inputImgBytesSize = bitmapData.Stride * bitmapData.Height; int inputImgWidth = inputBitmap.Width; int inputImgHeight = inputBitmap.Height; int intPtrSize = Marshal.SizeOf(typeof(IntPtr)); OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8); //OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Float); byte[] outputByteArray = new byte[inputImgBytesSize]; //Allocate OpenCL image memory buffer Mem outputImage2DBuffer = (Mem)Cl.CreateImage2D(_context, MemFlags.CopyHostPtr | MemFlags.WriteOnly, clImageFormat, (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)0, outputByteArray, out error); CheckErr(error, "Cl.CreateImage2D output"); //Pass the memory buffers to our kernel function error = Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, outputImage2DBuffer); CheckErr(error, "Cl.SetKernelArg"); //Create a command queue, where all of the commands for execution will be added CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error); CheckErr(error, "Cl.CreateCommandQueue"); Event clevent; //Copy input image from the host to the GPU. IntPtr[] originPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; //x, y, z IntPtr[] regionPtr = new IntPtr[] { (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)1 }; //x, y, z IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)1 }; error = Cl.EnqueueWriteImage(cmdQueue, outputImage2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, outputByteArray, 0, null, out clevent); CheckErr(error, "Cl.EnqueueWriteImage"); //Execute our kernel (OpenCL code) error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent); CheckErr(error, "Cl.EnqueueNDRangeKernel"); //Wait for completion of all calculations on the GPU. error = Cl.Finish(cmdQueue); CheckErr(error, "Cl.Finish"); //Read the processed image from GPU to raw RGBA data byte[] array error = Cl.EnqueueReadImage(cmdQueue, outputImage2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, outputByteArray, 0, null, out clevent); CheckErr(error, "Cl.clEnqueueReadImage"); //Clean up memory Cl.ReleaseKernel(kernel); Cl.ReleaseCommandQueue(cmdQueue); //Cl.ReleaseMemObject(inputImage2DBuffer); Cl.ReleaseMemObject(outputImage2DBuffer); //Get a pointer to our unmanaged output byte[] array GCHandle pinnedOutputArray = GCHandle.Alloc(outputByteArray, GCHandleType.Pinned); IntPtr outputBmpPointer = pinnedOutputArray.AddrOfPinnedObject(); //Create a new bitmap with processed data and save it to a file. Bitmap outputBitmap = new Bitmap(inputImgWidth, inputImgHeight, bitmapData.Stride, PixelFormat.Format32bppArgb, outputBmpPointer); return(outputBitmap); //outputBitmap.Save(outputImagePath, System.Drawing.Imaging.ImageFormat.Png); //pinnedOutputArray.Free(); } }
public override Bitmap Plot() { ErrorCode error; using (Kernel kernel = CompileKernel("mandelbrot")) { Bitmap plotImg = new Bitmap(Width, Height); int intPtrSize = Marshal.SizeOf(typeof(IntPtr)); int uint4size = Marshal.SizeOf(typeof(uint4)); // Buffer do OpenCL para manter os dados da imagem OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8); //// Obtém o buffer de pixels //BitmapData data = plotImg.LockBits(new Rectangle(0, 0, plotImg.Width, plotImg.Height), ImageLockMode.WriteOnly, plotImg.PixelFormat); //int depth = Bitmap.GetPixelFormatSize(data.PixelFormat) / 8; // Tamanho de cada pixel em memória, em bytes int depth = Bitmap.GetPixelFormatSize(PixelFormat.Format32bppArgb) / 8; int stride = 4 * ((Width * depth + 3) / 4); byte[] buffer = new byte[Height * stride]; // Cria o buffer para se trabalhar na imagem //Marshal.Copy(data.Scan0, buffer, 0, buffer.Length); // Copia as informações da imagem no buffer // Cria o buffer do OpenCL para a imagem Mem image2dbuffer = (Mem)Cl.CreateImage2D(context, MemFlags.CopyHostPtr | MemFlags.WriteOnly, clImageFormat, (IntPtr)Width, (IntPtr)Height, (IntPtr)0, buffer, out error); CheckErr(error, "Cl.CreateImage2D"); // Passa os parametros para o kernel error = Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, image2dbuffer); CheckErr(error, "Cl.SetKernelArg imageBuffer"); uint4 startColorUi = new uint4(Colors.StartColor.B, Colors.StartColor.G, Colors.StartColor.R, Colors.StartColor.A); error = Cl.SetKernelArg(kernel, 1, (IntPtr)uint4size, startColorUi); CheckErr(error, "Cl.SetKernelArg startColor"); uint4 endColorUi = new uint4(Colors.EndColor.B, Colors.EndColor.G, Colors.EndColor.R, Colors.EndColor.A); error = Cl.SetKernelArg(kernel, 2, (IntPtr)uint4size, endColorUi); CheckErr(error, "Cl.SetKernelArg endColor"); error = Cl.SetKernelArg(kernel, 3, (IntPtr)sizeof(int), Iterations); CheckErr(error, "Cl.SetKernelArg iterations"); // Cria uma fila de comandos, com todos os comandos a serem executados pelo kernel CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, 0, out error); CheckErr(error, "Cl.CreateCommandQueue"); // Copia a imagem para a GPU Event clevent; IntPtr[] imgOriginPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; //x, y, z IntPtr[] imgRegionPtr = new IntPtr[] { (IntPtr)Width, (IntPtr)Height, (IntPtr)1 }; //x, y, z error = Cl.EnqueueWriteImage(cmdQueue, image2dbuffer, Bool.True, imgOriginPtr, imgRegionPtr, (IntPtr)0, (IntPtr)0, buffer, 0, null, out clevent); CheckErr(error, "Cl.EnqueueWriteImage"); // Executa o Kernel carregado pelo OpenCL (com múltiplos processadores :D) IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)Width, (IntPtr)Height, (IntPtr)1 }; // x, y, z error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent); CheckErr(error, "Cl.EnqueueNDRangeKernel"); // Espera terminar a execução error = Cl.Finish(cmdQueue); CheckErr(error, "Cl.Finish"); // Lê a imagem processada pela GPU e coloca novamente no buffer error = Cl.EnqueueReadImage(cmdQueue, image2dbuffer, Bool.True, imgOriginPtr, imgRegionPtr, (IntPtr)0, (IntPtr)0, buffer, 0, null, out clevent); CheckErr(error, "Cl.clEnqueueReadImage"); // Limpa a memória Cl.ReleaseKernel(kernel); Cl.ReleaseCommandQueue(cmdQueue); Cl.ReleaseMemObject(image2dbuffer); // Get a pointer to our unmanaged output byte[] array //GCHandle pinnedBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); //IntPtr bmpPointer = pinnedBuffer.AddrOfPinnedObject(); BitmapData data = plotImg.LockBits(new Rectangle(0, 0, plotImg.Width, plotImg.Height), ImageLockMode.WriteOnly, plotImg.PixelFormat); Marshal.Copy(buffer, 0, data.Scan0, buffer.Length); // Copia as informações no buffer de volta à imagem plotImg.UnlockBits(data); // Libera a imagem //pinnedBuffer.Free(); return(plotImg); } }
public void ScryptTest() { ErrorCode error; //Load and compile kernel source code. string programPath = System.Environment.CurrentDirectory + "/../../scrypt.cl"; //Cl if (!System.IO.File.Exists(programPath)) { Console.WriteLine("Program doesn't exist at path " + programPath); return; } string programSource = System.IO.File.ReadAllText(programPath); IntPtr[] sz = new IntPtr[programSource.Length * 2]; Program program = Cl.CreateProgramWithSource(_context, 1, new[] { programSource }, null, out error); if (1 == 1) { CheckErr(error, "Cl.CreateProgramWithSource"); // status = clBuildProgram(clState->program, 1, &devices[gpu], ""-D LOOKUP_GAP=%d -D CONCURRENT_THREADS=%d -D WORKSIZE=%d", NULL, NULL); //Compile kernel source error = Cl.BuildProgram(program, 1, new[] { _device }, "-D LOOKUP_GAP=1 -D CONCURRENT_THREADS=1 -D WORKSIZE=1", null, IntPtr.Zero); CheckErr(error, "Cl.BuildProgram"); //Check for any compilation errors if (Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <BuildStatus>() != BuildStatus.Success && 1 == 0) { CheckErr(error, "Cl.GetProgramBuildInfo"); Console.WriteLine("Cl.GetProgramBuildInfo != Success"); Console.WriteLine(Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Log, out error)); return; } //Create the required kernel (entry function) [search] Kernel kernel = Cl.CreateKernel(program, "search", out error); CheckErr(error, "Cl.CreateKernel"); int intPtrSize = 0; intPtrSize = Marshal.SizeOf(typeof(IntPtr)); //Image's RGBA data converted to an unmanaged[] array byte[] inputByteArray; //OpenCL memory buffer that will keep our image's byte[] data. Mem inputImage2DBuffer; //Create a command queue, where all of the commands for execution will be added CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error); CheckErr(error, "Cl.CreateCommandQueue"); clState _clState = new clState(); _clState.cl_command_queue = cmdQueue; _clState.cl_kernel = kernel; _clState.cl_context = _context; IntPtr buffersize = new IntPtr(1024); IntPtr blank_res = new IntPtr(1024); Object thrdataRes = new Object(); //int buffersize = 1024; OpenCL.Net.Event clevent; // status |= clEnqueueWriteBuffer(clState->commandQueue, clState->outputBuffer, CL_TRUE, 0, buffersize, blank_res, 0, NULL, NULL); dev_blk_ctx blk = new dev_blk_ctx(); ErrorCode err = queue_scrypt_kernel(_clState, blk); ErrorCode status = Cl.EnqueueWriteBuffer(_clState.cl_command_queue, _clState.outputBuffer, OpenCL.Net.Bool.True, new IntPtr(0), buffersize, blank_res, 0, null, out clevent); IntPtr[] globalThreads = new IntPtr[0]; IntPtr[] localThreads = new IntPtr[0]; //uint16 workdim = new uint16(1); uint workdim = 1; status = Cl.EnqueueNDRangeKernel(_clState.cl_command_queue, _clState.cl_kernel, workdim, null, globalThreads, localThreads, 0, null, out clevent); CheckErr(error, "Cl.EnqueueNDRangeKernel"); IntPtr offset = new IntPtr(0); status = Cl.EnqueueReadBuffer(_clState.cl_command_queue, _clState.outputBuffer, OpenCL.Net.Bool.False, offset, buffersize, thrdataRes, 0, null, out clevent); //Wait for completion of all calculations on the GPU. error = Cl.Finish(_clState.cl_command_queue); CheckErr(error, "Cl.Finish"); //Clean up memory Cl.ReleaseKernel(_clState.cl_kernel); Cl.ReleaseCommandQueue(_clState.cl_command_queue); } }
public static void Initialize() { Platform[] platforms = Cl.GetPlatformIDs(out ErrorCode error); if (error != ErrorCode.Success) { Log.Print("Impossible to run OpenCL, no any graphic platform available, abording launch."); Application.Exit(); } Vector2I res = Graphics.RenderResolution; int pixelXAmount = res.x; int pixelYAmount = res.y; int amountOfObjects = 1; unsafe { inputSize = sizeof(C_CAMERA); outputSize = sizeof(byte) * pixelXAmount * pixelYAmount * 4; } UsedDevice = Cl.GetDeviceIDs(platforms[0], DeviceType.All, out error)[0]; gpu_context = Cl.CreateContext(null, 1, new Device[] { UsedDevice }, null, IntPtr.Zero, out error); InfoBuffer namebuffer = Cl.GetDeviceInfo(UsedDevice, DeviceInfo.Name, out error); Log.Print("OpenCL Running on " + namebuffer); Queue = Cl.CreateCommandQueue(gpu_context, UsedDevice, CommandQueueProperties.OutOfOrderExecModeEnable, out error); if (error != ErrorCode.Success) { Console.WriteLine("Impossible to create gpu queue, abording launch."); Application.Exit(); } CLoader.LoadProjectPaths(@".\libs", new[] { "c" }, out string[] cfiles, out string[] hfiles); Program program = CLoader.LoadProgram(cfiles, hfiles, UsedDevice, gpu_context); //Program prog = CLoader.LoadProgram(CLoader.GetCFilesDir(@".\", new[] { "cl" }).ToArray(), new[] { "headers" }, UsedDevice, gpu_context); kernel = Cl.CreateKernel(program, "rm_render_entry", out error); if (error != ErrorCode.Success) { Log.Print("Error when creating kernel: " + error.ToString()); } memory = new IntPtr(outputSize); memInput = (Mem)Cl.CreateBuffer(gpu_context, MemFlags.ReadOnly, inputSize, out error); memTime = (Mem)(Cl.CreateBuffer(gpu_context, MemFlags.ReadOnly, timeSize, out error)); memOutput = (Mem)Cl.CreateBuffer(gpu_context, MemFlags.WriteOnly, outputSize, out error); //GPU_PARAM param = new GPU_PARAM() { X_RESOLUTION = res.x, Y_RESOLUTION = res.y }; ////Vector3D pos = camera.Malleable.Position; //Quaternion q = camera.Malleable.Rotation; IntPtr notused; InfoBuffer local = new InfoBuffer(new IntPtr(4)); error = Cl.GetKernelWorkGroupInfo(kernel, UsedDevice, KernelWorkGroupInfo.WorkGroupSize, new IntPtr(sizeof(int)), local, out notused); if (error != ErrorCode.Success) { Log.Print("Error getting kernel workgroup info: " + error.ToString()); } //int intPtrSize = 0; intPtrSize = Marshal.SizeOf(typeof(IntPtr)); Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, memInput); Cl.SetKernelArg(kernel, 1, (IntPtr)intPtrSize, memTime); Cl.SetKernelArg(kernel, 4, (IntPtr)intPtrSize, memOutput); //Cl.SetKernelArg(kernel, 2, new IntPtr(4), pixelAmount * 4); workGroupSizePtr = new IntPtr[] { new IntPtr(pixelXAmount * pixelYAmount) }; }
public void MatMul() { if (!prepared) { Prepare(this.BuildIR().InlineIR()); prepared = true; } // create kernel Cl.Kernel kernel = Cl.CreateKernel(program, "MatMul", out error); clSafeCall(error); // create command queue Cl.CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, Cl.CommandQueueProperties.None, out error); clSafeCall(error); // allocate host matrices float[] A = new float[WA * HA]; float[] B = new float[WB * HB]; float[] C = new float[WC * HC]; // initialize host memory Random rand = new Random(); for (int i = 0; i < A.Length; i++) { A[i] = (float)rand.Next() / short.MaxValue; } for (int i = 0; i < B.Length; i++) { B[i] = (float)rand.Next() / short.MaxValue; } // allocate device vectors Cl.Mem hDeviceMemA = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadOnly, (IntPtr)(sizeof(float) * A.Length), A, out error); clSafeCall(error); Cl.Mem hDeviceMemB = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadOnly, (IntPtr)(sizeof(float) * B.Length), B, out error); clSafeCall(error); Cl.Mem hDeviceMemC = Cl.CreateBuffer(context, Cl.MemFlags.WriteOnly, (IntPtr)(sizeof(float) * C.Length), IntPtr.Zero, out error); clSafeCall(error); // setup kernel arguments clSafeCall(Cl.SetKernelArg(kernel, 0, hDeviceMemA)); clSafeCall(Cl.SetKernelArg(kernel, 1, hDeviceMemB)); clSafeCall(Cl.SetKernelArg(kernel, 2, hDeviceMemC)); clSafeCall(Cl.SetKernelArg(kernel, 3, BLOCK_SIZE * BLOCK_SIZE * sizeof(float), null)); clSafeCall(Cl.SetKernelArg(kernel, 4, BLOCK_SIZE * BLOCK_SIZE * sizeof(float), null)); clSafeCall(Cl.SetKernelArg(kernel, 5, WA)); clSafeCall(Cl.SetKernelArg(kernel, 6, WB)); // execute kernel clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, new[] { (IntPtr)WC, (IntPtr)HC }, new[] { (IntPtr)BLOCK_SIZE, (IntPtr)BLOCK_SIZE }, 0, null, out clevent)); // copy results from device back to host clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, hDeviceMemC, Cl.Bool.True, IntPtr.Zero, (IntPtr)(sizeof(float) * C.Length), C, 0, null, out clevent)); clSafeCall(Cl.Finish(cmdQueue)); for (int i = 0; i < HA; ++i) { for (int j = 0; j < WB; ++j) { float sum = 0; for (int k = 0; k < WA; ++k) { sum += A[i * WA + k] * B[k * WB + j]; } float err = Math.Abs((sum - C[i * WB + j]) / sum); Assert.That(err, Is.LessThanOrEqualTo(1E-3F)); } } }
private static long PoissonRBSOR(Cl.Device device, Cl.Context context, Cl.Program program, bool lmem, float x0, float y0, float x1, float y1, int dimX, int dimY, int N, float omega, string fileName = null, string options = "") { Cl.ErrorCode error; Cl.Event clevent; // build program clSafeCall(Cl.BuildProgram(program, 1, new[] { device }, options, null, IntPtr.Zero)); Cl.BuildStatus status = Cl.GetProgramBuildInfo(program, device, Cl.ProgramBuildInfo.Status, out error).CastTo <Cl.BuildStatus>(); if (status != Cl.BuildStatus.Success) { throw new Exception(status.ToString()); } // save binary if (fileName != null) { Cl.InfoBuffer binarySizes = Cl.GetProgramInfo(program, Cl.ProgramInfo.BinarySizes, out error); clSafeCall(error); Cl.InfoBufferArray binaries = new Cl.InfoBufferArray( binarySizes.CastToEnumerable <IntPtr>(Enumerable.Range(0, 1)).Select(sz => new Cl.InfoBuffer(sz)).ToArray()); IntPtr szRet; clSafeCall(Cl.GetProgramInfo(program, Cl.ProgramInfo.Binaries, binaries.Size, binaries, out szRet)); byte[] binary = binaries[0].CastToArray <byte>(binarySizes.CastTo <IntPtr>(0).ToInt32()); File.WriteAllBytes(fileName, binary); } // create kernel Cl.Kernel kernel = Cl.CreateKernel(program, "PoissonRBSOR" + (lmem ? "_LMem" : ""), out error); clSafeCall(error); // create command queue Cl.CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, Cl.CommandQueueProperties.None, out error); clSafeCall(error); float hx = (x1 - x0) / dimX; float hy = (y1 - y0) / dimY; // boundary values float[] hgrid = new float[dimX * dimY]; int gstride = dimX; for (int i = 1; i < dimY - 1; i++) { int y_idx = i * gstride; float y_val = y0 + i * hy; hgrid[y_idx] = u(x0, y_val); hgrid[y_idx + dimX - 1] = u(x0 + (dimX - 1) * hx, y_val); } for (int j = 1; j < dimX - 1; j++) { float x_val = x0 + j * hx; hgrid[j] = u(x_val, y0); hgrid[j + (dimY - 1) * gstride] = u(x_val, y0 + (dimY - 1) * hy); } // laplacian values float[] hlaplacian = new float[(dimX - 2) * (dimY - 2)]; int lstride = dimX - 2; for (int i = 1; i < dimY - 1; i++) { for (int j = 1; j < dimX - 1; j++) { hlaplacian[j - 1 + (i - 1) * lstride] = J(x0 + j * hx, y0 + i * hy); } } // allocate device vectors Cl.Mem dgrid = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadWrite, (IntPtr)(sizeof(float) * hgrid.Length), hgrid, out error); clSafeCall(error); Cl.Mem dlaplacian = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadOnly, (IntPtr)(sizeof(float) * hlaplacian.Length), hlaplacian, out error); clSafeCall(error); // setup kernel arguments clSafeCall(Cl.SetKernelArg(kernel, 0, dgrid)); clSafeCall(Cl.SetKernelArg(kernel, 1, dlaplacian)); clSafeCall(Cl.SetKernelArg(kernel, 2, dimX)); clSafeCall(Cl.SetKernelArg(kernel, 3, dimY)); clSafeCall(Cl.SetKernelArg(kernel, 4, gstride)); clSafeCall(Cl.SetKernelArg(kernel, 5, lstride)); clSafeCall(Cl.SetKernelArg(kernel, 6, hx)); clSafeCall(Cl.SetKernelArg(kernel, 7, hy)); clSafeCall(Cl.SetKernelArg(kernel, 8, omega)); if (lmem) { clSafeCall(Cl.SetKernelArg(kernel, 10, (AREA_SIZE_Y + 2) * (AREA_SIZE_X + 2) * sizeof(float), null)); } IntPtr[] lo = { (IntPtr)TILE_SIZE_X, (IntPtr)TILE_SIZE_Y }; IntPtr[] gl = { (IntPtr)((dimX - 2 + (lmem ? AREA_SIZE_X : TILE_SIZE_X) - 1) / (lmem ? AREA_SIZE_X : TILE_SIZE_X) * TILE_SIZE_X), (IntPtr)((dimY - 2 + (lmem ? AREA_SIZE_Y : TILE_SIZE_Y) - 1) / (lmem ? AREA_SIZE_Y : TILE_SIZE_Y) * TILE_SIZE_Y) }; // execute RED kernel clSafeCall(Cl.SetKernelArg(kernel, 9, 1)); clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, gl, lo, 0, null, out clevent)); // execute BLACK kernel clSafeCall(Cl.SetKernelArg(kernel, 9, 0)); clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, gl, lo, 0, null, out clevent)); clSafeCall(Cl.Finish(cmdQueue)); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (int idx = 1; idx < N; idx++) { // execute RED kernel clSafeCall(Cl.SetKernelArg(kernel, 9, 1)); clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, gl, lo, 0, null, out clevent)); // execute BLACK kernel clSafeCall(Cl.SetKernelArg(kernel, 9, 0)); clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, gl, lo, 0, null, out clevent)); } clSafeCall(Cl.Finish(cmdQueue)); stopwatch.Stop(); // copy results from device back to host clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, dgrid, Cl.Bool.True, IntPtr.Zero, (IntPtr)(sizeof(float) * hgrid.Length), hgrid, 0, null, out clevent)); clSafeCall(Cl.Finish(cmdQueue)); cmdQueue.Dispose(); kernel.Dispose(); dgrid.Dispose(); float avgerr = 0, maxerr = 0; for (int i = 1; i < dimY - 1; i++) { for (int j = 1; j < dimX - 1; j++) { float theory = u(x0 + j * hx, y0 + i * hy); float err = Math.Abs(theory - hgrid[j + i * gstride]) / Math.Abs(theory); avgerr += err; maxerr = Math.Max(maxerr, err); } } avgerr /= dimX * dimY; long elapsedTime = stopwatch.ElapsedMilliseconds; Console.WriteLine("average error = {0}%\nmaximal error = {1}%\nelapsed time: {2}ms\niterations per second: {3}", avgerr * 100, maxerr * 100, elapsedTime, (double)N / (double)elapsedTime * 1000.0d); return(elapsedTime); }
public static CommandQueue CreateCommandQueue(Context context, Device device, out ErrorCode error) { return(Cl.CreateCommandQueue(context, device, CommandQueueProperties.None, out error)); }
public void Prototype() { ErrorCode error; Device device = (from d in Cl.GetDeviceIDs( (from platform in Cl.GetPlatformIDs(out error) where Cl.GetPlatformInfo(platform, PlatformInfo.Name, out error).ToString() == "AMD Accelerated Parallel Processing" // Use "NVIDIA CUDA" if you don't have amd select platform).First(), DeviceType.Gpu, out error) select d).First(); Context context = Cl.CreateContext(null, 1, new[] { device }, null, IntPtr.Zero, out error); string source = System.IO.File.ReadAllText("kernels.cl"); int chunkHalfLength = 300000000; int worldSeed = 420; int workItems = 3000; int outputAllocation = 100; IntPtr outputSize = new IntPtr(workItems * outputAllocation); var xr = new int[outputSize.ToInt32()]; var zr = new int[outputSize.ToInt32()]; var sc = new int[outputSize.ToInt32()]; using (Program program = Cl.CreateProgramWithSource(context, 1, new[] { source }, null, out error)) { Assert.AreEqual(error, ErrorCode.Success); error = Cl.BuildProgram(program, 1, new[] { device }, "", null, IntPtr.Zero); Assert.AreEqual(error, ErrorCode.Success); var buildInfo = Cl.GetProgramBuildInfo(program, device, ProgramBuildInfo.Status, out error).CastTo <BuildStatus>(); Assert.AreEqual(buildInfo, BuildStatus.Success); Assert.AreEqual(error, ErrorCode.Success); Kernel[] kernels = Cl.CreateKernelsInProgram(program, out error); Assert.AreEqual(error, ErrorCode.Success); Kernel kernel = kernels[0]; IMem hDeviceMemXr = Cl.CreateBuffer(context, MemFlags.WriteOnly, (IntPtr)(sizeof(int) * outputSize.ToInt32()), IntPtr.Zero, out error); Assert.AreEqual(ErrorCode.Success, error); IMem hDeviceMemZr = Cl.CreateBuffer(context, MemFlags.WriteOnly, (IntPtr)(sizeof(int) * outputSize.ToInt32()), IntPtr.Zero, out error); Assert.AreEqual(ErrorCode.Success, error); IMem hDeviceMemSc = Cl.CreateBuffer(context, MemFlags.WriteOnly, (IntPtr)(sizeof(int) * outputSize.ToInt32()), IntPtr.Zero, out error); Assert.AreEqual(ErrorCode.Success, error); CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, (CommandQueueProperties)0, out error); int intPtrSize = Marshal.SizeOf(typeof(IntPtr)); int intSize = Marshal.SizeOf(typeof(int)); error = Cl.SetKernelArg(kernel, 0, new IntPtr(intPtrSize), hDeviceMemXr); Assert.AreEqual(ErrorCode.Success, error); error = Cl.SetKernelArg(kernel, 1, new IntPtr(intPtrSize), hDeviceMemZr); Assert.AreEqual(ErrorCode.Success, error); error = Cl.SetKernelArg(kernel, 2, new IntPtr(intPtrSize), hDeviceMemSc); Assert.AreEqual(ErrorCode.Success, error); error = Cl.SetKernelArg(kernel, 3, new IntPtr(intSize), new IntPtr(chunkHalfLength)); Assert.AreEqual(ErrorCode.Success, error); error = Cl.SetKernelArg(kernel, 4, new IntPtr(intSize), new IntPtr(worldSeed)); Assert.AreEqual(ErrorCode.Success, error); error = Cl.SetKernelArg(kernel, 5, new IntPtr(intSize), new IntPtr(workItems)); Assert.AreEqual(ErrorCode.Success, error); error = Cl.SetKernelArg(kernel, 6, new IntPtr(intSize), new IntPtr(outputAllocation)); Assert.AreEqual(ErrorCode.Success, error); error = Cl.EnqueueWriteBuffer(cmdQueue, hDeviceMemXr, Bool.True, IntPtr.Zero, new IntPtr(outputSize.ToInt32() * sizeof(float)), xr, 0, null, out Event clevent); Assert.AreEqual(ErrorCode.Success, error); error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 1, null, new IntPtr[] { new IntPtr(workItems) }, null, 0, null, out clevent); error = Cl.EnqueueReadBuffer(cmdQueue, hDeviceMemXr, Bool.True, 0, xr.Length, xr, 0, null, out clevent); Assert.AreEqual(ErrorCode.Success, error, error.ToString()); Cl.Finish(cmdQueue); } }
public void TestSlimeFinder() { const int squareLength = 1024; int globalSize = squareLength * squareLength; var candidates = new int[globalSize]; ErrorCode error; Device device = (from d in Cl.GetDeviceIDs( (from platform in Cl.GetPlatformIDs(out error) where Cl.GetPlatformInfo(platform, PlatformInfo.Name, out error).ToString() == "AMD Accelerated Parallel Processing" // Use "NVIDIA CUDA" if you don't have amd select platform).First(), DeviceType.Gpu, out error) select d).First(); Context context = Cl.CreateContext(null, 1, new[] { device }, null, IntPtr.Zero, out error); string source = System.IO.File.ReadAllText("kernels.cl"); using Program program = Cl.CreateProgramWithSource(context, 1, new[] { source }, null, out error); error = Cl.BuildProgram(program, 1, new[] { device }, string.Empty, null, IntPtr.Zero); InfoBuffer buildStatus = Cl.GetProgramBuildInfo(program, device, ProgramBuildInfo.Status, out error); Assert.AreEqual(buildStatus.CastTo <BuildStatus>(), BuildStatus.Success); Assert.AreEqual(error, ErrorCode.Success); Kernel[] kernels = Cl.CreateKernelsInProgram(program, out error); Kernel kernel = kernels[0]; Assert.AreEqual(error, ErrorCode.Success); CommandQueue queue = Cl.CreateCommandQueue(context, device, CommandQueueProperties.None, out error); Assert.AreEqual(error, ErrorCode.Success); IMem dataOut = Cl.CreateBuffer(context, MemFlags.WriteOnly, (IntPtr)(globalSize * sizeof(int)), out error); Assert.AreEqual(error, ErrorCode.Success); var intSizePtr = new IntPtr(Marshal.SizeOf(typeof(int))); error = Cl.SetKernelArg(kernel, 0, intSizePtr, new IntPtr(0)); error |= Cl.SetKernelArg(kernel, 1, intSizePtr, new IntPtr(0)); error |= Cl.SetKernelArg(kernel, 2, new IntPtr(Marshal.SizeOf(typeof(IntPtr))), dataOut); error |= Cl.SetKernelArg(kernel, 3, intSizePtr, new IntPtr(420)); error |= Cl.SetKernelArg(kernel, 4, intSizePtr, new IntPtr(globalSize)); Assert.AreEqual(error, ErrorCode.Success); int local_size = 256; int global_size = (int)Math.Ceiling(globalSize / (float)local_size) * local_size; var stopW = new Stopwatch(); stopW.Start(); error = Cl.EnqueueNDRangeKernel(queue, kernel, 1, null, new IntPtr[] { new IntPtr(global_size) }, new IntPtr[] { new IntPtr(local_size) }, 0, null, out Event clevent); Assert.AreEqual(error, ErrorCode.Success); Cl.Finish(queue); stopW.Stop(); Cl.EnqueueReadBuffer(queue, dataOut, Bool.True, IntPtr.Zero, (IntPtr)(globalSize * sizeof(int)), candidates, 0, null, out clevent); candidates.ForEach(c => { if (c > 50) { Console.Write($"{c},"); } }); Console.WriteLine($"\n{stopW.ElapsedMilliseconds} ms"); error = Cl.SetKernelArg(kernel, 0, intSizePtr, new IntPtr(16383)); error |= Cl.SetKernelArg(kernel, 1, intSizePtr, new IntPtr(16383)); stopW.Start(); error = Cl.EnqueueNDRangeKernel(queue, kernel, 1, null, new IntPtr[] { new IntPtr(global_size) }, new IntPtr[] { new IntPtr(local_size) }, 0, null, out clevent); Assert.AreEqual(error, ErrorCode.Success); Cl.Finish(queue); stopW.Stop(); Cl.EnqueueReadBuffer(queue, dataOut, Bool.True, IntPtr.Zero, (IntPtr)(globalSize * sizeof(int)), candidates, 0, null, out clevent); candidates.ForEach(c => { if (c > 50) { Console.Write($"{c},"); } }); Console.WriteLine($"\n{stopW.ElapsedMilliseconds} ms"); Cl.ReleaseKernel(kernel); Cl.ReleaseMemObject(dataOut); Cl.ReleaseCommandQueue(queue); Cl.ReleaseProgram(program); Cl.ReleaseContext(context); }
public void SquareArray() { // Adapted from //https://github.com/rsnemmen/OpenCL-examples/blob/master/square_array/square.cl int array_size = 100000; var bytes = (IntPtr)(array_size * sizeof(float)); var hdata = new float[array_size]; var houtput = new float[array_size]; for (int i = 0; i < array_size; i++) { hdata[i] = 1.0f * i; } ErrorCode error; Device device = (from d in Cl.GetDeviceIDs( (from platform in Cl.GetPlatformIDs(out error) where Cl.GetPlatformInfo(platform, PlatformInfo.Name, out error).ToString() == "AMD Accelerated Parallel Processing" // Use "NVIDIA CUDA" if you don't have amd select platform).First(), DeviceType.Gpu, out error) select d).First(); Context context = Cl.CreateContext(null, 1, new[] { device }, null, IntPtr.Zero, out error); string source = System.IO.File.ReadAllText("squared.cl"); using (Program program = Cl.CreateProgramWithSource(context, 1, new[] { source }, null, out error)) { Assert.AreEqual(error, ErrorCode.Success); error = Cl.BuildProgram(program, 1, new[] { device }, string.Empty, null, IntPtr.Zero); Assert.AreEqual(ErrorCode.Success, error); Assert.AreEqual(Cl.GetProgramBuildInfo(program, device, ProgramBuildInfo.Status, out error).CastTo <BuildStatus>(), BuildStatus.Success); Kernel[] kernels = Cl.CreateKernelsInProgram(program, out error); Kernel kernel = kernels[0]; CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, (CommandQueueProperties)0, out error); IMem ddata = Cl.CreateBuffer(context, MemFlags.ReadOnly, bytes, null, out error); IMem doutput = Cl.CreateBuffer(context, MemFlags.WriteOnly, bytes, null, out error); error = Cl.EnqueueWriteBuffer(cmdQueue, ddata, Bool.True, (IntPtr)0, bytes, hdata, 0, null, out Event clevent); Assert.AreEqual(ErrorCode.Success, error); error = Cl.SetKernelArg(kernel, 0, new IntPtr(Marshal.SizeOf(typeof(IntPtr))), ddata); error |= Cl.SetKernelArg(kernel, 1, new IntPtr(Marshal.SizeOf(typeof(IntPtr))), doutput); error |= Cl.SetKernelArg(kernel, 2, new IntPtr(Marshal.SizeOf(typeof(int))), new IntPtr(array_size)); Assert.AreEqual(error, ErrorCode.Success); int local_size = 256; var infoBufferr = new InfoBuffer(); error = Cl.GetKernelWorkGroupInfo(kernel, device, KernelWorkGroupInfo.WorkGroupSize, new IntPtr(sizeof(int)), new InfoBuffer(), out IntPtr localSize); var x = localSize.ToInt32();//Why is it giving me 8??? Vega 56 has 256 work group size int global_size = (int)Math.Ceiling(array_size / (float)local_size) * local_size; error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 1, null, new IntPtr[] { new IntPtr(global_size) }, new IntPtr[] { new IntPtr(local_size) }, 0, null, out clevent); Cl.Finish(cmdQueue); Cl.EnqueueReadBuffer(cmdQueue, doutput, Bool.True, IntPtr.Zero, bytes, houtput, 0, null, out clevent); houtput.ForEach(o => Console.Write($"{o}, ")); Cl.ReleaseKernel(kernel); Cl.ReleaseMemObject(ddata); Cl.ReleaseMemObject(doutput); Cl.ReleaseCommandQueue(cmdQueue); Cl.ReleaseProgram(program); Cl.ReleaseContext(context); } }
public HTTPResponse GetResponse(HTTPRequest request) { HTTPResponse response = new HTTPResponse(200); StringBuilder sb = new StringBuilder(); ErrorCode error; if (!_isInit) { init(); _isInit = true; } if (request.Method == HTTPRequest.METHOD_GET) { sb.Append("<html><body>"); sb.Append(GenUploadForm()); sb.Append("</body></html>"); response.Body = Encoding.UTF8.GetBytes(sb.ToString()); return(response); } else if (request.Method == HTTPRequest.METHOD_POST) { sb.Append(request.Body); response.Body = Encoding.UTF8.GetBytes(sb.ToString()); string programPath = System.Environment.CurrentDirectory + "/Kernel.cl"; if (!System.IO.File.Exists(programPath)) { Console.WriteLine("Program doesn't exist at path " + programPath); return(new HTTPResponse(404)); } sb.Append("<html><body>"); string programSource = System.IO.File.ReadAllText(programPath); using (OpenCL.Net.Program program = Cl.CreateProgramWithSource(_context, 1, new[] { programSource }, null, out error)) { LogError(error, "Cl.CreateProgramWithSource"); error = Cl.BuildProgram(program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero); LogError(error, "Cl.BuildProgram"); if (Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <OpenCL.Net.BuildStatus>() != BuildStatus.Success) { LogError(error, "Cl.GetProgramBuildInfo"); Console.WriteLine("Cl.GetProgramBuildInfo != Success"); Console.WriteLine(Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Log, out error)); return(new HTTPResponse(404)); } Kernel kernel = Cl.CreateKernel(program, "answer", out error); LogError(error, "Cl.CreateKernel"); Random rand = new Random(); int[] input = (from i in Enumerable.Range(0, 100) select(int) rand.Next()).ToArray(); int[] output = new int[100]; var buffIn = _context.CreateBuffer(input, MemFlags.ReadOnly); var buffOut = _context.CreateBuffer(output, MemFlags.WriteOnly); int IntPtrSize = Marshal.SizeOf(typeof(IntPtr)); error = Cl.SetKernelArg(kernel, 0, (IntPtr)IntPtrSize, buffIn); error |= Cl.SetKernelArg(kernel, 1, (IntPtr)IntPtrSize, buffOut); LogError(error, "Cl.SetKernelArg"); CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error); LogError(error, "Cl.CreateCommandQueue"); Event clevent; error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, new[] { (IntPtr)100, (IntPtr)1 }, null, 0, null, out clevent); LogError(error, "Cl.EnqueueNDRangeKernel"); error = Cl.Finish(cmdQueue); LogError(error, "Cl.Finih"); error = Cl.EnqueueReadBuffer(cmdQueue, buffOut, OpenCL.Net.Bool.True, 0, 100, output, 0, null, out clevent); LogError(error, "Cl.EnqueueReadBuffer"); error = Cl.Finish(cmdQueue); LogError(error, "Cl.Finih"); Cl.ReleaseKernel(kernel); Cl.ReleaseCommandQueue(cmdQueue); Cl.ReleaseMemObject(buffIn); Cl.ReleaseMemObject(buffOut); sb.Append("<pre>"); for (int i = 0; i != 100; i++) { sb.Append(input[i] + " % 42 = " + output[i] + "<br />"); } sb.Append("</pre>"); } sb.Append("</body></html>"); response.Body = Encoding.UTF8.GetBytes(sb.ToString()); return(response); } return(new HTTPResponse(501)); }
public void VecAdd() { if (!prepared) { Prepare(this.BuildIR().InlineIR()); prepared = true; } // create kernel Cl.Kernel kernel = Cl.CreateKernel(program, "VecAdd", out error); clSafeCall(error); // create command queue Cl.CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, Cl.CommandQueueProperties.None, out error); clSafeCall(error); int length = 1 << 10; // allocate host vectors float[] A = new float[length]; float[] B = new float[length]; float[] C = new float[length]; // initialize host memory Random rand = new Random(); for (int i = 0; i < length; i++) { A[i] = (float)rand.Next() / short.MaxValue; B[i] = (float)rand.Next() / short.MaxValue; } // allocate device vectors Cl.Mem hDeviceMemA = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadOnly, (IntPtr)(sizeof(float) * length), A, out error); clSafeCall(error); Cl.Mem hDeviceMemB = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadOnly, (IntPtr)(sizeof(float) * length), B, out error); clSafeCall(error); Cl.Mem hDeviceMemC = Cl.CreateBuffer(context, Cl.MemFlags.WriteOnly, (IntPtr)(sizeof(float) * length), IntPtr.Zero, out error); clSafeCall(error); // setup kernel arguments clSafeCall(Cl.SetKernelArg(kernel, 0, hDeviceMemA)); clSafeCall(Cl.SetKernelArg(kernel, 1, hDeviceMemB)); clSafeCall(Cl.SetKernelArg(kernel, 2, hDeviceMemC)); clSafeCall(Cl.SetKernelArg(kernel, 3, length)); // execute kernel clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 1, null, new[] { (IntPtr)length }, new[] { (IntPtr)256 }, 0, null, out clevent)); // copy results from device back to host clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, hDeviceMemC, Cl.Bool.True, IntPtr.Zero, (IntPtr)(sizeof(float) * length), C, 0, null, out clevent)); clSafeCall(Cl.Finish(cmdQueue)); for (int i = 0; i < length; i++) { float sum = A[i] + B[i]; float err = Math.Abs((sum - C[i]) / sum); Assert.That(err, Is.LessThanOrEqualTo(1E-3F)); } }
/* Broken at the moment. */ public void GetStatGPU(string file) { var stopwatch = new System.Diagnostics.Stopwatch(); stopwatch.Start(); stopwatch.Restart(); ErrorCode err; using (OpenCL.Net.Program program = Cl.CreateProgramWithSource(clInfo._context, 1, new[] { clInfo.KernelSrc }, null, out err)) { clInfo.CheckErr(err, "Cl.CreateProgramWithSource"); //Compile Kernels & check errors. err = Cl.BuildProgram(program, 1, new[] { clInfo._device }, string.Empty, null, IntPtr.Zero); clInfo.CheckErr(err, "Cl.BuildProgram"); if (Cl.GetProgramBuildInfo(program, clInfo._device, ProgramBuildInfo.Status, out err).CastTo <BuildStatus>() != BuildStatus.Success) { clInfo.CheckErr(err, "Cl.GetProgramBuildInfo"); Console.WriteLine("Cl.GetProgramBuildInfo != Success"); Console.WriteLine(Cl.GetProgramBuildInfo(program, clInfo._device, ProgramBuildInfo.Log, out err)); } //Specify the specific kernel for use Kernel kernel = Cl.CreateKernel(program, "satAvg", out err); clInfo.CheckErr(err, "Cl.CreateKernel"); int intPtrSize = 0; intPtrSize = Marshal.SizeOf(typeof(IntPtr)); IMem image2DBuffer; OpenCL.Net.ImageFormat imageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8); int imageWidth, imageHeight, imageBytesSize, imageStride; using (FileStream imgStream = new FileStream(file, FileMode.Open)) { Image image = Image.FromStream(imgStream); if (image == null) { Console.Error.WriteLine($"failed to open file {file}"); return; } imageWidth = image.Width; imageHeight = image.Height; //Create a bitmap from the file with the correct channel settings. Bitmap inputBitmap = new Bitmap(image); BitmapData bitmapDat = inputBitmap.LockBits(new Rectangle(0, 0, inputBitmap.Width, inputBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); imageStride = bitmapDat.Stride; imageBytesSize = imageStride * bitmapDat.Height; byte[] inputByteArray = new byte[imageBytesSize]; Marshal.Copy(bitmapDat.Scan0, inputByteArray, 0, imageBytesSize); //Create & populate memory buffer for use in Kernel image2DBuffer = Cl.CreateImage2D(clInfo._context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, imageFormat, (IntPtr)inputBitmap.Width, (IntPtr)inputBitmap.Height, (IntPtr)0, inputByteArray, out err); clInfo.CheckErr(err, "Cl.CreateImage2D output"); } //Create an output buffer for the average saturation of the image. float saturation = 0; IMem sat = Cl.CreateBuffer(clInfo._context, MemFlags.CopyHostPtr | MemFlags.WriteOnly, (IntPtr)intPtrSize, (object)saturation, out err); clInfo.CheckErr(err, "Cl.CreateBuffer saturation"); //Passing buffers to the CL kernel err = Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, image2DBuffer); //TODO: Figure out how to pass a float to the kernel //err |= Cl.SetKernelArg(kernel, 1, (IntPtr)intPtrSize, sat ); clInfo.CheckErr(err, "Cl.SetKernelArg"); //Create & queue commands CommandQueue cmdQueue = Cl.CreateCommandQueue(clInfo._context, clInfo._device, CommandQueueProperties.None, out err); clInfo.CheckErr(err, "Cl.CreateCommandQueue"); Event @event; //Transfer image data to kernel buffers IntPtr[] originPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; IntPtr[] regionPtr = new IntPtr[] { (IntPtr)imageWidth, (IntPtr)imageHeight, (IntPtr)1 }; IntPtr[] workGroupPtr = new IntPtr[] { (IntPtr)imageWidth, (IntPtr)imageHeight, (IntPtr)1 }; err = Cl.EnqueueReadImage(cmdQueue, image2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, null, 0, null, out @event); clInfo.CheckErr(err, "Cl.EnqueueReadImage"); //Execute the kerenl err = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupPtr, null, 0, null, out @event); clInfo.CheckErr(err, "Cl.EnqueueNDRangeKernel"); err = Cl.Finish(cmdQueue); clInfo.CheckErr(err, "Cl.Finish"); Cl.ReleaseKernel(kernel); Cl.ReleaseCommandQueue(cmdQueue); Cl.ReleaseMemObject(image2DBuffer); } Console.WriteLine(stopwatch.Elapsed); stopwatch.Stop(); }
public void PoissonJacobi() { if (!prepared) { Prepare(this.BuildIR().InlineIR()); prepared = true; } // create kernel Cl.Kernel kernel = Cl.CreateKernel(program, "PoissonJacobi", out error); clSafeCall(error); // create command queue Cl.CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, Cl.CommandQueueProperties.None, out error); clSafeCall(error); // initialize host memory uint dimX = 162; uint dimY = 122; uint N = 15000; float x0 = (float)(-0.25 * Math.PI); float y0 = (float)(-0.25 * Math.PI); float hx = 2.0f * Math.Abs(x0) / dimX; float hy = 2.0f * Math.Abs(y0) / dimY; float[] hData = new float[dimX * dimY]; uint stride = dimX; //boundary values for (uint i = 1; i < dimY - 1; i++) { uint y_idx = i * stride; float y_val = y0 + i * hy; hData[y_idx] = u(x0, y_val); hData[y_idx + dimX - 1] = u(x0 + (dimX - 1) * hx, y_val); } for (uint j = 1; j < dimX - 1; j++) { float x_val = x0 + j * hx; hData[j] = u(x_val, y0); hData[j + (dimY - 1) * stride] = u(x_val, y0 + (dimY - 1) * hy); } // allocate device vectors Cl.Mem input = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadWrite, (IntPtr)(sizeof(float) * hData.Length), hData, out error); clSafeCall(error); Cl.Mem output = Cl.CreateBuffer(context, Cl.MemFlags.CopyHostPtr | Cl.MemFlags.ReadWrite, (IntPtr)(sizeof(float) * hData.Length), hData, out error); clSafeCall(error); float a1 = 2 * hy / hx; float a2 = 2 * hx / hy; float a3 = a1; float a4 = a2; float a = a1 + a2 + a3 + a4; // setup kernel arguments clSafeCall(Cl.SetKernelArg(kernel, 2, (AREA_SIZE_Y + 2) * (AREA_SIZE_X + 2) * sizeof(float), null)); clSafeCall(Cl.SetKernelArg(kernel, 3, dimX)); clSafeCall(Cl.SetKernelArg(kernel, 4, dimY)); clSafeCall(Cl.SetKernelArg(kernel, 5, stride)); clSafeCall(Cl.SetKernelArg(kernel, 6, a1)); clSafeCall(Cl.SetKernelArg(kernel, 7, a2)); clSafeCall(Cl.SetKernelArg(kernel, 8, a3)); clSafeCall(Cl.SetKernelArg(kernel, 9, a4)); clSafeCall(Cl.SetKernelArg(kernel, 10, a)); clSafeCall(Cl.SetKernelArg(kernel, 11, hx)); clSafeCall(Cl.SetKernelArg(kernel, 12, hy)); clSafeCall(Cl.SetKernelArg(kernel, 13, x0)); clSafeCall(Cl.SetKernelArg(kernel, 14, y0)); IntPtr[] lo = { (IntPtr)16, (IntPtr)16 }; IntPtr[] gl = { (IntPtr)((dimX - 2 + AREA_SIZE_X - 1) / AREA_SIZE_X * 16), (IntPtr)((dimY - 2 + AREA_SIZE_Y - 1) / AREA_SIZE_Y * 16) }; Cl.Mem curIn = input; Cl.Mem curOut = output; // execute kernel (and perform data transfering silently) clSafeCall(Cl.SetKernelArg(kernel, 0, curIn)); clSafeCall(Cl.SetKernelArg(kernel, 1, curOut)); clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, gl, lo, 0, null, out clevent)); clSafeCall(Cl.Finish(cmdQueue)); Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); for (uint idx = 1; idx < N; idx++) { // swap buffers Cl.Mem temp = curIn; curIn = curOut; curOut = temp; // execute kernel clSafeCall(Cl.SetKernelArg(kernel, 0, curIn)); clSafeCall(Cl.SetKernelArg(kernel, 1, curOut)); clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, gl, lo, 0, null, out clevent)); } clSafeCall(Cl.Finish(cmdQueue)); stopwatch.Stop(); // copy results from device back to host clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, curOut, Cl.Bool.True, IntPtr.Zero, (IntPtr)(sizeof(float) * hData.Length), hData, 0, null, out clevent)); clSafeCall(Cl.Finish(cmdQueue)); float avgerr = 0, maxerr = 0; for (uint i = 1; i < dimY - 1; i++) { for (uint j = 1; j < dimX - 1; j++) { float theory = u(x0 + j * hx, y0 + i * hy); float err = Math.Abs(theory - hData[j + i * stride]) / Math.Abs(theory); avgerr += err; maxerr = Math.Max(maxerr, err); } } avgerr /= dimX * dimY; long elapsedTime = stopwatch.ElapsedMilliseconds; double dataSizePerIteration = dimX * dimY * 2 * sizeof(float); double dataSizeTotal = dataSizePerIteration * N; double elapsedSeconds = elapsedTime * 0.001; double gigabyteFactor = 1 << 30; double bandwidth = dataSizeTotal / (gigabyteFactor * elapsedSeconds); Console.WriteLine("avgerr = {0} maxerr = {1} elapsedTime = {2} ms bandwidth = {3} GB/s", avgerr, maxerr, elapsedTime, bandwidth); Assert.That(maxerr, Is.LessThanOrEqualTo(5E-2F)); Assert.That(avgerr, Is.LessThanOrEqualTo(1E-2F)); }
public static void SetupSpace(int deviceID) { //int deviceID; // will be asked to user List <Device> devicesList = new List <Device>(); List <string> deviceNames = new List <string>(); List <string> platformNames = new List <string>(); int nDevices = 0; // Get list of available platforms Console.WriteLine("\nSearching for OpenCL-capable platforms... "); Platform[] platforms = Cl.GetPlatformIDs(out ClError); CheckErr(ClError, "CL.Setup: Cl.GetPlatformIDs"); Console.WriteLine("{0} platforms found.\n", platforms.Length); foreach (Platform platform in platforms) { // Get platform info string platformName = Cl.GetPlatformInfo(platform, PlatformInfo.Name, out ClError).ToString(); Console.WriteLine("Platform: " + platformName); CheckErr(ClError, "CL.Setup: Cl.GetPlatformInfo"); // Get all available devices within this platform and list them on screen foreach (Device dev in Cl.GetDeviceIDs(platform, DeviceType.All, out ClError)) { CheckErr(ClError, "CL.Setup: Cl.GetDeviceIDs"); string deviceName = Cl.GetDeviceInfo(dev, DeviceInfo.Name, out ClError).ToString(); CheckErr(ClError, "CL.Setup: Cl.GetDeviceInfo"); Console.WriteLine("Device {0}: {1}", nDevices, deviceName); devicesList.Add(dev); deviceNames.Add(deviceName); platformNames.Add(platformName); nDevices++; } Console.WriteLine(); } if (nDevices == 0) { throw new PlatformNotSupportedException("No OpenCL-capable platform and/or devices were found on this system."); } //Console.Write("Enter ID of device to use: "); //deviceID = int.Parse(Console.ReadLine()); // Select device according to user's choice device = devicesList[deviceID]; Console.WriteLine("\nUsing device {0}", deviceNames[deviceID]); // Create OpenCL context context = Cl.CreateContext(null, 1, new[] { device }, ContextNotify, IntPtr.Zero, out ClError); //Second parameter is amount of devices CheckErr(ClError, "CL.Setup: Cl.CreateContext"); // Create OpenCL command queue queue = Cl.CreateCommandQueue(context, device, (CommandQueueProperties)0, out ClError); CheckErr(ClError, "CL.Setup: Cl.CreateCommandQueue"); // Extract some device info maxWorkItemSizes = Cl.GetDeviceInfo(device, DeviceInfo.MaxWorkItemSizes, out ClError).CastToEnumerable <int>(new int[] { 0, 1, 2 }).ToList(); Console.WriteLine("Max work item sizes: {0}, {1}, {2}", maxWorkItemSizes[0], maxWorkItemSizes[1], maxWorkItemSizes[2]); maxWorkGroupSize = Cl.GetDeviceInfo(device, DeviceInfo.MaxWorkGroupSize, out ClError).CastTo <int>(); Console.WriteLine("Max work group size: {0}", maxWorkGroupSize); maxComputeUnits = Cl.GetDeviceInfo(device, DeviceInfo.MaxComputeUnits, out ClError).CastTo <int>(); Console.WriteLine("Max compute units: {0}", maxComputeUnits); }
public void ImagingTest(string inputImagePath, string outputImagePath) { ErrorCode error; //Load and compile kernel source code. string programPath = System.Environment.CurrentDirectory + "/../../imagingtest.cl"; //The path to the source file may vary if (!System.IO.File.Exists(programPath)) { Console.WriteLine("Program doesn't exist at path " + programPath); return; } string programSource = System.IO.File.ReadAllText(programPath); using (Program program = Cl.CreateProgramWithSource(_context, 1, new[] { programSource }, null, out error)) { CheckErr(error, "Cl.CreateProgramWithSource"); //Compile kernel source error = Cl.BuildProgram(program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero); CheckErr(error, "Cl.BuildProgram"); //Check for any compilation errors if (Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <BuildStatus>() != BuildStatus.Success && 1 == 0) { CheckErr(error, "Cl.GetProgramBuildInfo"); Console.WriteLine("Cl.GetProgramBuildInfo != Success"); Console.WriteLine(Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Log, out error)); return; } //Create the required kernel (entry function) Kernel kernel = Cl.CreateKernel(program, "imagingTest", out error); CheckErr(error, "Cl.CreateKernel"); int intPtrSize = 0; intPtrSize = Marshal.SizeOf(typeof(IntPtr)); //Image's RGBA data converted to an unmanaged[] array byte[] inputByteArray; //OpenCL memory buffer that will keep our image's byte[] data. Mem inputImage2DBuffer; OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8); int inputImgWidth, inputImgHeight; int inputImgBytesSize; int inputImgStride; //Try loading the input image using (FileStream imageFileStream = new FileStream(inputImagePath, FileMode.Open)) { System.Drawing.Image inputImage = System.Drawing.Image.FromStream(imageFileStream); if (inputImage == null) { Console.WriteLine("Unable to load input image"); return; } inputImgWidth = inputImage.Width; inputImgHeight = inputImage.Height; System.Drawing.Bitmap bmpImage = new System.Drawing.Bitmap(inputImage); //Get raw pixel data of the bitmap //The format should match the format of clImageFormat BitmapData bitmapData = bmpImage.LockBits(new Rectangle(0, 0, bmpImage.Width, bmpImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);//inputImage.PixelFormat); inputImgStride = bitmapData.Stride; inputImgBytesSize = bitmapData.Stride * bitmapData.Height; //Copy the raw bitmap data to an unmanaged byte[] array inputByteArray = new byte[inputImgBytesSize]; Marshal.Copy(bitmapData.Scan0, inputByteArray, 0, inputImgBytesSize); //Allocate OpenCL image memory buffer inputImage2DBuffer = (OpenCL.Net.Mem)OpenCL.Net.Cl.CreateImage2D(_context, OpenCL.Net.MemFlags.CopyHostPtr | OpenCL.Net.MemFlags.ReadOnly, clImageFormat, (IntPtr)bitmapData.Width, (IntPtr)bitmapData.Height, (IntPtr)0, inputByteArray, out error); CheckErr(error, "Cl.CreateImage2D input"); } //Unmanaged output image's raw RGBA byte[] array byte[] outputByteArray = new byte[inputImgBytesSize]; //Allocate OpenCL image memory buffer OpenCL.Net.Mem outputImage2DBuffer = (OpenCL.Net.Mem)OpenCL.Net.Cl.CreateImage2D(_context, OpenCL.Net.MemFlags.CopyHostPtr | OpenCL.Net.MemFlags.WriteOnly, clImageFormat, (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)0, outputByteArray, out error); CheckErr(error, "Cl.CreateImage2D output"); //Pass the memory buffers to our kernel function error = Cl.SetKernelArg(kernel, 0, (IntPtr)intPtrSize, inputImage2DBuffer); error |= Cl.SetKernelArg(kernel, 1, (IntPtr)intPtrSize, outputImage2DBuffer); CheckErr(error, "Cl.SetKernelArg"); //Create a command queue, where all of the commands for execution will be added CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error); CheckErr(error, "Cl.CreateCommandQueue"); OpenCL.Net.Event clevent; //Copy input image from the host to the GPU. IntPtr[] originPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; //x, y, z IntPtr[] regionPtr = new IntPtr[] { (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)1 }; //x, y, z IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)inputImgWidth, (IntPtr)inputImgHeight, (IntPtr)1 }; error = Cl.EnqueueWriteImage(cmdQueue, inputImage2DBuffer, OpenCL.Net.Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, inputByteArray, 0, null, out clevent); CheckErr(error, "Cl.EnqueueWriteImage"); //Execute our kernel (OpenCL code) // CommandQueue q = new OpenCL.Net.CommandQueue(); //enqueue nd range kernel // error = cmdQueue.EnqueueKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent); // OpenCL.Net.Cl.EnqueueNDRangeKernel( OpenCL.Net.Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent); CheckErr(error, "Cl.EnqueueNDRangeKernel"); //Wait for completion of all calculations on the GPU. error = Cl.Finish(cmdQueue); CheckErr(error, "Cl.Finish"); //Read the processed image from GPU to raw RGBA data byte[] array error = Cl.EnqueueReadImage(cmdQueue, outputImage2DBuffer, OpenCL.Net.Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, outputByteArray, 0, null, out clevent); CheckErr(error, "Cl.clEnqueueReadImage"); //Clean up memory Cl.ReleaseKernel(kernel); Cl.ReleaseCommandQueue(cmdQueue); Cl.ReleaseMemObject(inputImage2DBuffer); Cl.ReleaseMemObject(outputImage2DBuffer); //Get a pointer to our unmanaged output byte[] array GCHandle pinnedOutputArray = GCHandle.Alloc(outputByteArray, GCHandleType.Pinned); IntPtr outputBmpPointer = pinnedOutputArray.AddrOfPinnedObject(); //Create a new bitmap with processed data and save it to a file. Bitmap outputBitmap = new Bitmap(inputImgWidth, inputImgHeight, inputImgStride, PixelFormat.Format32bppArgb, outputBmpPointer); outputBitmap.Save(outputImagePath, System.Drawing.Imaging.ImageFormat.Png); pinnedOutputArray.Free(); } }
public void SmallTypes(Cl.Program program) { // create kernel Cl.Kernel kernel = Cl.CreateKernel(program, "SmallTypes", out error); clSafeCall(error); // create command queue Cl.CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, Cl.CommandQueueProperties.None, out error); clSafeCall(error); // allocate host vectors short[] hres1 = { 0 }; short[] hres2 = { 0 }; // allocate device vectors Cl.Mem dres1 = Cl.CreateBuffer(context, Cl.MemFlags.WriteOnly, (IntPtr)(sizeof(short) * hres1.Length), IntPtr.Zero, out error); clSafeCall(error); Cl.Mem dres2 = Cl.CreateBuffer(context, Cl.MemFlags.WriteOnly, (IntPtr)(sizeof(short) * hres2.Length), IntPtr.Zero, out error); clSafeCall(error); // setup kernel arguments clSafeCall(Cl.SetKernelArg(kernel, 0, dres1)); clSafeCall(Cl.SetKernelArg(kernel, 1, dres2)); clSafeCall(Cl.SetKernelArg(kernel, 2, (byte)1)); clSafeCall(Cl.SetKernelArg(kernel, 3, (sbyte)-20)); clSafeCall(Cl.SetKernelArg(kernel, 4, (ushort)30)); clSafeCall(Cl.SetKernelArg(kernel, 5, (short)-4)); clSafeCall(Cl.SetKernelArg(kernel, 6, true)); // execute kernel clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 1, null, new[] { (IntPtr)1 }, null, 0, null, out clevent)); // copy results from device back to host clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, dres1, Cl.Bool.True, IntPtr.Zero, (IntPtr)(sizeof(short) * hres1.Length), hres1, 0, null, out clevent)); clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, dres2, Cl.Bool.True, IntPtr.Zero, (IntPtr)(sizeof(short) * hres1.Length), hres2, 0, null, out clevent)); clSafeCall(Cl.Finish(cmdQueue)); Assert.AreEqual(7, hres1[0]); Assert.AreEqual(-7, hres2[0]); // setup kernel arguments clSafeCall(Cl.SetKernelArg(kernel, 6, false)); // execute kernel clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 1, null, new[] { (IntPtr)1 }, null, 0, null, out clevent)); // copy results from device back to host clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, dres1, Cl.Bool.True, IntPtr.Zero, (IntPtr)(sizeof(short) * hres1.Length), hres1, 0, null, out clevent)); clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, dres2, Cl.Bool.True, IntPtr.Zero, (IntPtr)(sizeof(short) * hres1.Length), hres2, 0, null, out clevent)); clSafeCall(Cl.Finish(cmdQueue)); Assert.AreEqual(-7, hres1[0]); Assert.AreEqual(7, hres2[0]); }
public HTTPResponse GetResponse(HTTPRequest request) { HTTPResponse response = new HTTPResponse(200); StringBuilder sb = new StringBuilder(); ErrorCode error; if (!_isInit) { init(); _isInit = true; } if (request.Method == HTTPRequest.METHOD_GET) { // Input form, this can be place by any HTML page sb.Append("<html><body>"); sb.Append(GenUploadForm()); sb.Append("</body></html>"); response.Body = Encoding.UTF8.GetBytes(sb.ToString()); return(response); } else if (request.Method == HTTPRequest.METHOD_POST) { // Get remote image from URL string url = Uri.UnescapeDataString(request.GetRequestByKey("imageUploadUrl")); byte[] data; try { data = DownloadImageFromUrl(url); } catch (Exception) { return(new HTTPResponse(400)); } // https://www.codeproject.com/Articles/502829/GPGPU-image-processing-basics-using-OpenCL-NET // Convert image to bitmap binary Image inputImage = Image.FromStream(new MemoryStream(data)); if (inputImage == null) { return(new HTTPResponse(500)); } int imagewidth = inputImage.Width; int imageHeight = inputImage.Height; Bitmap bmpImage = new Bitmap(inputImage); BitmapData bitmapData = bmpImage.LockBits(new Rectangle(0, 0, bmpImage.Width, bmpImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); int inputImageByteSize = bitmapData.Stride * bitmapData.Height; byte[] inputByteArray = new byte[inputImageByteSize]; Marshal.Copy(bitmapData.Scan0, inputByteArray, 0, inputImageByteSize); // Load kernel source code string programPath = System.Environment.CurrentDirectory + "/Kernel.cl"; if (!System.IO.File.Exists(programPath)) { return(new HTTPResponse(404)); } string programSource = System.IO.File.ReadAllText(programPath); using (OpenCL.Net.Program program = Cl.CreateProgramWithSource(_context, 1, new[] { programSource }, null, out error)) { // Create kernel LogError(error, "Cl.CreateProgramWithSource"); error = Cl.BuildProgram(program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero); LogError(error, "Cl.BuildProgram"); if (Cl.GetProgramBuildInfo(program, _device, ProgramBuildInfo.Status, out error).CastTo <OpenCL.Net.BuildStatus>() != BuildStatus.Success) { LogError(error, "Cl.GetProgramBuildInfo"); return(new HTTPResponse(404)); } Kernel kernel = Cl.CreateKernel(program, _parameters["KernelFunction"], out error); LogError(error, "Cl.CreateKernel"); // Create image memory objects OpenCL.Net.ImageFormat clImageFormat = new OpenCL.Net.ImageFormat(ChannelOrder.RGBA, ChannelType.Unsigned_Int8); IMem inputImage2DBuffer = Cl.CreateImage2D(_context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, clImageFormat, (IntPtr)bitmapData.Width, (IntPtr)bitmapData.Height, (IntPtr)0, inputByteArray, out error); LogError(error, "CreateImage2D input"); byte[] outputByteArray = new byte[inputImageByteSize]; IMem outputImage2DBuffer = Cl.CreateImage2D(_context, MemFlags.CopyHostPtr | MemFlags.WriteOnly, clImageFormat, (IntPtr)bitmapData.Width, (IntPtr)bitmapData.Height, (IntPtr)0, outputByteArray, out error); LogError(error, "CreateImage2D output"); // Set arguments int IntPtrSize = Marshal.SizeOf(typeof(IntPtr)); error = Cl.SetKernelArg(kernel, 0, (IntPtr)IntPtrSize, inputImage2DBuffer); error |= Cl.SetKernelArg(kernel, 1, (IntPtr)IntPtrSize, outputImage2DBuffer); LogError(error, "Cl.SetKernelArg"); // Create command queue CommandQueue cmdQueue = Cl.CreateCommandQueue(_context, _device, (CommandQueueProperties)0, out error); LogError(error, "Cl.CreateCommandQueue"); Event clevent; // Copy input image from the host to the GPU IntPtr[] originPtr = new IntPtr[] { (IntPtr)0, (IntPtr)0, (IntPtr)0 }; IntPtr[] regionPtr = new IntPtr[] { (IntPtr)imagewidth, (IntPtr)imageHeight, (IntPtr)1 }; IntPtr[] workGroupSizePtr = new IntPtr[] { (IntPtr)imagewidth, (IntPtr)imageHeight, (IntPtr)1 }; error = Cl.EnqueueWriteImage(cmdQueue, inputImage2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, inputByteArray, 0, null, out clevent); LogError(error, "Cl.EnqueueWriteImage"); // Run the kernel error = Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 2, null, workGroupSizePtr, null, 0, null, out clevent); LogError(error, "Cl.EnqueueNDRangeKernel"); // Wait for finish event error = Cl.Finish(cmdQueue); LogError(error, "Cl.Finish"); // Read the output image back from GPU error = Cl.EnqueueReadImage(cmdQueue, outputImage2DBuffer, Bool.True, originPtr, regionPtr, (IntPtr)0, (IntPtr)0, outputByteArray, 0, null, out clevent); LogError(error, "Cl.EnqueueReadImage"); error = Cl.Finish(cmdQueue); LogError(error, "Cl.Finih"); // Release memory Cl.ReleaseKernel(kernel); Cl.ReleaseCommandQueue(cmdQueue); Cl.ReleaseMemObject(inputImage2DBuffer); Cl.ReleaseMemObject(outputImage2DBuffer); // Convert binary bitmap to JPEG image and return as response GCHandle pinnedOutputArray = GCHandle.Alloc(outputByteArray, GCHandleType.Pinned); IntPtr outputBmpPointer = pinnedOutputArray.AddrOfPinnedObject(); Bitmap outputBitmap = new Bitmap(imagewidth, imageHeight, bitmapData.Stride, PixelFormat.Format32bppArgb, outputBmpPointer); MemoryStream msOutput = new MemoryStream(); outputBitmap.Save(msOutput, System.Drawing.Imaging.ImageFormat.Jpeg); response.Body = msOutput.ToArray(); response.Type = "image/jpeg"; return(response); } } return(new HTTPResponse(501)); }
public void BlockMutation() { AssemblyName assemblyName = new AssemblyName("UniGPUTestFixture"); AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, assemblyName.Name + ".dll"); TypeBuilder typeBuilder = moduleBuilder.DefineType("CILBBTypeMutation", TypeAttributes.Public); MethodBuilder methodBuilder = typeBuilder.DefineMethod("TestCase", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new Type[] { typeof(int), typeof(int[]) }); methodBuilder.DefineParameter(1, ParameterAttributes.None, "arg"); methodBuilder.DefineParameter(2, ParameterAttributes.None, "addr"); ILGenerator il = methodBuilder.GetILGenerator(); LocalBuilder lb = il.DeclareLocal(typeof(float)); Label ZERO = il.DefineLabel(); Label LOOP = il.DefineLabel(); Label LOOP_FLT_MUTATOR = il.DefineLabel(); Label LOOP_INT_MUTATOR = il.DefineLabel(); il.Emit(OpCodes.Ldarg_1); il.Emit(OpCodes.Ldc_I4_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Brfalse, ZERO); il.MarkLabel(LOOP); il.Emit(OpCodes.Conv_I2); il.Emit(OpCodes.Starg, 0); il.Emit(OpCodes.Ldarga, 0); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldind_I4); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldc_I4_2); il.Emit(OpCodes.Rem); il.Emit(OpCodes.Not); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.And); il.Emit(OpCodes.Brtrue, LOOP_FLT_MUTATOR); il.MarkLabel(LOOP_INT_MUTATOR); il.Emit(OpCodes.Conv_I4); il.Emit(OpCodes.Starg, 0); il.Emit(OpCodes.Ldind_I4); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Add); il.Emit(OpCodes.Ldc_I4_2); il.Emit(OpCodes.Div); il.Emit(OpCodes.Ldc_I4_M1); il.Emit(OpCodes.Neg); il.Emit(OpCodes.Sub); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Bge, LOOP); il.Emit(OpCodes.Br, ZERO); il.MarkLabel(LOOP_FLT_MUTATOR); il.Emit(OpCodes.Conv_R4); il.Emit(OpCodes.Stloc_0); il.Emit(OpCodes.Pop); il.Emit(OpCodes.Ldloc_0); il.Emit(OpCodes.Ldc_R4, 1.0f); il.Emit(OpCodes.Sub); il.Emit(OpCodes.Dup); il.Emit(OpCodes.Ldc_R4, 1.0f); il.Emit(OpCodes.Bge, LOOP); il.Emit(OpCodes.Conv_I4); il.MarkLabel(ZERO); il.Emit(OpCodes.Ldc_I4_1); il.Emit(OpCodes.Add); il.Emit(OpCodes.Stelem_I4); il.Emit(OpCodes.Ret); MethodInfo method = typeBuilder.CreateType().GetMethod(methodBuilder.Name); int[] res = { 0 }; method.Invoke(null, new object[] { 8, res }); //Assert.AreEqual(1, res[0]); Cl.Program program = method.BuildIR().ToGPUClProgram(device, context); clSafeCall(Cl.BuildProgram(program, 1, new[] { device }, string.Empty, null, IntPtr.Zero)); Assert.AreEqual(Cl.BuildStatus.Success, Cl.GetProgramBuildInfo(program, device, Cl.ProgramBuildInfo.Status, out error). CastTo <Cl.BuildStatus>()); Cl.Kernel kernel = Cl.CreateKernel(program, "TestCase", out error); clSafeCall(error); Cl.Mem cl_res = Cl.CreateBuffer(context, Cl.MemFlags.WriteOnly, (IntPtr)sizeof(int), IntPtr.Zero, out error); clSafeCall(error); Cl.CommandQueue cmdQueue = Cl.CreateCommandQueue(context, device, (Cl.CommandQueueProperties) 0, out error); clSafeCall(error); clSafeCall(Cl.SetKernelArg(kernel, 0, 8)); clSafeCall(Cl.SetKernelArg(kernel, 1, cl_res)); clSafeCall(Cl.EnqueueNDRangeKernel(cmdQueue, kernel, 1, null, new[] { (IntPtr)1 }, null, 0, null, out clevent)); clSafeCall(Cl.EnqueueReadBuffer(cmdQueue, cl_res, Cl.Bool.True, IntPtr.Zero, (IntPtr)sizeof(int), res, 0, null, out clevent)); clSafeCall(Cl.Finish(cmdQueue)); clSafeCall(Cl.ReleaseMemObject(cl_res)); program.Dispose(); Assert.AreEqual(1, res[0]); }
static void Main(string[] args) { Console.WriteLine("Hello World!"); uint platformCount; ErrorCode result = Cl.GetPlatformIDs(0, null, out platformCount); Console.WriteLine("{0} platforms found", platformCount); var platformIds = new Platform[platformCount]; result = Cl.GetPlatformIDs(platformCount, platformIds, out platformCount); var platformCounter = 0; foreach (var platformId in platformIds) { IntPtr paramSize; result = Cl.GetPlatformInfo(platformId, PlatformInfo.Name, IntPtr.Zero, InfoBuffer.Empty, out paramSize); using (var buffer = new InfoBuffer(paramSize)) { result = Cl.GetPlatformInfo(platformIds[0], PlatformInfo.Name, paramSize, buffer, out paramSize); Console.WriteLine($"Platform {platformCounter}: {buffer}"); } platformCounter++; } Console.WriteLine($"Using first platform..."); uint deviceCount; result = Cl.GetDeviceIDs(platformIds[0], DeviceType.All, 0, null, out deviceCount); Console.WriteLine("{0} devices found", deviceCount); var deviceIds = new Device[deviceCount]; result = Cl.GetDeviceIDs(platformIds[0], DeviceType.All, deviceCount, deviceIds, out var numberDevices); var selectedDevice = deviceIds[0]; var context = Cl.CreateContext(null, 1, new[] { selectedDevice }, null, IntPtr.Zero, out var error); const string kernelSrc = @" // Simple test; c[i] = a[i] + b[i] __kernel void add_array(__global float *a, __global float *b, __global float *c) { int xid = get_global_id(0); c[xid] = a[xid] + b[xid] - 1500; } __kernel void sub_array(__global float *a, __global float *b, __global float *c) { int xid = get_global_id(0); c[xid] = a[xid] - b[xid] - 2000; } __kernel void double_everything(__global float *a) { int xid = get_global_id(0); a[xid] = a[xid] * 2; } "; var src = kernelSrc; Console.WriteLine("=== src ==="); Console.WriteLine(src); Console.WriteLine("============"); var program = Cl.CreateProgramWithSource(context, 1, new[] { src }, null, out var error2); error2 = Cl.BuildProgram(program, 1, new[] { selectedDevice }, string.Empty, null, IntPtr.Zero); if (error2 == ErrorCode.BuildProgramFailure) { Console.Error.WriteLine(Cl.GetProgramBuildInfo(program, selectedDevice, ProgramBuildInfo.Log, out error)); } Console.WriteLine(error2); // Get the kernels. var kernels = Cl.CreateKernelsInProgram(program, out error); Console.WriteLine($"Program contains {kernels.Length} kernels."); var kernelAdd = kernels[0]; var kernelDouble = kernels[2]; // float[] A = new float[1000]; float[] B = new float[1000]; float[] C = new float[1000]; for (var i = 0; i < 1000; i++) { A[i] = i; B[i] = i; } IMem <float> hDeviceMemA = Cl.CreateBuffer(context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, A, out error); IMem <float> hDeviceMemB = Cl.CreateBuffer(context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, B, out error); IMem <float> hDeviceMemC = Cl.CreateBuffer(context, MemFlags.CopyHostPtr | MemFlags.ReadOnly, C, out error); // Create a command queue. var cmdQueue = Cl.CreateCommandQueue(context, selectedDevice, CommandQueueProperties.None, out error); int intPtrSize = 0; intPtrSize = Marshal.SizeOf(typeof(IntPtr)); error = Cl.SetKernelArg(kernelDouble, 0, new IntPtr(intPtrSize), hDeviceMemA); error = Cl.SetKernelArg(kernelAdd, 0, new IntPtr(intPtrSize), hDeviceMemA); error = Cl.SetKernelArg(kernelAdd, 1, new IntPtr(intPtrSize), hDeviceMemB); error = Cl.SetKernelArg(kernelAdd, 2, new IntPtr(intPtrSize), hDeviceMemC); // write data from host to device Event clevent; error = Cl.EnqueueWriteBuffer(cmdQueue, hDeviceMemA, Bool.True, IntPtr.Zero, new IntPtr(1000 * sizeof(float)), A, 0, null, out clevent); error = Cl.EnqueueWriteBuffer(cmdQueue, hDeviceMemB, Bool.True, IntPtr.Zero, new IntPtr(1000 * sizeof(float)), B, 1, new [] { clevent }, out clevent); // execute kernel error = Cl.EnqueueNDRangeKernel(cmdQueue, kernelDouble, 1, null, new IntPtr[] { new IntPtr(1000) }, null, 1, new [] { clevent }, out clevent); var infoBuffer = Cl.GetEventInfo(clevent, EventInfo.CommandExecutionStatus, out var e2); error = Cl.EnqueueNDRangeKernel(cmdQueue, kernelAdd, 1, null, new IntPtr[] { new IntPtr(1000) }, null, 1, new [] { clevent }, out clevent); Console.WriteLine($"Run result: {error}"); error = Cl.EnqueueReadBuffer(cmdQueue, hDeviceMemC, Bool.False, 0, C.Length, C, 1, new [] { clevent }, out clevent); Cl.WaitForEvents(1, new [] { clevent }); for (var i = 0; i < 1000; i++) { Console.WriteLine($"[{i}]: {C[i]}"); } program.Dispose(); foreach (var res in typeof(SourceLoader).Assembly.GetManifestResourceNames()) { Console.WriteLine(res); } }
private void init(string oclProgramSourcePath) { string kernelSource = File.ReadAllText(oclProgramSourcePath); string[] kernelNames = new string[] { "accumulate", "quickBlurImgH", "quickBlurImgV", "upsizeImg", "halfSizeImgH", "halfSizeImgV", "getLumaImg", "mapToGreyscaleBmp", "getContrastImg", "capHolesImg", "maxReduceImgH", "maxReduceImgV", "mapToFauxColorsBmp", "quickSpikesFilterImg", "convolveImg" }; bool gpu = true; //err = clGetDeviceIDs(NULL, gpu ? CL_DEVICE_TYPE_GPU : CL_DEVICE_TYPE_CPU, 1, &device_id, NULL); // NVidia driver doesn't seem to support a NULL first param (properties) // http://stackoverflow.com/questions/19140989/how-to-remove-cl-invalid-platform-error-in-opencl-code // now get all the platform IDs Platform[] platforms = Cl.GetPlatformIDs(out err); assert(err, "Error: Failed to get platform ids!"); InfoBuffer deviceInfo = Cl.GetPlatformInfo(platforms[0], PlatformInfo.Name, out err); assert(err, "error retrieving platform name"); Console.WriteLine("Platform name: {0}\n", deviceInfo.ToString()); // Arbitrary, should be configurable Device[] devices = Cl.GetDeviceIDs(platforms[0], gpu ? DeviceType.Gpu : DeviceType.Cpu, out err); assert(err, "Error: Failed to create a device group!"); _device = devices[0]; // Arbitrary, should be configurable deviceInfo = Cl.GetDeviceInfo(_device, DeviceInfo.Name, out err); assert(err, "error retrieving device name"); Debug.WriteLine("Device name: {0}", deviceInfo.ToString()); deviceInfo = Cl.GetDeviceInfo(_device, DeviceInfo.ImageSupport, out err); assert(err, "error retrieving device image capability"); Debug.WriteLine("Device supports img: {0}", (deviceInfo.CastTo <Bool>() == Bool.True)); // Create a compute context // _context = Cl.CreateContext(null, 1, new[] { _device }, ContextNotify, IntPtr.Zero, out err); assert(err, "Error: Failed to create a compute context!"); // Create the compute program from the source buffer // _program = Cl.CreateProgramWithSource(_context, 1, new[] { kernelSource }, new[] { (IntPtr)kernelSource.Length }, out err); assert(err, "Error: Failed to create compute program!"); // Build the program executable // err = Cl.BuildProgram(_program, 1, new[] { _device }, string.Empty, null, IntPtr.Zero); assert(err, "Error: Failed to build program executable!"); InfoBuffer buffer = Cl.GetProgramBuildInfo(_program, _device, ProgramBuildInfo.Log, out err); Debug.WriteLine("build success: {0}", buffer.CastTo <BuildStatus>() == BuildStatus.Success); foreach (string kernelName in kernelNames) { // Create the compute kernel in the program we wish to run // OpenCL.Net.Kernel kernel = Cl.CreateKernel(_program, kernelName, out err); assert(err, "Error: Failed to create compute kernel!"); _kernels.Add(kernelName, kernel); } // Create a command queue // _commandsQueue = Cl.CreateCommandQueue(_context, _device, CommandQueueProperties.None, out err); assert(err, "Error: Failed to create a command commands!"); }