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_); } } } }
/* Wrapper. */ void oskar_evaluate_jones_K(oskar_Jones* K, int num_sources, const oskar_Mem* l, const oskar_Mem* m, const oskar_Mem* n, const oskar_Mem* u, const oskar_Mem* v, const oskar_Mem* w, double frequency_hz, const oskar_Mem* source_filter, double source_filter_min, double source_filter_max, int* status) { int num_stations, jones_type, base_type, location; double wavenumber; /* Check if safe to proceed. */ if (*status) return; /* Get the Jones matrix block meta-data. */ jones_type = oskar_jones_type(K); base_type = oskar_type_precision(jones_type); location = oskar_jones_mem_location(K); num_stations = oskar_jones_num_stations(K); wavenumber = 2.0 * M_PI * frequency_hz / 299792458.0; /* Check that the data is in the right location. */ if (oskar_mem_location(l) != location || oskar_mem_location(m) != location || oskar_mem_location(n) != location || oskar_mem_location(source_filter) != location || oskar_mem_location(u) != location || oskar_mem_location(v) != location || oskar_mem_location(w) != location) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } /* Check that the data are of the right type. */ if (!oskar_type_is_complex(jones_type) || oskar_type_is_matrix(jones_type)) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } if (base_type != oskar_mem_type(l) || base_type != oskar_mem_type(m) || base_type != oskar_mem_type(n) || base_type != oskar_mem_type(u) || base_type != oskar_mem_type(v) || base_type != oskar_mem_type(w) || base_type != oskar_mem_type(source_filter)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } /* Evaluate Jones matrices. */ if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA if (jones_type == OSKAR_SINGLE_COMPLEX) { oskar_evaluate_jones_K_cuda_f(oskar_jones_float2(K, status), num_sources, oskar_mem_float_const(l, status), oskar_mem_float_const(m, status), oskar_mem_float_const(n, status), num_stations, oskar_mem_float_const(u, status), oskar_mem_float_const(v, status), oskar_mem_float_const(w, status), wavenumber, oskar_mem_float_const(source_filter, status), source_filter_min, source_filter_max); } else if (jones_type == OSKAR_DOUBLE_COMPLEX) { oskar_evaluate_jones_K_cuda_d(oskar_jones_double2(K, status), num_sources, oskar_mem_double_const(l, status), oskar_mem_double_const(m, status), oskar_mem_double_const(n, status), num_stations, oskar_mem_double_const(u, status), oskar_mem_double_const(v, status), oskar_mem_double_const(w, status), wavenumber, oskar_mem_double_const(source_filter, status), source_filter_min, source_filter_max); } oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { if (jones_type == OSKAR_SINGLE_COMPLEX) { oskar_evaluate_jones_K_f(oskar_jones_float2(K, status), num_sources, oskar_mem_float_const(l, status), oskar_mem_float_const(m, status), oskar_mem_float_const(n, status), num_stations, oskar_mem_float_const(u, status), oskar_mem_float_const(v, status), oskar_mem_float_const(w, status), wavenumber, oskar_mem_float_const(source_filter, status), source_filter_min, source_filter_max); } else if (jones_type == OSKAR_DOUBLE_COMPLEX) { oskar_evaluate_jones_K_d(oskar_jones_double2(K, status), num_sources, oskar_mem_double_const(l, status), oskar_mem_double_const(m, status), oskar_mem_double_const(n, status), num_stations, oskar_mem_double_const(u, status), oskar_mem_double_const(v, status), oskar_mem_double_const(w, status), wavenumber, oskar_mem_double_const(source_filter, status), source_filter_min, source_filter_max); } } }
/* Wrapper. */ void oskar_evaluate_jones_R(oskar_Jones* R, int num_sources, const oskar_Mem* ra_rad, const oskar_Mem* dec_rad, const oskar_Telescope* telescope, double gast, int* status) { int i, n, num_stations, jones_type, base_type, location; double latitude, lst; oskar_Mem *R_station; /* Check if safe to proceed. */ if (*status) return; /* Get the Jones matrix block meta-data. */ jones_type = oskar_jones_type(R); base_type = oskar_type_precision(jones_type); location = oskar_jones_mem_location(R); num_stations = oskar_jones_num_stations(R); n = (oskar_telescope_allow_station_beam_duplication(telescope) ? 1 : num_stations); /* Check that the data dimensions are OK. */ if (num_sources > (int)oskar_mem_length(ra_rad) || num_sources > (int)oskar_mem_length(dec_rad) || num_sources > oskar_jones_num_sources(R) || num_stations != oskar_telescope_num_stations(telescope)) { *status = OSKAR_ERR_DIMENSION_MISMATCH; return; } /* Check that the data is in the right location. */ if (location != oskar_mem_location(ra_rad) || location != oskar_mem_location(dec_rad)) { *status = OSKAR_ERR_LOCATION_MISMATCH; return; } /* Check that the data is of the right type. */ if (!oskar_type_is_matrix(jones_type)) { *status = OSKAR_ERR_BAD_DATA_TYPE; return; } if (base_type != oskar_mem_precision(ra_rad) || base_type != oskar_mem_precision(dec_rad)) { *status = OSKAR_ERR_TYPE_MISMATCH; return; } /* Evaluate Jones matrix for each source for appropriate stations. */ R_station = oskar_mem_create_alias(0, 0, 0, status); if (location == OSKAR_GPU) { #ifdef OSKAR_HAVE_CUDA for (i = 0; i < n; ++i) { const oskar_Station* station; /* Get station data. */ station = oskar_telescope_station_const(telescope, i); latitude = oskar_station_lat_rad(station); lst = gast + oskar_station_lon_rad(station); oskar_jones_get_station_pointer(R_station, R, i, status); /* Evaluate source parallactic angles. */ if (base_type == OSKAR_SINGLE) { oskar_evaluate_jones_R_cuda_f( oskar_mem_float4c(R_station, status), num_sources, oskar_mem_float_const(ra_rad, status), oskar_mem_float_const(dec_rad, status), (float)latitude, (float)lst); } else if (base_type == OSKAR_DOUBLE) { oskar_evaluate_jones_R_cuda_d( oskar_mem_double4c(R_station, status), num_sources, oskar_mem_double_const(ra_rad, status), oskar_mem_double_const(dec_rad, status), latitude, lst); } } oskar_device_check_error(status); #else *status = OSKAR_ERR_CUDA_NOT_AVAILABLE; #endif } else if (location == OSKAR_CPU) { for (i = 0; i < n; ++i) { const oskar_Station* station; /* Get station data. */ station = oskar_telescope_station_const(telescope, i); latitude = oskar_station_lat_rad(station); lst = gast + oskar_station_lon_rad(station); oskar_jones_get_station_pointer(R_station, R, i, status); /* Evaluate source parallactic angles. */ if (base_type == OSKAR_SINGLE) { oskar_evaluate_jones_R_f( oskar_mem_float4c(R_station, status), num_sources, oskar_mem_float_const(ra_rad, status), oskar_mem_float_const(dec_rad, status), (float)latitude, (float)lst); } else if (base_type == OSKAR_DOUBLE) { oskar_evaluate_jones_R_d( oskar_mem_double4c(R_station, status), num_sources, oskar_mem_double_const(ra_rad, status), oskar_mem_double_const(dec_rad, status), latitude, lst); } } } /* Copy data for station 0 to stations 1 to n, if using a common sky. */ if (oskar_telescope_allow_station_beam_duplication(telescope)) { oskar_Mem* R0; R0 = oskar_mem_create_alias(0, 0, 0, status); oskar_jones_get_station_pointer(R0, R, 0, status); for (i = 1; i < num_stations; ++i) { oskar_jones_get_station_pointer(R_station, R, i, status); oskar_mem_copy_contents(R_station, R0, 0, 0, oskar_mem_length(R0), status); } oskar_mem_free(R0, status); } oskar_mem_free(R_station, status); }