/**
 * \related cl_Steel_Thread_t
 *
 * This function allocates memory for structure, initialize OpenCL & set
 * function pointers
 *
 * @param[in] device_type type of OpenCL device(s) we want to initialize
 * @param[in] init_params Additional parameters, that will be passed at OpenCL
 * program building stage for all objects, that will have this Steel Thread as
 * parent one.
 *
 * @return pointer to allocated structure in case of success,
 * \ref VOID_STEEL_THREAD_PTR otherwise
 *
 * @warning always use 'Destroy' function pointer to free memory, allocated by
 * this function.
 */
scow_Steel_Thread* Make_Steel_Thread(cl_device_id given_device)
{
    scow_Steel_Thread* self = (scow_Steel_Thread*) calloc(1, sizeof(*self));
    OCL_CHECK_EXISTENCE(self, VOID_STEEL_THREAD_PTR);

    self->error             = Make_Error();
    self->Destroy           = Steel_Thread_Destroy;
    self->Wait_For_Commands = Steel_Thread_Wait_For_Cmd;
    self->Wait_For_Data     = Steel_Thread_Wait_For_Data;
    self->FlushCmd          = Steel_Thread_Flush_Cmd;

    // Get OpenCL Platform, to which OpenCL Device belongs to;
    cl_platform_id platform;
    ret_code ret = clGetDeviceInfo(given_device, CL_DEVICE_PLATFORM, sizeof(platform),
        &platform, NULL);
    OCL_DIE_ON_ERROR(ret, CL_SUCCESS, self->Destroy(self), VOID_STEEL_THREAD_PTR);

    // And initialize SCOW wrappers around then
    self->device = Make_Device(given_device);
    OCL_CHECK_EXISTENCE_AND_DO(self->device, self->Destroy(self),
        VOID_STEEL_THREAD_PTR);

    self->platform = Make_Platform(platform);
    OCL_CHECK_EXISTENCE_AND_DO(self->platform, self->Destroy(self),
        VOID_STEEL_THREAD_PTR);

    // Init OpenCL at last
    ret = Init_OpenCL(self);
    OCL_DIE_ON_ERROR(ret, CL_SUCCESS, self->Destroy(self), NULL);

    return self;
}
Example #2
0
*/	static void Scan_Error(REBCNT errnum, SCAN_STATE *ss, REBCNT tkn, REBYTE *arg, REBCNT size, REBVAL *relax)
/*
**		Scanner error handler
**
***********************************************************************/
{
	ERROR_OBJ *error;
	REBSER *errs;
	REBYTE *name;
	REBYTE *cp;
	REBYTE *bp;
	REBSER *ser;
	REBCNT len = 0;

	ss->errors++;

	if (PG_Boot_Strs)
		name = BOOT_STR(RS_SCAN,tkn);
	else
		name = (REBYTE*)"boot";

	cp = ss->head_line;
    while (IS_LEX_SPACE(*cp)) cp++;	// skip indentation
	bp = cp;
	while (NOT_NEWLINE(*cp)) cp++, len++;

	//DISABLE_GC;
	errs = Make_Error(errnum, 0, 0, 0);
	error = (ERROR_OBJ *)FRM_VALUES(errs);
	ser = Make_Binary(len + 16);
	Append_Bytes(ser, "(line ");
	Append_Int(ser, ss->line_count);
	Append_Bytes(ser, ") ");
	Append_Series(ser, (REBYTE*)bp, len);
	Set_String(&error->nearest, ser);
	Set_String(&error->arg1, Copy_Bytes(name, -1));
	Set_String(&error->arg2, Copy_Bytes(arg, size));

	if (relax) {
		SET_ERROR(relax, errnum, errs);
		//ENABLE_GC;
		return;
	}

	Throw_Error(errs);	// ENABLE_GC implied
}
/**
 * \related cl_Mem_Object_t
 *
 * This function allocates memory for Memory Object with generic data container
 * & sets function pointers
 *
 * @param[in] parent_thread parent Steel Thread, which gives OpenCL context, etc
 * @param[in] mem_flags OpenCL memory flags, which will be used for OpenCL
 * memory objects creation
 * @param[in] size amount of memory, which will be allocated, in bytes
 * @param[in] host_ptr pointer to Host-side memory region (if any). This argument
 * is optional. If not needed - provide null pointer instead.
 *
 * @return pointer to allocated structure in case of success,
 * \ref VOID_MEM_OBJ_PTR otherwise
 *
 * @warning always use 'Destroy' function pointer to free memory, allocated
 * by this function.
 */
