예제 #1
0
	cl_command_queue clCreateCommandQueueFCL (cl_context context,
						  cl_device_id device,
						  cl_command_queue_properties properties,
						  cl_int *errcode_ret)
	{
		MSG(clCreateCommandQueueFCL);
		if (properties & ~(CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE | CL_QUEUE_PROFILING_ENABLE))
		{
			SET_RET(CL_INVALID_VALUE);
			return 0;
		}

		FreeOCL::unlocker unlock;
		if (!FreeOCL::is_valid(context))
		{
			SET_RET(CL_INVALID_CONTEXT);
			return 0;
		}
		unlock.handle(context);

		if (!FreeOCL::is_valid(device))
		{
			SET_RET(CL_INVALID_DEVICE);
			return 0;
		}

		cl_command_queue q = new _cl_command_queue(context);
		q->device = device;
		q->properties = properties;

		SET_RET(CL_SUCCESS);

		return q;
	}
예제 #2
0
파일: mem.cpp 프로젝트: Agorath/freeocl
	cl_int clSetMemObjectDestructorCallbackFCL (cl_mem memobj,
											 void (CL_CALLBACK *pfn_notify)(cl_mem memobj,
																			void *user_data),
											 void *user_data)
	{
		MSG(clSetMemObjectDestructorCallbackFCL);
		if (pfn_notify)
			return CL_INVALID_VALUE;

		FreeOCL::unlocker unlock;
		if (!FreeOCL::is_valid(memobj))
			return CL_INVALID_MEM_OBJECT;
		unlock.handle(memobj);

		FreeOCL::mem_call_back call_back = { pfn_notify, user_data };
		memobj->call_backs.push_front(call_back);		// They are called in reverse order
		return CL_SUCCESS;
	}
예제 #3
0
파일: mem.cpp 프로젝트: Agorath/freeocl
	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;
	}
예제 #4
0
파일: mem.cpp 프로젝트: Agorath/freeocl
	cl_int clGetMemObjectInfoFCL (cl_mem memobj,
							   cl_mem_info param_name,
							   size_t param_value_size,
							   void *param_value,
							   size_t *param_value_size_ret)
	{
		MSG(clGetMemObjectInfoFCL);
		FreeOCL::unlocker unlock;
		if (!FreeOCL::is_valid(memobj))
			return CL_INVALID_MEM_OBJECT;
		unlock.handle(memobj);

		bool bTooSmall = false;
		switch(param_name)
		{
		case CL_MEM_TYPE:					bTooSmall = SET_VAR(memobj->mem_type);	break;
		case CL_MEM_FLAGS:					bTooSmall = SET_VAR(memobj->flags);	break;
		case CL_MEM_SIZE:					bTooSmall = SET_VAR(memobj->size);	break;
		case CL_MEM_HOST_PTR:				bTooSmall = SET_VAR(memobj->host_ptr);	break;
		case CL_MEM_MAP_COUNT:
			{
				cl_uint n = memobj->mapped.size();
				bTooSmall = SET_VAR(n);
			}
			break;
		case CL_MEM_REFERENCE_COUNT:		bTooSmall = SET_VAR(memobj->get_ref_count());	break;
		case CL_MEM_CONTEXT:				bTooSmall = SET_VAR(memobj->context);	break;
		case CL_MEM_ASSOCIATED_MEMOBJECT:	bTooSmall = SET_VAR(memobj->parent);	break;
		case CL_MEM_OFFSET:					bTooSmall = SET_VAR(memobj->offset);	break;
		default:
			return CL_INVALID_VALUE;
		}

		if (bTooSmall && param_value != NULL)
			return CL_INVALID_VALUE;

		return CL_SUCCESS;
	}
