121 lines
2.6 KiB
C++
121 lines
2.6 KiB
C++
|
|
#ifndef _USER_COMPUTE_H
|
||
|
|
#define _USER_COMPUTE_H
|
||
|
|
|
||
|
|
#include <memory>
|
||
|
|
#include <vector>
|
||
|
|
#define CL_TARGET_OPENCL_VERSION 120
|
||
|
|
#include <CL/cl.h>
|
||
|
|
|
||
|
|
namespace smo {
|
||
|
|
namespace compute {
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief OpenCL compute device information
|
||
|
|
*
|
||
|
|
* Manages a single OpenCL device, creating and owning its context and command
|
||
|
|
* queue.
|
||
|
|
*/
|
||
|
|
class ComputeDevice
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
/**
|
||
|
|
* @brief Construct a ComputeDevice from platform and device IDs
|
||
|
|
*
|
||
|
|
* Creates the OpenCL context and command queue for the device.
|
||
|
|
* Throws std::runtime_error if context or queue creation fails.
|
||
|
|
*
|
||
|
|
* @param platformId OpenCL platform ID
|
||
|
|
* @param deviceId OpenCL device ID
|
||
|
|
*/
|
||
|
|
ComputeDevice(cl_platform_id platformId, cl_device_id deviceId);
|
||
|
|
|
||
|
|
~ComputeDevice()
|
||
|
|
{
|
||
|
|
if (commandQueue)
|
||
|
|
{
|
||
|
|
clReleaseCommandQueue(commandQueue);
|
||
|
|
commandQueue = nullptr;
|
||
|
|
}
|
||
|
|
if (context)
|
||
|
|
{
|
||
|
|
clReleaseContext(context);
|
||
|
|
context = nullptr;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Non-copyable
|
||
|
|
ComputeDevice(const ComputeDevice&) = delete;
|
||
|
|
ComputeDevice& operator=(const ComputeDevice&) = delete;
|
||
|
|
|
||
|
|
cl_platform_id platform;
|
||
|
|
cl_device_id device;
|
||
|
|
cl_context context;
|
||
|
|
cl_command_queue commandQueue;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief Association between an OpenCL buffer and a compute device
|
||
|
|
*/
|
||
|
|
struct ClBufferDeviceAssociation
|
||
|
|
{
|
||
|
|
ClBufferDeviceAssociation(
|
||
|
|
cl_mem buf, const std::shared_ptr<ComputeDevice>& dev)
|
||
|
|
: buffer(buf), device(dev)
|
||
|
|
{}
|
||
|
|
|
||
|
|
cl_mem buffer;
|
||
|
|
std::shared_ptr<ComputeDevice> device;
|
||
|
|
};
|
||
|
|
|
||
|
|
/**
|
||
|
|
* @brief OpenCL buffer created on all compute devices
|
||
|
|
*
|
||
|
|
* Manages a USE_HOST_PTR buffer created on all available compute devices.
|
||
|
|
* The constructor creates buffers for all devices, and the destructor releases
|
||
|
|
* them.
|
||
|
|
*/
|
||
|
|
class ClBuffer
|
||
|
|
{
|
||
|
|
public:
|
||
|
|
/**
|
||
|
|
* @brief Construct a ClBuffer and create buffers on all devices
|
||
|
|
*
|
||
|
|
* Creates a USE_HOST_PTR buffer on each device's context.
|
||
|
|
* Throws std::runtime_error if buffer creation fails for any device.
|
||
|
|
*
|
||
|
|
* @param hostPtr Host pointer to use
|
||
|
|
* @param size Size of buffer in bytes
|
||
|
|
* @param flags Additional OpenCL memory flags
|
||
|
|
* @param devices Vector of compute devices to create buffers on
|
||
|
|
*/
|
||
|
|
ClBuffer(
|
||
|
|
void* hostPtr, size_t size, cl_mem_flags flags,
|
||
|
|
const std::vector<std::shared_ptr<ComputeDevice>>& devices);
|
||
|
|
|
||
|
|
~ClBuffer()
|
||
|
|
{
|
||
|
|
for (auto& assoc : associations)
|
||
|
|
{
|
||
|
|
if (assoc.buffer)
|
||
|
|
{
|
||
|
|
clReleaseMemObject(assoc.buffer);
|
||
|
|
assoc.buffer = nullptr;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// Non-copyable
|
||
|
|
ClBuffer(const ClBuffer&) = delete;
|
||
|
|
ClBuffer& operator=(const ClBuffer&) = delete;
|
||
|
|
|
||
|
|
void* hostPtr;
|
||
|
|
size_t size;
|
||
|
|
cl_mem_flags flags;
|
||
|
|
std::vector<ClBufferDeviceAssociation> associations;
|
||
|
|
};
|
||
|
|
|
||
|
|
} // namespace compute
|
||
|
|
} // namespace smo
|
||
|
|
|
||
|
|
#endif // _USER_COMPUTE_H
|