Exemplo n.º 1
0
void oskar_blank_below_horizon(int offset_mask, int num_sources,
        const oskar_Mem* mask, int offset_out, oskar_Mem* data, int* status)
{
    if (*status) return;
    const int location = oskar_mem_location(data);
    if (oskar_mem_location(mask) != location)
    {
        *status = OSKAR_ERR_LOCATION_MISMATCH;
        return;
    }
    if (oskar_mem_type(mask) != oskar_mem_precision(data))
    {
        *status = OSKAR_ERR_TYPE_MISMATCH;
        return;
    }
    if ((int)oskar_mem_length(data) < num_sources)
    {
        *status = OSKAR_ERR_DIMENSION_MISMATCH;
        return;
    }
    if (location == OSKAR_CPU)
    {
        switch (oskar_mem_type(data))
        {
        case OSKAR_DOUBLE_COMPLEX_MATRIX:
            blank_below_horizon_matrix_d(offset_mask, num_sources,
                    oskar_mem_double_const(mask, status), offset_out,
                    oskar_mem_double4c(data, status));
            break;
        case OSKAR_DOUBLE_COMPLEX:
            blank_below_horizon_scalar_d(offset_mask, num_sources,
                    oskar_mem_double_const(mask, status), offset_out,
                    oskar_mem_double2(data, status));
            break;
        case OSKAR_SINGLE_COMPLEX_MATRIX:
            blank_below_horizon_matrix_f(offset_mask, num_sources,
                    oskar_mem_float_const(mask, status), offset_out,
                    oskar_mem_float4c(data, status));
            break;
        case OSKAR_SINGLE_COMPLEX:
            blank_below_horizon_scalar_f(offset_mask, num_sources,
                    oskar_mem_float_const(mask, status), offset_out,
                    oskar_mem_float2(data, status));
            break;
        default:
            *status = OSKAR_ERR_BAD_DATA_TYPE;
            break;
        }
    }
    else
    {
        size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1};
        const char* k = 0;
        switch (oskar_mem_type(data))
        {
        case OSKAR_DOUBLE_COMPLEX_MATRIX:
            k = "blank_below_horizon_matrix_double"; break;
        case OSKAR_DOUBLE_COMPLEX:
            k = "blank_below_horizon_scalar_double"; break;
        case OSKAR_SINGLE_COMPLEX_MATRIX:
            k = "blank_below_horizon_matrix_float"; break;
        case OSKAR_SINGLE_COMPLEX:
            k = "blank_below_horizon_scalar_float"; break;
        default:
            *status = OSKAR_ERR_BAD_DATA_TYPE;
            return;
        }
        oskar_device_check_local_size(location, 0, local_size);
        global_size[0] = oskar_device_global_size(
                (size_t) num_sources, local_size[0]);
        const oskar_Arg args[] = {
                {INT_SZ, &offset_mask},
                {INT_SZ, &num_sources},
                {PTR_SZ, oskar_mem_buffer_const(mask)},
                {INT_SZ, &offset_out},
                {PTR_SZ, oskar_mem_buffer(data)}
        };
        oskar_device_launch_kernel(k, location, 1, local_size, global_size,
                sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status);
    }
}
Exemplo n.º 2
0
void oskar_mem_add_real(oskar_Mem* mem, double val, int* status)
{
    int precision, location;
    size_t i, num_elements;

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

    /* Get meta-data. */
    precision = oskar_mem_precision(mem);
    location = oskar_mem_location(mem);

    /* Check for empty array. */
    num_elements = oskar_mem_length(mem);
    if (num_elements == 0)
        return;

    /* Check location. */
    if (location == OSKAR_GPU)
    {
        *status = OSKAR_ERR_BAD_LOCATION;
        return;
    }

    /* Get total number of elements to add. */
    if (oskar_mem_is_matrix(mem))
        num_elements *= 4;

    /* Switch on type and location. */
    if (oskar_mem_is_complex(mem))
    {
        if (precision == OSKAR_DOUBLE)
        {
            double2 *t;
            t = oskar_mem_double2(mem, status);
            for (i = 0; i < num_elements; ++i) t[i].x += val;
        }
        else if (precision == OSKAR_SINGLE)
        {
            float2 *t;
            t = oskar_mem_float2(mem, status);
            for (i = 0; i < num_elements; ++i) t[i].x += val;
        }
        else
        {
            *status = OSKAR_ERR_BAD_DATA_TYPE;
        }
    }
    else
    {
        if (precision == OSKAR_DOUBLE)
        {
            double *t;
            t = oskar_mem_double(mem, status);
            for (i = 0; i < num_elements; ++i) t[i] += val;
        }
        else if (precision == OSKAR_SINGLE)
        {
            float *t;
            t = oskar_mem_float(mem, status);
            for (i = 0; i < num_elements; ++i) t[i] += val;
        }
        else
        {
            *status = OSKAR_ERR_BAD_DATA_TYPE;
        }
    }
}
Exemplo n.º 3
0
void oskar_evaluate_station_beam(int num_points,
        int coord_type, oskar_Mem* x, oskar_Mem* y, oskar_Mem* z,
        double norm_ra_rad, double norm_dec_rad, const oskar_Station* station,
        oskar_StationWork* work, int time_index, double frequency_hz,
        double GAST, int offset_out, oskar_Mem* beam, int* status)
{
    oskar_Mem* out;
    const size_t num_points_orig = (size_t)num_points;
    if (*status) return;

    /* Set output beam array to work buffer. */
    out = oskar_station_work_beam_out(work, beam, num_points_orig, status);

    /* Check that the arrays have enough space to add an extra source at the
     * end (for normalisation). We don't want to reallocate here, since that
     * will be slow to do each time: must simply ensure that we pass input
     * arrays that are large enough.
     * The normalisation doesn't need to happen if the station has an
     * isotropic beam. */
    const int normalise = oskar_station_normalise_final_beam(station) &&
            (oskar_station_type(station) != OSKAR_STATION_TYPE_ISOTROPIC);
    if (normalise)
    {
        /* Increment number of points. */
        num_points++;

        /* Check the input arrays are big enough to hold the new source. */
        if ((int)oskar_mem_length(x) < num_points ||
                (int)oskar_mem_length(y) < num_points ||
                (int)oskar_mem_length(z) < num_points)
        {
            *status = OSKAR_ERR_DIMENSION_MISMATCH;
            return;
        }

        /* Get the beam direction in the appropriate coordinate system. */
        const int bypass = (coord_type != OSKAR_ENU_DIRECTIONS);
        const double ha0 = GAST + oskar_station_lon_rad(station) - norm_ra_rad;
        const double lat = oskar_station_lat_rad(station);
        oskar_convert_relative_directions_to_enu_directions(1, bypass, 0,
                1, 0, 0, 0, ha0, norm_dec_rad, lat, num_points - 1, x, y, z,
                status);
    }

    /* Evaluate the station beam for the given directions. */
    if (coord_type == OSKAR_ENU_DIRECTIONS)
        evaluate_station_beam_enu_directions(out, num_points, x, y, z,
                station, work, time_index, frequency_hz, GAST, status);
    else if (coord_type == OSKAR_RELATIVE_DIRECTIONS)
        evaluate_station_beam_relative_directions(out, num_points, x, y, z,
                station, work, time_index, frequency_hz, GAST, status);
    else
        *status = OSKAR_ERR_INVALID_ARGUMENT;

    /* Scale beam pattern by amplitude at the last source if required. */
    if (normalise)
        oskar_mem_normalise(out, 0, oskar_mem_length(out),
                num_points - 1, status);

    /* Copy output beam data. */
    oskar_mem_copy_contents(beam, out, offset_out, 0, num_points_orig, status);
}
Exemplo n.º 4
0
/* 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);
}