COMPASS  5.0.0
End-to-end AO simulation tool using GPU acceleration
carma_utils.h
Go to the documentation of this file.
1 // -----------------------------------------------------------------------------
2 // This file is part of COMPASS <https://anr-compass.github.io/compass/>
3 //
4 // Copyright (C) 2011-2019 COMPASS Team <https://github.com/ANR-COMPASS>
5 // All rights reserved.
6 // Distributed under GNU - LGPL
7 //
8 // COMPASS is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser
9 // General Public License as published by the Free Software Foundation, either version 3 of the License,
10 // or any later version.
11 //
12 // COMPASS: End-to-end AO simulation tool using GPU acceleration
13 // The COMPASS platform was designed to meet the need of high-performance for the simulation of AO systems.
14 //
15 // The final product includes a software package for simulating all the critical subcomponents of AO,
16 // particularly in the context of the ELT and a real-time core based on several control approaches,
17 // with performances consistent with its integration into an instrument. Taking advantage of the specific
18 // hardware architecture of the GPU, the COMPASS tool allows to achieve adequate execution speeds to
19 // conduct large simulation campaigns called to the ELT.
20 //
21 // The COMPASS platform can be used to carry a wide variety of simulations to both testspecific components
22 // of AO of the E-ELT (such as wavefront analysis device with a pyramid or elongated Laser star), and
23 // various systems configurations such as multi-conjugate AO.
24 //
25 // COMPASS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the
26 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
27 // See the GNU Lesser General Public License for more details.
28 //
29 // You should have received a copy of the GNU Lesser General Public License along with COMPASS.
30 // If not, see <https://www.gnu.org/licenses/lgpl-3.0.txt>.
31 // -----------------------------------------------------------------------------
32 
40 
41 
42 #ifndef _CARMA_UTILS_H_
43 #define _CARMA_UTILS_H_
44 
45 #include <stdint.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <string.h>
49 
50 #include <driver_types.h>
51 #include <vector_types.h>
52 #include <chrono>
53 #include <iostream>
54 #include <sstream>
55 #include <string>
56 #include <vector>
57 
58 #include <cuda.h>
59 #include <cuda_fp16.h>
60 #include <cuda_runtime_api.h>
61 #include <cufft.h>
62 
63 #ifdef USE_OCTOPUS
64 #include <Cacao.h>
65 #endif
66 
67 #define CARMA_PI 3.1415926535897932384626433832
68 
69 struct doubleint {
70  int start;
71  int nbInflu;
72 };
73 
74 template <class T>
75 struct tuple_t {
76  int pos;
77  T data;
78 };
79 
80 namespace carma_utils {
81 template <typename T>
82 inline std::string to_string(const T &n) {
83  std::ostringstream stm;
84  stm << n;
85  return stm.str();
86 }
87 template <typename T>
88 inline T from_string(const std::string &myString) {
89  std::istringstream buffer(myString);
90  T value;
91  buffer >> value;
92  return value;
93 }
94 void inline split(std::vector<std::string> &tokens, const std::string &text,
95  char sep) {
96  std::string::size_type start = 0, end = 0;
97  while ((end = text.find(sep, start)) != std::string::npos) {
98  tokens.push_back(text.substr(start, end - start));
99  start = end + 1;
100  }
101  tokens.push_back(text.substr(start));
102 }
103 
104 class ProgressBar {
105  int prev = 0, count = 0, max;
106  int ndigits = 0;
107  double progress = 0;
108  int bar_width = 42;
109  std::string desc;
110  std::chrono::system_clock::time_point start;
111 
112  public:
113  ProgressBar(int i, const std::string &desc = "");
114  void update();
115  void finish();
116 };
117 
118 } // namespace carma_utils
119 
120 #ifdef DEBUG
121 #define DEBUG_TRACE(fmt, args...) \
122  fprintf(stderr, "[%s@%d]: " fmt "\n", __FILE__, __LINE__, ##args)
123 #else
124 #define DEBUG_TRACE(fmt, args...) \
125  fprintf(stderr, "[%s@%d]: " fmt "\n", __FILE__, __LINE__, ##args)
126 #endif
127 
128 #define CAST(type, new_var, var) type new_var = dynamic_cast<type>(var)
129 #define SCAST(type, new_var, var) type new_var = static_cast<type>(var)
130 
131 // We define these calls here, so the user doesn't need to include __FILE__ and
132 // __LINE__ The advantage is the developers gets to use the inline function so
133 // they can debug
134 #ifdef DEBUG
135 #define carma_safe_call_no_sync(err) __carma_safe_call_no_sync(err, __FILE__, __LINE__)
136 #define carma_safe_call(err) __carma_safe_call((err), #err, __FILE__, __LINE__)
137 #define carma_safe_device_synchronize() \
138  __carma_safe_device_synchronize(__FILE__, __LINE__)
139 #define carmafft_safe_call(err) __carmafft_safe_call(err, __FILE__, __LINE__)
140 #define carma_check_msg(msg) __carma_check_msg(msg, __FILE__, __LINE__)
141 #define carma_safe_malloc(mallocCall) \
142  __carma_safe_malloc((mallocCall), __FILE__, __LINE__)
143 #else
144 #define carma_safe_call_no_sync(err) err
145 #define carma_safe_call(err) err
146 #define carma_safe_device_synchronize() cudaDeviceSynchronize()
147 #define carmafft_safe_call(err) err
148 #define cutil_check_error(err) err
149 #define carma_check_msg(msg)
150 #define cutil_safe_malloc(mallocCall) (mallocCall)
151 #endif
152 
153 #ifndef MIN
154 #define MIN(a, b) ((a < b) ? a : b)
155 #endif
156 #ifndef MAX
157 #define MAX(a, b) ((a > b) ? a : b)
158 #endif
159 
160 inline unsigned int next_pow2(unsigned int x) {
161  --x;
162  x |= x >> 1;
163  x |= x >> 2;
164  x |= x >> 4;
165  x |= x >> 8;
166  x |= x >> 16;
167  return ++x;
168 }
169 
170 inline bool is_pow2(unsigned int x) { return ((x & (x - 1)) == 0); }
171 
172 class CarmaDevice;
173 void get_num_blocks_and_threads(CarmaDevice *device, int n, int &blocks,
174  int &threads);
175 void sum_get_num_blocks_and_threads(int n, CarmaDevice *device, int &blocks,
176  int &threads);
177 template <class T_data>
178 int find_nnz(T_data *d_data, int *tmp_colind, int N, int *d_nnz, int &h_nnz,
179  CarmaDevice *device);
180 template <class T_data>
181 int fill_sparse_vect(T_data *dense_data, int *colind_sorted, T_data *values,
182  int *colind, int *rowind, int nnz, CarmaDevice *device);
183 int float_to_double(float *idata, double *odata, int N, CarmaDevice *device);
184 int double_to_float(double *idata, float *odata, int N, CarmaDevice *device);
186 template <typename T_data>
187 int fill_array_with_value(T_data *d_data, T_data value, int N,
188  CarmaDevice *device);
189 
190 #ifdef CAN_DO_HALF
191 int copy_from_float_to_half(const float *data, half *dest, int N,
192  CarmaDevice *device);
193 int copy_from_half_to_float(const half *d_data, float *h_dest, int N,
194  CarmaDevice *device);
195 half *float_to_half_array(float *source, int N, CarmaDevice *device);
196 float *half_to_float_array(half *source, int N, CarmaDevice *device);
197 #endif
198 
201 
202 // NOTE: "(%s:%i) : " allows Eclipse to directly jump to the file at the right
203 // line when the user double clicks on the error line in the Output pane. Like
204 // any compile error.
205 
206 inline void __carma_safe_call_no_sync(cudaError err, const char *file,
207  const int line) {
208  if (cudaSuccess != err) {
209  fprintf(stderr, "(%s:%i) : carma_safe_call_no_sync() Runtime API error : %s.\n",
210  file, line, cudaGetErrorString(err));
211  // exit(EXIT_FAILURE);
212  throw cudaGetErrorString(err);
213  }
214 }
215 
216 inline void __carma_safe_call(cudaError err, const char *code, const char *file,
217  const int line) {
218  if (cudaSuccess != err) {
219  fprintf(stderr, "[%s:%i] %s\n carma_safe_call() Runtime API error : %s.\n",
220  file, line, code, cudaGetErrorString(err));
221  // exit(EXIT_FAILURE);
222  throw cudaGetErrorString(err);
223  }
224 }
225 
226 inline void __carma_safe_device_synchronize(const char *file, const int line) {
227  cudaError err = cudaDeviceSynchronize();
228  if (cudaSuccess != err) {
229  fprintf(stderr,
230  "(%s:%i) : cudaDeviceSynchronize() Driver API error : %s.\n", file,
231  line, cudaGetErrorString(err));
232  // exit(EXIT_FAILURE);
233  throw cudaGetErrorString(err);
234  }
235 }
236 
237 inline void __carmafft_safe_call(cufftResult err, const char *file,
238  const int line) {
239  if (CUFFT_SUCCESS != err) {
240  fprintf(stderr, "(%s:%i) : carmafft_safe_call() CUFFT error.\n", file, line);
241  // exit(EXIT_FAILURE);
242  throw "carmafft_safe_call() CUFFT error";
243  }
244 }
245 
246 inline void __carma_check_msg(const char *error_message, const char *file,
247  const int line) {
248  cudaError_t err = cudaGetLastError();
249  if (cudaSuccess != err) {
250  fprintf(stderr, "(%s:%i) : carma_check_msg() CUTIL CUDA error : %s : %s.\n",
251  file, line, error_message, cudaGetErrorString(err));
252  throw cudaGetErrorString(err);
253  }
254 #ifdef DEBUG
255  err = cudaDeviceSynchronize();
256  if (cudaSuccess != err) {
257  fprintf(stderr,
258  "(%s:%i) : carma_check_msg cudaDeviceSynchronize error: %s : %s.\n",
259  file, line, error_message, cudaGetErrorString(err));
260  throw cudaGetErrorString(err);
261  }
262 #endif
263 }
264 inline void __carma_safe_malloc(void *pointer, const char *file, const int line) {
265  if (!(pointer)) {
266  fprintf(stderr, "(%s:%i) : cutil_safe_malloc host malloc failure\n", file,
267  line);
268  throw "cutil_safe_malloc() cutil_safe_malloc host malloc failure";
269  }
270 }
271 
272 #endif // _CARMA_UTILS_H_
carma_utils
Definition: carma_utils.h:80
double_to_float
int double_to_float(double *idata, float *odata, int N, CarmaDevice *device)
next_pow2
unsigned int next_pow2(unsigned int x)
Definition: carma_utils.h:160
CarmaDevice
Definition: carma_context.h:57
get_num_blocks_and_threads
void get_num_blocks_and_threads(CarmaDevice *device, int n, int &blocks, int &threads)
carma_utils::from_string
T from_string(const std::string &myString)
Definition: carma_utils.h:88
doubleint::start
int start
Definition: carma_utils.h:70
doubleint::nbInflu
int nbInflu
Definition: carma_utils.h:71
sum_get_num_blocks_and_threads
void sum_get_num_blocks_and_threads(int n, CarmaDevice *device, int &blocks, int &threads)
carma_utils::ProgressBar::update
void update()
__carma_safe_call_no_sync
void __carma_safe_call_no_sync(cudaError err, const char *file, const int line)
Definition: carma_utils.h:206
carma_start_profile
void carma_start_profile()
carma_utils::to_string
std::string to_string(const T &n)
Definition: carma_utils.h:82
carma_utils::ProgressBar::finish
void finish()
float_to_double
int float_to_double(float *idata, double *odata, int N, CarmaDevice *device)
__carma_check_msg
void __carma_check_msg(const char *error_message, const char *file, const int line)
Definition: carma_utils.h:246
is_pow2
bool is_pow2(unsigned int x)
Definition: carma_utils.h:170
carma_utils::ProgressBar::ProgressBar
ProgressBar(int i, const std::string &desc="")
__carma_safe_device_synchronize
void __carma_safe_device_synchronize(const char *file, const int line)
Definition: carma_utils.h:226
tuple_t::data
T data
Definition: carma_utils.h:77
carma_utils::split
void split(std::vector< std::string > &tokens, const std::string &text, char sep)
Definition: carma_utils.h:94
__carma_safe_call
void __carma_safe_call(cudaError err, const char *code, const char *file, const int line)
Definition: carma_utils.h:216
carma_stop_profile
void carma_stop_profile()
__carma_safe_malloc
void __carma_safe_malloc(void *pointer, const char *file, const int line)
Definition: carma_utils.h:264
print_mem_info
int print_mem_info()
carma_utils::ProgressBar
Definition: carma_utils.h:104
tuple_t::pos
int pos
Definition: carma_utils.h:76
fill_sparse_vect
int fill_sparse_vect(T_data *dense_data, int *colind_sorted, T_data *values, int *colind, int *rowind, int nnz, CarmaDevice *device)
find_nnz
int find_nnz(T_data *d_data, int *tmp_colind, int N, int *d_nnz, int &h_nnz, CarmaDevice *device)
doubleint
Definition: carma_utils.h:69
__carmafft_safe_call
void __carmafft_safe_call(cufftResult err, const char *file, const int line)
Definition: carma_utils.h:237
fill_array_with_value
int fill_array_with_value(T_data *d_data, T_data value, int N, CarmaDevice *device)
tuple_t
Definition: carma_utils.h:75