У меня есть следующее очень простое ядро в OpenCL
void kernel simple_add(global const int* A, global const int* B, global int* C){
C[get_global_id(0)]=A[get_global_id(0)]+B[get_global_id(0)];
};
Я создал программу на C ++ для загрузки ядра из двоичного файла, созданного из его источника.Двоичный файл загружается правильно (CL_SUCCESS), но не отображает правильный результат для ввода.Он отображает изменяющиеся значения мусора следующим образом:
result:
538976310 538976288 538976288 538976288 538976288 790634528 796160111 1702129257 1886334828 1818455653
inline cl::Program CreateProgramFromBinary(cl::Context context,const std::vector<cl::Device> devices, const char* fileName)
{
std::ifstream file(fileName, std::ios::binary | std::ios::in | std::ios::ate);
uint32_t size = file.tellg();
file.seekg(0, std::ios::beg);
char* buffer = new char[size];
file.read(buffer, size);
file.close();
cl::Program::Binaries bin{{buffer, size}};
std::vector<cl_int> binaryStatus;
cl_int err = 0;
cl::Program program = cl::Program{context, devices, bin, &binaryStatus, &err};
if(err != CL_SUCCESS) {
std::cout<<" Error loading"<< err<< "\n";
exit(1);
}
for (std::vector<cl_int>::const_iterator bE = binaryStatus.begin(); bE != binaryStatus.end(); bE++) {
std::cout<< *bE <<std::endl;
}
std::cout<<"No Error loading"<< err<< "\n";
delete[] buffer;
return program;
}
int main(int argc, char** argv)
{
std::vector<cl::Device> devices= loadDevices();
cl::Context context{devices};
std::cout << "Save program binary for future run..." << std::endl;
//cl::Program program = CreateBinaryFromProgram(context, devices, "HelloWorld.cl", "HelloWorld.cl.bin");
//CreateBinaryFromProgram(context, devices, "HelloWorld.cl", "HelloWorld.cl.bin");
std::cout << "Reading from binary..." << std::endl;
cl::Program program = CreateProgramFromBinary(context, devices, "HelloWorld.cl.bin");
std::cout << "Running Program..." << std::endl;
cl::Buffer buffer_A(context,CL_MEM_READ_WRITE,sizeof(int)*10);
cl::Buffer buffer_B(context,CL_MEM_READ_WRITE,sizeof(int)*10);
cl::Buffer buffer_C(context,CL_MEM_READ_WRITE,sizeof(int)*10);
int A[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
int B[] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
//create queue to which we will push commands for the device.
cl::CommandQueue queue(context,devices[0]);
//write arrays A and B to the device
queue.enqueueWriteBuffer(buffer_A,CL_TRUE,0,sizeof(int)*10,A);
queue.enqueueWriteBuffer(buffer_B,CL_TRUE,0,sizeof(int)*10,B);
//run the kernel
cl::Kernel kernel_add=cl::Kernel(program,"simple_add");
kernel_add.setArg(0,buffer_A);
kernel_add.setArg(1,buffer_B);
kernel_add.setArg(2,buffer_C);
queue.enqueueNDRangeKernel(kernel_add,cl::NullRange,cl::NDRange(10),cl::NullRange);
queue.finish();
int C[10];
//read result C from the device to array C
queue.enqueueReadBuffer(buffer_C,CL_TRUE,0,sizeof(int)*10,C);
std::cout<<" result: \n";
for(int i=0;i<10;i++)
std::cout<<C[i]<<" ";
std::cout << "\n";
return 0;
}
Загрузка этой программы непосредственно из файла CL, однако, приводит к правильному выводу программы.Отличается ли загруженный бинарный файл от файла CL?
РЕДАКТИРОВАТЬ:
Как я создал двоичный файл
inline cl::Program CreateBinaryFromProgram(const cl::Context context,const std::vector<cl::Device> devices, const char* readFileName, const char* writeFileName)
{
std::ifstream file(readFileName, std::ios::binary| std::ios::ate | std::ios::in);
uint32_t size = file.tellg();
file.seekg(0, std::ios::beg);
char* buffer = new char[size];
file.read(buffer, size);
file.close();
cl::Program::Sources sources;
// kernel calculates for each element C=A+B
std::string kernel_code(buffer);
sources.push_back({kernel_code.c_str(),kernel_code.length()});
cl::Program program{context,sources};
if(program.build(devices)!=CL_SUCCESS){
std::cout<<" Error building: "<<program.getBuildInfo<CL_PROGRAM_BUILD_LOG>(devices[0])<<"\n";
exit(1);
}
std::vector<size_t> output_sizes = program.getInfo<CL_PROGRAM_BINARY_SIZES>();
std::vector<char*> output = program.getInfo<CL_PROGRAM_BINARIES>();
std::cout << sizeof(output[0]) << std::endl;
std::cout << output_sizes[0] << std::endl;
const std::vector<unsigned long> binSizes = program.getInfo<CL_PROGRAM_BINARY_SIZES>();
std::vector<char> binData (std::accumulate(binSizes.begin(),binSizes.end(),0));
char* binChunk = &binData[0] ;
//A list of pointers to the binary data
std::vector<char*> binaries;
for(unsigned int i = 0; i<binSizes.size(); ++i) {
binaries.push_back(binChunk) ;
binChunk += binSizes[i] ;
}
program.getInfo(CL_PROGRAM_BINARIES , &binaries[0] ) ;
std::ofstream binaryfile(writeFileName, std::ios::binary);
for (unsigned int i = 0; i < binaries.size(); ++i)
binaryfile.write(binaries[i], binSizes[i]);
delete[] buffer;
return program;
}