added example 02
This commit is contained in:
@@ -15,7 +15,10 @@ curl https://www.khronos.org/registry/cl/api/1.2/cl.hpp -o CL/cl.hpp
|
|||||||
this example is based off of [this example](simpleopencl.blogspot.ca/2013/06/tutorial-simple-start-with-opencl-and-c.html) (example-ception), but it goes a bit further. In the blogspot example, two 10-element vectors are created and a thread is used for each pair of elements. In this example, 10 threads are spawned but two 100-element vectors are used, and it is shown how to split up a specific number of elements per thread.
|
this example is based off of [this example](simpleopencl.blogspot.ca/2013/06/tutorial-simple-start-with-opencl-and-c.html) (example-ception), but it goes a bit further. In the blogspot example, two 10-element vectors are created and a thread is used for each pair of elements. In this example, 10 threads are spawned but two 100-element vectors are used, and it is shown how to split up a specific number of elements per thread.
|
||||||
|
|
||||||
## example 01
|
## example 01
|
||||||
See the README in the folder.
|
Measures the duration of adding two vectors. See the README in the folder for more details.
|
||||||
|
|
||||||
|
## example 02
|
||||||
|
Demonstrates that one array can be modified several times without having to re-read and re-write data to and from the GPU.
|
||||||
|
|
||||||
## TODO
|
## TODO
|
||||||
|
|
||||||
|
|||||||
96
example02/main.cpp
Normal file
96
example02/main.cpp
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <iterator>
|
||||||
|
#include "../CL/cl.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
using namespace cl;
|
||||||
|
|
||||||
|
|
||||||
|
int factorial(int n) {
|
||||||
|
return (n <= 1) ? 1 : n * factorial(n-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Platform getPlatform() {
|
||||||
|
/* Returns the first platform found. */
|
||||||
|
std::vector<Platform> all_platforms;
|
||||||
|
Platform::get(&all_platforms);
|
||||||
|
|
||||||
|
if (all_platforms.size()==0) {
|
||||||
|
cout << "No platforms found. Check OpenCL installation!\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
return all_platforms[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Device getDevice(cl::Platform platform, int i, bool display=false) {
|
||||||
|
/* Returns the deviced specified by the index i on platform.
|
||||||
|
* If display is true, then all of the platforms are listed.
|
||||||
|
*/
|
||||||
|
std::vector<Device> all_devices;
|
||||||
|
platform.getDevices(CL_DEVICE_TYPE_ALL, &all_devices);
|
||||||
|
if(all_devices.size()==0){
|
||||||
|
cout << "No devices found. Check OpenCL installation!\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (display) {
|
||||||
|
for (int j=0; j<all_devices.size(); j++)
|
||||||
|
printf("Device %d: %s\n", j, all_devices[j].getInfo<CL_DEVICE_NAME>().c_str());
|
||||||
|
}
|
||||||
|
return all_devices[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
const int n = 1024; // size of vectors
|
||||||
|
const int c_max = 5; // max value to iterate to
|
||||||
|
const int coeff = factorial(c_max);
|
||||||
|
|
||||||
|
int A[n], B[n], C[n]; // A is initial, B is result, C is expected result
|
||||||
|
for (int i=0; i<n; i++) {
|
||||||
|
A[i] = i;
|
||||||
|
C[i] = coeff * i;
|
||||||
|
}
|
||||||
|
Platform default_platform = getPlatform();
|
||||||
|
Device default_device = getDevice(default_platform, 1);
|
||||||
|
Context context({default_device});
|
||||||
|
Program::Sources sources;
|
||||||
|
|
||||||
|
// calculates for each element; C = A + B
|
||||||
|
std::string kernel_code=
|
||||||
|
"void kernel multiply_by(global int* A, const int c) {"
|
||||||
|
" A[get_global_id(0)] = c * A[get_global_id(0)];"
|
||||||
|
"}";
|
||||||
|
sources.push_back({kernel_code.c_str(), kernel_code.length()});
|
||||||
|
|
||||||
|
Program program(context, sources);
|
||||||
|
if (program.build({default_device}) != CL_SUCCESS) {
|
||||||
|
cout << "Error building: " << program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(default_device) << std::endl;
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
Buffer buffer_A(context, CL_MEM_READ_WRITE, sizeof(int) * n);
|
||||||
|
CommandQueue queue(context, default_device);
|
||||||
|
queue.enqueueWriteBuffer(buffer_A, CL_TRUE, 0, sizeof(int)*n, A);
|
||||||
|
|
||||||
|
Kernel multiply_by = cl::Kernel(program, "multiply_by");
|
||||||
|
multiply_by.setArg(0, buffer_A);
|
||||||
|
|
||||||
|
for (int c=2; c<=c_max; c++) {
|
||||||
|
multiply_by.setArg(1, c);
|
||||||
|
queue.enqueueNDRangeKernel(multiply_by, cl::NullRange, cl::NDRange(n), cl::NDRange(32));
|
||||||
|
}
|
||||||
|
|
||||||
|
queue.enqueueReadBuffer(buffer_A, CL_TRUE, 0, sizeof(int)*n, B);
|
||||||
|
|
||||||
|
if (std::equal(std::begin(B), std::end(B), std::begin(C)))
|
||||||
|
cout << "Arrays are equal!" << endl;
|
||||||
|
else
|
||||||
|
cout << "Uh-oh, the arrays aren't equal!" << endl;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user