34#include "../code_config.hpp"
35#include "../parallelization/mpi_structure.hpp"
36#include "../parallelization/omp_structure.hpp"
37#include "../parallelization/vectorization.hpp"
39#include "../../include/CConfig.hpp"
45template <
class ScalarType>
59#ifdef SU2_ENABLE_CUDA_KERNELS
60template <
class ScalarType>
63template <
class ScalarType>
79#define CSYSVEC_PARFOR SU2_OMP_FOR_(simd schedule(static, omp_chunk_size) SU2_NOWAIT)
81#define CSYSVEC_PARFOR SU2_OMP_FOR_(schedule(static, omp_chunk_size) SU2_NOWAIT)
83#define END_CSYSVEC_PARFOR END_SU2_OMP_FOR
85#define CSYSVEC_PARFOR SU2_OMP_SIMD
86#define END_CSYSVEC_PARFOR
100#define SU2_DEVICE_REGION(...) SU2_OMP_SAFE_GLOBAL_ACCESS(__VA_ARGS__)
101#define BEGIN_SU2_DEVICE_REGION BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS
102#define END_SU2_DEVICE_REGION END_SU2_OMP_SAFE_GLOBAL_ACCESS
115#ifdef SU2_ENABLE_CUDA_KERNELS
132template <
class Scalar>
135 const Scalar* data =
nullptr;
145template <
class Scalar>
150template <
class Scalar>
155template <DeviceAssignOp Op,
class Scalar,
class T>
159template <DeviceAssignOp Op,
class Scalar,
class T>
160__global__
void DeviceAssignKernel(
Scalar* data,
unsigned long size, T expr) {
161 const unsigned long i =
static_cast<unsigned long>(blockIdx.x) * blockDim.x + threadIdx.x;
162 if (i >= size)
return;
177template <DeviceAssignOp Op,
class Scalar,
class T>
179 if (size == 0)
return;
180 constexpr unsigned block_size = 256;
181 const auto grid_size =
static_cast<unsigned>((size + block_size - 1) / block_size);
182 DeviceAssignKernel<Op><<<grid_size, block_size>>>(data, size, expr.derived());
194template <
class ScalarType>
197 enum { OMP_MAX_SIZE = 4096 };
200 unsigned long omp_chunk_size = OMP_MAX_SIZE;
201 ScalarType* vec_val =
nullptr;
202 unsigned long nElm = 0;
203 unsigned long nElmDomain = 0;
204 unsigned long nVar = 1;
206 ScalarType* d_vec_val =
nullptr;
209 mutable std::unique_ptr<ScalarType[]>
212 mutable std::array<ScalarType, 1> dot_scratch;
225 void Initialize(
unsigned long numBlk,
unsigned long numBlkDomain,
unsigned long numVar,
const ScalarType* val,
226 bool valIsArray,
bool errorIfParallel =
true);
231 template <
size_t N,
size_t nVar,
class VecTypeSIMD,
class F>
233 static_assert(VecTypeSIMD::StaticSize,
"This method requires static size vectors.");
234 for (
size_t i = 0; i < nVar; ++i) {
236 for (
size_t k = 0; k < N; ++k) out[k][i] = mask[k] * in[i][k];
245 template <VecExpr::DeviceAssignOp Op,
class T>
247#ifdef SU2_ENABLE_CUDA_KERNELS
248 if constexpr (su2_gpu_capable_v<ScalarType>) {
251 VecExpr::AssignDeviceExpression<Op>(d_vec_val, nElm, stored_expr);
259 template <VecExpr::DeviceAssignOp Op>
261#ifdef SU2_ENABLE_CUDA_KERNELS
262 if constexpr (su2_gpu_capable_v<ScalarType>) {
274 ScalarType dotGPU(
const CSysVector& other)
const;
300 explicit CSysVector(
unsigned long size, ScalarType val = 0.0) { Initialize(size, size, 1, &val,
false); }
309 CSysVector(
unsigned long numBlk,
unsigned long numBlkDomain,
unsigned long numVar, ScalarType val = 0.0) {
310 Initialize(numBlk, numBlkDomain, numVar, &val,
false);
318 CSysVector(
unsigned long size,
const ScalarType* u_array) { Initialize(size, size, 1, u_array,
true); }
327 CSysVector(
unsigned long numBlk,
unsigned long numBlkDomain,
unsigned long numVar,
const ScalarType* u_array) {
328 Initialize(numBlk, numBlkDomain, numVar, u_array,
true);
342 std::swap(omp_chunk_size, other.omp_chunk_size);
343 std::swap(vec_val, other.vec_val);
344 std::swap(d_vec_val, other.d_vec_val);
345 std::swap(nElm, other.nElm);
346 std::swap(nElmDomain, other.nElmDomain);
347 std::swap(nVar, other.nVar);
348 std::swap(dot_scratch, other.dot_scratch);
358 void Initialize(
unsigned long numBlk,
unsigned long numBlkDomain,
unsigned long numVar, ScalarType val = 0.0) {
359 Initialize(numBlk, numBlkDomain, numVar, &val,
false,
false);
370 void Initialize(
unsigned long numBlk,
unsigned long numBlkDomain,
unsigned long numVar,
const ScalarType* ptr) {
371 Initialize(numBlk, numBlkDomain, numVar, ptr,
true,
false);
384 if ((
const void*)
this == (
const void*)&other)
return;
430 inline unsigned long GetNVar()
const {
return nVar; }
435 inline unsigned long GetNBlk()
const {
return nElm / nVar; }
447 inline ScalarType&
operator[](
unsigned long i) {
return vec_val[i]; }
448 inline const ScalarType&
operator[](
unsigned long i)
const {
return vec_val[i]; }
453 inline const ScalarType*
begin()
const {
return vec_val; }
454 inline const ScalarType*
end()
const {
return vec_val + nElm; }
462 inline ScalarType&
operator()(
unsigned long iPoint,
unsigned long iVar) {
return vec_val[iPoint * nVar + iVar]; }
463 inline const ScalarType&
operator()(
unsigned long iPoint,
unsigned long iVar)
const {
464 return vec_val[iPoint * nVar + iVar];
473#ifdef SU2_ENABLE_CUDA_KERNELS
474 if constexpr (su2_gpu_capable_v<ScalarType>) {
479 for (
auto i = 0ul; i < nElm; ++i) vec_val[i] = other.vec_val[i];
488#define MAKE_COMPOUND(OP, ASSIGN_OP) \
489 CSysVector& operator OP(ScalarType val) { \
490 if constexpr (su2_gpu_capable_v<ScalarType>) { \
491 if (VecExpr::UseDeviceExpressions()) return AssignDevice<ASSIGN_OP>(val); \
494 for (auto i = 0ul; i < nElm; ++i) vec_val[i] OP val; \
499 CSysVector& operator OP(const VecExpr::CVecExpr<T, ScalarType>& expr) { \
500 if constexpr (su2_gpu_capable_v<ScalarType>) { \
501 if (VecExpr::UseDeviceExpressions()) return AssignDevice<ASSIGN_OP>(expr); \
504 for (auto i = 0ul; i < nElm; ++i) vec_val[i] OP expr.derived()[i]; \
527#ifdef SU2_ENABLE_CUDA_KERNELS
528 if constexpr (su2_gpu_capable_v<ScalarType>) {
529 using DeviceExpr = std::remove_cv_t<VecExpr::remove_reference_t<T>>;
530 static_assert(std::is_same_v<DeviceExpr, CSysVector>,
531 "On the device the dot product needs a real device pointer (dotGPU takes a "
532 "materialized vector, not an expression template), so it only takes vectors. "
533 "Assign the expression to a vector first.");
538 return dot_scratch[0];
547 ScalarType sum = 0.0;
550 for (
auto i = 0ul; i < nElmDomain; ++i) {
551 sum += vec_val[i] * expr.
derived()[i];
568 return dot_scratch[0];
581 const std::vector<CSysVector>&
W,
size_t m);
600 inline ScalarType*
GetBlock(
unsigned long iPoint) {
return &vec_val[iPoint * nVar]; }
601 inline const ScalarType*
GetBlock(
unsigned long iPoint)
const {
return &vec_val[iPoint * nVar]; }
608 for (
auto iVar = 0ul; iVar < nVar; iVar++) vec_val[iPoint * nVar + iVar] = 0.0;
618 template <
class VectorType,
bool Overwrite = true>
621 for (
auto i = 0ul; i < nVar; ++i) vec_val[iPoint * nVar + i] = alpha * block[i];
623 for (
auto i = 0ul; i < nVar; ++i) vec_val[iPoint * nVar + i] += alpha * block[i];
630 template <
class VectorType>
632 SetBlock<VectorType, false>(iPoint, block, alpha);
638 template <
class VectorType>
646 template <
class VectorType>
648 ScalarType alpha = 1) {
660 template <
size_t N,
class T,
class VecTypeSIMD,
class F = ScalarType>
663 constexpr size_t nVar = VecTypeSIMD::StaticSize;
664 assert(nVar == this->nVar);
665 ScalarType vec[N][nVar];
666 UnpackBlock(vector, mask, vec);
669 for (
size_t k = 0; k < N; ++k) {
670 if (mask[k] == 0)
continue;
672 for (
size_t i = 0; i < nVar; ++i) vec_val[iPoint[k] * nVar + i] = vec[k][i];
680 template <
size_t N,
class T,
class VecTypeSIMD,
class F = ScalarType>
684 constexpr size_t nVar = VecTypeSIMD::StaticSize;
685 assert(nVar == this->nVar);
686 ScalarType vec[N][nVar];
687 UnpackBlock(vector, mask, vec);
690 for (
size_t k = 0; k < N; ++k) {
691 if (mask[k] == 0)
continue;
693 for (
size_t i = 0; i < nVar; ++i) {
694 vec_val[iPoint[k] * nVar + i] += vec[k][i];
695 vec_val[jPoint[k] * nVar + i] -= vec[k][i];
703template <
class Scalar>
710#undef END_CSYSVEC_PARFOR
CNewtonIntegration::Scalar Scalar
Definition CNewtonIntegration.cpp:31
#define MAKE_COMPOUND(OP, ASSIGN_OP)
Compound assignement operations with scalars and expressions.
Definition CSysVector.hpp:488
#define END_CSYSVEC_PARFOR
Definition CSysVector.hpp:86
#define SU2_DEVICE_REGION(...)
Brackets device work so that it is issued by a single thread with the whole team synchronized before ...
Definition CSysVector.hpp:100
#define BEGIN_SU2_DEVICE_REGION
Definition CSysVector.hpp:101
#define END_SU2_DEVICE_REGION
Definition CSysVector.hpp:102
#define CSYSVEC_PARFOR
OpenMP worksharing construct used in CSysVector for loops.
Definition CSysVector.hpp:85
constexpr bool su2_gpu_capable_v
True for the plain floating-point scalar types the GPU vector kernels (CSysVectorGPU....
Definition CSysVector.hpp:64
Header file containing universal functions that provide basic and essential utilities for other GPU p...
#define gpuErrChk(ans)
Definition GPUComms.cuh:58
A templated matrix/vector-like object.
Definition C2DContainer.hpp:374
static Comm GetComm()
Definition mpi_structure.hpp:530
static void Allreduce(const void *sendbuf, void *recvbuf, int count, Datatype datatype, Op op, Comm comm)
Definition mpi_structure.hpp:570
Class for holding and manipulating vectors needed by linear solvers.
Definition CSysVector.hpp:195
CSysVector(unsigned long size, const ScalarType *u_array)
Construct from array.
Definition CSysVector.hpp:318
void DtHTransfer(bool trigger=true) const
Performs the memory copy from device to host.
Definition CSysVectorGPU.cu:200
const ScalarType & operator()(unsigned long iPoint, unsigned long iVar) const
Definition CSysVector.hpp:463
CSysVector & operator=(const CSysVector &other)
Assignment operator from another vector.
Definition CSysVector.hpp:472
unsigned long GetNElmDomain() const
return the number of local elements in the CSysVector without ghost cells
Definition CSysVector.hpp:425
void SetBlock(simd::Array< T, N > iPoint, const VecTypeSIMD &vector, simd::Array< F, N > mask=1)
Vectorized version of SetBlock, sets multiple iPoint's.
Definition CSysVector.hpp:661
void swap(CSysVector &other)
Swap contents with another vector.
Definition CSysVector.hpp:341
void Initialize(unsigned long numBlk, unsigned long numBlkDomain, unsigned long numVar, ScalarType val=0.0)
Initialize the class with a scalar.
Definition CSysVector.hpp:358
unsigned long GetNBlkDomain() const
return the number of blocks (typically number of nodes locally)
Definition CSysVector.hpp:440
ScalarType & operator[](unsigned long i)
Access operator with assignment permitted.
Definition CSysVector.hpp:447
unsigned long GetNBlk() const
return the number of blocks (typically number of nodes locally)
Definition CSysVector.hpp:435
CSysVector(const CSysVector &u)
Copy constructor of the class.
Definition CSysVector.hpp:336
~CSysVector()
Destructor.
Definition CSysVector.cpp:159
CSysVector(unsigned long numBlk, unsigned long numBlkDomain, unsigned long numVar, ScalarType val=0.0)
Construct from size and value (block version).
Definition CSysVector.hpp:309
void UpdateBlocks(simd::Array< T, N > iPoint, simd::Array< T, N > jPoint, const VecTypeSIMD &vector, simd::Array< F, N > mask=1)
Vectorized version of UpdateBlocks, updates multiple i/jPoint's.
Definition CSysVector.hpp:681
ScalarType norm() const
L2 norm of the vector.
Definition CSysVector.hpp:593
ScalarType * GetDevicePointer() const
return device pointer that points to the CSysVector values in GPU memory
Definition CSysVector.hpp:409
ScalarType squaredNorm() const
Squared L2 norm of the vector (via dot with self).
Definition CSysVector.hpp:587
void HtDTransfer(bool trigger=true) const
Performs the memory copy from host to device.
Definition CSysVectorGPU.cu:193
void Initialize(unsigned long numBlk, unsigned long numBlkDomain, unsigned long numVar, const ScalarType *ptr)
Initialize the class with an array.
Definition CSysVector.hpp:370
const ScalarType * GetHostPointer() const
return host pointer that points to the CSysVector values, counterpart of GetDevicePointer
Definition CSysVector.hpp:415
CSysVector()=default
Required by CVecExpr.
void SubtractBlock(unsigned long iPoint, const VectorType &block)
Subtract "block" from the vector, see AddBlock.
Definition CSysVector.hpp:639
ScalarType * GetBlock(unsigned long iPoint)
Get pointer to a block.
Definition CSysVector.hpp:600
static const su2matrix< ScalarType > & multiDot(const std::vector< CSysVector > &V, size_t i0, size_t n, const std::vector< CSysVector > &W, size_t m)
Computes the product of V^T W efficiencly, where V and W are tall matrices stored as vectors of CSysV...
Definition CSysVector.cpp:74
unsigned long GetLocSize() const
return the number of local elements in the CSysVector
Definition CSysVector.hpp:420
ScalarType & operator()(unsigned long iPoint, unsigned long iVar)
Access operator with assignment permitted block version.
Definition CSysVector.hpp:462
ScalarType dot(const VecExpr::CVecExpr< T, ScalarType > &expr) const
Dot product between "this" and an expression.
Definition CSysVector.hpp:526
void SetBlock_Zero(unsigned long iPoint)
Set the values to zero for one block.
Definition CSysVector.hpp:607
void SetValZero(void)
Sets to zero all the entries of the vector.
Definition CSysVector.hpp:518
void AddBlock(unsigned long iPoint, const VectorType &block, ScalarType alpha=1)
Add "block" to the vector, see SetBlock.
Definition CSysVector.hpp:631
const ScalarType * end() const
Definition CSysVector.hpp:454
const ScalarType & operator[](unsigned long i) const
Definition CSysVector.hpp:448
void UpdateBlocks(unsigned long iPoint, unsigned long jPoint, const VectorType &block, ScalarType alpha=1)
Add to iPoint, subtract from jPoint.
Definition CSysVector.hpp:647
void PassiveCopy(const CSysVector< T > &other)
Set our values (resizing if required) by copying from other, the derivative information is lost.
Definition CSysVector.hpp:379
unsigned long GetNVar() const
return the number of variables at each block (typically number per node)
Definition CSysVector.hpp:430
void SetBlock(unsigned long iPoint, const VectorType &block, ScalarType alpha=1)
Set "block" to the vector.
Definition CSysVector.hpp:619
static constexpr bool StoreAsRef
Definition CSysVector.hpp:283
const ScalarType * begin() const
Iterators for range for loops.
Definition CSysVector.hpp:453
const ScalarType * GetBlock(unsigned long iPoint) const
Definition CSysVector.hpp:601
CSysVector(unsigned long numBlk, unsigned long numBlkDomain, unsigned long numVar, const ScalarType *u_array)
Constructor from array (block version).
Definition CSysVector.hpp:327
CSysVector(unsigned long size, ScalarType val=0.0)
Construct from size and value.
Definition CSysVector.hpp:300
Expression class to broadcast a scalar value. Allows implementing "vector-scalar" operations re-using...
Definition vector_expressions.hpp:75
Base vector expression class.
Definition vector_expressions.hpp:58
const Derived & derived() const
Cast the expression to Derived, usually to allow evaluation via operator[].
Definition vector_expressions.hpp:63
How a CSysVector is captured inside an expression: a bare pointer to whichever storage the expression...
Definition CSysVector.hpp:133
CVectorView(const CSysVector< Scalar > &vector)
Definition CSysVector.hpp:704
static constexpr bool StoreAsRef
Definition CSysVector.hpp:138
const Scalar & operator[](size_t i) const
Definition CSysVector.hpp:142
A simple SIMD type relying on implicit vectorization, i.e. done by the compiler, explicitly vectorize...
Definition vectorization.hpp:89
#define SU2_CUDA_HOST_DEVICE
Definition code_config.hpp:57
#define FORCEINLINE
Definition code_config.hpp:44
FORCEINLINE ARRAY_T sqrt(const ARRAY_T &x)
Definition special_vectorization.hpp:116
typename store_type< T >::type store_t
Definition vector_expressions.hpp:109
#define MPI_FLOAT
Definition mpi_structure.hpp:483
#define MPI_SUM
Definition mpi_structure.hpp:486
#define MPI_DOUBLE
Definition mpi_structure.hpp:484
passivedouble GetValue(const su2double &data)
Get the (primitive) value of the datatype (needs to be specialized for active types).
Definition datatype_structure.hpp:113
Definition CSysVector.hpp:104
bool UseDeviceExpressions()
Whether vector expressions are currently evaluated on the device.
Definition CSysVector.hpp:119
void SetUseDeviceExpressions(bool)
Definition CSysVector.hpp:120
void AssignDeviceExpression(Scalar *data, unsigned long size, const CVecExpr< T, Scalar > &expr)
DeviceAssignOp
Definition CSysVector.hpp:106
#define BEGIN_SU2_OMP_SAFE_GLOBAL_ACCESS
Definition omp_structure.hpp:187
constexpr int omp_get_num_threads()
Number of threads in current team.
Definition omp_structure.hpp:75
#define END_SU2_OMP_SAFE_GLOBAL_ACCESS
Definition omp_structure.hpp:192
#define SU2_OMP_BARRIER
Definition omp_structure.hpp:142
#define SU2_OMP_SAFE_GLOBAL_ACCESS(...)
Definition omp_structure.hpp:197
constexpr int omp_get_thread_num()
Index of current thread, akin to MPI rank.
Definition omp_structure.hpp:85
#define SU2_OMP_SIMD
Definition omp_structure.hpp:125
#define SU2_OMP_SIMD_IF_NOT_AD
Definition omp_structure.hpp:129
@ V
Menter k-w SST model with vorticity production terms.
@ W
W-cycle multigrid solver.
Definition vector_expressions.hpp:105
Expression templates for vector types with coefficient-wise operations.