Esempio n. 1
0
/**
 * \brief ocl::Image::copyTo Copies from this Image to the destination Image.
 *
 * The operation assumes that all data are valid and no synchronization is necessary (active Queue executes in-order).
 * The operation forces that all commands within the active Queue including this one are completed.
 *
 * \param src_origin is the 3D offset in bytes from which the Image is read.
 * \param region is the 3D region of the data. It is given with {image_width, image_height, image_depth}.
 * \param dest is the Image into which the data is going to be copied.
 * \param dest_origin is the 3D offset in bytes from which the destionation Image is read.
 */
void ocl::Image::copyTo(size_t *src_origin, const size_t *region, const Image & dest, size_t *dest_origin, const EventList & list ) const
{
    TRUE_ASSERT(this->context() == dest.context(), "Context of this and dest must be equal");
    TRUE_ASSERT(this->id() != dest.id(), "Images must not be equal this->id() " << this->id() << "; other.id " << dest.id());
    OPENCL_SAFE_CALL( clEnqueueCopyImage(this->activeQueue().id(), this->id(), dest.id(), src_origin, dest_origin, region, list.size(), list.events().data(), NULL) );
    OPENCL_SAFE_CALL( clFinish(this->activeQueue().id()) );
}
Esempio n. 2
0
/*! \brief Erases comments within the string object containing kernel function.
  *
  * Note that this is a helper function and that
  * you do not have to call this function.
*/
void ocl::Program::eraseComments(std::string &kernels) const
{
	size_t end_pos = 0, pos = 0;
    while(pos < kernels.length()){
            pos = kernels.find("/*", pos,2);
            end_pos = kernels.find("*/", pos,2);
            if(pos >= kernels.length()) break;
            if(end_pos >= kernels.length()) break;
            TRUE_ASSERT(pos < end_pos, pos << " >= " << end_pos);
//		cout << "Erasing substring : " << kernels.substr(start_pos, end_pos-start_pos+2) <<  "-ENDEND" << endl;
            kernels.erase(pos, end_pos-pos+2);
            pos += 2;
	}
        pos = 0;
        while(pos < kernels.length()){
            pos = kernels.find("//", pos,2);
            end_pos = kernels.find("\n", pos); std::string s("\n");
            if(pos >= kernels.length()) break;
            if(end_pos >= kernels.length()) break;
            TRUE_ASSERT(pos < end_pos, pos << " >= " << end_pos);
            //		cout << "Erasing substring : " << kernels.substr(start_pos, end_pos-start_pos) <<  "-ENDEND" << endl;
            kernels.erase(pos, end_pos-pos);
            pos++;
	}
}
Esempio n. 3
0
/**
 * \brief ocl::Image::create Creates cl_mem for this Image.
 *
 * Note that no Memory is allocated. Allocation takes place when data is transfered.
 * It is assumed that an active Queue exists.
 *
 * \param width Width of the image.
 * \param height Height of the image.
 * \param depth Depth of the image.
 * \param type Channeltype of the image.
 * \param order Channelorder of the image.
 */
