int benchmark(int num_stations, int num_sources, int type, int jones_type, int loc, int use_extended, int use_time_ave, int niter, std::vector<double>& times) { int status = 0; oskar_Timer* timer; timer = oskar_timer_create(loc == OSKAR_GPU ? OSKAR_TIMER_CUDA : OSKAR_TIMER_OMP); // Set up a test sky model, telescope model and Jones matrices. oskar_Telescope* tel = oskar_telescope_create(type, loc, num_stations, &status); oskar_Sky* sky = oskar_sky_create(type, loc, num_sources, &status); oskar_Jones* J = oskar_jones_create(jones_type, loc, num_stations, num_sources, &status); oskar_telescope_set_channel_bandwidth(tel, 1e6); oskar_telescope_set_time_average(tel, (double) use_time_ave); oskar_sky_set_use_extended(sky, use_extended); // Memory for visibility coordinates and output visibility slice. oskar_Mem *vis, *u, *v, *w; vis = oskar_mem_create(jones_type, loc, oskar_telescope_num_baselines(tel), &status); u = oskar_mem_create(type, loc, num_stations, &status); v = oskar_mem_create(type, loc, num_stations, &status); w = oskar_mem_create(type, loc, num_stations, &status); // Run benchmark. times.resize(niter); for (int i = 0; i < niter; ++i) { oskar_timer_start(timer); oskar_cross_correlate(vis, oskar_sky_num_sources(sky), J, sky, tel, u, v, w, 0.0, 100e6, &status); times[i] = oskar_timer_elapsed(timer); } // Free memory. oskar_mem_free(u, &status); oskar_mem_free(v, &status); oskar_mem_free(w, &status); oskar_mem_free(vis, &status); oskar_jones_free(J, &status); oskar_telescope_free(tel, &status); oskar_sky_free(sky, &status); oskar_timer_free(timer); return status; }
static void sim_baselines(oskar_Simulator* h, DeviceData* d, oskar_Sky* sky, int channel_index_block, int time_index_block, int time_index_simulation, int* status) { int num_baselines, num_stations, num_src, num_times_block, num_channels; double dt_dump_days, t_start, t_dump, gast, frequency, ra0, dec0; const oskar_Mem *x, *y, *z; oskar_Mem* alias = 0; /* Get dimensions. */ num_baselines = oskar_telescope_num_baselines(d->tel); num_stations = oskar_telescope_num_stations(d->tel); num_src = oskar_sky_num_sources(sky); num_times_block = oskar_vis_block_num_times(d->vis_block); num_channels = oskar_vis_block_num_channels(d->vis_block); /* Return if there are no sources in the chunk, * or if block time index requested is outside the valid range. */ if (num_src == 0 || time_index_block >= num_times_block) return; /* Get the time and frequency of the visibility slice being simulated. */ dt_dump_days = h->time_inc_sec / 86400.0; t_start = h->time_start_mjd_utc; t_dump = t_start + dt_dump_days * (time_index_simulation + 0.5); gast = oskar_convert_mjd_to_gast_fast(t_dump); frequency = h->freq_start_hz + channel_index_block * h->freq_inc_hz; /* Scale source fluxes with spectral index and rotation measure. */ oskar_sky_scale_flux_with_frequency(sky, frequency, status); /* Evaluate station u,v,w coordinates. */ ra0 = oskar_telescope_phase_centre_ra_rad(d->tel); dec0 = oskar_telescope_phase_centre_dec_rad(d->tel); x = oskar_telescope_station_true_x_offset_ecef_metres_const(d->tel); y = oskar_telescope_station_true_y_offset_ecef_metres_const(d->tel); z = oskar_telescope_station_true_z_offset_ecef_metres_const(d->tel); oskar_convert_ecef_to_station_uvw(num_stations, x, y, z, ra0, dec0, gast, d->u, d->v, d->w, status); /* Set dimensions of Jones matrices. */ if (d->R) oskar_jones_set_size(d->R, num_stations, num_src, status); if (d->Z) oskar_jones_set_size(d->Z, num_stations, num_src, status); oskar_jones_set_size(d->J, num_stations, num_src, status); oskar_jones_set_size(d->E, num_stations, num_src, status); oskar_jones_set_size(d->K, num_stations, num_src, status); /* Evaluate station beam (Jones E: may be matrix). */ oskar_timer_resume(d->tmr_E); oskar_evaluate_jones_E(d->E, num_src, OSKAR_RELATIVE_DIRECTIONS, oskar_sky_l(sky), oskar_sky_m(sky), oskar_sky_n(sky), d->tel, gast, frequency, d->station_work, time_index_simulation, status); oskar_timer_pause(d->tmr_E); #if 0 /* Evaluate ionospheric phase (Jones Z: scalar) and join with Jones E. * NOTE this is currently only a CPU implementation. */ if (d->Z) { oskar_evaluate_jones_Z(d->Z, num_src, sky, d->tel, &settings->ionosphere, gast, frequency, &(d->workJonesZ), status); oskar_timer_resume(d->tmr_join); oskar_jones_join(d->E, d->Z, d->E, status); oskar_timer_pause(d->tmr_join); } #endif /* Evaluate parallactic angle (Jones R: matrix), and join with Jones Z*E. * TODO Move this into station beam evaluation instead. */ if (d->R) { oskar_timer_resume(d->tmr_E); oskar_evaluate_jones_R(d->R, num_src, oskar_sky_ra_rad_const(sky), oskar_sky_dec_rad_const(sky), d->tel, gast, status); oskar_timer_pause(d->tmr_E); oskar_timer_resume(d->tmr_join); oskar_jones_join(d->R, d->E, d->R, status); oskar_timer_pause(d->tmr_join); } /* Evaluate interferometer phase (Jones K: scalar). */ oskar_timer_resume(d->tmr_K); oskar_evaluate_jones_K(d->K, num_src, oskar_sky_l_const(sky), oskar_sky_m_const(sky), oskar_sky_n_const(sky), d->u, d->v, d->w, frequency, oskar_sky_I_const(sky), h->source_min_jy, h->source_max_jy, status); oskar_timer_pause(d->tmr_K); /* Join Jones K with Jones Z*E. */ oskar_timer_resume(d->tmr_join); oskar_jones_join(d->J, d->K, d->R ? d->R : d->E, status); oskar_timer_pause(d->tmr_join); /* Create alias for auto/cross-correlations. */ oskar_timer_resume(d->tmr_correlate); alias = oskar_mem_create_alias(0, 0, 0, status); /* Auto-correlate for this time and channel. */ if (oskar_vis_block_has_auto_correlations(d->vis_block)) { oskar_mem_set_alias(alias, oskar_vis_block_auto_correlations(d->vis_block), num_stations * (num_channels * time_index_block + channel_index_block), num_stations, status); oskar_auto_correlate(alias, num_src, d->J, sky, status); } /* Cross-correlate for this time and channel. */ if (oskar_vis_block_has_cross_correlations(d->vis_block)) { oskar_mem_set_alias(alias, oskar_vis_block_cross_correlations(d->vis_block), num_baselines * (num_channels * time_index_block + channel_index_block), num_baselines, status); oskar_cross_correlate(alias, num_src, d->J, sky, d->tel, d->u, d->v, d->w, gast, frequency, status); } /* Free alias for auto/cross-correlations. */ oskar_mem_free(alias, status); oskar_timer_pause(d->tmr_correlate); }
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 }