|
|
@ -13,64 +13,71 @@ |
|
|
|
#include <cassert> |
|
|
|
#include <iostream> |
|
|
|
|
|
|
|
// debugging tool
|
|
|
|
static void check(cl_int err){ |
|
|
|
assert(err == CL_SUCCESS); |
|
|
|
namespace cl { |
|
|
|
// debugging tool
|
|
|
|
inline void checky(cl_int err){ |
|
|
|
assert(err == CL_SUCCESS); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// simple variadic wrapper for kernels/arguments (1D)
|
|
|
|
struct KernelOp{ |
|
|
|
KernelOp(const cl::Program& program, const char* name, cl_int* err) |
|
|
|
: kernel(program, name, err) |
|
|
|
{} |
|
|
|
|
|
|
|
template <typename... Args> |
|
|
|
cl_int operator()(cl::CommandQueue & queue, size_t W, size_t H, Args&&... args){ |
|
|
|
return apply(queue, W, H, 0, std::forward<Args>(args)...); |
|
|
|
} |
|
|
|
|
|
|
|
KernelOp(const cl::Program& program, const char* name, cl_int* err = nullptr) |
|
|
|
: kernel(program, name, err) |
|
|
|
{} |
|
|
|
|
|
|
|
template <typename... Args> |
|
|
|
cl_int operator()(cl::CommandQueue & queue, size_t W, Args&&... args){ |
|
|
|
return apply(queue, W, 0, std::forward<Args>(args)...); |
|
|
|
} |
|
|
|
|
|
|
|
private: |
|
|
|
cl::Kernel kernel; |
|
|
|
|
|
|
|
template <typename T, typename... Args> |
|
|
|
cl_int apply(cl::CommandQueue & queue, size_t W, size_t H, cl_uint n, T&& t, Args&&... args){ |
|
|
|
check(kernel.setArg(n, t)); |
|
|
|
return apply(queue, W, H, n+1, std::forward<Args>(args)...); |
|
|
|
} |
|
|
|
|
|
|
|
cl_int apply(cl::CommandQueue & queue, size_t W, size_t H, size_t){ |
|
|
|
return queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(W, H), cl::NullRange); |
|
|
|
} |
|
|
|
cl::Kernel kernel; |
|
|
|
|
|
|
|
template <typename T, typename... Args> |
|
|
|
cl_int apply(cl::CommandQueue & queue, size_t W, cl_uint n, T&& t, Args&&... args){ |
|
|
|
cl::checky(kernel.setArg(n, t)); |
|
|
|
return apply(queue, W, n+1, std::forward<Args>(args)...); |
|
|
|
} |
|
|
|
|
|
|
|
cl_int apply(cl::CommandQueue & queue, size_t W, size_t){ |
|
|
|
return queue.enqueueNDRangeKernel(kernel, cl::NullRange, cl::NDRange(W)); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
// We need to put the op<<'s in namespace cl (ADL)
|
|
|
|
namespace cl { |
|
|
|
std::ostream& operator<<(std::ostream& out, Platform const & platform){ |
|
|
|
return out << platform.getInfo<CL_PLATFORM_NAME>() << ", " << platform.getInfo<CL_PLATFORM_VERSION>(); |
|
|
|
} |
|
|
|
|
|
|
|
std::ostream& operator<<(std::ostream& out, Device const & device){ |
|
|
|
out << device.getInfo<CL_DEVICE_NAME>() << ", " << device.getInfo<CL_DEVICE_VERSION>() << ", " << device.getInfo<CL_DRIVER_VERSION>(); |
|
|
|
return out; |
|
|
|
} |
|
|
|
|
|
|
|
std::ostream& operator<<(std::ostream& out, Context const & context){ |
|
|
|
Platform p; |
|
|
|
context.getInfo(CL_CONTEXT_PLATFORM, &p); |
|
|
|
out << "Platform:\t" << p << '\n'; |
|
|
|
|
|
|
|
auto devices = context.getInfo<CL_CONTEXT_DEVICES>(); |
|
|
|
out << "Number of devices:\t" << devices.size() << '\n'; |
|
|
|
int i = 0; |
|
|
|
for(auto&& d : devices){ |
|
|
|
out << ++i << "\t" << d << '\n'; |
|
|
|
} |
|
|
|
return out; |
|
|
|
} |
|
|
|
|
|
|
|
std::ostream& operator<<(std::ostream& out, Program const & program){ |
|
|
|
return out << "Kernels in program:\t" << program.getInfo<CL_PROGRAM_KERNEL_NAMES>(); |
|
|
|
} |
|
|
|
inline std::ostream& operator<<(std::ostream& out, Platform const & platform){ |
|
|
|
return out << platform.getInfo<CL_PLATFORM_NAME>() << ", " << platform.getInfo<CL_PLATFORM_VERSION>(); |
|
|
|
} |
|
|
|
|
|
|
|
inline std::ostream& operator<<(std::ostream& out, Device const & device){ |
|
|
|
out << device.getInfo<CL_DEVICE_NAME>() << ", " << device.getInfo<CL_DEVICE_VERSION>() << ", " << device.getInfo<CL_DRIVER_VERSION>(); |
|
|
|
return out; |
|
|
|
} |
|
|
|
|
|
|
|
inline std::ostream& operator<<(std::ostream& out, Context const & context){ |
|
|
|
Platform p; |
|
|
|
context.getInfo(CL_CONTEXT_PLATFORM, &p); |
|
|
|
out << "Platform:\t" << p << '\n'; |
|
|
|
|
|
|
|
auto devices = context.getInfo<CL_CONTEXT_DEVICES>(); |
|
|
|
out << "Number of devices:\t" << devices.size() << '\n'; |
|
|
|
int i = 0; |
|
|
|
for(auto&& d : devices){ |
|
|
|
out << ++i << "\t" << d << '\n'; |
|
|
|
} |
|
|
|
return out; |
|
|
|
} |
|
|
|
|
|
|
|
inline std::ostream& operator<<(std::ostream& out, Program const & program){ |
|
|
|
return out << "Kernels in program:\t" << program.getInfo<CL_PROGRAM_KERNEL_NAMES>(); |
|
|
|
} |
|
|
|
|
|
|
|
inline std::ostream& operator<<(std::ostream& out, Image const & image){ |
|
|
|
out << "Image: " << image.getImageInfo<CL_IMAGE_WIDTH>() << "x" << image.getImageInfo<CL_IMAGE_HEIGHT>(); |
|
|
|
return out << " elements: " << image.getImageInfo<CL_IMAGE_ELEMENT_SIZE>() << " pitch: " << image.getImageInfo<CL_IMAGE_ROW_PITCH>(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
#endif |
|
|
|