예제 #5
0
파일: mem.cpp 프로젝트: Agorath/freeocl
	void * clEnqueueMapBufferFCL (cl_command_queue command_queue,
							   cl_mem buffer,
							   cl_bool blocking_map,
							   cl_map_flags map_flags,
							   size_t offset,
							   size_t cb,
							   cl_uint num_events_in_wait_list,
							   const cl_event *event_wait_list,
							   cl_event *event,
							   cl_int *errcode_ret)
	{
		MSG(clEnqueueMapBufferFCL);
		if (map_flags & ~(CL_MAP_READ | CL_MAP_WRITE | CL_MAP_WRITE_INVALIDATE_REGION))
		{
			SET_RET(CL_INVALID_VALUE);
			return NULL;
		}
		FreeOCL::unlocker unlock;
		if (!FreeOCL::is_valid(command_queue))
		{
			SET_RET(CL_INVALID_COMMAND_QUEUE);
			return NULL;
		}
		unlock.handle(command_queue);

		if (!FreeOCL::is_valid(command_queue->context))
		{
			SET_RET(CL_INVALID_CONTEXT);
			return NULL;
		}
		command_queue->context->unlock();

		if (!FreeOCL::is_valid(buffer))
		{
			SET_RET(CL_INVALID_MEM_OBJECT);
			return NULL;
		}
		unlock.handle(buffer);

		if (buffer->size < offset + cb)
		{
			SET_RET(CL_INVALID_VALUE);
			return NULL;
		}

		void *p = (char*)buffer->ptr + offset;
		if ((num_events_in_wait_list == 0 || event_wait_list == NULL) && blocking_map == CL_FALSE)
		{
			buffer->mapped.insert(p);
			if (event)
			{
				cl_event e = new _cl_event(command_queue->context);
				*event = e;
				e->command_queue = command_queue;
				e->command_type = CL_COMMAND_MAP_BUFFER;
				e->status = CL_QUEUED;
				e->change_status(CL_QUEUED);
				e->change_status(CL_SUBMITTED);
				e->change_status(CL_RUNNING);
				e->change_status(CL_COMPLETE);
			}
		}
		else
		{
			FreeOCL::smartptr<FreeOCL::command_map_buffer> cmd = new FreeOCL::command_map_buffer;
			cmd->num_events_in_wait_list = num_events_in_wait_list;
			cmd->event_wait_list = event_wait_list;
			cmd->event = (blocking_map == CL_TRUE || event) ? new _cl_event(command_queue->context) : NULL;
			if (cmd->event)
			{
				cmd->event->command_queue = command_queue;
				cmd->event->command_type = CL_COMMAND_MAP_BUFFER;
				cmd->event->status = CL_QUEUED;
				if (event)
					*event = cmd->event.weak();
			}
			cmd->buffer = buffer;
			cmd->ptr = p;

			unlock.forget(command_queue);
			command_queue->enqueue(cmd);
			unlock.unlockall();

			if (blocking_map == CL_TRUE)
			{
				clWaitForEventsFCL(1, &cmd->event.weak());
				if (event == NULL)
					clReleaseEventFCL(cmd->event.weak());
			}
		}
		SET_RET(CL_SUCCESS);
		return p;
	}
예제 #6
0
파일: mem.cpp 프로젝트: Agorath/freeocl
	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;
	}
예제 #7
0
파일: mem.cpp 프로젝트: Agorath/freeocl
	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;
	}
