Exemplo n.º 1
0
oskar_VisBlock* oskar_simulator_finalise_block(oskar_Simulator* h,
        int block_index, int* status)
{
    int i, i_active;
    oskar_VisBlock *b0 = 0, *b = 0;
    if (*status) return 0;

    /* The visibilities must be copied back
     * at the end of the block simulation. */

    /* Combine all vis blocks into the first one. */
    i_active = (block_index + 1) % 2;
    b0 = h->d[0].vis_block_cpu[!i_active];
    if (!h->coords_only)
    {
        oskar_Mem *xc0 = 0, *ac0 = 0;
        xc0 = oskar_vis_block_cross_correlations(b0);
        ac0 = oskar_vis_block_auto_correlations(b0);
        for (i = 1; i < h->num_devices; ++i)
        {
            b = h->d[i].vis_block_cpu[!i_active];
            if (oskar_vis_block_has_cross_correlations(b))
                oskar_mem_add(xc0, xc0, oskar_vis_block_cross_correlations(b),
                        oskar_mem_length(xc0), status);
            if (oskar_vis_block_has_auto_correlations(b))
                oskar_mem_add(ac0, ac0, oskar_vis_block_auto_correlations(b),
                        oskar_mem_length(ac0), status);
        }
    }

    /* Calculate baseline uvw coordinates for the block. */
    if (oskar_vis_block_has_cross_correlations(b0))
    {
        const oskar_Mem *x, *y, *z;
        x = oskar_telescope_station_measured_x_offset_ecef_metres_const(h->tel);
        y = oskar_telescope_station_measured_y_offset_ecef_metres_const(h->tel);
        z = oskar_telescope_station_measured_z_offset_ecef_metres_const(h->tel);
        oskar_convert_ecef_to_baseline_uvw(
                oskar_telescope_num_stations(h->tel), x, y, z,
                oskar_telescope_phase_centre_ra_rad(h->tel),
                oskar_telescope_phase_centre_dec_rad(h->tel),
                oskar_vis_block_num_times(b0),
                oskar_vis_header_time_start_mjd_utc(h->header),
                oskar_vis_header_time_inc_sec(h->header) / 86400.0,
                oskar_vis_block_start_time_index(b0),
                oskar_vis_block_baseline_uu_metres(b0),
                oskar_vis_block_baseline_vv_metres(b0),
                oskar_vis_block_baseline_ww_metres(b0), h->temp, status);
    }

    /* Add uncorrelated system noise to the combined visibilities. */
    if (!h->coords_only)
    {
        oskar_vis_block_add_system_noise(b0, h->header, h->tel,
                block_index, h->temp, status);
    }

    /* Return a pointer to the block. */
    return b0;
}
Exemplo n.º 2
0
/* Evaluate the TEC value for each pierce point - note: at the moment this is
 * just the accumulation of one or more TID screens.
 * TODO convert this to a stand-alone function.
 */
