void oskar_telescope_load_position(oskar_Telescope* telescope,
                                   const char* filename, int* status)
{
    int num_coords;
    oskar_Mem *lon, *lat, *alt;

    /* Load columns from file. */
    lon = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, status);
    lat = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, status);
    alt = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, status);
    num_coords = (int) oskar_mem_load_ascii(filename, 3, status,
                                            lon, "", lat, "", alt, "0.0");

    /* Set the telescope centre coordinates. */
    if (num_coords == 1)
    {
        telescope->lon_rad = (oskar_mem_double(lon, status))[0] * M_PI / 180.0;
        telescope->lat_rad = (oskar_mem_double(lat, status))[0] * M_PI / 180.0;
        telescope->alt_metres = (oskar_mem_double(alt, status))[0];
    }
    else
    {
        *status = OSKAR_ERR_BAD_COORD_FILE;
    }

    /* Free memory. */
    oskar_mem_free(lon, status);
    oskar_mem_free(lat, status);
    oskar_mem_free(alt, status);
}
Example #2
0
TEST(Mem, random_gaussian_accum)
{
    int status = 0;
    int seed = 1;
    int blocksize = 256;
    int rounds = 10240;
    oskar_Mem* block = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU,
            blocksize, &status);
    oskar_Mem* total = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU,
            blocksize * rounds, &status);

    for (int i = 0; i < rounds; ++i)
    {
        oskar_mem_random_gaussian(block, seed, i, 0, 0, 1.0, &status);
        oskar_mem_copy_contents(total, block,
                i * blocksize, 0, blocksize, &status);
    }
    ASSERT_EQ(0, status) << oskar_get_error_string(status);

    if (save)
    {
        FILE* fhan = fopen("random_gaussian_accum.txt", "w");
        oskar_mem_save_ascii(fhan, 1, blocksize * rounds, &status, total);
        fclose(fhan);
    }

    oskar_mem_free(block, &status);
    oskar_mem_free(total, &status);
}
Example #3
0
TEST(element_weights_errors, test_evaluate)
{
    int num_elements           = 10000;
    double element_gain        = 1.0;
    double element_gain_error  = 0.0;
    double element_phase       = 0.0 * M_PI;
    double element_phase_error = 0.0  * M_PI;
    int error = 0;
    unsigned int seed = 1;

    oskar_Mem *d_gain, *d_gain_error, *d_phase, *d_phase_error, *d_errors;
    d_gain = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU,
            num_elements, &error);
    d_gain_error = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU,
            num_elements, &error);
    d_phase = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU,
            num_elements, &error);
    d_phase_error = oskar_mem_create(OSKAR_DOUBLE, OSKAR_GPU,
            num_elements, &error);
    d_errors = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_GPU,
            num_elements, &error);
    ASSERT_EQ(0, error) << oskar_get_error_string(error);

    oskar_mem_set_value_real(d_gain, element_gain, 0, 0, &error);
    oskar_mem_set_value_real(d_gain_error, element_gain_error, 0, 0, &error);
    oskar_mem_set_value_real(d_phase, element_phase, 0, 0, &error);
    oskar_mem_set_value_real(d_phase_error, element_phase_error, 0, 0, &error);
    oskar_mem_set_value_real(d_errors, 0.0, 0, 0, &error);
    ASSERT_EQ(0, error) << oskar_get_error_string(error);

    // Evaluate weights errors.
    oskar_evaluate_element_weights_errors(num_elements,
            d_gain, d_gain_error, d_phase, d_phase_error,
            seed, 0, 0, d_errors, &error);
    ASSERT_EQ(0, error) << oskar_get_error_string(error);

    // Write memory to file for inspection.
    const char* fname = "temp_test_element_errors.dat";
    FILE* file = fopen(fname, "w");
    oskar_mem_save_ascii(file, 5, num_elements, &error,
            d_gain, d_gain_error, d_phase, d_phase_error, d_errors);
    fclose(file);
    remove(fname);

    // Free memory.
    oskar_mem_free(d_gain, &error);
    oskar_mem_free(d_gain_error, &error);
    oskar_mem_free(d_phase, &error);
    oskar_mem_free(d_phase_error, &error);
    oskar_mem_free(d_errors, &error);
    ASSERT_EQ(0, error) << oskar_get_error_string(error);
}
Example #4
0
oskar_Imager* oskar_imager_create(int imager_precision, int* status)
{
    oskar_Imager* h = 0;
    h = (oskar_Imager*) calloc(1, sizeof(oskar_Imager));

    /* Create timers. */
    h->tmr_grid_finalise = oskar_timer_create(OSKAR_TIMER_NATIVE);
    h->tmr_grid_update = oskar_timer_create(OSKAR_TIMER_NATIVE);
    h->tmr_init = oskar_timer_create(OSKAR_TIMER_NATIVE);
    h->tmr_read = oskar_timer_create(OSKAR_TIMER_NATIVE);
    h->tmr_write = oskar_timer_create(OSKAR_TIMER_NATIVE);
    h->mutex = oskar_mutex_create();

    /* Create scratch arrays. */
    h->imager_prec = imager_precision;
    h->uu_im       = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);
    h->vv_im       = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);
    h->ww_im       = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);
    h->uu_tmp      = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);
    h->vv_tmp      = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);
    h->ww_tmp      = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);
    h->vis_im      = oskar_mem_create(imager_precision | OSKAR_COMPLEX,
            OSKAR_CPU, 0, status);
    h->weight_im   = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);
    h->weight_tmp  = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);
    h->time_im     = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, status);

    /* Check data type. */
    if (imager_precision != OSKAR_SINGLE && imager_precision != OSKAR_DOUBLE)
    {
        *status = OSKAR_ERR_BAD_DATA_TYPE;
        return h;
    }

    /* Get number of devices available, and device location. */
    oskar_device_set_require_double_precision(imager_precision == OSKAR_DOUBLE);
    h->num_gpus_avail = oskar_device_count(0, &h->dev_loc);

    /* Set sensible defaults. */
    oskar_imager_set_gpus(h, -1, 0, status);
    oskar_imager_set_num_devices(h, -1);
    oskar_imager_set_algorithm(h, "FFT", status);
    oskar_imager_set_image_type(h, "I", status);
    oskar_imager_set_weighting(h, "Natural", status);
    oskar_imager_set_ms_column(h, "DATA", status);
    oskar_imager_set_default_direction(h);
    oskar_imager_set_generate_w_kernels_on_gpu(h, 1);
    oskar_imager_set_fov(h, 1.0);
    oskar_imager_set_size(h, 256, status);
    oskar_imager_set_uv_filter_max(h, DBL_MAX);
    return h;
}
Example #5
0
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;
}
Example #6
0
void oskar_imager_init_dft(oskar_Imager* h, int* status)
{
    int num_pixels;
    oskar_imager_free_dft(h, status);
    if (*status) return;

    /* Calculate pixel coordinate grid required for the DFT imager. */
    num_pixels = h->image_size * h->image_size;
    h->l = oskar_mem_create(h->imager_prec, OSKAR_CPU, num_pixels, status);
    h->m = oskar_mem_create(h->imager_prec, OSKAR_CPU, num_pixels, status);
    h->n = oskar_mem_create(h->imager_prec, OSKAR_CPU, num_pixels, status);
    oskar_evaluate_image_lmn_grid(h->image_size, h->image_size,
            h->fov_deg * M_PI/180, h->fov_deg * M_PI/180, 0,
            h->l, h->m, h->n, status);
    oskar_mem_add_real(h->n, -1.0, status); /* n-1 */
}
Example #7
0
TEST(Mem, stats)
{
    int status = 0;
    oskar_Mem* values;
    values = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 5, &status);

    // Fill an array with the values 1, 2, 3, 4, 5.
    double *v = oskar_mem_double(values, &status);
    v[0] = 1.0;
    v[1] = 2.0;
    v[2] = 3.0;
    v[3] = 4.0;
    v[4] = 5.0;

    // Compute minimum, maximum, mean and population standard deviation.
    double min, max, mean, std_dev;
    oskar_mem_stats(values, oskar_mem_length(values), &min, &max, &mean,
                    &std_dev, &status);

    // Check values are correct.
    ASSERT_DOUBLE_EQ(3.0, mean);
    ASSERT_DOUBLE_EQ(1.0, min);
    ASSERT_DOUBLE_EQ(5.0, max);
    ASSERT_DOUBLE_EQ(sqrt(2.0), std_dev);

    // Free memory.
    oskar_mem_free(values, &status);
}
void oskar_telescope_set_noise_freq(oskar_Telescope* model,
        double start_hz, double inc_hz, int num_channels, int* status)
{
    int i;
    oskar_Mem* noise_freq_hz;
    noise_freq_hz = oskar_mem_create(model->precision, OSKAR_CPU,
            num_channels, status);
    if (*status) return;
    if (model->precision == OSKAR_DOUBLE)
    {
        double* f = oskar_mem_double(noise_freq_hz, status);
        for (i = 0; i < num_channels; ++i) f[i] = start_hz + i * inc_hz;
    }
    else
    {
        float* f = oskar_mem_float(noise_freq_hz, status);
        for (i = 0; i < num_channels; ++i) f[i] = start_hz + i * inc_hz;
    }

    /* Set noise frequency for all top-level stations. */
    for (i = 0; i < model->num_stations; ++i)
    {
        oskar_Mem* t;
        t = oskar_station_noise_freq_hz(model->station[i]);
        oskar_mem_realloc(t, num_channels, status);
        oskar_mem_copy(t, noise_freq_hz, status);
    }
    oskar_mem_free(noise_freq_hz, status);
}
Example #9
0
TEST(Mem, set_value_real_double_complex_matrix)
{
    // Double precision complex matrix.
    int n = 100, status = 0;
    oskar_Mem *mem, *mem2;
    mem = oskar_mem_create(OSKAR_DOUBLE_COMPLEX_MATRIX, 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);
    double4c* v = oskar_mem_double4c(mem2, &status);
    ASSERT_EQ(0, status) << oskar_get_error_string(status);
    for (int i = 0; i < n; ++i)
    {
        EXPECT_DOUBLE_EQ(v[i].a.x, 6.5);
        EXPECT_DOUBLE_EQ(v[i].a.y, 0.0);
        EXPECT_DOUBLE_EQ(v[i].b.x, 0.0);
        EXPECT_DOUBLE_EQ(v[i].b.y, 0.0);
        EXPECT_DOUBLE_EQ(v[i].c.x, 0.0);
        EXPECT_DOUBLE_EQ(v[i].c.y, 0.0);
        EXPECT_DOUBLE_EQ(v[i].d.x, 6.5);
        EXPECT_DOUBLE_EQ(v[i].d.y, 0.0);
    }
    oskar_mem_free(mem, &status);
    oskar_mem_free(mem2, &status);
}
Example #10
0
    void createTestData(int precision, int location, int matrix)
    {
        int status = 0, type;

        // Allocate memory for data structures.
        type = precision | OSKAR_COMPLEX;
        if (matrix) type |= OSKAR_MATRIX;
        jones = oskar_jones_create(type, location, num_stations, num_sources,
                &status);
        u_ = oskar_mem_create(precision, location, num_stations, &status);
        v_ = oskar_mem_create(precision, location, num_stations, &status);
        w_ = oskar_mem_create(precision, location, num_stations, &status);
        sky = oskar_sky_create(precision, location, num_sources, &status);
        tel = oskar_telescope_create(precision, location,
                num_stations, &status);
        ASSERT_EQ(0, status) << oskar_get_error_string(status);

        // Fill data structures with random data in sensible ranges.
        srand(2);
        oskar_mem_random_range(oskar_jones_mem(jones), 1.0, 5.0, &status);
        oskar_mem_random_range(u_, 1.0, 5.0, &status);
        oskar_mem_random_range(v_, 1.0, 5.0, &status);
        oskar_mem_random_range(w_, 1.0, 5.0, &status);
        oskar_mem_random_range(
                oskar_telescope_station_true_x_offset_ecef_metres(tel),
                0.1, 1000.0, &status);
        oskar_mem_random_range(
                oskar_telescope_station_true_y_offset_ecef_metres(tel),
                0.1, 1000.0, &status);
        oskar_mem_random_range(
                oskar_telescope_station_true_z_offset_ecef_metres(tel),
                0.1, 1000.0, &status);
        oskar_mem_random_range(oskar_sky_I(sky), 1.0, 2.0, &status);
        oskar_mem_random_range(oskar_sky_Q(sky), 0.1, 1.0, &status);
        oskar_mem_random_range(oskar_sky_U(sky), 0.1, 0.5, &status);
        oskar_mem_random_range(oskar_sky_V(sky), 0.1, 0.2, &status);
        oskar_mem_random_range(oskar_sky_l(sky), 0.1, 0.9, &status);
        oskar_mem_random_range(oskar_sky_m(sky), 0.1, 0.9, &status);
        oskar_mem_random_range(oskar_sky_n(sky), 0.1, 0.9, &status);
        oskar_mem_random_range(oskar_sky_gaussian_a(sky), 0.1e-6, 0.2e-6,
                &status);
        oskar_mem_random_range(oskar_sky_gaussian_b(sky), 0.1e-6, 0.2e-6,
                &status);
        oskar_mem_random_range(oskar_sky_gaussian_c(sky), 0.1e-6, 0.2e-6,
                &status);
        ASSERT_EQ(0, status) << oskar_get_error_string(status);
    }
