diff options
author | Francisco Jerez <[email protected]> | 2013-10-06 13:49:05 -0700 |
---|---|---|
committer | Francisco Jerez <[email protected]> | 2013-10-21 10:47:02 -0700 |
commit | 7d61769e447e47022bea5e9fd415344b45a5a050 (patch) | |
tree | da8e1ad5f6af1f326a8f8f1cf0711c0a2a0057fc | |
parent | 099d281b38fae791300984964fab1124b0eb14d2 (diff) |
clover: Switch to the new utility code.
Tested-by: Tom Stellard <[email protected]>
17 files changed, 152 insertions, 717 deletions
diff --git a/src/gallium/state_trackers/clover/Makefile.sources b/src/gallium/state_trackers/clover/Makefile.sources index df1b270fbde..daa50918346 100644 --- a/src/gallium/state_trackers/clover/Makefile.sources +++ b/src/gallium/state_trackers/clover/Makefile.sources @@ -9,8 +9,6 @@ CPP_SOURCES := \ util/pointer.hpp \ util/range.hpp \ util/tuple.hpp \ - core/base.hpp \ - core/compat.hpp \ core/compiler.hpp \ core/geometry.hpp \ core/device.hpp \ diff --git a/src/gallium/state_trackers/clover/api/context.cpp b/src/gallium/state_trackers/clover/api/context.cpp index 371744120ee..8586b3ece25 100644 --- a/src/gallium/state_trackers/clover/api/context.cpp +++ b/src/gallium/state_trackers/clover/api/context.cpp @@ -37,7 +37,7 @@ clCreateContext(const cl_context_properties *props, cl_uint num_devs, (!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) { diff --git a/src/gallium/state_trackers/clover/api/kernel.cpp b/src/gallium/state_trackers/clover/api/kernel.cpp index 13113a22b8e..24b17b6eb3b 100644 --- a/src/gallium/state_trackers/clover/api/kernel.cpp +++ b/src/gallium/state_trackers/clover/api/kernel.cpp @@ -202,16 +202,16 @@ namespace { 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)) @@ -220,23 +220,21 @@ namespace { 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); } @@ -250,9 +248,8 @@ namespace { 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); diff --git a/src/gallium/state_trackers/clover/api/program.cpp b/src/gallium/state_trackers/clover/api/program.cpp index 6e5ca08d76b..2ef3a2eced4 100644 --- a/src/gallium/state_trackers/clover/api/program.cpp +++ b/src/gallium/state_trackers/clover/api/program.cpp @@ -35,7 +35,7 @@ clCreateProgramWithSource(cl_context ctx, cl_uint count, 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 @@ -66,7 +66,7 @@ clCreateProgramWithBinary(cl_context ctx, cl_uint count, 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, @@ -85,26 +85,23 @@ clCreateProgramWithBinary(cl_context ctx, cl_uint count, 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); @@ -148,7 +145,7 @@ clBuildProgram(cl_program prog, cl_uint count, const cl_device_id *devs, 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); @@ -189,8 +186,7 @@ clGetProgramInfo(cl_program prog, cl_program_info param, 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()); @@ -204,7 +200,7 @@ clGetProgramInfo(cl_program prog, cl_program_info param, ent.second.serialize(s); return bin.size(); }, - prog->binaries().begin(), prog->binaries().end())); + prog->binaries())); case CL_PROGRAM_BINARIES: return matrix_property<unsigned char>( @@ -215,7 +211,7 @@ clGetProgramInfo(cl_program prog, cl_program_info param, ent.second.serialize(s); return bin; }, - prog->binaries().begin(), prog->binaries().end())); + prog->binaries())); default: return CL_INVALID_VALUE; diff --git a/src/gallium/state_trackers/clover/api/transfer.cpp b/src/gallium/state_trackers/clover/api/transfer.cpp index 43036da528d..d2aae67bebe 100644 --- a/src/gallium/state_trackers/clover/api/transfer.cpp +++ b/src/gallium/state_trackers/clover/api/transfer.cpp @@ -29,7 +29,12 @@ 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. @@ -40,12 +45,12 @@ namespace { 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); } @@ -89,7 +94,8 @@ namespace { 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 }}}; } }; @@ -100,21 +106,24 @@ namespace { 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]); } } }; @@ -125,8 +134,8 @@ namespace { /// 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); @@ -148,9 +157,9 @@ clEnqueueReadBuffer(cl_command_queue q, cl_mem obj, cl_bool blocking, 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; @@ -173,9 +182,9 @@ clEnqueueWriteBuffer(cl_command_queue q, cl_mem obj, cl_bool blocking, 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; @@ -202,11 +211,11 @@ clEnqueueReadBufferRect(cl_command_queue q, cl_mem obj, cl_bool blocking, 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; @@ -233,11 +242,11 @@ clEnqueueWriteBufferRect(cl_command_queue q, cl_mem obj, cl_bool blocking, 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; @@ -257,9 +266,9 @@ clEnqueueCopyBuffer(cl_command_queue q, cl_mem src_obj, cl_mem dst_obj, 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; @@ -283,11 +292,11 @@ clEnqueueCopyBufferRect(cl_command_queue q, cl_mem src_obj, cl_mem dst_obj, 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; @@ -314,10 +323,10 @@ clEnqueueReadImage(cl_command_queue q, cl_mem obj, cl_bool blocking, *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; @@ -343,11 +352,11 @@ clEnqueueWriteImage(cl_command_queue q, cl_mem obj, cl_bool blocking, 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; @@ -371,7 +380,10 @@ clEnqueueCopyImage(cl_command_queue q, cl_mem src_obj, cl_mem dst_obj, 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; @@ -395,11 +407,11 @@ clEnqueueCopyImageToBuffer(cl_command_queue q, cl_mem src_obj, cl_mem dst_obj, 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; @@ -423,11 +435,11 @@ clEnqueueCopyBufferToImage(cl_command_queue q, cl_mem src_obj, cl_mem dst_obj, 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; @@ -448,7 +460,7 @@ clEnqueueMapBuffer(cl_command_queue q, cl_mem obj, cl_bool blocking, 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 })); @@ -473,7 +485,7 @@ clEnqueueMapImage(cl_command_queue q, cl_mem obj, cl_bool blocking, 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 })); diff --git a/src/gallium/state_trackers/clover/api/util.hpp b/src/gallium/state_trackers/clover/api/util.hpp index f4febb3c529..d9d9b7a73cb 100644 --- a/src/gallium/state_trackers/clover/api/util.hpp +++ b/src/gallium/state_trackers/clover/api/util.hpp @@ -29,6 +29,7 @@ #include <map> #include "core/base.hpp" +#include "util/algorithm.hpp" #include "pipe/p_compiler.h" namespace clover { @@ -49,9 +50,9 @@ 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; } @@ -69,7 +70,7 @@ namespace clover { 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; } diff --git a/src/gallium/state_trackers/clover/core/base.hpp b/src/gallium/state_trackers/clover/core/base.hpp index 6377ea0d5a6..ca42334891c 100644 --- a/src/gallium/state_trackers/clover/core/base.hpp +++ b/src/gallium/state_trackers/clover/core/base.hpp @@ -31,6 +31,7 @@ #include <functional> #include "CL/cl.h" +#include "util/pointer.hpp" /// /// Main namespace of the CL state tracker. @@ -53,230 +54,6 @@ namespace clover { 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 diff --git a/src/gallium/state_trackers/clover/core/compat.hpp b/src/gallium/state_trackers/clover/core/compat.hpp deleted file mode 100644 index d4977c1ff58..00000000000 --- a/src/gallium/state_trackers/clover/core/compat.hpp +++ /dev/null @@ -1,290 +0,0 @@ -// -// 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 diff --git a/src/gallium/state_trackers/clover/core/compiler.hpp b/src/gallium/state_trackers/clover/core/compiler.hpp index 80846beef2b..5edb056ec59 100644 --- a/src/gallium/state_trackers/clover/core/compiler.hpp +++ b/src/gallium/state_trackers/clover/core/compiler.hpp @@ -23,7 +23,7 @@ #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" diff --git a/src/gallium/state_trackers/clover/core/event.cpp b/src/gallium/state_trackers/clover/core/event.cpp index ce9eda37419..c94727a6371 100644 --- a/src/gallium/state_trackers/clover/core/event.cpp +++ b/src/gallium/state_trackers/clover/core/event.cpp @@ -21,6 +21,7 @@ // #include "core/event.hpp" +#include "util/algorithm.hpp" #include "pipe/p_screen.h" using namespace clover; @@ -190,7 +191,7 @@ soft_event::status() const { else if (!signalled() || any_of([](const ref_ptr<event> &ev) { return ev->status() != CL_COMPLETE; - }, deps.begin(), deps.end())) + }, deps)) return CL_SUBMITTED; else diff --git a/src/gallium/state_trackers/clover/core/geometry.hpp b/src/gallium/state_trackers/clover/core/geometry.hpp deleted file mode 100644 index 0c4ed9bae34..00000000000 --- a/src/gallium/state_trackers/clover/core/geometry.hpp +++ /dev/null @@ -1,72 +0,0 @@ -// -// 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 diff --git a/src/gallium/state_trackers/clover/core/kernel.cpp b/src/gallium/state_trackers/clover/core/kernel.cpp index 6b949dd17ef..1a75cd48a00 100644 --- a/src/gallium/state_trackers/clover/core/kernel.cpp +++ b/src/gallium/state_trackers/clover/core/kernel.cpp @@ -22,6 +22,7 @@ #include "core/kernel.hpp" #include "core/resource.hpp" +#include "util/algorithm.hpp" #include "util/u_math.h" #include "pipe/p_context.h" @@ -67,8 +68,9 @@ _cl_kernel::launch(clover::command_queue &q, 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, @@ -151,7 +153,7 @@ _cl_kernel::exec_context::bind(clover::command_queue *_q) { 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 || diff --git a/src/gallium/state_trackers/clover/core/memory.cpp b/src/gallium/state_trackers/clover/core/memory.cpp index 863a4175415..742e3d3106a 100644 --- a/src/gallium/state_trackers/clover/core/memory.cpp +++ b/src/gallium/state_trackers/clover/core/memory.cpp @@ -100,7 +100,7 @@ clover::resource & 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))); diff --git a/src/gallium/state_trackers/clover/core/module.hpp b/src/gallium/state_trackers/clover/core/module.hpp index 33808ed5005..03b8d3a0b03 100644 --- a/src/gallium/state_trackers/clover/core/module.hpp +++ b/src/gallium/state_trackers/clover/core/module.hpp @@ -23,7 +23,7 @@ #ifndef CLOVER_CORE_MODULE_HPP #define CLOVER_CORE_MODULE_HPP -#include "core/compat.hpp" +#include "util/compat.hpp" namespace clover { struct module { diff --git a/src/gallium/state_trackers/clover/core/program.cpp b/src/gallium/state_trackers/clover/core/program.cpp index 219a1e066f4..8cf1337f7ac 100644 --- a/src/gallium/state_trackers/clover/core/program.cpp +++ b/src/gallium/state_trackers/clover/core/program.cpp @@ -22,6 +22,7 @@ #include "core/program.hpp" #include "core/compiler.hpp" +#include "util/algorithm.hpp" using namespace clover; @@ -37,7 +38,7 @@ _cl_program::_cl_program(clover::context &ctx, for_each([&](clover::device *dev, const clover::module &bin) { _binaries.insert({ dev, bin }); }, - devs.begin(), devs.end(), binaries.begin()); + devs, binaries); } void diff --git a/src/gallium/state_trackers/clover/core/resource.cpp b/src/gallium/state_trackers/clover/core/resource.cpp index 3b003e9e927..2121268cd8f 100644 --- a/src/gallium/state_trackers/clover/core/resource.cpp +++ b/src/gallium/state_trackers/clover/core/resource.cpp @@ -21,6 +21,7 @@ // #include "core/resource.hpp" +#include "util/algorithm.hpp" #include "pipe/p_screen.h" #include "util/u_sampler.h" #include "util/u_format.h" @@ -30,7 +31,7 @@ using namespace clover; 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] }) { @@ -46,16 +47,16 @@ namespace { } 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, @@ -64,16 +65,16 @@ resource::copy(command_queue &q, const point &origin, const point ®ion, 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 @@ -142,7 +143,7 @@ root_resource::root_resource(clover::device &dev, clover::memory_obj &obj, 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, @@ -161,16 +162,16 @@ root_resource::~root_resource() { 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 ) | @@ -195,3 +196,11 @@ mapping::~mapping() { 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; +} diff --git a/src/gallium/state_trackers/clover/core/resource.hpp b/src/gallium/state_trackers/clover/core/resource.hpp index 73663a3d6c6..90a68d099ac 100644 --- a/src/gallium/state_trackers/clover/core/resource.hpp +++ b/src/gallium/state_trackers/clover/core/resource.hpp @@ -27,7 +27,7 @@ #include "core/base.hpp" #include "core/memory.hpp" -#include "core/geometry.hpp" +#include "util/algebra.hpp" #include "pipe/p_state.h" namespace clover { @@ -39,16 +39,16 @@ 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; @@ -70,7 +70,7 @@ namespace clover { void unbind_surface(clover::command_queue &q, pipe_surface *st); pipe_resource *pipe; - point offset; + vector offset; private: std::list<mapping> maps; @@ -95,7 +95,7 @@ namespace clover { /// class sub_resource : public resource { public: - sub_resource(clover::resource &r, point offset); + sub_resource(clover::resource &r, const vector &offset); }; /// @@ -105,12 +105,15 @@ namespace clover { 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; } |