Exemple #1
0
void oskar_fft_exec(oskar_FFT* h, oskar_Mem* data, int* status)
{
    oskar_Mem *data_copy = 0, *data_ptr = data;
    if (oskar_mem_location(data) != h->location)
    {
        data_copy = oskar_mem_create_copy(data, h->location, status);
        data_ptr = data_copy;
    }
    if (h->location == OSKAR_CPU)
    {
        if (h->num_dim == 1)
        {
            *status = OSKAR_ERR_FUNCTION_NOT_AVAILABLE;
        }
        else if (h->num_dim == 2)
        {
            if (h->precision == OSKAR_DOUBLE)
                oskar_fftpack_cfft2f(h->dim_size, h->dim_size, h->dim_size,
                        oskar_mem_double(data_ptr, status),
                        oskar_mem_double(h->fftpack_wsave, status),
                        oskar_mem_double(h->fftpack_work, status));
            else
                oskar_fftpack_cfft2f_f(h->dim_size, h->dim_size, h->dim_size,
                        oskar_mem_float(data_ptr, status),
                        oskar_mem_float(h->fftpack_wsave, status),
                        oskar_mem_float(h->fftpack_work, status));
            /* This step not needed for W-kernel generation, so turn it off. */
            if (h->ensure_consistent_norm)
                oskar_mem_scale_real(data_ptr, (double)h->num_cells_total,
                        0, h->num_cells_total, status);
        }
    }
    else if (h->location == OSKAR_GPU)
    {
#ifdef OSKAR_HAVE_CUDA
        if (h->precision == OSKAR_DOUBLE)
            cufftExecZ2Z(h->cufft_plan,
                    (cufftDoubleComplex*) oskar_mem_void(data_ptr),
                    (cufftDoubleComplex*) oskar_mem_void(data_ptr),
                    CUFFT_FORWARD);
        else
            cufftExecC2C(h->cufft_plan,
                    (cufftComplex*) oskar_mem_void(data_ptr),
                    (cufftComplex*) oskar_mem_void(data_ptr),
                    CUFFT_FORWARD);
#endif
    }
    else
        *status = OSKAR_ERR_BAD_LOCATION;
    if (oskar_mem_location(data) != h->location)
        oskar_mem_copy(data, data_ptr, status);
    oskar_mem_free(data_copy, status);
}
int oskar_find_closest_match(double value, const oskar_Mem* values,
        int* status)
{
    int type, num_values, match_index = 0;

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

    /* Check location. */
    if (oskar_mem_location(values) != OSKAR_CPU)
    {
        *status = OSKAR_ERR_BAD_LOCATION;
        return 0;
    }

    /* Switch on type. */
    type = oskar_mem_type(values);
    num_values = (int)oskar_mem_length(values);
    if (type == OSKAR_DOUBLE)
    {
        match_index = oskar_find_closest_match_d(value, num_values,
                oskar_mem_double_const(values, status));
    }
    else if (type == OSKAR_SINGLE)
    {
        match_index = oskar_find_closest_match_f(value, num_values,
                oskar_mem_float_const(values, status));
    }
    else
    {
        *status = OSKAR_ERR_BAD_DATA_TYPE;
    }
    return match_index;
}
void oskar_convert_station_uvw_to_baseline_uvw(int num_stations, int offset_in,
        const oskar_Mem* u, const oskar_Mem* v, const oskar_Mem* w,
        int offset_out, oskar_Mem* uu, oskar_Mem* vv, oskar_Mem* ww,
        int* status)
{
    if (*status) return;
    const int type = oskar_mem_type(u);
    const int location = oskar_mem_location(u);
    if (location == OSKAR_CPU)
    {
        if (type == OSKAR_SINGLE)
            convert_station_uvw_to_baseline_uvw_float(num_stations, offset_in,
                    oskar_mem_float_const(u, status),
                    oskar_mem_float_const(v, status),
                    oskar_mem_float_const(w, status), offset_out,
                    oskar_mem_float(uu, status),
                    oskar_mem_float(vv, status),
                    oskar_mem_float(ww, status));
        else if (type == OSKAR_DOUBLE)
            convert_station_uvw_to_baseline_uvw_double(num_stations, offset_in,
                    oskar_mem_double_const(u, status),
                    oskar_mem_double_const(v, status),
                    oskar_mem_double_const(w, status), offset_out,
                    oskar_mem_double(uu, status),
                    oskar_mem_double(vv, status),
                    oskar_mem_double(ww, status));
        else
            *status = OSKAR_ERR_BAD_DATA_TYPE;
    }
    else
    {
        size_t local_size[] = {32, 1, 1}, global_size[] = {1, 1, 1};
        const char* k = 0;
        if (type == OSKAR_SINGLE)
            k = "convert_station_uvw_to_baseline_uvw_float";
        else if (type == OSKAR_DOUBLE)
            k = "convert_station_uvw_to_baseline_uvw_double";
        else
        {
            *status = OSKAR_ERR_BAD_DATA_TYPE;
            return;
        }
        oskar_device_check_local_size(location, 0, local_size);
        global_size[0] = num_stations * local_size[0];
        const oskar_Arg args[] = {
                {INT_SZ, &num_stations},
                {INT_SZ, &offset_in},
                {PTR_SZ, oskar_mem_buffer_const(u)},
                {PTR_SZ, oskar_mem_buffer_const(v)},
                {PTR_SZ, oskar_mem_buffer_const(w)},
                {INT_SZ, &offset_out},
                {PTR_SZ, oskar_mem_buffer(uu)},
                {PTR_SZ, oskar_mem_buffer(vv)},
                {PTR_SZ, oskar_mem_buffer(ww)}
        };
        oskar_device_launch_kernel(k, location, 1, local_size, global_size,
                sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status);
    }
}
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);
}
Exemple #5
0
void oskar_mem_multiply(
        oskar_Mem* out,
        const oskar_Mem* in1,
        const oskar_Mem* in2,
        size_t offset_out,
        size_t offset_in1,
        size_t offset_in2,
        size_t num_elements,
        int* status)
{
    oskar_Mem *a_temp = 0, *b_temp = 0;
    const oskar_Mem *a_, *b_; /* Pointers. */
    if (num_elements == 0) return;
    const int location = oskar_mem_location(out);
    const unsigned int off_a = (unsigned int) offset_in1;
    const unsigned int off_b = (unsigned int) offset_in2;
    const unsigned int off_c = (unsigned int) offset_out;
    const unsigned int n = (unsigned int) num_elements;
    if (*status) return;
    a_ = in1;
    b_ = in2;
    if (oskar_mem_location(in1) != location)
    {
        a_temp = oskar_mem_create_copy(in1, location, status);
        a_ = a_temp;
    }
    if (oskar_mem_location(in2) != location)
    {
        b_temp = oskar_mem_create_copy(in2, location, status);
        b_ = b_temp;
    }
    if (location == OSKAR_CPU)
    {
        void *c = out->data;
        const void *a = a_->data, *b = b_->data;
        /* Check if types are all the same. */
        if (out->type == in1->type && out->type == in2->type)
        {
            switch (out->type)
            {
            case OSKAR_DOUBLE:
                mem_mul_rr_r_double(off_a, off_b, off_c, n,
                        (const double*)a, (const double*)b, (double*)c);
                break;
            case OSKAR_DOUBLE_COMPLEX:
                mem_mul_cc_c_double(off_a, off_b, off_c, n,
                        (const double2*)a, (const double2*)b, (double2*)c);
                break;
            case OSKAR_DOUBLE_COMPLEX_MATRIX:
                mem_mul_mm_m_double(off_a, off_b, off_c, n,
                        (const double4c*)a, (const double4c*)b, (double4c*)c);
                break;
            case OSKAR_SINGLE:
                mem_mul_rr_r_float(off_a, off_b, off_c, n,
                        (const float*)a, (const float*)b, (float*)c);
                break;
            case OSKAR_SINGLE_COMPLEX:
                mem_mul_cc_c_float(off_a, off_b, off_c, n,
                        (const float2*)a, (const float2*)b, (float2*)c);
                break;
            case OSKAR_SINGLE_COMPLEX_MATRIX:
                mem_mul_mm_m_float(off_a, off_b, off_c, n,
                        (const float4c*)a, (const float4c*)b, (float4c*)c);
                break;
            default:
                *status = OSKAR_ERR_BAD_DATA_TYPE;
                break;
            }
        }
        else
        {
            switch (out->type)
            {
            case OSKAR_DOUBLE_COMPLEX_MATRIX:
            {
                switch (in1->type)
                {
                case OSKAR_DOUBLE_COMPLEX:
                    if (in2->type == in1->type)
                        mem_mul_cc_m_double(off_a, off_b, off_c, n,
                                (const double2*)a, (const double2*)b,
                                (double4c*)c);
                    else if (in2->type == out->type)
                        mem_mul_cm_m_double(off_a, off_b, off_c, n,
                                (const double2*)a, (const double4c*)b,
                                (double4c*)c);
                    else
                        *status = OSKAR_ERR_TYPE_MISMATCH;
                    break;
                case OSKAR_DOUBLE_COMPLEX_MATRIX:
                    if (in2->type == OSKAR_DOUBLE_COMPLEX)
                        mem_mul_mc_m_double(off_a, off_b, off_c, n,
                                (const double4c*)a, (const double2*)b,
                                (double4c*)c);
                    else
                        *status = OSKAR_ERR_TYPE_MISMATCH;
                    break;
                default:
                    *status = OSKAR_ERR_TYPE_MISMATCH;
                    break;
                }
                break;
            }
            case OSKAR_SINGLE_COMPLEX_MATRIX:
            {
                switch (in1->type)
                {
                case OSKAR_SINGLE_COMPLEX:
                    if (in2->type == in1->type)
                        mem_mul_cc_m_float(off_a, off_b, off_c, n,
                                (const float2*)a, (const float2*)b,
                                (float4c*)c);
                    else if (in2->type == out->type)
                        mem_mul_cm_m_float(off_a, off_b, off_c, n,
                                (const float2*)a, (const float4c*)b,
                                (float4c*)c);
                    else
                        *status = OSKAR_ERR_TYPE_MISMATCH;
                    break;
                case OSKAR_SINGLE_COMPLEX_MATRIX:
                    if (in2->type == OSKAR_SINGLE_COMPLEX)
                        mem_mul_mc_m_float(off_a, off_b, off_c, n,
                                (const float4c*)a, (const float2*)b,
                                (float4c*)c);
                    else
                        *status = OSKAR_ERR_TYPE_MISMATCH;
                    break;
                default:
                    *status = OSKAR_ERR_TYPE_MISMATCH;
                    break;
                }
                break;
            }
            default:
                *status = OSKAR_ERR_TYPE_MISMATCH;
                break;
            }
        }
    }
    else
    {
        const char* k = 0;
        /* Check if types are all the same. */
        if (out->type == in1->type && out->type == in2->type)
        {
            switch (out->type)
            {
            case OSKAR_DOUBLE:                k = "mem_mul_rr_r_double"; break;
            case OSKAR_DOUBLE_COMPLEX:        k = "mem_mul_cc_c_double"; break;
            case OSKAR_DOUBLE_COMPLEX_MATRIX: k = "mem_mul_mm_m_double"; break;
            case OSKAR_SINGLE:                k = "mem_mul_rr_r_float"; break;
            case OSKAR_SINGLE_COMPLEX:        k = "mem_mul_cc_c_float"; break;
            case OSKAR_SINGLE_COMPLEX_MATRIX: k = "mem_mul_mm_m_float"; break;
            default:
                *status = OSKAR_ERR_BAD_DATA_TYPE;
                break;
            }
        }
        else
        {
            switch (out->type)
            {
            case OSKAR_DOUBLE_COMPLEX_MATRIX:
            {
                switch (in1->type)
                {
                case OSKAR_DOUBLE_COMPLEX:
                    if (in2->type == in1->type)
                        k = "mem_mul_cc_m_double";
                    else if (in2->type == out->type)
                        k = "mem_mul_cm_m_double";
                    else
                        *status = OSKAR_ERR_TYPE_MISMATCH;
                    break;
                case OSKAR_DOUBLE_COMPLEX_MATRIX:
                    if (in2->type == OSKAR_DOUBLE_COMPLEX)
                        k = "mem_mul_mc_m_double";
                    else
                        *status = OSKAR_ERR_TYPE_MISMATCH;
                    break;
                default:
                    *status = OSKAR_ERR_TYPE_MISMATCH;
                    break;
                }
                break;
            }
            case OSKAR_SINGLE_COMPLEX_MATRIX:
            {
                switch (in1->type)
                {
                case OSKAR_SINGLE_COMPLEX:
                    if (in2->type == in1->type)
                        k = "mem_mul_cc_m_float";
                    else if (in2->type == out->type)
                        k = "mem_mul_cm_m_float";
                    else
                        *status = OSKAR_ERR_TYPE_MISMATCH;
                    break;
                case OSKAR_SINGLE_COMPLEX_MATRIX:
                    if (in2->type == OSKAR_SINGLE_COMPLEX)
                        k = "mem_mul_mc_m_float";
                    else
                        *status = OSKAR_ERR_TYPE_MISMATCH;
                    break;
                default:
                    *status = OSKAR_ERR_TYPE_MISMATCH;
                    break;
                }
                break;
            }
            default:
                *status = OSKAR_ERR_TYPE_MISMATCH;
                break;
            }
        }
        if (!*status)
        {
            size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1};
            oskar_device_check_local_size(location, 0, local_size);
            global_size[0] = oskar_device_global_size(
                    num_elements, local_size[0]);
            const oskar_Arg args[] = {
                    {INT_SZ, &off_a},
                    {INT_SZ, &off_b},
                    {INT_SZ, &off_c},
                    {INT_SZ, &n},
                    {PTR_SZ, oskar_mem_buffer_const(a_)},
                    {PTR_SZ, oskar_mem_buffer_const(b_)},
                    {PTR_SZ, oskar_mem_buffer(out)}
            };
            oskar_device_launch_kernel(k, location, 1, local_size, global_size,
                    sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status);
        }
    }

    /* Free temporary arrays. */
    oskar_mem_free(a_temp, status);
    oskar_mem_free(b_temp, status);
}
void oskar_convert_ludwig3_to_theta_phi_components(
        int num_points, const oskar_Mem* phi, int stride, int offset,
        oskar_Mem* vec, int* status)
{
    if (*status) return;
    const int type = oskar_mem_type(phi);
    const int location = oskar_mem_location(phi);
    const int off_h = offset, off_v = offset + 1;
    if (!oskar_mem_is_matrix(vec))
    {
        *status = OSKAR_ERR_TYPE_MISMATCH;
        return;
    }
    if (location == OSKAR_CPU)
    {
        if (type == OSKAR_SINGLE)
            convert_ludwig3_to_theta_phi_float(
                    num_points,
                    oskar_mem_float_const(phi, status),
                    stride, off_h, off_v,
                    oskar_mem_float2(vec, status),
                    oskar_mem_float2(vec, status));
        else if (type == OSKAR_DOUBLE)
            convert_ludwig3_to_theta_phi_double(
                    num_points,
                    oskar_mem_double_const(phi, status),
                    stride, off_h, off_v,
                    oskar_mem_double2(vec, status),
                    oskar_mem_double2(vec, status));
        else
            *status = OSKAR_ERR_BAD_DATA_TYPE;
    }
    else
    {
        size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1};
        const char* k = 0;
        if (type == OSKAR_SINGLE)
            k = "convert_ludwig3_to_theta_phi_float";
        else if (type == OSKAR_DOUBLE)
            k = "convert_ludwig3_to_theta_phi_double";
        else
        {
            *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_points, local_size[0]);
        const oskar_Arg args[] = {
                {INT_SZ, &num_points},
                {PTR_SZ, oskar_mem_buffer_const(phi)},
                {INT_SZ, &stride},
                {INT_SZ, &off_h},
                {INT_SZ, &off_v},
                {PTR_SZ, oskar_mem_buffer(vec)},
                {PTR_SZ, oskar_mem_buffer(vec)}
        };
        oskar_device_launch_kernel(k, location, 1, local_size, global_size,
                sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status);
    }
}
/* Wrapper. */
void oskar_evaluate_cross_power(int num_sources,
        int num_stations, const oskar_Mem* jones, oskar_Mem* out,
        int *status)
{
    int type, location;

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

    /* Check type and location. */
    type = oskar_mem_type(jones);
    location = oskar_mem_location(jones);
    if (type != oskar_mem_type(out))
    {
        *status = OSKAR_ERR_TYPE_MISMATCH;
        return;
    }
    if (location != oskar_mem_location(out))
    {
        *status = OSKAR_ERR_LOCATION_MISMATCH;
        return;
    }

    /* Switch on type and location combination. */
    if (type == OSKAR_SINGLE_COMPLEX_MATRIX)
    {
        if (location == OSKAR_GPU)
        {
#ifdef OSKAR_HAVE_CUDA
            oskar_evaluate_cross_power_cuda_f(num_sources,
                    num_stations, oskar_mem_float4c_const(jones, status),
                    oskar_mem_float4c(out, status));
            oskar_device_check_error(status);
#else
            *status = OSKAR_ERR_CUDA_NOT_AVAILABLE;
#endif
        }
        else if (location == OSKAR_CPU)
        {
            oskar_evaluate_cross_power_omp_f(num_sources,
                    num_stations, oskar_mem_float4c_const(jones, status),
                    oskar_mem_float4c(out, status));
        }
    }
    else if (type == OSKAR_DOUBLE_COMPLEX_MATRIX)
    {
        if (location == OSKAR_GPU)
        {
#ifdef OSKAR_HAVE_CUDA
            oskar_evaluate_cross_power_cuda_d(num_sources,
                    num_stations, oskar_mem_double4c_const(jones, status),
                    oskar_mem_double4c(out, status));
            oskar_device_check_error(status);
#else
            *status = OSKAR_ERR_CUDA_NOT_AVAILABLE;
#endif
        }
        else if (location == OSKAR_CPU)
        {
            oskar_evaluate_cross_power_omp_d(num_sources,
                    num_stations, oskar_mem_double4c_const(jones, status),
                    oskar_mem_double4c(out, status));
        }
    }

    /* Scalar versions. */
    else if (type == OSKAR_SINGLE_COMPLEX)
    {
        if (location == OSKAR_GPU)
        {
#ifdef OSKAR_HAVE_CUDA
            oskar_evaluate_cross_power_scalar_cuda_f(num_sources,
                    num_stations, oskar_mem_float2_const(jones, status),
                    oskar_mem_float2(out, status));
            oskar_device_check_error(status);
#else
            *status = OSKAR_ERR_CUDA_NOT_AVAILABLE;
#endif
        }
        else if (location == OSKAR_CPU)
        {
            oskar_evaluate_cross_power_scalar_omp_f(num_sources,
                    num_stations, oskar_mem_float2_const(jones, status),
                    oskar_mem_float2(out, status));
        }
    }
    else if (type == OSKAR_DOUBLE_COMPLEX)
    {
        if (location == OSKAR_GPU)
        {
#ifdef OSKAR_HAVE_CUDA
            oskar_evaluate_cross_power_scalar_cuda_d(num_sources,
                    num_stations, oskar_mem_double2_const(jones, status),
                    oskar_mem_double2(out, status));
            oskar_device_check_error(status);
#else
            *status = OSKAR_ERR_CUDA_NOT_AVAILABLE;
#endif
        }
        else if (location == OSKAR_CPU)
        {
            oskar_evaluate_cross_power_scalar_omp_d(num_sources,
                    num_stations, oskar_mem_double2_const(jones, status),
                    oskar_mem_double2(out, status));
        }
    }
    else
    {
        *status = OSKAR_ERR_BAD_DATA_TYPE;
    }
}
void oskar_splines_evaluate(const oskar_Splines* spline,
        int num_points, const oskar_Mem* x, const oskar_Mem* y,
        int stride_out, int offset_out, oskar_Mem* output, int* status)
{
    if (*status) return;
    const int type = oskar_splines_precision(spline);
    const int location = oskar_splines_mem_location(spline);
    const int nx = oskar_splines_num_knots_x_theta(spline);
    const int ny = oskar_splines_num_knots_y_phi(spline);
    const oskar_Mem* tx = oskar_splines_knots_x_theta_const(spline);
    const oskar_Mem* ty = oskar_splines_knots_y_phi_const(spline);
    const oskar_Mem* coeff = oskar_splines_coeff_const(spline);
    if (type != oskar_mem_type(x) || type != oskar_mem_type(y))
    {
        *status = OSKAR_ERR_TYPE_MISMATCH;
        return;
    }
    if (location != oskar_mem_location(output) ||
            location != oskar_mem_location(x) ||
            location != oskar_mem_location(y))
    {
        *status = OSKAR_ERR_LOCATION_MISMATCH;
        return;
    }
    if (location == OSKAR_CPU)
    {
        int i;
        if (type == OSKAR_SINGLE)
        {
            const float *tx_, *ty_, *coeff_, *x_, *y_;
            float *out;
            tx_    = oskar_mem_float_const(tx, status);
            ty_    = oskar_mem_float_const(ty, status);
            coeff_ = oskar_mem_float_const(coeff, status);
            x_     = oskar_mem_float_const(x, status);
            y_     = oskar_mem_float_const(y, status);
            out    = oskar_mem_float(output, status) + offset_out;
            if (nx == 0 || ny == 0 || !tx_ || !ty_ || !coeff_)
                for (i = 0; i < num_points; ++i) out[i * stride_out] = 0.0f;
            else
            {
                float x1, y1, wrk[8];
                int iwrk1[2], kwrk1 = 2, lwrk = 8, err = 0;
                for (i = 0; i < num_points; ++i)
                {
                    x1 = x_[i];
                    y1 = y_[i];
                    oskar_dierckx_bispev_f(tx_, nx, ty_, ny, coeff_, 3, 3,
                            &x1, 1, &y1, 1, &out[i * stride_out],
                            wrk, lwrk, iwrk1, kwrk1, &err);
                    if (err != 0)
                    {
                        *status = OSKAR_ERR_SPLINE_EVAL_FAIL;
                        return;
                    }
                }
            }
        }
        else if (type == OSKAR_DOUBLE)
        {
            const double *tx_, *ty_, *coeff_, *x_, *y_;
            double *out;
            tx_    = oskar_mem_double_const(tx, status);
            ty_    = oskar_mem_double_const(ty, status);
            coeff_ = oskar_mem_double_const(coeff, status);
            x_     = oskar_mem_double_const(x, status);
            y_     = oskar_mem_double_const(y, status);
            out    = oskar_mem_double(output, status) + offset_out;
            if (nx == 0 || ny == 0 || !tx_ || !ty_ || !coeff_)
                for (i = 0; i < num_points; ++i) out[i * stride_out] = 0.0;
            else
            {
                double x1, y1, wrk[8];
                int iwrk1[2], kwrk1 = 2, lwrk = 8, err = 0;
                for (i = 0; i < num_points; ++i)
                {
                    x1 = x_[i];
                    y1 = y_[i];
                    oskar_dierckx_bispev_d(tx_, nx, ty_, ny, coeff_, 3, 3,
                            &x1, 1, &y1, 1, &out[i * stride_out],
                            wrk, lwrk, iwrk1, kwrk1, &err);
                    if (err != 0)
                    {
                        *status = OSKAR_ERR_SPLINE_EVAL_FAIL;
                        return;
                    }
                }
            }
        }
        else
            *status = OSKAR_ERR_BAD_DATA_TYPE;
    }
    else
    {
        size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1};
        const char* k = 0;
        if (nx == 0 || ny == 0)
        {
            if (type == OSKAR_DOUBLE)      k = "set_zeros_stride_double";
            else if (type == OSKAR_SINGLE) k = "set_zeros_stride_float";
            else
            {
                *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_points, local_size[0]);
            const oskar_Arg args[] = {
                    {INT_SZ, &num_points},
                    {INT_SZ, &stride_out},
                    {INT_SZ, &offset_out},
                    {PTR_SZ, oskar_mem_buffer(output)}
            };
            oskar_device_launch_kernel(k, location, 1, local_size, global_size,
                    sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status);
        }
        else
        {
            if (type == OSKAR_DOUBLE)      k = "dierckx_bispev_bicubic_double";
            else if (type == OSKAR_SINGLE) k = "dierckx_bispev_bicubic_float";
            else
            {
                *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_points, local_size[0]);
            const oskar_Arg args[] = {
                    {PTR_SZ, oskar_mem_buffer_const(tx)},
                    {INT_SZ, &nx},
                    {PTR_SZ, oskar_mem_buffer_const(ty)},
                    {INT_SZ, &ny},
                    {PTR_SZ, oskar_mem_buffer_const(coeff)},
                    {INT_SZ, &num_points},
                    {PTR_SZ, oskar_mem_buffer_const(x)},
                    {PTR_SZ, oskar_mem_buffer_const(y)},
                    {INT_SZ, &stride_out},
                    {INT_SZ, &offset_out},
                    {PTR_SZ, oskar_mem_buffer(output)}
            };
            oskar_device_launch_kernel(k, location, 1, local_size, global_size,
                    sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status);
        }
    }
}
void oskar_mem_evaluate_relative_error(const oskar_Mem* val_approx,
        const oskar_Mem* val_accurate, double* min_rel_error,
        double* max_rel_error, double* avg_rel_error, double* std_rel_error,
        int* status)
{
    int prec_approx, prec_accurate;
    size_t i, n;
    const oskar_Mem *app_ptr, *acc_ptr;
    oskar_Mem *approx_temp = 0, *accurate_temp = 0;
    double old_m = 0.0, new_m = 0.0, old_s = 0.0, new_s = 0.0;

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

    /* Initialise outputs. */
    if (max_rel_error) *max_rel_error = -DBL_MAX;
    if (min_rel_error) *min_rel_error = DBL_MAX;
    if (avg_rel_error) *avg_rel_error = DBL_MAX;
    if (std_rel_error) *std_rel_error = DBL_MAX;

    /* Type and dimension check. */
    if (oskar_mem_is_matrix(val_approx) && !oskar_mem_is_matrix(val_accurate))
    {
        *status = OSKAR_ERR_TYPE_MISMATCH;
        return;
    }
    if (oskar_mem_is_complex(val_approx) && !oskar_mem_is_complex(val_accurate))
    {
        *status = OSKAR_ERR_TYPE_MISMATCH;
        return;
    }

    /* Get and check base types. */
    prec_approx = oskar_mem_precision(val_approx);
    prec_accurate = oskar_mem_precision(val_accurate);
    if (prec_approx != OSKAR_SINGLE && prec_approx != OSKAR_DOUBLE)
    {
        *status = OSKAR_ERR_BAD_DATA_TYPE;
        return;
    }
    if (prec_accurate != OSKAR_SINGLE && prec_accurate != OSKAR_DOUBLE)
    {
        *status = OSKAR_ERR_BAD_DATA_TYPE;
        return;
    }

    /* Get number of elements to check. */
    n = oskar_mem_length(val_approx) < oskar_mem_length(val_accurate) ?
            oskar_mem_length(val_approx) : oskar_mem_length(val_accurate);
    if (oskar_mem_is_matrix(val_approx)) n *= 4;

    /* Copy input data to temporary CPU arrays if required. */
    app_ptr = val_approx;
    acc_ptr = val_accurate;
    if (oskar_mem_location(val_approx) != OSKAR_CPU)
    {
        approx_temp = oskar_mem_create_copy(val_approx, OSKAR_CPU,
                status);
        if (*status)
        {
            oskar_mem_free(approx_temp, status);
            return;
        }
        app_ptr = approx_temp;
    }
    if (oskar_mem_location(val_accurate) != OSKAR_CPU)
    {
        accurate_temp = oskar_mem_create_copy(val_accurate, OSKAR_CPU,
                status);
        if (*status)
        {
            oskar_mem_free(accurate_temp, status);
            return;
        }
        acc_ptr = accurate_temp;
    }

    /* Check numbers are the same, to appropriate precision. */
    if (prec_approx == OSKAR_SINGLE && prec_accurate == OSKAR_SINGLE)
    {
        const float *approx, *accurate;
        approx = oskar_mem_float_const(app_ptr, status);
        accurate = oskar_mem_float_const(acc_ptr, status);
        CHECK_ELEMENTS(1e-5)
    }
    else if (prec_approx == OSKAR_DOUBLE && prec_accurate == OSKAR_SINGLE)
void oskar_gaussian_circular(int num_points,
        const oskar_Mem* l, const oskar_Mem* m, double std,
        oskar_Mem* out, int* status)
{
    if (*status) return;
    const int location = oskar_mem_location(out);
    const double inv_2_var = 1.0 / (2.0 * std * std);
    const float inv_2_var_f = (float)inv_2_var;
    if (oskar_mem_precision(out) != oskar_mem_type(l) ||
            oskar_mem_precision(out) != oskar_mem_type(m))
    {
        *status = OSKAR_ERR_TYPE_MISMATCH;
        return;
    }
    if (location != oskar_mem_location(l) || location != oskar_mem_location(m))
    {
        *status = OSKAR_ERR_LOCATION_MISMATCH;
        return;
    }
    if ((int)oskar_mem_length(l) < num_points ||
            (int)oskar_mem_length(m) < num_points)
    {
        *status = OSKAR_ERR_DIMENSION_MISMATCH;
        return;
    }
    oskar_mem_ensure(out, num_points, status);
    if (*status) return;
    if (location == OSKAR_CPU)
    {
        switch (oskar_mem_type(out))
        {
        case OSKAR_SINGLE_COMPLEX:
            gaussian_circular_complex_f(num_points,
                    oskar_mem_float_const(l, status),
                    oskar_mem_float_const(m, status), inv_2_var_f,
                    oskar_mem_float2(out, status));
            break;
        case OSKAR_DOUBLE_COMPLEX:
            gaussian_circular_complex_d(num_points,
                    oskar_mem_double_const(l, status),
                    oskar_mem_double_const(m, status), inv_2_var,
                    oskar_mem_double2(out, status));
            break;
        case OSKAR_SINGLE_COMPLEX_MATRIX:
            gaussian_circular_matrix_f(num_points,
                    oskar_mem_float_const(l, status),
                    oskar_mem_float_const(m, status), inv_2_var_f,
                    oskar_mem_float4c(out, status));
            break;
        case OSKAR_DOUBLE_COMPLEX_MATRIX:
            gaussian_circular_matrix_d(num_points,
                    oskar_mem_double_const(l, status),
                    oskar_mem_double_const(m, status), inv_2_var,
                    oskar_mem_double4c(out, 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;
        const int is_dbl = oskar_mem_is_double(out);
        switch (oskar_mem_type(out))
        {
        case OSKAR_SINGLE_COMPLEX:
            k = "gaussian_circular_complex_float"; break;
        case OSKAR_DOUBLE_COMPLEX:
            k = "gaussian_circular_complex_double"; break;
        case OSKAR_SINGLE_COMPLEX_MATRIX:
            k = "gaussian_circular_matrix_float"; break;
        case OSKAR_DOUBLE_COMPLEX_MATRIX:
            k = "gaussian_circular_matrix_double"; 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_points, local_size[0]);
        const oskar_Arg args[] = {
                {INT_SZ, &num_points},
                {PTR_SZ, oskar_mem_buffer_const(l)},
                {PTR_SZ, oskar_mem_buffer_const(m)},
                {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
                        (const void*)&inv_2_var : (const void*)&inv_2_var_f},
                {PTR_SZ, oskar_mem_buffer(out)}
        };
        oskar_device_launch_kernel(k, location, 1, local_size, global_size,
                sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status);
    }
}
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_CPU)
    {
        *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;
        }
    }
}
void oskar_mem_write_fits_cube(oskar_Mem* data, const char* root_name,
        int width, int height, int num_planes, int i_plane, int* status)
{
    oskar_Mem *copy = 0, *ptr = 0;
    size_t len, buf_len;
    char* fname;

    /* Checks. */
    if (*status) return;
    if (oskar_mem_is_matrix(data))
    {
        *status = OSKAR_ERR_BAD_DATA_TYPE;
        return;
    }

    /* Construct the filename. */
    len = strlen(root_name);
    buf_len = 11 + len;
    fname = (char*) calloc(buf_len, sizeof(char));

    /* Copy to host memory if necessary. */
    ptr = data;
    if (oskar_mem_location(data) != OSKAR_CPU)
    {
        copy = oskar_mem_create_copy(ptr, OSKAR_CPU, status);
        ptr = copy;
    }

    /* Deal with complex data. */
    if (oskar_mem_is_complex(ptr))
    {
        oskar_Mem *temp;
        temp = oskar_mem_create(oskar_mem_precision(ptr), OSKAR_CPU,
                oskar_mem_length(ptr), status);

        /* Extract the real part and write it. */
        SNPRINTF(fname, buf_len, "%s_REAL.fits", root_name);
        convert_complex(ptr, temp, 0, status);
        write_pixels(temp, fname, width, height, num_planes, i_plane, status);

        /* Extract the imaginary part and write it. */
        SNPRINTF(fname, buf_len, "%s_IMAG.fits", root_name);
        convert_complex(ptr, temp, 1, status);
        write_pixels(temp, fname, width, height, num_planes, i_plane, status);
        oskar_mem_free(temp, status);
    }
    else
    {
        /* No conversion needed. */
        if ((len >= 5) && (
                !strcmp(&(root_name[len-5]), ".fits") ||
                !strcmp(&(root_name[len-5]), ".FITS") ))
        {
            SNPRINTF(fname, buf_len, "%s", root_name);
        }
        else
        {
            SNPRINTF(fname, buf_len, "%s.fits", root_name);
        }
        write_pixels(ptr, fname, width, height, num_planes, i_plane, status);
    }
    free(fname);
    oskar_mem_free(copy, status);
}
Exemple #13
0
void oskar_dftw(
        int normalise,
        int num_in,
        double wavenumber,
        const oskar_Mem* weights_in,
        const oskar_Mem* x_in,
        const oskar_Mem* y_in,
        const oskar_Mem* z_in,
        int offset_coord_out,
        int num_out,
        const oskar_Mem* x_out,
        const oskar_Mem* y_out,
        const oskar_Mem* z_out,
        const oskar_Mem* data,
        int offset_out,
        oskar_Mem* output,
        int* status)
{
    if (*status) return;
    const int location = oskar_mem_location(output);
    const int type = oskar_mem_precision(output);
    const int is_dbl = oskar_mem_is_double(output);
    const int is_3d = (z_in != NULL && z_out != NULL);
    const int is_data = (data != NULL);
    const int is_matrix = oskar_mem_is_matrix(output);
    if (!oskar_mem_is_complex(output) || !oskar_mem_is_complex(weights_in) ||
            oskar_mem_is_matrix(weights_in))
    {
        *status = OSKAR_ERR_BAD_DATA_TYPE;
        return;
    }
    if (oskar_mem_location(weights_in) != location ||
            oskar_mem_location(x_in) != location ||
            oskar_mem_location(y_in) != location ||
            oskar_mem_location(x_out) != location ||
            oskar_mem_location(y_out) != location)
    {
        *status = OSKAR_ERR_LOCATION_MISMATCH;
        return;
    }
    if (oskar_mem_precision(weights_in) != type ||
            oskar_mem_type(x_in) != type ||
            oskar_mem_type(y_in) != type ||
            oskar_mem_type(x_out) != type ||
            oskar_mem_type(y_out) != type)
    {
        *status = OSKAR_ERR_TYPE_MISMATCH;
        return;
    }
    if (is_data)
    {
        if (oskar_mem_location(data) != location)
        {
            *status = OSKAR_ERR_LOCATION_MISMATCH;
            return;
        }
        if (!oskar_mem_is_complex(data) ||
                oskar_mem_type(data) != oskar_mem_type(output) ||
                oskar_mem_precision(data) != type)
        {
            *status = OSKAR_ERR_TYPE_MISMATCH;
            return;
        }
    }
    if (is_3d)
    {
        if (oskar_mem_location(z_in) != location ||
                oskar_mem_location(z_out) != location)
        {
            *status = OSKAR_ERR_LOCATION_MISMATCH;
            return;
        }
        if (oskar_mem_type(z_in) != type || oskar_mem_type(z_out) != type)
        {
            *status = OSKAR_ERR_TYPE_MISMATCH;
            return;
        }
    }
    oskar_mem_ensure(output, (size_t) offset_out + num_out, status);
    if (*status) return;
    if (location == OSKAR_CPU)
    {
        if (is_data)
        {
            if (is_matrix)
            {
                if (is_3d)
                {
                    if (is_dbl)
                        dftw_m2m_3d_double(num_in, wavenumber,
                                oskar_mem_double2_const(weights_in, status),
                                oskar_mem_double_const(x_in, status),
                                oskar_mem_double_const(y_in, status),
                                oskar_mem_double_const(z_in, status),
                                offset_coord_out, num_out,
                                oskar_mem_double_const(x_out, status),
                                oskar_mem_double_const(y_out, status),
                                oskar_mem_double_const(z_out, status),
                                oskar_mem_double4c_const(data, status),
                                offset_out,
                                oskar_mem_double4c(output, status), 0);
                    else
                        dftw_m2m_3d_float(num_in, (float)wavenumber,
                                oskar_mem_float2_const(weights_in, status),
                                oskar_mem_float_const(x_in, status),
                                oskar_mem_float_const(y_in, status),
                                oskar_mem_float_const(z_in, status),
                                offset_coord_out, num_out,
                                oskar_mem_float_const(x_out, status),
                                oskar_mem_float_const(y_out, status),
                                oskar_mem_float_const(z_out, status),
                                oskar_mem_float4c_const(data, status),
                                offset_out,
                                oskar_mem_float4c(output, status), 0);
                }
                else
                {
                    if (is_dbl)
                        dftw_m2m_2d_double(num_in, wavenumber,
                                oskar_mem_double2_const(weights_in, status),
                                oskar_mem_double_const(x_in, status),
                                oskar_mem_double_const(y_in, status), 0,
                                offset_coord_out, num_out,
                                oskar_mem_double_const(x_out, status),
                                oskar_mem_double_const(y_out, status), 0,
                                oskar_mem_double4c_const(data, status),
                                offset_out,
                                oskar_mem_double4c(output, status), 0);
                    else
                        dftw_m2m_2d_float(num_in, (float)wavenumber,
                                oskar_mem_float2_const(weights_in, status),
                                oskar_mem_float_const(x_in, status),
                                oskar_mem_float_const(y_in, status), 0,
                                offset_coord_out, num_out,
                                oskar_mem_float_const(x_out, status),
                                oskar_mem_float_const(y_out, status), 0,
                                oskar_mem_float4c_const(data, status),
                                offset_out,
                                oskar_mem_float4c(output, status), 0);
                }
            }
            else
            {
                if (is_3d)
                {
                    if (is_dbl)
                        dftw_c2c_3d_double(num_in, wavenumber,
                                oskar_mem_double2_const(weights_in, status),
                                oskar_mem_double_const(x_in, status),
                                oskar_mem_double_const(y_in, status),
                                oskar_mem_double_const(z_in, status),
                                offset_coord_out, num_out,
                                oskar_mem_double_const(x_out, status),
                                oskar_mem_double_const(y_out, status),
                                oskar_mem_double_const(z_out, status),
                                oskar_mem_double2_const(data, status),
                                offset_out,
                                oskar_mem_double2(output, status), 0);
                    else
                        dftw_c2c_3d_float(num_in, (float)wavenumber,
                                oskar_mem_float2_const(weights_in, status),
                                oskar_mem_float_const(x_in, status),
                                oskar_mem_float_const(y_in, status),
                                oskar_mem_float_const(z_in, status),
                                offset_coord_out, num_out,
                                oskar_mem_float_const(x_out, status),
                                oskar_mem_float_const(y_out, status),
                                oskar_mem_float_const(z_out, status),
                                oskar_mem_float2_const(data, status),
                                offset_out,
                                oskar_mem_float2(output, status), 0);
                }
                else
                {
                    if (is_dbl)
                        dftw_c2c_2d_double(num_in, wavenumber,
                                oskar_mem_double2_const(weights_in, status),
                                oskar_mem_double_const(x_in, status),
                                oskar_mem_double_const(y_in, status), 0,
                                offset_coord_out, num_out,
                                oskar_mem_double_const(x_out, status),
                                oskar_mem_double_const(y_out, status), 0,
                                oskar_mem_double2_const(data, status),
                                offset_out,
                                oskar_mem_double2(output, status), 0);
                    else
                        dftw_c2c_2d_float(num_in, (float)wavenumber,
                                oskar_mem_float2_const(weights_in, status),
                                oskar_mem_float_const(x_in, status),
                                oskar_mem_float_const(y_in, status), 0,
                                offset_coord_out, num_out,
                                oskar_mem_float_const(x_out, status),
                                oskar_mem_float_const(y_out, status), 0,
                                oskar_mem_float2_const(data, status),
                                offset_out,
                                oskar_mem_float2(output, status), 0);
                }
            }
        }
        else
        {
            if (is_3d)
            {
                if (is_dbl)
                    dftw_o2c_3d_double(num_in, wavenumber,
                            oskar_mem_double2_const(weights_in, status),
                            oskar_mem_double_const(x_in, status),
                            oskar_mem_double_const(y_in, status),
                            oskar_mem_double_const(z_in, status),
                            offset_coord_out, num_out,
                            oskar_mem_double_const(x_out, status),
                            oskar_mem_double_const(y_out, status),
                            oskar_mem_double_const(z_out, status),
                            0, offset_out,
                            oskar_mem_double2(output, status), 0);
                else
                    dftw_o2c_3d_float(num_in, (float)wavenumber,
                            oskar_mem_float2_const(weights_in, status),
                            oskar_mem_float_const(x_in, status),
                            oskar_mem_float_const(y_in, status),
                            oskar_mem_float_const(z_in, status),
                            offset_coord_out, num_out,
                            oskar_mem_float_const(x_out, status),
                            oskar_mem_float_const(y_out, status),
                            oskar_mem_float_const(z_out, status),
                            0, offset_out,
                            oskar_mem_float2(output, status), 0);
            }
            else
            {
                if (is_dbl)
                    dftw_o2c_2d_double(num_in, wavenumber,
                            oskar_mem_double2_const(weights_in, status),
                            oskar_mem_double_const(x_in, status),
                            oskar_mem_double_const(y_in, status), 0,
                            offset_coord_out, num_out,
                            oskar_mem_double_const(x_out, status),
                            oskar_mem_double_const(y_out, status), 0,
                            0, offset_out,
                            oskar_mem_double2(output, status), 0);
                else
                    dftw_o2c_2d_float(num_in, (float)wavenumber,
                            oskar_mem_float2_const(weights_in, status),
                            oskar_mem_float_const(x_in, status),
                            oskar_mem_float_const(y_in, status), 0,
                            offset_coord_out, num_out,
                            oskar_mem_float_const(x_out, status),
                            oskar_mem_float_const(y_out, status), 0,
                            0, offset_out,
                            oskar_mem_float2(output, status), 0);
            }
        }
    }
    else
    {
        size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1};
        const void* np = 0;
        const char* k = 0;
        int max_in_chunk;
        float wavenumber_f = (float) wavenumber;

        /* Select the kernel. */
        switch (is_dbl * DBL | is_3d * D3 | is_data * DAT | is_matrix * MAT)
        {
        case D2 | FLT:             k = "dftw_o2c_2d_float";  break;
        case D2 | DBL:             k = "dftw_o2c_2d_double"; break;
        case D3 | FLT:             k = "dftw_o2c_3d_float";  break;
        case D3 | DBL:             k = "dftw_o2c_3d_double"; break;
        case D2 | FLT | DAT:       k = "dftw_c2c_2d_float";  break;
        case D2 | DBL | DAT:       k = "dftw_c2c_2d_double"; break;
        case D3 | FLT | DAT:       k = "dftw_c2c_3d_float";  break;
        case D3 | DBL | DAT:       k = "dftw_c2c_3d_double"; break;
        case D2 | FLT | DAT | MAT: k = "dftw_m2m_2d_float";  break;
        case D2 | DBL | DAT | MAT: k = "dftw_m2m_2d_double"; break;
        case D3 | FLT | DAT | MAT: k = "dftw_m2m_3d_float";  break;
        case D3 | DBL | DAT | MAT: k = "dftw_m2m_3d_double"; break;
        default:
            *status = OSKAR_ERR_FUNCTION_NOT_AVAILABLE;
            return;
        }
        if (oskar_device_is_nv(location))
            local_size[0] = (size_t) get_block_size(num_out);
        oskar_device_check_local_size(location, 0, local_size);
        global_size[0] = oskar_device_global_size(
                (size_t) num_out, local_size[0]);

        /* max_in_chunk must be multiple of 16. */
        max_in_chunk = is_3d ? (is_dbl ? 384 : 800) : (is_dbl ? 448 : 896);
        if (is_data && is_3d && !is_dbl) max_in_chunk = 768;
        const size_t element_size = is_dbl ? sizeof(double) : sizeof(float);
        const size_t local_mem_size = max_in_chunk * element_size;
        const size_t arg_size_local[] = {
                2 * local_mem_size, 2 * local_mem_size,
                (is_3d ? local_mem_size : 0)
        };

        /* Set kernel arguments. */
        const oskar_Arg args[] = {
                {INT_SZ, &num_in},
                {is_dbl ? DBL_SZ : FLT_SZ,
                        is_dbl ? (void*)&wavenumber : (void*)&wavenumber_f},
                {PTR_SZ, oskar_mem_buffer_const(weights_in)},
                {PTR_SZ, oskar_mem_buffer_const(x_in)},
                {PTR_SZ, oskar_mem_buffer_const(y_in)},
                {PTR_SZ, is_3d ? oskar_mem_buffer_const(z_in) : &np},
                {INT_SZ, &offset_coord_out},
                {INT_SZ, &num_out},
                {PTR_SZ, oskar_mem_buffer_const(x_out)},
                {PTR_SZ, oskar_mem_buffer_const(y_out)},
                {PTR_SZ, is_3d ? oskar_mem_buffer_const(z_out) : &np},
                {PTR_SZ, is_data ? oskar_mem_buffer_const(data) : &np},
                {INT_SZ, &offset_out},
                {PTR_SZ, oskar_mem_buffer(output)},
                {INT_SZ, &max_in_chunk}
        };
        oskar_device_launch_kernel(k, location, 1, local_size, global_size,
                sizeof(args) / sizeof(oskar_Arg), args,
                sizeof(arg_size_local) / sizeof(size_t), arg_size_local,
                status);
    }
    if (normalise)
        oskar_mem_scale_real(output, 1. / num_in, offset_out, num_out, status);
}
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);
    }
}
void oskar_evaluate_element_weights_dft(int num_elements,
        const oskar_Mem* x, const oskar_Mem* y, const oskar_Mem* z,
        double wavenumber, double x_beam, double y_beam, double z_beam,
        oskar_Mem* weights, int* status)
{
    if (*status) return;
    const int location = oskar_mem_location(weights);
    const int type = oskar_mem_type(weights);
    const int precision = oskar_mem_precision(weights);
    if (oskar_mem_location(x) != location ||
            oskar_mem_location(y) != location ||
            oskar_mem_location(z) != location)
    {
        *status = OSKAR_ERR_LOCATION_MISMATCH;
        return;
    }
    if (oskar_mem_type(x) != precision || oskar_mem_type(y) != precision ||
            oskar_mem_type(z) != precision)
    {
        *status = OSKAR_ERR_TYPE_MISMATCH;
        return;
    }
    if ((int)oskar_mem_length(weights) < num_elements ||
            (int)oskar_mem_length(x) < num_elements ||
            (int)oskar_mem_length(y) < num_elements ||
            (int)oskar_mem_length(z) < num_elements)
    {
        *status = OSKAR_ERR_DIMENSION_MISMATCH;
        return;
    }
    if (location == OSKAR_CPU)
    {
        if (type == OSKAR_DOUBLE_COMPLEX)
            evaluate_element_weights_dft_d(num_elements,
                    oskar_mem_double_const(x, status),
                    oskar_mem_double_const(y, status),
                    oskar_mem_double_const(z, status),
                    wavenumber, x_beam, y_beam, z_beam,
                    oskar_mem_double2(weights, status));
        else if (type == OSKAR_SINGLE_COMPLEX)
            evaluate_element_weights_dft_f(num_elements,
                    oskar_mem_float_const(x, status),
                    oskar_mem_float_const(y, status),
                    oskar_mem_float_const(z, status),
                    wavenumber, x_beam, y_beam, z_beam,
                    oskar_mem_float2(weights, status));
        else
            *status = OSKAR_ERR_BAD_DATA_TYPE;
    }
    else
    {
        size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1};
        const char* k = 0;
        const int is_dbl = oskar_mem_is_double(weights);
        if (type == OSKAR_DOUBLE_COMPLEX)
            k = "evaluate_element_weights_dft_double";
        else if (type == OSKAR_SINGLE_COMPLEX)
            k = "evaluate_element_weights_dft_float";
        else
        {
            *status = OSKAR_ERR_BAD_DATA_TYPE;
            return;
        }
        const float w = (float) wavenumber;
        const float x1 = (float) x_beam;
        const float y1 = (float) y_beam;
        const float z1 = (float) z_beam;
        oskar_device_check_local_size(location, 0, local_size);
        global_size[0] = oskar_device_global_size(
                (size_t) num_elements, local_size[0]);
        const oskar_Arg args[] = {
                {INT_SZ, &num_elements},
                {PTR_SZ, oskar_mem_buffer_const(x)},
                {PTR_SZ, oskar_mem_buffer_const(y)},
                {PTR_SZ, oskar_mem_buffer_const(z)},
                {is_dbl ? DBL_SZ : FLT_SZ,
                        is_dbl ? (const void*)&wavenumber : (const void*)&w},
                {is_dbl ? DBL_SZ : FLT_SZ,
                        is_dbl ? (const void*)&x_beam : (const void*)&x1},
                {is_dbl ? DBL_SZ : FLT_SZ,
                        is_dbl ? (const void*)&y_beam : (const void*)&y1},
                {is_dbl ? DBL_SZ : FLT_SZ,
                        is_dbl ? (const void*)&z_beam : (const void*)&z1},
                {PTR_SZ, oskar_mem_buffer(weights)}
        };
        oskar_device_launch_kernel(k, location, 1, local_size, global_size,
                sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status);
    }
}
void oskar_mem_save_ascii(FILE* file, size_t num_mem,
        size_t offset, size_t num_elements, int* status, ...)
{
    int type;
    size_t i, j;
    va_list args;
    oskar_Mem** handles; /* Array of oskar_Mem pointers in CPU memory. */

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

    /* Check there are at least the number of specified elements in
     * each array. */
    va_start(args, status);
    for (i = 0; i < num_mem; ++i)
    {
        const oskar_Mem* mem;
        mem = va_arg(args, const oskar_Mem*);
        if (oskar_mem_length(mem) < num_elements)
            *status = OSKAR_ERR_DIMENSION_MISMATCH;
    }
    va_end(args);

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

    /* Allocate and set up the handle array. */
    handles = (oskar_Mem**) malloc(num_mem * sizeof(oskar_Mem*));
    va_start(args, status);
    for (i = 0; i < num_mem; ++i)
    {
        oskar_Mem* mem;
        mem = va_arg(args, oskar_Mem*);
        if (oskar_mem_location(mem) != OSKAR_CPU)
        {
            handles[i] = oskar_mem_create_copy(mem, OSKAR_CPU, status);
        }
        else
        {
            handles[i] = mem;
        }
    }
    va_end(args);

    for (j = 0; j < num_elements; ++j)
    {
        /* Break if error. */
        if (*status) break;

        for (i = 0; i < num_mem; ++i)
        {
            const void* data;
            data = oskar_mem_void_const(handles[i]);
            type = oskar_mem_type(handles[i]);
            switch (type)
            {
            case OSKAR_SINGLE:
            {
                fprintf(file, SDF, ((const float*)data)[j + offset]);
                continue;
            }
            case OSKAR_DOUBLE:
            {
                fprintf(file, SDD, ((const double*)data)[j + offset]);
                continue;
            }
            case OSKAR_SINGLE_COMPLEX:
            {
                float2 d;
                d = ((const float2*)data)[j + offset];
                fprintf(file, SDF SDF, d.x, d.y);
                continue;
            }
            case OSKAR_DOUBLE_COMPLEX:
            {
                double2 d;
                d = ((const double2*)data)[j + offset];
                fprintf(file, SDD SDD, d.x, d.y);
                continue;
            }
            case OSKAR_SINGLE_COMPLEX_MATRIX:
            {
                float4c d;
                d = ((const float4c*)data)[j + offset];
                fprintf(file, SDF SDF SDF SDF SDF SDF SDF SDF,
                        d.a.x, d.a.y, d.b.x, d.b.y, d.c.x, d.c.y, d.d.x, d.d.y);
                continue;
            }
            case OSKAR_DOUBLE_COMPLEX_MATRIX:
            {
                double4c d;
                d = ((const double4c*)data)[j + offset];
                fprintf(file, SDD SDD SDD SDD SDD SDD SDD SDD,
                        d.a.x, d.a.y, d.b.x, d.b.y, d.c.x, d.c.y, d.d.x, d.d.y);
                continue;
            }
            case OSKAR_CHAR:
            {
                putc(((const char*)data)[j + offset], file);
                continue;
            }
            case OSKAR_INT:
            {
                fprintf(file, "%5d ", ((const int*)data)[j + offset]);
                continue;
            }
            default:
            {
                *status = OSKAR_ERR_BAD_DATA_TYPE;
                continue;
            }
            }
        }
        putc('\n', file);
    }

    /* Free any temporary memory used by this function. */
    va_start(args, status);
    for (i = 0; i < num_mem; ++i)
    {
        const oskar_Mem* mem;
        mem = va_arg(args, const oskar_Mem*);
        if (oskar_mem_location(mem) != OSKAR_CPU)
        {
            oskar_mem_free(handles[i], status);
        }
    }
    va_end(args);

    /* Free the handle array. */
    free(handles);
}
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_);
            }
        }
    }
}
Exemple #18
0
/* Wrapper. */
void oskar_convert_enu_directions_to_theta_phi(int num_points,
        const oskar_Mem* x, const oskar_Mem* y, const oskar_Mem* z,
        double delta_phi, oskar_Mem* theta, oskar_Mem* phi, int* status)
{
    int type, location;

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

    /* Get data type and location. */
    type = oskar_mem_type(theta);
    location = oskar_mem_location(theta);

    /* Compute modified theta and phi coordinates. */
    if (location == OSKAR_GPU)
    {
#ifdef OSKAR_HAVE_CUDA
        if (type == OSKAR_SINGLE)
        {
            oskar_convert_enu_directions_to_theta_phi_cuda_f(num_points,
                    oskar_mem_float_const(x, status),
                    oskar_mem_float_const(y, status),
                    oskar_mem_float_const(z, status), (float)delta_phi,
                    oskar_mem_float(theta, status),
                    oskar_mem_float(phi, status));
            oskar_device_check_error(status);
        }
        else if (type == OSKAR_DOUBLE)
        {
            oskar_convert_enu_directions_to_theta_phi_cuda_d(num_points,
                    oskar_mem_double_const(x, status),
                    oskar_mem_double_const(y, status),
                    oskar_mem_double_const(z, status), delta_phi,
                    oskar_mem_double(theta, status),
                    oskar_mem_double(phi, status));
            oskar_device_check_error(status);
        }
        else
            *status = OSKAR_ERR_BAD_DATA_TYPE;
#else
        *status = OSKAR_ERR_CUDA_NOT_AVAILABLE;
#endif
    }
    else if (location == OSKAR_CPU)
    {
        if (type == OSKAR_SINGLE)
        {
            oskar_convert_enu_directions_to_theta_phi_f(num_points,
                    oskar_mem_float_const(x, status),
                    oskar_mem_float_const(y, status),
                    oskar_mem_float_const(z, status), (float)delta_phi,
                    oskar_mem_float(theta, status),
                    oskar_mem_float(phi, status));
        }
        else if (type == OSKAR_DOUBLE)
        {
            oskar_convert_enu_directions_to_theta_phi_d(num_points,
                    oskar_mem_double_const(x, status),
                    oskar_mem_double_const(y, status),
                    oskar_mem_double_const(z, status), delta_phi,
                    oskar_mem_double(theta, status),
                    oskar_mem_double(phi, status));
        }
        else
            *status = OSKAR_ERR_BAD_DATA_TYPE;
    }
}
int oskar_sph_rotate_to_position(int n, oskar_Mem* lon, oskar_Mem* lat,
        double lon0, double lat0)
{
    int i;

    if (lon == NULL || lat == NULL)
        return OSKAR_ERR_INVALID_ARGUMENT;

    if (oskar_mem_location(lon) != OSKAR_CPU || oskar_mem_location(lat) != OSKAR_CPU)
        return OSKAR_ERR_BAD_LOCATION;

    if (oskar_mem_type(lon) == OSKAR_DOUBLE && oskar_mem_type(lat) == OSKAR_DOUBLE)
    {
        /* Construct rotation matrix. */
        double cosLon, sinLon, cosLat, sinLat;
        double m11, m12, m13, m21, m22, m23, m31, m33;
        cosLon = cos(lon0);
        sinLon = sin(lon0);
        cosLat = cos(lat0);
        sinLat = sin(lat0);
        m11 = cosLon * sinLat; m12 = -sinLon; m13 = cosLon * cosLat;
        m21 = sinLon * sinLat; m22 =  cosLon; m23 = sinLon * cosLat;
        m31 = -cosLat; m33 = sinLat;

        for (i = 0; i < n; ++i)
        {
            double x, y, z, a, b, c;

            /* Direction cosines */
            c = cos(((double*)lat->data)[i]);
            x = c * cos(((double*)lon->data)[i]);
            y = c * sin(((double*)lon->data)[i]);
            z = sin(((double*)lat->data)[i]);

            /* Apply rotation matrix */
            a = m11 * x + m12 * y + m13 * z;
            b = m21 * x + m22 * y + m23 * z;
            c = m31 * x + m33 * z;

            /* Convert back to angles. */
            ((double*)lon->data)[i] = atan2(b, a);
            ((double*)lat->data)[i] = atan2(c, sqrt(a*a + b*b));
        }
    }
    else if (oskar_mem_type(lon) == OSKAR_SINGLE && oskar_mem_type(lat) == OSKAR_SINGLE)
    {
        /* Construct rotation matrix. */
        float cosLon, sinLon, cosLat, sinLat;
        float m11, m12, m13, m21, m22, m23, m31, m33;
        cosLon = cosf(lon0);
        sinLon = sinf(lon0);
        cosLat = cosf(lat0);
        sinLat = sinf(lat0);
        m11 = cosLon * sinLat; m12 = -sinLon; m13 = cosLon * cosLat;
        m21 = sinLon * sinLat; m22 =  cosLon; m23 = sinLon * cosLat;
        m31 = -cosLat; m33 = sinLat;

        for (i = 0; i < n; ++i)
        {
            float x, y, z, a, b, c;

            /* Direction cosines */
            c = cosf(((float*)lat->data)[i]);
            x = c * cosf(((float*)lon->data)[i]);
            y = c * sinf(((float*)lon->data)[i]);
            z = sinf(((float*)lat->data)[i]);

            /* Apply rotation matrix */
            a = m11 * x + m12 * y + m13 * z;
            b = m21 * x + m22 * y + m23 * z;
            c = m31 * x + m33 * z;

            /* Convert back to angles. */
            ((float*)lon->data)[i] = atan2f(b, a);
            ((float*)lat->data)[i] = atan2f(c, sqrtf(a*a + b*b));
        }
    }
    else
    {
        return OSKAR_ERR_BAD_DATA_TYPE;
    }

    return 0;
}
/* Wrapper. */
void oskar_convert_ludwig3_to_theta_phi_components(oskar_Mem* vec,
        int offset, int stride, int num_points, const oskar_Mem* phi,
        int* status)
{
    int type, location;

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

    /* Check that the vector component data is in matrix form. */
    if (!oskar_mem_is_matrix(vec))
    {
        *status = OSKAR_ERR_TYPE_MISMATCH;
        return;
    }

    /* Get data type and location. */
    type = oskar_mem_type(phi);
    location = oskar_mem_location(phi);

    /* Convert vector representation from Ludwig-3 to spherical. */
    if (type == OSKAR_SINGLE)
    {
        float2 *h_theta, *v_phi;
        const float *phi_;
        h_theta = oskar_mem_float2(vec, status) + offset;
        v_phi = oskar_mem_float2(vec, status) + offset + 1;
        phi_ = oskar_mem_float_const(phi, status);

        if (location == OSKAR_GPU)
        {
#ifdef OSKAR_HAVE_CUDA
            oskar_convert_ludwig3_to_theta_phi_components_cuda_f(num_points,
                    h_theta, v_phi, phi_, stride);
            oskar_device_check_error(status);
#else
            *status = OSKAR_ERR_CUDA_NOT_AVAILABLE;
#endif
        }
        else if (location == OSKAR_CPU)
        {
            oskar_convert_ludwig3_to_theta_phi_components_f(num_points,
                    h_theta, v_phi, phi_, stride);
        }
    }
    else if (type == OSKAR_DOUBLE)
    {
        double2 *h_theta, *v_phi;
        const double *phi_;
        h_theta = oskar_mem_double2(vec, status) + offset;
        v_phi = oskar_mem_double2(vec, status) + offset + 1;
        phi_ = oskar_mem_double_const(phi, status);

        if (location == OSKAR_GPU)
        {
#ifdef OSKAR_HAVE_CUDA
            oskar_convert_ludwig3_to_theta_phi_components_cuda_d(num_points,
                    h_theta, v_phi, phi_, stride);
            oskar_device_check_error(status);
#else
            *status = OSKAR_ERR_CUDA_NOT_AVAILABLE;
#endif
        }
        else if (location == OSKAR_CPU)
        {
            oskar_convert_ludwig3_to_theta_phi_components_d(num_points,
                    h_theta, v_phi, phi_, stride);
        }
    }
    else
        *status = OSKAR_ERR_BAD_DATA_TYPE;
}
/* Wrapper. */
void oskar_convert_ecef_to_station_uvw(int num_stations, const oskar_Mem* x,
        const oskar_Mem* y, const oskar_Mem* z, double ra0_rad,
        double dec0_rad, double gast, oskar_Mem* u, oskar_Mem* v,
        oskar_Mem* w, int* status)
{
    int type, location;
    double ha0_rad;

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

    /* Get data type and location of the input coordinates. */
    type = oskar_mem_type(x);
    location = oskar_mem_location(x);

    /* Check that the memory is allocated. */
    if (!oskar_mem_allocated(u) || !oskar_mem_allocated(v) ||
            !oskar_mem_allocated(w) || !oskar_mem_allocated(x) ||
            !oskar_mem_allocated(y) || !oskar_mem_allocated(z))
    {
        *status = OSKAR_ERR_MEMORY_NOT_ALLOCATED;
        return;
    }

    /* Check that the data dimensions are OK. */
    if ((int)oskar_mem_length(u) < num_stations ||
            (int)oskar_mem_length(v) < num_stations ||
            (int)oskar_mem_length(w) < num_stations ||
            (int)oskar_mem_length(x) < num_stations ||
            (int)oskar_mem_length(y) < num_stations ||
            (int)oskar_mem_length(z) < num_stations)
    {
        *status = OSKAR_ERR_DIMENSION_MISMATCH;
        return;
    }

    /* Check that the data are in the right location. */
    if (oskar_mem_location(y) != location ||
            oskar_mem_location(z) != location ||
            oskar_mem_location(u) != location ||
            oskar_mem_location(v) != location ||
            oskar_mem_location(w) != location)
    {
        *status = OSKAR_ERR_BAD_LOCATION;
        return;
    }

    /* Check that the data is of the right type. */
    if (oskar_mem_type(y) != type || oskar_mem_type(z) != type ||
            oskar_mem_type(u) != type || oskar_mem_type(v) != type ||
            oskar_mem_type(w) != type)
    {
        *status = OSKAR_ERR_TYPE_MISMATCH;
        return;
    }

    /* Evaluate Greenwich Hour Angle of phase centre. */
    ha0_rad = gast - ra0_rad;

    /* Evaluate station u,v,w coordinates. */
    if (location == OSKAR_GPU)
    {
#ifdef OSKAR_HAVE_CUDA
        if (type == OSKAR_SINGLE)
        {
            oskar_convert_ecef_to_station_uvw_cuda_f(num_stations,
                    oskar_mem_float_const(x, status),
                    oskar_mem_float_const(y, status),
                    oskar_mem_float_const(z, status),
                    (float)ha0_rad, (float)dec0_rad,
                    oskar_mem_float(u, status),
                    oskar_mem_float(v, status),
                    oskar_mem_float(w, status));
        }
        else if (type == OSKAR_DOUBLE)
        {
            oskar_convert_ecef_to_station_uvw_cuda_d(num_stations,
                    oskar_mem_double_const(x, status),
                    oskar_mem_double_const(y, status),
                    oskar_mem_double_const(z, status),
                    ha0_rad, dec0_rad,
                    oskar_mem_double(u, status),
                    oskar_mem_double(v, status),
                    oskar_mem_double(w, status));
        }
        else
        {
            *status = OSKAR_ERR_BAD_DATA_TYPE;
        }
        oskar_device_check_error(status);
#else
        *status = OSKAR_ERR_CUDA_NOT_AVAILABLE;
#endif
    }
    else if (location == OSKAR_CPU)
    {
        if (type == OSKAR_SINGLE)
        {
            oskar_convert_ecef_to_station_uvw_f(num_stations,
                    oskar_mem_float_const(x, status),
                    oskar_mem_float_const(y, status),
                    oskar_mem_float_const(z, status),
                    (float)ha0_rad, (float)dec0_rad,
                    oskar_mem_float(u, status),
                    oskar_mem_float(v, status),
                    oskar_mem_float(w, status));
        }
        else if (type == OSKAR_DOUBLE)
        {
            oskar_convert_ecef_to_station_uvw_d(num_stations,
                    oskar_mem_double_const(x, status),
                    oskar_mem_double_const(y, status),
                    oskar_mem_double_const(z, status),
                    ha0_rad, dec0_rad,
                    oskar_mem_double(u, status),
                    oskar_mem_double(v, status),
                    oskar_mem_double(w, status));
        }
        else
        {
            *status = OSKAR_ERR_BAD_DATA_TYPE;
        }
    }
    else
    {
        *status = OSKAR_ERR_BAD_LOCATION;
    }
}
Exemple #22
0
/* 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);
        }
    }
}
void oskar_evaluate_vla_beam_pbcor(oskar_Mem* beam, int num_sources,
        const oskar_Mem* l, const oskar_Mem* m, double frequency_hz,
        int* status)
{
    int index, precision, type, location;
    double f, p1, p2, p3;

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

    /* Check type and location. */
    precision = oskar_mem_precision(beam);
    type = oskar_mem_type(beam);
    location = oskar_mem_location(beam);
    if (precision != oskar_mem_type(l) || precision != oskar_mem_type(m))
    {
        *status = OSKAR_ERR_TYPE_MISMATCH;
        return;
    }
    if (location != oskar_mem_location(l) || location != oskar_mem_location(m))
    {
        *status = OSKAR_ERR_LOCATION_MISMATCH;
        return;
    }

    /* Find the nearest frequency at which data exists. */
    index = oskar_find_closest_match_d(frequency_hz / 1.0e9,
            sizeof(freqs_ghz) / sizeof(double), freqs_ghz);
    f = frequency_hz / 1.0e9;
    p1 = p1s[index];
    p2 = p2s[index];
    p3 = p3s[index];

    /* Switch on precision. */
    if (precision == OSKAR_SINGLE)
    {
        const float *l_, *m_;
        l_ = oskar_mem_float_const(l, status);
        m_ = oskar_mem_float_const(m, status);

        if (location == OSKAR_GPU)
        {
#ifdef OSKAR_HAVE_CUDA
            if (type == OSKAR_SINGLE)
            {
                oskar_evaluate_vla_beam_pbcor_cuda_f(
                        oskar_mem_float(beam, status),
                        num_sources, l_, m_, f, p1, p2, p3);
            }
            else if (type == OSKAR_SINGLE_COMPLEX)
            {
                oskar_evaluate_vla_beam_pbcor_complex_cuda_f(
                        oskar_mem_float2(beam, status),
                        num_sources, l_, m_, f, p1, p2, p3);
            }
            else if (type == OSKAR_SINGLE_COMPLEX_MATRIX)
            {
                oskar_evaluate_vla_beam_pbcor_matrix_cuda_f(
                        oskar_mem_float4c(beam, status),
                        num_sources, l_, m_, f, p1, p2, p3);
            }
            oskar_device_check_error(status);
#else
            *status = OSKAR_ERR_CUDA_NOT_AVAILABLE;
#endif
        }
        else if (location == OSKAR_CPU)
        {
            if (type == OSKAR_SINGLE)
            {
                oskar_evaluate_vla_beam_pbcor_f(
                        oskar_mem_float(beam, status),
                        num_sources, l_, m_, f, p1, p2, p3);
            }
            else if (type == OSKAR_SINGLE_COMPLEX)
            {
                oskar_evaluate_vla_beam_pbcor_complex_f(
                        oskar_mem_float2(beam, status),
                        num_sources, l_, m_, f, p1, p2, p3);
            }
            else if (type == OSKAR_SINGLE_COMPLEX_MATRIX)
            {
                oskar_evaluate_vla_beam_pbcor_matrix_f(
                        oskar_mem_float4c(beam, status),
                        num_sources, l_, m_, f, p1, p2, p3);
            }
        }
    }
    else if (precision == OSKAR_DOUBLE)
    {
        const double *l_, *m_;
        l_ = oskar_mem_double_const(l, status);
        m_ = oskar_mem_double_const(m, status);

        if (location == OSKAR_GPU)
        {
#ifdef OSKAR_HAVE_CUDA
            if (type == OSKAR_DOUBLE)
            {
                oskar_evaluate_vla_beam_pbcor_cuda_d(
                        oskar_mem_double(beam, status),
                        num_sources, l_, m_, f, p1, p2, p3);
            }
            else if (type == OSKAR_DOUBLE_COMPLEX)
            {
                oskar_evaluate_vla_beam_pbcor_complex_cuda_d(
                        oskar_mem_double2(beam, status),
                        num_sources, l_, m_, f, p1, p2, p3);
            }
            else if (type == OSKAR_DOUBLE_COMPLEX_MATRIX)
            {
                oskar_evaluate_vla_beam_pbcor_matrix_cuda_d(
                        oskar_mem_double4c(beam, status),
                        num_sources, l_, m_, f, p1, p2, p3);
            }
            oskar_device_check_error(status);
#else
            *status = OSKAR_ERR_CUDA_NOT_AVAILABLE;
#endif
        }
        else if (location == OSKAR_CPU)
        {
            if (type == OSKAR_DOUBLE)
            {
                oskar_evaluate_vla_beam_pbcor_d(
                        oskar_mem_double(beam, status),
                        num_sources, l_, m_, f, p1, p2, p3);
            }
            else if (type == OSKAR_DOUBLE_COMPLEX)
            {
                oskar_evaluate_vla_beam_pbcor_complex_d(
                        oskar_mem_double2(beam, status),
                        num_sources, l_, m_, f, p1, p2, p3);
            }
            else if (type == OSKAR_DOUBLE_COMPLEX_MATRIX)
            {
                oskar_evaluate_vla_beam_pbcor_matrix_d(
                        oskar_mem_double4c(beam, status),
                        num_sources, l_, m_, f, p1, p2, p3);
            }
        }
    }
    else
    {
        *status = OSKAR_ERR_BAD_DATA_TYPE;
    }
}
Exemple #24
0
void oskar_evaluate_station_beam_gaussian(oskar_Mem* beam,
        int num_points, const oskar_Mem* l, const oskar_Mem* m,
        const oskar_Mem* horizon_mask, double fwhm_rad, int* status)
{
    int type, location;
    double fwhm_lm, std;

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

    /* Get type and check consistency. */
    type = oskar_mem_precision(beam);
    if (type != oskar_mem_type(l) || type != oskar_mem_type(m))
    {
        *status = OSKAR_ERR_TYPE_MISMATCH;
        return;
    }
    if (type != OSKAR_SINGLE && type != OSKAR_DOUBLE)
    {
        *status = OSKAR_ERR_BAD_DATA_TYPE;
        return;
    }
    if (!oskar_mem_is_complex(beam))
    {
        *status = OSKAR_ERR_BAD_DATA_TYPE;
        return;
    }

    if (fwhm_rad == 0.0)
    {
        *status = OSKAR_ERR_SETTINGS_TELESCOPE;
        return;
    }

    /* Get location and check consistency. */
    location = oskar_mem_location(beam);
    if (location != oskar_mem_location(l) ||
            location != oskar_mem_location(m))
    {
        *status = OSKAR_ERR_LOCATION_MISMATCH;
        return;
    }

    /* Check that length of input arrays are consistent. */
    if ((int)oskar_mem_length(l) < num_points ||
            (int)oskar_mem_length(m) < num_points)
    {
        *status = OSKAR_ERR_DIMENSION_MISMATCH;
        return;
    }

    /* Resize output array if needed. */
    if ((int)oskar_mem_length(beam) < num_points)
        oskar_mem_realloc(beam, num_points, status);

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

    /* Compute Gaussian standard deviation from FWHM. */
    fwhm_lm = sin(fwhm_rad);
    std = fwhm_lm / (2.0 * sqrt(2.0 * log(2.0)));

    if (type == OSKAR_DOUBLE)
    {
        const double *l_, *m_;
        l_ = oskar_mem_double_const(l, status);
        m_ = oskar_mem_double_const(m, status);

        if (location == OSKAR_CPU)
        {
            if (oskar_mem_is_scalar(beam))
            {
                oskar_gaussian_d(oskar_mem_double2(beam, status),
                        num_points, l_, m_, std);
            }
            else
            {
                oskar_gaussian_md(oskar_mem_double4c(beam, status),
                        num_points, l_, m_, std);
            }
        }
        else
        {
#ifdef OSKAR_HAVE_CUDA
            if (oskar_mem_is_scalar(beam))
            {
                oskar_gaussian_cuda_d(oskar_mem_double2(beam, status),
                        num_points, l_, m_, std);
            }
            else
            {
                oskar_gaussian_cuda_md(oskar_mem_double4c(beam, status),
                        num_points, l_, m_, std);
            }
            oskar_device_check_error(status);
#else
            *status = OSKAR_ERR_CUDA_NOT_AVAILABLE;
#endif
        }
    }
    else /* type == OSKAR_SINGLE */
    {
        const float *l_, *m_;
        l_ = oskar_mem_float_const(l, status);
        m_ = oskar_mem_float_const(m, status);

        if (location == OSKAR_CPU)
        {
            if (oskar_mem_is_scalar(beam))
            {
                oskar_gaussian_f(oskar_mem_float2(beam, status), num_points,
                        l_, m_, (float)std);
            }
            else
            {
                oskar_gaussian_mf(oskar_mem_float4c(beam, status), num_points,
                        l_, m_, (float)std);
            }
        }
        else
        {
#ifdef OSKAR_HAVE_CUDA
            if (oskar_mem_is_scalar(beam))
            {
                oskar_gaussian_cuda_f(oskar_mem_float2(beam, status),
                        num_points, l_, m_, (float)std);
            }
            else
            {
                oskar_gaussian_cuda_mf(oskar_mem_float4c(beam, status),
                        num_points, l_, m_, (float)std);
            }
            oskar_device_check_error(status);
#else
            *status = OSKAR_ERR_CUDA_NOT_AVAILABLE;
#endif
        }
    }

    /* Blank (zero) sources below the horizon. */
    oskar_blank_below_horizon(beam, horizon_mask, num_points, status);
}
Exemple #25
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);
}