oskar_Mem* oskar_mem_read_binary_raw(const char* filename, int type,
        int location, int* status)
{
    size_t num_elements, element_size, size_bytes;
    oskar_Mem *mem = 0;
    FILE* stream;

    /* Check if safe to proceed. */
    if (*status) return 0;

    /* Open the input file. */
    stream = fopen(filename, "rb");
    if (!stream)
    {
        *status = OSKAR_ERR_FILE_IO;
        return 0;
    }

    /* Get the file size. */
    fseek(stream, 0, SEEK_END);
    size_bytes = ftell(stream);

    /* Create memory block of the right size. */
    element_size = oskar_mem_element_size(type);
    num_elements = (size_t)ceil(size_bytes / element_size);
    mem = oskar_mem_create(type, OSKAR_CPU, num_elements, status);
    if (*status)
    {
        oskar_mem_free(mem, status);
        fclose(stream);
        return 0;
    }

    /* Read the data. */
    fseek(stream, 0, SEEK_SET);
    if (fread(oskar_mem_void(mem), 1, size_bytes, stream) != size_bytes)
    {
        oskar_mem_free(mem, status);
        fclose(stream);
        *status = OSKAR_ERR_FILE_IO;
        return 0;
    }

    /* Close the input file. */
    fclose(stream);

    /* Copy to GPU memory if required. */
    if (location != OSKAR_CPU)
    {
        oskar_Mem* gpu;
        gpu = oskar_mem_create_copy(mem, location, status);
        oskar_mem_free(mem, status);
        return gpu;
    }

    return mem;
}
Example #12
0
oskar_Imager* oskar_imager_create(int imager_precision, int* status)
{
    oskar_Imager* h = 0;
    h = (oskar_Imager*) calloc(1, sizeof(oskar_Imager));

    /* Create scratch arrays. */
    h->imager_prec = imager_precision;
    h->uu_im       = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);
    h->vv_im       = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);
    h->ww_im       = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);
    h->uu_tmp      = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);
    h->vv_tmp      = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);
    h->ww_tmp      = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);
    h->vis_im      = oskar_mem_create(imager_precision | OSKAR_COMPLEX,
            OSKAR_CPU, 0, status);
    h->weight_im   = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);
    h->weight_tmp  = oskar_mem_create(imager_precision, OSKAR_CPU, 0, status);

    /* Check data type. */
    if (imager_precision != OSKAR_SINGLE && imager_precision != OSKAR_DOUBLE)
    {
        *status = OSKAR_ERR_BAD_DATA_TYPE;
        return h;
    }

    /* Set sensible defaults. */
    oskar_imager_set_gpus(h, -1, 0, status);
    oskar_imager_set_fft_on_gpu(h, 0);
    oskar_imager_set_generate_w_kernels_on_gpu(h, 1);
    oskar_imager_set_fov(h, 1.0);
    oskar_imager_set_size(h, 256, status);
    oskar_imager_set_channel_start(h, 0);
    oskar_imager_set_channel_end(h, -1);
    oskar_imager_set_channel_snapshots(h, 1);
    oskar_imager_set_time_start(h, 0);
    oskar_imager_set_time_end(h, -1);
    oskar_imager_set_time_snapshots(h, 0);
    oskar_imager_set_uv_filter_max(h, -1.0);
    oskar_imager_set_image_type(h, "I", status);
    oskar_imager_set_algorithm(h, "FFT", status);
    oskar_imager_set_weighting(h, "Natural", status);
    oskar_imager_set_ms_column(h, "DATA", status);
    oskar_imager_set_default_direction(h);
    return h;
}
void oskar_telescope_load_station_coords_wgs84(oskar_Telescope* telescope,
        const char* filename, double longitude, double latitude,
        double altitude, int* status)
{
    int num_stations;
    oskar_Mem *lon_deg, *lat_deg, *alt_m;

    /* Load columns from file into memory. */
    lon_deg = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, status);
    lat_deg = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, status);
    alt_m   = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, status);
    num_stations = (int) oskar_mem_load_ascii(filename, 3, status,
            lon_deg, "", lat_deg, "", alt_m, "0.0");

    /* Set the station coordinates. */
    oskar_telescope_set_station_coords_wgs84(telescope, longitude, latitude,
            altitude, num_stations, lon_deg, lat_deg, alt_m, status);

    /* Free memory. */
    oskar_mem_free(lon_deg, status);
    oskar_mem_free(lat_deg, status);
    oskar_mem_free(alt_m, status);
}
Example #14
0
TEST(Mem, type_check_single)
{
    int status = 0;
    oskar_Mem *mem;
    mem = oskar_mem_create(OSKAR_SINGLE, OSKAR_CPU, 0, &status);
    ASSERT_EQ(0, status) << oskar_get_error_string(status);
    EXPECT_EQ((int)OSKAR_FALSE, oskar_mem_is_double(mem));
    EXPECT_EQ((int)OSKAR_FALSE, oskar_mem_is_complex(mem));
    EXPECT_EQ((int)OSKAR_TRUE, oskar_mem_is_scalar(mem));
    EXPECT_EQ((int)OSKAR_FALSE, oskar_type_is_double(OSKAR_SINGLE));
    EXPECT_EQ((int)OSKAR_FALSE, oskar_type_is_complex(OSKAR_SINGLE));
    EXPECT_EQ((int)OSKAR_TRUE, oskar_type_is_scalar(OSKAR_SINGLE));
    oskar_mem_free(mem, &status);
    ASSERT_EQ(0, status) << oskar_get_error_string(status);
}
Example #15
0
TEST(Mem, type_check_double_complex)
{
    int status = 0;
    oskar_Mem *mem;
    mem = oskar_mem_create(OSKAR_DOUBLE_COMPLEX, OSKAR_CPU, 0,
            &status);
    EXPECT_EQ((int)OSKAR_TRUE, oskar_mem_is_double(mem));
    EXPECT_EQ((int)OSKAR_TRUE, oskar_mem_is_complex(mem));
    EXPECT_EQ((int)OSKAR_TRUE, oskar_mem_is_scalar(mem));
    EXPECT_EQ((int)OSKAR_TRUE, oskar_type_is_double(OSKAR_DOUBLE_COMPLEX));
    EXPECT_EQ((int)OSKAR_TRUE, oskar_type_is_complex(OSKAR_DOUBLE_COMPLEX));
    EXPECT_EQ((int)OSKAR_TRUE, oskar_type_is_scalar(OSKAR_DOUBLE_COMPLEX));
    oskar_mem_free(mem, &status);
    ASSERT_EQ(0, status) << oskar_get_error_string(status);
}
Example #16
0
int main(int argc, char** argv)
{
    int status = 0;
    oskar::OptionParser opt("oskar_convert_geodetic_to_ecef",
            oskar_version_string());
    opt.set_description("Converts geodetic longitude/latitude/altitude to "
            "Cartesian ECEF coordinates. Assumes WGS84 ellipsoid.");
    opt.add_required("input file", "Path to file containing input coordinates. "
            "Angles must be in degrees.");
    if (!opt.check_options(argc, argv))
        return OSKAR_FAIL;
    const char* filename = opt.get_arg();

    // Load the input file.
    oskar_Mem *lon = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
    oskar_Mem *lat = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
    oskar_Mem *alt = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, 0, &status);
    size_t num_points = oskar_mem_load_ascii(filename, 3, &status,
            lon, "", lat, "", alt, "0.0");
    oskar_mem_scale_real(lon, M_PI / 180.0, &status);
    oskar_mem_scale_real(lat, M_PI / 180.0, &status);

    // Convert coordinates.
    oskar_Mem *x = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU,
            num_points, &status);
    oskar_Mem *y = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU,
            num_points, &status);
    oskar_Mem *z = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU,
            num_points, &status);
    oskar_convert_geodetic_spherical_to_ecef(num_points,
            oskar_mem_double_const(lon, &status),
            oskar_mem_double_const(lat, &status),
            oskar_mem_double_const(alt, &status),
            oskar_mem_double(x, &status),
            oskar_mem_double(y, &status),
            oskar_mem_double(z, &status));

    // Print converted coordinates.
    oskar_mem_save_ascii(stdout, 3, num_points, &status, x, y, z);

    // Clean up.
    oskar_mem_free(lon, &status);
    oskar_mem_free(lat, &status);
    oskar_mem_free(alt, &status);
    oskar_mem_free(x, &status);
    oskar_mem_free(y, &status);
    oskar_mem_free(z, &status);
    if (status)
    {
        oskar_log_error(0, oskar_get_error_string(status));
        return status;
    }

    return 0;
}
Example #17
0
TEST(Mem, set_value_real_double)
{
    // Double precision real.
    int n = 100, status = 0;
    oskar_Mem *mem;
    mem = oskar_mem_create(OSKAR_DOUBLE, OSKAR_CPU, n, &status);
    oskar_mem_set_value_real(mem, 4.5, 0, 0, &status);
    double* v = oskar_mem_double(mem, &status);
    ASSERT_EQ(0, status) << oskar_get_error_string(status);

    for (int i = 0; i < n; ++i)
    {
        EXPECT_DOUBLE_EQ(v[i], 4.5);
    }
    oskar_mem_free(mem, &status);
}
Example #18
0
TEST(Mem, set_value_real_single)
{
    // Single precision real.
    int n = 100, status = 0;
    oskar_Mem *mem;
    mem = oskar_mem_create(OSKAR_SINGLE, OSKAR_CPU, n, &status);
    oskar_mem_set_value_real(mem, 4.5, 0, 0, &status);
    float* v = oskar_mem_float(mem, &status);
    ASSERT_EQ(0, status) << oskar_get_error_string(status);

    for (int i = 0; i < n; ++i)
    {
        EXPECT_FLOAT_EQ(v[i], 4.5);
    }
    oskar_mem_free(mem, &status);
}
Example #19
0
oskar_Mem* oskar_mem_create_copy_from_raw(void* ptr, int type, int location,
        size_t num_elements, int* status)
{
    oskar_Mem *m = 0, *t = 0;
    if (*status) return 0;

    /* Create the handles. */
    m = oskar_mem_create(type, location, num_elements, status);
    t = oskar_mem_create_alias_from_raw(ptr, type, location, num_elements,
            status);
    oskar_mem_copy(m, t, status);
    oskar_mem_free(t, status);

    /* Return a handle the structure .*/
    return m;
}
    void createTestData(int precision, int location, int matrix)
    {
        int status = 0, type;

        // Allocate memory for data structures.
        type = precision | OSKAR_COMPLEX;
        if (matrix) type |= OSKAR_MATRIX;
        jones = oskar_mem_create(type, location, num_stations * num_sources,
                &status);
        ASSERT_EQ(0, status) << oskar_get_error_string(status);

        // Fill data structures with random data in sensible ranges.
        srand(0);
        oskar_mem_random_range(jones, 1.0, 10.0, &status);
        ASSERT_EQ(0, status) << oskar_get_error_string(status);
    }