scow_Mem_Object* Make_Buffer(scow_Steel_Thread *parent_thread,
        const cl_mem_flags mem_flags, const size_t size, void *host_ptr)
{
    cl_int ret;
    scow_Mem_Object* self;

    OCL_CHECK_EXISTENCE(parent_thread, VOID_MEM_OBJ_PTR);

    self = (scow_Mem_Object*) calloc(1, sizeof(*self));
    OCL_CHECK_EXISTENCE(self, VOID_MEM_OBJ_PTR);

    self->obj_mem_type = BUFFER;
    self->size = size;
    self->host_ptr = host_ptr;
    self->mem_flags = mem_flags;
    self->parent_thread = parent_thread;

    self->error = Make_Error();
    self->timer = Make_Timer(VOID_KERNEL_PTR);

    self->Get_Mem_Obj = Mem_Object_Get_Mem_Obj;
    self->Destroy = Mem_Object_Destroy;
    self->Swap = Mem_Object_Swap;
    self->Unmap = Mem_Object_Unmap;

    self->Map = Buffer_Map;
    self->Write = Buffer_Send_To_Device;
    self->Read = Buffer_Get_From_Device;
    self->Copy = Buffer_Copy;
    self->Erase = Buffer_Erase;
    self->Sync = Mem_Object_Sync;

    self->Get_Height = Buffer_Get_Height;
    self->Get_Width = Buffer_Get_Width;
    self->Get_Row_Pitch = Buffer_Get_Row_Pitch;
    self->Make_Child = Buffer_Make_Sub_Buffer;

    self->cl_mem_object = clCreateBuffer(self->parent_thread->context,
            self->mem_flags, self->size, self->host_ptr, &ret);

    OCL_DIE_ON_ERROR(ret, CL_SUCCESS, self->Destroy(self), VOID_MEM_OBJ_PTR);

    return self;
}
Example #4
0
STOID Mold_Error(REBVAL *value, REB_MOLD *mold, REBFLG molded)
{
	ERROR_OBJ *err;
	REBVAL *msg;  // Error message block

	// Protect against recursion. !!!!

	if (molded) {
		if (VAL_OBJ_FRAME(value) && VAL_ERR_NUM(value) >= RE_NOTE && VAL_ERR_OBJECT(value))
			Mold_Object(value, mold);
		else {
			// Happens if throw or return is molded.
			// make error! 0-3
			Pre_Mold(value, mold);
			Append_Int(mold->series, VAL_ERR_NUM(value));
			End_Mold(mold);
		}
		return;
	}

	// If it is an unprocessed BREAK, THROW, CONTINUE, RETURN:
	if (VAL_ERR_NUM(value) < RE_NOTE || !VAL_ERR_OBJECT(value)) {
		VAL_ERR_OBJECT(value) = Make_Error(VAL_ERR_NUM(value), value, 0, 0); // spoofs field
	}
	err = VAL_ERR_VALUES(value);

	// Form: ** <type> Error:
	Emit(mold, "** WB", &err->type, RS_ERRS+0);

	// Append: error message ARG1, ARG2, etc.
	msg = Find_Error_Info(err, 0);
	if (msg) {
		if (!IS_BLOCK(msg)) Mold_Value(mold, msg, 0);
		else {
			//start = DSP + 1;
			//Reduce_In_Frame(VAL_ERR_OBJECT(value), VAL_BLK_DATA(msg));
			//SERIES_TAIL(DS_Series) = DSP + 1;
			//Form_Block_Series(DS_Series, start, mold, 0);
			Form_Block_Series(VAL_SERIES(msg), 0, mold, VAL_ERR_OBJECT(value));
		}
	} else
		Append_Boot_Str(mold->series, RS_ERRS+1);

	Append_Byte(mold->series, '\n');

	// Form: ** Where: function
	value = &err->where;
	if (VAL_TYPE(value) > REB_NONE) {
		Append_Boot_Str(mold->series, RS_ERRS+2);
		Mold_Value(mold, value, 0);
		Append_Byte(mold->series, '\n');
	}

	// Form: ** Near: location
	value = &err->nearest;
	if (VAL_TYPE(value) > REB_NONE) {
		Append_Boot_Str(mold->series, RS_ERRS+3);
		if (IS_STRING(value)) // special case: source file line number
			Append_String(mold->series, VAL_SERIES(value), 0, VAL_TAIL(value));
		else if (IS_BLOCK(value))
			Mold_Simple_Block(mold, VAL_BLK_DATA(value), 60);
		Append_Byte(mold->series, '\n');
	}
}
/**
 * \related cl_Mem_Object_t
 *
 * This function allocates memory for Memory Object with OpenCL image & sets
 * function pointers.
 *
 * @param[in] parent_thread parent Steel Thread, which gives OpenCL context, etc
 * @param[in] mem_flags OpenCL memory flags, which will be used for OpenCL
 * memory objects creation
 * @param[in] image_format OpenCL image format, that describe characteristics
 * @param[in] width image width
 * @param[in] height image height
 * @param[in] host_ptr pointer to Host-side memory region (if any). This argument
 * is optional. If not needed - provide null pointer instead.
 *
 * @return pointer to allocated structure in case of success,
 * \ref VOID_MEM_OBJ_PTR otherwise
 *
 * @warning always use 'Destroy' function pointer to free memory, allocated
 * by this function.
 */
