static int bfam_ts_adams_update(const char * key, void *val, void *arg) { bfam_ts_adams_allprefix_t *data = (bfam_ts_adams_allprefix_t *) arg; bfam_subdomain_t* sub = (bfam_subdomain_t*) val; bfam_ts_adams_t* ts = data->ts; switch(BFAM_MIN(ts->numSteps+1,ts->nStages)) { case 1: { bfam_long_real_t A[1] = {BFAM_LONG_REAL(1.0)}; bfam_ts_adams_do_update(sub, A, ts, data->dt, 1); } break; case 2: { bfam_long_real_t A[2] = { BFAM_LONG_REAL( 3.0) / BFAM_LONG_REAL( 2.0), BFAM_LONG_REAL(-1.0) / BFAM_LONG_REAL( 2.0), }; bfam_ts_adams_do_update(sub, A, ts, data->dt, 2); } break; case 3: { bfam_long_real_t A[3] = { BFAM_LONG_REAL(23.0)/ BFAM_LONG_REAL(12.0), BFAM_LONG_REAL(-4.0)/ BFAM_LONG_REAL( 3.0), BFAM_LONG_REAL( 5.0)/ BFAM_LONG_REAL(12.0), }; bfam_ts_adams_do_update(sub, A, ts, data->dt, 3); } break; case 4: { bfam_long_real_t A[4] = { BFAM_LONG_REAL( 55.0)/ BFAM_LONG_REAL( 24.0), BFAM_LONG_REAL(-59.0)/ BFAM_LONG_REAL( 24.0), BFAM_LONG_REAL( 37.0)/ BFAM_LONG_REAL( 24.0), BFAM_LONG_REAL( -3.0)/ BFAM_LONG_REAL( 8.0), }; bfam_ts_adams_do_update(sub, A, ts, data->dt, 4); } break; default: BFAM_ABORT("Adams-Bashforth order %d not implemented",ts->nStages); } return 1; }
cl_kernel bfam_cl_kernel_from_string(cl_context ctx, char const *knl, char const *knl_name, char const *options) { // create an OpenCL program (may have multiple kernels) size_t sizes[] = { strlen(knl) }; cl_int status; cl_program program = clCreateProgramWithSource(ctx, 1, &knl, sizes, &status); BFAM_CL_CHECK(status, "clCreateProgramWithSource"); // build it status = clBuildProgram(program, 0, NULL, options, NULL, NULL); if (status != CL_SUCCESS) { // build failed, get build log and print it cl_device_id dev; BFAM_CL_SAFE_CALL(clGetProgramInfo(program, CL_PROGRAM_DEVICES, sizeof(dev), &dev, NULL)); size_t log_size; BFAM_CL_SAFE_CALL(clGetProgramBuildInfo(program, dev, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size)); char *log = (char *) bfam_malloc(log_size); char devname[MAX_NAME_LEN]; BFAM_CL_SAFE_CALL(clGetDeviceInfo(dev, CL_DEVICE_NAME, sizeof(devname), devname, NULL)); BFAM_CL_SAFE_CALL(clGetProgramBuildInfo(program, dev, CL_PROGRAM_BUILD_LOG, log_size, log, NULL)); BFAM_LERROR("*** build of '%s' on '%s' failed:\n%s\n*** (end of error)\n", knl_name, devname, log); BFAM_ABORT("Building kernel from a string"); } else BFAM_CL_CHECK(status, "clBuildProgram"); // fish the kernel out of the program cl_kernel kernel = clCreateKernel(program, knl_name, &status); BFAM_CL_CHECK(status, "clCreateKernel"); BFAM_CL_SAFE_CALL(clReleaseProgram(program)); return kernel; }
void bfam_cl_create_context_on(const char *plat_name, const char *dev_name, cl_uint idx, cl_context *ctx, cl_command_queue *queue, int enable_profiling) { char dev_sel_buf[MAX_NAME_LEN]; char platform_sel_buf[MAX_NAME_LEN]; // get number of platforms cl_uint plat_count; BFAM_CL_SAFE_CALL(clGetPlatformIDs(0, NULL, &plat_count)); // allocate memory, get list of platform handles cl_platform_id *platforms = (cl_platform_id *) bfam_malloc(plat_count*sizeof(cl_platform_id)); BFAM_CL_SAFE_CALL(clGetPlatformIDs(plat_count, platforms, NULL)); // print menu, if requested #ifndef BFAM_CL_HELPER_FORCE_INTERACTIVE if (plat_name == CHOOSE_INTERACTIVELY) // yes, we want exactly that pointer #endif { puts("Choose platform:"); for (cl_uint i = 0; i < plat_count; ++i) { char buf[MAX_NAME_LEN]; BFAM_CL_SAFE_CALL(clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, sizeof(buf), buf, NULL)); printf("[%d] %s\n", i, buf); } printf("Enter choice: "); fflush(stdout); char *sel = read_a_line(); if (!sel) { BFAM_ABORT("error reading line from stdin"); } int sel_int = BFAM_MIN(BFAM_MAX(0, atoi(sel)), (int) plat_count-1); bfam_free(sel); BFAM_CL_SAFE_CALL(clGetPlatformInfo(platforms[sel_int], CL_PLATFORM_VENDOR, sizeof(platform_sel_buf), platform_sel_buf, NULL)); plat_name = platform_sel_buf; } // iterate over platforms for (cl_uint i = 0; i < plat_count; ++i) { // get platform name char buf[MAX_NAME_LEN]; BFAM_CL_SAFE_CALL(clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, sizeof(buf), buf, NULL)); // does it match? if (!plat_name || strstr(buf, plat_name)) { // get number of devices in platform cl_uint dev_count; BFAM_CL_SAFE_CALL(clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, 0, NULL, &dev_count)); // allocate memory, get list of device handles in platform cl_device_id *devices = (cl_device_id *) bfam_malloc(dev_count*sizeof(cl_device_id)); BFAM_CL_SAFE_CALL(clGetDeviceIDs(platforms[i], CL_DEVICE_TYPE_ALL, dev_count, devices, NULL)); // {{{ print device menu, if requested #ifndef BFAM_CL_HELPER_FORCE_INTERACTIVE if (dev_name == CHOOSE_INTERACTIVELY) // yes, we want exactly that pointer #endif { puts("Choose device:"); for (cl_uint j = 0; j < dev_count; ++j) { char buf[MAX_NAME_LEN]; BFAM_CL_SAFE_CALL(clGetDeviceInfo(devices[j], CL_DEVICE_NAME, sizeof(buf), buf, NULL)); printf("[%d] %s\n", j, buf); } printf("Enter choice: "); fflush(stdout); char *sel = read_a_line(); if (!sel) { BFAM_ABORT("error reading line from stdin"); abort(); /* Add this for the clang static analysis */ } int int_sel = BFAM_MIN(BFAM_MAX(0, atoi(sel)), (int) dev_count-1); bfam_free(sel); BFAM_CL_SAFE_CALL(clGetDeviceInfo(devices[int_sel], CL_DEVICE_NAME, sizeof(dev_sel_buf), dev_sel_buf, NULL)); dev_name = dev_sel_buf; } // }}} // iterate over devices for (cl_uint j = 0; j < dev_count; ++j) { // get device name char buf[MAX_NAME_LEN]; BFAM_CL_SAFE_CALL(clGetDeviceInfo(devices[j], CL_DEVICE_NAME, sizeof(buf), buf, NULL)); // does it match? if (!dev_name || strstr(buf, dev_name)) { if (idx == 0) { cl_platform_id plat = platforms[i]; cl_device_id dev = devices[j]; bfam_free(devices); bfam_free(platforms); // create a context cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties) plat, 0 }; cl_int status; *ctx = clCreateContext( cps, 1, &dev, NULL, NULL, &status); BFAM_CL_CHECK(status, "clCreateContext"); // create a command queue cl_command_queue_properties qprops = 0; if (enable_profiling) qprops |= CL_QUEUE_PROFILING_ENABLE; *queue = clCreateCommandQueue(*ctx, dev, qprops, &status); BFAM_CL_CHECK(status, "clCreateCommandQueue"); return; } else --idx; } } bfam_free(devices); } } bfam_free(platforms); BFAM_ABORT("create_context_on: specified device not found."); }
int bfam_lua_global_function_call(lua_State *L, const char *name, const char *sig, ...) { va_list vl; int num_arg = 0; int num_res = 0; va_start(vl, sig); char buf[BFAM_LUA_MAX_COMMAND_LEN]; /* Assign the Lua expression to a Lua global variable. */ snprintf(buf, BFAM_LUA_MAX_COMMAND_LEN, BFAM_LUA_EVALEXP_VAR "=%s", name); if (!luaL_dostring(L, buf)) { /* Get the value of the global varibable */ lua_getglobal(L, BFAM_LUA_EVALEXP_VAR); } else { BFAM_ROOT_WARNING("function `%s' not found in lua file", name); return 1; } if (!lua_isfunction(L, -1)) { BFAM_ROOT_WARNING("function `%s' not found in lua file", name); lua_pop(L, 1); return 1; } for (num_arg = 0; sig[num_arg] && sig[num_arg] != '>'; num_arg++) { luaL_checkstack(L, 1, "too many arguments"); switch (sig[num_arg]) { case 'd': lua_pushnumber(L, va_arg(vl, double)); break; case 'l': lua_pushnumber(L, (double)va_arg(vl, bfam_long_real_t)); break; case 'r': lua_pushnumber(L, (double)va_arg(vl, bfam_real_t)); break; case 'i': lua_pushinteger(L, va_arg(vl, int)); break; case 's': lua_pushstring(L, va_arg(vl, char *)); break; case '>': break; default: BFAM_ABORT("function '%s' invalid input argument (%c)", name, sig[num_arg]); } } BFAM_ABORT_IF_NOT(sig[num_arg] == '>', "arguments for '%s' does not contain " " a '>' character", name); num_res = (int)strlen(sig) - num_arg - 1; BFAM_ABORT_IF_NOT(lua_pcall(L, num_arg, num_res, 0) == 0, "error running function %s: %s", name, lua_tostring(L, -1)); for (int n = 0; n < num_res; n++) { switch (sig[num_arg + 1 + n]) { case 'd': BFAM_ABORT_IF_NOT(lua_isnumber(L, n - num_res), "for '%s' return %d expected number got '%s'", name, n, lua_tostring(L, n - num_res)); *va_arg(vl, double *) = (double)lua_tonumber(L, n - num_res); break; case 'l': BFAM_ABORT_IF_NOT(lua_isnumber(L, n - num_res), "for '%s' return %d expected number got '%s'", name, n, lua_tostring(L, n - num_res)); *va_arg(vl, bfam_long_real_t *) = (bfam_long_real_t)lua_tonumber(L, n - num_res); break; case 'r': BFAM_ABORT_IF_NOT(lua_isnumber(L, n - num_res), "for '%s' return %d expected number got '%s'", name, n, lua_tostring(L, n - num_res)); *va_arg(vl, bfam_real_t *) = (bfam_real_t)lua_tonumber(L, n - num_res); break; case 'i': BFAM_ABORT_IF_NOT(lua_isnumber(L, n - num_res), "for '%s' return %d expected number got '%s'", name, n, lua_tostring(L, n - num_res)); *va_arg(vl, int *) = (int)lua_tointeger(L, n - num_res); break; case 's': BFAM_ABORT_IF_NOT(lua_isstring(L, n - num_res), "for '%s' return %d expected string got '%s'", name, n, lua_tostring(L, n - num_res)); *va_arg(vl, const char **) = lua_tostring(L, n - num_res); break; default: BFAM_ABORT("function '%s' invalid output argument (%c)", name, sig[num_arg]); } } lua_pop(L, num_res); va_end(vl); return 0; }