imate
C++/CUDA Reference
cu_vector_operations.cu
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: Copyright 2021, Siavash Ameli <sameli@berkeley.edu>
3  * SPDX-License-Identifier: BSD-3-Clause
4  * SPDX-FileType: SOURCE
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the license found in the LICENSE.txt file in the root
8  * directory of this source tree.
9  */
10 
11 
12 // =======
13 // Headers
14 // =======
15 
16 #include "./cu_vector_operations.h"
17 #include <cmath> // sqrt
18 #include <cassert> // assert
19 #include "./cublas_interface.h" // cublas_interface
20 
21 
22 // ===========
23 // copy vector
24 // ===========
25 
36 
37 template <typename DataType>
39  cublasHandle_t cublas_handle,
40  const DataType* input_vector,
41  const LongIndexType vector_size,
42  DataType* output_vector)
43 {
44  int incx = 1;
45  int incy = 1;
46 
47  cublasStatus_t status = cublas_interface::cublasXcopy(
48  cublas_handle, vector_size, input_vector, incx, output_vector,
49  incy);
50 
51  assert(status == CUBLAS_STATUS_SUCCESS);
52 }
53 
54 // ==================
55 // copy scaled vector
56 // ==================
57 
71 
72 template <typename DataType>
74  cublasHandle_t cublas_handle,
75  const DataType* input_vector,
76  const LongIndexType vector_size,
77  const DataType scale,
78  DataType* output_vector)
79 {
80  cublasStatus_t status;
81  int incx = 1;
82  int incy = 1;
83 
84  // Copy input to output vector
85  status = cublas_interface::cublasXcopy(cublas_handle, vector_size,
86  input_vector, incx,
87  output_vector, incy);
88 
89  assert(status == CUBLAS_STATUS_SUCCESS);
90 
91  // Scale outpu vector
92  status = cublas_interface::cublasXscal(cublas_handle, vector_size, &scale,
93  output_vector, incy);
94 
95  assert(status == CUBLAS_STATUS_SUCCESS);
96 }
97 
98 
99 // ======================
100 // subtract scaled vector
101 // ======================
102 
124 
125 template <typename DataType>
127  cublasHandle_t cublas_handle,
128  const DataType* input_vector,
129  const LongIndexType vector_size,
130  const DataType scale,
131  DataType* output_vector)
132 {
133  if (scale == 0.0)
134  {
135  return;
136  }
137 
138  int incx = 1;
139  int incy = 1;
140 
141  DataType neg_scale = -scale;
142  cublasStatus_t status = cublas_interface::cublasXaxpy(
143  cublas_handle, vector_size, &neg_scale, input_vector, incx,
144  output_vector, incy);
145 
146  assert(status == CUBLAS_STATUS_SUCCESS);
147 }
148 
149 
150 // =============
151 // inner product
152 // =============
153 
164 
165 template <typename DataType>
167  cublasHandle_t cublas_handle,
168  const DataType* vector1,
169  const DataType* vector2,
170  const LongIndexType vector_size)
171 {
172  DataType inner_prod;
173  int incx = 1;
174  int incy = 1;
175 
176  cublasStatus_t status = cublas_interface::cublasXdot(
177  cublas_handle, vector_size, vector1, incx, vector2, incy,
178  &inner_prod);
179 
180  assert(status == CUBLAS_STATUS_SUCCESS);
181 
182  return inner_prod;
183 }
184 
185 
186 // ==============
187 // euclidean norm
188 // ==============
189 
199 
200 template <typename DataType>
202  cublasHandle_t cublas_handle,
203  const DataType* vector,
204  const LongIndexType vector_size)
205 {
206  DataType norm;
207  int incx = 1;
208 
209  cublasStatus_t status = cublas_interface::cublasXnrm2(
210  cublas_handle, vector_size, vector, incx, &norm);
211 
212  assert(status == CUBLAS_STATUS_SUCCESS);
213 
214  return norm;
215 }
216 
217 
218 // =========================
219 // normalize vector in place
220 // =========================
221 
232 
233 template <typename DataType>
235  cublasHandle_t cublas_handle,
236  DataType* vector,
237  const LongIndexType vector_size)
238 {
239  // Norm of vector
241  cublas_handle, vector, vector_size);
242 
243  // Normalize in place
244  DataType scale = 1.0 / norm;
245  int incx = 1;
246  cublasStatus_t status = cublas_interface::cublasXscal(
247  cublas_handle, vector_size, &scale, vector, incx);
248 
249  assert(status == CUBLAS_STATUS_SUCCESS);
250 
251  return norm;
252 }
253 
254 
255 // =========================
256 // normalize vector and copy
257 // =========================
258 
271 
272 template <typename DataType>
274  cublasHandle_t cublas_handle,
275  const DataType* vector,
276  const LongIndexType vector_size,
277  DataType* output_vector)
278 {
279  // Norm of vector
281  cublas_handle, vector, vector_size);
282 
283  // Normalize to output
284  DataType scale = 1.0 / norm;
286  vector_size, scale,
287  output_vector);
288 
289  return norm;
290 }
291 
292 
293 // ===============================
294 // Explicit template instantiation
295 // ===============================
296 
297 template class cuVectorOperations<float>;
298 template class cuVectorOperations<double>;
A static class for vector operations, similar to level-1 operations of the BLAS library....
static void copy_vector(cublasHandle_t cublas_handle, const DataType *input_vector, const LongIndexType vector_size, DataType *output_vector)
Copies a vector to a new vector. Result is written in-place.
static void copy_scaled_vector(cublasHandle_t cublas_handle, const DataType *input_vector, const LongIndexType vector_size, const DataType scale, DataType *output_vector)
Scales a vector and stores to a new vector.
static void subtract_scaled_vector(cublasHandle_t cublas_handle, const DataType *input_vector, const LongIndexType vector_size, const DataType scale, DataType *output_vector)
Subtracts the scaled input vector from the output vector.
static DataType normalize_vector_in_place(cublasHandle_t cublas_handle, DataType *vector, const LongIndexType vector_size)
Normalizes a vector based on Euclidean 2-norm. The result is written in-place.
static DataType inner_product(cublasHandle_t cublas_handle, const DataType *vector1, const DataType *vector2, const LongIndexType vector_size)
Computes Euclidean inner product of two vectors.
static DataType normalize_vector_and_copy(cublasHandle_t cublas_handle, const DataType *vector, const LongIndexType vector_size, DataType *output_vector)
Normalizes a vector based on Euclidean 2-norm. The result is written into another vector.
static DataType euclidean_norm(cublasHandle_t cublas_handle, const DataType *vector, const LongIndexType vector_size)
Computes the Euclidean 2-norm of a 1D array.
cublasStatus_t cublasXdot(cublasHandle_t handle, int n, const DataType *x, int incx, const DataType *y, int incy, DataType *result)
cublasStatus_t cublasXscal(cublasHandle_t handle, int n, const DataType *alpha, DataType *x, int incx)
cublasStatus_t cublasXnrm2(cublasHandle_t handle, int n, const DataType *x, int incx, DataType *result)
cublasStatus_t cublasXcopy(cublasHandle_t handle, int n, const DataType *x, int incx, DataType *y, int incy)
cublasStatus_t cublasXaxpy(cublasHandle_t handle, int n, const DataType *alpha, const DataType *x, int incx, DataType *y, int incy)
int LongIndexType
Definition: types.h:60