/** * \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; }
*/ 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; }
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; }
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'); } }
*/ void Trap3(REBCNT num, REBVAL *arg1, REBVAL *arg2, REBVAL *arg3) /* ***********************************************************************/ { Throw_Error(Make_Error(num, arg1, arg2, arg3)); }
*/ void Trap2(REBCNT num, REBVAL *arg1, REBVAL *arg2) /* ***********************************************************************/ { Throw_Error(Make_Error(num, arg1, arg2, 0)); }
*/ void Trap1(REBCNT num, REBVAL *arg1) /* ***********************************************************************/ { Throw_Error(Make_Error(num, arg1, 0, 0)); }
*/ void Trap0(REBCNT num) /* ***********************************************************************/ { Throw_Error(Make_Error(num, 0, 0, 0)); }