void ocl::Image::create(size_t width, size_t height, size_t depth, ChannelType type, ChannelOrder order, Access access)
{
    TRUE_ASSERT(this->_context != 0, "Context not valid - cannot create Image");
    cl_mem_flags flags = access;

    cl_image_format format;
    format.image_channel_order = order;
    format.image_channel_data_type = type;

    cl_int status;

#if defined(OPENCL_V1_0) || defined(OPENCL_V1_1)
    this->_id = clCreateImage3D(this->_context->id(), flags, &format, width, height, depth, 0, 0, NULL, &status);
#else
    _cl_image_desc desc;
    desc.image_type = CL_MEM_OBJECT_IMAGE3D;
    desc.image_height = height;
    desc.image_width = width;
    desc.image_depth = depth;
    desc.image_array_size = 1;
    desc.image_row_pitch = 0;
    desc.image_slice_pitch = 0;
    desc.num_mip_levels = 0;
    desc.num_samples = 0;
    desc.buffer = NULL;
    this->_id = clCreateImage(this->_context->id(), flags, &format, &desc, NULL, &status);
#endif
    OPENCL_SAFE_CALL(status);
    TRUE_ASSERT(this->_id != 0, "Could not create 3D image.");
}
Esempio n. 4
0
/*! \brief Sets the Types for the Kernel objects.
  *
  * Note that this Progam should not be built.
*/
void ocl::Program::setTypes(const utl::Types& types)
{
    TRUE_ASSERT(!types.empty(), "Types should not be empty");
    TRUE_ASSERT(!this->isBuilt(), "Program already built.");
    _types = types;

}
Esempio n. 5
0
/**
 * \brief ocl::Image::write Transfers data from host memory to this Image.
 *
 * You can be sure that the data is read. Be sure that the queue
 * and this Image are in the same context.
 * \param queue is a command queue on which the command is executed.
 * \param origin is the 3D offset in bytes from which the Image is read.
 * \param ptr_to_host_data must point to a memory location whith region bytes available.
 * \param region is the 3D region of the data. It is given with {image_width, image_height, image_depth}.
 */
void ocl::Image::write(const Queue& queue, size_t *origin, const void *ptr_to_host_data, const size_t *region, const EventList &list) const
{
    TRUE_ASSERT(ptr_to_host_data != NULL, "data == 0");
    TRUE_ASSERT(queue.context() == *this->context(), "Context of queue and this must be equal");
    OPENCL_SAFE_CALL( clEnqueueWriteImage(queue.id(), this->id(), CL_TRUE, origin, region, 0, 0, ptr_to_host_data, list.size(), list.events().data(), NULL) );
    OPENCL_SAFE_CALL( clFinish(queue.id()) );
}
Esempio n. 6
0
/*! \brief Copies the Event.
  *
  * Note that no deep copy is performed. Both Event Objects
  * refer to the same OpenCL event.
  *
  * \param other Event from which the OpenCL Event and Context is taken from.
  */
ocl::Event::Event( const Event & other ) : _id(other._id), _ctxt(other._ctxt)
{
    TRUE_ASSERT(_id != 0, "Event not valid (id == 0)");
    TRUE_ASSERT(_ctxt != 0, "Event not valid (ctxt == 0)");


	OPENCL_SAFE_CALL( clRetainEvent( _id ) );
}
Esempio n. 7
0
/**
 * \brief ocl::Image::writeAsync Transfers data from host memory to this Image.
 *
 * Waits until the event list is completed. Be sure that the queue
 * and this Image are in the same context.
 * \param queue is a command queue on which the command is executed.
 * \param origin is the 3D offset in bytes from which the Image is read.
 * \param ptr_to_host_data must point to a memory location whith region bytes available.
 * \param region is the 3D region of the data. It is given with {image_width, image_height, image_depth}.
 * \param list contains all events for which this command has to wait.
 * \return an event which can be further put into an event list for synchronization.
 */
ocl::Event ocl::Image::writeAsync(const Queue &queue, size_t *origin, const void *ptr_to_host_data, const size_t *region, const EventList &list) const
{
    TRUE_ASSERT(ptr_to_host_data != NULL, "data == 0");
    TRUE_ASSERT(queue.context() == *this->context(), "Context of queue and this must be equal");
    cl_event event_id;
    OPENCL_SAFE_CALL( clEnqueueWriteImage(queue.id(), this->id(), CL_FALSE, origin, region, 0, 0, ptr_to_host_data, list.size(), list.events().data(), &event_id) );
    return ocl::Event(event_id, this->context());
}
Esempio n. 8
0
/*! \brief Instantiates an Event returned by an command Queue instruction.
  *
  * Do not instantiate user events with this constructor.
  *
  * \param id is an OpenCL event id provided by the creating command Queue instruction.
  * \param ctxt is a valid Context provided which is the same as the command queue Context.
  */
