std::vector<device> device_list(DevFilter&& filter) { std::vector<device> dev_list = boost::compute::system::devices(); std::vector<device> device; for(auto d = dev_list.begin(); d != dev_list.end(); d++) { if (!d->get_info<cl_bool>(CL_DEVICE_AVAILABLE)) continue; if (!filter(*d)) continue; device.push_back(*d); } return device; }
bool operator()(const boost::compute::device &d) const { static std::map<cl_device_id, std::string> dev_uids = get_uids(); static /*thread_local*/ std::vector<std::unique_ptr<locker>> locks; std::unique_ptr<locker> lck(new locker(dev_uids[d.get()])); if (lck->try_lock() && filter(d)) { locks.push_back(std::move(lck)); return true; } return false; }
void printDeviceInfo(const boost::compute::device & dev) { INFOM("===================================================================="); INFOM("name : " << dev.name()); // misc information INFOM("--- misc info -----------------------------"); INFOM("CL_DEVICE_ERROR_CORRECTION_SUPPORT : " << dev.get_info<cl_bool>(CL_DEVICE_ERROR_CORRECTION_SUPPORT)); INFOM("CL_DEVICE_HOST_UNIFIED_MEMORY : " << dev.get_info<cl_bool>(CL_DEVICE_HOST_UNIFIED_MEMORY)); INFOM("CL_DEVICE_MAX_COMPUTE_UNITS : " << dev.get_info<cl_uint>(CL_DEVICE_MAX_COMPUTE_UNITS)); INFOM("CL_DEVICE_PROFILING_TIMER_RESOLUTION (ns) : " << dev.get_info<size_t>(CL_DEVICE_PROFILING_TIMER_RESOLUTION)); // global memory information INFOM("--- global memory info --------------------"); INFOM("CL_DEVICE_GLOBAL_MEM_CACHE_SIZE (KB) : " << dev.get_info<cl_ulong>(CL_DEVICE_GLOBAL_MEM_CACHE_SIZE) / 1024); INFOM("CL_DEVICE_GLOBAL_MEM_CACHE_TYPE : " << cacheTypeToString(dev.get_info<cl_device_mem_cache_type>(CL_DEVICE_GLOBAL_MEM_CACHE_TYPE))); INFOM("CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE (B) : " << dev.get_info<cl_uint>(CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE)); INFOM("CL_DEVICE_GLOBAL_MEM_SIZE (MB) : " << dev.get_info<cl_ulong>(CL_DEVICE_GLOBAL_MEM_SIZE) / 1024 / 1024); // local memory information INFOM("--- local memory info ---------------------"); INFOM("CL_DEVICE_LOCAL_MEM_SIZE (KB) : " << dev.get_info<cl_ulong>(CL_DEVICE_LOCAL_MEM_SIZE) / 1024); INFOM("CL_DEVICE_LOCAL_MEM_TYPE : " << localMemTypeToString(dev.get_info<cl_device_local_mem_type>(CL_DEVICE_LOCAL_MEM_TYPE))); // constant memory information INFOM("--- constant memory info ------------------"); INFOM("CL_DEVICE_MAX_CONSTANT_ARGS : " << dev.get_info<cl_uint>(CL_DEVICE_MAX_CONSTANT_ARGS)); INFOM("CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE (KB) : " << dev.get_info<cl_ulong>(CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE) / 1024); // memory object information INFOM("--- memory object info --------------------"); INFOM("CL_DEVICE_MAX_MEM_ALLOC_SIZE (MB) : " << dev.get_info<cl_ulong>(CL_DEVICE_MAX_MEM_ALLOC_SIZE) / 1024 / 1024); // work group information INFOM("--- work group info -----------------------"); INFOM("CL_DEVICE_MAX_WORK_GROUP_SIZE : " << dev.get_info<size_t>(CL_DEVICE_MAX_WORK_GROUP_SIZE)); INFOM("CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS : " << dev.get_info<size_t>(CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS)); INFOM("CL_DEVICE_MAX_WORK_ITEM_SIZES : " << dev.get_info<std::vector<size_t>>(CL_DEVICE_MAX_WORK_ITEM_SIZES)); INFOM("===================================================================="); }
bool findGPUDevice(boost::compute::device & dev) { std::vector<boost::compute::device> devs(boost::compute::system::devices()); for (const boost::compute::device & dev_ : devs) { if (dev_.type() == CL_DEVICE_TYPE_GPU) { INFOM("Using device: " << dev_.name()); dev = dev_; return true; } } dev = boost::compute::system::default_device(); WARNM("Could not find any GPU device. Using device: " << dev.name()); return false; }
namespace compute { typedef boost::compute::context context; typedef boost::compute::device device; typedef boost::compute::program program; typedef boost::compute::command_queue command_queue; typedef cl_command_queue_properties command_queue_properties; typedef cl_device_id device_id; typedef cl_context context_id; /// Launch grid size. struct ndrange { union { size_t dim[3]; struct { size_t x, y, z; }; }; ndrange(size_t x = 1, size_t y = 1, size_t z = 1) : x(x), y(y), z(z) {} }; /// Binds the specified context to the calling CPU thread. /** * With the OpenCL backend this is an empty stub provided for compatibility * with the CUDA backend. */ inline void select_context(const command_queue&) { } /// Returns device associated with the given queue. inline device get_device(const command_queue &q) { return q.get_device(); } /// Returns id of the device associated with the given queue. inline device_id get_device_id(const command_queue &q) { return q.get_device().get(); } /// Returns raw context id for the given queue. inline context_id get_context_id(const command_queue &q) { return q.get_context().get(); } /// Returns context for the given queue. inline context get_context(const command_queue &q) { return q.get_context(); } /// Compares contexts by raw ids. struct compare_contexts { bool operator()(const context &a, const context &b) const { return a.get() < b.get(); } }; /// Compares queues by raw ids. struct compare_queues { bool operator()(const command_queue &a, const command_queue &b) const { return a.get() < b.get(); } }; /// Create command queue on the same context and device as the given one. inline command_queue duplicate_queue(const command_queue &q) { return command_queue(q.get_context(), q.get_device(), q.get_properties()); } /// Checks if the compute device is CPU. inline bool is_cpu(const command_queue &q) { return q.get_device().get_info<cl_device_type>(CL_DEVICE_TYPE) & CL_DEVICE_TYPE_CPU; } /// Select devices by given criteria. /** * \param filter Device filter functor. Functors may be combined with logical * operators. * \returns list of devices satisfying the provided filter. * * This example selects any GPU which supports double precision arithmetic: \code auto devices = device_list( Filter::Type(CL_DEVICE_TYPE_GPU) && Filter::DoublePrecision ); \endcode */ template<class DevFilter> std::vector<device> device_list(DevFilter&& filter) { std::vector<device> dev_list = boost::compute::system::devices(); std::vector<device> device; for(auto d = dev_list.begin(); d != dev_list.end(); d++) { if (!d->get_info<cl_bool>(CL_DEVICE_AVAILABLE)) continue; if (!filter(*d)) continue; device.push_back(*d); } return device; } /// Create command queues on devices by given criteria. /** * \param filter Device filter functor. Functors may be combined with logical * operators. * \param properties Command queue properties. * * \returns list of queues accociated with selected devices. * \see device_list */ template<class DevFilter> std::pair<std::vector<context>, std::vector<command_queue>> queue_list(DevFilter &&filter, cl_command_queue_properties properties = 0) { std::vector<context> c; std::vector<command_queue> q; std::vector<device> dev_list = boost::compute::system::devices(); for(auto d = dev_list.begin(); d != dev_list.end(); d++) { if (!d->get_info<cl_bool>(CL_DEVICE_AVAILABLE)) continue; if (!filter(*d)) continue; try { c.push_back(context(*d)); q.push_back(command_queue(c.back(), *d, properties)); } catch(...) { // Something bad happened. Better skip this device. } } return std::make_pair(c, q); } } // namespace compute
bool operator()(const boost::compute::device &d) const { return 0 != (d.type() & type); }
bool operator()(const boost::compute::device &d) const { return d.name().find(devname) != std::string::npos; }
bool operator()(const boost::compute::device &d) const { return d.platform().name().find(platform) != std::string::npos; }
bool operator()(const boost::compute::device &d) const { return d.vendor().find(vendor) != std::string::npos; }
bool operator()(const boost::compute::device &d) const { return d.check_version(_major, _minor); }
bool operator()(const boost::compute::device &d) const { return d.supports_extension(extension); }
bool operator()(const boost::compute::device &d) const { return d.supports_extension("cl_khr_fp64") || d.supports_extension("cl_amd_fp64"); }
// used to sort devices by number of compute units bool compare_compute_units(const boost::compute::device &a, const boost::compute::device &b) { return a.compute_units() < b.compute_units(); }