-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcljacobiiterator.cpp
More file actions
120 lines (95 loc) · 4.64 KB
/
cljacobiiterator.cpp
File metadata and controls
120 lines (95 loc) · 4.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#include "cljacobiiterator.h"
#define __CL_ENABLE_EXCEPTIONS
#include <CL/cl.hpp>
#include <iostream>
#include <fstream>
ClJacobiIterator::ClJacobiIterator()
{
std::vector<cl::Platform> platforms;
cl::Platform::get(&platforms);
for(const cl::Platform& platform : platforms)
{
std::cout << "Name: " << platform.getInfo<CL_PLATFORM_NAME>();
std::cout << " Vendor: " << platform.getInfo<CL_PLATFORM_VENDOR>();
std::cout << std::endl;
std::string platformName{platform.getInfo<CL_PLATFORM_NAME>()};
platformName.pop_back();
if(platformName == std::string("NVIDIA CUDA"))
//if(platformName == std::string("Intel(R) OpenCL"))
{
try
{
std::vector<cl::Device> devices;
platform.getDevices(CL_DEVICE_TYPE_GPU, &devices);
m_context.reset(new cl::Context(devices));
m_CommandQueue.reset(new cl::CommandQueue(*m_context, devices[0]));
std::cout << " Local memory size: " << devices[0].getInfo<CL_DEVICE_LOCAL_MEM_SIZE>() << std::endl;
std::ifstream sourceFile("JacobiKernel.cl");
std::string sourceCode(std::istreambuf_iterator<char>(sourceFile),(std::istreambuf_iterator<char>()));
cl::Program::Sources source(1, std::make_pair(sourceCode.c_str(), sourceCode.length()+1));
cl::Program program = cl::Program(*m_context, source);
program.build(devices);
m_kernel.reset(new cl::Kernel(program, "JacobiKernel"));
return;
}
catch(cl::Error error)
{
std::cout << error.what() << "(" << error.err() << ")" << std::endl;
}
}
}
}
ClJacobiIterator::~ClJacobiIterator()
{
}
void ClJacobiIterator::operator()(GridValues& uValues, const GridValues& fValues, size_t iterations) const
{
try
{
const int GRID_STRIDE = fValues.size();
const int THREADS_STRIDE = GRID_STRIDE - 2;
cl::Buffer clUValues1 = cl::Buffer(*m_context, CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR,
(GRID_STRIDE) * (GRID_STRIDE) * sizeof(double),
&(uValues.value(0,0)));
cl::Buffer clUValues2 = cl::Buffer(*m_context, CL_MEM_READ_WRITE|CL_MEM_COPY_HOST_PTR,
(GRID_STRIDE) * (GRID_STRIDE) * sizeof(double),
&(uValues.value(0,0)));
cl::Buffer clStaticUValues = cl::Buffer(*m_context, CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR,
(GRID_STRIDE) * (GRID_STRIDE) * sizeof(double),
&(uValues.value(0,0)));
cl::Buffer* currentInputBufferPointer = &clUValues1;
cl::Buffer* currentOutputBufferPointer = &clUValues2;
double* fValuesPointer = const_cast<double*>(&(fValues.values()[0]));
cl::Buffer clFValues = cl::Buffer(*m_context, CL_MEM_READ_ONLY|CL_MEM_COPY_HOST_PTR,
((GRID_STRIDE) * (GRID_STRIDE)) * sizeof(double),
fValuesPointer);
const double h2 = pow(uValues.realStep(), 2);
for(size_t iteration = 0; iteration < iterations; ++iteration)
{
//const size_t TREADS_COUNT = THREADS_STRIDE + 1 <= 1024 ? THREADS_STRIDE + 1 : 1024u;
const size_t TREADS_COUNT = 512;
int iArg = 0;
m_kernel->setArg(iArg++, *currentInputBufferPointer);
m_kernel->setArg(iArg++, clFValues);
m_kernel->setArg(iArg++, *currentOutputBufferPointer);
m_kernel->setArg(iArg++, clStaticUValues);
m_kernel->setArg(iArg++, TREADS_COUNT * sizeof(double), NULL);
m_kernel->setArg(iArg++, h2);
m_kernel->setArg(iArg++, GRID_STRIDE);
//CL_INVALID_WORK_DIMENSION
m_CommandQueue->enqueueNDRangeKernel(*m_kernel, cl::NullRange, cl::NDRange(16, 32), cl::NDRange(16, 32));
//m_CommandQueue->
//m_CommandQueue->finish();
std::swap(currentInputBufferPointer, currentOutputBufferPointer);
}
m_CommandQueue->finish();
//В конце цикла swap!
m_CommandQueue->enqueueReadBuffer(*currentInputBufferPointer, CL_TRUE, 0,
((GRID_STRIDE) * (GRID_STRIDE)) * sizeof(double),
&(uValues.value(0,0)));
}
catch(cl::Error error)
{
std::cout << error.what() << "(" << error.err() << ")" << std::endl;
}
}