imate
C++/CUDA Reference
cuLinearOperator< DataType > Class Template Reference

Base class for linear operators. This class serves as interface for all derived classes. More...

#include <cu_linear_operator.h>

Inheritance diagram for cuLinearOperator< DataType >:
Collaboration diagram for cuLinearOperator< DataType >:

Public Member Functions

 cuLinearOperator ()
 
 cuLinearOperator (int num_gpu_devices_)
 Constructor with setting num_rows and num_columns. More...
 
virtual ~cuLinearOperator ()
 
cublasHandle_t get_cublas_handle () const
 This function returns a reference to the cublasHandle_t object. The object will be created, if it is not created already. More...
 
- Public Member Functions inherited from cLinearOperator< DataType >
 cLinearOperator ()
 Default constructor. More...
 
 cLinearOperator (const LongIndexType num_rows_, const LongIndexType num_columns_)
 Constructor with setting num_rows and num_columns. More...
 
virtual ~cLinearOperator ()
 
LongIndexType get_num_rows () const
 
LongIndexType get_num_columns () const
 
void set_parameters (DataType *parameters_)
 Sets the scalar parameter this->parameters. Parameter is initialized to NULL. However, before calling dot or transpose_dot functions, the parameters must be set. More...
 
IndexType get_num_parameters () const
 
FlagType is_eigenvalue_relation_known () const
 Returns a flag that determines whether a relation between the parameters of the operator and its eigenvalue(s) is known. More...
 
virtual DataType get_eigenvalue (const DataType *known_parameters, const DataType known_eigenvalue, const DataType *inquiry_parameters) const =0
 
virtual void dot (const DataType *vector, DataType *product)=0
 
virtual void transpose_dot (const DataType *vector, DataType *product)=0
 

Protected Member Functions

int query_gpu_devices () const
 Before any numerical computation, this method chechs if any gpu device is available on the machine, or notifies the user if nothing was found. More...
 
void initialize_cublas_handle ()
 Creates a cublasHandle_t object, if not created already. More...
 
void initialize_cusparse_handle ()
 Creates a cusparseHandle_t object, if not created already. More...
 

Protected Attributes

int num_gpu_devices
 
bool copied_host_to_device
 
cublasHandle_t * cublas_handle
 
cusparseHandle_t * cusparse_handle
 
- Protected Attributes inherited from cLinearOperator< DataType >
const LongIndexType num_rows
 
const LongIndexType num_columns
 
FlagType eigenvalue_relation_known
 
DataType * parameters
 
IndexType num_parameters
 

Detailed Description

template<typename DataType>
class cuLinearOperator< DataType >

Base class for linear operators. This class serves as interface for all derived classes.

The prefix c in this class's name (and its derivatves), stands for the cpp code, intrast to the cu prefix, which stands for the cuda code. Most derived classes have a cuda counterpart.

See also
cuMatrix, cuAffineMatrixFunction, cLinearOperator

Definition at line 43 of file cu_linear_operator.h.

Constructor & Destructor Documentation

◆ cuLinearOperator() [1/2]

template<typename DataType >
cuLinearOperator< DataType >::cuLinearOperator

Definition at line 30 of file cu_linear_operator.cu.

30  :
31 
32  // Initializer list
33  num_gpu_devices(0),
34  copied_host_to_device(false),
35  cublas_handle(NULL),
36  cusparse_handle(NULL)
37 {
38  // Check any gpu device exists
39  this->num_gpu_devices = this->query_gpu_devices();
40 
41  // Regardless of using dense (cublas) or sparse (cusparse) matrices, the
42  // cublas handle should be initialized, since it is needed for the methods
43  // in cuVectorOperations
45 }
cublasHandle_t * cublas_handle
int query_gpu_devices() const
Before any numerical computation, this method chechs if any gpu device is available on the machine,...
cusparseHandle_t * cusparse_handle
void initialize_cublas_handle()
Creates a cublasHandle_t object, if not created already.

References cuLinearOperator< DataType >::initialize_cublas_handle(), cuLinearOperator< DataType >::num_gpu_devices, and cuLinearOperator< DataType >::query_gpu_devices().

Here is the call graph for this function:

◆ cuLinearOperator() [2/2]

template<typename DataType >
cuLinearOperator< DataType >::cuLinearOperator ( int  num_gpu_devices_)
explicit

Constructor with setting num_rows and num_columns.

