COMPASS  5.0.0
End-to-end AO simulation tool using GPU acceleration
carma_context.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 
41 
42 #ifndef _CARMA_CONTEXT_H_
43 #define _CARMA_CONTEXT_H_
44 
45 #include <cuda_runtime_api.h>
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <vector_types.h>
49 #include <memory>
50 #include <string>
51 #include <vector>
52 
53 #include "carma_cublas.h"
54 #include "carma_cusparse.h"
55 #include "carma_utils.h"
56 
57 class CarmaDevice {
58  protected:
59  int id;
60  cudaDeviceProp properties;
61  float compute_perf;
62  float cores_per_sm;
64  size_t free_mem;
65  size_t total_mem;
66 
67  cublasHandle_t cublas_handle;
68  cusparseHandle_t cusparse_handle;
69  cudaStream_t main_stream;
70 
71  public:
72  CarmaDevice(int devid);
73  int set_cublas_math_mode(bool tensor);
74  // CarmaDevice(const CarmaDevice& device);
76  cudaStream_t get_stream() { return main_stream; }
77  int get_id() { return id; }
78  cudaDeviceProp get_properties() { return properties; }
79  float get_compute_perf() { return compute_perf; }
80  float get_cores_per_sm() { return cores_per_sm; }
81  bool is_gpu_capable_p2p() { return (bool)(properties.major >= 2); }
82 
83  bool is_p2p_activate() { return p2p_activate; }
84 
85  std::string get_name() { return properties.name; }
86 
87  size_t get_total_mem() { return total_mem; }
88  size_t get_free_mem() {
89  carma_safe_call(cudaMemGetInfo(&total_mem, &total_mem));
90  return total_mem;
91  }
92 
93  cublasHandle_t get_cublas_handle() { return cublas_handle; }
94  cusparseHandle_t get_cusparse_handle() { return cusparse_handle; }
95 };
96 
97 #define set_active_device(new_device, silent) \
98  _set_active_device(new_device, silent, __FILE__, __LINE__)
99 #define set_active_device_force(new_device, silent) \
100  _set_active_device_force(new_device, silent, __FILE__, __LINE__)
101 #define set_active_deviceForCpy(new_device, silent) \
102  _set_active_device_for_copy(new_device, silent, __FILE__, __LINE__)
103 
105  private:
106  int ndevice;
107  std::vector<CarmaDevice*> devices;
108  int active_device;
109  int** can_access_peer;
110 
112  static std::shared_ptr<CarmaContext> s_instance;
113 
114  CarmaContext();
115  CarmaContext(int num_device);
116  CarmaContext(int nb_devices, int32_t* devices);
117 
118  CarmaContext& operator=(const CarmaContext&) { return *s_instance; }
119  CarmaContext(const CarmaContext&)
120  : ndevice(0), active_device(0), can_access_peer(nullptr) {}
121 
122  void init_context(const int nb_devices, int32_t* devices_id);
123 
124  public:
126 
127  static CarmaContext& instance_1gpu(int num_device);
128  static CarmaContext& instance_ngpu(int nb_devices, int32_t* devices_id);
130 
131  int get_ndevice() { return ndevice; }
132  CarmaDevice* get_device(int dev) { return devices[dev]; }
133  int get_active_device() { return active_device; }
134  int get_active_real_device() { return devices[active_device]->get_id(); }
135 
137  int runtime_version;
138  carma_safe_call(cudaRuntimeGetVersion(&runtime_version));
139  return runtime_version;
140  }
141 
143  int driver_version;
144  carma_safe_call(cudaRuntimeGetVersion(&driver_version));
145  return driver_version;
146  }
147 
148  std::string get_device_name(int device);
149  std::string get_device_info(int device);
150  std::string get_device_mem_info(int device);
151 
152  inline int _set_active_device_for_copy(int new_device, int silent,
153  std::string file, int line) {
154  if (new_device > ndevice) return -1;
155  return (can_access_peer[active_device][new_device] != 1)
156  ? _set_active_device(new_device, silent, file, line)
157  : active_device;
158  }
159  inline int _set_active_device(int new_device, int silent, std::string file,
160  int line) {
161  return (this->active_device != new_device)
162  ? _set_active_device_force(new_device, silent, file, line)
163  : active_device;
164  }
165  int _set_active_device_force(int new_device, int silent, std::string file,
166  int line);
168  cublasHandle_t get_cublas_handle() { return get_cublas_handle(active_device); }
169  cusparseHandle_t get_cusparse_handle() {
170  return get_cusparse_handle(active_device);
171  }
172 
173  cublasHandle_t get_cublas_handle(int device) {
174  return devices[device]->get_cublas_handle();
175  }
176  cusparseHandle_t get_cusparse_handle(int device) {
177  return devices[device]->get_cusparse_handle();
178  }
179  bool can_p2p(int dev1, int dev2) { return can_access_peer[dev1][dev2]; }
180 
181  std::string magma_info();
182 };
183 
185 inline int convert_sm_version2cores(int major, int minor) {
186  // Defines for GPU Architecture types (using the SM version to determine the #
187  // of cores per SM
188  typedef struct {
189  int SM; // 0xMm (hexidecimal notation), M = SM Major version, and m = SM
190  // minor version
191  int Cores;
192  } sSMtoCores;
193 
194  sSMtoCores nGpuArchCoresPerSM[] = {
195  {0x20, 32}, // Fermi Generation (SM 2.0) GF100 class
196  {0x21, 48}, // Fermi Generation (SM 2.1) GF10x class
197  {0x30, 192}, // Kepler Generation (SM 3.0) GK10x class
198  {0x32, 192}, // Kepler Generation (SM 3.2) GK10x class
199  {0x35, 192}, // Kepler Generation (SM 3.5) GK11x class
200  {0x37, 192}, // Kepler Generation (SM 3.7) GK21x class
201  {0x50, 128}, // Maxwell Generation (SM 5.0) GM10x class
202  {0x52, 128}, // Maxwell Generation (SM 5.2) GM20x class
203  {0x53, 128}, // Maxwell Generation (SM 5.3) GM20x class
204  {0x60, 64}, // Pascal Generation (SM 6.0) GP100 class
205  {0x61, 128}, // Pascal Generation (SM 6.1) GP10x class
206  {0x62, 128}, // Pascal Generation (SM 6.2) GP10x class
207  {0x70, 64}, // Volta Generation (SM 7.0) GV100 class
208  {0x72, 64}, // Volta Generation (SM 7.2) GV10B class
209  {0x75, 64}, // Turing Generation (SM 7.5) TU100 class
210  {-1, -1}};
211 
212  int index = 0;
213 
214  while (nGpuArchCoresPerSM[index].SM != -1) {
215  if (nGpuArchCoresPerSM[index].SM == ((major << 4) + minor)) {
216  return nGpuArchCoresPerSM[index].Cores;
217  }
218 
219  index++;
220  }
221 
222  // If we don't find the values, we default use the previous one to run
223  // properly
224  printf(
225  "MapSMtoCores for SM %d.%d is undefined. Default to use %d Cores/SM\n",
226  major, minor, nGpuArchCoresPerSM[index - 1].Cores);
227  return nGpuArchCoresPerSM[index - 1].Cores;
228 }
229 #endif // _CARMA_CONTEXT_H_
CarmaDevice::set_cublas_math_mode
int set_cublas_math_mode(bool tensor)
CarmaDevice::get_compute_perf
float get_compute_perf()
Definition: carma_context.h:79
CarmaContext::get_ndevice
int get_ndevice()
Definition: carma_context.h:131
CarmaDevice::total_mem
size_t total_mem
Definition: carma_context.h:65
carma_cusparse.h
this file provides the cusparse features to CarmaObj
CarmaDevice::is_gpu_capable_p2p
bool is_gpu_capable_p2p()
Definition: carma_context.h:81
CarmaContext::get_cuda_driver_get_version
int get_cuda_driver_get_version()
Definition: carma_context.h:142
CarmaContext::get_cuda_runtime_get_version
int get_cuda_runtime_get_version()
Definition: carma_context.h:136
carma_cublas.h
this file provides the cublas features to CarmaObj
CarmaDevice
Definition: carma_context.h:57
CarmaDevice::get_id
int get_id()
Definition: carma_context.h:77
CarmaContext::get_active_real_device
int get_active_real_device()
Definition: carma_context.h:134
CarmaContext::get_device_mem_info
std::string get_device_mem_info(int device)
carma_utils.h
this file provides tools to CarmaObj
carma_safe_call
#define carma_safe_call(err)
Definition: carma_utils.h:145
CarmaContext::instance_ngpu
static CarmaContext & instance_ngpu(int nb_devices, int32_t *devices_id)
CarmaContext::get_cublas_handle
cublasHandle_t get_cublas_handle(int device)
Definition: carma_context.h:173
CarmaDevice::get_cusparse_handle
cusparseHandle_t get_cusparse_handle()
Definition: carma_context.h:94
CarmaDevice::id
int id
Definition: carma_context.h:59
CarmaDevice::is_p2p_activate
bool is_p2p_activate()
Definition: carma_context.h:83
CarmaContext::get_cusparse_handle
cusparseHandle_t get_cusparse_handle()
Definition: carma_context.h:169
CarmaContext::get_device_info
std::string get_device_info(int device)
CarmaDevice::get_properties
cudaDeviceProp get_properties()
Definition: carma_context.h:78
CarmaDevice::main_stream
cudaStream_t main_stream
Definition: carma_context.h:69
CarmaContext::_set_active_device_force
int _set_active_device_force(int new_device, int silent, std::string file, int line)
CarmaDevice::compute_perf
float compute_perf
Definition: carma_context.h:61
CarmaDevice::get_cublas_handle
cublasHandle_t get_cublas_handle()
Definition: carma_context.h:93
CarmaContext::instance
static CarmaContext & instance()
CarmaContext::~CarmaContext
~CarmaContext()
CarmaDevice::properties
cudaDeviceProp properties
Definition: carma_context.h:60
CarmaContext::get_active_device
int get_active_device()
Definition: carma_context.h:133
CarmaDevice::get_stream
cudaStream_t get_stream()
Definition: carma_context.h:76
CarmaDevice::get_cores_per_sm
float get_cores_per_sm()
Definition: carma_context.h:80
CarmaContext
this class provides the context in which CarmaObj are created
Definition: carma_context.h:104
CarmaContext::get_cublas_handle
cublasHandle_t get_cublas_handle()
Definition: carma_context.h:168
CarmaDevice::~CarmaDevice
~CarmaDevice()
CarmaContext::magma_info
std::string magma_info()
CarmaContext::_set_active_device
int _set_active_device(int new_device, int silent, std::string file, int line)
Definition: carma_context.h:159
CarmaContext::get_cusparse_handle
cusparseHandle_t get_cusparse_handle(int device)
Definition: carma_context.h:176
CarmaDevice::get_free_mem
size_t get_free_mem()
Definition: carma_context.h:88
CarmaContext::get_max_gflops_device_id
int get_max_gflops_device_id()
convert_sm_version2cores
int convert_sm_version2cores(int major, int minor)
from /usr/local/cuda/samples/common/inc/helper_cuda.h
Definition: carma_context.h:185
CarmaContext::_set_active_device_for_copy
int _set_active_device_for_copy(int new_device, int silent, std::string file, int line)
Definition: carma_context.h:152
CarmaContext::instance_1gpu
static CarmaContext & instance_1gpu(int num_device)
CarmaDevice::cublas_handle
cublasHandle_t cublas_handle
Definition: carma_context.h:67
CarmaContext::get_device_name
std::string get_device_name(int device)
CarmaDevice::get_name
std::string get_name()
Definition: carma_context.h:85
CarmaContext::can_p2p
bool can_p2p(int dev1, int dev2)
Definition: carma_context.h:179
CarmaDevice::cusparse_handle
cusparseHandle_t cusparse_handle
Definition: carma_context.h:68
CarmaDevice::free_mem
size_t free_mem
Definition: carma_context.h:64
CarmaContext::get_device
CarmaDevice * get_device(int dev)
Definition: carma_context.h:132
CarmaDevice::CarmaDevice
CarmaDevice(int devid)
CarmaDevice::p2p_activate
bool p2p_activate
Definition: carma_context.h:63
CarmaDevice::cores_per_sm
float cores_per_sm
Definition: carma_context.h:62
CarmaDevice::get_total_mem
size_t get_total_mem()
Definition: carma_context.h:87