static void evaluate_jones_Z_station(oskar_Mem* Z_station, double wavelength, const oskar_Mem* TEC, const oskar_Mem* hor_z, double min_elevation, int num_pp, int* status) { int i, type; double arg; /* Check if safe to proceed. */ if (*status) return; type = oskar_mem_type(Z_station); if (type == OSKAR_DOUBLE_COMPLEX) { double2* Z = oskar_mem_double2(Z_station, status); for (i = 0; i < num_pp; ++i) { /* Initialise as an unit scalar Z = (1 + 0i) i.e. no phase change */ Z[i].x = 1.0; Z[i].y = 0.0; /* If the pierce point is below the minimum specified elevation * don't evaluate a phase */ if (asin((oskar_mem_double_const(hor_z, status))[i]) < min_elevation) continue; arg = wavelength * 25. * oskar_mem_double_const(TEC, status)[i]; /* Z phase == exp(i * lambda * 25 * tec) */ Z[i].x = cos(arg); Z[i].y = sin(arg); } } else if (type == OSKAR_SINGLE_COMPLEX) { float2* Z = oskar_mem_float2(Z_station, status); for (i = 0; i < num_pp; ++i) { /* Initialise as an unit scalar Z = (1 + 0i) i.e. no phase change */ Z[i].x = 1.0; Z[i].y = 0.0; /* If the pierce point is below the minimum specified elevation * don't evaluate a phase */ if (asin((oskar_mem_float_const(hor_z, status))[i]) < min_elevation) continue; arg = wavelength * 25. * oskar_mem_float_const(TEC, status)[i]; /* Z phase == exp(i * lambda * 25 * tec) */ Z[i].x = cos(arg); Z[i].y = sin(arg); } } else { *status = OSKAR_ERR_BAD_DATA_TYPE; } }
void copy_vis_pol(oskar_Mem* amps, oskar_Mem* wt, int amps_offset, const oskar_Mem* vis, const oskar_Mem* weight, int vis_offset, int weight_offset, int num_baselines, int stride, int pol_offset, int* status) { int i; if (*status) return; if (oskar_mem_precision(amps) == OSKAR_SINGLE) { float* w_out; const float* w_in; w_out = oskar_mem_float(wt, status) + amps_offset; w_in = oskar_mem_float_const(weight, status); for (i = 0; i < num_baselines; ++i) w_out[i] = w_in[stride * (weight_offset + i) + pol_offset]; if (vis) { float2* a; const float2* v; a = oskar_mem_float2(amps, status) + amps_offset; v = oskar_mem_float2_const(vis, status); for (i = 0; i < num_baselines; ++i) a[i] = v[stride * (vis_offset + i) + pol_offset]; } } else { double* w_out; const double* w_in; w_out = oskar_mem_double(wt, status) + amps_offset; w_in = oskar_mem_double_const(weight, status); for (i = 0; i < num_baselines; ++i) w_out[i] = w_in[stride * (weight_offset + i) + pol_offset]; if (vis) { double2* a; const double2* v; a = oskar_mem_double2(amps, status) + amps_offset; v = oskar_mem_double2_const(vis, status); for (i = 0; i < num_baselines; ++i) a[i] = v[stride * (vis_offset + i) + pol_offset]; } } }
TEST(Mem, set_value_real_double_complex) { // Double precision complex. int n = 100, status = 0; oskar_Mem *mem, *mem2; mem = oskar_mem_create(OSKAR_DOUBLE_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); double2* v = oskar_mem_double2(mem2, &status); ASSERT_EQ(0, status) << oskar_get_error_string(status); for (int i = 0; i < n; ++i) { EXPECT_DOUBLE_EQ(v[i].x, 6.5); EXPECT_DOUBLE_EQ(v[i].y, 0.0); } oskar_mem_free(mem, &status); oskar_mem_free(mem2, &status); }
void oskar_evaluate_element_weights_dft(int num_elements, const oskar_Mem* x, const oskar_Mem* y, const oskar_Mem* z, double wavenumber, double x_beam, double y_beam, double z_beam, oskar_Mem* weights, int* status) { if (*status) return; const int location = oskar_mem_location(weights); const int type = oskar_mem_type(weights); const int precision = oskar_mem_precision(weights); if (oskar_mem_location(x) != location || oskar_mem_location(y) != location || oskar_mem_location(z) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if (oskar_mem_type(x) != precision || oskar_mem_type(y) != precision || oskar_mem_type(z) != precision) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if ((int)oskar_mem_length(weights) < num_elements || (int)oskar_mem_length(x) < num_elements || (int)oskar_mem_length(y) < num_elements || (int)oskar_mem_length(z) < num_elements) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } if (location == OSKAR_CPU) { if (type == OSKAR_DOUBLE_COMPLEX) evaluate_element_weights_dft_d(num_elements, oskar_mem_double_const(x, status), oskar_mem_double_const(y, status), oskar_mem_double_const(z, status), wavenumber, x_beam, y_beam, z_beam, oskar_mem_double2(weights, status)); else if (type == OSKAR_SINGLE_COMPLEX) evaluate_element_weights_dft_f(num_elements, oskar_mem_float_const(x, status), oskar_mem_float_const(y, status), oskar_mem_float_const(z, status), wavenumber, x_beam, y_beam, z_beam, oskar_mem_float2(weights, status)); else *status = OSKAR_ERR_BAD_DATA_TYPE; } else { size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1}; const char* k = 0; const int is_dbl = oskar_mem_is_double(weights); if (type == OSKAR_DOUBLE_COMPLEX) k = "evaluate_element_weights_dft_double"; else if (type == OSKAR_SINGLE_COMPLEX) k = "evaluate_element_weights_dft_float"; else { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } const float w = (float) wavenumber; const float x1 = (float) x_beam; const float y1 = (float) y_beam; const float z1 = (float) z_beam; oskar_device_check_local_size(location, 0, local_size); global_size[0] = oskar_device_global_size( (size_t) num_elements, local_size[0]); const oskar_Arg args[] = { {INT_SZ, &num_elements}, {PTR_SZ, oskar_mem_buffer_const(x)}, {PTR_SZ, oskar_mem_buffer_const(y)}, {PTR_SZ, oskar_mem_buffer_const(z)}, {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ? (const void*)&wavenumber : (const void*)&w}, {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ? (const void*)&x_beam : (const void*)&x1}, {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ? (const void*)&y_beam : (const void*)&y1}, {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ? (const void*)&z_beam : (const void*)&z1}, {PTR_SZ, oskar_mem_buffer(weights)} }; oskar_device_launch_kernel(k, location, 1, local_size, global_size, sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status); } }
void oskar_convert_ludwig3_to_theta_phi_components( int num_points, const oskar_Mem* phi, int stride, int offset, oskar_Mem* vec, int* status) { if (*status) return; const int type = oskar_mem_type(phi); const int location = oskar_mem_location(phi); const int off_h = offset, off_v = offset + 1; if (!oskar_mem_is_matrix(vec)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (location == OSKAR_CPU) { if (type == OSKAR_SINGLE) convert_ludwig3_to_theta_phi_float( num_points, oskar_mem_float_const(phi, status), stride, off_h, off_v, oskar_mem_float2(vec, status), oskar_mem_float2(vec, status)); else if (type == OSKAR_DOUBLE) convert_ludwig3_to_theta_phi_double( num_points, oskar_mem_double_const(phi, status), stride, off_h, off_v, oskar_mem_double2(vec, status), oskar_mem_double2(vec, status)); else *status = OSKAR_ERR_BAD_DATA_TYPE; } else { size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1}; const char* k = 0; if (type == OSKAR_SINGLE) k = "convert_ludwig3_to_theta_phi_float"; else if (type == OSKAR_DOUBLE) k = "convert_ludwig3_to_theta_phi_double"; else { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } oskar_device_check_local_size(location, 0, local_size); global_size[0] = oskar_device_global_size( (size_t) num_points, local_size[0]); const oskar_Arg args[] = { {INT_SZ, &num_points}, {PTR_SZ, oskar_mem_buffer_const(phi)}, {INT_SZ, &stride}, {INT_SZ, &off_h}, {INT_SZ, &off_v}, {PTR_SZ, oskar_mem_buffer(vec)}, {PTR_SZ, oskar_mem_buffer(vec)} }; oskar_device_launch_kernel(k, location, 1, local_size, global_size, sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status); } }
void oskar_evaluate_vla_beam_pbcor(oskar_Mem* beam, int num_sources, const oskar_Mem* l, const oskar_Mem* m, double frequency_hz, int* status) { int index, precision, type, location; double f, p1, p2, p3; /* Check if safe to proceed. */ if (*status) return; /* Check type and location. */ precision = oskar_mem_precision(beam); type = oskar_mem_type(beam); location = oskar_mem_location(beam); if (precision != oskar_mem_type(l) || precision != oskar_mem_type(m)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (location != oskar_mem_location(l) || location != oskar_mem_location(m)) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } /* Find the nearest frequency at which data exists. */ index = oskar_find_closest_match_d(frequency_hz / 1.0e9, sizeof(freqs_ghz) / sizeof(double), freqs_ghz); f = frequency_hz / 1.0e9; p1 = p1s[index]; p2 = p2s[index]; p3 = p3s[index]; /* Switch on precision. */ if (precision == OSKAR_SINGLE) { const float *l_, *m_; l_ = oskar_mem_float_const(l, status); m_ = oskar_mem_float_const(m, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA if (type == OSKAR_SINGLE) { oskar_evaluate_vla_beam_pbcor_cuda_f( oskar_mem_float(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_SINGLE_COMPLEX) { oskar_evaluate_vla_beam_pbcor_complex_cuda_f( oskar_mem_float2(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_SINGLE_COMPLEX_MATRIX) { oskar_evaluate_vla_beam_pbcor_matrix_cuda_f( oskar_mem_float4c(beam, status), num_sources, l_, m_, f, p1, p2, p3); } oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { if (type == OSKAR_SINGLE) { oskar_evaluate_vla_beam_pbcor_f( oskar_mem_float(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_SINGLE_COMPLEX) { oskar_evaluate_vla_beam_pbcor_complex_f( oskar_mem_float2(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_SINGLE_COMPLEX_MATRIX) { oskar_evaluate_vla_beam_pbcor_matrix_f( oskar_mem_float4c(beam, status), num_sources, l_, m_, f, p1, p2, p3); } } } else if (precision == OSKAR_DOUBLE) { const double *l_, *m_; l_ = oskar_mem_double_const(l, status); m_ = oskar_mem_double_const(m, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA if (type == OSKAR_DOUBLE) { oskar_evaluate_vla_beam_pbcor_cuda_d( oskar_mem_double(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_DOUBLE_COMPLEX) { oskar_evaluate_vla_beam_pbcor_complex_cuda_d( oskar_mem_double2(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_DOUBLE_COMPLEX_MATRIX) { oskar_evaluate_vla_beam_pbcor_matrix_cuda_d( oskar_mem_double4c(beam, status), num_sources, l_, m_, f, p1, p2, p3); } oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { if (type == OSKAR_DOUBLE) { oskar_evaluate_vla_beam_pbcor_d( oskar_mem_double(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_DOUBLE_COMPLEX) { oskar_evaluate_vla_beam_pbcor_complex_d( oskar_mem_double2(beam, status), num_sources, l_, m_, f, p1, p2, p3); } else if (type == OSKAR_DOUBLE_COMPLEX_MATRIX) { oskar_evaluate_vla_beam_pbcor_matrix_d( oskar_mem_double4c(beam, status), num_sources, l_, m_, f, p1, p2, p3); } } } else { *status = OSKAR_ERR_BAD_DATA_TYPE; } }
TEST(imager, grid_sum) { int status = 0, type = OSKAR_DOUBLE; int size = 2048, grid_size = size * size; // Create and set up the imager. oskar_Imager* im = oskar_imager_create(type, &status); oskar_imager_set_grid_kernel(im, "pillbox", 1, 1, &status); oskar_imager_set_fov(im, 5.0); oskar_imager_set_size(im, size, &status); oskar_Mem* grid = oskar_mem_create(type | OSKAR_COMPLEX, OSKAR_CPU, grid_size, &status); ASSERT_EQ(0, status); // Create visibility data. int num_vis = 10000; oskar_Mem* uu = oskar_mem_create(type, OSKAR_CPU, num_vis, &status); oskar_Mem* vv = oskar_mem_create(type, OSKAR_CPU, num_vis, &status); oskar_Mem* ww = oskar_mem_create(type, OSKAR_CPU, num_vis, &status); oskar_Mem* vis = oskar_mem_create(type | OSKAR_COMPLEX, OSKAR_CPU, num_vis, &status); oskar_Mem* weight = oskar_mem_create(type, OSKAR_CPU, num_vis, &status); oskar_mem_random_gaussian(uu, 0, 1, 2, 3, 100.0, &status); oskar_mem_random_gaussian(vv, 4, 5, 6, 7, 100.0, &status); oskar_mem_set_value_real(vis, 1.0, 0, num_vis, &status); oskar_mem_set_value_real(weight, 1.0, 0, num_vis, &status); // Grid visibility data. double plane_norm = 0.0; oskar_imager_update_plane(im, num_vis, uu, vv, ww, vis, weight, grid, &plane_norm, 0, &status); ASSERT_DOUBLE_EQ((double)num_vis, plane_norm); // Sum the grid. double2* t = oskar_mem_double2(grid, &status); double sum = 0.0; for (int i = 0; i < grid_size; i++) sum += t[i].x; ASSERT_DOUBLE_EQ((double)num_vis, sum); // Finalise the image. oskar_imager_finalise_plane(im, grid, plane_norm, &status); ASSERT_EQ(0, status); #ifdef WRITE_FITS // Get the real part only. if (oskar_mem_precision(grid) == OSKAR_DOUBLE) { double *t = oskar_mem_double(grid, &status); for (int j = 0; j < grid_size; ++j) t[j] = t[2 * j]; } else { float *t = oskar_mem_float(grid, &status); for (int j = 0; j < grid_size; ++j) t[j] = t[2 * j]; } // Save the real part. fitsfile* f; long naxes[2] = {size, size}, firstpix[2] = {1, 1}; fits_create_file(&f, "test_imager_grid_sum.fits", &status); fits_create_img(f, (type == OSKAR_DOUBLE ? DOUBLE_IMG : FLOAT_IMG), 2, naxes, &status); fits_write_pix(f, (type == OSKAR_DOUBLE ? TDOUBLE : TFLOAT), firstpix, grid_size, oskar_mem_void(grid), &status); fits_close_file(f, &status); #endif // Clean up. oskar_imager_free(im, &status); oskar_mem_free(uu, &status); oskar_mem_free(vv, &status); oskar_mem_free(ww, &status); oskar_mem_free(vis, &status); oskar_mem_free(weight, &status); oskar_mem_free(grid, &status); }
/* Wrapper. */ void oskar_convert_ludwig3_to_theta_phi_components(oskar_Mem* vec, int offset, int stride, int num_points, const oskar_Mem* phi, int* status) { int type, location; /* Check if safe to proceed. */ if (*status) return; /* Check that the vector component data is in matrix form. */ if (!oskar_mem_is_matrix(vec)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } /* Get data type and location. */ type = oskar_mem_type(phi); location = oskar_mem_location(phi); /* Convert vector representation from Ludwig-3 to spherical. */ if (type == OSKAR_SINGLE) { float2 *h_theta, *v_phi; const float *phi_; h_theta = oskar_mem_float2(vec, status) + offset; v_phi = oskar_mem_float2(vec, status) + offset + 1; phi_ = oskar_mem_float_const(phi, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_convert_ludwig3_to_theta_phi_components_cuda_f(num_points, h_theta, v_phi, phi_, stride); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { oskar_convert_ludwig3_to_theta_phi_components_f(num_points, h_theta, v_phi, phi_, stride); } } else if (type == OSKAR_DOUBLE) { double2 *h_theta, *v_phi; const double *phi_; h_theta = oskar_mem_double2(vec, status) + offset; v_phi = oskar_mem_double2(vec, status) + offset + 1; phi_ = oskar_mem_double_const(phi, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_convert_ludwig3_to_theta_phi_components_cuda_d(num_points, h_theta, v_phi, phi_, stride); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { oskar_convert_ludwig3_to_theta_phi_components_d(num_points, h_theta, v_phi, phi_, stride); } } else *status = OSKAR_ERR_BAD_DATA_TYPE; }
void oskar_mem_add_real(oskar_Mem* mem, double val, int* status) { int precision, location; size_t i, num_elements; /* Check if safe to proceed. */ if (*status) return; /* Get meta-data. */ precision = oskar_mem_precision(mem); location = oskar_mem_location(mem); /* Check for empty array. */ num_elements = oskar_mem_length(mem); if (num_elements == 0) return; /* Check location. */ if (location != OSKAR_CPU) { *status = OSKAR_ERR_BAD_LOCATION; return; } /* Get total number of elements to add. */ if (oskar_mem_is_matrix(mem)) num_elements *= 4; /* Switch on type and location. */ if (oskar_mem_is_complex(mem)) { if (precision == OSKAR_DOUBLE) { double2 *t; t = oskar_mem_double2(mem, status); for (i = 0; i < num_elements; ++i) t[i].x += val; } else if (precision == OSKAR_SINGLE) { float2 *t; t = oskar_mem_float2(mem, status); for (i = 0; i < num_elements; ++i) t[i].x += val; } else { *status = OSKAR_ERR_BAD_DATA_TYPE; } } else { if (precision == OSKAR_DOUBLE) { double *t; t = oskar_mem_double(mem, status); for (i = 0; i < num_elements; ++i) t[i] += val; } else if (precision == OSKAR_SINGLE) { float *t; t = oskar_mem_float(mem, status); for (i = 0; i < num_elements; ++i) t[i] += val; } else { *status = OSKAR_ERR_BAD_DATA_TYPE; } } }
void oskar_imager_filter_uv(const oskar_Imager* h, size_t* num_vis, oskar_Mem* uu, oskar_Mem* vv, oskar_Mem* ww, oskar_Mem* amp, oskar_Mem* weight, int* status) { size_t i, n; double r, range[2]; /* Return immediately if filtering is not enabled. */ if (h->uv_filter_min <= 0.0 && h->uv_filter_max < 0.0) return; if (*status) return; /* Get the range (squared, to avoid lots of square roots later). */ range[0] = h->uv_filter_min; range[1] = (h->uv_filter_max < 0.0) ? (double) FLT_MAX : h->uv_filter_max; range[0] *= range[0]; range[1] *= range[1]; /* Get the number of input points, and set the number selected to zero. */ n = *num_vis; *num_vis = 0; /* Apply the UV baseline length filter. */ if (h->imager_prec == OSKAR_DOUBLE) { double *uu_, *vv_, *ww_, *weight_; double2* amp_; uu_ = oskar_mem_double(uu, status); vv_ = oskar_mem_double(vv, status); ww_ = oskar_mem_double(ww, status); amp_ = oskar_mem_double2(amp, status); weight_ = oskar_mem_double(weight, status); for (i = 0; i < n; ++i) { r = uu_[i] * uu_[i] + vv_[i] * vv_[i]; if (r >= range[0] && r <= range[1]) { uu_[*num_vis] = uu_[i]; vv_[*num_vis] = vv_[i]; ww_[*num_vis] = ww_[i]; amp_[*num_vis] = amp_[i]; weight_[*num_vis] = weight_[i]; (*num_vis)++; } } } else { float *uu_, *vv_, *ww_, *weight_; float2* amp_; uu_ = oskar_mem_float(uu, status); vv_ = oskar_mem_float(vv, status); ww_ = oskar_mem_float(ww, status); amp_ = oskar_mem_float2(amp, status); weight_ = oskar_mem_float(weight, status); for (i = 0; i < n; ++i) { r = uu_[i] * uu_[i] + vv_[i] * vv_[i]; if (r >= range[0] && r <= range[1]) { uu_[*num_vis] = uu_[i]; vv_[*num_vis] = vv_[i]; ww_[*num_vis] = ww_[i]; amp_[*num_vis] = amp_[i]; weight_[*num_vis] = weight_[i]; (*num_vis)++; } } } }
void oskar_dftw( int normalise, int num_in, double wavenumber, const oskar_Mem* weights_in, const oskar_Mem* x_in, const oskar_Mem* y_in, const oskar_Mem* z_in, int offset_coord_out, int num_out, const oskar_Mem* x_out, const oskar_Mem* y_out, const oskar_Mem* z_out, const oskar_Mem* data, int offset_out, oskar_Mem* output, int* status) { if (*status) return; const int location = oskar_mem_location(output); const int type = oskar_mem_precision(output); const int is_dbl = oskar_mem_is_double(output); const int is_3d = (z_in != NULL && z_out != NULL); const int is_data = (data != NULL); const int is_matrix = oskar_mem_is_matrix(output); if (!oskar_mem_is_complex(output) || !oskar_mem_is_complex(weights_in) || oskar_mem_is_matrix(weights_in)) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } if (oskar_mem_location(weights_in) != location || oskar_mem_location(x_in) != location || oskar_mem_location(y_in) != location || oskar_mem_location(x_out) != location || oskar_mem_location(y_out) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if (oskar_mem_precision(weights_in) != type || oskar_mem_type(x_in) != type || oskar_mem_type(y_in) != type || oskar_mem_type(x_out) != type || oskar_mem_type(y_out) != type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (is_data) { if (oskar_mem_location(data) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if (!oskar_mem_is_complex(data) || oskar_mem_type(data) != oskar_mem_type(output) || oskar_mem_precision(data) != type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } } if (is_3d) { if (oskar_mem_location(z_in) != location || oskar_mem_location(z_out) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if (oskar_mem_type(z_in) != type || oskar_mem_type(z_out) != type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } } oskar_mem_ensure(output, (size_t) offset_out + num_out, status); if (*status) return; if (location == OSKAR_CPU) { if (is_data) { if (is_matrix) { if (is_3d) { if (is_dbl) dftw_m2m_3d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), oskar_mem_double_const(z_in, status), offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), oskar_mem_double_const(z_out, status), oskar_mem_double4c_const(data, status), offset_out, oskar_mem_double4c(output, status), 0); else dftw_m2m_3d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), oskar_mem_float_const(z_in, status), offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), oskar_mem_float_const(z_out, status), oskar_mem_float4c_const(data, status), offset_out, oskar_mem_float4c(output, status), 0); } else { if (is_dbl) dftw_m2m_2d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), 0, oskar_mem_double4c_const(data, status), offset_out, oskar_mem_double4c(output, status), 0); else dftw_m2m_2d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), 0, oskar_mem_float4c_const(data, status), offset_out, oskar_mem_float4c(output, status), 0); } } else { if (is_3d) { if (is_dbl) dftw_c2c_3d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), oskar_mem_double_const(z_in, status), offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), oskar_mem_double_const(z_out, status), oskar_mem_double2_const(data, status), offset_out, oskar_mem_double2(output, status), 0); else dftw_c2c_3d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), oskar_mem_float_const(z_in, status), offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), oskar_mem_float_const(z_out, status), oskar_mem_float2_const(data, status), offset_out, oskar_mem_float2(output, status), 0); } else { if (is_dbl) dftw_c2c_2d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), 0, oskar_mem_double2_const(data, status), offset_out, oskar_mem_double2(output, status), 0); else dftw_c2c_2d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), 0, oskar_mem_float2_const(data, status), offset_out, oskar_mem_float2(output, status), 0); } } } else { if (is_3d) { if (is_dbl) dftw_o2c_3d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), oskar_mem_double_const(z_in, status), offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), oskar_mem_double_const(z_out, status), 0, offset_out, oskar_mem_double2(output, status), 0); else dftw_o2c_3d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), oskar_mem_float_const(z_in, status), offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), oskar_mem_float_const(z_out, status), 0, offset_out, oskar_mem_float2(output, status), 0); } else { if (is_dbl) dftw_o2c_2d_double(num_in, wavenumber, oskar_mem_double2_const(weights_in, status), oskar_mem_double_const(x_in, status), oskar_mem_double_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_double_const(x_out, status), oskar_mem_double_const(y_out, status), 0, 0, offset_out, oskar_mem_double2(output, status), 0); else dftw_o2c_2d_float(num_in, (float)wavenumber, oskar_mem_float2_const(weights_in, status), oskar_mem_float_const(x_in, status), oskar_mem_float_const(y_in, status), 0, offset_coord_out, num_out, oskar_mem_float_const(x_out, status), oskar_mem_float_const(y_out, status), 0, 0, offset_out, oskar_mem_float2(output, status), 0); } } } else { size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1}; const void* np = 0; const char* k = 0; int max_in_chunk; float wavenumber_f = (float) wavenumber; /* Select the kernel. */ switch (is_dbl * DBL | is_3d * D3 | is_data * DAT | is_matrix * MAT) { case D2 | FLT: k = "dftw_o2c_2d_float"; break; case D2 | DBL: k = "dftw_o2c_2d_double"; break; case D3 | FLT: k = "dftw_o2c_3d_float"; break; case D3 | DBL: k = "dftw_o2c_3d_double"; break; case D2 | FLT | DAT: k = "dftw_c2c_2d_float"; break; case D2 | DBL | DAT: k = "dftw_c2c_2d_double"; break; case D3 | FLT | DAT: k = "dftw_c2c_3d_float"; break; case D3 | DBL | DAT: k = "dftw_c2c_3d_double"; break; case D2 | FLT | DAT | MAT: k = "dftw_m2m_2d_float"; break; case D2 | DBL | DAT | MAT: k = "dftw_m2m_2d_double"; break; case D3 | FLT | DAT | MAT: k = "dftw_m2m_3d_float"; break; case D3 | DBL | DAT | MAT: k = "dftw_m2m_3d_double"; break; default: *status = OSKAR_ERR_FUNCTION_NOT_AVAILABLE; return; } if (oskar_device_is_nv(location)) local_size[0] = (size_t) get_block_size(num_out); oskar_device_check_local_size(location, 0, local_size); global_size[0] = oskar_device_global_size( (size_t) num_out, local_size[0]); /* max_in_chunk must be multiple of 16. */ max_in_chunk = is_3d ? (is_dbl ? 384 : 800) : (is_dbl ? 448 : 896); if (is_data && is_3d && !is_dbl) max_in_chunk = 768; const size_t element_size = is_dbl ? sizeof(double) : sizeof(float); const size_t local_mem_size = max_in_chunk * element_size; const size_t arg_size_local[] = { 2 * local_mem_size, 2 * local_mem_size, (is_3d ? local_mem_size : 0) }; /* Set kernel arguments. */ const oskar_Arg args[] = { {INT_SZ, &num_in}, {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ? (void*)&wavenumber : (void*)&wavenumber_f}, {PTR_SZ, oskar_mem_buffer_const(weights_in)}, {PTR_SZ, oskar_mem_buffer_const(x_in)}, {PTR_SZ, oskar_mem_buffer_const(y_in)}, {PTR_SZ, is_3d ? oskar_mem_buffer_const(z_in) : &np}, {INT_SZ, &offset_coord_out}, {INT_SZ, &num_out}, {PTR_SZ, oskar_mem_buffer_const(x_out)}, {PTR_SZ, oskar_mem_buffer_const(y_out)}, {PTR_SZ, is_3d ? oskar_mem_buffer_const(z_out) : &np}, {PTR_SZ, is_data ? oskar_mem_buffer_const(data) : &np}, {INT_SZ, &offset_out}, {PTR_SZ, oskar_mem_buffer(output)}, {INT_SZ, &max_in_chunk} }; oskar_device_launch_kernel(k, location, 1, local_size, global_size, sizeof(args) / sizeof(oskar_Arg), args, sizeof(arg_size_local) / sizeof(size_t), arg_size_local, status); } if (normalise) oskar_mem_scale_real(output, 1. / num_in, offset_out, num_out, 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(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); }
void oskar_blank_below_horizon(int offset_mask, int num_sources, const oskar_Mem* mask, int offset_out, oskar_Mem* data, int* status) { if (*status) return; const int location = oskar_mem_location(data); if (oskar_mem_location(mask) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if (oskar_mem_type(mask) != oskar_mem_precision(data)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if ((int)oskar_mem_length(data) < num_sources) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } if (location == OSKAR_CPU) { switch (oskar_mem_type(data)) { case OSKAR_DOUBLE_COMPLEX_MATRIX: blank_below_horizon_matrix_d(offset_mask, num_sources, oskar_mem_double_const(mask, status), offset_out, oskar_mem_double4c(data, status)); break; case OSKAR_DOUBLE_COMPLEX: blank_below_horizon_scalar_d(offset_mask, num_sources, oskar_mem_double_const(mask, status), offset_out, oskar_mem_double2(data, status)); break; case OSKAR_SINGLE_COMPLEX_MATRIX: blank_below_horizon_matrix_f(offset_mask, num_sources, oskar_mem_float_const(mask, status), offset_out, oskar_mem_float4c(data, status)); break; case OSKAR_SINGLE_COMPLEX: blank_below_horizon_scalar_f(offset_mask, num_sources, oskar_mem_float_const(mask, status), offset_out, oskar_mem_float2(data, status)); break; default: *status = OSKAR_ERR_BAD_DATA_TYPE; break; } } else { size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1}; const char* k = 0; switch (oskar_mem_type(data)) { case OSKAR_DOUBLE_COMPLEX_MATRIX: k = "blank_below_horizon_matrix_double"; break; case OSKAR_DOUBLE_COMPLEX: k = "blank_below_horizon_scalar_double"; break; case OSKAR_SINGLE_COMPLEX_MATRIX: k = "blank_below_horizon_matrix_float"; break; case OSKAR_SINGLE_COMPLEX: k = "blank_below_horizon_scalar_float"; break; default: *status = OSKAR_ERR_BAD_DATA_TYPE; return; } oskar_device_check_local_size(location, 0, local_size); global_size[0] = oskar_device_global_size( (size_t) num_sources, local_size[0]); const oskar_Arg args[] = { {INT_SZ, &offset_mask}, {INT_SZ, &num_sources}, {PTR_SZ, oskar_mem_buffer_const(mask)}, {INT_SZ, &offset_out}, {PTR_SZ, oskar_mem_buffer(data)} }; oskar_device_launch_kernel(k, location, 1, local_size, global_size, sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status); } }
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); }
void oskar_gaussian_circular(int num_points, const oskar_Mem* l, const oskar_Mem* m, double std, oskar_Mem* out, int* status) { if (*status) return; const int location = oskar_mem_location(out); const double inv_2_var = 1.0 / (2.0 * std * std); const float inv_2_var_f = (float)inv_2_var; if (oskar_mem_precision(out) != oskar_mem_type(l) || oskar_mem_precision(out) != oskar_mem_type(m)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (location != oskar_mem_location(l) || location != oskar_mem_location(m)) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } if ((int)oskar_mem_length(l) < num_points || (int)oskar_mem_length(m) < num_points) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } oskar_mem_ensure(out, num_points, status); if (*status) return; if (location == OSKAR_CPU) { switch (oskar_mem_type(out)) { case OSKAR_SINGLE_COMPLEX: gaussian_circular_complex_f(num_points, oskar_mem_float_const(l, status), oskar_mem_float_const(m, status), inv_2_var_f, oskar_mem_float2(out, status)); break; case OSKAR_DOUBLE_COMPLEX: gaussian_circular_complex_d(num_points, oskar_mem_double_const(l, status), oskar_mem_double_const(m, status), inv_2_var, oskar_mem_double2(out, status)); break; case OSKAR_SINGLE_COMPLEX_MATRIX: gaussian_circular_matrix_f(num_points, oskar_mem_float_const(l, status), oskar_mem_float_const(m, status), inv_2_var_f, oskar_mem_float4c(out, status)); break; case OSKAR_DOUBLE_COMPLEX_MATRIX: gaussian_circular_matrix_d(num_points, oskar_mem_double_const(l, status), oskar_mem_double_const(m, status), inv_2_var, oskar_mem_double4c(out, status)); break; default: *status = OSKAR_ERR_BAD_DATA_TYPE; break; } } else { size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1}; const char* k = 0; const int is_dbl = oskar_mem_is_double(out); switch (oskar_mem_type(out)) { case OSKAR_SINGLE_COMPLEX: k = "gaussian_circular_complex_float"; break; case OSKAR_DOUBLE_COMPLEX: k = "gaussian_circular_complex_double"; break; case OSKAR_SINGLE_COMPLEX_MATRIX: k = "gaussian_circular_matrix_float"; break; case OSKAR_DOUBLE_COMPLEX_MATRIX: k = "gaussian_circular_matrix_double"; break; default: *status = OSKAR_ERR_BAD_DATA_TYPE; return; } oskar_device_check_local_size(location, 0, local_size); global_size[0] = oskar_device_global_size( (size_t) num_points, local_size[0]); const oskar_Arg args[] = { {INT_SZ, &num_points}, {PTR_SZ, oskar_mem_buffer_const(l)}, {PTR_SZ, oskar_mem_buffer_const(m)}, {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ? (const void*)&inv_2_var : (const void*)&inv_2_var_f}, {PTR_SZ, oskar_mem_buffer(out)} }; oskar_device_launch_kernel(k, location, 1, local_size, global_size, sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status); } }
void oskar_auto_correlate(oskar_Mem* vis, int n_sources, const oskar_Jones* J, const oskar_Sky* sky, int* status) { int jones_type, base_type, location, matrix_type, n_stations; /* Check if safe to proceed. */ if (*status) return; /* Get the data dimensions. */ n_stations = oskar_jones_num_stations(J); /* Check data locations. */ location = oskar_sky_mem_location(sky); if (oskar_jones_mem_location(J) != location || oskar_mem_location(vis) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } /* Check for consistent data types. */ jones_type = oskar_jones_type(J); base_type = oskar_sky_precision(sky); matrix_type = oskar_type_is_matrix(jones_type) && oskar_mem_is_matrix(vis); if (oskar_mem_precision(vis) != base_type || oskar_type_precision(jones_type) != base_type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (oskar_mem_type(vis) != jones_type) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } /* If neither single or double precision, return error. */ if (base_type != OSKAR_SINGLE && base_type != OSKAR_DOUBLE) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } /* Check the input dimensions. */ if (oskar_jones_num_sources(J) < n_sources) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } /* Select kernel. */ if (base_type == OSKAR_DOUBLE) { const double *I_, *Q_, *U_, *V_; I_ = oskar_mem_double_const(oskar_sky_I_const(sky), status); Q_ = oskar_mem_double_const(oskar_sky_Q_const(sky), status); U_ = oskar_mem_double_const(oskar_sky_U_const(sky), status); V_ = oskar_mem_double_const(oskar_sky_V_const(sky), status); if (matrix_type) { double4c *vis_; const double4c *J_; vis_ = oskar_mem_double4c(vis, status); J_ = oskar_jones_double4c_const(J, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_auto_correlate_cuda_d(n_sources, n_stations, J_, I_, Q_, U_, V_, vis_); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else /* CPU */ { oskar_auto_correlate_omp_d(n_sources, n_stations, J_, I_, Q_, U_, V_, vis_); } } else /* Scalar version. */ { double2 *vis_; const double2 *J_; vis_ = oskar_mem_double2(vis, status); J_ = oskar_jones_double2_const(J, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_auto_correlate_scalar_cuda_d(n_sources, n_stations, J_, I_, vis_); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else /* CPU */ { oskar_auto_correlate_scalar_omp_d(n_sources, n_stations, J_, I_, vis_); } } } else /* Single precision. */ { const float *I_, *Q_, *U_, *V_; I_ = oskar_mem_float_const(oskar_sky_I_const(sky), status); Q_ = oskar_mem_float_const(oskar_sky_Q_const(sky), status); U_ = oskar_mem_float_const(oskar_sky_U_const(sky), status); V_ = oskar_mem_float_const(oskar_sky_V_const(sky), status); if (matrix_type) { float4c *vis_; const float4c *J_; vis_ = oskar_mem_float4c(vis, status); J_ = oskar_jones_float4c_const(J, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_auto_correlate_cuda_f(n_sources, n_stations, J_, I_, Q_, U_, V_, vis_); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else /* CPU */ { oskar_auto_correlate_omp_f(n_sources, n_stations, J_, I_, Q_, U_, V_, vis_); } } else /* Scalar version. */ { float2 *vis_; const float2 *J_; vis_ = oskar_mem_float2(vis, status); J_ = oskar_jones_float2_const(J, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_auto_correlate_scalar_cuda_f(n_sources, n_stations, J_, I_, vis_); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else /* CPU */ { oskar_auto_correlate_scalar_omp_f(n_sources, n_stations, J_, I_, vis_); } } } }
void oskar_evaluate_station_beam_gaussian(oskar_Mem* beam, int num_points, const oskar_Mem* l, const oskar_Mem* m, const oskar_Mem* horizon_mask, double fwhm_rad, int* status) { int type, location; double fwhm_lm, std; /* Check if safe to proceed. */ if (*status) return; /* Get type and check consistency. */ type = oskar_mem_precision(beam); if (type != oskar_mem_type(l) || type != oskar_mem_type(m)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (type != OSKAR_SINGLE && type != OSKAR_DOUBLE) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } if (!oskar_mem_is_complex(beam)) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } if (fwhm_rad == 0.0) { *status = OSKAR_ERR_SETTINGS_TELESCOPE; return; } /* Get location and check consistency. */ location = oskar_mem_location(beam); if (location != oskar_mem_location(l) || location != oskar_mem_location(m)) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } /* Check that length of input arrays are consistent. */ if ((int)oskar_mem_length(l) < num_points || (int)oskar_mem_length(m) < num_points) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } /* Resize output array if needed. */ if ((int)oskar_mem_length(beam) < num_points) oskar_mem_realloc(beam, num_points, status); /* Check if safe to proceed. */ if (*status) return; /* Compute Gaussian standard deviation from FWHM. */ fwhm_lm = sin(fwhm_rad); std = fwhm_lm / (2.0 * sqrt(2.0 * log(2.0))); if (type == OSKAR_DOUBLE) { const double *l_, *m_; l_ = oskar_mem_double_const(l, status); m_ = oskar_mem_double_const(m, status); if (location == OSKAR_CPU) { if (oskar_mem_is_scalar(beam)) { oskar_gaussian_d(oskar_mem_double2(beam, status), num_points, l_, m_, std); } else { oskar_gaussian_md(oskar_mem_double4c(beam, status), num_points, l_, m_, std); } } else { #ifdef OSKAR_HAVE_CUDA if (oskar_mem_is_scalar(beam)) { oskar_gaussian_cuda_d(oskar_mem_double2(beam, status), num_points, l_, m_, std); } else { oskar_gaussian_cuda_md(oskar_mem_double4c(beam, status), num_points, l_, m_, std); } oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } } else /* type == OSKAR_SINGLE */ { const float *l_, *m_; l_ = oskar_mem_float_const(l, status); m_ = oskar_mem_float_const(m, status); if (location == OSKAR_CPU) { if (oskar_mem_is_scalar(beam)) { oskar_gaussian_f(oskar_mem_float2(beam, status), num_points, l_, m_, (float)std); } else { oskar_gaussian_mf(oskar_mem_float4c(beam, status), num_points, l_, m_, (float)std); } } else { #ifdef OSKAR_HAVE_CUDA if (oskar_mem_is_scalar(beam)) { oskar_gaussian_cuda_f(oskar_mem_float2(beam, status), num_points, l_, m_, (float)std); } else { oskar_gaussian_cuda_mf(oskar_mem_float4c(beam, status), num_points, l_, m_, (float)std); } oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } } /* Blank (zero) sources below the horizon. */ oskar_blank_below_horizon(beam, horizon_mask, num_points, status); }
/* Wrapper. */ void oskar_evaluate_cross_power(int num_sources, int num_stations, const oskar_Mem* jones, oskar_Mem* out, int *status) { int type, location; /* Check if safe to proceed. */ if (*status) return; /* Check type and location. */ type = oskar_mem_type(jones); location = oskar_mem_location(jones); if (type != oskar_mem_type(out)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } if (location != oskar_mem_location(out)) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } /* Switch on type and location combination. */ if (type == OSKAR_SINGLE_COMPLEX_MATRIX) { if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_evaluate_cross_power_cuda_f(num_sources, num_stations, oskar_mem_float4c_const(jones, status), oskar_mem_float4c(out, status)); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { oskar_evaluate_cross_power_omp_f(num_sources, num_stations, oskar_mem_float4c_const(jones, status), oskar_mem_float4c(out, status)); } } else if (type == OSKAR_DOUBLE_COMPLEX_MATRIX) { if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_evaluate_cross_power_cuda_d(num_sources, num_stations, oskar_mem_double4c_const(jones, status), oskar_mem_double4c(out, status)); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { oskar_evaluate_cross_power_omp_d(num_sources, num_stations, oskar_mem_double4c_const(jones, status), oskar_mem_double4c(out, status)); } } /* Scalar versions. */ else if (type == OSKAR_SINGLE_COMPLEX) { if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_evaluate_cross_power_scalar_cuda_f(num_sources, num_stations, oskar_mem_float2_const(jones, status), oskar_mem_float2(out, status)); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { oskar_evaluate_cross_power_scalar_omp_f(num_sources, num_stations, oskar_mem_float2_const(jones, status), oskar_mem_float2(out, status)); } } else if (type == OSKAR_DOUBLE_COMPLEX) { if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA oskar_evaluate_cross_power_scalar_cuda_d(num_sources, num_stations, oskar_mem_double2_const(jones, status), oskar_mem_double2(out, status)); oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { oskar_evaluate_cross_power_scalar_omp_d(num_sources, num_stations, oskar_mem_double2_const(jones, status), oskar_mem_double2(out, status)); } } else { *status = OSKAR_ERR_BAD_DATA_TYPE; } }