static void oskar_evaluate_TEC(oskar_WorkJonesZ* work, int num_pp,
        const oskar_SettingsIonosphere* settings,
        double gast, int* status)
{
    int i;

    /* FIXME(BM) For now limit number of screens to 1, this can be removed
     * if a TEC model which is valid for multiple screens is implemented
     */
    if (settings->num_TID_screens > 1)
        *status = OSKAR_ERR_INVALID_ARGUMENT;

    oskar_mem_set_value_real(work->total_TEC, 0.0, 0, 0, status);

    /* Loop over TID screens to evaluate TEC values */
    for (i = 0; i < settings->num_TID_screens; ++i)
    {
        oskar_mem_set_value_real(work->screen_TEC, 0.0, 0, 0, status);

        /* Evaluate TEC values for the screen */
        oskar_evaluate_tec_tid(work->screen_TEC, num_pp, work->pp_lon,
                work->pp_lat, work->pp_rel_path, settings->TEC0,
                &settings->TID[i], gast);

        /* Accumulate into total TEC */
        /* FIXME(BM) addition is not physical for more than one TEC screen in
         * the way TIDs are currently evaluated as TEC0 is added into both
         * screens.
         */
        oskar_mem_add(work->total_TEC, work->total_TEC, work->screen_TEC,
                oskar_mem_length(work->total_TEC), status);
    }
}
static void* run_blocks(void* arg)
{
    oskar_Imager* h;
    oskar_Mem *plane, *uu, *vv, *ww = 0, *amp, *weight, *block, *l, *m, *n;
    size_t max_size;
    const size_t smallest = 1024, largest = 65536;
    int dev_loc = OSKAR_CPU, *status;

    /* Get thread function arguments. */
    h = ((ThreadArgs*)arg)->h;
    const int thread_id = ((ThreadArgs*)arg)->thread_id;
    const int num_vis = ((ThreadArgs*)arg)->num_vis;
    plane = ((ThreadArgs*)arg)->plane;
    status = &(h->status);

    /* Set the device used by the thread. */
    if (thread_id < h->num_gpus)
    {
        dev_loc = h->dev_loc;
        oskar_device_set(h->dev_loc, h->gpu_ids[thread_id], status);
    }

    /* Copy visibility data to device. */
    uu = oskar_mem_create_copy(((ThreadArgs*)arg)->uu, dev_loc, status);
    vv = oskar_mem_create_copy(((ThreadArgs*)arg)->vv, dev_loc, status);
    amp = oskar_mem_create_copy(((ThreadArgs*)arg)->amp, dev_loc, status);
    weight = oskar_mem_create_copy(((ThreadArgs*)arg)->weight, dev_loc, status);
    if (h->algorithm == OSKAR_ALGORITHM_DFT_3D)
        ww = oskar_mem_create_copy(((ThreadArgs*)arg)->ww, dev_loc, status);

#ifdef _OPENMP
    /* Disable nested parallelism. */
    omp_set_nested(0);
    omp_set_num_threads(1);
#endif

    /* Calculate the maximum pixel block size, and number of blocks. */
    const size_t num_pixels = (size_t)h->image_size * (size_t)h->image_size;
    max_size = num_pixels / h->num_devices;
    max_size = ((max_size + smallest - 1) / smallest) * smallest;
    if (max_size > largest) max_size = largest;
    if (max_size < smallest) max_size = smallest;
    const int num_blocks = (int) ((num_pixels + max_size - 1) / max_size);

    /* Allocate device memory for pixel block data. */
    block = oskar_mem_create(h->imager_prec, dev_loc, 0, status);
    l = oskar_mem_create(h->imager_prec, dev_loc, max_size, status);
    m = oskar_mem_create(h->imager_prec, dev_loc, max_size, status);
    n = oskar_mem_create(h->imager_prec, dev_loc, max_size, status);

    /* Loop until all blocks are done. */
    for (;;)
    {
        size_t block_size;

        /* Get a unique block index. */
        oskar_mutex_lock(h->mutex);
        const int i_block = (h->i_block)++;
        oskar_mutex_unlock(h->mutex);
        if ((i_block >= num_blocks) || *status) break;

        /* Calculate the block size. */
        const size_t block_start = i_block * max_size;
        block_size = num_pixels - block_start;
        if (block_size > max_size) block_size = max_size;

        /* Copy the (l,m,n) positions for the block. */
        oskar_mem_copy_contents(l, h->l, 0, block_start, block_size, status);
        oskar_mem_copy_contents(m, h->m, 0, block_start, block_size, status);
        if (h->algorithm == OSKAR_ALGORITHM_DFT_3D)
            oskar_mem_copy_contents(n, h->n, 0, block_start,
                    block_size, status);

        /* Run DFT for the block. */
        oskar_dft_c2r(num_vis, 2.0 * M_PI, uu, vv, ww, amp, weight,
                (int) block_size, l, m, n, block, status);

        /* Add data to existing pixels. */
        oskar_mem_add(plane, plane, block,
                block_start, block_start, 0, block_size, status);
    }

    /* Free memory. */
    oskar_mem_free(uu, status);
    oskar_mem_free(vv, status);
    oskar_mem_free(ww, status);
    oskar_mem_free(amp, status);
    oskar_mem_free(weight, status);
    oskar_mem_free(block, status);
    oskar_mem_free(l, status);
    oskar_mem_free(m, status);
    oskar_mem_free(n, status);
    return 0;
}