Note
For the classed that are virtually derived (virtual inheritance) from this class, this constructor will never be called. Rather, the default constructor is called by the most derived class. Thus, set the member data directly instead of below.

Definition at line 60 of file cu_linear_operator.cu.

61  :
62 
63  // Initializer list
64  num_gpu_devices(0),
65  copied_host_to_device(false),
66  cublas_handle(NULL),
67  cusparse_handle(NULL)
68 {
69  // Check any gpu device exists
70  int device_count = this->query_gpu_devices();
71 
72  // Set number of gpu devices
73  if (num_gpu_devices_ == 0)
74  {
75  this->num_gpu_devices = device_count;
76  }
77  else if (num_gpu_devices_ > device_count)
78  {
79  std::cerr << "ERROR: Number of requested gpu devices exceeds the " \
80  << "number of available gpu devices. Nummber of detected " \
81  << "devices are " << device_count << " while the " \
82  << "requested number of devices are " << num_gpu_devices_ \
83  << "." << std::endl;
84  abort();
85  }
86  else
87  {
88  this->num_gpu_devices = num_gpu_devices_;
89  }
90 
91  // Regardless of using dense (cublas) or sparse (cusparse) matrices, the
92  // cublas handle should be initialized, since it is needed for the methods
93  // in cuVectorOperations
95 }

References cuLinearOperator< DataType >::initialize_cublas_handle(), cuLinearOperator< DataType >::num_gpu_devices, and cuLinearOperator< DataType >::query_gpu_devices().

Here is the call graph for this function:

◆ ~cuLinearOperator()

template<typename DataType >
cuLinearOperator< DataType >::~cuLinearOperator
virtual

Definition at line 103 of file cu_linear_operator.cu.

104 {
105  // cublas handle
106  if (this->cublas_handle != NULL)
107  {
108  // Set the number of threads
109  omp_set_num_threads(this->num_gpu_devices);
110 
111  #pragma omp parallel
112  {
113  // Switch to a device with the same device id as the cpu thread id
114  unsigned int thread_id = omp_get_thread_num();
116 
117  cublasStatus_t status = cublasDestroy(
118  this->cublas_handle[thread_id]);
119  assert(status == CUBLAS_STATUS_SUCCESS);
120  }
121 
122  // Deallocate arrays of pointers on cpu
123  delete[] this->cublas_handle;
124  this->cublas_handle = NULL;
125  }
126 
127  // cusparse handle
128  if (this->cusparse_handle != NULL)
129  {
130  // Set the number of threads
131  omp_set_num_threads(this->num_gpu_devices);
132 
133  #pragma omp parallel
134  {
135  // Switch to a device with the same device id as the cpu thread id
136  unsigned int thread_id = omp_get_thread_num();
138 
139  cusparseStatus_t status = cusparseDestroy(
140  this->cusparse_handle[thread_id]);
141  assert(status == CUSPARSE_STATUS_SUCCESS);
142  }
143 
144  // Deallocate arrays of pointers on cpu
145  delete[] this->cusparse_handle;
146  this->cusparse_handle = NULL;
147  }
148 }
static void set_device(int device_id)
Sets the current device in multi-gpu applications.
cusparseStatus_t cusparseDestroy(cusparseHandle_t handle)
Definition of CUDA's cusparseDestroy function using dynamically loaded cublas library.

References cusparseDestroy(), and CudaInterface< ArrayType >::set_device().

Here is the call graph for this function:

Member Function Documentation

◆ get_cublas_handle()

template<typename DataType >
cublasHandle_t cuLinearOperator< DataType >::get_cublas_handle

This function returns a reference to the cublasHandle_t object. The object will be created, if it is not created already.

The cublasHandle is needed for the client code (slq method) for vector operations on GPU. However, in this class, the cublasHandle_t might not be needed by it self if the derived class is a sparse matrix, becase the sparse matrix needs only cusparseHandle_t. In case if the cublasHandle_t is not created, it will be created for the purpose of the client codes.

Returns
A void pointer to the cublasHandle_t instance.

Definition at line 168 of file cu_linear_operator.cu.

169 {
170  // Get device id
171  int device_id = CudaInterface<DataType>::get_device();
172 
173  return this->cublas_handle[device_id];
174 }
static int get_device()
Gets the current device in multi-gpu applications.

References CudaInterface< ArrayType >::get_device().

Referenced by cu_golub_kahn_bidiagonalization(), and cu_lanczos_tridiagonalization().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initialize_cublas_handle()

template<typename DataType >
void cuLinearOperator< DataType >::initialize_cublas_handle
protected

