error* platform__get_devices(clobj_t _plat, clobj_t **_devices, uint32_t *num_devices, cl_device_type devtype) { auto plat = static_cast<platform*>(_plat); return c_handle_error([&] { *num_devices = 0; try { pyopencl_call_guarded(clGetDeviceIDs, plat, devtype, 0, nullptr, buf_arg(*num_devices)); } catch (const clerror &e) { if (e.code() != CL_DEVICE_NOT_FOUND) throw e; *num_devices = 0; } if (*num_devices == 0) { *_devices = nullptr; return; } pyopencl_buf<cl_device_id> devices(*num_devices); pyopencl_call_guarded(clGetDeviceIDs, plat, devtype, devices, buf_arg(*num_devices)); *_devices = buf_to_base<device>(devices).release(); }); }
error* get_gl_object_info(clobj_t mem, cl_gl_object_type *otype, GLuint *gl_name) { auto globj = static_cast<memory_object*>(mem); return c_handle_error([&] { pyopencl_call_guarded(clGetGLObjectInfo, globj, buf_arg(*otype), buf_arg(*gl_name)); }); }
pyopencl_buf<clobj_t> program::all_kernels() { cl_uint num_knls; pyopencl_call_guarded(clCreateKernelsInProgram, this, 0, nullptr, buf_arg(num_knls)); pyopencl_buf<cl_kernel> knls(num_knls); pyopencl_call_guarded(clCreateKernelsInProgram, this, knls, buf_arg(num_knls)); return buf_to_base<kernel>(knls, true); }
error* get_platforms(clobj_t **_platforms, uint32_t *num_platforms) { return c_handle_error([&] { *num_platforms = 0; pyopencl_call_guarded(clGetPlatformIDs, 0, nullptr, buf_arg(*num_platforms)); pyopencl_buf<cl_platform_id> platforms(*num_platforms); pyopencl_call_guarded(clGetPlatformIDs, platforms, buf_arg(*num_platforms)); *_platforms = buf_to_base<platform>(platforms).release(); }); }
error* context__get_supported_image_formats(clobj_t _ctx, cl_mem_flags flags, cl_mem_object_type image_type, generic_info *out) { auto ctx = static_cast<context*>(_ctx); return c_handle_error([&] { cl_uint num; pyopencl_call_guarded(clGetSupportedImageFormats, ctx, flags, image_type, 0, nullptr, buf_arg(num)); pyopencl_buf<cl_image_format> formats(num); pyopencl_call_guarded(clGetSupportedImageFormats, ctx, flags, image_type, formats, buf_arg(num)); *out = pyopencl_convert_array_info(cl_image_format, formats); }); }
void program::compile(const char *opts, const clobj_t *_devs, size_t num_devs, const clobj_t *_prgs, const char *const *names, size_t num_hdrs) { const auto devs = buf_from_class<device>(_devs, num_devs); const auto prgs = buf_from_class<program>(_prgs, num_hdrs); pyopencl_call_guarded(clCompileProgram, this, devs, opts, prgs, buf_arg(names, num_hdrs), nullptr, nullptr); }
void matrix_multiply_cl(pclu_context * pclu, matrix * cc, matrix * aa, matrix * bb) { pclu_program *pgm = pclu_create_program(pclu, "fmma.cl"); char *log = pclu_program_build_log(pgm); if (strlen(log) > 0) printf("Build log:\n%s\n", log); size_t aa_size = matrix_bytes(aa); pclu_buffer *aa_buf = pclu_create_buffer(pclu, aa_size); pclu_write_buffer(aa_buf, aa_size, aa->data); size_t bb_size = matrix_bytes(bb); pclu_buffer *bb_buf = pclu_create_buffer(pclu, bb_size); pclu_write_buffer(bb_buf, bb_size, bb->data); size_t cc_size = matrix_bytes(cc); pclu_buffer *cc_buf = pclu_create_buffer(pclu, cc_size); pclu_write_buffer(cc_buf, cc_size, cc->data); pclu_range range = pclu_range_2d(cc->rows, cc->cols); cl_long nn = SIZE; cl_long spin = SPIN; timer* tt = timer_alloc(); pclu_call_kernel(pgm, "fmma", range, 5, buf_arg(cc_buf), buf_arg(aa_buf), buf_arg(bb_buf), lit_arg(nn), lit_arg(spin)); double kt = timer_read(tt); timer_free(tt); printf("Kernel took %.04f seconds.\n", kt); pclu_read_buffer(cc_buf, cc_size, cc->data); printf("alpha\n"); pclu_destroy_program(pgm); printf("beta\n"); }
void context::get_version(cl_context ctx, int *major, int *minor) { cl_device_id s_buff[16]; size_t size; pyopencl_buf<cl_device_id> d_buff(0); cl_device_id *devs = s_buff; pyopencl_call_guarded(clGetContextInfo, ctx, CL_CONTEXT_DEVICES, 0, nullptr, buf_arg(size)); if (PYOPENCL_UNLIKELY(!size)) { throw clerror("Context.get_version", CL_INVALID_VALUE, "Cannot get devices from context."); } if (PYOPENCL_UNLIKELY(size > sizeof(s_buff))) { d_buff.resize(size / sizeof(cl_device_id)); devs = d_buff.get(); } pyopencl_call_guarded(clGetContextInfo, ctx, CL_CONTEXT_DEVICES, size_arg(devs, size), buf_arg(size)); device::get_version(devs[0], major, minor); }
// Program error* create_program_with_source(clobj_t *prog, clobj_t _ctx, const char *_src) { auto ctx = static_cast<context*>(_ctx); return c_handle_error([&] { const auto &src = _src; const size_t length = strlen(src); cl_program result = pyopencl_call_guarded( clCreateProgramWithSource, ctx, len_arg(src), buf_arg(length)); *prog = new_program(result, KND_SOURCE); }); }
void platform::get_version(cl_platform_id plat, int *major, int *minor) { char s_buff[128]; size_t size; pyopencl_buf<char> d_buff(0); char *name = s_buff; pyopencl_call_guarded(clGetPlatformInfo, plat, CL_PLATFORM_VERSION, 0, nullptr, buf_arg(size)); if (PYOPENCL_UNLIKELY(size > sizeof(s_buff))) { d_buff.resize(size); name = d_buff.get(); } pyopencl_call_guarded(clGetPlatformInfo, plat, CL_PLATFORM_VERSION, size_arg(name, size), buf_arg(size)); std::cmatch ver_match; if (!std::regex_match(name, ver_match, ver_regex)) { throw clerror("Platform.get_version", CL_INVALID_VALUE, "platform returned non-conformant " "platform version string"); } *major = atoi(name + ver_match.position(1)); *minor = atoi(name + ver_match.position(2)); }