Example #21
0
oskar_WorkJonesZ* oskar_work_jones_z_create(int type, int location, int* status)
{
    oskar_WorkJonesZ* work = 0;

    /* Check the base type is correct */
    if (!(type == OSKAR_SINGLE || type == OSKAR_DOUBLE))
        *status = OSKAR_ERR_BAD_DATA_TYPE;

    work = (oskar_WorkJonesZ*) malloc(sizeof(oskar_WorkJonesZ));

    work->hor_x = oskar_mem_create(type, location, 0, status);
    work->hor_y = oskar_mem_create(type, location, 0, status);
    work->hor_z = oskar_mem_create(type, location, 0, status);
    work->pp_lon = oskar_mem_create(type, location, 0, status);
    work->pp_lat = oskar_mem_create(type, location, 0, status);
    work->pp_rel_path = oskar_mem_create(type, location, 0, status);
    work->screen_TEC = oskar_mem_create(type, location, 0, status);
    work->total_TEC = oskar_mem_create(type, location, 0, status);

    return work;
}
Example #22
0
oskar_Simulator* oskar_simulator_create(int precision, int* status)
{
    oskar_Simulator* h = 0;
    h = (oskar_Simulator*) calloc(1, sizeof(oskar_Simulator));
    h->prec      = precision;
    h->tmr_sim   = oskar_timer_create(OSKAR_TIMER_NATIVE);
    h->tmr_write = oskar_timer_create(OSKAR_TIMER_NATIVE);
    h->temp      = oskar_mem_create(precision, OSKAR_CPU, 0, status);
    h->mutex     = oskar_mutex_create();

    /* Set sensible defaults. */
    h->max_sources_per_chunk = 16384;
    oskar_simulator_set_gpus(h, -1, 0, status);
    oskar_simulator_set_num_devices(h, -1);
    oskar_simulator_set_correlation_type(h, "Cross-correlations", status);
    oskar_simulator_set_horizon_clip(h, 1);
    oskar_simulator_set_source_flux_range(h, 0.0, DBL_MAX);
    oskar_simulator_set_max_times_per_block(h, 10);
    return h;
}
Example #23
0
oskar_Mem* oskar_mem_create_copy(const oskar_Mem* src, int location,
        int* status)
{
    oskar_Mem* mem = 0;

    /* Check if safe to proceed. */
    if (*status) return 0;

    /* Create the new structure. */
    mem = oskar_mem_create(oskar_mem_type(src), location,
            oskar_mem_length(src), status);
    if (!mem || *status)
        return mem;

    /* Copy the memory. */
    oskar_mem_copy_contents(mem, src, 0, 0, oskar_mem_length(src), status);

    /* Return a handle to the new structure. */
    return mem;
}
Example #24
0
TEST(Mem, set_value_real_single_complex)
{
    // Single precision complex.
    int n = 100, status = 0;
    oskar_Mem *mem, *mem2;
    mem = oskar_mem_create(OSKAR_SINGLE_COMPLEX, OSKAR_GPU, n,
            &status);
    oskar_mem_set_value_real(mem, 6.5, 0, 0, &status);
    ASSERT_EQ(0, status) << oskar_get_error_string(status);

    mem2 = oskar_mem_create_copy(mem, OSKAR_CPU, &status);
    float2* v = oskar_mem_float2(mem2, &status);
    ASSERT_EQ(0, status) << oskar_get_error_string(status);
    for (int i = 0; i < n; ++i)
    {
        EXPECT_FLOAT_EQ(v[i].x, 6.5);
        EXPECT_FLOAT_EQ(v[i].y, 0.0);
    }
    oskar_mem_free(mem, &status);
    oskar_mem_free(mem2, &status);
}
Example #25
0
void oskar_binary_read_mem_ext(oskar_Binary* handle, oskar_Mem* mem,
        const char* name_group, const char* name_tag, int user_index,
        int* status)
{
    int type;
    oskar_Mem *temp = 0, *data = 0;
    size_t size_bytes = 0, element_size = 0;

    /* Check if safe to proceed. */
    if (*status) return;

    /* Get the data type. */
    type = oskar_mem_type(mem);

    /* Initialise temporary (to zero length). */
    temp = oskar_mem_create(type, OSKAR_CPU, 0, status);

    /* Check if data is in CPU or GPU memory. */
    data = (oskar_mem_location(mem) == OSKAR_CPU) ? mem : temp;

    /* Query the tag index to find out how big the block is. */
    element_size = oskar_mem_element_size(type);
    oskar_binary_query_ext(handle, (unsigned char)type,
            name_group, name_tag, user_index, &size_bytes, status);

    /* Resize memory block if necessary, so that it can hold the data. */
    oskar_mem_realloc(data, size_bytes / element_size, status);

    /* Load the memory. */
    oskar_binary_read_ext(handle, (unsigned char)type, name_group, name_tag,
            user_index, size_bytes, oskar_mem_void(data), status);

    /* Copy to GPU memory if required. */
    if (oskar_mem_location(mem) != OSKAR_CPU)
        oskar_mem_copy(mem, temp, status);

    /* Free the temporary. */
    oskar_mem_free(temp, status);
}
void oskar_telescope_set_noise_rms(oskar_Telescope* model,
        double start, double end, int* status)
{
    int i, j, num_channels;
    double inc;
    oskar_Station* s;
    oskar_Mem *noise_rms_jy, *h;

    /* Set noise RMS for all top-level stations. */
    if (*status) return;
    for (i = 0; i < model->num_stations; ++i)
    {
        s = model->station[i];
        h = oskar_station_noise_rms_jy(s);
        num_channels = (int)oskar_mem_length(oskar_station_noise_freq_hz(s));
        if (num_channels == 0)
        {
            *status = OSKAR_ERR_OUT_OF_RANGE;
            return;
        }
        oskar_mem_realloc(h, num_channels, status);
        noise_rms_jy = oskar_mem_create(model->precision, OSKAR_CPU,
                num_channels, status);
        inc = (end - start) / (double)num_channels;
        if (model->precision == OSKAR_DOUBLE)
        {
            double* r = oskar_mem_double(noise_rms_jy, status);
            for (j = 0; j < num_channels; ++j) r[j] = start + j * inc;
        }
        else
        {
            float* r = oskar_mem_float(noise_rms_jy, status);
            for (j = 0; j < num_channels; ++j) r[j] = start + j * inc;
        }
        oskar_mem_copy(h, noise_rms_jy, status);
        oskar_mem_free(noise_rms_jy, status);
    }
}
static void set_up_host_data(oskar_BeamPattern* h, int *status)
{
    int i, k;
    size_t j;
    if (*status) return;

    /* Set up pixel positions. */
    oskar_beam_pattern_generate_coordinates(h,
            OSKAR_SPHERICAL_TYPE_EQUATORIAL, status);

    /* Work out how many pixel chunks have to be processed. */
    h->num_chunks = (h->num_pixels + h->max_chunk_size - 1) / h->max_chunk_size;

    /* Create scratch arrays for output pixel data. */
    if (!h->pix)
    {
        h->pix = oskar_mem_create(h->prec, OSKAR_CPU,
                h->max_chunk_size, status);
        h->ctemp = oskar_mem_create(h->prec | OSKAR_COMPLEX, OSKAR_CPU,
                h->max_chunk_size, status);
    }

    /* Get the contents of the log at this point so we can write a
     * reasonable file header. Replace newlines with zeros. */
    h->settings_log_length = 0;
    free(h->settings_log);
    h->settings_log = oskar_log_file_data(h->log, &h->settings_log_length);
    for (j = 0; j < h->settings_log_length; ++j)
    {
        if (h->settings_log[j] == '\n') h->settings_log[j] = 0;
        if (h->settings_log[j] == '\r') h->settings_log[j] = ' ';
    }

    /* Return if data products already exist. */
    if (h->data_products) return;

    /* Create a file for each requested data product. */
    /* Voltage amplitude and phase can only be generated if there is
     * no averaging. */
    if (h->separate_time_and_channel)
    {
        /* Create station-level data products. */
        for (i = 0; i < h->num_active_stations; ++i)
        {
            /* Text file. */
            if (h->voltage_raw_txt)
                new_text_file(h, RAW_COMPLEX, -1, -1, i, 0, 0, status);
            if (h->voltage_amp_txt)
            {
                if (h->pol_mode == OSKAR_POL_MODE_SCALAR)
                    new_text_file(h, AMP, -1, -1, i, 0, 0, status);
                else for (k = XX; k <= YY; ++k)
                    new_text_file(h, AMP, -1, k, i, 0, 0, status);
            }
            if (h->voltage_phase_txt)
            {
                if (h->pol_mode == OSKAR_POL_MODE_SCALAR)
                    new_text_file(h, PHASE, -1, -1, i, 0, 0, status);
                else for (k = XX; k <= YY; ++k)
                    new_text_file(h, PHASE, -1, k, i, 0, 0, status);
            }
            if (h->ixr_txt && h->pol_mode == OSKAR_POL_MODE_FULL)
                new_text_file(h, IXR, -1, -1, i, 0, 0, status);

            /* Can only create images if coordinates are on a grid. */
            if (h->coord_grid_type != 'B') continue;

            /* FITS file. */
            if (h->voltage_amp_fits)
            {
                if (h->pol_mode == OSKAR_POL_MODE_SCALAR)
                    new_fits_file(h, AMP, -1, -1, i, 0, 0, status);
                else for (k = XX; k <= YY; ++k)
                    new_fits_file(h, AMP, -1, k, i, 0, 0, status);
            }
            if (h->voltage_phase_fits)
            {
                if (h->pol_mode == OSKAR_POL_MODE_SCALAR)
                    new_fits_file(h, PHASE, -1, -1, i, 0, 0, status);
                else for (k = XX; k <= YY; ++k)
                    new_fits_file(h, PHASE, -1, k, i, 0, 0, status);
            }
            if (h->ixr_fits && h->pol_mode == OSKAR_POL_MODE_FULL)
                new_fits_file(h, IXR, -1, -1, i, 0, 0, status);
        }
    }

    /* Create data products that can be averaged. */
    if (h->separate_time_and_channel)
        create_averaged_products(h, 0, 0, status);
    if (h->average_time_and_channel)
        create_averaged_products(h, 1, 1, status);
    if (h->average_single_axis == 'C')
        create_averaged_products(h, 0, 1, status);
    else if (h->average_single_axis == 'T')
        create_averaged_products(h, 1, 0, status);

    /* Check that at least one output file will be generated. */
    if (h->num_data_products == 0 && !*status)
    {
        *status = OSKAR_ERR_FILE_IO;
        oskar_log_error(h->log, "No output file(s) selected.");
    }
}
Example #28
0
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;
}
static void set_up_device_data(oskar_BeamPattern* h, int* status)
{
    int i, beam_type, max_src, max_size, auto_power, cross_power, raw_data;
    if (*status) return;

    /* Get local variables. */
    max_src = h->max_chunk_size;
    max_size = h->num_active_stations * max_src;
    beam_type = h->prec | OSKAR_COMPLEX;
    if (h->pol_mode == OSKAR_POL_MODE_FULL)
        beam_type |= OSKAR_MATRIX;
    raw_data = h->ixr_txt || h->ixr_fits ||
            h->voltage_raw_txt || h->voltage_amp_txt || h->voltage_phase_txt ||
            h->voltage_amp_fits || h->voltage_phase_fits;
    auto_power = h->auto_power_fits || h->auto_power_txt;
    cross_power = h->cross_power_raw_txt ||
            h->cross_power_amp_fits || h->cross_power_phase_fits ||
            h->cross_power_amp_txt || h->cross_power_phase_txt;

    /* Expand the number of devices to the number of selected GPUs,
     * if required. */
    if (h->num_devices < h->num_gpus)
        oskar_beam_pattern_set_num_devices(h, h->num_gpus);

    for (i = 0; i < h->num_devices; ++i)
    {
        int dev_loc, i_stokes;
        DeviceData* d = &h->d[i];
        if (*status) break;

        /* 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;
        }

        /* Device memory. */
        d->previous_chunk_index = -1;
        if (!d->tel)
        {
            d->jones_data = oskar_mem_create(beam_type, dev_loc, max_size,
                    status);
            d->x    = oskar_mem_create(h->prec, dev_loc, 1 + max_src, status);
            d->y    = oskar_mem_create(h->prec, dev_loc, 1 + max_src, status);
            d->z    = oskar_mem_create(h->prec, dev_loc, 1 + max_src, status);
            d->tel  = oskar_telescope_create_copy(h->tel, dev_loc, status);
            d->work = oskar_station_work_create(h->prec, dev_loc, status);
        }

        /* Host memory. */
        if (!d->jones_data_cpu[0] && raw_data)
        {
            d->jones_data_cpu[0] = oskar_mem_create(beam_type, OSKAR_CPU,
                    max_size, status);
            d->jones_data_cpu[1] = oskar_mem_create(beam_type, OSKAR_CPU,
                    max_size, status);
        }

        /* Auto-correlation beam output arrays. */
        for (i_stokes = 0; i_stokes < 4; ++i_stokes)
        {
            if (!h->stokes[i_stokes]) continue;

            if (!d->auto_power[i_stokes] && auto_power)
            {
                /* Device memory. */
                d->auto_power[i_stokes] = oskar_mem_create(beam_type, dev_loc,
                        max_size, status);

                /* Host memory. */
                d->auto_power_cpu[i_stokes][0] = oskar_mem_create(
                        beam_type, OSKAR_CPU, max_size, status);
                d->auto_power_cpu[i_stokes][1] = oskar_mem_create(
                        beam_type, OSKAR_CPU, max_size, status);
                if (h->average_single_axis == 'T')
                    d->auto_power_time_avg[i_stokes] = oskar_mem_create(
                            beam_type, OSKAR_CPU, max_size, status);
                if (h->average_single_axis == 'C')
                    d->auto_power_channel_avg[i_stokes] = oskar_mem_create(
                            beam_type, OSKAR_CPU, max_size, status);
                if (h->average_time_and_channel)
                    d->auto_power_channel_and_time_avg[i_stokes] =
                            oskar_mem_create(beam_type, OSKAR_CPU,
                                    max_size, status);
            }

            /* Cross-correlation beam output arrays. */
            if (!d->cross_power[i_stokes] && cross_power)
            {
                if (h->num_active_stations < 2)
                {
                    oskar_log_error(h->log, "Cannot create cross-power beam "
                            "using less than two active stations.");
                    *status = OSKAR_ERR_INVALID_ARGUMENT;
                    break;
                }

                /* Device memory. */
                d->cross_power[i_stokes] = oskar_mem_create(
                        beam_type, dev_loc, max_src, status);

                /* Host memory. */
                d->cross_power_cpu[i_stokes][0] = oskar_mem_create(

                        beam_type, OSKAR_CPU, max_src, status);
                d->cross_power_cpu[i_stokes][1] = oskar_mem_create(
                        beam_type, OSKAR_CPU, max_src, status);
                if (h->average_single_axis == 'T')
                    d->cross_power_time_avg[i_stokes] = oskar_mem_create(
                            beam_type, OSKAR_CPU, max_src, status);
                if (h->average_single_axis == 'C')
                    d->cross_power_channel_avg[i_stokes] = oskar_mem_create(
                            beam_type, OSKAR_CPU, max_src, status);
                if (h->average_time_and_channel)
                    d->cross_power_channel_and_time_avg[i_stokes] =
                            oskar_mem_create(beam_type, OSKAR_CPU,
                                    max_src, status);
            }
            if (d->auto_power[i_stokes])
                oskar_mem_clear_contents(d->auto_power[i_stokes], status);
            if (d->cross_power[i_stokes])
                oskar_mem_clear_contents(d->cross_power[i_stokes], status);
        }

        /* Timers. */
        if (!d->tmr_compute)
            d->tmr_compute = oskar_timer_create(OSKAR_TIMER_NATIVE);
    }
}
Example #30
0
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);
        }
    }
}