util/pointer.hpp \
util/range.hpp \
util/tuple.hpp \
- core/base.hpp \
- core/compat.hpp \
core/compiler.hpp \
core/geometry.hpp \
core/device.hpp \
(!pfn_notify && user_data))
throw error(CL_INVALID_VALUE);
- if (any_of(is_zero<cl_device_id>, devs, devs + num_devs))
+ if (any_of(is_zero(), range(devs, num_devs)))
throw error(CL_INVALID_DEVICE);
for (auto p : mprops) {
if (&kern->prog.ctx != &q->ctx ||
any_of([&](const cl_event ev) {
return &ev->ctx != &q->ctx;
- }, deps, deps + num_deps))
+ }, range(deps, num_deps)))
throw error(CL_INVALID_CONTEXT);
if (bool(num_deps) != bool(deps) ||
- any_of(is_zero<cl_event>, deps, deps + num_deps))
+ any_of(is_zero(), range(deps, num_deps)))
throw error(CL_INVALID_EVENT_WAIT_LIST);
if (any_of([](std::unique_ptr<kernel::argument> &arg) {
return !arg->set();
- }, kern->args.begin(), kern->args.end()))
+ }, kern->args))
throw error(CL_INVALID_KERNEL_ARGS);
if (!kern->prog.binaries().count(&q->dev))
if (dims < 1 || dims > q->dev.max_block_size().size())
throw error(CL_INVALID_WORK_DIMENSION);
- if (!grid_size || any_of(is_zero<size_t>, grid_size, grid_size + dims))
+ if (!grid_size || any_of(is_zero(), range(grid_size, dims)))
throw error(CL_INVALID_GLOBAL_WORK_SIZE);
if (block_size) {
if (any_of([](size_t b, size_t max) {
return b == 0 || b > max;
- }, block_size, block_size + dims,
- q->dev.max_block_size().begin()))
+ }, range(block_size, dims),
+ q->dev.max_block_size()))
throw error(CL_INVALID_WORK_ITEM_SIZE);
- if (any_of([](size_t b, size_t g) {
- return g % b;
- }, block_size, block_size + dims, grid_size))
+ if (any_of(modulus(), range(grid_size, dims),
+ range(block_size, dims)))
throw error(CL_INVALID_WORK_GROUP_SIZE);
- if (fold(std::multiplies<size_t>(), 1u,
- block_size, block_size + dims) >
+ if (fold(multiplies(), 1u, range(block_size, dims)) >
q->dev.max_threads_per_block())
throw error(CL_INVALID_WORK_GROUP_SIZE);
}
const std::vector<size_t> &grid_offset,
const std::vector<size_t> &grid_size,
const std::vector<size_t> &block_size) {
- const std::vector<size_t> reduced_grid_size = map(
- std::divides<size_t>(), grid_size.begin(), grid_size.end(),
- block_size.begin());
+ const std::vector<size_t> reduced_grid_size =
+ map(divides(), grid_size, block_size);
return [=](event &) {
kern->launch(*q, grid_offset, reduced_grid_size, block_size);
throw error(CL_INVALID_CONTEXT);
if (!count || !strings ||
- any_of(is_zero<const char *>, strings, strings + count))
+ any_of(is_zero(), range(strings, count)))
throw error(CL_INVALID_VALUE);
// Concatenate all the provided fragments together
if (any_of([&](const cl_device_id dev) {
return !ctx->has_device(dev);
- }, devs, devs + count))
+ }, range(devs, count)))
throw error(CL_INVALID_DEVICE);
// Deserialize the provided binaries,
return { CL_INVALID_BINARY, {} };
}
},
- binaries, binaries + count, lengths);
+ range(binaries, count),
+ range(lengths, count));
// update the status array,
if (status_ret)
- std::transform(modules.begin(), modules.end(), status_ret,
- keys<cl_int, module>);
+ copy(map(keys(), modules), status_ret);
- if (any_of(key_equals<cl_int, module>(CL_INVALID_VALUE),
- modules.begin(), modules.end()))
+ if (any_of(key_equals(CL_INVALID_VALUE), modules))
throw error(CL_INVALID_VALUE);
- if (any_of(key_equals<cl_int, module>(CL_INVALID_BINARY),
- modules.begin(), modules.end()))
+ if (any_of(key_equals(CL_INVALID_BINARY), modules))
throw error(CL_INVALID_BINARY);
// initialize a program object with them.
ret_error(errcode_ret, CL_SUCCESS);
return new program(*ctx, { devs, devs + count },
- map(values<cl_int, module>,
- modules.begin(), modules.end()));
+ map(values(), modules));
} catch (error &e) {
ret_error(errcode_ret, e);
if (devs) {
if (any_of([&](const cl_device_id dev) {
return !prog->ctx.has_device(dev);
- }, devs, devs + count))
+ }, range(devs, count)))
throw error(CL_INVALID_DEVICE);
prog->build({ devs, devs + count }, opts);
case CL_PROGRAM_DEVICES:
return vector_property<cl_device_id>(
buf, size, size_ret,
- map(keys<device *, module>,
- prog->binaries().begin(), prog->binaries().end()));
+ map(keys(), prog->binaries()));
case CL_PROGRAM_SOURCE:
return string_property(buf, size, size_ret, prog->source());
ent.second.serialize(s);
return bin.size();
},
- prog->binaries().begin(), prog->binaries().end()));
+ prog->binaries()));
case CL_PROGRAM_BINARIES:
return matrix_property<unsigned char>(
ent.second.serialize(s);
return bin;
},
- prog->binaries().begin(), prog->binaries().end()));
+ prog->binaries()));
default:
return CL_INVALID_VALUE;
using namespace clover;
namespace {
- typedef resource::point point;
+ typedef resource::vector vector_t;
+
+ vector_t
+ vector(const size_t *p) {
+ return range(p, 3);
+ }
///
/// Common argument checking shared by memory transfer commands.
throw error(CL_INVALID_COMMAND_QUEUE);
if (bool(num_deps) != bool(deps) ||
- any_of(is_zero<cl_event>, deps, deps + num_deps))
+ any_of(is_zero(), range(deps, num_deps)))
throw error(CL_INVALID_EVENT_WAIT_LIST);
if (any_of([&](const cl_event ev) {
return &ev->ctx != &q->ctx;
- }, deps, deps + num_deps))
+ }, range(deps, num_deps)))
throw error(CL_INVALID_CONTEXT);
}
static mapping
get(cl_command_queue q, memory_obj *obj, cl_map_flags flags,
size_t offset, size_t size) {
- return { *q, obj->resource(q), flags, true, { offset }, { size, 1, 1 }};
+ return { *q, obj->resource(q), flags, true,
+ {{ offset }}, {{ size, 1, 1 }}};
}
};
template<typename T, typename S>
std::function<void (event &)>
soft_copy_op(cl_command_queue q,
- T dst_obj, const point &dst_orig, const point &dst_pitch,
- S src_obj, const point &src_orig, const point &src_pitch,
- const point ®ion) {
+ T dst_obj, const vector_t &dst_orig, const vector_t &dst_pitch,
+ S src_obj, const vector_t &src_orig, const vector_t &src_pitch,
+ const vector_t ®ion) {
return [=](event &) {
auto dst = _map<T>::get(q, dst_obj, CL_MAP_WRITE,
- dst_pitch(dst_orig), dst_pitch(region));
+ dot(dst_pitch, dst_orig),
+ dst_pitch[2] * region[2]);
auto src = _map<S>::get(q, src_obj, CL_MAP_READ,
- src_pitch(src_orig), src_pitch(region));
- point p;
-
- for (p[2] = 0; p[2] < region[2]; ++p[2]) {
- for (p[1] = 0; p[1] < region[1]; ++p[1]) {
- std::memcpy(static_cast<char *>(dst) + dst_pitch(p),
- static_cast<const char *>(src) + src_pitch(p),
- src_pitch[0] * region[0]);
+ dot(src_pitch, src_orig),
+ src_pitch[2] * region[2]);
+ vector_t v = {};
+
+ for (v[2] = 0; v[2] < region[2]; ++v[2]) {
+ for (v[1] = 0; v[1] < region[1]; ++v[1]) {
+ std::memcpy(
+ static_cast<char *>(dst) + dot(dst_pitch, v),
+ static_cast<const char *>(src) + dot(src_pitch, v),
+ src_pitch[0] * region[0]);
}
}
};
///
template<typename T, typename S>
std::function<void (event &)>
- hard_copy_op(cl_command_queue q, T dst_obj, const point &dst_orig,
- S src_obj, const point &src_orig, const point ®ion) {
+ hard_copy_op(cl_command_queue q, T dst_obj, const vector_t &dst_orig,
+ S src_obj, const vector_t &src_orig, const vector_t ®ion) {
return [=](event &) {
dst_obj->resource(q).copy(*q, dst_orig, region,
src_obj->resource(q), src_orig);
hard_event *hev = new hard_event(
*q, CL_COMMAND_READ_BUFFER, { deps, deps + num_deps },
soft_copy_op(q,
- ptr, { 0 }, { 1 },
- obj, { offset }, { 1 },
- { size, 1, 1 }));
+ ptr, {{ 0 }}, {{ 1 }},
+ obj, {{ offset }}, {{ 1 }},
+ {{ size, 1, 1 }}));
ret_object(ev, hev);
return CL_SUCCESS;
hard_event *hev = new hard_event(
*q, CL_COMMAND_WRITE_BUFFER, { deps, deps + num_deps },
soft_copy_op(q,
- obj, { offset }, { 1 },
- ptr, { 0 }, { 1 },
- { size, 1, 1 }));
+ obj, {{ offset }}, {{ 1 }},
+ ptr, {{ 0 }}, {{ 1 }},
+ {{ size, 1, 1 }}));
ret_object(ev, hev);
return CL_SUCCESS;
hard_event *hev = new hard_event(
*q, CL_COMMAND_READ_BUFFER_RECT, { deps, deps + num_deps },
soft_copy_op(q,
- ptr, host_origin,
- { 1, host_row_pitch, host_slice_pitch },
- obj, obj_origin,
- { 1, obj_row_pitch, obj_slice_pitch },
- region));
+ ptr, vector(host_origin),
+ {{ 1, host_row_pitch, host_slice_pitch }},
+ obj, vector(obj_origin),
+ {{ 1, obj_row_pitch, obj_slice_pitch }},
+ vector(region)));
ret_object(ev, hev);
return CL_SUCCESS;
hard_event *hev = new hard_event(
*q, CL_COMMAND_WRITE_BUFFER_RECT, { deps, deps + num_deps },
soft_copy_op(q,
- obj, obj_origin,
- { 1, obj_row_pitch, obj_slice_pitch },
- ptr, host_origin,
- { 1, host_row_pitch, host_slice_pitch },
- region));
+ obj, vector(obj_origin),
+ {{ 1, obj_row_pitch, obj_slice_pitch }},
+ ptr, vector(host_origin),
+ {{ 1, host_row_pitch, host_slice_pitch }},
+ vector(region)));
ret_object(ev, hev);
return CL_SUCCESS;
hard_event *hev = new hard_event(
*q, CL_COMMAND_COPY_BUFFER, { deps, deps + num_deps },
- hard_copy_op(q, dst_obj, { dst_offset },
- src_obj, { src_offset },
- { size, 1, 1 }));
+ hard_copy_op(q, dst_obj, {{ dst_offset }},
+ src_obj, {{ src_offset }},
+ {{ size, 1, 1 }}));
ret_object(ev, hev);
return CL_SUCCESS;
hard_event *hev = new hard_event(
*q, CL_COMMAND_COPY_BUFFER_RECT, { deps, deps + num_deps },
soft_copy_op(q,
- dst_obj, dst_origin,
- { 1, dst_row_pitch, dst_slice_pitch },
- src_obj, src_origin,
- { 1, src_row_pitch, src_slice_pitch },
- region));
+ dst_obj, vector(dst_origin),
+ {{ 1, dst_row_pitch, dst_slice_pitch }},
+ src_obj, vector(src_origin),
+ {{ 1, src_row_pitch, src_slice_pitch }},
+ vector(region)));
ret_object(ev, hev);
return CL_SUCCESS;
*q, CL_COMMAND_READ_IMAGE, { deps, deps + num_deps },
soft_copy_op(q,
ptr, {},
- { 1, row_pitch, slice_pitch },
- obj, origin,
- { 1, img->row_pitch(), img->slice_pitch() },
- region));
+ {{ 1, row_pitch, slice_pitch }},
+ obj, vector(origin),
+ {{ 1, img->row_pitch(), img->slice_pitch() }},
+ vector(region)));
ret_object(ev, hev);
return CL_SUCCESS;
hard_event *hev = new hard_event(
*q, CL_COMMAND_WRITE_IMAGE, { deps, deps + num_deps },
soft_copy_op(q,
- obj, origin,
- { 1, img->row_pitch(), img->slice_pitch() },
+ obj, vector(origin),
+ {{ 1, img->row_pitch(), img->slice_pitch() }},
ptr, {},
- { 1, row_pitch, slice_pitch },
- region));
+ {{ 1, row_pitch, slice_pitch }},
+ vector(region)));
ret_object(ev, hev);
return CL_SUCCESS;
hard_event *hev = new hard_event(
*q, CL_COMMAND_COPY_IMAGE, { deps, deps + num_deps },
- hard_copy_op(q, dst_obj, dst_origin, src_obj, src_origin, region));
+ hard_copy_op(q,
+ dst_obj, vector(dst_origin),
+ src_obj, vector(src_origin),
+ vector(region)));
ret_object(ev, hev);
return CL_SUCCESS;
hard_event *hev = new hard_event(
*q, CL_COMMAND_COPY_IMAGE_TO_BUFFER, { deps, deps + num_deps },
soft_copy_op(q,
- dst_obj, { dst_offset },
- { 0, 0, 0 },
- src_obj, src_origin,
- { 1, src_img->row_pitch(), src_img->slice_pitch() },
- region));
+ dst_obj, {{ dst_offset }},
+ {{ 0, 0, 0 }},
+ src_obj, vector(src_origin),
+ {{ 1, src_img->row_pitch(), src_img->slice_pitch() }},
+ vector(region)));
ret_object(ev, hev);
return CL_SUCCESS;
hard_event *hev = new hard_event(
*q, CL_COMMAND_COPY_BUFFER_TO_IMAGE, { deps, deps + num_deps },
soft_copy_op(q,
- dst_obj, dst_origin,
- { 1, dst_img->row_pitch(), dst_img->slice_pitch() },
- src_obj, { src_offset },
- { 0, 0, 0 },
- region));
+ dst_obj, vector(dst_origin),
+ {{ 1, dst_img->row_pitch(), dst_img->slice_pitch() }},
+ src_obj, {{ src_offset }},
+ {{ 0, 0, 0 }},
+ vector(region)));
ret_object(ev, hev);
return CL_SUCCESS;
throw error(CL_INVALID_VALUE);
void *map = obj->resource(q).add_map(
- *q, flags, blocking, { offset }, { size });
+ *q, flags, blocking, {{ offset }}, {{ size }});
ret_object(ev, new hard_event(*q, CL_COMMAND_MAP_BUFFER,
{ deps, deps + num_deps }));
validate_obj(q, img);
void *map = obj->resource(q).add_map(
- *q, flags, blocking, origin, region);
+ *q, flags, blocking, vector(origin), vector(region));
ret_object(ev, new hard_event(*q, CL_COMMAND_MAP_IMAGE,
{ deps, deps + num_deps }));
#include <map>
#include "core/base.hpp"
+#include "util/algorithm.hpp"
#include "pipe/p_compiler.h"
namespace clover {
if (buf)
for_each([](typename V::value_type src, T *dst) {
if (dst)
- std::copy(src.begin(), src.end(), dst);
+ copy(src, dst);
},
- v.begin(), v.end(), (T **)buf);
+ v, range((T **)buf, v.size()));
return CL_SUCCESS;
}
if (size_ret)
*size_ret = sizeof(T) * v.size();
if (buf)
- std::copy(v.begin(), v.end(), (T *)buf);
+ copy(v, (T *)buf);
return CL_SUCCESS;
}
#include <functional>
#include "CL/cl.h"
+#include "util/pointer.hpp"
///
/// Main namespace of the CL state tracker.
protected:
cl_int code;
};
-
- ///
- /// Base class for objects that support reference counting.
- ///
- class ref_counter {
- public:
- ref_counter() : _ref_count(1) {}
-
- unsigned ref_count() {
- return _ref_count;
- }
-
- void retain() {
- _ref_count++;
- }
-
- bool release() {
- return (--_ref_count) == 0;
- }
-
- private:
- std::atomic<unsigned> _ref_count;
- };
-
- ///
- /// Intrusive smart pointer for objects that implement the
- /// clover::ref_counter interface.
- ///
- template<typename T>
- class ref_ptr {
- public:
- ref_ptr(T *q = NULL) : p(NULL) {
- reset(q);
- }
-
- ref_ptr(const ref_ptr<T> &ref) : p(NULL) {
- reset(ref.p);
- }
-
- ~ref_ptr() {
- reset(NULL);
- }
-
- void reset(T *q = NULL) {
- if (q)
- q->retain();
- if (p && p->release())
- delete p;
- p = q;
- }
-
- ref_ptr &operator=(const ref_ptr &ref) {
- reset(ref.p);
- return *this;
- }
-
- T *operator*() const {
- return p;
- }
-
- T *operator->() const {
- return p;
- }
-
- operator bool() const {
- return p;
- }
-
- private:
- T *p;
- };
-
- ///
- /// Transfer the caller's ownership of a reference-counted object
- /// to a clover::ref_ptr smart pointer.
- ///
- template<typename T>
- inline ref_ptr<T>
- transfer(T *p) {
- ref_ptr<T> ref { p };
- p->release();
- return ref;
- }
-
- template<typename T, typename S, int N>
- struct _iter_helper {
- template<typename F, typename Its, typename... Args>
- static T
- step(F op, S state, Its its, Args... args) {
- return _iter_helper<T, S, N - 1>::step(
- op, state, its, *(std::get<N>(its)++), args...);
- }
- };
-
- template<typename T, typename S>
- struct _iter_helper<T, S, 0> {
- template<typename F, typename Its, typename... Args>
- static T
- step(F op, S state, Its its, Args... args) {
- return op(state, *(std::get<0>(its)++), args...);
- }
- };
-
- struct _empty {};
-
- template<typename T>
- struct _iter_helper<T, _empty, 0> {
- template<typename F, typename Its, typename... Args>
- static T
- step(F op, _empty state, Its its, Args... args) {
- return op(*(std::get<0>(its)++), args...);
- }
- };
-
- template<typename F, typename... Its>
- struct _result_helper {
- typedef typename std::remove_const<
- typename std::result_of<
- F (typename std::iterator_traits<Its>::value_type...)
- >::type
- >::type type;
- };
-
- ///
- /// Iterate \a op on the result of zipping all the specified
- /// iterators together.
- ///
- /// Similar to std::for_each, but it accepts functions of an
- /// arbitrary number of arguments.
- ///
- template<typename F, typename It0, typename... Its>
- F
- for_each(F op, It0 it0, It0 end0, Its... its) {
- while (it0 != end0)
- _iter_helper<void, _empty, sizeof...(Its)>::step(
- op, {}, std::tie(it0, its...));
-
- return op;
- }
-
- ///
- /// Iterate \a op on the result of zipping all the specified
- /// iterators together, storing return values in a new container.
- ///
- /// Similar to std::transform, but it accepts functions of an
- /// arbitrary number of arguments and it doesn't have to be
- /// provided with an output iterator.
- ///
- template<typename F, typename It0, typename... Its,
- typename C = std::vector<
- typename _result_helper<F, It0, Its...>::type>>
- C
- map(F op, It0 it0, It0 end0, Its... its) {
- C c;
-
- while (it0 != end0)
- c.push_back(
- _iter_helper<typename C::value_type, _empty, sizeof...(Its)>
- ::step(op, {}, std::tie(it0, its...)));
-
- return c;
- }
-
- ///
- /// Reduce the result of zipping all the specified iterators
- /// together, using iterative application of \a op from left to
- /// right.
- ///
- /// Similar to std::accumulate, but it accepts functions of an
- /// arbitrary number of arguments.
- ///
- template<typename F, typename T, typename It0, typename... Its>
- T
- fold(F op, T a, It0 it0, It0 end0, Its... its) {
- while (it0 != end0)
- a = _iter_helper<T, T, sizeof...(Its)>::step(
- op, a, std::tie(it0, its...));
-
- return a;
- }
-
- ///
- /// Iterate \a op on the result of zipping the specified iterators
- /// together, checking if any of the evaluations returns \a true.
- ///
- /// Similar to std::any_of, but it accepts functions of an
- /// arbitrary number of arguments.
- ///
- template<typename F, typename It0, typename... Its>
- bool
- any_of(F op, It0 it0, It0 end0, Its... its) {
- while (it0 != end0)
- if (_iter_helper<bool, _empty, sizeof...(Its)>::step(
- op, {}, std::tie(it0, its...)))
- return true;
-
- return false;
- }
-
- template<typename T, typename S>
- T
- keys(const std::pair<T, S> &ent) {
- return ent.first;
- }
-
- template<typename T, typename S>
- std::function<bool (const std::pair<T, S> &)>
- key_equals(const T &x) {
- return [=](const std::pair<T, S> &ent) {
- return ent.first == x;
- };
- }
-
- template<typename T, typename S>
- S
- values(const std::pair<T, S> &ent) {
- return ent.second;
- }
-
- template<typename T>
- bool
- is_zero(T x) {
- return x == 0;
- }
}
#endif
+++ /dev/null
-//
-// Copyright 2012 Francisco Jerez
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-// OTHER DEALINGS IN THE SOFTWARE.
-//
-
-#ifndef CLOVER_CORE_COMPAT_HPP
-#define CLOVER_CORE_COMPAT_HPP
-
-#include <new>
-#include <cstring>
-#include <cstdlib>
-#include <string>
-#include <stdint.h>
-
-
-namespace clover {
- namespace compat {
- // XXX - For cases where we can't rely on STL... I.e. the
- // interface between code compiled as C++98 and C++11
- // source. Get rid of this as soon as everything can be
- // compiled as C++11.
-
- template<typename T>
- class vector {
- protected:
- static T *
- alloc(int n, const T *q, int m) {
- T *p = reinterpret_cast<T *>(std::malloc(n * sizeof(T)));
-
- for (int i = 0; i < m; ++i)
- new(&p[i]) T(q[i]);
-
- return p;
- }
-
- static void
- free(int n, T *p) {
- for (int i = 0; i < n; ++i)
- p[i].~T();
-
- std::free(p);
- }
-
- public:
- vector() : p(NULL), n(0) {
- }
-
- vector(const vector &v) : p(alloc(v.n, v.p, v.n)), n(v.n) {
- }
-
- vector(T *p, size_t n) : p(alloc(n, p, n)), n(n) {
- }
-
- template<typename C>
- vector(const C &v) :
- p(alloc(v.size(), &*v.begin(), v.size())), n(v.size()) {
- }
-
- ~vector() {
- free(n, p);
- }
-
- vector &
- operator=(const vector &v) {
- free(n, p);
-
- p = alloc(v.n, v.p, v.n);
- n = v.n;
-
- return *this;
- }
-
- void
- reserve(size_t m) {
- if (n < m) {
- T *q = alloc(m, p, n);
- free(n, p);
-
- p = q;
- n = m;
- }
- }
-
- void
- resize(size_t m, T x = T()) {
- size_t n = size();
-
- reserve(m);
-
- for (size_t i = n; i < m; ++i)
- new(&p[i]) T(x);
- }
-
- void
- push_back(const T &x) {
- size_t n = size();
- reserve(n + 1);
- new(&p[n]) T(x);
- }
-
- size_t
- size() const {
- return n;
- }
-
- T *
- begin() {
- return p;
- }
-
- const T *
- begin() const {
- return p;
- }
-
- T *
- end() {
- return p + n;
- }
-
- const T *
- end() const {
- return p + n;
- }
-
- T &
- operator[](int i) {
- return p[i];
- }
-
- const T &
- operator[](int i) const {
- return p[i];
- }
-
- private:
- T *p;
- size_t n;
- };
-
- template<typename T>
- class vector_ref {
- public:
- vector_ref(T *p, size_t n) : p(p), n(n) {
- }
-
- template<typename C>
- vector_ref(C &v) : p(&*v.begin()), n(v.size()) {
- }
-
- size_t
- size() const {
- return n;
- }
-
- T *
- begin() {
- return p;
- }
-
- const T *
- begin() const {
- return p;
- }
-
- T *
- end() {
- return p + n;
- }
-
- const T *
- end() const {
- return p + n;
- }
-
- T &
- operator[](int i) {
- return p[i];
- }
-
- const T &
- operator[](int i) const {
- return p[i];
- }
-
- private:
- T *p;
- size_t n;
- };
-
- class istream {
- public:
- typedef vector_ref<const unsigned char> buffer_t;
-
- class error {
- public:
- virtual ~error() {}
- };
-
- istream(const buffer_t &buf) : buf(buf), offset(0) {}
-
- void
- read(char *p, size_t n) {
- if (offset + n > buf.size())
- throw error();
-
- std::memcpy(p, buf.begin() + offset, n);
- offset += n;
- }
-
- private:
- const buffer_t &buf;
- size_t offset;
- };
-
- class ostream {
- public:
- typedef vector<unsigned char> buffer_t;
-
- ostream(buffer_t &buf) : buf(buf), offset(buf.size()) {}
-
- void
- write(const char *p, size_t n) {
- buf.resize(offset + n);
- std::memcpy(buf.begin() + offset, p, n);
- offset += n;
- }
-
- private:
- buffer_t &buf;
- size_t offset;
- };
-
- class string : public vector_ref<const char> {
- public:
- string(const char *p) : vector_ref(p, std::strlen(p)) {
- }
-
- template<typename C>
- string(const C &v) : vector_ref(v) {
- }
-
- operator std::string() const {
- return std::string(begin(), end());
- }
-
- const char *
- find(const string &s) const {
- for (size_t i = 0; i + s.size() < size(); ++i) {
- if (!std::memcmp(begin() + i, s.begin(), s.size()))
- return begin() + i;
- }
-
- return end();
- }
- };
-
- template<typename T>
- bool
- operator==(const vector_ref<T> &a, const vector_ref<T> &b) {
- if (a.size() != b.size())
- return false;
-
- for (size_t i = 0; i < a.size(); ++i)
- if (a[i] != b[i])
- return false;
-
- return true;
- }
- }
-}
-
-#endif
#ifndef CLOVER_CORE_COMPILER_HPP
#define CLOVER_CORE_COMPILER_HPP
-#include "core/compat.hpp"
+#include "util/compat.hpp"
#include "core/module.hpp"
#include "pipe/p_defines.h"
//
#include "core/event.hpp"
+#include "util/algorithm.hpp"
#include "pipe/p_screen.h"
using namespace clover;
else if (!signalled() ||
any_of([](const ref_ptr<event> &ev) {
return ev->status() != CL_COMPLETE;
- }, deps.begin(), deps.end()))
+ }, deps))
return CL_SUBMITTED;
else
+++ /dev/null
-//
-// Copyright 2012 Francisco Jerez
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the "Software"),
-// to deal in the Software without restriction, including without limitation
-// the rights to use, copy, modify, merge, publish, distribute, sublicense,
-// and/or sell copies of the Software, and to permit persons to whom the
-// Software is furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in
-// all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
-// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
-// OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
-// ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-// OTHER DEALINGS IN THE SOFTWARE.
-//
-
-#ifndef CLOVER_CORE_GEOMETRY_HPP
-#define CLOVER_CORE_GEOMETRY_HPP
-
-#include <array>
-#include <algorithm>
-
-namespace clover {
- ///
- /// N-dimensional coordinate array.
- ///
- template<typename T, int N>
- class point {
- public:
- point() : a() {
- }
-
- point(std::initializer_list<T> v) {
- auto it = std::copy(v.begin(), v.end(), a.begin());
- std::fill(it, a.end(), 0);
- }
-
- point(const T *v) {
- std::copy(v, v + N, a.begin());
- }
-
- T &operator[](int i) {
- return a[i];
- }
-
- const T &operator[](int i) const {
- return a[i];
- }
-
- point operator+(const point &p) const {
- point q;
- std::transform(a.begin(), a.end(), p.a.begin(),
- q.a.begin(), std::plus<T>());
- return q;
- }
-
- T operator()(const point &p) const {
- return std::inner_product(p.a.begin(), p.a.end(), a.begin(), 0);
- }
-
- protected:
- std::array<T, N> a;
- };
-}
-
-#endif
#include "core/kernel.hpp"
#include "core/resource.hpp"
+#include "util/algorithm.hpp"
#include "util/u_math.h"
#include "pipe/p_context.h"
const std::vector<size_t> &grid_size,
const std::vector<size_t> &block_size) {
void *st = exec.bind(&q);
- auto g_handles = map([&](size_t h) { return (uint32_t *)&exec.input[h]; },
- exec.g_handles.begin(), exec.g_handles.end());
+ std::vector<uint32_t *> g_handles = map([&](size_t h) {
+ return (uint32_t *)&exec.input[h];
+ }, exec.g_handles);
q.pipe->bind_compute_state(q.pipe, st);
q.pipe->bind_sampler_states(q.pipe, PIPE_SHADER_COMPUTE,
for_each([=](std::unique_ptr<kernel::argument> &karg,
const module::argument &marg) {
karg->bind(*this, marg);
- }, kern.args.begin(), kern.args.end(), margs.begin());
+ }, kern.args, margs);
// Create a new compute state if anything changed.
if (!st || q != _q ||
sub_buffer::resource(cl_command_queue q) {
// Create a new resource if there's none for this device yet.
if (!resources.count(&q->dev)) {
- auto r = new sub_resource(parent.resource(q), { offset() });
+ auto r = new sub_resource(parent.resource(q), {{ offset() }});
resources.insert(std::make_pair(&q->dev,
std::unique_ptr<sub_resource>(r)));
#ifndef CLOVER_CORE_MODULE_HPP
#define CLOVER_CORE_MODULE_HPP
-#include "core/compat.hpp"
+#include "util/compat.hpp"
namespace clover {
struct module {
#include "core/program.hpp"
#include "core/compiler.hpp"
+#include "util/algorithm.hpp"
using namespace clover;
for_each([&](clover::device *dev, const clover::module &bin) {
_binaries.insert({ dev, bin });
},
- devs.begin(), devs.end(), binaries.begin());
+ devs, binaries);
}
void
//
#include "core/resource.hpp"
+#include "util/algorithm.hpp"
#include "pipe/p_screen.h"
#include "util/u_sampler.h"
#include "util/u_format.h"
namespace {
class box {
public:
- box(const resource::point &origin, const resource::point &size) :
+ box(const resource::vector &origin, const resource::vector &size) :
pipe({ (int)origin[0], (int)origin[1],
(int)origin[2], (int)size[0],
(int)size[1], (int)size[2] }) {
}
resource::resource(clover::device &dev, clover::memory_obj &obj) :
- dev(dev), obj(obj), pipe(NULL), offset{0} {
+ dev(dev), obj(obj), pipe(NULL), offset() {
}
resource::~resource() {
}
void
-resource::copy(command_queue &q, const point &origin, const point ®ion,
- resource &src_res, const point &src_origin) {
- point p = offset + origin;
+resource::copy(command_queue &q, const vector &origin, const vector ®ion,
+ resource &src_res, const vector &src_origin) {
+ auto p = offset + origin;
q.pipe->resource_copy_region(q.pipe, pipe, 0, p[0], p[1], p[2],
src_res.pipe, 0,
void *
resource::add_map(command_queue &q, cl_map_flags flags, bool blocking,
- const point &origin, const point ®ion) {
+ const vector &origin, const vector ®ion) {
maps.emplace_back(q, *this, flags, blocking, origin, region);
return maps.back();
}
void
resource::del_map(void *p) {
- auto it = std::find(maps.begin(), maps.end(), p);
- if (it != maps.end())
- maps.erase(it);
+ erase_if([&](mapping &m) {
+ return static_cast<void *>(m) == p;
+ }, maps);
}
unsigned
throw error(CL_OUT_OF_RESOURCES);
if (!data.empty()) {
- box rect { { 0, 0, 0 }, { info.width0, info.height0, info.depth0 } };
+ box rect { {{ 0, 0, 0 }}, {{ info.width0, info.height0, info.depth0 }} };
unsigned cpp = util_format_get_blocksize(info.format);
q.pipe->transfer_inline_write(q.pipe, pipe, 0, PIPE_TRANSFER_WRITE,
dev.pipe->resource_destroy(dev.pipe, pipe);
}
-sub_resource::sub_resource(clover::resource &r, point offset) :
+sub_resource::sub_resource(resource &r, const vector &offset) :
resource(r.dev, r.obj) {
- pipe = r.pipe;
- offset = r.offset + offset;
+ this->pipe = r.pipe;
+ this->offset = r.offset + offset;
}
mapping::mapping(command_queue &q, resource &r,
cl_map_flags flags, bool blocking,
- const resource::point &origin,
- const resource::point ®ion) :
+ const resource::vector &origin,
+ const resource::vector ®ion) :
pctx(q.pipe) {
unsigned usage = ((flags & CL_MAP_WRITE ? PIPE_TRANSFER_WRITE : 0 ) |
(flags & CL_MAP_READ ? PIPE_TRANSFER_READ : 0 ) |
pctx->transfer_unmap(pctx, pxfer);
}
}
+
+mapping &
+mapping::operator=(mapping m) {
+ std::swap(pctx, m.pctx);
+ std::swap(pxfer, m.pxfer);
+ std::swap(p, m.p);
+ return *this;
+}
#include "core/base.hpp"
#include "core/memory.hpp"
-#include "core/geometry.hpp"
+#include "util/algebra.hpp"
#include "pipe/p_state.h"
namespace clover {
///
class resource {
public:
- typedef clover::point<size_t, 3> point;
+ typedef std::array<size_t, 3> vector;
resource(const resource &r) = delete;
virtual ~resource();
- void copy(command_queue &q, const point &origin, const point ®ion,
- resource &src_resource, const point &src_origin);
+ void copy(command_queue &q, const vector &origin, const vector ®ion,
+ resource &src_resource, const vector &src_origin);
void *add_map(command_queue &q, cl_map_flags flags, bool blocking,
- const point &origin, const point ®ion);
+ const vector &origin, const vector ®ion);
void del_map(void *p);
unsigned map_count() const;
void unbind_surface(clover::command_queue &q, pipe_surface *st);
pipe_resource *pipe;
- point offset;
+ vector offset;
private:
std::list<mapping> maps;
///
class sub_resource : public resource {
public:
- sub_resource(clover::resource &r, point offset);
+ sub_resource(clover::resource &r, const vector &offset);
};
///
class mapping {
public:
mapping(command_queue &q, resource &r, cl_map_flags flags,
- bool blocking, const resource::point &origin,
- const resource::point ®ion);
+ bool blocking, const resource::vector &origin,
+ const resource::vector ®ion);
mapping(const mapping &m) = delete;
mapping(mapping &&m);
~mapping();
+ mapping &
+ operator=(mapping m);
+
operator void *() {
return p;
}