/* 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); } } }
static void set_up_device_data(oskar_Simulator* h, int* status) { int i, dev_loc, complx, vistype, num_stations, num_src; if (*status) return; /* Get local variables. */ num_stations = oskar_telescope_num_stations(h->tel); num_src = h->max_sources_per_chunk; complx = (h->prec) | OSKAR_COMPLEX; vistype = complx; if (oskar_telescope_pol_mode(h->tel) == OSKAR_POL_MODE_FULL) vistype |= OSKAR_MATRIX; /* Expand the number of devices to the number of selected GPUs, * if required. */ if (h->num_devices < h->num_gpus) oskar_simulator_set_num_devices(h, h->num_gpus); for (i = 0; i < h->num_devices; ++i) { DeviceData* d = &h->d[i]; d->previous_chunk_index = -1; /* Select the device. */ if (i < h->num_gpus) { oskar_device_set(h->gpu_ids[i], status); dev_loc = OSKAR_GPU; } else { dev_loc = OSKAR_CPU; } /* Timers. */ if (!d->tmr_compute) { d->tmr_compute = oskar_timer_create(OSKAR_TIMER_NATIVE); d->tmr_copy = oskar_timer_create(OSKAR_TIMER_NATIVE); d->tmr_clip = oskar_timer_create(OSKAR_TIMER_NATIVE); d->tmr_E = oskar_timer_create(OSKAR_TIMER_NATIVE); d->tmr_K = oskar_timer_create(OSKAR_TIMER_NATIVE); d->tmr_join = oskar_timer_create(OSKAR_TIMER_NATIVE); d->tmr_correlate = oskar_timer_create(OSKAR_TIMER_NATIVE); } /* Visibility blocks. */ if (!d->vis_block) { d->vis_block = oskar_vis_block_create_from_header(dev_loc, h->header, status); d->vis_block_cpu[0] = oskar_vis_block_create_from_header(OSKAR_CPU, h->header, status); d->vis_block_cpu[1] = oskar_vis_block_create_from_header(OSKAR_CPU, h->header, status); } oskar_vis_block_clear(d->vis_block, status); oskar_vis_block_clear(d->vis_block_cpu[0], status); oskar_vis_block_clear(d->vis_block_cpu[1], status); /* Device scratch memory. */ if (!d->tel) { d->u = oskar_mem_create(h->prec, dev_loc, num_stations, status); d->v = oskar_mem_create(h->prec, dev_loc, num_stations, status); d->w = oskar_mem_create(h->prec, dev_loc, num_stations, status); d->chunk = oskar_sky_create(h->prec, dev_loc, num_src, status); d->chunk_clip = oskar_sky_create(h->prec, dev_loc, num_src, status); d->tel = oskar_telescope_create_copy(h->tel, dev_loc, status); d->J = oskar_jones_create(vistype, dev_loc, num_stations, num_src, status); d->R = oskar_type_is_matrix(vistype) ? oskar_jones_create(vistype, dev_loc, num_stations, num_src, status) : 0; d->E = oskar_jones_create(vistype, dev_loc, num_stations, num_src, status); d->K = oskar_jones_create(complx, dev_loc, num_stations, num_src, status); d->Z = 0; d->station_work = oskar_station_work_create(h->prec, dev_loc, status); } } }
oskar_VisHeader* oskar_vis_header_create(int amp_type, int coord_precision, int max_times_per_block, int num_times_total, int max_channels_per_block, int num_channels_total, int num_stations, int write_autocorr, int write_crosscor, int* status) { oskar_VisHeader* hdr = 0; /* Check if safe to proceed. */ if (*status) return 0; /* Check type. */ if (!oskar_type_is_complex(amp_type)) { *status = OSKAR_ERR_BAD_DATA_TYPE; return 0; } /* Allocate the structure. */ hdr = (oskar_VisHeader*) malloc(sizeof(oskar_VisHeader)); if (!hdr) { *status = OSKAR_ERR_MEMORY_ALLOC_FAILURE; return 0; } hdr->amp_type = amp_type; hdr->coord_precision = coord_precision; /* Set number of tags per block in the binary file. */ /* This must be updated if the number of fields written to file from * the oskar_VisBlock structure is changed. */ hdr->num_tags_per_block = 1; if (write_crosscor) hdr->num_tags_per_block += 4; if (write_autocorr) hdr->num_tags_per_block += 1; /* Set dimensions. */ hdr->max_times_per_block = max_times_per_block; hdr->num_times_total = num_times_total; hdr->max_channels_per_block = max_channels_per_block; hdr->num_channels_total = num_channels_total; hdr->num_stations = num_stations; /* Set default polarisation type. */ if (oskar_type_is_matrix(amp_type)) hdr->pol_type = OSKAR_VIS_POL_TYPE_LINEAR_XX_XY_YX_YY; else hdr->pol_type = OSKAR_VIS_POL_TYPE_STOKES_I; /* Initialise meta-data. */ hdr->write_autocorr = write_autocorr; hdr->write_crosscorr = write_crosscor; hdr->freq_start_hz = 0.0; hdr->freq_inc_hz = 0.0; hdr->channel_bandwidth_hz = 0.0; hdr->time_start_mjd_utc = 0.0; hdr->time_inc_sec = 0.0; hdr->time_average_sec = 0.0; hdr->phase_centre_type = 0; hdr->phase_centre_deg[0] = 0.0; hdr->phase_centre_deg[1] = 0.0; hdr->telescope_centre_lon_deg = 0.0; hdr->telescope_centre_lat_deg = 0.0; hdr->telescope_centre_alt_m = 0.0; /* Initialise CPU memory. */ hdr->telescope_path = oskar_mem_create(OSKAR_CHAR, OSKAR_CPU, 0, status); hdr->settings = oskar_mem_create(OSKAR_CHAR, OSKAR_CPU, 0, status); hdr->station_x_offset_ecef_metres = oskar_mem_create(coord_precision, OSKAR_CPU, num_stations, status); hdr->station_y_offset_ecef_metres = oskar_mem_create(coord_precision, OSKAR_CPU, num_stations, status); hdr->station_z_offset_ecef_metres = oskar_mem_create(coord_precision, OSKAR_CPU, num_stations, status); /* Return handle to structure. */ return hdr; }
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_imager_read_coords_vis(oskar_Imager* h, const char* filename, int i_file, int num_files, int* percent_done, int* percent_next, int* status) { oskar_Binary* vis_file; oskar_VisHeader* header; oskar_Mem *uu, *vv, *ww, *weight, *time_centroid, *time_slice; int coord_prec, max_times_per_block, tags_per_block, i_block, num_blocks; int num_times_total, num_stations, num_baselines, num_pols; double time_start_mjd, time_inc_sec; if (*status) return; /* Read the header. */ vis_file = oskar_binary_create(filename, 'r', status); header = oskar_vis_header_read(vis_file, status); if (*status) { oskar_vis_header_free(header, status); oskar_binary_free(vis_file); return; } coord_prec = oskar_vis_header_coord_precision(header); max_times_per_block = oskar_vis_header_max_times_per_block(header); tags_per_block = oskar_vis_header_num_tags_per_block(header); num_times_total = oskar_vis_header_num_times_total(header); num_stations = oskar_vis_header_num_stations(header); num_baselines = num_stations * (num_stations - 1) / 2; num_pols = oskar_type_is_matrix(oskar_vis_header_amp_type(header)) ? 4 : 1; num_blocks = (num_times_total + max_times_per_block - 1) / max_times_per_block; time_start_mjd = oskar_vis_header_time_start_mjd_utc(header) * 86400.0; time_inc_sec = oskar_vis_header_time_inc_sec(header); /* Set visibility meta-data. */ oskar_imager_set_vis_frequency(h, oskar_vis_header_freq_start_hz(header), oskar_vis_header_freq_inc_hz(header), oskar_vis_header_num_channels_total(header)); oskar_imager_set_vis_phase_centre(h, oskar_vis_header_phase_centre_ra_deg(header), oskar_vis_header_phase_centre_dec_deg(header)); /* Create scratch arrays. Weights are all 1. */ uu = oskar_mem_create(coord_prec, OSKAR_CPU, 0, status); vv = oskar_mem_create(coord_prec, OSKAR_CPU, 0, status); ww = oskar_mem_create(coord_prec, OSKAR_CPU, 0, status); time_centroid = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, num_baselines * max_times_per_block, status); time_slice = oskar_mem_create_alias(0, 0, 0, status); weight = oskar_mem_create(h->imager_prec, OSKAR_CPU, num_baselines * num_pols * max_times_per_block, status); oskar_mem_set_value_real(weight, 1.0, 0, 0, status); /* Loop over visibility blocks. */ for (i_block = 0; i_block < num_blocks; ++i_block) { int t, num_times, num_channels, start_time, start_chan, end_chan; int dim_start_and_size[6]; size_t num_rows; if (*status) break; /* Read block metadata. */ oskar_timer_resume(h->tmr_read); oskar_binary_set_query_search_start(vis_file, i_block * tags_per_block, status); oskar_binary_read(vis_file, OSKAR_INT, OSKAR_TAG_GROUP_VIS_BLOCK, OSKAR_VIS_BLOCK_TAG_DIM_START_AND_SIZE, i_block, sizeof(dim_start_and_size), dim_start_and_size, status); start_time = dim_start_and_size[0]; start_chan = dim_start_and_size[1]; num_times = dim_start_and_size[2]; num_channels = dim_start_and_size[3]; num_rows = num_times * num_baselines; end_chan = start_chan + num_channels - 1; /* Fill in the time centroid values. */ for (t = 0; t < num_times; ++t) { oskar_mem_set_alias(time_slice, time_centroid, t * num_baselines, num_baselines, status); oskar_mem_set_value_real(time_slice, time_start_mjd + (start_time + t + 0.5) * time_inc_sec, 0, num_baselines, status); } /* Read the baseline coordinates. */ oskar_binary_read_mem(vis_file, uu, OSKAR_TAG_GROUP_VIS_BLOCK, OSKAR_VIS_BLOCK_TAG_BASELINE_UU, i_block, status); oskar_binary_read_mem(vis_file, vv, OSKAR_TAG_GROUP_VIS_BLOCK, OSKAR_VIS_BLOCK_TAG_BASELINE_VV, i_block, status); oskar_binary_read_mem(vis_file, ww, OSKAR_TAG_GROUP_VIS_BLOCK, OSKAR_VIS_BLOCK_TAG_BASELINE_WW, i_block, status); /* Update the imager with the data. */ oskar_timer_pause(h->tmr_read); oskar_imager_update(h, num_rows, start_chan, end_chan, num_pols, uu, vv, ww, 0, weight, time_centroid, status); *percent_done = (int) round(100.0 * ( (i_block + 1) / (double)(num_blocks * num_files) + i_file / (double)num_files)); if (h->log && percent_next && *percent_done >= *percent_next) { oskar_log_message(h->log, 'S', -2, "%3d%% ...", *percent_done); *percent_next = 10 + 10 * (*percent_done / 10); } } oskar_mem_free(uu, status); oskar_mem_free(vv, status); oskar_mem_free(ww, status); oskar_mem_free(weight, status); oskar_mem_free(time_centroid, status); oskar_mem_free(time_slice, status); oskar_vis_header_free(header, status); oskar_binary_free(vis_file); }
/* 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); }