1 #ifndef VIENNACL_OCL_CONTEXT_HPP_
2 #define VIENNACL_OCL_CONTEXT_HPP_
25 #include <OpenCL/cl.h>
46 typedef std::vector< viennacl::ocl::program > ProgramContainer;
50 device_type_(CL_DEVICE_TYPE_DEFAULT),
52 default_device_num_(1) {}
71 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
72 std::cout <<
"ViennaCL: Setting new device type for context " << h_ << std::endl;
80 std::vector<viennacl::ocl::device>
const &
devices()
const
89 return devices_[current_device_id];
95 assert(i >= 0 && i < devices_.size());
96 current_device_id = i;
102 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
103 std::cout <<
"ViennaCL: Setting new current device for context " << h_ << std::endl;
106 for (
size_t i=0; i<devices_.size(); ++i)
108 if (devices_[i] == d)
111 current_device_id = i;
116 std::cerr <<
"ViennaCL: Warning: Could not set device " << d.
name() <<
" for context." << std::endl;
122 assert(!initialized_ &&
"Device must be added to context before it is initialized!");
123 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
124 std::cout <<
"ViennaCL: Adding new device to context " << h_ << std::endl;
126 if (std::find(devices_.begin(), devices_.end(), d) == devices_.end())
127 devices_.push_back(d);
133 assert(!initialized_ &&
"Device must be added to context before it is initialized!");
170 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
171 std::cout <<
"ViennaCL: Creating memory of size " << size <<
" for context " << h_ << std::endl;
174 flags |= CL_MEM_COPY_HOST_PTR;
186 template <
typename SCALARTYPE,
typename A,
template <
typename,
typename>
class VectorType >
189 return create_memory(flags, static_cast<cl_uint>(
sizeof(SCALARTYPE) * _buffer.size()), (
void*)&_buffer[0]);
197 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
198 std::cout <<
"ViennaCL: Adding existing queue " << q <<
" for device " << dev <<
" to context " << h_ << std::endl;
206 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
207 std::cout <<
"ViennaCL: Adding new queue for device " << dev <<
" to context " << h_ << std::endl;
222 return queues_[devices_[current_device_id].id()][0];
229 assert(i >= 0 && i < queues_.size() &&
"In class 'context': id invalid in get_queue()");
230 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
231 std::cout <<
"ViennaCL: Getting queue " << i <<
" for device " << dev <<
" in context " << h_ << std::endl;
233 unsigned int device_index;
234 for (device_index = 0; device_index < devices_.size(); ++device_index)
236 if (devices_[device_index] == dev)
240 assert(device_index < devices_.size() &&
"Device not within context");
242 return queues_[devices_[device_index].id()][i];
251 return programs_.back();
258 const char * source_text = source.c_str();
259 size_t source_size = source.size();
262 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
263 std::cout <<
"ViennaCL: Adding program '" << prog_name <<
"' to context " << h_ << std::endl;
269 err = clBuildProgram(temp, 0, NULL, NULL, NULL, NULL);
270 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_BUILD)
272 cl_build_status status;
273 clGetProgramBuildInfo(temp, devices_[0].
id(), CL_PROGRAM_BUILD_STATUS,
sizeof(cl_build_status), &status, NULL);
274 clGetProgramBuildInfo(temp, devices_[0].
id(), CL_PROGRAM_BUILD_LOG,
sizeof(
char)*1024, &buffer, NULL);
275 std::cout <<
"Build Scalar: Err = " << err <<
" Status = " << status << std::endl;
276 std::cout <<
"Log: " << buffer << std::endl;
283 return programs_.back();
289 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
290 std::cout <<
"ViennaCL: Getting program '" << name <<
"' from context " << h_ << std::endl;
292 for (ProgramContainer::iterator it = programs_.begin();
293 it != programs_.end();
296 if (it->name() == name)
299 std::cerr <<
"Could not find program '" << name <<
"'" << std::endl;
300 assert(!
"In class 'context': name invalid in get_program()");
307 assert(
id >= 0 &&
id < programs_.size() &&
"In class 'context': id invalid in get_program()");
308 return programs_[id];
323 return h_ < other.h_;
330 assert(!initialized_ &&
"ViennaCL FATAL error: Context already created!");
332 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
333 std::cout <<
"ViennaCL: Initializing new ViennaCL context." << std::endl;
337 std::vector<cl_device_id> device_id_array;
338 if (devices_.empty())
341 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
342 std::cout <<
"ViennaCL: Setting all devices for context..." << std::endl;
347 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
348 std::cout <<
"ViennaCL: Number of devices for context: " << devices.size() << std::endl;
350 for (
size_t i=0; i<devices.size(); ++i)
351 devices_.push_back(devices[i]);
353 if (devices.size() == 0)
355 std::cerr <<
"ViennaCL: FATAL ERROR: No devices of type '";
356 switch (device_type_)
358 case CL_DEVICE_TYPE_CPU: std::cout <<
"CPU";
break;
359 case CL_DEVICE_TYPE_GPU: std::cout <<
"CPU";
break;
360 case CL_DEVICE_TYPE_ACCELERATOR: std::cout <<
"ACCELERATOR";
break;
361 case CL_DEVICE_TYPE_DEFAULT: std::cout <<
"DEFAULT";
break;
363 std::cout <<
"UNKNOWN" << std::endl;
365 std::cout <<
"' found!" << std::endl;
370 for (std::vector< viennacl::ocl::device >::const_iterator iter = devices_.begin();
371 iter != devices_.end();
373 device_id_array.push_back(iter->id());
375 cl_uint
device_num = std::max(default_device_num_, device_id_array.size());
376 h_ = clCreateContext(0,
378 &(device_id_array[0]),
383 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
384 std::cout <<
"ViennaCL: Initialization of new ViennaCL context done." << std::endl;
389 void init_existing(cl_context c)
391 assert(!initialized_ &&
"ViennaCL FATAL error: Context already created!");
392 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
393 std::cout <<
"ViennaCL: Initialization of ViennaCL context from existing context." << std::endl;
399 if (devices_.empty())
410 assert(temp > 0 &&
"ViennaCL: FATAL error: Provided context does not contain any devices!");
411 num_devices = temp /
sizeof(cl_device_id);
413 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
414 std::cout <<
"ViennaCL: Reusing context with " << num_devices <<
" devices." << std::endl;
417 std::vector<cl_device_id> device_ids(num_devices);
418 err = clGetContextInfo(h_, CL_CONTEXT_DEVICES, num_devices *
sizeof(cl_device_id), &(device_ids[0]), NULL);
421 for (
size_t i=0; i<num_devices; ++i)
424 current_device_id = 0;
427 #if defined(VIENNACL_DEBUG_ALL) || defined(VIENNACL_DEBUG_CONTEXT)
428 std::cout <<
"ViennaCL: Initialization of ViennaCL context from existing context done." << std::endl;
434 cl_device_type device_type_;
436 std::vector< viennacl::ocl::device > devices_;
437 unsigned int current_device_id;
438 std::size_t default_device_num_;
439 ProgramContainer programs_;
440 std::map< cl_device_id, std::vector< viennacl::ocl::command_queue> > queues_;