scow_Mem_Object* Make_Image(
    scow_Steel_Thread       *parent_thread,
    const cl_mem_flags      mem_flags, 
    const cl_image_format   *image_format,
    const size_t            width, 
    const size_t            height, 
    const size_t            row_pitch,
    void                    *host_ptr)
{
    cl_int ret;
    scow_Mem_Object* self;

    OCL_CHECK_EXISTENCE(parent_thread, VOID_MEM_OBJ_PTR);
    OCL_CHECK_EXISTENCE(image_format, VOID_MEM_OBJ_PTR);

    self = (scow_Mem_Object*) calloc(1, sizeof(*self));
    OCL_CHECK_EXISTENCE(self, VOID_MEM_OBJ_PTR);

    self->obj_mem_type = IMAGE;
    self->parent_thread = parent_thread;
    self->host_ptr = host_ptr;
    self->mem_flags = mem_flags;
    self->width = width;
    self->height = height;
    self->row_pitch = 0;

    self->error = Make_Error();
    self->timer = Make_Timer(VOID_KERNEL_PTR);

    self->Get_Mem_Obj = Mem_Object_Get_Mem_Obj;
    self->Destroy = Mem_Object_Destroy;
    self->Swap = Mem_Object_Swap;
    self->Unmap = Mem_Object_Unmap;

    self->Map = Image_Map;
    self->Write = Image_Send_To_Device;
    self->Read = Image_Get_From_Device;
    self->Copy = Image_Copy;
    self->Erase = NULL;
    self->Sync = Mem_Object_Sync;

    self->Get_Height = Image_Get_Height;
    self->Get_Width = Image_Get_Width;
    self->Get_Row_Pitch = Image_Get_Row_Pitch;
    self->Make_Child = NULL;

#ifdef CL_USE_DEPRECATED_OPENCL_1_1_APIS
	self->cl_mem_object = clCreateImage2D(self->parent_thread->context,
            mem_flags, image_format, self->width, self->height, self->row_pitch,
            host_ptr, &ret);
#else
    cl_image_desc image_desc = {
        .image_type         = CL_MEM_OBJECT_IMAGE2D,
        .image_width        = self->width,
        .image_height       = self->height,
        .image_array_size   = 1,
        .image_row_pitch    = self->row_pitch,
        .image_slice_pitch  = host_ptr ? (self->row_pitch * self->height) : 0,
        .num_mip_levels     = 0,
        .num_samples        = 0,
        .buffer             = NULL
    };
    self->cl_mem_object = clCreateImage(self->parent_thread->context,
        mem_flags, image_format, &image_desc, host_ptr, &ret);
#endif

    OCL_DIE_ON_ERROR(ret, CL_SUCCESS, self->Destroy(self), VOID_MEM_OBJ_PTR);

    return self;
}
/**
 * \related cl_Mem_Object_t
 *
 * This function allocates memory for child Memory Object with generic data
 * container & sets function pointers
 *
 * @param[in] self pointer to existing Memory Object, in which function pointer
 * 'Make_Child' is defined to point on this function.
 * @param[in] mem_flags OpenCL memory flags, which will be used for OpenCL
 * sub-buffer creation
 * @param[in] buffer_create_type information about sub-buffer creation type
 * @param[in] buffer_create_info structure with sub-buffer origin & size
 * values.
 *
 * @return pointer to allocated structure in case of success,
 * \ref VOID_MEM_OBJ_PTR otherwise. In case of error it sets error code, which
 * is available via 'error' structure.
 *
 * @warning always use 'Destroy' function pointer to free memory, allocated
 * by this function.
 */