예제 #8
0
파일: mem.cpp 프로젝트: Agorath/freeocl
	cl_mem clCreateBufferFCL (cl_context context,
						   cl_mem_flags flags,
						   size_t size,
						   void *host_ptr,
						   cl_int *errcode_ret)
	{
		MSG(clCreateBufferFCL);
		if (size == 0)
		{
			SET_RET(CL_INVALID_BUFFER_SIZE);
			return 0;
		}
		if (((flags & (CL_MEM_USE_HOST_PTR | CL_MEM_COPY_HOST_PTR))
			&& host_ptr == NULL)
			|| (host_ptr != NULL && !(flags & (CL_MEM_USE_HOST_PTR | CL_MEM_COPY_HOST_PTR))))
		{
			SET_RET(CL_INVALID_HOST_PTR);
			return 0;
		}

		if ((flags & CL_MEM_USE_HOST_PTR) && (flags & (CL_MEM_ALLOC_HOST_PTR | CL_MEM_COPY_HOST_PTR)))
		{
			SET_RET(CL_INVALID_VALUE);
			return 0;
		}

		if (((flags & CL_MEM_READ_WRITE) && (flags & (CL_MEM_WRITE_ONLY | CL_MEM_READ_ONLY)))
		    || ((flags & CL_MEM_WRITE_ONLY) && (flags & CL_MEM_READ_ONLY)))
		{
			SET_RET(CL_INVALID_VALUE);
			return 0;
		}

		if (((flags & CL_MEM_HOST_NO_ACCESS) && (flags & (CL_MEM_HOST_READ_ONLY | CL_MEM_HOST_WRITE_ONLY)))
			|| ((flags & CL_MEM_HOST_READ_ONLY) && (flags & CL_MEM_HOST_WRITE_ONLY)))
		{
			SET_RET(CL_INVALID_VALUE);
			return 0;
		}

		FreeOCL::unlocker unlock;
		if (!FreeOCL::is_valid(context))
		{
			SET_RET(CL_INVALID_CONTEXT);
			return 0;
		}
		unlock.handle(context);

		cl_mem mem = new _cl_mem(context);
		mem->flags = flags;
		mem->size = size;
		mem->mem_type = CL_MEM_OBJECT_BUFFER;
		mem->host_ptr = host_ptr;
		mem->parent = NULL;
		mem->offset = 0;
		if (flags & CL_MEM_USE_HOST_PTR)
			mem->ptr = host_ptr;
#ifdef FREEOCL_OS_WINDOWS
        else if ((mem->ptr = __mingw_aligned_malloc(size, 256)) == NULL)
#else
		else if (posix_memalign(&(mem->ptr), 256, size) == ENOMEM)
#endif
		{
			SET_RET(CL_OUT_OF_RESOURCES);
			delete mem;
			return 0;
		}

		if (flags & CL_MEM_COPY_HOST_PTR)
			memcpy(mem->ptr, host_ptr, size);

		SET_RET(CL_SUCCESS);

		return mem;
	}
예제 #9
0
파일: mem.cpp 프로젝트: Agorath/freeocl
	cl_mem clCreateSubBufferFCL (cl_mem buffer,
							  cl_mem_flags flags,
							  cl_buffer_create_type buffer_create_type,
							  const void *buffer_create_info,
							  cl_int *errcode_ret)
	{
		MSG(clCreateSubBufferFCL);
		FreeOCL::unlocker unlock;
		if (!FreeOCL::is_valid(buffer))
		{
			SET_RET(CL_INVALID_MEM_OBJECT);
			return 0;
		}
		unlock.handle(buffer);

		if (buffer->parent)
		{
			SET_RET(CL_INVALID_MEM_OBJECT);
			return 0;
		}

		if (((buffer->flags & CL_MEM_WRITE_ONLY) && ((flags & CL_MEM_READ_WRITE) || (flags & CL_MEM_READ_ONLY)))
				|| ((buffer->flags & CL_MEM_READ_ONLY) && ((flags & CL_MEM_READ_WRITE) || (flags & CL_MEM_WRITE_ONLY)))
				|| (flags & CL_MEM_USE_HOST_PTR)
				|| (flags & CL_MEM_ALLOC_HOST_PTR)
				|| (flags & CL_MEM_COPY_HOST_PTR))
		{
			SET_RET(CL_INVALID_VALUE);
			return 0;
		}

		if (buffer_create_info == NULL)
		{
			SET_RET(CL_INVALID_VALUE);
			return 0;
		}

		switch(buffer_create_type)
		{
		case CL_BUFFER_CREATE_TYPE_REGION:
			{
				const _cl_buffer_region *p_info = (const _cl_buffer_region *)buffer_create_info;
				if (p_info->size == 0)
				{
					SET_RET(CL_INVALID_BUFFER_SIZE);
					return 0;
				}
				if (p_info->size + p_info->origin > buffer->size)
				{
					SET_RET(CL_INVALID_VALUE);
					return 0;
				}
				if ((p_info->origin % FreeOCL::device->mem_base_addr_align) != 0)
				{
					SET_RET(CL_MISALIGNED_SUB_BUFFER_OFFSET);
					return 0;
				}

				cl_mem mem = new _cl_mem(buffer->context);
				mem->flags = flags;
				mem->size = p_info->size;
				mem->mem_type = CL_MEM_OBJECT_BUFFER;
				mem->host_ptr = NULL;
				mem->parent = buffer;
				mem->offset = p_info->origin;
				mem->ptr = (char*)buffer->ptr + p_info->origin;

				SET_RET(CL_SUCCESS);
				return mem;
			}
			break;
		default:
			SET_RET(CL_INVALID_VALUE);
			return 0;
		}

		SET_RET(CL_INVALID_VALUE);
		return 0;
	}