MFEM v4.7.0
Finite element discretization library
Loading...
Searching...
No Matches
dtensor.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2024, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_DTENSOR
13#define MFEM_DTENSOR
14
16
17namespace mfem
18{
19
20/// A Class to compute the real index from the multi-indices of a tensor
21template <int N, int Dim, typename T, typename... Args>
23{
24public:
25 MFEM_HOST_DEVICE
26 static inline int result(const int* sizes, T first, Args... args)
27 {
28#if !(defined(MFEM_USE_CUDA) || defined(MFEM_USE_HIP))
29 MFEM_ASSERT(first<sizes[N-1],"Trying to access out of boundary.");
30#endif
31 return static_cast<int>(first + sizes[N - 1] * TensorInd < N + 1, Dim, Args... >
32 ::result(sizes, args...));
33 }
34};
35
36// Terminal case
37template <int Dim, typename T, typename... Args>
38class TensorInd<Dim, Dim, T, Args...>
39{
40public:
41 MFEM_HOST_DEVICE
42 static inline int result(const int* sizes, T first, Args... args)
43 {
44#if !(defined(MFEM_USE_CUDA) || defined(MFEM_USE_HIP))
45 MFEM_ASSERT(first<sizes[Dim-1],"Trying to access out of boundary.");
46#endif
47 return static_cast<int>(first);
48 }
49};
50
51
52/// A class to initialize the size of a Tensor
53template <int N, int Dim, typename T, typename... Args>
54class Init
55{
56public:
57 MFEM_HOST_DEVICE
58 static inline int result(int* sizes, T first, Args... args)
59 {
60 sizes[N - 1] = first;
61 return first * Init < N + 1, Dim, Args... >::result(sizes, args...);
62 }
63};
64
65// Terminal case
66template <int Dim, typename T, typename... Args>
67class Init<Dim, Dim, T, Args...>
68{
69public:
70 MFEM_HOST_DEVICE
71 static inline int result(int* sizes, T first, Args... args)
72 {
73 sizes[Dim - 1] = first;
74 return first;
75 }
76};
77
78
79/// A basic generic Tensor class, appropriate for use on the GPU
80template<int Dim, typename Scalar = real_t>
82{
83protected:
85 Scalar *data;
86 int sizes[Dim];
87
88public:
89 /// Default constructor
90 DeviceTensor() = delete;
91
92 /// Constructor to initialize a tensor from the Scalar array data_
93 template <typename... Args> MFEM_HOST_DEVICE
94 DeviceTensor(Scalar* data_, Args... args)
95 {
96 static_assert(sizeof...(args) == Dim, "Wrong number of arguments");
97 // Initialize sizes, and compute the number of values
98 const long int nb = Init<1, Dim, Args...>::result(sizes, args...);
99 capacity = nb;
100 data = (capacity > 0) ? data_ : NULL;
101 }
102
103 /// Copy constructor (default)
104 DeviceTensor(const DeviceTensor&) = default;
105
106 /// Copy assignment (default)
108
109 /// Conversion to `Scalar *`.
110 MFEM_HOST_DEVICE inline operator Scalar *() const { return data; }
111
112 /// Const accessor for the data
113 template <typename... Args> MFEM_HOST_DEVICE inline
114 Scalar& operator()(Args... args) const
115 {
116 static_assert(sizeof...(args) == Dim, "Wrong number of arguments");
118 }
119
120 /// Subscript operator where the tensor is viewed as a 1D array.
121 MFEM_HOST_DEVICE inline Scalar& operator[](int i) const
122 {
123 return data[i];
124 }
125};
126
127
128/** @brief Wrap a pointer as a DeviceTensor with automatically deduced template
129 parameters */
130template <typename T, typename... Dims> MFEM_HOST_DEVICE
131inline DeviceTensor<sizeof...(Dims),T> Reshape(T *ptr, Dims... dims)
132{
133 return DeviceTensor<sizeof...(Dims),T>(ptr, dims...);
134}
135
136
139
142
145
148
149} // mfem namespace
150
151#endif // MFEM_DTENSOR
A basic generic Tensor class, appropriate for use on the GPU.
Definition dtensor.hpp:82
DeviceTensor(const DeviceTensor &)=default
Copy constructor (default)
MFEM_HOST_DEVICE Scalar & operator[](int i) const
Subscript operator where the tensor is viewed as a 1D array.
Definition dtensor.hpp:121
MFEM_HOST_DEVICE DeviceTensor(Scalar *data_, Args... args)
Constructor to initialize a tensor from the Scalar array data_.
Definition dtensor.hpp:94
DeviceTensor()=delete
Default constructor.
DeviceTensor & operator=(const DeviceTensor &)=default
Copy assignment (default)
MFEM_HOST_DEVICE Scalar & operator()(Args... args) const
Const accessor for the data.
Definition dtensor.hpp:114
static MFEM_HOST_DEVICE int result(int *sizes, T first, Args... args)
Definition dtensor.hpp:71
A class to initialize the size of a Tensor.
Definition dtensor.hpp:55
static MFEM_HOST_DEVICE int result(int *sizes, T first, Args... args)
Definition dtensor.hpp:58
static MFEM_HOST_DEVICE int result(const int *sizes, T first, Args... args)
Definition dtensor.hpp:42
A Class to compute the real index from the multi-indices of a tensor.
Definition dtensor.hpp:23
static MFEM_HOST_DEVICE int result(const int *sizes, T first, Args... args)
Definition dtensor.hpp:26
DeviceTensor< 2, real_t > DeviceMatrix
Definition dtensor.hpp:143
DeviceTensor< 1, const int > ConstDeviceArray
Definition dtensor.hpp:138
MFEM_HOST_DEVICE DeviceTensor< sizeof...(Dims), T > Reshape(T *ptr, Dims... dims)
Wrap a pointer as a DeviceTensor with automatically deduced template parameters.
Definition dtensor.hpp:131
DeviceTensor< 2, const real_t > ConstDeviceMatrix
Definition dtensor.hpp:144
DeviceTensor< 3, const real_t > ConstDeviceCube
Definition dtensor.hpp:147
DeviceTensor< 1, real_t > DeviceVector
Definition dtensor.hpp:140
kernels::InvariantsEvaluator2D::Buffers Args
DeviceTensor< 1, int > DeviceArray
Definition dtensor.hpp:137
DeviceTensor< 1, const real_t > ConstDeviceVector
Definition dtensor.hpp:141
DeviceTensor< 3, real_t > DeviceCube
Definition dtensor.hpp:146