static scow_Mem_Object* Buffer_Make_Sub_Buffer(scow_Mem_Object *self,
        cl_mem_flags flags, cl_buffer_create_type buffer_create_type,
        const void *buffer_create_info)
{
    OCL_CHECK_EXISTENCE(self, VOID_MEM_OBJ_PTR);

    cl_int ret;
    scow_Mem_Object* child;

    /* Sub-buffer creation is defined only for Buffer, which isn't someone's
     * child. */
    if (self->obj_mem_type != BUFFER)
    {
        ret = INVALID_ARG_TYPE;
        self->error->Set_Last_Code(self->error, ret);
        OCL_DIE_ON_ERROR(ret, CL_SUCCESS, NULL, VOID_MEM_OBJ_PTR);
    }

    if (self->obj_paternity != PARENT_OBJECT)
    {
        ret = WRONG_PARENT_OBJECT;
        self->error->Set_Last_Code(self->error, ret);
        OCL_DIE_ON_ERROR(ret, CL_SUCCESS, NULL, VOID_MEM_OBJ_PTR);
    }

    child = (scow_Mem_Object*) calloc(1, sizeof(*child));
    OCL_CHECK_EXISTENCE(child, VOID_MEM_OBJ_PTR);

    child->obj_mem_type = BUFFER;
    child->obj_paternity = CHILD_OBJECT;
    child->mem_flags = flags;
    child->parent_thread = self->parent_thread;

    child->error = Make_Error();
    child->timer = Make_Timer(VOID_KERNEL_PTR);

    child->Get_Mem_Obj = Mem_Object_Get_Mem_Obj;
    child->Destroy = Mem_Object_Destroy;
    child->Swap = Mem_Object_Swap;
    child->Unmap = Mem_Object_Unmap;

    child->Map = Buffer_Map;
    child->Write = Buffer_Send_To_Device;
    child->Read = Buffer_Get_From_Device;
    child->Copy = Buffer_Copy;
    child->Erase = Buffer_Erase;
    child->Sync = Mem_Object_Sync;

    child->Get_Height = Buffer_Get_Height;
    child->Get_Width = Buffer_Get_Width;
    child->Get_Row_Pitch = Buffer_Get_Row_Pitch;
    child->Make_Child = Buffer_Make_Sub_Buffer;

    child->cl_mem_object = clCreateSubBuffer(self->cl_mem_object, flags,
            buffer_create_type, buffer_create_info, &ret);

    OCL_DIE_ON_ERROR(ret, CL_SUCCESS, child->Destroy(child), VOID_MEM_OBJ_PTR);

    child->size = ((cl_buffer_region*) buffer_create_info)->size;
    child->origin = ((cl_buffer_region*) buffer_create_info)->origin;

    if (self->host_ptr)
    {
        child->host_ptr = (unsigned char*)self->host_ptr + child->origin;
    }

    return child;
}
Example #7
0
static void Mold_Error(const REBVAL *value, REB_MOLD *mold, REBFLG molded)
{
	ERROR_OBJ *err;
	REBVAL *msg;  // Error message block
	REBSER *frame;

	// Protect against recursion. !!!!

	if (molded) {
		if (VAL_OBJ_FRAME(value) && VAL_ERR_NUM(value) >= RE_NOTE && VAL_ERR_OBJECT(value))
			Mold_Object(value, mold);
		else {
			// Happens if throw or return is molded.
			// make error! 0-3
			Pre_Mold(value, mold);
			Append_Int(mold->series, VAL_ERR_NUM(value));
			End_Mold(mold);
		}
		return;
	}

	if (VAL_ERR_NUM(value) < RE_THROW_MAX) {
		// Though we generally do not make error objects for THROWN() errors,
		// we do make one here for the purposes of molding.
		frame = Make_Error(VAL_ERR_NUM(value), value, 0, 0);
		err = ERR_VALUES(frame);
	}
	else {
		frame = VAL_ERR_OBJECT(value);
		err = VAL_ERR_VALUES(value);
	}

	// Form: ** <type> Error:
	Emit(mold, "** WB", &err->type, RS_ERRS+0);

	// Append: error message ARG1, ARG2, etc.
	msg = Find_Error_Info(err, 0);
	if (msg) {
		if (!IS_BLOCK(msg)) Mold_Value(mold, msg, 0);
		else {
			//start = DSP + 1;
			//Reduce_In_Frame(frame, VAL_BLK_DATA(msg));
			//SERIES_TAIL(DS_Series) = DSP + 1;
			//Form_Block_Series(DS_Series, start, mold, 0);
			Form_Block_Series(VAL_SERIES(msg), 0, mold, frame);
		}
	} else
		Append_Boot_Str(mold->series, RS_ERRS+1);

	Append_Byte(mold->series, '\n');

	// Form: ** Where: function
	value = &err->where;
	if (VAL_TYPE(value) > REB_NONE) {
		Append_Boot_Str(mold->series, RS_ERRS+2);
		Mold_Value(mold, value, 0);
		Append_Byte(mold->series, '\n');
	}

	// Form: ** Near: location
	value = &err->nearest;
	if (VAL_TYPE(value) > REB_NONE) {
		Append_Boot_Str(mold->series, RS_ERRS+3);
		if (IS_STRING(value)) // special case: source file line number
			Append_String(mold->series, VAL_SERIES(value), 0, VAL_TAIL(value));
		else if (IS_BLOCK(value))
			Mold_Simple_Block(mold, VAL_BLK_DATA(value), 60);
		Append_Byte(mold->series, '\n');
	}
}
Example #8
0
*/	void Trap3(REBCNT num, REBVAL *arg1, REBVAL *arg2, REBVAL *arg3)
/*
***********************************************************************/
{
	Throw_Error(Make_Error(num, arg1, arg2, arg3));
}
Example #9
0
*/	void Trap2(REBCNT num, REBVAL *arg1, REBVAL *arg2)
/*
***********************************************************************/
{
	Throw_Error(Make_Error(num, arg1, arg2, 0));
}
Example #10
0
*/	void Trap1(REBCNT num, REBVAL *arg1)
/*
***********************************************************************/
{
	Throw_Error(Make_Error(num, arg1, 0, 0));
}
Example #11
0
*/	void Trap0(REBCNT num)
/*
***********************************************************************/
{
	Throw_Error(Make_Error(num, 0, 0, 0));
}