TEST(Mem, set_value_real_single_complex) { // Single precision complex. int n = 100, status = 0; oskar_Mem *mem, *mem2; mem = oskar_mem_create(OSKAR_SINGLE_COMPLEX, OSKAR_GPU, n, &status); oskar_mem_set_value_real(mem, 6.5, 0, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); mem2 = oskar_mem_create_copy(mem, OSKAR_CPU, &status); float2* v = oskar_mem_float2(mem2, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); for (int i = 0; i < n; ++i) { EXPECT_FLOAT_EQ(v[i].x, 6.5); EXPECT_FLOAT_EQ(v[i].y, 0.0); } oskar_mem_free(mem, &status); oskar_mem_free(mem2, &status); }
TEST(Mem, type_check_double_complex) { int status = 0; oskar_Mem *mem; mem = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_CPU, 0, &status); EXPECT_EQ((int)OSKAR_TRUE, oskar_mem_is_double(mem)); EXPECT_EQ((int)OSKAR_TRUE, oskar_mem_is_complex(mem)); EXPECT_EQ((int)OSKAR_TRUE, oskar_mem_is_scalar(mem)); EXPECT_EQ((int)OSKAR_TRUE, oskar_type_is_double(OSKAR_DOUBLE_COMPLEX)); EXPECT_EQ((int)OSKAR_TRUE, oskar_type_is_complex(OSKAR_DOUBLE_COMPLEX)); EXPECT_EQ((int)OSKAR_TRUE, oskar_type_is_scalar(OSKAR_DOUBLE_COMPLEX)); oskar_mem_free(mem, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); }
TEST(Mem, set_value_real_single) { // Single precision real. int n = 100, status = 0; oskar_Mem *mem; mem = oskar_mem_create(OSKAR_SINGLE, OSKAR_CPU, n, &status); oskar_mem_set_value_real(mem, 4.5, 0, 0, &status); float* v = oskar_mem_float(mem, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); for (int i = 0; i < n; ++i) { EXPECT_FLOAT_EQ(v[i], 4.5); } oskar_mem_free(mem, &status); }
TEST(Mem, set_value_real_double) { // Double precision real. int n = 100, status = 0; oskar_Mem *mem; mem = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, n, &status); oskar_mem_set_value_real(mem, 4.5, 0, 0, &status); double* v = oskar_mem_double(mem, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); for (int i = 0; i < n; ++i) { EXPECT_DOUBLE_EQ(v[i], 4.5); } oskar_mem_free(mem, &status); }
int main(int argc, char** argv) { int error = 0; oskar::OptionParser opt("oskar_fits_image_to_sky_model", oskar_version_string()); opt.set_description("Converts a FITS image to an OSKAR sky model. A number " "of options are provided to control how much of the image is used " "to make the sky model."); opt.add_required("FITS file", "The input FITS image to convert."); opt.add_required("sky model file", "The output OSKAR sky model file name to save."); opt.add_flag("-s", "Spectral index. This is the spectral index that will " "be given to each pixel in the output sky model.", 1, "0.0"); opt.add_flag("-f", "Minimum allowed fraction of image peak. Pixel values " "below this fraction will be ignored.", 1, "0.0"); opt.add_flag("-n", "Noise floor in units of original image. " "Pixels below this value will be ignored.", 1, "0.0"); if (!opt.check_options(argc, argv)) return EXIT_FAILURE; // Parse command line. double spectral_index = 0.0; double min_peak_fraction = 0.0; double min_abs_val = 0.0; opt.get("-f")->getDouble(min_peak_fraction); opt.get("-n")->getDouble(min_abs_val); opt.get("-s")->getDouble(spectral_index); // Load the FITS image data. oskar_Sky* sky = oskar_sky_from_fits_file(OSKAR_DOUBLE, opt.get_arg(0), min_peak_fraction, min_abs_val, "Jy/beam", 0, 0.0, spectral_index, &error); // Write out the sky model. oskar_sky_save(opt.get_arg(1), sky, &error); if (error) { oskar_log_error(0, oskar_get_error_string(error)); return error; } oskar_sky_free(sky, &error); return 0; }
static void check_values(const oskar_Mem* approx, const oskar_Mem* accurate) { int status = 0; double min_rel_error, max_rel_error, avg_rel_error, std_rel_error, tol; oskar_mem_evaluate_relative_error(approx, accurate, &min_rel_error, &max_rel_error, &avg_rel_error, &std_rel_error, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); tol = oskar_mem_is_double(approx) && oskar_mem_is_double(accurate) ? 1e-11 : 2e-3; EXPECT_LT(max_rel_error, tol) << std::setprecision(5) << "RELATIVE ERROR" << " MIN: " << min_rel_error << " MAX: " << max_rel_error << " AVG: " << avg_rel_error << " STD: " << std_rel_error; tol = oskar_mem_is_double(approx) && oskar_mem_is_double(accurate) ? 1e-12 : 1e-5; EXPECT_LT(avg_rel_error, tol) << std::setprecision(5) << "RELATIVE ERROR" << " MIN: " << min_rel_error << " MAX: " << max_rel_error << " AVG: " << avg_rel_error << " STD: " << std_rel_error; }
static PyObject* load(PyObject* self, PyObject* args) { oskar_Sky* h = 0; PyObject* capsule = 0; int status = 0, prec = 0; const char *filename = 0, *type = 0; if (!PyArg_ParseTuple(args, "ss", &filename, &type)) return 0; prec = (type[0] == 'S' || type[0] == 's') ? OSKAR_SINGLE : OSKAR_DOUBLE; h = oskar_sky_load(filename, prec, &status); capsule = PyCapsule_New((void*)h, name, (PyCapsule_Destructor)sky_free); /* Check for errors. */ if (status) { PyErr_Format(PyExc_RuntimeError, "oskar_sky_load() failed with code %d (%s).", status, oskar_get_error_string(status)); return 0; } return Py_BuildValue("N", capsule); /* Don't increment refcount. */ }
static PyObject* save(PyObject* self, PyObject* args) { oskar_Sky *h = 0; PyObject* capsule = 0; int status = 0; const char* filename = 0; if (!PyArg_ParseTuple(args, "Os", &capsule, &filename)) return 0; if (!(h = get_handle(capsule))) return 0; /* Save the sky model. */ oskar_sky_save(filename, h, &status); /* Check for errors. */ if (status) { PyErr_Format(PyExc_RuntimeError, "oskar_sky_save() failed with code %d (%s).", status, oskar_get_error_string(status)); return 0; } return Py_BuildValue(""); }
int main(int argc, char** argv) { oskar::OptionParser opt("oskar_cuda_system_info", oskar_version_string()); opt.set_description("Display a summary of the available CUDA capability"); if (!opt.check_options(argc, argv)) return EXIT_FAILURE; // Create the CUDA info structure. int error = 0; oskar_CudaInfo* info = oskar_cuda_info_create(&error); if (error) { oskar_log_error(0, "Could not determine CUDA system information (%s)", oskar_get_error_string(error)); oskar_cuda_info_free(info); return error; } // Log the CUDA system info. oskar_cuda_info_log(NULL, info); oskar_cuda_info_free(info); return 0; }
static PyObject* append(PyObject* self, PyObject* args) { oskar_Sky *h1 = 0, *h2 = 0; PyObject *capsule1 = 0, *capsule2 = 0; int status = 0; if (!PyArg_ParseTuple(args, "OO", &capsule1, &capsule2)) return 0; if (!(h1 = get_handle(capsule1))) return 0; if (!(h2 = get_handle(capsule2))) return 0; /* Append the sky model. */ oskar_sky_append(h1, h2, &status); /* Check for errors. */ if (status) { PyErr_Format(PyExc_RuntimeError, "oskar_sky_append() failed with code %d (%s).", status, oskar_get_error_string(status)); return 0; } return Py_BuildValue(""); }
static PyObject* create_copy(PyObject* self, PyObject* args) { oskar_Sky *h = 0, *t = 0; PyObject* capsule = 0; int status = 0; if (!PyArg_ParseTuple(args, "O", &capsule)) return 0; if (!(h = get_handle(capsule))) return 0; t = oskar_sky_create_copy(h, OSKAR_CPU, &status); /* Check for errors. */ if (status || !t) { PyErr_Format(PyExc_RuntimeError, "oskar_sky_create_copy() failed with code %d (%s).", status, oskar_get_error_string(status)); oskar_sky_free(t, &status); return 0; } capsule = PyCapsule_New((void*)t, name, (PyCapsule_Destructor)sky_free); return Py_BuildValue("N", capsule); /* Don't increment refcount. */ }
static PyObject* filter_by_flux(PyObject* self, PyObject* args) { oskar_Sky *h = 0; PyObject* capsule = 0; int status = 0; double min_flux_jy = 0.0, max_flux_jy = 0.0; if (!PyArg_ParseTuple(args, "Odd", &capsule, &min_flux_jy, &max_flux_jy)) return 0; if (!(h = get_handle(capsule))) return 0; /* Filter the sky model. */ oskar_sky_filter_by_flux(h, min_flux_jy, max_flux_jy, &status); /* Check for errors. */ if (status) { PyErr_Format(PyExc_RuntimeError, "oskar_sky_filter_by_flux() failed with code %d (%s).", status, oskar_get_error_string(status)); return 0; } return Py_BuildValue(""); }
static PyObject* append_file(PyObject* self, PyObject* args) { oskar_Sky *h = 0, *t = 0; PyObject* capsule = 0; int status = 0; const char* filename = 0; if (!PyArg_ParseTuple(args, "Os", &capsule, &filename)) return 0; if (!(h = get_handle(capsule))) return 0; /* Load the sky model. */ t = oskar_sky_load(filename, oskar_sky_precision(h), &status); oskar_sky_append(h, t, &status); oskar_sky_free(t, &status); /* Check for errors. */ if (status) { PyErr_Format(PyExc_RuntimeError, "oskar_sky_load() failed with code %d (%s).", status, oskar_get_error_string(status)); return 0; } return Py_BuildValue(""); }
TEST(binary_file, binary_read_write_mem) { const char filename[] = "temp_test_mem_binary.dat"; int num_cpu = 1000; int num_gpu = 2048; int status = 0; // Create the handle. oskar_Binary* h = oskar_binary_create(filename, 'w', &status); // Save data from CPU. { oskar_Mem* mem = oskar_mem_create(OSKAR_SINGLE, OSKAR_CPU, num_cpu, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); float* data = oskar_mem_float(mem, &status); // Fill array with data. for (int i = 0; i < num_cpu; ++i) { data[i] = i * 1024.0; } // Save CPU data. oskar_binary_write_mem_ext(h, mem, "USER", "TEST", 987654, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_mem_free(mem, &status); } // Save data from GPU. { oskar_Mem *mem_cpu, *mem_gpu; mem_cpu = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_CPU, num_gpu, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); double2* data = oskar_mem_double2(mem_cpu, &status); // Fill array with data. for (int i = 0; i < num_gpu; ++i) { data[i].x = i * 10.0; data[i].y = i * 20.0 + 1.0; } // Copy data to GPU. mem_gpu = oskar_mem_create_copy(mem_cpu, OSKAR_GPU, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Save GPU data. oskar_binary_write_mem_ext(h, mem_gpu, "AA", "BB", 2, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_mem_free(mem_cpu, &status); oskar_mem_free(mem_gpu, &status); } // Save a single integer with a large index. int val = 0xFFFFFF; oskar_binary_write_int(h, 50, 9, 800000, val, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Save data from CPU with blank tags. { oskar_Mem* mem = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, num_cpu, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); double* data = oskar_mem_double(mem, &status); // Fill array with data. for (int i = 0; i < num_cpu; ++i) { data[i] = i * 500.0; } // Save CPU data. oskar_binary_write_mem_ext(h, mem, "", "", 10, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Fill array with data. for (int i = 0; i < num_cpu; ++i) { data[i] = i * 501.0; } // Save CPU data. oskar_binary_write_mem_ext(h, mem, "", "", 11, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_mem_free(mem, &status); } // Save CPU data with tags that are equal lengths. { oskar_Mem* mem = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, num_cpu, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); double* data = oskar_mem_double(mem, &status); // Fill array with data. for (int i = 0; i < num_cpu; ++i) { data[i] = i * 1001.0; } // Save CPU data. oskar_binary_write_mem_ext(h, mem, "DOG", "CAT", 0, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Fill array with data. for (int i = 0; i < num_cpu; ++i) { data[i] = i * 127.0; } // Save CPU data. oskar_binary_write_mem_ext(h, mem, "ONE", "TWO", 0, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_mem_free(mem, &status); } // Create the handle for reading. oskar_binary_free(h); h = oskar_binary_create(filename, 'r', &status); // Load data directly to GPU. { oskar_Mem *mem_gpu, *mem_cpu; mem_gpu = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_GPU, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_binary_read_mem_ext(h, mem_gpu, "AA", "BB", 2, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); EXPECT_EQ(num_gpu, (int)oskar_mem_length(mem_gpu)); // Copy back to CPU and examine contents. mem_cpu = oskar_mem_create_copy(mem_gpu, OSKAR_CPU, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); double2* data = oskar_mem_double2(mem_cpu, &status); for (int i = 0; i < num_gpu; ++i) { EXPECT_DOUBLE_EQ(i * 10.0, data[i].x); EXPECT_DOUBLE_EQ(i * 20.0 + 1.0, data[i].y); } oskar_mem_free(mem_cpu, &status); oskar_mem_free(mem_gpu, &status); } // Load integer with a large index. int new_val = 0; oskar_binary_read_int(h, 50, 9, 800000, &new_val, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); EXPECT_EQ(val, new_val); // Load CPU data. { oskar_Mem* mem = oskar_mem_create(OSKAR_SINGLE, OSKAR_CPU, num_cpu, &status); oskar_binary_read_mem_ext(h, mem, "USER", "TEST", 987654, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); ASSERT_EQ(num_cpu, (int)oskar_mem_length(mem)); float* data = oskar_mem_float(mem, &status); for (int i = 0; i < num_cpu; ++i) { EXPECT_DOUBLE_EQ(i * 1024.0, data[i]); } oskar_mem_free(mem, &status); } // Load CPU data with blank tags. { double* data; oskar_Mem* mem = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, num_cpu, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_binary_read_mem_ext(h, mem, "", "", 10, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_binary_read_mem_ext(h, mem, "DOESN'T", "EXIST", 10, &status); EXPECT_EQ((int)OSKAR_ERR_BINARY_TAG_NOT_FOUND, status); status = 0; ASSERT_EQ(num_cpu, (int)oskar_mem_length(mem)); data = oskar_mem_double(mem, &status); for (int i = 0; i < num_cpu; ++i) { EXPECT_DOUBLE_EQ(i * 500.0, data[i]); } oskar_binary_read_mem_ext(h, mem, "", "", 11, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); ASSERT_EQ(num_cpu, (int)oskar_mem_length(mem)); data = oskar_mem_double(mem, &status); for (int i = 0; i < num_cpu; ++i) { EXPECT_DOUBLE_EQ(i * 501.0, data[i]); } oskar_mem_free(mem, &status); } // Load CPU data with tags that are equal lengths. { double* data; oskar_Mem* mem = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_binary_read_mem_ext(h, mem, "ONE", "TWO", 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); ASSERT_EQ(num_cpu, (int)oskar_mem_length(mem)); data = oskar_mem_double(mem, &status); for (int i = 0; i < num_cpu; ++i) { EXPECT_DOUBLE_EQ(i * 127.0, data[i]); } oskar_binary_read_mem_ext(h, mem, "DOG", "CAT", 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); ASSERT_EQ(num_cpu, (int)oskar_mem_length(mem)); data = oskar_mem_double(mem, &status); for (int i = 0; i < num_cpu; ++i) { EXPECT_DOUBLE_EQ(i * 1001.0, data[i]); } oskar_mem_free(mem, &status); } // Try to load data that isn't present. { oskar_Mem* mem = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_binary_read_mem_ext(h, mem, "DOESN'T", "EXIST", 10, &status); EXPECT_EQ((int)OSKAR_ERR_BINARY_TAG_NOT_FOUND, status); status = 0; EXPECT_EQ(0, (int)oskar_mem_length(mem)); oskar_mem_free(mem, &status); } // Release the handle. oskar_binary_free(h); ASSERT_EQ(0, status) << oskar_get_error_string(status); }
TEST(evaluate_baselines, cpu_gpu) { oskar_Mem *u, *v, *w, *uu, *vv, *ww; oskar_Mem *u_gpu, *v_gpu, *w_gpu, *uu_gpu, *vv_gpu, *ww_gpu; int num_baselines, num_stations = 50, status = 0, type, location; double *u_, *v_, *w_, *uu_, *vv_, *ww_; num_baselines = num_stations * (num_stations - 1) / 2; type = OSKAR_DOUBLE; // Allocate host memory. location = OSKAR_CPU; u = oskar_mem_create(type, location, num_stations, &status); v = oskar_mem_create(type, location, num_stations, &status); w = oskar_mem_create(type, location, num_stations, &status); uu = oskar_mem_create(type, location, num_baselines, &status); vv = oskar_mem_create(type, location, num_baselines, &status); ww = oskar_mem_create(type, location, num_baselines, &status); u_ = oskar_mem_double(u, &status); v_ = oskar_mem_double(v, &status); w_ = oskar_mem_double(w, &status); uu_ = oskar_mem_double(uu, &status); vv_ = oskar_mem_double(vv, &status); ww_ = oskar_mem_double(ww, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Fill station coordinates with test data. for (int i = 0; i < num_stations; ++i) { u_[i] = (double)(i + 1); v_[i] = (double)(i + 2); w_[i] = (double)(i + 3); } // Evaluate baseline coordinates on CPU. oskar_convert_station_uvw_to_baseline_uvw(num_stations, 0, u, v, w, 0, uu, vv, ww, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Check results are correct. for (int s1 = 0, b = 0; s1 < num_stations; ++s1) { for (int s2 = s1 + 1; s2 < num_stations; ++s2, ++b) { EXPECT_DOUBLE_EQ(u_[s2] - u_[s1], uu_[b]); EXPECT_DOUBLE_EQ(v_[s2] - v_[s1], vv_[b]); EXPECT_DOUBLE_EQ(w_[s2] - w_[s1], ww_[b]); } } // Allocate device memory and copy input data. #ifdef OSKAR_HAVE_CUDA location = OSKAR_GPU; #endif u_gpu = oskar_mem_create_copy(u, location, &status); v_gpu = oskar_mem_create_copy(v, location, &status); w_gpu = oskar_mem_create_copy(w, location, &status); uu_gpu = oskar_mem_create(type, location, num_baselines, &status); vv_gpu = oskar_mem_create(type, location, num_baselines, &status); ww_gpu = oskar_mem_create(type, location, num_baselines, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Evaluate baseline coordinates on device. oskar_convert_station_uvw_to_baseline_uvw(num_stations, 0, u_gpu, v_gpu, w_gpu, 0, uu_gpu, vv_gpu, ww_gpu, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Check results are consistent. double max_, avg; oskar_mem_evaluate_relative_error(uu_gpu, uu, 0, &max_, &avg, 0, &status); ASSERT_LT(max_, 1e-12); ASSERT_LT(avg, 1e-12); oskar_mem_evaluate_relative_error(vv_gpu, vv, 0, &max_, &avg, 0, &status); ASSERT_LT(max_, 1e-12); ASSERT_LT(avg, 1e-12); oskar_mem_evaluate_relative_error(ww_gpu, ww, 0, &max_, &avg, 0, &status); ASSERT_LT(max_, 1e-12); ASSERT_LT(avg, 1e-12); // Free memory. oskar_mem_free(u, &status); oskar_mem_free(v, &status); oskar_mem_free(w, &status); oskar_mem_free(uu, &status); oskar_mem_free(vv, &status); oskar_mem_free(ww, &status); oskar_mem_free(u_gpu, &status); oskar_mem_free(v_gpu, &status); oskar_mem_free(w_gpu, &status); oskar_mem_free(uu_gpu, &status); oskar_mem_free(vv_gpu, &status); oskar_mem_free(ww_gpu, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); }
TEST(element_weights_errors, test_reinit) { int num_elements = 5; int status = 0; double gain = 1.5; double gain_error = 0.2; double phase = 0.1 * M_PI; double phase_error = (5 / 180.0) * M_PI; oskar_Mem *d_errors, *d_gain, *d_gain_error, *d_phase, *d_phase_error; d_errors = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_GPU, num_elements, &status); d_gain = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, num_elements, &status); d_gain_error = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, num_elements, &status); d_phase = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, num_elements, &status); d_phase_error = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, num_elements, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_mem_set_value_real(d_gain, gain, 0, 0, &status); oskar_mem_set_value_real(d_gain_error, gain_error, 0, 0, &status); oskar_mem_set_value_real(d_phase, phase, 0, 0, &status); oskar_mem_set_value_real(d_phase_error, phase_error, 0, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); int num_channels = 2; int num_chunks = 3; int num_stations = 5; int num_times = 3; unsigned int seed = 1; const char* fname = "temp_test_weights_error_reinit.dat"; FILE* file = fopen(fname, "w"); for (int chan = 0; chan < num_channels; ++chan) { fprintf(file, "channel: %i\n", chan); for (int chunk = 0; chunk < num_chunks; ++chunk) { fprintf(file, " chunk: %i\n", chunk); ASSERT_EQ(0, status) << oskar_get_error_string(status); for (int t = 0; t < num_times; ++t) { fprintf(file, " time: %i\n", t); for (int s = 0; s < num_stations; ++s) { fprintf(file, " station: %i ==> ", s); oskar_evaluate_element_weights_errors(num_elements, d_gain, d_gain_error, d_phase, d_phase_error, seed, t, s, d_errors, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_Mem *h_errors = oskar_mem_create_copy(d_errors, OSKAR_CPU, &status); double2* errors = oskar_mem_double2(h_errors, &status); for (int i = 0; i < num_elements; ++i) { fprintf(file, "(% -6.4f, % -6.4f), ", errors[i].x, errors[i].y); } fprintf(file, "\n"); oskar_mem_free(h_errors, &status); } } ASSERT_EQ(0, status) << oskar_get_error_string(status); } } fclose(file); // remove(fname); oskar_mem_free(d_gain, &status); oskar_mem_free(d_gain_error, &status); oskar_mem_free(d_phase, &status); oskar_mem_free(d_phase_error, &status); oskar_mem_free(d_errors, &status); }
TEST(element_weights_errors, test_apply) { int num_elements = 10000; int status = 0; double gain = 1.5; double gain_error = 0.2; double phase = 0.1 * M_PI; double phase_error = (5 / 180.0) * M_PI; double weight_gain = 1.0; double weight_phase = 0.5 * M_PI; double2 weight; weight.x = weight_gain * cos(weight_phase); weight.y = weight_gain * sin(weight_phase); oskar_Mem *d_gain, *d_gain_error, *d_phase, *d_phase_error, *d_errors; oskar_Mem *h_weights, *d_weights; d_errors = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_GPU, num_elements, &status); d_gain = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, num_elements, &status); d_gain_error = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, num_elements, &status); d_phase = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, num_elements, &status); d_phase_error = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, num_elements, &status); h_weights = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_CPU, num_elements, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_mem_set_value_real(d_gain, gain, 0, 0, &status); oskar_mem_set_value_real(d_gain_error, gain_error, 0, 0, &status); oskar_mem_set_value_real(d_phase, phase, 0, 0, &status); oskar_mem_set_value_real(d_phase_error, phase_error, 0, 0, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); double2* h_weights_ = oskar_mem_double2(h_weights, &status); for (int i = 0; i < num_elements; ++i) { h_weights_[i].x = weight.x; h_weights_[i].y = weight.y; } d_weights = oskar_mem_create_copy(h_weights, OSKAR_GPU, &status); oskar_evaluate_element_weights_errors(num_elements, d_gain, d_gain_error, d_phase, d_phase_error, 0, 0, 0, d_errors, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_mem_element_multiply(NULL, d_weights, d_errors, num_elements, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Write memory to file for inspection. const char* fname = "temp_test_weights.dat"; FILE* file = fopen(fname, "w"); oskar_mem_save_ascii(file, 7, num_elements, &status, d_gain, d_gain_error, d_phase, d_phase_error, d_errors, h_weights, d_weights); fclose(file); remove(fname); // Free memory. oskar_mem_free(d_gain, &status); oskar_mem_free(d_gain_error, &status); oskar_mem_free(d_phase, &status); oskar_mem_free(d_phase_error, &status); oskar_mem_free(d_errors, &status); oskar_mem_free(h_weights, &status); oskar_mem_free(d_weights, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); }
TEST(Mem, random_uniform) { int seed = 1; int c1 = 437; int c2 = 0; int c3 = 0xDECAFBAD; int n = 544357; int status = 0; double max_err = 0.0, avg_err = 0.0; oskar_Mem* v_cpu_f = oskar_mem_create(OSKAR_SINGLE, OSKAR_CPU, n, &status); oskar_Mem* v_gpu_f = oskar_mem_create(OSKAR_SINGLE, OSKAR_GPU, n, &status); oskar_Mem* v_cpu_d = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, n, &status); oskar_Mem* v_gpu_d = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU, n, &status); oskar_Timer* tmr = oskar_timer_create(OSKAR_TIMER_CUDA); // Run in single precision. oskar_timer_start(tmr); oskar_mem_random_uniform(v_cpu_f, seed, c1, c2, c3, &status); report_time(n, "uniform", "single", "CPU", oskar_timer_elapsed(tmr)); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_timer_start(tmr); oskar_mem_random_uniform(v_gpu_f, seed, c1, c2, c3, &status); report_time(n, "uniform", "single", "GPU", oskar_timer_elapsed(tmr)); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Check consistency between CPU and GPU results. oskar_mem_evaluate_relative_error(v_gpu_f, v_cpu_f, 0, &max_err, &avg_err, 0, &status); EXPECT_LT(max_err, 1e-5); EXPECT_LT(avg_err, 1e-5); // Run in double precision. oskar_timer_start(tmr); oskar_mem_random_uniform(v_cpu_d, seed, c1, c2, c3, &status); report_time(n, "uniform", "double", "CPU", oskar_timer_elapsed(tmr)); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_timer_start(tmr); oskar_mem_random_uniform(v_gpu_d, seed, c1, c2, c3, &status); report_time(n, "uniform", "double", "GPU", oskar_timer_elapsed(tmr)); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Check consistency between CPU and GPU results. oskar_mem_evaluate_relative_error(v_gpu_d, v_cpu_d, 0, &max_err, &avg_err, 0, &status); EXPECT_LT(max_err, 1e-10); EXPECT_LT(avg_err, 1e-10); // Check consistency between single and double precision. oskar_mem_evaluate_relative_error(v_cpu_f, v_cpu_d, 0, &max_err, &avg_err, 0, &status); EXPECT_LT(max_err, 1e-5); EXPECT_LT(avg_err, 1e-5); if (save) { FILE* fhan = fopen("random_uniform.txt", "w"); oskar_mem_save_ascii(fhan, 4, n, &status, v_cpu_f, v_gpu_f, v_cpu_d, v_gpu_d); fclose(fhan); } // Free memory. oskar_mem_free(v_cpu_f, &status); oskar_mem_free(v_gpu_f, &status); oskar_mem_free(v_cpu_d, &status); oskar_mem_free(v_gpu_d, &status); oskar_timer_free(tmr); }
int main(int argc, char** argv) { oskar::OptionParser opt("oskar_array_pattern_benchmark", OSKAR_VERSION_STR); opt.add_required("No. array elements"); opt.add_required("No. directions"); opt.add_flag("-sp", "Use single precision (default: double precision)"); opt.add_flag("-g", "Run on the GPU"); opt.add_flag("-c", "Run on the CPU"); opt.add_flag("-o2c", "Single level beam pattern, phase only (real to complex DFT)"); opt.add_flag("-c2c", "Beam pattern using complex inputs (complex to complex DFT)"); opt.add_flag("-m2m", "Beam pattern using complex, polarised inputs (complex matrix to matrix DFT)"); opt.add_flag("-2d", "Use a 2-dimensional phase term (default: 3D)"); opt.add_flag("-n", "Number of iterations", 1, "1"); opt.add_flag("-v", "Display verbose output."); if (!opt.check_options(argc, argv)) return EXIT_FAILURE; int num_elements = atoi(opt.get_arg(0)); int num_directions = atoi(opt.get_arg(1)); OpType op_type = UNDEF; int op_type_count = 0; if (opt.is_set("-o2c")) { op_type = O2C; op_type_count++; } if (opt.is_set("-c2c")) { op_type = C2C; op_type_count++; } if (opt.is_set("-m2m")) { op_type = M2M; op_type_count++; } int loc; if (opt.is_set("-g")) loc = OSKAR_GPU; if (opt.is_set("-c")) loc = OSKAR_CPU; if (!(opt.is_set("-c") ^ opt.is_set("-g"))) { opt.error("Please select one of -g or -c"); return EXIT_FAILURE; } int precision = opt.is_set("-sp") ? OSKAR_SINGLE : OSKAR_DOUBLE; bool evaluate_2d = opt.is_set("-2d") ? true : false; int niter; opt.get("-n")->getInt(niter); if (op_type == UNDEF || op_type_count != 1) { opt.error("Please select one of the following flags: -o2c, -c2c, -m2m"); return EXIT_FAILURE; } if (opt.is_set("-v")) { printf("\n"); printf("- Number of elements: %i\n", num_elements); printf("- Number of directions: %i\n", num_directions); printf("- Precision: %s\n", (precision == OSKAR_SINGLE) ? "single" : "double"); printf("- %s\n", loc == OSKAR_CPU ? "CPU" : "GPU"); printf("- %s\n", evaluate_2d ? "2D" : "3D"); printf("- Evaluation type = "); if (op_type == O2C) printf("o2c\n"); else if (op_type == C2C) printf("c2c\n"); else if (op_type == M2M) printf("m2m\n"); else printf("Error undefined!\n"); printf("- Number of iterations: %i\n", niter); printf("\n"); } double time_taken = 0.0; int status = benchmark(num_elements, num_directions, op_type, loc, precision, evaluate_2d, niter, time_taken); if (status) { fprintf(stderr, "ERROR: array pattern evaluation failed with code %i: " "%s\n", status, oskar_get_error_string(status)); return EXIT_FAILURE; } if (opt.is_set("-v")) { printf("==> Total time taken: %f seconds.\n", time_taken); printf("==> Time taken per iteration: %f seconds.\n", time_taken/niter); printf("\n"); } else { printf("%f\n", time_taken/niter); } return EXIT_SUCCESS; }
void destroyTestData() { int status = 0; oskar_mem_free(jones, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); }
int main(int argc, char** argv) { int status = 0; oskar::OptionParser opt("oskar_evaulate_pierce_points", oskar_version_string()); opt.add_required("settings file"); if (!opt.check_options(argc, argv)) return EXIT_FAILURE; const char* settings_file = opt.get_arg(); // Create the log. oskar_Log* log = oskar_log_create(OSKAR_LOG_MESSAGE, OSKAR_LOG_STATUS); oskar_log_message(log, 'M', 0, "Running binary %s", argv[0]); // Enum values used in writing time-freq data binary files enum OSKAR_TIME_FREQ_TAGS { TIME_IDX = 0, FREQ_IDX = 1, TIME_MJD_UTC = 2, FREQ_HZ = 3, NUM_FIELDS = 4, NUM_FIELD_TAGS = 5, HEADER_OFFSET = 10, DATA = 0, DIMS = 1, LABEL = 2, UNITS = 3, GRP = OSKAR_TAG_GROUP_TIME_FREQ_DATA }; oskar_Settings_old settings; oskar_settings_old_load(&settings, log, settings_file, &status); oskar_log_set_keep_file(log, settings.sim.keep_log_file); if (status) return status; oskar_Telescope* tel = oskar_settings_to_telescope(&settings, log, &status); oskar_Sky* sky = oskar_settings_to_sky(&settings, log, &status); // FIXME remove this restriction ... (see evaluate Z) if (settings.ionosphere.num_TID_screens != 1) return OSKAR_ERR_SETUP_FAIL; int type = settings.sim.double_precision ? OSKAR_DOUBLE : OSKAR_SINGLE; int loc = OSKAR_CPU; int num_sources = oskar_sky_num_sources(sky); oskar_Mem *hor_x, *hor_y, *hor_z; hor_x = oskar_mem_create(type, loc, num_sources, &status); hor_y = oskar_mem_create(type, loc, num_sources, &status); hor_z = oskar_mem_create(type, loc, num_sources, &status); oskar_Mem *pp_lon, *pp_lat, *pp_rel_path; int num_stations = oskar_telescope_num_stations(tel); int num_pp = num_stations * num_sources; pp_lon = oskar_mem_create(type, loc, num_pp, &status); pp_lat = oskar_mem_create(type, loc, num_pp, &status); pp_rel_path = oskar_mem_create(type, loc, num_pp, &status); // Pierce points for one station (non-owned oskar_Mem pointers) oskar_Mem *pp_st_lon, *pp_st_lat, *pp_st_rel_path; pp_st_lon = oskar_mem_create_alias(0, 0, 0, &status); pp_st_lat = oskar_mem_create_alias(0, 0, 0, &status); pp_st_rel_path = oskar_mem_create_alias(0, 0, 0, &status); int num_times = settings.obs.num_time_steps; double obs_start_mjd_utc = settings.obs.start_mjd_utc; double dt_dump = settings.obs.dt_dump_days; // Binary file meta-data std::string label1 = "pp_lon"; std::string label2 = "pp_lat"; std::string label3 = "pp_path"; std::string units = "radians"; std::string units2 = ""; oskar_Mem *dims = oskar_mem_create(OSKAR_INT, loc, 2, &status); /* FIXME is this the correct dimension order ? * FIXME get the MATLAB reader to respect dimension ordering */ oskar_mem_int(dims, &status)[0] = num_sources; oskar_mem_int(dims, &status)[1] = num_stations; const char* filename = settings.ionosphere.pierce_points.filename; oskar_Binary* h = oskar_binary_create(filename, 'w', &status); double screen_height_m = settings.ionosphere.TID->height_km * 1000.0; // printf("Number of times = %i\n", num_times); // printf("Number of stations = %i\n", num_stations); void *x_, *y_, *z_; x_ = oskar_mem_void(oskar_telescope_station_true_x_offset_ecef_metres(tel)); y_ = oskar_mem_void(oskar_telescope_station_true_y_offset_ecef_metres(tel)); z_ = oskar_mem_void(oskar_telescope_station_true_z_offset_ecef_metres(tel)); for (int t = 0; t < num_times; ++t) { double t_dump = obs_start_mjd_utc + t * dt_dump; // MJD UTC double gast = oskar_convert_mjd_to_gast_fast(t_dump + dt_dump / 2.0); for (int i = 0; i < num_stations; ++i) { const oskar_Station* station = oskar_telescope_station_const(tel, i); double lon = oskar_station_lon_rad(station); double lat = oskar_station_lat_rad(station); double alt = oskar_station_alt_metres(station); double x_ecef, y_ecef, z_ecef, x_offset, y_offset, z_offset; if (type == OSKAR_DOUBLE) { x_offset = ((double*)x_)[i]; y_offset = ((double*)y_)[i]; z_offset = ((double*)z_)[i]; } else { x_offset = (double)((float*)x_)[i]; y_offset = (double)((float*)y_)[i]; z_offset = (double)((float*)z_)[i]; } oskar_convert_offset_ecef_to_ecef(1, &x_offset, &y_offset, &z_offset, lon, lat, alt, &x_ecef, &y_ecef, &z_ecef); double last = gast + lon; if (type == OSKAR_DOUBLE) { oskar_convert_apparent_ra_dec_to_enu_directions_d(num_sources, oskar_mem_double_const(oskar_sky_ra_rad_const(sky), &status), oskar_mem_double_const(oskar_sky_dec_rad_const(sky), &status), last, lat, oskar_mem_double(hor_x, &status), oskar_mem_double(hor_y, &status), oskar_mem_double(hor_z, &status)); } else { oskar_convert_apparent_ra_dec_to_enu_directions_f(num_sources, oskar_mem_float_const(oskar_sky_ra_rad_const(sky), &status), oskar_mem_float_const(oskar_sky_dec_rad_const(sky), &status), last, lat, oskar_mem_float(hor_x, &status), oskar_mem_float(hor_y, &status), oskar_mem_float(hor_z, &status)); } int offset = i * num_sources; oskar_mem_set_alias(pp_st_lon, pp_lon, offset, num_sources, &status); oskar_mem_set_alias(pp_st_lat, pp_lat, offset, num_sources, &status); oskar_mem_set_alias(pp_st_rel_path, pp_rel_path, offset, num_sources, &status); oskar_evaluate_pierce_points(pp_st_lon, pp_st_lat, pp_st_rel_path, x_ecef, y_ecef, z_ecef, screen_height_m, num_sources, hor_x, hor_y, hor_z, &status); } // Loop over stations. if (status != 0) continue; int index = t; // could be = (num_times * f) + t if we have frequency data int num_fields = 3; int num_field_tags = 4; double freq_hz = 0.0; int freq_idx = 0; // Write the header TAGS oskar_binary_write_int(h, GRP, TIME_IDX, index, t, &status); oskar_binary_write_double(h, GRP, FREQ_IDX, index, freq_idx, &status); oskar_binary_write_double(h, GRP, TIME_MJD_UTC, index, t_dump, &status); oskar_binary_write_double(h, GRP, FREQ_HZ, index, freq_hz, &status); oskar_binary_write_int(h, GRP, NUM_FIELDS, index, num_fields, &status); oskar_binary_write_int(h, GRP, NUM_FIELD_TAGS, index, num_field_tags, &status); // Write data TAGS (fields) int field, tagID; field = 0; tagID = HEADER_OFFSET + (num_field_tags * field); oskar_binary_write_mem(h, pp_lon, GRP, tagID + DATA, index, 0, &status); oskar_binary_write_mem(h, dims, GRP, tagID + DIMS, index, 0, &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + LABEL, index, label1.size()+1, label1.c_str(), &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + UNITS, index, units.size()+1, units.c_str(), &status); field = 1; tagID = HEADER_OFFSET + (num_field_tags * field); oskar_binary_write_mem(h, pp_lat, GRP, tagID + DATA, index, 0, &status); oskar_binary_write_mem(h, dims, GRP, tagID + DIMS, index, 0, &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + LABEL, index, label2.size()+1, label2.c_str(), &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + UNITS, index, units.size()+1, units.c_str(), &status); field = 2; tagID = HEADER_OFFSET + (num_field_tags * field); oskar_binary_write_mem(h, pp_rel_path, GRP, tagID + DATA, index, 0, &status); oskar_binary_write_mem(h, dims, GRP, tagID + DIMS, index, 0, &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + LABEL, index, label3.size()+1, label3.c_str(), &status); oskar_binary_write(h, OSKAR_CHAR, GRP, tagID + UNITS, index, units2.size()+1, units2.c_str(), &status); } // Loop over times // Close the OSKAR binary file. oskar_binary_free(h); // clean up memory oskar_mem_free(hor_x, &status); oskar_mem_free(hor_y, &status); oskar_mem_free(hor_z, &status); oskar_mem_free(pp_lon, &status); oskar_mem_free(pp_lat, &status); oskar_mem_free(pp_rel_path, &status); oskar_mem_free(pp_st_lon, &status); oskar_mem_free(pp_st_lat, &status); oskar_mem_free(pp_st_rel_path, &status); oskar_mem_free(dims, &status); oskar_telescope_free(tel, &status); oskar_sky_free(sky, &status); // Check for errors. if (status) oskar_log_error(log, "Run failed: %s.", oskar_get_error_string(status)); oskar_log_free(log); return status; }
void runTest(int prec1, int prec2, int loc1, int loc2, int matrix) { int status = 0, type; oskar_Mem *beam1, *beam2; oskar_Timer *timer1, *timer2; double time1, time2; // Create the timers. timer1 = oskar_timer_create(loc1 == OSKAR_GPU ? OSKAR_TIMER_CUDA : OSKAR_TIMER_NATIVE); timer2 = oskar_timer_create(loc2 == OSKAR_GPU ? OSKAR_TIMER_CUDA : OSKAR_TIMER_NATIVE); // Run first part. type = prec1 | OSKAR_COMPLEX; if (matrix) type |= OSKAR_MATRIX; beam1 = oskar_mem_create(type, loc1, num_sources, &status); oskar_mem_clear_contents(beam1, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); createTestData(prec1, loc1, matrix); oskar_timer_start(timer1); oskar_evaluate_cross_power(num_sources, num_stations, jones, 0, beam1, &status); time1 = oskar_timer_elapsed(timer1); destroyTestData(); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Run second part. type = prec2 | OSKAR_COMPLEX; if (matrix) type |= OSKAR_MATRIX; beam2 = oskar_mem_create(type, loc2, num_sources, &status); oskar_mem_clear_contents(beam2, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); createTestData(prec2, loc2, matrix); oskar_timer_start(timer2); oskar_evaluate_cross_power(num_sources, num_stations, jones, 0, beam2, &status); time2 = oskar_timer_elapsed(timer2); destroyTestData(); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Destroy the timers. oskar_timer_free(timer1); oskar_timer_free(timer2); // Compare results. check_values(beam1, beam2); // Free memory. oskar_mem_free(beam1, &status); oskar_mem_free(beam2, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Record properties for test. RecordProperty("JonesType", matrix ? "Matrix" : "Scalar"); RecordProperty("Prec1", prec1 == OSKAR_SINGLE ? "Single" : "Double"); RecordProperty("Loc1", loc1 == OSKAR_CPU ? "CPU" : "GPU"); RecordProperty("Time1_ms", int(time1 * 1000)); RecordProperty("Prec2", prec2 == OSKAR_SINGLE ? "Single" : "Double"); RecordProperty("Loc2", loc2 == OSKAR_CPU ? "CPU" : "GPU"); RecordProperty("Time2_ms", int(time2 * 1000)); #ifdef ALLOW_PRINTING // Print times. printf(" > %s.\n", matrix ? "Matrix" : "Scalar"); printf(" %s precision %s: %.2f ms, %s precision %s: %.2f ms\n", prec1 == OSKAR_SINGLE ? "Single" : "Double", loc1 == OSKAR_CPU ? "CPU" : "GPU", time1 * 1000.0, prec2 == OSKAR_SINGLE ? "Single" : "Double", loc2 == OSKAR_CPU ? "CPU" : "GPU", time2 * 1000.0); #endif }
int main(int argc, char** argv) { oskar::OptionParser opt("oskar_correlator_benchmark", OSKAR_VERSION_STR); opt.add_flag("-nst", "Number of stations.", 1, "", true); opt.add_flag("-nsrc", "Number of sources.", 1, "", true); opt.add_flag("-sp", "Use single precision (default: double precision)"); opt.add_flag("-s", "Use scalar Jones terms (default: matrix/polarised)."); opt.add_flag("-g", "Run on the GPU"); opt.add_flag("-c", "Run on the CPU"); opt.add_flag("-e", "Use Gaussian sources (default: point sources)."); opt.add_flag("-t", "Use analytical time averaging (default: no time " "averaging)."); opt.add_flag("-r", "Dump raw iteration data to this file.", 1); opt.add_flag("-std", "Discard values greater than this number of standard " "deviations from the mean.", 1); opt.add_flag("-n", "Number of iterations", 1, "1", false); opt.add_flag("-v", "Display verbose output.", false); if (!opt.check_options(argc, argv)) return EXIT_FAILURE; int num_stations, num_sources, niter; double max_std_dev = 0.0; opt.get("-nst")->getInt(num_stations); opt.get("-nsrc")->getInt(num_sources); int type = opt.is_set("-sp") ? OSKAR_SINGLE : OSKAR_DOUBLE; int jones_type = type | OSKAR_COMPLEX; if (!opt.is_set("-s")) jones_type |= OSKAR_MATRIX; opt.get("-n")->getInt(niter); int use_extended = opt.is_set("-e") ? OSKAR_TRUE : OSKAR_FALSE; int use_time_ave = opt.is_set("-t") ? OSKAR_TRUE : OSKAR_FALSE; std::string raw_file; if (opt.is_set("-r")) opt.get("-r")->getString(raw_file); if (opt.is_set("-std")) opt.get("-std")->getDouble(max_std_dev); int loc; if (opt.is_set("-g")) loc = OSKAR_GPU; if (opt.is_set("-c")) loc = OSKAR_CPU; if (!(opt.is_set("-c") ^ opt.is_set("-g"))) { opt.error("Please select one of -g or -c"); return EXIT_FAILURE; } if (opt.is_set("-v")) { printf("\n"); printf("- Number of stations: %i\n", num_stations); printf("- Number of sources: %i\n", num_sources); printf("- Precision: %s\n", (type == OSKAR_SINGLE) ? "single" : "double"); printf("- Jones type: %s\n", (opt.is_set("-s")) ? "scalar" : "matrix"); printf("- Extended sources: %s\n", (use_extended) ? "true" : "false"); printf("- Analytical time smearing: %s\n", (use_time_ave) ? "true" : "false"); printf("- Number of iterations: %i\n", niter); if (max_std_dev > 0.0) printf("- Max standard deviations: %f\n", max_std_dev); if (!raw_file.empty()) printf("- Writing iteration data to: %s\n", raw_file.c_str()); printf("\n"); } // Run benchmarks. double time_taken_sec = 0.0, average_time_sec = 0.0; std::vector<double> times; int status = benchmark(num_stations, num_sources, type, jones_type, loc, use_extended, use_time_ave, niter, times); // Compute total time taken. for (int i = 0; i < niter; ++i) { time_taken_sec += times[i]; } // Dump raw data if requested. if (!raw_file.empty()) { FILE* raw_stream = 0; raw_stream = fopen(raw_file.c_str(), "w"); if (raw_stream) { for (int i = 0; i < niter; ++i) { fprintf(raw_stream, "%.6f\n", times[i]); } fclose(raw_stream); } } // Check for errors. if (status) { fprintf(stderr, "ERROR: correlate failed with code %i: %s\n", status, oskar_get_error_string(status)); return EXIT_FAILURE; } // Compute average. if (max_std_dev > 0.0) { double std_dev_sec = 0.0, old_time_average_sec; // Compute standard deviation. old_time_average_sec = time_taken_sec / niter; for (int i = 0; i < niter; ++i) { std_dev_sec += pow(times[i] - old_time_average_sec, 2.0); } std_dev_sec /= niter; std_dev_sec = sqrt(std_dev_sec); // Compute new mean. average_time_sec = 0.0; int counter = 0; for (int i = 0; i < niter; ++i) { if (fabs(times[i] - old_time_average_sec) < max_std_dev * std_dev_sec) { average_time_sec += times[i]; counter++; } } if (counter) average_time_sec /= counter; } else { average_time_sec = time_taken_sec / niter; } // Print average. if (opt.is_set("-v")) { printf("==> Total time taken: %f seconds.\n", time_taken_sec); printf("==> Time taken per iteration: %f seconds.\n", average_time_sec); printf("==> Iteration values:\n"); for (int i = 0; i < niter; ++i) { printf("%.6f\n", times[i]); } printf("\n"); } else { printf("%f\n", average_time_sec); } return EXIT_SUCCESS; }
void runTest(int prec1, int prec2, int loc1, int loc2, int matrix, int extended, double time_average) { int num_baselines, status = 0, type; oskar_Mem *vis1, *vis2; oskar_Timer *timer1, *timer2; double time1, time2, frequency = 100e6; // Create the timers. timer1 = oskar_timer_create(loc1 == OSKAR_GPU ? OSKAR_TIMER_CUDA : OSKAR_TIMER_NATIVE); timer2 = oskar_timer_create(loc2 == OSKAR_GPU ? OSKAR_TIMER_CUDA : OSKAR_TIMER_NATIVE); // Run first part. createTestData(prec1, loc1, matrix); num_baselines = oskar_telescope_num_baselines(tel); type = prec1 | OSKAR_COMPLEX; if (matrix) type |= OSKAR_MATRIX; vis1 = oskar_mem_create(type, loc1, num_baselines, &status); oskar_mem_clear_contents(vis1, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_sky_set_use_extended(sky, extended); oskar_telescope_set_channel_bandwidth(tel, bandwidth); oskar_telescope_set_time_average(tel, time_average); oskar_timer_start(timer1); oskar_cross_correlate(vis1, oskar_sky_num_sources(sky), jones, sky, tel, u_, v_, w_, 1.0, frequency, &status); time1 = oskar_timer_elapsed(timer1); destroyTestData(); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Run second part. createTestData(prec2, loc2, matrix); num_baselines = oskar_telescope_num_baselines(tel); type = prec2 | OSKAR_COMPLEX; if (matrix) type |= OSKAR_MATRIX; vis2 = oskar_mem_create(type, loc2, num_baselines, &status); oskar_mem_clear_contents(vis2, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); oskar_sky_set_use_extended(sky, extended); oskar_telescope_set_channel_bandwidth(tel, bandwidth); oskar_telescope_set_time_average(tel, time_average); oskar_timer_start(timer2); oskar_cross_correlate(vis2, oskar_sky_num_sources(sky), jones, sky, tel, u_, v_, w_, 1.0, frequency, &status); time2 = oskar_timer_elapsed(timer2); destroyTestData(); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Destroy the timers. oskar_timer_free(timer1); oskar_timer_free(timer2); // Compare results. check_values(vis1, vis2); // Free memory. oskar_mem_free(vis1, &status); oskar_mem_free(vis2, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); // Record properties for test. RecordProperty("SourceType", extended ? "Gaussian" : "Point"); RecordProperty("JonesType", matrix ? "Matrix" : "Scalar"); RecordProperty("TimeSmearing", time_average == 0.0 ? "off" : "on"); RecordProperty("Prec1", prec1 == OSKAR_SINGLE ? "Single" : "Double"); RecordProperty("Loc1", loc1 == OSKAR_CPU ? "CPU" : "GPU"); RecordProperty("Time1_ms", int(time1 * 1000)); RecordProperty("Prec2", prec2 == OSKAR_SINGLE ? "Single" : "Double"); RecordProperty("Loc2", loc2 == OSKAR_CPU ? "CPU" : "GPU"); RecordProperty("Time2_ms", int(time2 * 1000)); #ifdef ALLOW_PRINTING // Print times. printf(" > %s. %s sources. Time smearing %s.\n", matrix ? "Matrix" : "Scalar", extended ? "Gaussian" : "Point", time_average == 0.0 ? "off" : "on"); printf(" %s precision %s: %.2f ms, %s precision %s: %.2f ms\n", prec1 == OSKAR_SINGLE ? "Single" : "Double", loc1 == OSKAR_CPU ? "CPU" : "GPU", time1 * 1000.0, prec2 == OSKAR_SINGLE ? "Single" : "Double", loc2 == OSKAR_CPU ? "CPU" : "GPU", time2 * 1000.0); #endif }
TEST(fit_ellipse, test1) { int num_points = 7, status = 0; double maj_d = 0.0, min_d = 0.0, pa_d = 0.0; float maj_f = 0.0, min_f = 0.0, pa_f = 0.0; // Test double precision. { std::vector<double> x(num_points), y(num_points); std::vector<double> work1(5 * num_points), work2(5 * num_points); x[0] = -0.1686; x[1] = -0.0921; x[2] = 0.0765; x[3] = 0.1686; x[4] = 0.0921; x[5] = -0.0765; x[6] = -0.1686; y[0] = 0.7282; y[1] = 0.6994; y[2] = 0.6675; y[3] = 0.6643; y[4] = 0.7088; y[5] = 0.7407; y[6] = 0.7282; oskar_fit_ellipse_d(&maj_d, &min_d, &pa_d, num_points, &x[0], &y[0], &work1[0], &work2[0], &status); EXPECT_EQ(0, status) << oskar_get_error_string(status); } // Test single precision. { std::vector<float> x(num_points), y(num_points); std::vector<float> work1(5 * num_points), work2(5 * num_points); x[0] = -0.1686; x[1] = -0.0921; x[2] = 0.0765; x[3] = 0.1686; x[4] = 0.0921; x[5] = -0.0765; x[6] = -0.1686; y[0] = 0.7282; y[1] = 0.6994; y[2] = 0.6675; y[3] = 0.6643; y[4] = 0.7088; y[5] = 0.7407; y[6] = 0.7282; oskar_fit_ellipse_f(&maj_f, &min_f, &pa_f, num_points, &x[0], &y[0], &work1[0], &work2[0], &status); EXPECT_EQ(0, status) << oskar_get_error_string(status); } // Compare results. EXPECT_NEAR(maj_d, 0.3608619735, 1e-9); EXPECT_NEAR(min_d, 0.0494223702, 1e-9); EXPECT_NEAR(pa_d, -1.3865537748, 1e-9); EXPECT_NEAR(maj_d, maj_f, 1e-5); EXPECT_NEAR(min_d, min_f, 1e-5); EXPECT_NEAR(pa_d, pa_f, 1e-5); }
static PyObject* append_sources(PyObject* self, PyObject* args) { oskar_Sky *h = 0; PyObject *obj[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; oskar_Mem *ra_c, *dec_c, *I_c, *Q_c, *U_c, *V_c; oskar_Mem *ref_c, *spix_c, *rm_c, *maj_c, *min_c, *pa_c; PyArrayObject *ra = 0, *dec = 0, *I = 0, *Q = 0, *U = 0, *V = 0; PyArrayObject *ref = 0, *spix = 0, *rm = 0, *maj = 0, *min = 0, *pa = 0; int status = 0, npy_type, type, flags, num_sources, old_num; /* Parse inputs: RA, Dec, I, Q, U, V, ref, spix, rm, maj, min, pa. */ if (!PyArg_ParseTuple(args, "OOOOOOOOOOOOO", &obj[0], &obj[1], &obj[2], &obj[3], &obj[4], &obj[5], &obj[6], &obj[7], &obj[8], &obj[9], &obj[10], &obj[11], &obj[12])) return 0; if (!(h = get_handle(obj[0]))) return 0; /* Make sure input objects are arrays. Convert if required. */ flags = NPY_ARRAY_FORCECAST | NPY_ARRAY_IN_ARRAY; type = oskar_sky_precision(h); npy_type = numpy_type_from_oskar(type); ra = (PyArrayObject*) PyArray_FROM_OTF(obj[1], npy_type, flags); dec = (PyArrayObject*) PyArray_FROM_OTF(obj[2], npy_type, flags); I = (PyArrayObject*) PyArray_FROM_OTF(obj[3], npy_type, flags); Q = (PyArrayObject*) PyArray_FROM_OTF(obj[4], npy_type, flags); U = (PyArrayObject*) PyArray_FROM_OTF(obj[5], npy_type, flags); V = (PyArrayObject*) PyArray_FROM_OTF(obj[6], npy_type, flags); ref = (PyArrayObject*) PyArray_FROM_OTF(obj[7], npy_type, flags); spix = (PyArrayObject*) PyArray_FROM_OTF(obj[8], npy_type, flags); rm = (PyArrayObject*) PyArray_FROM_OTF(obj[9], npy_type, flags); maj = (PyArrayObject*) PyArray_FROM_OTF(obj[10], npy_type, flags); min = (PyArrayObject*) PyArray_FROM_OTF(obj[11], npy_type, flags); pa = (PyArrayObject*) PyArray_FROM_OTF(obj[12], npy_type, flags); if (!ra || !dec || !I || !Q || !U || !V || !ref || !spix || !rm || !maj || !min || !pa) goto fail; /* Check size of input arrays. */ num_sources = (int) PyArray_SIZE(I); if (num_sources != (int) PyArray_SIZE(ra) || num_sources != (int) PyArray_SIZE(dec) || num_sources != (int) PyArray_SIZE(Q) || num_sources != (int) PyArray_SIZE(U) || num_sources != (int) PyArray_SIZE(V) || num_sources != (int) PyArray_SIZE(ref) || num_sources != (int) PyArray_SIZE(spix) || num_sources != (int) PyArray_SIZE(rm) || num_sources != (int) PyArray_SIZE(maj) || num_sources != (int) PyArray_SIZE(min) || num_sources != (int) PyArray_SIZE(pa)) { PyErr_SetString(PyExc_RuntimeError, "Input data dimension mismatch."); goto fail; } /* Pointers to input arrays. */ ra_c = oskar_mem_create_alias_from_raw(PyArray_DATA(ra), type, OSKAR_CPU, num_sources, &status); dec_c = oskar_mem_create_alias_from_raw(PyArray_DATA(dec), type, OSKAR_CPU, num_sources, &status); I_c = oskar_mem_create_alias_from_raw(PyArray_DATA(I), type, OSKAR_CPU, num_sources, &status); Q_c = oskar_mem_create_alias_from_raw(PyArray_DATA(Q), type, OSKAR_CPU, num_sources, &status); U_c = oskar_mem_create_alias_from_raw(PyArray_DATA(U), type, OSKAR_CPU, num_sources, &status); V_c = oskar_mem_create_alias_from_raw(PyArray_DATA(V), type, OSKAR_CPU, num_sources, &status); ref_c = oskar_mem_create_alias_from_raw(PyArray_DATA(ref), type, OSKAR_CPU, num_sources, &status); spix_c = oskar_mem_create_alias_from_raw(PyArray_DATA(spix), type, OSKAR_CPU, num_sources, &status); rm_c = oskar_mem_create_alias_from_raw(PyArray_DATA(rm), type, OSKAR_CPU, num_sources, &status); maj_c = oskar_mem_create_alias_from_raw(PyArray_DATA(maj), type, OSKAR_CPU, num_sources, &status); min_c = oskar_mem_create_alias_from_raw(PyArray_DATA(min), type, OSKAR_CPU, num_sources, &status); pa_c = oskar_mem_create_alias_from_raw(PyArray_DATA(pa), type, OSKAR_CPU, num_sources, &status); /* Copy source data into the sky model. */ old_num = oskar_sky_num_sources(h); oskar_sky_resize(h, old_num + num_sources, &status); oskar_mem_copy_contents(oskar_sky_ra_rad(h), ra_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_dec_rad(h), dec_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_I(h), I_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_Q(h), Q_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_U(h), U_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_V(h), V_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_reference_freq_hz(h), ref_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_spectral_index(h), spix_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_rotation_measure_rad(h), rm_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_fwhm_major_rad(h), maj_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_fwhm_minor_rad(h), min_c, old_num, 0, num_sources, &status); oskar_mem_copy_contents(oskar_sky_position_angle_rad(h), pa_c, old_num, 0, num_sources, &status); /* Free memory. */ oskar_mem_free(ra_c, &status); oskar_mem_free(dec_c, &status); oskar_mem_free(I_c, &status); oskar_mem_free(Q_c, &status); oskar_mem_free(U_c, &status); oskar_mem_free(V_c, &status); oskar_mem_free(ref_c, &status); oskar_mem_free(spix_c, &status); oskar_mem_free(rm_c, &status); oskar_mem_free(maj_c, &status); oskar_mem_free(min_c, &status); oskar_mem_free(pa_c, &status); /* Check for errors. */ if (status) { PyErr_Format(PyExc_RuntimeError, "Sky model append_sources() failed with code %d (%s).", status, oskar_get_error_string(status)); goto fail; } Py_XDECREF(ra); Py_XDECREF(dec); Py_XDECREF(I); Py_XDECREF(Q); Py_XDECREF(U); Py_XDECREF(V); Py_XDECREF(ref); Py_XDECREF(spix); Py_XDECREF(rm); Py_XDECREF(maj); Py_XDECREF(min); Py_XDECREF(pa); return Py_BuildValue(""); fail: Py_XDECREF(ra); Py_XDECREF(dec); Py_XDECREF(I); Py_XDECREF(Q); Py_XDECREF(U); Py_XDECREF(V); Py_XDECREF(ref); Py_XDECREF(spix); Py_XDECREF(rm); Py_XDECREF(maj); Py_XDECREF(min); Py_XDECREF(pa); return 0; }