ocl::Event::Event(cl_event id, ocl::Context* ctxt) : _id(id), _ctxt(ctxt)
{
    TRUE_ASSERT(id != 0, "Event not valid.");
    TRUE_ASSERT(ctxt != 0, "Context not valid");

    cl_context cl_ctxt = 0;
    OPENCL_SAFE_CALL( clGetEventInfo (this->id(), CL_EVENT_CONTEXT , sizeof(cl_ctxt), &cl_ctxt, NULL));
    TRUE_ASSERT(_ctxt->id() == cl_ctxt, "Context must be the same");
}
Esempio n. 9
0
/*! \brief Instantiates a user Event.
  *
  * You can add this event to track a command within a command Queue by adding this
  * Event into the EventList of the command. This
  * Event is created using the provided Context.
  */
ocl::Event::Event(ocl::Context& ctxt) : _id(0), _ctxt(&ctxt)
{
    TRUE_ASSERT(this->_ctxt != 0, "Context not valid");

    cl_int err;
    _id =  clCreateUserEvent (_ctxt->id(), &err);
    OPENCL_SAFE_CALL(err);
    TRUE_ASSERT(_id != 0, "Could not create user event");
}
Esempio n. 10
0
/**
 * \brief ocl::Image::copyToAsync Copies asynchronously from this Image to the destination Image.
 *
 * \param queue is a command queue on which the command is executed.
 * \param src_origin is the 3D offset in bytes from which the Image is read.
 * \param region is the 3D region of the data. It is given with {image_width, image_height, image_depth}.
 * \param dest is the Image into which the data is going to be copied.
 * \param dest_origin is the 3D offset in bytes from which the destionation Image is read.
 * \param list contains all events for which this command has to wait.
 * \return event which can be integrated into other EventList.
 */
ocl::Event ocl::Image::copyToAsync(const Queue &queue, size_t *src_origin, const size_t *region, const Image &dest, size_t *dest_origin, const EventList &list)
{
    TRUE_ASSERT(this->context() == dest.context(), "Context of this and dest must be equal");
    TRUE_ASSERT(queue.context() == *this->context(), "Context of queue and this must be equal");
    cl_event event_id;
    OPENCL_SAFE_CALL( clEnqueueCopyImage(queue.id(), this->id(), dest.id(),
                                         src_origin, dest_origin, region, list.size(),
                                         list.events().data(), &event_id) );
    return ocl::Event(event_id, this->context());
}
Esempio n. 11
0
/**
 * \brief ocl::Image::copyToAsync Copies asynchronously from this Image to the destination Image.
 *
 * \param src_origin is the 3D offset in bytes from which the Image is read.
 * \param region is the 3D region of the data. It is given with {image_width, image_height, image_depth}.
 * \param dest is the Image into which the data is going to be copied.
 * \param dest_origin is the 3D offset in bytes from which the destionation Image is read.
 * \param list contains all events for which this command has to wait.
 * \return event which can be integrated into other EventList.
 */
ocl::Event ocl::Image::copyToAsync(size_t *src_origin, const size_t *region, const Image &dest, size_t *dest_origin, const EventList &list)
{
    TRUE_ASSERT(this->context() == dest.context(), "Context of this and dest must be equal");
    TRUE_ASSERT(this->id() != dest.id(), "Images must not be equal this->id() " << this->id() << "; other.id " << dest.id());
    cl_event event_id;
    OPENCL_SAFE_CALL( clEnqueueCopyImage(this->activeQueue().id(), this->id(), dest.id(),
                                         src_origin, dest_origin, region, list.size(),
                                         list.events().data(), &event_id) );
    return ocl::Event(event_id, this->context());
}
Esempio n. 12
0
/*! \brief Instantiates a user Event.
  *
  * You can add this event to track a command within a command Queue by adding this
  * Event into the EventList of the command.
  * If there is an active Platform and an active Context
  * this Event is created. Otherwise do not forget
  * to provide a Context and to create this Event.
  */
