From 513d6238f12fdf208edc75465dca72ac056c4899 Mon Sep 17 00:00:00 2001 From: Denis Steckelmacher Date: Sun, 7 Aug 2011 16:07:42 +0200 Subject: Add an object tree to Clover This will allow me to implement the samplers and to add sanity checks in the API files. --- src/api/api_enqueue.cpp | 5 ++++ src/api/api_program.cpp | 2 +- src/core/commandqueue.cpp | 55 ++++++++++------------------------- src/core/commandqueue.h | 10 ++----- src/core/context.cpp | 5 ++-- src/core/context.h | 4 +-- src/core/cpu/device.cpp | 4 +-- src/core/cpu/kernel.cpp | 5 ++-- src/core/events.cpp | 2 +- src/core/kernel.cpp | 20 +++---------- src/core/kernel.h | 10 +++---- src/core/memobject.cpp | 23 ++++++--------- src/core/memobject.h | 6 ++-- src/core/object.cpp | 74 +++++++++++++++++++++++++++++++++++++++++++++++ src/core/object.h | 45 ++++++++++++++++++++++++++++ src/core/program.cpp | 13 ++------- src/core/program.h | 6 ++-- src/core/refcounted.cpp | 27 ----------------- src/core/refcounted.h | 25 ---------------- 19 files changed, 176 insertions(+), 165 deletions(-) create mode 100644 src/core/object.cpp create mode 100644 src/core/object.h delete mode 100644 src/core/refcounted.cpp delete mode 100644 src/core/refcounted.h diff --git a/src/api/api_enqueue.cpp b/src/api/api_enqueue.cpp index 821e8f2..578f8ab 100644 --- a/src/api/api_enqueue.cpp +++ b/src/api/api_enqueue.cpp @@ -682,6 +682,11 @@ clEnqueueMarker(cl_command_queue command_queue, } // Free events, they were memcpyed by Coal::Event + for (unsigned int i=0; idereference(); + } + std::free(events); return queueEvent(command_queue, command, event, false); diff --git a/src/api/api_program.cpp b/src/api/api_program.cpp index d1344b2..24f2f1b 100644 --- a/src/api/api_program.cpp +++ b/src/api/api_program.cpp @@ -184,7 +184,7 @@ clBuildProgram(cl_program program, { cl_uint context_num_devices = 0; cl_device_id *context_devices; - Coal::Context *context = program->context(); + Coal::Context *context = (Coal::Context *)program->parent(); cl_int result; result = context->info(CL_CONTEXT_NUM_DEVICES, sizeof(cl_uint), diff --git a/src/core/commandqueue.cpp b/src/core/commandqueue.cpp index 85eb3aa..32858a5 100644 --- a/src/core/commandqueue.cpp +++ b/src/core/commandqueue.cpp @@ -18,13 +18,9 @@ CommandQueue::CommandQueue(Context *ctx, DeviceInterface *device, cl_command_queue_properties properties, cl_int *errcode_ret) -: RefCounted(), p_ctx(ctx), p_device(device), p_properties(properties) +: Object(Object::T_CommandQueue, ctx), p_device(device), + p_properties(properties) { - // Increment the reference count of the context - // We begin by doing this to be able to unconditionnally release the context - // in the destructor, being certain that the context was actually retained. - clRetainContext((cl_context)ctx); - // Initialize the locking machinery pthread_mutex_init(&p_event_list_mutex, 0); @@ -42,9 +38,6 @@ CommandQueue::~CommandQueue() { // Free the mutex pthread_mutex_destroy(&p_event_list_mutex); - - // Release the parent context - clReleaseContext((cl_context)p_ctx); } cl_int CommandQueue::info(cl_command_queue_info param_name, @@ -65,7 +58,7 @@ cl_int CommandQueue::info(cl_command_queue_info param_name, switch (param_name) { case CL_QUEUE_CONTEXT: - SIMPLE_ASSIGN(cl_context, p_ctx); + SIMPLE_ASSIGN(cl_context, parent()); break; case CL_QUEUE_DEVICE: @@ -347,14 +340,10 @@ Event::Event(CommandQueue *parent, cl_uint num_events_in_wait_list, const Event **event_wait_list, cl_int *errcode_ret) -: RefCounted(), p_parent(parent), +: Object(Object::T_Event, parent), p_num_events_in_wait_list(num_events_in_wait_list), p_event_wait_list(0), - p_device_data(0), p_status(status), p_release_parent(true) + p_device_data(0), p_status(status) { - // Retain our parent - if (parent) - clRetainCommandQueue((cl_command_queue)p_parent); - // Initialize the locking machinery pthread_cond_init(&p_state_change_cond, 0); pthread_mutex_init(&p_state_mutex, 0); @@ -416,10 +405,10 @@ Event::Event(CommandQueue *parent, Event::~Event() { - if (p_parent && p_device_data) + if (parent() && p_device_data) { DeviceInterface *device = 0; - p_parent->info(CL_QUEUE_DEVICE, sizeof(DeviceInterface *), &device, 0); + ((CommandQueue *)parent())->info(CL_QUEUE_DEVICE, sizeof(DeviceInterface *), &device, 0); device->freeEventDeviceData(this); } @@ -432,19 +421,6 @@ Event::~Event() pthread_mutex_destroy(&p_state_mutex); pthread_cond_destroy(&p_state_change_cond); - - if (p_parent) - { - if (p_release_parent) - clReleaseCommandQueue((cl_command_queue)p_parent); - else - p_parent->dereference(); // Dereference but don't delete - } -} - -void Event::setReleaseParent(bool release) -{ - p_release_parent = release; } bool Event::isDummy() const @@ -489,8 +465,8 @@ void Event::setStatus(Status status) // If the event is completed, inform our parent so it can push other events // to the device. - if (p_parent && status == Complete) - p_parent->pushEventsOnDevice(); + if (parent() && status == Complete) + ((CommandQueue *)parent())->pushEventsOnDevice(); else if (type() == Event::User) ((UserEvent *)this)->flushQueues(); } @@ -602,15 +578,13 @@ cl_int Event::info(cl_event_info param_name, switch (param_name) { case CL_EVENT_COMMAND_QUEUE: - SIMPLE_ASSIGN(cl_command_queue, p_parent); + SIMPLE_ASSIGN(cl_command_queue, parent()); break; case CL_EVENT_CONTEXT: - if (p_parent) + if (parent()) { - // Tail call to CommandQueue - return p_parent->info(CL_QUEUE_CONTEXT, param_value_size, - param_value, param_value_size_ret); + SIMPLE_ASSIGN(cl_context, parent()->parent()); } else { @@ -660,8 +634,9 @@ cl_int Event::profilingInfo(cl_profiling_info param_name, cl_command_queue_properties queue_props; cl_int rs; - rs = p_parent->info(CL_QUEUE_PROPERTIES, sizeof(cl_command_queue_properties), - &queue_props, 0); + rs = ((CommandQueue *)parent())->info(CL_QUEUE_PROPERTIES, + sizeof(cl_command_queue_properties), + &queue_props, 0); if (rs != CL_SUCCESS) return rs; diff --git a/src/core/commandqueue.h b/src/core/commandqueue.h index f162440..0ea10bd 100644 --- a/src/core/commandqueue.h +++ b/src/core/commandqueue.h @@ -1,7 +1,7 @@ #ifndef __COMMANDQUEUE_H__ #define __COMMANDQUEUE_H__ -#include "refcounted.h" +#include "object.h" #include #include @@ -16,7 +16,7 @@ class Context; class DeviceInterface; class Event; -class CommandQueue : public RefCounted +class CommandQueue : public Object { public: CommandQueue(Context *ctx, @@ -43,7 +43,6 @@ class CommandQueue : public RefCounted Event **events(unsigned int &count); /*!< @note Retains all the events */ private: - Context *p_ctx; DeviceInterface *p_device; cl_command_queue_properties p_properties; @@ -51,7 +50,7 @@ class CommandQueue : public RefCounted pthread_mutex_t p_event_list_mutex; }; -class Event : public RefCounted +class Event : public Object { public: enum Type @@ -113,7 +112,6 @@ class Event : public RefCounted const Event **event_wait_list, cl_int *errcode_ret); - void setReleaseParent(bool release); virtual ~Event(); virtual Type type() const = 0; @@ -141,13 +139,11 @@ class Event : public RefCounted void *param_value, size_t *param_value_size_ret) const; private: - CommandQueue *p_parent; cl_uint p_num_events_in_wait_list; const Event **p_event_wait_list; pthread_cond_t p_state_change_cond; pthread_mutex_t p_state_mutex; - bool p_release_parent; Status p_status; void *p_device_data; diff --git a/src/core/context.cpp b/src/core/context.cpp index 1b89c75..54c3d66 100644 --- a/src/core/context.cpp +++ b/src/core/context.cpp @@ -21,8 +21,9 @@ Context::Context(const cl_context_properties *properties, size_t, void *), void *user_data, cl_int *errcode_ret) -: RefCounted(), p_properties(0), p_pfn_notify(pfn_notify), p_props_len(0), - p_user_data(user_data), p_platform(0), p_devices(0), p_num_devices(0) +: Object(Object::T_Context, 0), p_properties(0), p_pfn_notify(pfn_notify), + p_props_len(0), p_user_data(user_data), p_platform(0), p_devices(0), + p_num_devices(0) { if (!p_pfn_notify) p_pfn_notify = &default_pfn_notify; diff --git a/src/core/context.h b/src/core/context.h index 174dbc7..037c3ab 100644 --- a/src/core/context.h +++ b/src/core/context.h @@ -1,7 +1,7 @@ #ifndef __CONTEXT_H__ #define __CONTEXT_H__ -#include "refcounted.h" +#include "object.h" #include @@ -10,7 +10,7 @@ namespace Coal class DeviceInterface; -class Context : public RefCounted +class Context : public Object { public: Context(const cl_context_properties *properties, diff --git a/src/core/cpu/device.cpp b/src/core/cpu/device.cpp index b7ac22e..31f7aae 100644 --- a/src/core/cpu/device.cpp +++ b/src/core/cpu/device.cpp @@ -157,8 +157,8 @@ cl_int CPUDevice::initEventDeviceData(Event *event) { // Instantiate the JIT for the CPU program KernelEvent *e = (KernelEvent *)event; - CPUProgram *prog = - (CPUProgram *)e->kernel()->program()->deviceDependentProgram(this); + Program *p = (Program *)e->kernel()->parent(); + CPUProgram *prog = (CPUProgram *)p->deviceDependentProgram(this); if (!prog->initJIT()) return CL_INVALID_PROGRAM_EXECUTABLE; diff --git a/src/core/cpu/kernel.cpp b/src/core/cpu/kernel.cpp index a898522..55f2a6a 100644 --- a/src/core/cpu/kernel.cpp +++ b/src/core/cpu/kernel.cpp @@ -447,9 +447,8 @@ bool CPUKernelWorkGroup::run() if (!kernel_func) return false; - CPUProgram *prog = - (CPUProgram *)(p_kernel->kernel()->program() - ->deviceDependentProgram(p_kernel->device())); + Program *p = (Program *)p_kernel->kernel()->parent(); + CPUProgram *prog = (CPUProgram *)(p->deviceDependentProgram(p_kernel->device())); void (*kernel_func_addr)() = (void(*)())prog->jit()->getPointerToFunction(kernel_func); diff --git a/src/core/events.cpp b/src/core/events.cpp index f44c41e..9c0b169 100644 --- a/src/core/events.cpp +++ b/src/core/events.cpp @@ -37,7 +37,7 @@ BufferEvent::BufferEvent(CommandQueue *parent, if (*errcode_ret != CL_SUCCESS) return; - if (buffer->context() != ctx) + if ((Context *)buffer->parent() != ctx) { *errcode_ret = CL_INVALID_CONTEXT; return; diff --git a/src/core/kernel.cpp b/src/core/kernel.cpp index b7d5d82..c71264a 100644 --- a/src/core/kernel.cpp +++ b/src/core/kernel.cpp @@ -16,9 +16,9 @@ using namespace Coal; Kernel::Kernel(Program *program) -: RefCounted(), p_program(program), p_local_args(false) +: Object(Object::T_Kernel, program), p_local_args(false) { - clRetainProgram((cl_program)program); // TODO: Say a kernel is attached to the program (that becomes unalterable) + // TODO: Say a kernel is attached to the program (that becomes unalterable) null_dep.device = 0; null_dep.kernel = 0; @@ -36,8 +36,6 @@ Kernel::~Kernel() p_device_dependent.pop_back(); } - - clReleaseProgram((cl_program)p_program); } const Kernel::DeviceDependent &Kernel::deviceDependent(DeviceInterface *device) const @@ -116,7 +114,6 @@ cl_int Kernel::addFunction(DeviceInterface *device, llvm::Function *function, if (struct_name == "imade2d") { - // TODO: Address space qualifiers for image types, and read_only kind = Arg::Image2D; file = Arg::Global; } @@ -125,10 +122,6 @@ cl_int Kernel::addFunction(DeviceInterface *device, llvm::Function *function, kind = Arg::Image3D; file = Arg::Global; } - else if (struct_name == "sampler") - { - // TODO: Sampler - } } } else @@ -266,11 +259,6 @@ const Kernel::Arg &Kernel::arg(unsigned int index) const return p_args.at(index); } -Program *Kernel::program() const -{ - return p_program; -} - bool Kernel::argsSpecified() const { for (int i=0; icontext()); + SIMPLE_ASSIGN(cl_context, parent()->parent()); break; case CL_KERNEL_PROGRAM: - SIMPLE_ASSIGN(cl_program, p_program); + SIMPLE_ASSIGN(cl_program, parent()); break; default: diff --git a/src/core/kernel.h b/src/core/kernel.h index a2b7b75..9d4375b 100644 --- a/src/core/kernel.h +++ b/src/core/kernel.h @@ -1,7 +1,7 @@ #ifndef __KERNEL_H__ #define __KERNEL_H__ -#include "refcounted.h" +#include "object.h" #include @@ -21,7 +21,7 @@ class Program; class DeviceInterface; class DeviceKernel; -class Kernel : public RefCounted +class Kernel : public Object { public: Kernel(Program *program); @@ -48,8 +48,8 @@ class Kernel : public RefCounted Double, Buffer, Image2D, - Image3D - // TODO: Sampler + Image3D, + Sampler }; Arg(unsigned short vec_dim, File file, Kind kind); @@ -85,7 +85,6 @@ class Kernel : public RefCounted unsigned int numArgs() const; const Arg &arg(unsigned int index) const; - Program *program() const; DeviceKernel *deviceDependentKernel(DeviceInterface *device) const; bool argsSpecified() const; @@ -102,7 +101,6 @@ class Kernel : public RefCounted size_t *param_value_size_ret) const; private: - Program *p_program; std::string p_name; bool p_local_args; diff --git a/src/core/memobject.cpp b/src/core/memobject.cpp index aabb974..7d78e14 100644 --- a/src/core/memobject.cpp +++ b/src/core/memobject.cpp @@ -15,11 +15,9 @@ using namespace Coal; MemObject::MemObject(Context *ctx, cl_mem_flags flags, void *host_ptr, cl_int *errcode_ret) -: RefCounted(), p_ctx(ctx), p_flags(flags), p_host_ptr(host_ptr), +: Object(Object::T_MemObject, ctx), p_flags(flags), p_host_ptr(host_ptr), p_dtor_callback(0), p_devicebuffers(0), p_num_devices(0) { - clRetainContext((cl_context)ctx); - // Check the flags value const cl_mem_flags all_flags = CL_MEM_READ_WRITE | CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY | CL_MEM_USE_HOST_PTR | @@ -59,7 +57,6 @@ MemObject::MemObject(Context *ctx, cl_mem_flags flags, void *host_ptr, MemObject::~MemObject() { - clReleaseContext((cl_context)p_ctx); if (p_dtor_callback) p_dtor_callback((cl_mem)this, p_dtor_userdata); @@ -79,7 +76,9 @@ cl_int MemObject::init() DeviceInterface **devices = 0; cl_int rs; - rs = context()->info(CL_CONTEXT_NUM_DEVICES, sizeof(unsigned int), &p_num_devices, 0); + rs = ((Context *)parent())->info(CL_CONTEXT_NUM_DEVICES, + sizeof(unsigned int), + &p_num_devices, 0); if (rs != CL_SUCCESS) return rs; @@ -91,8 +90,9 @@ cl_int MemObject::init() if (!devices) return CL_OUT_OF_HOST_MEMORY; - rs = context()->info(CL_CONTEXT_DEVICES, - p_num_devices * sizeof(DeviceInterface *), devices, 0); + rs = ((Context *)parent())->info(CL_CONTEXT_DEVICES, + p_num_devices * sizeof(DeviceInterface *), + devices, 0); if (rs != CL_SUCCESS) { @@ -179,11 +179,6 @@ bool MemObject::allocate(DeviceInterface *device) return true; } -Context *MemObject::context() const -{ - return p_ctx; -} - cl_mem_flags MemObject::flags() const { return p_flags; @@ -309,7 +304,7 @@ cl_int MemObject::info(cl_mem_info param_name, break; case CL_MEM_CONTEXT: - SIMPLE_ASSIGN(cl_context, p_ctx); + SIMPLE_ASSIGN(cl_context, parent()); break; case CL_MEM_ASSOCIATED_MEMOBJECT: @@ -373,7 +368,7 @@ MemObject::Type Buffer::type() const SubBuffer::SubBuffer(class Buffer *parent, size_t offset, size_t size, cl_mem_flags flags, cl_int *errcode_ret) -: MemObject(parent->context(), flags, 0, errcode_ret), p_size(size), +: MemObject((Context *)parent->parent(), flags, 0, errcode_ret), p_size(size), p_offset(offset), p_parent(parent) { if (size == 0) diff --git a/src/core/memobject.h b/src/core/memobject.h index a0ac36b..e04f224 100644 --- a/src/core/memobject.h +++ b/src/core/memobject.h @@ -1,7 +1,7 @@ #ifndef __MEMOBJECT_H__ #define __MEMOBJECT_H__ -#include "refcounted.h" +#include "object.h" #include @@ -12,7 +12,7 @@ class DeviceBuffer; class Context; class DeviceInterface; -class MemObject : public RefCounted +class MemObject : public Object { public: enum Type @@ -37,7 +37,6 @@ class MemObject : public RefCounted virtual size_t size() const = 0; /*!< @warning this is a device-independent size */ virtual Type type() const = 0; - Context *context() const; cl_mem_flags flags() const; void *host_ptr() const; DeviceBuffer *deviceBuffer(DeviceInterface *device) const; @@ -53,7 +52,6 @@ class MemObject : public RefCounted size_t *param_value_size_ret) const; private: - Context *p_ctx; unsigned int p_num_devices, p_devices_to_allocate; cl_mem_flags p_flags; void *p_host_ptr; diff --git a/src/core/object.cpp b/src/core/object.cpp new file mode 100644 index 0000000..37cdcfe --- /dev/null +++ b/src/core/object.cpp @@ -0,0 +1,74 @@ +#include "object.h" + +using namespace Coal; + +std::list known_objects; + +Object::Object(Type type, Object *parent) +: p_references(1), p_parent(parent), p_type(type), p_release_parent(true) +{ + if (parent) + parent->reference(); + + // Add object in the list of known objects + known_objects.push_front(this); + p_it = known_objects.begin(); +} + +Object::~Object() +{ + if (p_parent && p_parent->dereference() && p_release_parent) + delete p_parent; + + // Remove object from the list of known objects + known_objects.erase(p_it); +} + +void Object::reference() +{ + p_references++; +} + +bool Object::dereference() +{ + p_references--; + return (p_references == 0); +} + +void Object::setReleaseParent (bool release) +{ + p_release_parent = release; +} + +unsigned int Object::references() const +{ + return p_references; +} + +Object *Object::parent() const +{ + return p_parent; +} + +Object::Type Object::type() const +{ + return p_type; +} + +bool Object::isA(Object::Type type) const +{ + // Check for null values + if (this == 0) + return false; + + // Check that the value isn't garbage or freed pointer + std::list::const_iterator it = known_objects.begin(), + e = known_objects.end(); + while (it != e) + { + if (*it == this) + return (*it)->type() == type; + } + + return false; +} diff --git a/src/core/object.h b/src/core/object.h new file mode 100644 index 0000000..1ec161f --- /dev/null +++ b/src/core/object.h @@ -0,0 +1,45 @@ +#ifndef __REFCOUNTED_H__ +#define __REFCOUNTED_H__ + +#include + +namespace Coal +{ + +class Object +{ + public: + enum Type + { + T_CommandQueue, + T_Event, + T_Context, + T_Kernel, + T_MemObject, + T_Program, + T_Sampler + }; + + Object(Type type, Object *parent = 0); + virtual ~Object(); + + void reference(); + bool dereference(); + unsigned int references() const; + void setReleaseParent(bool release); + + Object *parent() const; + Type type() const; + bool isA(Type type) const; + + private: + unsigned int p_references; + Object *p_parent; + Type p_type; + std::list::iterator p_it; + bool p_release_parent; +}; + +} + +#endif \ No newline at end of file diff --git a/src/core/program.cpp b/src/core/program.cpp index 32fd3ac..f64b97a 100644 --- a/src/core/program.cpp +++ b/src/core/program.cpp @@ -35,16 +35,12 @@ using namespace Coal; Program::Program(Context *ctx) -: RefCounted(), p_ctx(ctx), p_type(Invalid), p_state(Empty) +: Object(Object::T_Program, ctx), p_type(Invalid), p_state(Empty) { - // Retain parent context - clRetainContext((cl_context)ctx); } Program::~Program() { - clReleaseContext((cl_context)p_ctx); - while (p_device_dependent.size()) { DeviceDependent &dep = p_device_dependent.back(); @@ -422,11 +418,6 @@ Program::State Program::state() const return p_state; } -Context *Program::context() const -{ - return p_ctx; -} - cl_int Program::info(cl_program_info param_name, size_t param_value_size, void *param_value, @@ -465,7 +456,7 @@ cl_int Program::info(cl_program_info param_name, break; case CL_PROGRAM_CONTEXT: - SIMPLE_ASSIGN(cl_context, p_ctx); + SIMPLE_ASSIGN(cl_context, parent()); break; case CL_PROGRAM_SOURCE: diff --git a/src/core/program.h b/src/core/program.h index 04e932c..c8ae9c6 100644 --- a/src/core/program.h +++ b/src/core/program.h @@ -1,7 +1,7 @@ #ifndef __PROGRAM_H__ #define __PROGRAM_H__ -#include "refcounted.h" +#include "object.h" #include #include @@ -23,7 +23,7 @@ class DeviceInterface; class DeviceProgram; class Kernel; -class Program : public RefCounted +class Program : public Object { public: Program(Context *ctx); @@ -57,7 +57,6 @@ class Program : public RefCounted Type type() const; State state() const; - Context *context() const; Kernel *createKernel(const std::string &name, cl_int *errcode_ret); std::vector createKernels(cl_int *errcode_ret); @@ -74,7 +73,6 @@ class Program : public RefCounted size_t *param_value_size_ret) const; private: - Context *p_ctx; Type p_type; State p_state; std::string p_source; diff --git a/src/core/refcounted.cpp b/src/core/refcounted.cpp deleted file mode 100644 index 55402df..0000000 --- a/src/core/refcounted.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include "refcounted.h" - -using namespace Coal; - -RefCounted::RefCounted() : p_references(1) -{ -} - -RefCounted::~RefCounted() -{ -} - -void RefCounted::reference() -{ - p_references++; -} - -bool RefCounted::dereference() -{ - p_references--; - return (p_references == 0); -} - -unsigned int RefCounted::references() const -{ - return p_references; -} diff --git a/src/core/refcounted.h b/src/core/refcounted.h deleted file mode 100644 index 89b9ffe..0000000 --- a/src/core/refcounted.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __REFCOUNTED_H__ -#define __REFCOUNTED_H__ - -#include - -namespace Coal -{ - -class RefCounted -{ - public: - RefCounted(); - ~RefCounted(); - - void reference(); - bool dereference(); - unsigned int references() const; - - private: - unsigned int p_references; -}; - -} - -#endif \ No newline at end of file -- cgit v1.2.3