COMPASS  5.4.4
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-2023 COMPASS Team <https://github.com/ANR-COMPASS>
5 // All rights reserved.
6 
7 // -----------------------------------------------------------------------------
8 
15 
16 
17 #ifndef _CARMA_UTILS_H_
18 #define _CARMA_UTILS_H_
19 
20 #include <stdint.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include <driver_types.h>
26 #include <vector_types.h>
27 #include <chrono>
28 #include <iostream>
29 #include <sstream>
30 #include <string>
31 #include <vector>
32 
33 #include <cuda.h>
34 #include <cuda_fp16.h>
35 #include <cuda_runtime_api.h>
36 #include <cufft.h>
37 
38 #include <carma_indicators.hpp>
39 
40 #ifdef USE_OCTOPUS
41 #include <Cacao.h>
42 #endif
43 
44 #define CARMA_PI 3.1415926535897932384626433832
45 
46 struct doubleint {
47  int start;
48  int nbInflu;
49 };
50 
51 template <class T>
52 struct tuple_t {
53  int pos;
54  T data;
55 };
56 
57 namespace carma_utils {
58 template <typename T>
59 inline std::string to_string(const T &n) {
60  std::ostringstream stm;
61  stm << n;
62  return stm.str();
63 }
64 template <typename T>
65 inline T from_string(const std::string &myString) {
66  std::istringstream buffer(myString);
67  T value;
68  buffer >> value;
69  return value;
70 }
71 void inline split(std::vector<std::string> &tokens, const std::string &text,
72  char sep) {
73  std::string::size_type start = 0, end = 0;
74  while ((end = text.find(sep, start)) != std::string::npos) {
75  tokens.push_back(text.substr(start, end - start));
76  start = end + 1;
77  }
78  tokens.push_back(text.substr(start));
79 }
80 
81 } // namespace carma_utils
82 
83 #ifdef DEBUG
84 #define DEBUG_TRACE(fmt, args...) \
85  fprintf(stderr, "[%s@%d]: " fmt "\n", __FILE__, __LINE__, ##args)
86 #else
87 #define DEBUG_TRACE(fmt, args...) \
88  fprintf(stderr, "[%s@%d]: " fmt "\n", __FILE__, __LINE__, ##args)
89 #endif
90 
91 #define CAST(type, new_var, var) type new_var = dynamic_cast<type>(var)
92 #define SCAST(type, new_var, var) type new_var = static_cast<type>(var)
93 
94 // We define these calls here, so the user doesn't need to include __FILE__ and
95 // __LINE__ The advantage is the developers gets to use the inline function so
96 // they can debug
97 #ifdef DEBUG
98 #define carma_safe_call_no_sync(err) __carma_safe_call_no_sync(err, __FILE__, __LINE__)
99 #define carma_safe_call(err) __carma_safe_call((err), #err, __FILE__, __LINE__)
100 #define carma_safe_device_synchronize() \
101  __carma_safe_device_synchronize(__FILE__, __LINE__)
102 #define carmafft_safe_call(err) __carmafft_safe_call(err, __FILE__, __LINE__)
103 #define carma_check_msg(msg) __carma_check_msg(msg, __FILE__, __LINE__)
104 #define carma_safe_malloc(mallocCall) \
105  __carma_safe_malloc((mallocCall), __FILE__, __LINE__)
106 #else
107 #define carma_safe_call_no_sync(err) err
108 #define carma_safe_call(err) err
109 #define carma_safe_device_synchronize() cudaDeviceSynchronize()
110 #define carmafft_safe_call(err) err
111 #define cutil_check_error(err) err
112 #define carma_check_msg(msg)
113 #define cutil_safe_malloc(mallocCall) (mallocCall)
114 #endif
115 
116 #ifndef MIN
117 #define MIN(a, b) ((a < b) ? a : b)
118 #endif
119 #ifndef MAX
120 #define MAX(a, b) ((a > b) ? a : b)
121 #endif
122 
123 inline unsigned int next_pow2(unsigned int x) {
124  --x;
125  x |= x >> 1;
126  x |= x >> 2;
127  x |= x >> 4;
128  x |= x >> 8;
129  x |= x >> 16;
130  return ++x;
131 }
132 
133 inline bool is_pow2(unsigned int x) { return ((x & (x - 1)) == 0); }
134 
135 class CarmaDevice;
136 void get_num_blocks_and_threads(CarmaDevice *device, int n, int &blocks,
137  int &threads);
138 void sum_get_num_blocks_and_threads(int n, CarmaDevice *device, int &blocks,
139  int &threads);
140 template <class T_data>
141 int find_nnz(T_data *d_data, int *tmp_colind, int N, int *d_nnz, int &h_nnz,
142  CarmaDevice *device);
143 template <class T_data>
144 int fill_sparse_vect(T_data *dense_data, int *colind_sorted, T_data *values,
145  int *colind, int *rowind, int nnz, CarmaDevice *device);
146 int float_to_double(float *idata, double *odata, int N, CarmaDevice *device);
147 int double_to_float(double *idata, float *odata, int N, CarmaDevice *device);
149 template <typename T_data>
150 int fill_array_with_value(T_data *d_data, T_data value, int N,
151  CarmaDevice *device);
152 
153 #ifdef CAN_DO_HALF
154 int copy_from_float_to_half(const float *data, half *dest, int N,
155  CarmaDevice *device);
156 int copy_from_half_to_float(const half *d_data, float *h_dest, int N,
157  CarmaDevice *device);
158 half *float_to_half_array(float *source, int N, CarmaDevice *device);
159 float *half_to_float_array(half *source, int N, CarmaDevice *device);
160 #endif
161 
164 
165 // NOTE: "(%s:%i) : " allows Eclipse to directly jump to the file at the right
166 // line when the user double clicks on the error line in the Output pane. Like
167 // any compile error.
168 
169 inline void __carma_safe_call_no_sync(cudaError err, const char *file,
170  const int line) {
171  if (cudaSuccess != err) {
172  fprintf(stderr, "(%s:%i) : carma_safe_call_no_sync() Runtime API error : %s.\n",
173  file, line, cudaGetErrorString(err));
174  // exit(EXIT_FAILURE);
175  throw cudaGetErrorString(err);
176  }
177 }
178 
179 inline void __carma_safe_call(cudaError err, const char *code, const char *file,
180  const int line) {
181  if (cudaSuccess != err) {
182  fprintf(stderr, "[%s:%i] %s\n carma_safe_call() Runtime API error : %s.\n",
183  file, line, code, cudaGetErrorString(err));
184  // exit(EXIT_FAILURE);
185  throw cudaGetErrorString(err);
186  }
187 }
188 
189 inline void __carma_safe_device_synchronize(const char *file, const int line) {
190  cudaError err = cudaDeviceSynchronize();
191  if (cudaSuccess != err) {
192  fprintf(stderr,
193  "(%s:%i) : cudaDeviceSynchronize() Driver API error : %s.\n", file,
194  line, cudaGetErrorString(err));
195  // exit(EXIT_FAILURE);
196  throw cudaGetErrorString(err);
197  }
198 }
199 
200 inline void __carmafft_safe_call(cufftResult err, const char *file,
201  const int line) {
202  if (CUFFT_SUCCESS != err) {
203  fprintf(stderr, "(%s:%i) : carmafft_safe_call() CUFFT error.\n", file, line);
204  // exit(EXIT_FAILURE);
205  throw "carmafft_safe_call() CUFFT error";
206  }
207 }
208 
209 inline void __carma_check_msg(const char *error_message, const char *file,
210  const int line) {
211  cudaError_t err = cudaGetLastError();
212  if (cudaSuccess != err) {
213  fprintf(stderr, "(%s:%i) : carma_check_msg() CUTIL CUDA error : %s : %s.\n",
214  file, line, error_message, cudaGetErrorString(err));
215  throw cudaGetErrorString(err);
216  }
217 #ifdef DEBUG
218  err = cudaDeviceSynchronize();
219  if (cudaSuccess != err) {
220  fprintf(stderr,
221  "(%s:%i) : carma_check_msg cudaDeviceSynchronize error: %s : %s.\n",
222  file, line, error_message, cudaGetErrorString(err));
223  throw cudaGetErrorString(err);
224  }
225 #endif
226 }
227 inline void __carma_safe_malloc(void *pointer, const char *file, const int line) {
228  if (!(pointer)) {
229  fprintf(stderr, "(%s:%i) : cutil_safe_malloc host malloc failure\n", file,
230  line);
231  throw "cutil_safe_malloc() cutil_safe_malloc host malloc failure";
232  }
233 }
234 
235 #endif // _CARMA_UTILS_H_
int fill_array_with_value(T_data *d_data, T_data value, int N, CarmaDevice *device)
int fill_sparse_vect(T_data *dense_data, int *colind_sorted, T_data *values, int *colind, int *rowind, int nnz, CarmaDevice *device)
void __carmafft_safe_call(cufftResult err, const char *file, const int line)
Definition: carma_utils.h:200
void __carma_safe_device_synchronize(const char *file, const int line)
Definition: carma_utils.h:189
void __carma_safe_malloc(void *pointer, const char *file, const int line)
Definition: carma_utils.h:227
unsigned int next_pow2(unsigned int x)
Definition: carma_utils.h:123
void get_num_blocks_and_threads(CarmaDevice *device, int n, int &blocks, int &threads)
int print_mem_info()
int find_nnz(T_data *d_data, int *tmp_colind, int N, int *d_nnz, int &h_nnz, CarmaDevice *device)
void __carma_safe_call_no_sync(cudaError err, const char *file, const int line)
Definition: carma_utils.h:169
void __carma_check_msg(const char *error_message, const char *file, const int line)
Definition: carma_utils.h:209
void carma_start_profile()
int double_to_float(double *idata, float *odata, int N, CarmaDevice *device)
void __carma_safe_call(cudaError err, const char *code, const char *file, const int line)
Definition: carma_utils.h:179
int float_to_double(float *idata, double *odata, int N, CarmaDevice *device)
bool is_pow2(unsigned int x)
Definition: carma_utils.h:133
void sum_get_num_blocks_and_threads(int n, CarmaDevice *device, int &blocks, int &threads)
void carma_stop_profile()
void split(std::vector< std::string > &tokens, const std::string &text, char sep)
Definition: carma_utils.h:71
std::string to_string(const T &n)
Definition: carma_utils.h:59
T from_string(const std::string &myString)
Definition: carma_utils.h:65
int nbInflu
Definition: carma_utils.h:48
int pos
Definition: carma_utils.h:53