ocl::Event::Event() : _id(0), _ctxt(0)
{
    if(ocl::Platform::hasActivePlatform() && ocl::Platform::activePlatform()->hasActiveContext()){
        _ctxt = ocl::Platform::activePlatform()->activeContext();
        TRUE_ASSERT(_ctxt != 0, "No active context");
        cl_int err;
        _id =  clCreateUserEvent (_ctxt->id(), &err);
        OPENCL_SAFE_CALL(err);
        TRUE_ASSERT(_id != 0, "Could not create user event");
    }
}
Esempio n. 13
0
/**
 * \brief ocl::Image::map Maps the Image into the host memory.
 *
 *  No data transfer is performed. Note that in order to map data of the Image the active queue must be a cpu and must have been allocated
 *  with the Image access mode AllocHost. You cannot modify the Image with OpenCL until unmap.
 * \param ptr is returned and contains the address of a pointer to the host memory.
 * \param origin is the 3D offset in bytes from which the image is read.
 * \param region is the 3D region in bytes to be mapped.
 * \param access specifies in what way the host_mem is used.
 * \param list contains all events for which this command has to wait.
 * \return event which can be integrated into other EventList
 */
ocl::Event ocl::Image::mapAsync(void **ptr, size_t *origin, const size_t *region, Memory::Access access, const EventList &list) const
{
    TRUE_ASSERT(this->activeQueue().device().isCpu(), "Device " << this->activeQueue().device().name() << " is not a cpu!");
    cl_int status;
    cl_event event_id;
    cl_map_flags flags = access;
    *ptr = clEnqueueMapImage(this->activeQueue().id(), this->id(), CL_TRUE, flags,
                                      origin, region, 0, 0, list.size(), list.events().data(), &event_id, &status);
    OPENCL_SAFE_CALL (status ) ;
    TRUE_ASSERT(ptr != NULL, "Could not map image!");
    return ocl::Event(event_id, this->context());
}
Esempio n. 14
0
/**
 * \brief ocl::Image::map Maps the Image into the host memory.
 *
 *  No data transfer is performed. Note that in order to map data of the Image the active queue must be a cpu and must have been allocated
 *  with the Image access mode AllocHost. You cannot modify the Image with OpenCL until unmap.
 * \param origin is the 3D offset in bytes from which the image is read.
 * \param region is the 3D region in bytes to be mapped.
 * \param access specifies in what way the host_mem is used.
 * \return a void pointer to the mapped host memory location.
 */
void * ocl::Image::map(size_t *origin, const size_t *region, Memory::Access access) const
{
    TRUE_ASSERT(this->activeQueue().device().isCpu(), "Device " << this->activeQueue().device().name() << " is not a cpu!");
    cl_int status;
    cl_map_flags flags = access;
    void *pointer = clEnqueueMapImage(this->activeQueue().id(), this->id(), CL_TRUE, flags,
                                      origin, region, 0, 0, 0, NULL, NULL, &status);
    OPENCL_SAFE_CALL (status ) ;
    TRUE_ASSERT(pointer != NULL, "Could not map image!");
    OPENCL_SAFE_CALL( clFinish(this->activeQueue().id()) );
    return pointer;
}
Esempio n. 15
0
/**
 * \brief ocl::Image::writeAsync Transfers data from host memory to this Image.
 *
 * Waits until the event list is completed.
 * \param origin is the 3D offset in bytes from which the Image is read.
 * \param ptr_to_host_data must point to a memory location whith region bytes available.
 * \param region is the 3D region of the data. It is given with {image_width, image_height, image_depth}.
 * \param list contains all events for which this command has to wait.
 * \return an event which can be further put into an event list for synchronization.
 */
ocl::Event ocl::Image::writeAsync(size_t *origin, const void *ptr_to_host_data, const size_t *region, const EventList &list) const
{
    TRUE_ASSERT(ptr_to_host_data != NULL, "data == 0");
    cl_event event_id;
    OPENCL_SAFE_CALL( clEnqueueWriteImage(this->activeQueue().id(), this->id(), CL_FALSE, origin, region, 0, 0, ptr_to_host_data, list.size(), list.events().data(), &event_id) );
    return ocl::Event(event_id, this->context());
}
Esempio n. 16
0
/*! \brief Set the Context of this Program.
  *
  * Note that you cannot change the context
  * once this Program has been built.
*/
void ocl::Program::setContext(ocl::Context &c)
{
    TRUE_ASSERT(!this->isBuilt(), "Context already built");
    _context = &c;
    _context->insert(this);

}
Esempio n. 17
0
/**
 * \brief ocl::Image::write Transfers data from host memory to this Image.
 *
 * You can be sure that the data is write.
 * \param ptr_to_host_data must point to a memory location whith region bytes available.
 * \param region is the 3D region of the data. It is given with {image_width, image_height, image_depth}.
 */
