You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
258 lines
7.2 KiB
258 lines
7.2 KiB
//---------------------------------------------------------------------------// |
|
// Copyright (c) 2013 Kyle Lutz <kyle.r.lutz@gmail.com> |
|
// |
|
// Distributed under the Boost Software License, Version 1.0 |
|
// See accompanying file LICENSE_1_0.txt or copy at |
|
// http://www.boost.org/LICENSE_1_0.txt |
|
// |
|
// See http://boostorg.github.com/compute for more information. |
|
//---------------------------------------------------------------------------// |
|
|
|
#ifndef BOOST_COMPUTE_PLATFORM_HPP |
|
#define BOOST_COMPUTE_PLATFORM_HPP |
|
|
|
#include <algorithm> |
|
#include <string> |
|
#include <vector> |
|
|
|
#include <boost/algorithm/string/split.hpp> |
|
#include <boost/algorithm/string/classification.hpp> |
|
|
|
#include <boost/compute/cl.hpp> |
|
#include <boost/compute/device.hpp> |
|
#include <boost/compute/detail/get_object_info.hpp> |
|
|
|
namespace boost { |
|
namespace compute { |
|
|
|
/// \class platform |
|
/// \brief A compute platform. |
|
/// |
|
/// The platform class provides an interface to an OpenCL platform. |
|
/// |
|
/// To obtain a list of all platforms on the system use the |
|
/// system::platforms() method. |
|
/// |
|
/// \see device, context |
|
class platform |
|
{ |
|
public: |
|
/// Creates a new platform object for \p id. |
|
explicit platform(cl_platform_id id) |
|
: m_platform(id) |
|
{ |
|
} |
|
|
|
/// Creates a new platform as a copy of \p other. |
|
platform(const platform &other) |
|
: m_platform(other.m_platform) |
|
{ |
|
} |
|
|
|
/// Copies the platform id from \p other. |
|
platform& operator=(const platform &other) |
|
{ |
|
if(this != &other){ |
|
m_platform = other.m_platform; |
|
} |
|
|
|
return *this; |
|
} |
|
|
|
/// Destroys the platform object. |
|
~platform() |
|
{ |
|
} |
|
|
|
/// Returns the ID of the platform. |
|
cl_platform_id id() const |
|
{ |
|
return m_platform; |
|
} |
|
|
|
/// Returns the name of the platform. |
|
std::string name() const |
|
{ |
|
return get_info<std::string>(CL_PLATFORM_NAME); |
|
} |
|
|
|
/// Returns the name of the vendor for the platform. |
|
std::string vendor() const |
|
{ |
|
return get_info<std::string>(CL_PLATFORM_VENDOR); |
|
} |
|
|
|
/// Returns the profile string for the platform. |
|
std::string profile() const |
|
{ |
|
return get_info<std::string>(CL_PLATFORM_PROFILE); |
|
} |
|
|
|
/// Returns the version string for the platform. |
|
std::string version() const |
|
{ |
|
return get_info<std::string>(CL_PLATFORM_VERSION); |
|
} |
|
|
|
/// Returns a list of extensions supported by the platform. |
|
std::vector<std::string> extensions() const |
|
{ |
|
std::string extensions_string = |
|
get_info<std::string>(CL_PLATFORM_EXTENSIONS); |
|
std::vector<std::string> extensions_vector; |
|
boost::split(extensions_vector, |
|
extensions_string, |
|
boost::is_any_of("\t "), |
|
boost::token_compress_on); |
|
return extensions_vector; |
|
} |
|
|
|
/// Returns \c true if the platform supports the extension with |
|
/// \p name. |
|
bool supports_extension(const std::string &name) const |
|
{ |
|
const std::vector<std::string> extensions = this->extensions(); |
|
|
|
return std::find( |
|
extensions.begin(), extensions.end(), name) != extensions.end(); |
|
} |
|
|
|
/// Returns a list of devices on the platform. |
|
std::vector<device> devices(cl_device_type type = CL_DEVICE_TYPE_ALL) const |
|
{ |
|
size_t count = device_count(type); |
|
if(count == 0){ |
|
// no devices for this platform |
|
return std::vector<device>(); |
|
} |
|
|
|
std::vector<cl_device_id> device_ids(count); |
|
cl_int ret = clGetDeviceIDs(m_platform, |
|
type, |
|
static_cast<cl_uint>(count), |
|
&device_ids[0], |
|
0); |
|
if(ret != CL_SUCCESS){ |
|
BOOST_THROW_EXCEPTION(opencl_error(ret)); |
|
} |
|
|
|
std::vector<device> devices; |
|
for(cl_uint i = 0; i < count; i++){ |
|
devices.push_back(device(device_ids[i])); |
|
} |
|
|
|
return devices; |
|
} |
|
|
|
/// Returns the number of devices on the platform. |
|
size_t device_count(cl_device_type type = CL_DEVICE_TYPE_ALL) const |
|
{ |
|
cl_uint count = 0; |
|
cl_int ret = clGetDeviceIDs(m_platform, type, 0, 0, &count); |
|
if(ret != CL_SUCCESS){ |
|
if(ret == CL_DEVICE_NOT_FOUND){ |
|
// no devices for this platform |
|
return 0; |
|
} |
|
else { |
|
// something else went wrong |
|
BOOST_THROW_EXCEPTION(opencl_error(ret)); |
|
} |
|
} |
|
|
|
return count; |
|
} |
|
|
|
/// Returns information about the platform. |
|
/// |
|
/// \see_opencl_ref{clGetPlatformInfo} |
|
template<class T> |
|
T get_info(cl_platform_info info) const |
|
{ |
|
return detail::get_object_info<T>(clGetPlatformInfo, m_platform, info); |
|
} |
|
|
|
/// \overload |
|
template<int Enum> |
|
typename detail::get_object_info_type<platform, Enum>::type |
|
get_info() const; |
|
|
|
/// Returns the address of the \p function_name extension |
|
/// function. Returns \c 0 if \p function_name is invalid. |
|
void* get_extension_function_address(const char *function_name) const |
|
{ |
|
#ifdef BOOST_COMPUTE_CL_VERSION_1_2 |
|
return clGetExtensionFunctionAddressForPlatform(m_platform, |
|
function_name); |
|
#else |
|
return clGetExtensionFunctionAddress(function_name); |
|
#endif |
|
} |
|
|
|
/// Requests that the platform unload any compiler resources. |
|
void unload_compiler() |
|
{ |
|
#ifdef BOOST_COMPUTE_CL_VERSION_1_2 |
|
clUnloadPlatformCompiler(m_platform); |
|
#else |
|
clUnloadCompiler(); |
|
#endif |
|
} |
|
|
|
/// Returns \c true if the platform is the same at \p other. |
|
bool operator==(const platform &other) const |
|
{ |
|
return m_platform == other.m_platform; |
|
} |
|
|
|
/// Returns \c true if the platform is different from \p other. |
|
bool operator!=(const platform &other) const |
|
{ |
|
return m_platform != other.m_platform; |
|
} |
|
|
|
/// Returns \c true if the platform OpenCL version is major.minor |
|
/// or newer; otherwise returns \c false. |
|
bool check_version(int major, int minor) const |
|
{ |
|
std::stringstream stream; |
|
stream << version(); |
|
|
|
int actual_major, actual_minor; |
|
stream.ignore(7); // 'OpenCL ' |
|
stream >> actual_major; |
|
stream.ignore(1); // '.' |
|
stream >> actual_minor; |
|
|
|
return actual_major > major || |
|
(actual_major == major && actual_minor >= minor); |
|
} |
|
|
|
private: |
|
cl_platform_id m_platform; |
|
}; |
|
|
|
/// \internal_ define get_info() specializations for platform |
|
BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(platform, |
|
((std::string, CL_PLATFORM_PROFILE)) |
|
((std::string, CL_PLATFORM_VERSION)) |
|
((std::string, CL_PLATFORM_NAME)) |
|
((std::string, CL_PLATFORM_VENDOR)) |
|
((std::string, CL_PLATFORM_EXTENSIONS)) |
|
) |
|
|
|
#ifdef BOOST_COMPUTE_CL_VERSION_2_1 |
|
BOOST_COMPUTE_DETAIL_DEFINE_GET_INFO_SPECIALIZATIONS(platform, |
|
((cl_ulong, CL_PLATFORM_HOST_TIMER_RESOLUTION)) |
|
) |
|
#endif // BOOST_COMPUTE_CL_VERSION_2_1 |
|
|
|
inline boost::compute::platform device::platform() const |
|
{ |
|
return boost::compute::platform(get_info<CL_DEVICE_PLATFORM>()); |
|
} |
|
|
|
} // end compute namespace |
|
} // end boost namespace |
|
|
|
#endif // BOOST_COMPUTE_PLATFORM_HPP
|
|
|