Basic Image AlgorithmS Library  2.8.0
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
exampleOpenCLVectorAdd.cpp
1 /*
2 This file is part of the BIAS library (Basic ImageAlgorithmS).
3 
4 Copyright (C) 2003, 2004 (see file CONTACTS for details)
5  Multimediale Systeme der Informationsverarbeitung
6  Institut fuer Informatik
7  Christian-Albrechts-Universitaet Kiel
8 
9 
10 BIAS is free software; you can redistribute it and/or modify
11 it under the terms of the GNU Lesser General Public License as published by
12 the Free Software Foundation; either version 2.1 of the License, or
13 (at your option) any later version.
14 
15 BIAS is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU Lesser General Public License for more details.
19 
20 You should have received a copy of the GNU Lesser General Public License
21 along with BIAS; if not, write to the Free Software
22 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 */
24 
25 #include <OpenCLFramework/clfContext.hh>
26 #include <iostream>
27 
28 using namespace BIAS;
29 using namespace std;
30 
31 /**
32  * @brief the simple example from all the internet tutorials for using opencl
33  *
34  * in this example, we create two vectors with 1000 elements each. we then
35  * add them together with opencl and store the result in a third vector
36  * (C = A+b)
37  *
38  * @author fkellner 06/11
39  */
40 int main() {
41  // initialize vectors A and B (such that the sum of each element is 1000
42  const int LIST_SIZE = 1000;
43  int *A = new int[LIST_SIZE];
44  int *B = new int[LIST_SIZE];
45  for(int i = 0; i < LIST_SIZE; i++) {
46  A[i] = i;
47  B[i] = LIST_SIZE - i;
48  }
49  // create vector to store result
50  int *C = new int[LIST_SIZE];
51 
52  // try/catch of OpenCLException is strongly recommended!
53  try {
54  // create context on first GPU found
55  clfContext context;
56  // print some info
57  context.PrintPlatformsInfo();
58  context.PrintDeviceInfo();
59 
60  // create a program in this context
61  clfProgram *program = context.CreateProgram();
62 
63  // this is the source code for our compute kernel
64  string source = ""
65  "__kernel void vector_add(__global const int *A, __global const int *B, __global int *C) {\n"
66  " // element index\n"
67  " size_t v = get_global_id(0);\n"
68  " C[v] = A[v]+B[v];\n"
69  "}\n";
70 
71  // add code to our program
72  program->AddSourceFromString(source);
73  // compile program
74  program->Build();
75  // we want to use the vector_add kernel
76  program->AddKernel("vector_add");
77 
78  // allocate opencl buffers in the context
79  clfBuffer *bufferA = context.CreateBuffer();
80  bufferA->Allocate(LIST_SIZE * sizeof(int), true, false);
81  clfBuffer *bufferB = context.CreateBuffer();
82  bufferB->Allocate(LIST_SIZE * sizeof(int), true, false);
83  clfBuffer *bufferC = context.CreateBuffer();
84  bufferC->Allocate(LIST_SIZE * sizeof(int), false, true);
85  // now write our local memory to the buffers
86  // note that the Allocate functions allow different means of doing this
87  bufferA->WriteToBuffer(A);
88  bufferB->WriteToBuffer(B);
89 
90  // set the arguments of compute kernel vector_add.
91  program->KernelSetArgument( "vector_add", 0, *bufferA );
92  program->KernelSetArgument( "vector_add", 1, *bufferB );
93  program->KernelSetArgument( "vector_add", 2, *bufferC );
94 
95  // run the vector_add kernel on 1000 elements. each thread will handle one element
96  // which is not very efficient!
97  context.RunOn1DRange( *program, "vector_add", LIST_SIZE);
98 
99  // read the result back to host memory
100  bufferC->ReadFromBuffer(C);
101 
102  // check if each element of C is now 1000
103  bool success = true;
104  for(int i = 0; i < LIST_SIZE; i ++) {
105  if (C[i] != 1000) {
106  success = false;
107  }
108  }
109  if (success) {
110  cout << "computation successful." << endl;
111  } else {
112  cout << "error in computation!" << endl;
113  }
114 
115  } catch (clfException &err) {
116  // the detailed error string
117  cout << err.GetDetailedString() << endl;
118  }
119 
120  return 0;
121 }
void PrintPlatformsInfo(std::ostream &out=std::cout)
print info on available platforms
Definition: clfContext.cpp:204
clfBuffer * CreateBuffer()
create buffer object
Definition: clfContext.hh:79
OpenCL Program wrapper.
Definition: clfProgram.hh:53
void PrintDeviceInfo(unsigned int device=0, bool verbose=false, std::ostream &out=std::cout)
print info on computing device
Definition: clfContext.cpp:127
OpenCL Buffer wrapper.
Definition: clfBuffer.hh:43
void Build(int deviceNr=0, std::string options="")
builds the sources added by AddSource and AddSourceFromString
Definition: clfProgram.cpp:115
const std::string & GetDetailedString() const
detailed combination of all info available
clfProgram * CreateProgram()
create program object
Definition: clfContext.hh:71
void AddSourceFromString(std::string sourceCode)
adds source code from a string
Definition: clfProgram.cpp:100
OpenCL Context wrapper.
Definition: clfContext.hh:49
void ReadFromBuffer(void *data, unsigned int offset=0, unsigned int size=0)
read from buffer object to host memory
Definition: clfBuffer.cpp:128
clf Exception wrapper, is thrown in case of most clf errors
Definition: clfException.hh:48
void Allocate(unsigned int bufsize, bool readonly=false, bool writeonly=false, void *hostptr=NULL, bool copy=false)
Allocation of a memory buffer A memory buffer can be created on device or host, it can be initialized...
Definition: clfBuffer.cpp:45
void KernelSetArgument(std::string kernelname, unsigned int argnumber, clfBuffer &buffer)
set kernel argument
Definition: clfProgram.cpp:177
void AddKernel(std::string kernelname)
adds a kernel to the program.
Definition: clfProgram.cpp:158
void WriteToBuffer(const void *data, unsigned int offset=0, unsigned int size=0)
write from host memory to buffer object
Definition: clfBuffer.cpp:117
void RunOn1DRange(clfProgram &program, std::string kernelname, unsigned int globalrange, unsigned int localrange=0)
run a kernel on a 1D memory range
Definition: clfContext.cpp:220