void ocl::Image::write(const void *ptr_to_host_data, const size_t *region, const EventList &list) const
{
    TRUE_ASSERT(ptr_to_host_data != NULL, "data == 0");
    std::vector<size_t> origin = {0, 0, 0};
    OPENCL_SAFE_CALL( clEnqueueWriteImage(this->activeQueue().id(), this->id(), CL_TRUE, origin.data(), region, 0, 0, ptr_to_host_data, list.size(), list.events().data(), NULL) );
    OPENCL_SAFE_CALL( clFinish(this->activeQueue().id()) );
}
Esempio n. 18
0
ocl::Event& ocl::Event::operator =( ocl::Event const& other )
{

	if ( this == &other ) return *this;

	TRUE_ASSERT(other._id != 0, "Event not valid (id == 0)");
	TRUE_ASSERT(other._ctxt != 0, "Event not valid (ctxt == 0)");

	release();

	_id   = other._id;
	_ctxt = other._ctxt;

	clRetainEvent( _id );
	return *this;
}
Esempio n. 19
0
/*! \brief Returns the reference count of this Event object.*/
size_t ocl::Event::reference_count() const
{
    TRUE_ASSERT(_id != 0, "Cannot get reference count for this. Not yet created.");
    cl_uint info;
    OPENCL_SAFE_CALL( clGetEventInfo (_id, CL_EVENT_REFERENCE_COUNT, sizeof(info), &info, NULL)) ;
    return size_t(info);
}
Esempio n. 20
0
/*! \brief Destroys the Kernel specified by its function name. */
void ocl::Program::deleteKernel(const std::string &name)
{
    iterator it = _kernels.find(name);
    TRUE_ASSERT(it != _kernels.end(), "Kernel " << name << " does not exist yet");
	const Kernel *__k = it->second;
	delete __k;
	_kernels.erase(it);
}
Esempio n. 21
0
/*! \brief Reads kernel functions from an input stream into this Program.
  *
  * The input stream can contain multiple OpenCL kernel
  * functions. It deletes all comments and if the kernels
  * are templated, it substitutes the template parameter
  * with the provided types. For each Kernel function
  * a Kernel object is built and stored within a map.
  * The map stores the name of the kernel function and
  * the corresponding function.
  * Note that DEFINES are not supported yet.
*/
ocl::Program& ocl::Program::operator << (std::istream& stream)
{
	TRUE_ASSERT(!stream.fail(), "Error while opening file.");

    std::stringstream buffer;

    stream >> buffer.rdbuf();

	return (*this) << buffer.str();
}
Esempio n. 22
0
/*! \brief Builds this Program.
	*
    * Do not forget to load Kernel objects into this
    * Program before executing this function.
    * This Program with all Kernel objects are built. Note that
    * compiling and linking in seperate stages are note supported
    * yet. Kernels built with this Program
    * can be executed on all Device objects within the Context
    * for which this Program is built.
*/
void ocl::Program::build()
{
    TRUE_ASSERT(this->_context != 0, "Program has no Context");
    TRUE_ASSERT(this->_id == 0, "Program already built");

    TRUE_ASSERT(!_kernels.empty(), "No kernels loaded for the program");
    std::stringstream stream;

    this->print(stream);
    const std::string &t = stream.str();

    cl_int status;
    const char * file_char = t.c_str(); // stream.str().c_str();
    _id = clCreateProgramWithSource(this->context().id(), 1, (const char**)&file_char,   NULL, &status);
    OPENCL_SAFE_CALL(status);
    cl_int buildErr = clBuildProgram(_id, 0, NULL, _options().c_str(), NULL, NULL);
    checkBuild(buildErr);

    for(auto k : _kernels){
        k.second->create();
    }
}
Esempio n. 23
0
/**
 * \brief ocl::Image::create Creates an OpenCL Image from an OpenGL texture.
 * \param texture OpenGL-ID of the texture.
 * \param texture_target Target of the OpenGL texture.
 * \param miplevel MipMapping level.
 */
