clover: Add property list helpers with a syntax consistent with other API objects.

Tested-by: Tom Stellard <thomas.stellard@amd.com>
This commit is contained in:
Francisco Jerez 2013-09-16 21:13:47 -07:00
parent 04d0ab9f64
commit e5fc61fa3f
5 changed files with 91 additions and 50 deletions

View file

@ -22,6 +22,7 @@
#include "api/util.hpp"
#include "core/context.hpp"
#include "core/platform.hpp"
using namespace clover;
@ -31,19 +32,21 @@ clCreateContext(const cl_context_properties *d_props, cl_uint num_devs,
void (CL_CALLBACK *pfn_notify)(const char *, const void *,
size_t, void *),
void *user_data, cl_int *r_errcode) try {
auto props = property_map(d_props);
auto props = obj<property_list_tag>(d_props);
auto devs = objs(d_devs, num_devs);
if (!pfn_notify && user_data)
throw error(CL_INVALID_VALUE);
for (auto prop : props) {
if (prop.first != CL_CONTEXT_PLATFORM)
for (auto &prop : props) {
if (prop.first == CL_CONTEXT_PLATFORM)
obj(prop.second.as<cl_platform_id>());
else
throw error(CL_INVALID_PROPERTY);
}
ret_error(r_errcode, CL_SUCCESS);
return desc(new context(property_vector(props), devs));
return desc(new context(props, devs));
} catch (error &e) {
ret_error(r_errcode, e);
@ -116,7 +119,7 @@ clGetContextInfo(cl_context d_ctx, cl_context_info param,
break;
case CL_CONTEXT_PROPERTIES:
buf.as_vector<cl_context_properties>() = ctx.props();
buf.as_vector<cl_context_properties>() = desc(ctx.props());
break;
default:

View file

@ -30,44 +30,6 @@
#include "util/algorithm.hpp"
namespace clover {
///
/// Convert a NULL-terminated property list into an std::map.
///
template<typename T>
std::map<T, T>
property_map(const T *props) {
std::map<T, T> m;
while (props && *props) {
T key = *props++;
T value = *props++;
if (m.count(key))
throw clover::error(CL_INVALID_PROPERTY);
m.insert({ key, value });
}
return m;
}
///
/// Convert an std::map into a NULL-terminated property list.
///
template<typename T>
std::vector<T>
property_vector(const std::map<T, T> &m) {
std::vector<T> v;
for (auto &p : m) {
v.push_back(p.first);
v.push_back(p.second);
}
v.push_back(0);
return v;
}
///
/// Return an error code in \a p if non-zero.
///

View file

@ -26,7 +26,7 @@
using namespace clover;
context::context(const std::vector<cl_context_properties> &props,
context::context(const property_list &props,
const ref_vector<device> &devs) :
devs(map(addresses(), devs)), _props(props) {
}
@ -35,3 +35,8 @@ bool
context::has_device(device &dev) const {
return std::count(devs.begin(), devs.end(), &dev);
}
const context::property_list &
context::props() const {
return _props;
}

View file

@ -25,24 +25,27 @@
#include "core/object.hpp"
#include "core/device.hpp"
#include "core/property.hpp"
namespace clover {
class context : public ref_counter, public _cl_context {
private:
typedef clover::property_list<cl_context_properties> property_list;
public:
context(const std::vector<cl_context_properties> &props,
const ref_vector<device> &devs);
context(const property_list &props, const ref_vector<device> &devs);
context(const context &ctx) = delete;
bool has_device(device &dev) const;
const std::vector<cl_context_properties> &props() const {
return _props;
}
const property_list &
props() const;
const std::vector<device *> devs;
private:
std::vector<cl_context_properties> _props;
property_list _props;
};
}

View file

@ -188,6 +188,74 @@ namespace clover {
return *this;
}
};
template<typename T>
class property_element {
public:
property_element() : x() {
}
property_element(T x) : x(x) {
}
template<typename S>
S
as() const {
assert(sizeof(S) <= sizeof(T));
return reinterpret_cast<S>(x);
}
private:
T x;
};
template<typename D>
using property_list = std::map<D, property_element<D>>;
struct property_list_tag;
///
/// Create a clover::property_list object from a zero-terminated
/// CL property list.
///
template<typename T, typename D,
typename = typename std::enable_if<
std::is_same<T, property_list_tag>::value>::type>
property_list<D>
obj(const D *d_props) {
property_list<D> props;
while (d_props && *d_props) {
auto key = *d_props++;
auto value = *d_props++;
if (props.count(key))
throw error(CL_INVALID_PROPERTY);
props.insert({ key, value });
}
return props;
}
///
/// Create a zero-terminated CL property list from a
/// clover::property_list object.
///
template<typename D>
std::vector<D>
desc(const property_list<D> &props) {
std::vector<D> d_props;
for (auto &prop : props) {
d_props.push_back(prop.first);
d_props.push_back(prop.second.template as<D>());
}
d_props.push_back(0);
return d_props;
}
}
#endif