Mali OpenCL SDK v1.1.0
 All Classes Files Functions Variables Macros Pages
fir_float.cpp
Go to the documentation of this file.
1 /*
2  * This confidential and proprietary software may be used only as
3  * authorised by a licensing agreement from ARM Limited
4  * (C) COPYRIGHT 2013 ARM Limited
5  * ALL RIGHTS RESERVED
6  * The entire notice above must be reproduced on all authorised
7  * copies and copies may only be made to the extent permitted
8  * by a licensing agreement from ARM Limited.
9  */
10 
11 #include "common.h"
12 #include "image.h"
13 
14 #include <CL/cl.h>
15 #include <iostream>
16 #include <fstream>
17 #include <sstream>
18 #include <cstddef>
19 #include <cmath>
20 
21 using namespace std;
22 
30 int main(void)
31 {
32  /* Name of the bitmap to load and run the FIR filter on. */
33  string filename = "assets/input.bmp";
34 
35  cl_context context = 0;
36  cl_command_queue commandQueue = 0;
37  cl_program program = 0;
38  cl_device_id device = 0;
39  cl_kernel kernel = 0;
40  const unsigned int numberOfMemoryObjects = 2;
41  cl_mem memoryObjects[numberOfMemoryObjects] = {0, 0};
42  cl_int errorNumber;
43 
44  if (!createContext(&context))
45  {
46  cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numberOfMemoryObjects);
47  cerr << "Failed to create an OpenCL context. " << __FILE__ << ":"<< __LINE__ << endl;
48  return 1;
49  }
50 
51  if (!createCommandQueue(context, &commandQueue, &device))
52  {
53  cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numberOfMemoryObjects);
54  cerr << "Failed to create the OpenCL command queue. " << __FILE__ << ":"<< __LINE__ << endl;
55  return 1;
56  }
57 
58  if (!createProgram(context, device, "assets/fir_float.cl", &program))
59  {
60  cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numberOfMemoryObjects);
61  cerr << "Failed to create OpenCL program." << __FILE__ << ":"<< __LINE__ << endl;
62  return 1;
63  }
64 
65  kernel = clCreateKernel(program, "fir_float", &errorNumber);
66  if (!checkSuccess(errorNumber))
67  {
68  cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numberOfMemoryObjects);
69  cerr << "Failed to create OpenCL kernel. " << __FILE__ << ":"<< __LINE__ << endl;
70  return 1;
71  }
72 
73  /* Load 24-bits per pixel RGB data from a bitmap. */
74  cl_int width;
75  cl_int height;
76  unsigned char* loadedRGBData = NULL;
77  if (!loadFromBitmap(filename, &width, &height, &loadedRGBData))
78  {
79  cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numberOfMemoryObjects);
80  cerr << "Failed loading bitmap. " << __FILE__ << ":"<< __LINE__ << endl;
81  return 1;
82  }
83 
84  /* Convert 24-bits per pixel RGB into 8-bits per pixel luminance data. */
85  unsigned char* inputLuminance = new unsigned char [width * height];
86  RGBToLuminance(loadedRGBData, inputLuminance, width, height);
87  delete [] loadedRGBData;
88 
89  /* All buffers are the size of the image data. */
90  size_t bufferSize = width * height * sizeof(float);
91 
92  /* Create one input buffer for the original image data, and one output buffer for the output image data. */
93  bool createMemoryObjectsSuccess = true;
94  memoryObjects[0] = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_ALLOC_HOST_PTR, bufferSize, NULL, &errorNumber);
95  createMemoryObjectsSuccess &= checkSuccess(errorNumber);
96  memoryObjects[1] = clCreateBuffer(context, CL_MEM_WRITE_ONLY | CL_MEM_ALLOC_HOST_PTR, bufferSize, NULL, &errorNumber);
97  createMemoryObjectsSuccess &= checkSuccess(errorNumber);
98  if (!createMemoryObjectsSuccess)
99  {
100  cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numberOfMemoryObjects);
101  cerr << "Failed to create OpenCL buffers. " << __FILE__ << ":"<< __LINE__ << endl;
102  return 1;
103  }
104 
105  /* Map the input memory object to a host side pointer. */
106  cl_float* inputImageData = (cl_float*)clEnqueueMapBuffer(commandQueue, memoryObjects[0], CL_TRUE, CL_MAP_WRITE, 0, bufferSize, 0, NULL, NULL, &errorNumber);
107  if (!checkSuccess(errorNumber))
108  {
109  cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numberOfMemoryObjects);
110  cerr << "Mapping memory objects failed " << __FILE__ << ":"<< __LINE__ << endl;
111  return 1;
112  }
113 
114  /* Converting luminance data into float. A real world application would use real floating point data.*/
115  for(int i = 0; i < width * height; i++)
116  {
117  inputImageData[i] = (float)inputLuminance[i] / 255.0f;
118  }
119 
120  delete [] inputLuminance;
121 
122  /* Unmap the memory so we can pass it to the kernel. */
123  if (!checkSuccess(clEnqueueUnmapMemObject(commandQueue, memoryObjects[0], inputImageData, 0, NULL, NULL)))
124  {
125  cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numberOfMemoryObjects);
126  cerr << "Unmapping memory objects failed " << __FILE__ << ":"<< __LINE__ << endl;
127  return 1;
128  }
129 
130  /* Setup the kernel arguments. */
131  bool setKernelArgumentsSuccess = true;
132  setKernelArgumentsSuccess &= checkSuccess(clSetKernelArg(kernel, 0, sizeof(cl_mem), &memoryObjects[0]));
133  setKernelArgumentsSuccess &= checkSuccess(clSetKernelArg(kernel, 1, sizeof(cl_mem), &memoryObjects[1]));
134  setKernelArgumentsSuccess &= checkSuccess(clSetKernelArg(kernel, 2, sizeof(cl_int), &width));
135  if (!setKernelArgumentsSuccess)
136  {
137  cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numberOfMemoryObjects);
138  cerr << "Failed setting OpenCL kernel arguments. " << __FILE__ << ":"<< __LINE__ << endl;
139  return 1;
140  }
141 
142  /* An event to associate with the kernel. Allows us to retrieve profiling information later. */
143  cl_event event = 0;
144 
145  /* [Kernel size] */
146  /*
147  * Each instance of the kernel operates on a 4 * 1 portion of the image.
148  * Therefore, the global work size must be width / 4 by height / 1 work items.
149  */
150  size_t globalWorksize[2] = {width / 4, height / 1};
151  /* [Kernel size] */
152 
153  /* Enqueue the kernel */
154  if (!checkSuccess(clEnqueueNDRangeKernel(commandQueue, kernel, 2, NULL, globalWorksize, NULL, 0, NULL, &event)))
155  {
156  cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numberOfMemoryObjects);
157  cerr << "Failed enqueuing the kernel. " << __FILE__ << ":"<< __LINE__ << endl;
158  return 1;
159  }
160 
161  /* Wait for kernel execution completion. */
162  if (!checkSuccess(clFinish(commandQueue)))
163  {
164  cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numberOfMemoryObjects);
165  cerr << "Failed waiting for kernel execution to finish. " << __FILE__ << ":"<< __LINE__ << endl;
166  return 1;
167  }
168 
169  /* Print the profiling information for the event. */
170  printProfilingInfo(event);
171  /* Release the event object. */
172  if (!checkSuccess(clReleaseEvent(event)))
173  {
174  cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numberOfMemoryObjects);
175  cerr << "Failed releasing the event object. " << __FILE__ << ":"<< __LINE__ << endl;
176  return 1;
177  }
178 
179  /* Map the output memory to a host side pointer. */
180  cl_float* output = (cl_float*)clEnqueueMapBuffer(commandQueue, memoryObjects[1], CL_TRUE, CL_MAP_READ, 0, bufferSize, 0, NULL, NULL, &errorNumber);
181  if (!checkSuccess(errorNumber))
182  {
183  cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numberOfMemoryObjects);
184  cerr << "Mapping memory objects failed " << __FILE__ << ":"<< __LINE__ << endl;
185  return 1;
186  }
187 
188  /* Convert the float output to unsigned char for saving to bitmap. */
189  unsigned char *outputData= new unsigned char[width * height];
190  for(int i = 0; i< width * height; i++)
191  {
192  outputData[i] = (unsigned char)(output[i] * 255.0f);
193  }
194 
195  /* Unmap the output. */
196  if (!checkSuccess(clEnqueueUnmapMemObject(commandQueue, memoryObjects[1], output, 0, NULL, NULL)))
197  {
198  cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numberOfMemoryObjects);
199  cerr << "Unmapping memory objects failed " << __FILE__ << ":"<< __LINE__ << endl;
200  return 1;
201  }
202 
203  /* Release OpenCL objects. */
204  cleanUpOpenCL(context, commandQueue, program, kernel, memoryObjects, numberOfMemoryObjects);
205 
206  /* Convert the output luminance array to RGB and save it out to a file. */
207  unsigned char *rgbOut = new unsigned char[width * height * 3];
208  luminanceToRGB(outputData, rgbOut, width, height);
209  delete [] outputData;
210 
211  saveToBitmap("output.bmp", width, height, rgbOut);
212  delete [] rgbOut;
213 
214  return 0;
215 }