I am quite new to object oriented programming. I'm trying to modularize a code in a class format in order to make things easy to understand and make the code extendable.
I am stuck with this error:
Description Resource Path Location Type
make: *** [src/interface.o] Error 1 Emulation-SW /virtualization_proj C/C Problem
make: *** Waiting for unfinished jobs.... Emulation-SW /virtualization_proj C/C Problem
no matching function for call to ‘std::vector<std::vector<unsigned char, std::allocator<unsigned char> >, std::allocator<std::vector<unsigned char, std::allocator<unsigned char> > > >::push_back(<brace-enclosed initializer list>)’ interface.h /virtualization_proj/src line 58 C/C Problem
recipe for target 'src/interface.o' failed makefile /virtualization_proj/Emulation-SW line 57 C/C Problem
The error looks in the IDE as below:
Can someone help in resolving this error?
class INTERFACE{
public:
std::vector<cl::Device> devices;
cl::Device device;
std::vector<cl::Platform> platforms;
cl::Context context;
cl::CommandQueue q;
cl::Program::Binaries bins;
char *buf;
unsigned nb;
cl::Program program;
int push_xclbinFile_to_FPGA(){
bins.push_back({buf,nb}); // Push_back function is not getting recognized
devices.resize(1);
program= cl::Program(context, devices, bins);
return 1;
}
};
Edit
To make the question more clear, these lines work completely fine when I execute them from the main()
function as below. I hope this will clarify the question a little more.
Edit
The main
file code is as below:
int main(int argc, char* argv[]) {
// Compute the size of array in bytes
INTERFACE i_obj;
size_t size_in_bytes= i_obj.compute_size_in_bytes();
// Finding the device
int device_found= i_obj.finding_platform();
if(device_found==0){
std::cout<< "Device found successfully" << std::endl;
}
// Creating Context and Command Queue for selected device
cl::Context context(i_obj.devices);
cl::CommandQueue q(context, i_obj.device, CL_QUEUE_PROFILING_ENABLE);
i_obj.context= context;
i_obj.q= q;
VMGR *vm=new VMGR();
vm->initialize_mq(); // Creating the Queue1
while(1){
std::vector<std::string> numbers = vm->run();
int st=i_obj.buffer_values();
//setting input data
if (numbers.size()!=0){
if(numbers[2]=="SUB"){
//
// Read the xclbin file
int status_xclbin_read= i_obj.reading_the_xclbinFile(vm);
// Process the read Data
i_obj.bins.push_back({i_obj.buf,i_obj.nb});
(i_obj.devices).resize(1);
// Push the xclbin file into the FPGA
cl::Program program(i_obj.context, i_obj.devices, i_obj.bins);
// This call will get the kernel object from program. A kernel is an
// OpenCL function that is executed on the FPGA.
i_obj.krnl_vector_sub= cl::Kernel(program,"krnl_vsub");
int narg=0;
// set the kernel Arguments
i_obj.krnl_vector_sub.setArg(narg ,i_obj.buffer_a);
i_obj.krnl_vector_sub.setArg(narg ,i_obj.buffer_b);
i_obj.krnl_vector_sub.setArg(narg ,i_obj.buffer_result);
i_obj.krnl_vector_sub.setArg(narg ,api::DATA_SIZE);
//We then need to map our OpenCL buffers to get the pointers
i_obj.ptr_a = (int *) (i_obj.q).enqueueMapBuffer (i_obj.buffer_a , CL_TRUE , CL_MAP_WRITE , 0, size_in_bytes);
i_obj.ptr_b = (int *) (i_obj.q).enqueueMapBuffer (i_obj.buffer_b , CL_TRUE , CL_MAP_WRITE , 0, size_in_bytes);
i_obj.ptr_result = (int *) (i_obj.q).enqueueMapBuffer (i_obj.buffer_result , CL_TRUE , CL_MAP_READ , 0, size_in_bytes);
i_obj.bins.clear();
}
(i_obj.q).finish();
}
return 0;
}
CodePudding user response:
bins.push_back({buf,nb})
makes no sense. Because of that the compiler can't figure out what type {buf,nb}
is supposed to be.
Based on your error message, bins
is a std::vector<std::vector<unsigned char>>
, which means bins.push_back
needs you to pass it a std::vector<unsigned char>
. {buf,nb}
can't be converted to a std::vector<unsigned char>
though, since neither buf
, nor nb
are unsigned char
s (one is a char*
and the other an unsigned int
).
Note that the documentation for the relevant cl::Program
constructor appears to be incorrect. It is documented to accept a vector of (bin, size)
pairs, but it does not. It just accepts a vector of vectors containing binary data. std::vector
knows its own size, so that doesn't need to be passed separately. Looking at the code it appears that documentation was once correct, but the interface has changed based on the preprocessor conditionals in that constructor.