1 /*
2  * Copyright (c) 2013-2021, The OSKAR Developers.
3  * See the LICENSE file at the top-level directory of this distribution.
4  */
5 
6 #include "convert/define_convert_enu_directions_to_relative_directions.h"
7 #include "convert/oskar_convert_enu_directions_to_relative_directions.h"
8 #include "utility/oskar_device.h"
9 #include "utility/oskar_kernel_macros.h"
10 
11 #ifdef __cplusplus
12 extern "C" {
13 #endif
14 
OSKAR_CONVERT_ENU_DIR_TO_REL_DIR(convert_enu_directions_to_relative_directions_float,float)15 OSKAR_CONVERT_ENU_DIR_TO_REL_DIR(convert_enu_directions_to_relative_directions_float, float)
16 OSKAR_CONVERT_ENU_DIR_TO_REL_DIR(convert_enu_directions_to_relative_directions_double, double)
17 
18 void oskar_convert_enu_directions_to_relative_directions(int offset_in,
19         int num_points, const oskar_Mem* x, const oskar_Mem* y,
20         const oskar_Mem* z, double ha0, double dec0, double lat,
21         int offset_out, oskar_Mem* l, oskar_Mem* m, oskar_Mem* n, int* status)
22 {
23     if (*status) return;
24     const int type = oskar_mem_type(x);
25     const int location = oskar_mem_location(x);
26     const double sin_h0  = sin(ha0),  cos_h0  = cos(ha0);
27     const double sin_d0  = sin(dec0), cos_d0  = cos(dec0);
28     const double sin_lat = sin(lat),  cos_lat = cos(lat);
29     const float sin_h0_f = (float) sin_h0, cos_h0_f = (float) cos_h0;
30     const float sin_d0_f = (float) sin_d0, cos_d0_f = (float) cos_d0;
31     const float sin_lat_f = (float) sin_lat, cos_lat_f = (float) cos_lat;
32     if (type != oskar_mem_type(y) || type != oskar_mem_type(z) ||
33             type != oskar_mem_type(l) || type != oskar_mem_type(m) ||
34             type != oskar_mem_type(n))
35     {
36         *status = OSKAR_ERR_TYPE_MISMATCH;
37         return;
38     }
39     if (location != oskar_mem_location(y) ||
40             location != oskar_mem_location(z) ||
41             location != oskar_mem_location(l) ||
42             location != oskar_mem_location(m) ||
43             location != oskar_mem_location(n))
44     {
45         *status = OSKAR_ERR_LOCATION_MISMATCH;
46         return;
47     }
48     if (location == OSKAR_CPU)
49     {
50         if (type == OSKAR_SINGLE)
51         {
52             convert_enu_directions_to_relative_directions_float(
53                     offset_in, num_points,
54                     oskar_mem_float_const(x, status),
55                     oskar_mem_float_const(y, status),
56                     oskar_mem_float_const(z, status),
57                     sin_h0_f, cos_h0_f, sin_d0_f, cos_d0_f,
58                     sin_lat_f, cos_lat_f, offset_out,
59                     oskar_mem_float(l, status),
60                     oskar_mem_float(m, status),
61                     oskar_mem_float(n, status));
62         }
63         else if (type == OSKAR_DOUBLE)
64         {
65             convert_enu_directions_to_relative_directions_double(
66                     offset_in, num_points,
67                     oskar_mem_double_const(x, status),
68                     oskar_mem_double_const(y, status),
69                     oskar_mem_double_const(z, status),
70                     sin_h0, cos_h0, sin_d0, cos_d0,
71                     sin_lat, cos_lat, offset_out,
72                     oskar_mem_double(l, status),
73                     oskar_mem_double(m, status),
74                     oskar_mem_double(n, status));
75         }
76         else
77         {
78             *status = OSKAR_ERR_BAD_DATA_TYPE;
79         }
80     }
81     else
82     {
83         size_t local_size[] = {256, 1, 1}, global_size[] = {1, 1, 1};
84         const int is_dbl = (type == OSKAR_DOUBLE);
85         const char* k = 0;
86         if (type == OSKAR_SINGLE)
87         {
88             k = "convert_enu_directions_to_relative_directions_float";
89         }
90         else if (type == OSKAR_DOUBLE)
91         {
92             k = "convert_enu_directions_to_relative_directions_double";
93         }
94         else
95         {
96             *status = OSKAR_ERR_BAD_DATA_TYPE;
97             return;
98         }
99         oskar_device_check_local_size(location, 0, local_size);
100         global_size[0] = oskar_device_global_size(
101                 (size_t) num_points, local_size[0]);
102         const oskar_Arg args[] = {
103                 {INT_SZ, &offset_in},
104                 {INT_SZ, &num_points},
105                 {PTR_SZ, oskar_mem_buffer_const(x)},
106                 {PTR_SZ, oskar_mem_buffer_const(y)},
107                 {PTR_SZ, oskar_mem_buffer_const(z)},
108                 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
109                         (const void*)&sin_h0 : (const void*)&sin_h0_f},
110                 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
111                         (const void*)&cos_h0 : (const void*)&cos_h0_f},
112                 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
113                         (const void*)&sin_d0 : (const void*)&sin_d0_f},
114                 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
115                         (const void*)&cos_d0 : (const void*)&cos_d0_f},
116                 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
117                         (const void*)&sin_lat : (const void*)&sin_lat_f},
118                 {is_dbl ? DBL_SZ : FLT_SZ, is_dbl ?
119                         (const void*)&cos_lat : (const void*)&cos_lat_f},
120                 {INT_SZ, &offset_out},
121                 {PTR_SZ, oskar_mem_buffer(l)},
122                 {PTR_SZ, oskar_mem_buffer(m)},
123                 {PTR_SZ, oskar_mem_buffer(n)}
124         };
125         oskar_device_launch_kernel(k, location, 1, local_size, global_size,
126                 sizeof(args) / sizeof(oskar_Arg), args, 0, 0, status);
127     }
128 }
129 
130 #ifdef __cplusplus
131 }
132 #endif
133