Creates a cublasHandle_t object, if not created already.

Definition at line 185 of file cu_linear_operator.cu.

186 {
187  if (this->cublas_handle == NULL)
188  {
189  // Allocate pointers for each gpu device
190  this->cublas_handle = new cublasHandle_t[this->num_gpu_devices];
191 
192  // Set the number of threads
193  omp_set_num_threads(this->num_gpu_devices);
194 
195  #pragma omp parallel
196  {
197  // Switch to a device with the same device id as the cpu thread id
198  unsigned int thread_id = omp_get_thread_num();
200 
201  cublasStatus_t status = cublasCreate(
202  &this->cublas_handle[thread_id]);
203  assert(status == CUBLAS_STATUS_SUCCESS);
204  }
205  }
206 }

References CudaInterface< ArrayType >::set_device().

Referenced by cuDenseAffineMatrixFunction< DataType >::cuDenseAffineMatrixFunction(), cuDenseMatrix< DataType >::cuDenseMatrix(), and cuLinearOperator< DataType >::cuLinearOperator().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ initialize_cusparse_handle()

template<typename DataType >
void cuLinearOperator< DataType >::initialize_cusparse_handle
protected

Creates a cusparseHandle_t object, if not created already.

Definition at line 217 of file cu_linear_operator.cu.

218 {
219  if (this->cusparse_handle == NULL)
220  {
221  // Allocate pointers for each gpu device
222  this->cusparse_handle = new cusparseHandle_t[this->num_gpu_devices];
223 
224  // Set the number of threads
225  omp_set_num_threads(this->num_gpu_devices);
226 
227  #pragma omp parallel
228  {
229  // Switch to a device with the same device id as the cpu thread id
230  unsigned int thread_id = omp_get_thread_num();
232 
233  cusparseStatus_t status = cusparseCreate(
234  &this->cusparse_handle[thread_id]);
235  assert(status == CUSPARSE_STATUS_SUCCESS);
236  }
237  }
238 }
cusparseStatus_t cusparseCreate(cusparseHandle_t *handle)
Definition of CUDA's cusparseCreate function using dynamically loaded cublas library.

References cusparseCreate(), and CudaInterface< ArrayType >::set_device().

Referenced by cuCSCAffineMatrixFunction< DataType >::cuCSCAffineMatrixFunction(), cuCSCMatrix< DataType >::cuCSCMatrix(), cuCSRAffineMatrixFunction< DataType >::cuCSRAffineMatrixFunction(), and cuCSRMatrix< DataType >::cuCSRMatrix().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ query_gpu_devices()

template<typename DataType >
int cuLinearOperator< DataType >::query_gpu_devices
protected

Before any numerical computation, this method chechs if any gpu device is available on the machine, or notifies the user if nothing was found.

Returns
Number of gpu available devices.

Definition at line 252 of file cu_linear_operator.cu.

253 {
254  int device_count = 0;
255  cudaError_t error = cudaGetDeviceCount(&device_count);
256 
257  // Error code 38 means no cuda-capable device was detected.
258  if ((error != cudaSuccess) || (device_count < 1))
259  {
260  std::cerr << "ERROR: No cuda-capable GPU device was detected on " \
261  << "this machine. If a cuda-capable GPU device exists, " \
262  << "install its cuda driver. Alternatively, set " \
263  << "'gpu=False' to use cpu instead." \
264  << std::endl;
265 
266  abort();
267  }
268 
269  return device_count;
270 }
cudaError_t cudaGetDeviceCount(int *count)
Definition of CUDA's cudaGetDeviceCount function using dynamically loaded cudart library.

References cudaGetDeviceCount().

Referenced by cuLinearOperator< DataType >::cuLinearOperator().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ copied_host_to_device

template<typename DataType >
bool cuLinearOperator< DataType >::copied_host_to_device
protected

Definition at line 64 of file cu_linear_operator.h.

◆ cublas_handle

template<typename DataType >
cublasHandle_t* cuLinearOperator< DataType >::cublas_handle
protected

Definition at line 65 of file cu_linear_operator.h.

◆ cusparse_handle

template<typename DataType >
cusparseHandle_t* cuLinearOperator< DataType >::cusparse_handle
protected

Definition at line 66 of file cu_linear_operator.h.

◆ num_gpu_devices

template<typename DataType >
int cuLinearOperator< DataType >::num_gpu_devices
protected

The documentation for this class was generated from the following files: