Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-11-15 09:04:31

0001 //---------------------------------------------------------------------------//
0002 // Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com>
0003 //
0004 // Distributed under the Boost Software License, Version 1.0
0005 // See accompanying file LICENSE_1_0.txt or copy at
0006 // http://www.boost.org/LICENSE_1_0.txt
0007 //
0008 // See http://boostorg.github.com/compute for more information.
0009 //---------------------------------------------------------------------------//
0010 
0011 #ifndef BOOST_COMPUTE_DEVICE_HPP
0012 #define BOOST_COMPUTE_DEVICE_HPP
0013 
0014 #include <algorithm>
0015 #include <string>
0016 #include <vector>
0017 
0018 #include <boost/algorithm/string/split.hpp>
0019 #include <boost/algorithm/string/classification.hpp>
0020 
0021 #include <boost/compute/config.hpp>
0022 #include <boost/compute/exception.hpp>
0023 #include <boost/compute/types/fundamental.hpp>
0024 #include <boost/compute/detail/duration.hpp>
0025 #include <boost/compute/detail/get_object_info.hpp>
0026 #include <boost/compute/detail/assert_cl_success.hpp>
0027 
0028 namespace boost {
0029 namespace compute {
0030 
0031 class platform;
0032 
0033 /// \class device
0034 /// \brief A compute device.
0035 ///
0036 /// Typical compute devices include GPUs and multi-core CPUs. A list
0037 /// of all compute devices available on a platform can be obtained
0038 /// via the platform::devices() method.
0039 ///
0040 /// The default compute device for the system can be obtained with
0041 /// the system::default_device() method. For example:
0042 ///
0043 /// \snippet test/test_device.cpp default_gpu
0044 ///
0045 /// \see platform, context, command_queue
0046 class device
0047 {
0048 public:
0049     enum type {
0050         cpu = CL_DEVICE_TYPE_CPU,
0051         gpu = CL_DEVICE_TYPE_GPU,
0052         accelerator = CL_DEVICE_TYPE_ACCELERATOR
0053     };
0054 
0055     /// Creates a null device object.
0056     device()
0057         : m_id(0)
0058     {
0059     }
0060 
0061     /// Creates a new device object for \p id. If \p retain is \c true,
0062     /// the reference count for the device will be incremented.
0063     explicit device(cl_device_id id, bool retain = true)
0064         : m_id(id)
0065     {
0066         #ifdef BOOST_COMPUTE_CL_VERSION_1_2
0067         if(m_id && retain && is_subdevice()){
0068             clRetainDevice(m_id);
0069         }
0070         #else
0071         (void) retain;
0072         #endif
0073     }
0074 
0075     /// Creates a new device object as a copy of \p other.
0076     device(const device &other)
0077         : m_id(other.m_id)
0078     {
0079         #ifdef BOOST_COMPUTE_CL_VERSION_1_2
0080         if(m_id && is_subdevice()){
0081             clRetainDevice(m_id);
0082         }
0083         #endif
0084     }
0085 
0086     /// Copies the device from \p other to \c *this.
0087     device& operator=(const device &other)
0088     {
0089         if(this != &other){
0090             #ifdef BOOST_COMPUTE_CL_VERSION_1_2
0091             if(m_id && is_subdevice()){
0092                 clReleaseDevice(m_id);
0093             }
0094             #endif
0095 
0096             m_id = other.m_id;
0097 
0098             #ifdef BOOST_COMPUTE_CL_VERSION_1_2
0099             if(m_id && is_subdevice()){
0100                 clRetainDevice(m_id);
0101             }
0102             #endif
0103         }
0104 
0105         return *this;
0106     }
0107 
0108     #ifndef BOOST_COMPUTE_NO_RVALUE_REFERENCES
0109     /// Move-constructs a new device object from \p other.
0110     device(device&& other) BOOST_NOEXCEPT
0111         : m_id(other.m_id)
0112     {
0113         other.m_id = 0;
0114     }
0115 
0116     /// Move-assigns the device from \p other to \c *this.
0117     device& operator=(device&& other) BOOST_NOEXCEPT
0118     {
0119         #ifdef BOOST_COMPUTE_CL_VERSION_1_2
0120         if(m_id && is_subdevice()){
0121             clReleaseDevice(m_id);
0122         }
0123         #endif
0124 
0125         m_id = other.m_id;
0126         other.m_id = 0;
0127 
0128         return *this;
0129     }
0130     #endif // BOOST_COMPUTE_NO_RVALUE_REFERENCES
0131 
0132     /// Destroys the device object.
0133     ~device()
0134     {
0135         #ifdef BOOST_COMPUTE_CL_VERSION_1_2
0136         if(m_id && is_subdevice()){
0137             BOOST_COMPUTE_ASSERT_CL_SUCCESS(
0138                 clReleaseDevice(m_id)
0139             );
0140         }
0141         #endif
0142     }
0143 
0144     /// Returns the ID of the device.
0145     cl_device_id id() const
0146     {
0147         return m_id;
0148     }
0149 
0150     /// Returns a reference to the underlying OpenCL device id.
0151     cl_device_id& get() const
0152     {
0153         return const_cast<cl_device_id&>(m_id);
0154     }
0155 
0156     /// Returns the type of the device.
0157     cl_device_type type() const
0158     {
0159         return get_info<cl_device_type>(CL_DEVICE_TYPE);
0160     }
0161 
0162     #ifdef BOOST_COMPUTE_DOXYGEN_INVOKED
0163     /// Returns the platform for the device.
0164     platform platform() const;
0165     #else
0166     boost::compute::platform platform() const;
0167     #endif
0168 
0169     /// Returns the name of the device.
0170     std::string name() const
0171     {
0172         return get_info<std::string>(CL_DEVICE_NAME);
0173     }
0174 
0175     /// Returns the name of the vendor for the device.
0176     std::string vendor() const
0177     {
0178         return get_info<std::string>(CL_DEVICE_VENDOR);
0179     }
0180 
0181     /// Returns the device profile string.
0182     std::string profile() const
0183     {
0184         return get_info<std::string>(CL_DEVICE_PROFILE);
0185     }
0186 
0187     /// Returns the device version string.
0188     std::string version() const
0189     {
0190         return get_info<std::string>(CL_DEVICE_VERSION);
0191     }
0192 
0193     /// Returns the driver version string.
0194     std::string driver_version() const
0195     {
0196         return get_info<std::string>(CL_DRIVER_VERSION);
0197     }
0198 
0199     /// Returns a list of extensions supported by the device.
0200     std::vector<std::string> extensions() const
0201     {
0202         std::string extensions_string =
0203             get_info<std::string>(CL_DEVICE_EXTENSIONS);
0204         std::vector<std::string> extensions_vector;
0205         boost::split(extensions_vector,
0206                      extensions_string,
0207                      boost::is_any_of("\t "),
0208                      boost::token_compress_on);
0209         return extensions_vector;
0210     }
0211 
0212     /// Returns \c true if the device supports the extension with
0213     /// \p name.
0214     bool supports_extension(const std::string &name) const
0215     {
0216         const std::vector<std::string> extensions = this->extensions();
0217 
0218         return std::find(
0219             extensions.begin(), extensions.end(), name) != extensions.end();
0220     }
0221 
0222     /// Returns the number of address bits.
0223     uint_ address_bits() const
0224     {
0225         return get_info<uint_>(CL_DEVICE_ADDRESS_BITS);
0226     }
0227 
0228     /// Returns the global memory size in bytes.
0229     ulong_ global_memory_size() const
0230     {
0231         return get_info<ulong_>(CL_DEVICE_GLOBAL_MEM_SIZE);
0232     }
0233 
0234     /// Returns the local memory size in bytes.
0235     ulong_ local_memory_size() const
0236     {
0237         return get_info<ulong_>(CL_DEVICE_LOCAL_MEM_SIZE);
0238     }
0239 
0240     /// Returns the clock frequency for the device's compute units.
0241     uint_ clock_frequency() const
0242     {
0243         return get_info<uint_>(CL_DEVICE_MAX_CLOCK_FREQUENCY);
0244     }
0245 
0246     /// Returns the number of compute units in the device.
0247     uint_ compute_units() const
0248     {
0249         return get_info<uint_>(CL_DEVICE_MAX_COMPUTE_UNITS);
0250     }
0251 
0252     /// \internal_
0253     ulong_ max_memory_alloc_size() const
0254     {
0255         return get_info<ulong_>(CL_DEVICE_MAX_MEM_ALLOC_SIZE);
0256     }
0257 
0258     /// \internal_
0259     size_t max_work_group_size() const
0260     {
0261         return get_info<size_t>(CL_DEVICE_MAX_WORK_GROUP_SIZE);
0262     }
0263 
0264     /// \internal_
0265     uint_ max_work_item_dimensions() const
0266     {
0267         return get_info<uint_>(CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS);
0268     }
0269 
0270     /// Returns the preferred vector width for type \c T.
0271     template<class T>
0272     uint_ preferred_vector_width() const
0273     {
0274         return 0;
0275     }
0276 
0277     /// Returns the profiling timer resolution in nanoseconds.
0278     size_t profiling_timer_resolution() const
0279     {
0280         return get_info<size_t>(CL_DEVICE_PROFILING_TIMER_RESOLUTION);
0281     }
0282 
0283     /// Returns \c true if the device is a sub-device.
0284     bool is_subdevice() const
0285     {
0286     #if defined(BOOST_COMPUTE_CL_VERSION_1_2)
0287         try {
0288             return get_info<cl_device_id>(CL_DEVICE_PARENT_DEVICE) != 0;
0289         }
0290         catch(opencl_error&){
0291             // the get_info() call above will throw if the device's opencl version
0292             // is less than 1.2 (in which case it can't be a sub-device).
0293             return false;
0294         }
0295     #else
0296         return false;
0297     #endif
0298     }
0299 
0300     /// Returns information about the device.
0301     ///
0302     /// For example, to get the number of compute units:
0303     /// \code
0304     /// device.get_info<cl_uint>(CL_DEVICE_MAX_COMPUTE_UNITS);
0305     /// \endcode
0306     ///
0307     /// Alternatively, the template-specialized version can be used which
0308     /// automatically determines the result type:
0309     /// \code
0310     /// device.get_info<CL_DEVICE_MAX_COMPUTE_UNITS>();
0311     /// \endcode
0312     ///
0313     /// \see_opencl_ref{clGetDeviceInfo}
0314     template<class T>
0315     T get_info(cl_device_info info) const
0316     {
0317         return detail::get_object_info<T>(clGetDeviceInfo, m_id, info);
0318     }
0319 
0320     /// \overload
0321     template<int Enum>
0322     typename detail::get_object_info_type<device, Enum>::type
0323     get_info() const;
0324 
0325     #if defined(BOOST_COMPUTE_CL_VERSION_1_2) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
0326     /// Partitions the device into multiple sub-devices according to
0327     /// \p properties.
0328     ///
0329     /// \opencl_version_warning{1,2}
0330     std::vector<device>
0331     partition(const cl_device_partition_property *properties) const
0332     {
0333         // get sub-device count
0334         uint_ count = 0;
0335         int_ ret = clCreateSubDevices(m_id, properties, 0, 0, &count);
0336         if(ret != CL_SUCCESS){
0337             BOOST_THROW_EXCEPTION(opencl_error(ret));
0338         }
0339 
0340         // get sub-device ids
0341         std::vector<cl_device_id> ids(count);
0342         ret = clCreateSubDevices(m_id, properties, count, &ids[0], 0);
0343         if(ret != CL_SUCCESS){
0344             BOOST_THROW_EXCEPTION(opencl_error(ret));
0345         }
0346 
0347         // convert ids to device objects
0348         std::vector<device> devices(count);
0349         for(size_t i = 0; i < count; i++){
0350             devices[i] = device(ids[i], false);
0351         }
0352 
0353         return devices;
0354     }
0355 
0356     /// \opencl_version_warning{1,2}
0357     std::vector<device> partition_equally(size_t count) const
0358     {
0359         cl_device_partition_property properties[] = {
0360             CL_DEVICE_PARTITION_EQUALLY,
0361             static_cast<cl_device_partition_property>(count),
0362             0
0363         };
0364 
0365         return partition(properties);
0366     }
0367 
0368     /// \opencl_version_warning{1,2}
0369     std::vector<device>
0370     partition_by_counts(const std::vector<size_t> &counts) const
0371     {
0372         std::vector<cl_device_partition_property> properties;
0373 
0374         properties.push_back(CL_DEVICE_PARTITION_BY_COUNTS);
0375         for(size_t i = 0; i < counts.size(); i++){
0376             properties.push_back(
0377                 static_cast<cl_device_partition_property>(counts[i]));
0378         }
0379         properties.push_back(CL_DEVICE_PARTITION_BY_COUNTS_LIST_END);
0380         properties.push_back(0);
0381 
0382         return partition(&properties[0]);
0383     }
0384 
0385     /// \opencl_version_warning{1,2}
0386     std::vector<device>
0387     partition_by_affinity_domain(cl_device_affinity_domain domain) const
0388     {
0389         cl_device_partition_property properties[] = {
0390             CL_DEVICE_PARTITION_BY_AFFINITY_DOMAIN,
0391             static_cast<cl_device_partition_property>(domain),
0392             0
0393         };
0394 
0395         return partition(properties);
0396     }
0397     #endif // BOOST_COMPUTE_CL_VERSION_1_2
0398 
0399     #if defined(BOOST_COMPUTE_CL_VERSION_2_1) || defined(BOOST_COMPUTE_DOXYGEN_INVOKED)
0400     /// Returns the current value of the host clock as seen by device
0401     /// in nanoseconds.
0402     ///
0403     /// \see_opencl21_ref{clGetHostTimer}
0404     ///
0405     /// \opencl_version_warning{2,1}
0406     ulong_ get_host_timer() const
0407     {
0408         ulong_ host_timestamp = 0;
0409         cl_int ret = clGetHostTimer(m_id, &host_timestamp);
0410         if(ret != CL_SUCCESS){
0411             BOOST_THROW_EXCEPTION(opencl_error(ret));
0412         }
0413         return host_timestamp;
0414     }
0415 
0416     /// Returns a reasonably synchronized pair of timestamps from the device timer
0417     /// and the host timer as seen by device in nanoseconds. The first of returned
0418     /// std::pair is a device timer timestamp, the second is a host timer timestamp.
0419     ///
0420     /// \see_opencl21_ref{clGetDeviceAndHostTimer}
0421     ///
0422     /// \opencl_version_warning{2,1}
0423     std::pair<ulong_, ulong_> get_device_and_host_timer() const
0424     {
0425         ulong_ host_timestamp;
0426         ulong_ device_timestamp;
0427         cl_int ret = clGetDeviceAndHostTimer(
0428             m_id, &device_timestamp, &host_timestamp
0429         );
0430         if(ret != CL_SUCCESS){
0431             BOOST_THROW_EXCEPTION(opencl_error(ret));
0432         }
0433         return std::make_pair(
0434             device_timestamp, host_timestamp
0435         );
0436     }
0437 
0438     #if !defined(BOOST_COMPUTE_NO_HDR_CHRONO) || !defined(BOOST_COMPUTE_NO_BOOST_CHRONO)
0439     /// Returns the current value of the host clock as seen by device
0440     /// as duration.
0441     ///
0442     /// For example, to print the current value of the host clock as seen by device
0443     /// in milliseconds:
0444     /// \code
0445     /// std::cout << device.get_host_timer<std::chrono::milliseconds>().count() << " ms";
0446     /// \endcode
0447     ///
0448     /// \see_opencl21_ref{clGetHostTimer}
0449     ///
0450     /// \opencl_version_warning{2,1}
0451     template<class Duration>
0452     Duration get_host_timer() const
0453     {
0454         const ulong_ nanoseconds = this->get_host_timer();
0455         return detail::make_duration_from_nanoseconds(Duration(), nanoseconds);
0456     }
0457 
0458     /// Returns a reasonably synchronized pair of timestamps from the device timer
0459     /// and the host timer as seen by device as a std::pair<Duration, Duration> value.
0460     /// The first of returned std::pair is a device timer timestamp, the second is
0461     /// a host timer timestamp.
0462     ///
0463     /// \see_opencl21_ref{clGetDeviceAndHostTimer}
0464     ///
0465     /// \opencl_version_warning{2,1}
0466     template<class Duration>
0467     std::pair<Duration, Duration> get_device_and_host_timer() const
0468     {
0469         const std::pair<ulong_, ulong_> timestamps = this->get_device_and_host_timer();
0470         return std::make_pair(
0471             detail::make_duration_from_nanoseconds(Duration(), timestamps.first),
0472             detail::make_duration_from_nanoseconds(Duration(), timestamps.second)
0473         );
0474     }
0475     #endif // !defined(BOOST_COMPUTE_NO_HDR_CHRONO) || !defined(BOOST_COMPUTE_NO_BOOST_CHRONO)
0476     #endif // BOOST_COMPUTE_CL_VERSION_2_1
0477 
0478     /// Returns \c true if the device is the same at \p other.
0479     bool operator==(const device &other) const
0480     {
0481         return m_id == other.m_id;
0482     }
0483 
0484     /// Returns \c true if the device is different from \p other.
0485     bool operator!=(const device &other) const
0486     {
0487         return m_id != other.m_id;
0488     }
0489 
0490     /// Returns \c true if the device OpenCL version is major.minor
0491     /// or newer; otherwise returns \c false.
0492     bool check_version(int major, int minor) const
0493     {
0494         std::stringstream stream;
0495         stream << version();
0496 
0497         int actual_major, actual_minor;
0498         stream.ignore(7); // 'OpenCL '
0499         stream >> actual_major;
0500         stream.ignore(1); // '.'
0501         stream >> actual_minor;
0502 
0503         return actual_major > major ||
0504                (actual_major == major && actual_minor >= minor);
0505     }
0506 
0507 private:
0508     cl_device_id m_id;
0509 };
0510 
0511 /// \internal_
0512 template<>
0513 inline uint_ device::preferred_vector_width<short_>() const
0514 {
0515     return get_info<uint_>(CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT);
0516 }
0517 
0518 /// \internal_
0519 template<>
0520 inline uint_ device::preferred_vector_width<int_>() const
0521 {
0522     return get_info<uint_>(CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT);
0523 }
0524 
0525 /// \internal_
0526 template<>
0527 inline uint_ device::preferred_vector_width<long_>() const
0528 {
0529     return get_info<uint_>(CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG);
0530 }
0531 
0532 /// \internal_
0533 template<>
0534 inline uint_ device::preferred_vector_width<float_>() const
0535 {
0536     return get_info<uint_>(CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT);
0537 }
0538 
0539 /// \internal_
0540 template<>
0541 inline uint_ device::preferred_vector_width<double_>() const
0542 {
0543     return get_info<uint_>(CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE);
0544 }
0545 
0546 /// \internal_ define get_info() specializations for device
0547 BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(device,
0548     ((cl_uint, CL_DEVICE_ADDRESS_BITS))
0549     ((bool, CL_DEVICE_AVAILABLE))
0550     ((bool, CL_DEVICE_COMPILER_AVAILABLE))
0551     ((bool, CL_DEVICE_ENDIAN_LITTLE))
0552     ((bool, CL_DEVICE_ERROR_CORRECTION_SUPPORT))
0553     ((cl_device_exec_capabilities, CL_DEVICE_EXECUTION_CAPABILITIES))
0554     ((std::string, CL_DEVICE_EXTENSIONS))
0555     ((cl_ulong, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE))
0556     ((cl_device_mem_cache_type, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE))
0557     ((cl_uint, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE))
0558     ((cl_ulong, CL_DEVICE_GLOBAL_MEM_SIZE))
0559     ((bool, CL_DEVICE_IMAGE_SUPPORT))
0560     ((size_t, CL_DEVICE_IMAGE2D_MAX_HEIGHT))
0561     ((size_t, CL_DEVICE_IMAGE2D_MAX_WIDTH))
0562     ((size_t, CL_DEVICE_IMAGE3D_MAX_DEPTH))
0563     ((size_t, CL_DEVICE_IMAGE3D_MAX_HEIGHT))
0564     ((size_t, CL_DEVICE_IMAGE3D_MAX_WIDTH))
0565     ((cl_ulong, CL_DEVICE_LOCAL_MEM_SIZE))
0566     ((cl_device_local_mem_type, CL_DEVICE_LOCAL_MEM_TYPE))
0567     ((cl_uint, CL_DEVICE_MAX_CLOCK_FREQUENCY))
0568     ((cl_uint, CL_DEVICE_MAX_COMPUTE_UNITS))
0569     ((cl_uint, CL_DEVICE_MAX_CONSTANT_ARGS))
0570     ((cl_ulong, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE))
0571     ((cl_ulong, CL_DEVICE_MAX_MEM_ALLOC_SIZE))
0572     ((size_t, CL_DEVICE_MAX_PARAMETER_SIZE))
0573     ((cl_uint, CL_DEVICE_MAX_READ_IMAGE_ARGS))
0574     ((cl_uint, CL_DEVICE_MAX_SAMPLERS))
0575     ((size_t, CL_DEVICE_MAX_WORK_GROUP_SIZE))
0576     ((cl_uint, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS))
0577     ((std::vector<size_t>, CL_DEVICE_MAX_WORK_ITEM_SIZES))
0578     ((cl_uint, CL_DEVICE_MAX_WRITE_IMAGE_ARGS))
0579     ((cl_uint, CL_DEVICE_MEM_BASE_ADDR_ALIGN))
0580     ((cl_uint, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE))
0581     ((std::string, CL_DEVICE_NAME))
0582     ((cl_platform_id, CL_DEVICE_PLATFORM))
0583     ((cl_uint, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR))
0584     ((cl_uint, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT))
0585     ((cl_uint, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT))
0586     ((cl_uint, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG))
0587     ((cl_uint, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT))
0588     ((cl_uint, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE))
0589     ((std::string, CL_DEVICE_PROFILE))
0590     ((size_t, CL_DEVICE_PROFILING_TIMER_RESOLUTION))
0591     ((cl_command_queue_properties, CL_DEVICE_QUEUE_PROPERTIES))
0592     ((cl_device_fp_config, CL_DEVICE_SINGLE_FP_CONFIG))
0593     ((cl_device_type, CL_DEVICE_TYPE))
0594     ((std::string, CL_DEVICE_VENDOR))
0595     ((cl_uint, CL_DEVICE_VENDOR_ID))
0596     ((std::string, CL_DEVICE_VERSION))
0597     ((std::string, CL_DRIVER_VERSION))
0598 )
0599 
0600 #ifdef CL_DEVICE_DOUBLE_FP_CONFIG
0601 BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(device,
0602     ((cl_device_fp_config, CL_DEVICE_DOUBLE_FP_CONFIG))
0603 )
0604 #endif
0605 
0606 #ifdef CL_DEVICE_HALF_FP_CONFIG
0607 BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(device,
0608     ((cl_device_fp_config, CL_DEVICE_HALF_FP_CONFIG))
0609 )
0610 #endif
0611 
0612 #ifdef BOOST_COMPUTE_CL_VERSION_1_1
0613 BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(device,
0614     ((bool, CL_DEVICE_HOST_UNIFIED_MEMORY))
0615     ((cl_uint, CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR))
0616     ((cl_uint, CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT))
0617     ((cl_uint, CL_DEVICE_NATIVE_VECTOR_WIDTH_INT))
0618     ((cl_uint, CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG))
0619     ((cl_uint, CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT))
0620     ((cl_uint, CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE))
0621     ((std::string, CL_DEVICE_OPENCL_C_VERSION))
0622 )
0623 #endif // BOOST_COMPUTE_CL_VERSION_1_1
0624 
0625 #ifdef BOOST_COMPUTE_CL_VERSION_1_2
0626 BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(device,
0627     ((std::string, CL_DEVICE_BUILT_IN_KERNELS))
0628     ((bool, CL_DEVICE_LINKER_AVAILABLE))
0629     ((cl_device_id, CL_DEVICE_PARENT_DEVICE))
0630     ((cl_uint, CL_DEVICE_PARTITION_MAX_SUB_DEVICES))
0631     ((cl_device_partition_property, CL_DEVICE_PARTITION_PROPERTIES))
0632     ((cl_device_affinity_domain, CL_DEVICE_PARTITION_AFFINITY_DOMAIN))
0633     ((cl_device_partition_property, CL_DEVICE_PARTITION_TYPE))
0634     ((size_t, CL_DEVICE_PRINTF_BUFFER_SIZE))
0635     ((bool, CL_DEVICE_PREFERRED_INTEROP_USER_SYNC))
0636     ((cl_uint, CL_DEVICE_REFERENCE_COUNT))
0637 )
0638 #endif // BOOST_COMPUTE_CL_VERSION_1_2
0639 
0640 #ifdef BOOST_COMPUTE_CL_VERSION_2_0
0641 BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(device,
0642     ((size_t, CL_DEVICE_GLOBAL_VARIABLE_PREFERRED_TOTAL_SIZE))
0643     ((size_t, CL_DEVICE_MAX_GLOBAL_VARIABLE_SIZE))
0644     ((cl_uint, CL_DEVICE_MAX_ON_DEVICE_EVENTS))
0645     ((cl_uint, CL_DEVICE_MAX_ON_DEVICE_QUEUES))
0646     ((cl_uint, CL_DEVICE_MAX_PIPE_ARGS))
0647     ((cl_uint, CL_DEVICE_MAX_READ_WRITE_IMAGE_ARGS))
0648     ((cl_uint, CL_DEVICE_PIPE_MAX_ACTIVE_RESERVATIONS))
0649     ((cl_uint, CL_DEVICE_PIPE_MAX_PACKET_SIZE))
0650     ((cl_uint, CL_DEVICE_PREFERRED_GLOBAL_ATOMIC_ALIGNMENT))
0651     ((cl_uint, CL_DEVICE_PREFERRED_LOCAL_ATOMIC_ALIGNMENT))
0652     ((cl_uint, CL_DEVICE_PREFERRED_PLATFORM_ATOMIC_ALIGNMENT))
0653     ((cl_uint, CL_DEVICE_QUEUE_ON_DEVICE_MAX_SIZE))
0654     ((cl_uint, CL_DEVICE_QUEUE_ON_DEVICE_PREFERRED_SIZE))
0655     ((cl_command_queue_properties, CL_DEVICE_QUEUE_ON_DEVICE_PROPERTIES))
0656     ((cl_device_svm_capabilities, CL_DEVICE_SVM_CAPABILITIES))
0657     ((cl_uint, CL_DEVICE_IMAGE_BASE_ADDRESS_ALIGNMENT))
0658     ((cl_uint, CL_DEVICE_IMAGE_PITCH_ALIGNMENT))
0659 )
0660 #endif // BOOST_COMPUTE_CL_VERSION_2_0
0661 
0662 #ifdef BOOST_COMPUTE_CL_VERSION_2_1
0663 BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(device,
0664     ((std::string, CL_DEVICE_IL_VERSION))
0665     ((cl_uint, CL_DEVICE_MAX_NUM_SUB_GROUPS))
0666     ((bool, CL_DEVICE_SUB_GROUP_INDEPENDENT_FORWARD_PROGRESS))
0667 )
0668 #endif // BOOST_COMPUTE_CL_VERSION_2_1
0669 
0670 } // end compute namespace
0671 } // end boost namespace
0672 
0673 #endif // BOOST_COMPUTE_DEVICE_HPP