void ocl::Image::create(unsigned int texture, unsigned long texture_target, long miplevel)
{
    cl_mem_flags flags = ocl::Image::ReadWrite;
    if (this->_context->devices().size() == 1 &&
						this->_context->devices().front().type() == ocl::device_type::CPU){
        flags |= ocl::Image::AllocHost;
    }

    cl_int status;
#if defined(OPENCL_V1_0) || defined(OPENCL_V1_1)
    this->_id = clCreateFromGLTexture2D(this->_context->id(), flags, texture_target, miplevel, texture, &status);
#else
    this->_id = clCreateFromGLTexture(this->_context->id(), flags, texture_target, miplevel, texture, &status);
#endif
    OPENCL_SAFE_CALL(status);
    TRUE_ASSERT(this->_id != 0, "Could not create shared image.");
}
Esempio n. 24
0
/*! \brief Instantiates this Program for a given Context, predefined Types and CompileOption.
	*
    * This Program is not yet created, only initialized with the given Context, Types and CompileOptions.
    * In order to create it, load Kernel objects into this Program and call the appropriate create function.
    * Templated Kernel functions are then build for the given Types with the CompileOption.
    * The Kernel function name will be changed to kernel_<type>.
    *
    * \param context The Context for which this Program will be created.
    * \param types Types which consist of valid Type objects.
    * \param options defines a valid CompileOption for build process.
*/
ocl::Program::Program(ocl::Context& ctxt, const utl::Types &types, const ocl::CompileOption &options) :
    _id(NULL), _context(&ctxt), _types(types), _options(options)
{
    TRUE_ASSERT(!_types.empty(), "no types selected.");
    _context->insert(this);
}
Esempio n. 25
0
/*! \brief Sets the Types for the Kernel objects.
  *
  * Note that this Progam should not be built.
*/
void ocl::Program::setTypes(utl::Types&& types)
{
    TRUE_ASSERT(!types.empty(), "Types should not be empty");
    TRUE_ASSERT(!this->isBuilt(), "Program already built.");
    _types = std::move(types);
}
Esempio n. 26
0
/*! \brief Sets the CompileOption for this Program.
  *
  * Note that this should not be built.
*/
void ocl::Program::setCompileOption(const ocl::CompileOption & o)
{
    TRUE_ASSERT(!this->isBuilt(), "Program already built.");
    _options = o;
}
Esempio n. 27
0
/*! \brief Returns the context with which this Event was created.*/
ocl::Context& ocl::Event::context() const
{
    TRUE_ASSERT(this->_ctxt != 0, "No Context for Event");
    return *this->_ctxt;
}
Esempio n. 28
0
/*! \brief Returns the Context of this Program. */
ocl::Context& ocl::Program::context() const
{
    TRUE_ASSERT(this->_context != 0, "Context not valid.");
    return *this->_context;
}
Esempio n. 29
0
/*! \brief Returns the Kernel from this Program by providing the Kernel's function name and its Type.*/
ocl::Kernel& ocl::Program::kernel(const std::string &name, const utl::Type &t) const
{
    TRUE_ASSERT(_types.contains(t), "Type "<< t.name() <<" not found.");
    std::string n = name; n+= "_"; n+= t.name();
	return this->kernel(n);
}
Esempio n. 30
0
/*! \brief Returns the Kernel from this Program by providing the Kernel's function name.*/
ocl::Kernel& ocl::Program::kernel(const std::string &name) const
{
    const_iterator it = _kernels.find(name);
    TRUE_ASSERT(it != _kernels.end(), "Kernel " << name << " does not exist yet");
	return *(it->second);
}