cl_int clGetCommandQueueInfoFCL (cl_command_queue command_queue, cl_command_queue_info param_name, size_t param_value_size, void *param_value, size_t *param_value_size_ret) { MSG(clGetCommandQueueInfoFCL); if (!FreeOCL::is_valid(command_queue)) return CL_INVALID_COMMAND_QUEUE; bool bTooSmall = false; switch(param_name) { case CL_QUEUE_CONTEXT: bTooSmall = SET_VAR(command_queue->context); break; case CL_QUEUE_DEVICE: bTooSmall = SET_VAR(command_queue->device); break; case CL_QUEUE_REFERENCE_COUNT: bTooSmall = SET_VAR(command_queue->get_ref_count()); break; case CL_QUEUE_PROPERTIES: bTooSmall = SET_VAR(command_queue->properties); break; default: command_queue->unlock(); return CL_INVALID_VALUE; } command_queue->unlock(); if (bTooSmall && param_value != NULL) return CL_INVALID_VALUE; return CL_SUCCESS; }
bool is_valid(cl_command_queue q) { global_mutex.lock(); const bool r = valid_command_queues.count(q) != 0 && q->valid(); if (r) q->lock(); global_mutex.unlock(); return r; }
cl_int clRetainCommandQueueFCL (cl_command_queue command_queue) { MSG(clRetainCommandQueueFCL); if (!FreeOCL::is_valid(command_queue)) return CL_INVALID_COMMAND_QUEUE; command_queue->retain(); command_queue->unlock(); return CL_SUCCESS; }
cl_int clRetainCommandQueue(cl_command_queue command_queue) { if (!command_queue->isA(Coal::Object::T_CommandQueue)) return CL_INVALID_COMMAND_QUEUE; command_queue->reference(); return CL_SUCCESS; }
cl_int clSetCommandQueueProperty(cl_command_queue command_queue, cl_command_queue_properties properties, cl_bool enable, cl_command_queue_properties * old_properties) { if (!command_queue->isA(Coal::Object::T_CommandQueue)) return CL_INVALID_COMMAND_QUEUE; return command_queue->setProperty(properties, enable, old_properties); }
cl_int clReleaseCommandQueue(cl_command_queue command_queue) { if (!command_queue->isA(Coal::Object::T_CommandQueue)) return CL_INVALID_COMMAND_QUEUE; command_queue->flush(); if (command_queue->dereference()) delete command_queue; return CL_SUCCESS; }
cl_int clGetCommandQueueInfo(cl_command_queue command_queue, cl_command_queue_info param_name, size_t param_value_size, void * param_value, size_t * param_value_size_ret) { if (!command_queue->isA(Coal::Object::T_CommandQueue)) return CL_INVALID_COMMAND_QUEUE; return command_queue->info(param_name, param_value_size, param_value, param_value_size_ret); }
cl_int clEnqueueNativeKernel(cl_command_queue command_queue, void (*user_func)(void *), void * args, size_t cb_args, cl_uint num_mem_objects, const cl_mem * mem_list, const void ** args_mem_loc, cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event) { cl_int rs = CL_SUCCESS; if (!command_queue->isA(Coal::Object::T_CommandQueue)) return CL_INVALID_COMMAND_QUEUE; Coal::NativeKernelEvent *command = new Coal::NativeKernelEvent( (Coal::CommandQueue *)command_queue, user_func, args, cb_args, num_mem_objects, (const Coal::MemObject **)mem_list, args_mem_loc, num_events_in_wait_list, (const Coal::Event **)event_wait_list, &rs ); if (rs != CL_SUCCESS) { delete command; return rs; } return queueEvent(command_queue, command, event, false); }
cl_int clEnqueueTask(cl_command_queue command_queue, cl_kernel kernel, cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event) { cl_int rs = CL_SUCCESS; if (!command_queue->isA(Coal::Object::T_CommandQueue)) { return CL_INVALID_COMMAND_QUEUE; } Coal::TaskEvent *command = new Coal::TaskEvent( (Coal::CommandQueue *)command_queue, (Coal::Kernel *)kernel, num_events_in_wait_list, (const Coal::Event **)event_wait_list, &rs ); if (rs != CL_SUCCESS) { delete command; return rs; } return queueEvent(command_queue, command, event, false); }
cl_int clEnqueueNDRangeKernel(cl_command_queue command_queue, cl_kernel kernel, cl_uint work_dim, const size_t * global_work_offset, const size_t * global_work_size, const size_t * local_work_size, cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event) { cl_int rs = CL_SUCCESS; if (!command_queue->isA(Coal::Object::T_CommandQueue)) { return CL_INVALID_COMMAND_QUEUE; } Coal::KernelEvent *command = new Coal::KernelEvent( (Coal::CommandQueue *)command_queue, (Coal::Kernel *)kernel, work_dim, global_work_offset, global_work_size, local_work_size, num_events_in_wait_list, (const Coal::Event **)event_wait_list, &rs ); if (rs != CL_SUCCESS) { delete command; return rs; } return queueEvent(command_queue, command, event, false); }
cl_int clEnqueueUnmapMemObject(cl_command_queue command_queue, cl_mem memobj, void * mapped_ptr, cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event) { cl_int rs = CL_SUCCESS; if (!command_queue->isA(Coal::Object::T_CommandQueue)) { return CL_INVALID_COMMAND_QUEUE; } Coal::UnmapBufferEvent *command = new Coal::UnmapBufferEvent( (Coal::CommandQueue *)command_queue, (Coal::MemObject *)memobj, mapped_ptr, num_events_in_wait_list, (const Coal::Event **)event_wait_list, &rs ); if (rs != CL_SUCCESS) { delete command; return rs; } return queueEvent(command_queue, command, event, false); }
// Enqueued Commands APIs cl_int clEnqueueReadBuffer(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_read, size_t offset, size_t cb, void * ptr, cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event) { cl_int rs = CL_SUCCESS; if (!command_queue->isA(Coal::Object::T_CommandQueue)) return CL_INVALID_COMMAND_QUEUE; Coal::ReadBufferEvent *command = new Coal::ReadBufferEvent( (Coal::CommandQueue *)command_queue, (Coal::MemObject *)buffer, offset, cb, ptr, num_events_in_wait_list, (const Coal::Event **)event_wait_list, &rs ); if (rs != CL_SUCCESS) { delete command; return rs; } return queueEvent(command_queue, command, event, blocking_read); }
cl_int clEnqueueWriteImage(cl_command_queue command_queue, cl_mem image, cl_bool blocking_write, const size_t * origin, const size_t * region, size_t row_pitch, size_t slice_pitch, const void * ptr, cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event) { cl_int rs = CL_SUCCESS; if (!command_queue->isA(Coal::Object::T_CommandQueue)) return CL_INVALID_COMMAND_QUEUE; Coal::WriteImageEvent *command = new Coal::WriteImageEvent( (Coal::CommandQueue *)command_queue, (Coal::Image2D *)image, origin, region, row_pitch, slice_pitch, (void *)ptr, num_events_in_wait_list, (const Coal::Event **)event_wait_list, &rs ); if (rs != CL_SUCCESS) { delete command; return rs; } return queueEvent(command_queue, command, event, blocking_write); }
cl_int clEnqueueCopyBufferToImage(cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_image, size_t src_offset, const size_t * dst_origin, const size_t * region, cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event) { cl_int rs = CL_SUCCESS; if (!command_queue->isA(Coal::Object::T_CommandQueue)) return CL_INVALID_COMMAND_QUEUE; Coal::CopyBufferToImageEvent *command = new Coal::CopyBufferToImageEvent( (Coal::CommandQueue *)command_queue, (Coal::MemObject *)src_buffer, (Coal::Image2D *)dst_image, src_offset, dst_origin, region, num_events_in_wait_list, (const Coal::Event **)event_wait_list, &rs ); if (rs != CL_SUCCESS) { delete command; return rs; } return queueEvent(command_queue, command, event, false); }
cl_int clReleaseCommandQueue(cl_command_queue command_queue) { if (!command_queue->isA(Coal::Object::T_CommandQueue)) { #ifdef DBG_OUTPUT std::cout << "clReleaseCommandQueue failed" << std::endl; #endif return CL_INVALID_COMMAND_QUEUE; } command_queue->flush(); if (command_queue->dereference()) delete command_queue; return CL_SUCCESS; }
PUBLIC cl_int clFlush(cl_command_queue q) { if (!q) return CL_INVALID_COMMAND_QUEUE; q->flush(); return CL_SUCCESS; }
cl_int clReleaseCommandQueueFCL (cl_command_queue command_queue) { MSG(clReleaseCommandQueueFCL); if (!FreeOCL::is_valid(command_queue)) return CL_INVALID_COMMAND_QUEUE; command_queue->release(); if (command_queue->get_ref_count() == 0) { command_queue->invalidate(); command_queue->unlock(); delete command_queue; } else command_queue->unlock(); return CL_SUCCESS; }
PUBLIC cl_int clRetainCommandQueue(cl_command_queue q) { if (!q) return CL_INVALID_COMMAND_QUEUE; q->retain(); return CL_SUCCESS; }
PUBLIC cl_int clReleaseCommandQueue(cl_command_queue q) { if (!q) return CL_INVALID_COMMAND_QUEUE; if (q->release()) delete q; return CL_SUCCESS; }
cl_int clFinishFCL (cl_command_queue command_queue) { MSG(clFinishFCL); if (!FreeOCL::is_valid(command_queue)) return CL_INVALID_COMMAND_QUEUE; if (command_queue->done()) { command_queue->unlock(); return CL_SUCCESS; } command_queue->unlock(); cl_event event; cl_int err = clEnqueueMarkerFCL(command_queue, &event); if (err != CL_SUCCESS) return err; err = clWaitForEventsFCL(1, &event); clReleaseEventFCL(event); return err; }
cl_int clEnqueueMarker(cl_command_queue command_queue, cl_event * event) { cl_int rs = CL_SUCCESS; if (!command_queue->isA(Coal::Object::T_CommandQueue)) return CL_INVALID_COMMAND_QUEUE; if (!event) return CL_INVALID_VALUE; // Get the events in command_queue unsigned int count; Coal::Event **events = command_queue->events(count); Coal::MarkerEvent *command = new Coal::MarkerEvent( (Coal::CommandQueue *)command_queue, count, (const Coal::Event **)events, &rs); if (rs != CL_SUCCESS) { delete command; return rs; } // Free events, they were memcpyed by Coal::Event for (unsigned int i=0; i<count; ++i) { events[i]->dereference(); } std::free(events); return queueEvent(command_queue, command, event, false); }
PUBLIC cl_int clGetCommandQueueInfo(cl_command_queue q, cl_command_queue_info param, size_t size, void *buf, size_t *size_ret) { if (!q) return CL_INVALID_COMMAND_QUEUE; switch (param) { case CL_QUEUE_CONTEXT: return scalar_property<cl_context>(buf, size, size_ret, &q->ctx); case CL_QUEUE_DEVICE: return scalar_property<cl_device_id>(buf, size, size_ret, &q->dev); case CL_QUEUE_REFERENCE_COUNT: return scalar_property<cl_uint>(buf, size, size_ret, q->ref_count()); case CL_QUEUE_PROPERTIES: return scalar_property<cl_command_queue_properties>(buf, size, size_ret, q->props()); default: return CL_INVALID_VALUE; } }
cl_int clEnqueueBarrier(cl_command_queue command_queue) { cl_int rs = CL_SUCCESS; if (!command_queue->isA(Coal::Object::T_CommandQueue)) return CL_INVALID_COMMAND_QUEUE; Coal::BarrierEvent *command = new Coal::BarrierEvent( (Coal::CommandQueue *)command_queue, &rs); if (rs != CL_SUCCESS) { delete command; return rs; } return queueEvent(command_queue, command, 0, false); }
cl_int clEnqueueUnmapMemObjectFCL (cl_command_queue command_queue, cl_mem memobj, void *mapped_ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event) { MSG(clEnqueueUnmapMemObjectFCL); FreeOCL::unlocker unlock; if (!FreeOCL::is_valid(command_queue)) return CL_INVALID_COMMAND_QUEUE; unlock.handle(command_queue); if (!FreeOCL::is_valid(command_queue->context)) return CL_INVALID_CONTEXT; command_queue->context->unlock(); if (!FreeOCL::is_valid(memobj)) return CL_INVALID_MEM_OBJECT; unlock.handle(memobj); FreeOCL::smartptr<FreeOCL::command_unmap_buffer> cmd = new FreeOCL::command_unmap_buffer; cmd->num_events_in_wait_list = num_events_in_wait_list; cmd->event_wait_list = event_wait_list; cmd->event = event ? new _cl_event(command_queue->context) : NULL; cmd->buffer = memobj; cmd->ptr = mapped_ptr; if (cmd->event) { *event = cmd->event.weak(); cmd->event->command_queue = command_queue; cmd->event->command_type = CL_COMMAND_UNMAP_MEM_OBJECT; cmd->event->status = CL_QUEUED; } unlock.forget(command_queue); command_queue->enqueue(cmd); return CL_SUCCESS; }
cl_int clEnqueueWaitForEvents(cl_command_queue command_queue, cl_uint num_events, const cl_event * event_list) { cl_int rs = CL_SUCCESS; if (!command_queue->isA(Coal::Object::T_CommandQueue)) return CL_INVALID_COMMAND_QUEUE; Coal::WaitForEventsEvent *command = new Coal::WaitForEventsEvent( (Coal::CommandQueue *)command_queue, num_events, (const Coal::Event **)event_list, &rs); if (rs != CL_SUCCESS) { delete command; return rs; } return queueEvent(command_queue, command, 0, false); }
cl_int clSetCommandQueuePropertyFCL (cl_command_queue command_queue, cl_command_queue_properties properties, cl_bool enable, cl_command_queue_properties *old_properties) { if (properties & ~(CL_QUEUE_PROFILING_ENABLE | CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE)) return CL_INVALID_VALUE; MSG(clSetCommandQueuePropertyFCL); clFinishFCL (command_queue); if (!FreeOCL::is_valid(command_queue)) return CL_INVALID_COMMAND_QUEUE; if (old_properties) *old_properties = command_queue->properties; if (enable) command_queue->properties |= properties; else command_queue->properties &= ~properties; command_queue->unlock(); return CL_SUCCESS; }
cl_int clEnqueueWriteBufferRect(cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_write, const size_t * buffer_origin, const size_t * host_origin, const size_t * region, size_t buffer_row_pitch, size_t buffer_slice_pitch, size_t host_row_pitch, size_t host_slice_pitch, const void * ptr, cl_uint num_events_in_wait_list, const cl_event * event_wait_list, cl_event * event) { cl_int rs = CL_SUCCESS; if (!command_queue->isA(Coal::Object::T_CommandQueue)) return CL_INVALID_COMMAND_QUEUE; Coal::WriteBufferRectEvent *command = new Coal::WriteBufferRectEvent( (Coal::CommandQueue *)command_queue, (Coal::MemObject *)buffer, buffer_origin, host_origin, region, buffer_row_pitch, buffer_slice_pitch, host_row_pitch, host_slice_pitch, (void *)ptr, num_events_in_wait_list, (const Coal::Event **)event_wait_list, &rs ); if (rs != CL_SUCCESS) { delete command; return rs; } return queueEvent(command_queue, command, event, blocking_write); }
cl_int clEnqueueWriteBufferFCL (cl_command_queue command_queue, cl_mem buffer, cl_bool blocking_write, size_t offset, size_t cb, const void *ptr, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event) { MSG(clEnqueueWriteBufferFCL); FreeOCL::unlocker unlock; if (ptr == NULL) return CL_INVALID_VALUE; if (!FreeOCL::is_valid(command_queue)) return CL_INVALID_COMMAND_QUEUE; unlock.handle(command_queue); if (!FreeOCL::is_valid(command_queue->context)) return CL_INVALID_CONTEXT; command_queue->context->unlock(); if (!FreeOCL::is_valid(buffer)) return CL_INVALID_MEM_OBJECT; unlock.handle(buffer); if (!FreeOCL::is_valid(buffer->context)) return CL_INVALID_CONTEXT; buffer->context->unlock(); if (buffer->context != command_queue->context) return CL_INVALID_CONTEXT; if (buffer->size < offset + cb) return CL_INVALID_VALUE; if (buffer->flags & (CL_MEM_HOST_NO_ACCESS | CL_MEM_HOST_READ_ONLY)) return CL_INVALID_OPERATION; if (event_wait_list == NULL && num_events_in_wait_list > 0) return CL_INVALID_EVENT_WAIT_LIST; if (event_wait_list != NULL && num_events_in_wait_list == 0) return CL_INVALID_EVENT_WAIT_LIST; for(size_t i = 0 ; i < num_events_in_wait_list ; ++i) { if (!FreeOCL::is_valid(event_wait_list[i])) return CL_INVALID_EVENT_WAIT_LIST; unlock.handle(event_wait_list[i]); } if (blocking_write == CL_TRUE) { for(size_t i = 0 ; i < num_events_in_wait_list ; ++i) if (event_wait_list[i]->status < 0) return CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST; } FreeOCL::smartptr<FreeOCL::command_write_buffer> cmd = new FreeOCL::command_write_buffer; cmd->num_events_in_wait_list = num_events_in_wait_list; cmd->event_wait_list = event_wait_list; cmd->event = (blocking_write == CL_TRUE || event) ? new _cl_event(command_queue->context) : NULL; cmd->buffer = buffer; cmd->offset = offset; cmd->cb = cb; cmd->ptr = ptr; if (cmd->event) { cmd->event->command_queue = command_queue; cmd->event->command_type = CL_COMMAND_WRITE_BUFFER; cmd->event->status = CL_QUEUED; } if (event) *event = cmd->event.weak(); unlock.forget(command_queue); command_queue->enqueue(cmd); unlock.unlockall(); if (blocking_write == CL_TRUE) { clWaitForEventsFCL(1, &(cmd->event.weak())); if (event == NULL) clReleaseEventFCL(cmd->event.weak()); } return CL_SUCCESS; }
cl_int clEnqueueCopyBufferFCL (cl_command_queue command_queue, cl_mem src_buffer, cl_mem dst_buffer, size_t src_offset, size_t dst_offset, size_t cb, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event) { MSG(clEnqueueCopyBufferFCL); FreeOCL::unlocker unlock; if (!FreeOCL::is_valid(command_queue)) return CL_INVALID_COMMAND_QUEUE; unlock.handle(command_queue); if (!FreeOCL::is_valid(command_queue->context)) return CL_INVALID_CONTEXT; command_queue->context->unlock(); if (!FreeOCL::is_valid(src_buffer)) return CL_INVALID_MEM_OBJECT; unlock.handle(src_buffer); if (src_buffer->size < src_offset + cb) return CL_INVALID_VALUE; if (dst_buffer != src_buffer) // Don't lock it twice if it's the same buffer { if (!FreeOCL::is_valid(dst_buffer)) return CL_INVALID_MEM_OBJECT; unlock.handle(dst_buffer); if (dst_buffer->size < dst_offset + cb) return CL_INVALID_VALUE; } if (src_buffer == dst_buffer && std::max(src_offset, dst_offset) - std::min(src_offset, dst_offset) < cb) return CL_MEM_COPY_OVERLAP; FreeOCL::smartptr<FreeOCL::command_copy_buffer> cmd = new FreeOCL::command_copy_buffer; cmd->num_events_in_wait_list = num_events_in_wait_list; cmd->event_wait_list = event_wait_list; cmd->event = event ? new _cl_event(command_queue->context) : NULL; cmd->src_buffer = src_buffer; cmd->src_offset = src_offset; cmd->dst_buffer = dst_buffer; cmd->dst_offset = dst_offset; cmd->cb = cb; if (cmd->event) { cmd->event->command_queue = command_queue; cmd->event->command_type = CL_COMMAND_COPY_BUFFER; cmd->event->status = CL_QUEUED; } if (event) *event = cmd->event.weak(); unlock.forget(command_queue); command_queue->enqueue(cmd); return CL_SUCCESS; }