Loading...
Searching...
No Matches
opennn_types.h
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-only
2// Copyright (C) 2026 Artificial Intelligence Techniques, S.L. and Roberto López González
3
4#pragma once
5#ifndef OPENNN_TYPES_H_
6#define OPENNN_TYPES_H_
7
8#if defined(__INTELLISENSE__) && !defined(OPENNN_HAS_CUDA)
9#define OPENNN_HAS_CUDA
10#endif
11
12#ifndef EIGEN_USE_THREADS
13#define EIGEN_USE_THREADS
14#endif
15#ifndef EIGEN_MAX_ALIGN_BYTES
16#define EIGEN_MAX_ALIGN_BYTES 64
17#endif
18#ifndef EIGEN_NO_DEBUG
19#define EIGEN_NO_DEBUG
20#endif
21#ifndef NOMINMAX
22#define NOMINMAX
23#endif
24#define _SILENCE_CXX17_ITERATOR_BASE_CLASS_DEPRECATION_WARNING
25#define _CRT_SECURE_NO_WARNINGS
26#define EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
27#define _SILENCE_EXPERIMENTAL_FILESYSTEM_DEPRECATION_WARNING
28
29#include <algorithm>
30#include <cassert>
31#include <cmath>
32#include <cstdint>
33#include <cstdlib>
34#include <cstring>
35#include <ctime>
36#include <exception>
37#include <filesystem>
38#include <format>
39#include <fstream>
40#include <functional>
41#include <iomanip>
42#include <iostream>
43#include <iterator>
44#include <map>
45#include <memory>
46#include <numeric>
47#include <optional>
48#include <random>
49#include <set>
50#include <source_location>
51#include <span>
52#include <sstream>
53#include <stdexcept>
54#include <string>
55#include <string_view>
56#include <tuple>
57#include <unordered_map>
58#include <unordered_set>
59#include <utility>
60#include <vector>
61
62#include <Eigen/Core>
63#include <unsupported/Eigen/CXX11/Tensor>
64
65#ifdef OPENNN_HAS_CUDA
66
67#include <cuda.h>
68#include <cuda_runtime.h>
69#include <cublas_v2.h>
70#include <cublasLt.h>
71#include <cudnn.h>
72#include <cuda_bf16.h>
73
74using namespace std;
75
76template <typename T>
77void check_cuda_status(T status, const char* msg,
78 source_location loc = source_location::current())
79{
80 if (status != 0)
81 throw runtime_error(string(msg) + " Error: " + to_string(static_cast<int>(status)) +
82 " in " + loc.file_name() + ":" + to_string(loc.line()));
83}
84
85#define CHECK_CUDA(x) check_cuda_status(x, "CUDA")
86#define CHECK_CUBLAS(x) check_cuda_status(x, "CuBLAS")
87#define CHECK_CUDNN(x) check_cuda_status(x, "cuDNN")
88
89#else
90
91using cudaStream_t = void*;
92using cudaEvent_t = void*;
93using cudaGraph_t = void*;
94using cudaGraphExec_t = void*;
95using cublasHandle_t = void*;
96using cublasLtHandle_t = void*;
97using cudnnHandle_t = void*;
98using cublasLtMatmulDesc_t = void*;
99using cublasLtMatrixLayout_t = void*;
100struct cublasLtMatmulAlgo_t {};
101
102struct __nv_bfloat16 { unsigned short __x; };
103struct __half { unsigned short __x; };
104
105enum cudaDataType_t { CUDA_R_32F = 0, CUDA_R_16F = 2, CUDA_R_8I = 3, CUDA_R_32I = 10, CUDA_R_16BF = 14 };
106enum cublasComputeType_t { CUBLAS_COMPUTE_32F = 68, CUBLAS_COMPUTE_32F_FAST_16BF = 75, CUBLAS_COMPUTE_32F_FAST_TF32 = 77 };
107enum cublasOperation_t { CUBLAS_OP_N = 0, CUBLAS_OP_T = 1 };
108enum cublasLtEpilogue_t { CUBLASLT_EPILOGUE_DEFAULT = 1, CUBLASLT_EPILOGUE_RELU = 2, CUBLASLT_EPILOGUE_BIAS = 4, CUBLASLT_EPILOGUE_RELU_BIAS = 6, CUBLASLT_EPILOGUE_RELU_AUX_BIAS = 134, CUBLASLT_EPILOGUE_DRELU = 136, CUBLASLT_EPILOGUE_GELU_AUX_BIAS = 164 };
109
110enum cudnnDataType_t { CUDNN_DATA_FLOAT = 0, CUDNN_DATA_HALF = 2, CUDNN_DATA_INT8 = 3, CUDNN_DATA_INT32 = 4, CUDNN_DATA_BFLOAT16 = 9 };
111
112struct cudnnTensorStruct {};
113using cudnnTensorDescriptor_t = cudnnTensorStruct*;
114struct cudnnPoolingStruct {};
115using cudnnPoolingDescriptor_t = cudnnPoolingStruct*;
116using cudnnDropoutDescriptor_t = void*;
117using cudnnOpTensorDescriptor_t = void*;
118using cudnnRNNDescriptor_t = void*;
119using cudnnRNNDataDescriptor_t = void*;
120
121#endif
122
123#define OPENNN_CUDA_STUB_BODY(name) { throw runtime_error(#name " requires CUDA support."); }
124#define OPENNN_CUDA_STUB(ret, name, sig) static ret name sig OPENNN_CUDA_STUB_BODY(name)
125
126#define OPENNN_CUDA_TEMPLATE_STUB(name) template<typename... Ts, typename... As> static void name(As&&...) OPENNN_CUDA_STUB_BODY(name)
127
128using namespace std;
129using Eigen::Index;
130
131using type = float;
132
133namespace opennn {
134
135using DeviceStream = cudaStream_t;
136using DeviceEvent = cudaEvent_t;
137using DeviceGraph = cudaGraph_t;
138using DeviceGraphExec = cudaGraphExec_t;
139using BlasHandle = cublasHandle_t;
140using BlasLtHandle = cublasLtHandle_t;
141using DnnHandle = cudnnHandle_t;
142using DnnOpTensorDescriptor = cudnnOpTensorDescriptor_t;
143using DnnDataType = cudnnDataType_t;
144#ifdef OPENNN_HAS_CUDA
145using DnnStatus = cudnnStatus_t;
146#else
147using DnnStatus = int;
148#endif
149using DnnTensorDescriptor = cudnnTensorDescriptor_t;
150using DnnRNNDataDescriptor = cudnnRNNDataDescriptor_t;
151using DnnRNNDescriptor = cudnnRNNDescriptor_t;
152using DnnDropoutDescriptor = cudnnDropoutDescriptor_t;
153using DnnPoolingDescriptor = cudnnPoolingDescriptor_t;
154#ifdef OPENNN_HAS_CUDA
155using DnnRNNMode = cudnnRNNMode_t;
156#else
157using DnnRNNMode = int;
158#endif
159using BlasComputeType = cublasComputeType_t;
160#ifdef OPENNN_HAS_CUDA
161using BlasPointerMode = cublasPointerMode_t;
162using BlasMathMode = cublasMath_t;
163#else
164using BlasPointerMode = int;
165using BlasMathMode = int;
166#endif
167using BlasOperation = cublasOperation_t;
168using DeviceDataType = cudaDataType_t;
169
170using namespace Eigen;
171using bfloat16 = __nv_bfloat16;
172
173inline float bfloat16_to_float_host(const uint16_t value)
174{
175 return bit_cast<float>(uint32_t(value) << 16);
176}
177
178inline uint16_t float_to_bfloat16_host(const float value)
179{
180 uint32_t bits = bit_cast<uint32_t>(value);
181 if ((bits & 0x7FFFFFFFu) > 0x7F800000u)
182 return uint16_t((bits >> 16) | 0x0040u);
183
184 bits += 0x7FFFu + ((bits >> 16) & 1u);
185 return uint16_t(bits >> 16);
186}
187
188inline void float_2_bfloat16_host(const Index count,
189 const float* source,
190 uint16_t* destination)
191{
192 #pragma omp parallel for if(count > 4096)
193 for (Index i = 0; i < count; ++i)
194 destination[i] = float_to_bfloat16_host(source[i]);
195}
196
197using type = float;
198
199class Json;
200class JsonDocument;
201class JsonWriter;
202
203namespace detail
204{
205
206#if defined(__CUDA_ARCH__)
207
208template<typename Message, typename... Args>
209[[noreturn]] __device__ inline void throw_formatted(Message&&, Args&&...)
210{
211 __trap();
212}
213
214#else
215
216[[noreturn]] inline void throw_formatted(string_view message,
217 const source_location& loc = source_location::current())
218{
219 // The file name, never the path it was built from. The applications show this
220 // text to the user exactly as it arrives, so the full path would put the build
221 // machine's directory layout in a dialog on someone else's computer.
222 const string_view file = loc.file_name();
223 const size_t separator = file.find_last_of("/\\");
224
225 throw runtime_error(format("{} [at {}:{}]",
226 message,
227 separator == string_view::npos
228 ? file
229 : file.substr(separator + 1),
230 loc.line()));
231}
232
233template<typename... Args>
234[[noreturn]] inline void throw_formatted(format_string<Args...> message, Args&&... args)
235{
236 throw runtime_error(format(message, std::forward<Args>(args)...));
237}
238
239#endif
240
241}
242
243#define throw_if(condition, ...) do { if (condition) ::opennn::detail::throw_formatted(__VA_ARGS__); } while (false)
244
245namespace detail
246{
247
248template<typename Map>
249void make_bounded_cache_room(Map& entries, const size_t capacity)
250{
251 throw_if(capacity == 0, "A bounded cache requires a positive capacity.");
252
253 if (entries.size() >= capacity)
254 entries.erase(entries.begin());
255}
256
257template<typename Map, typename Key>
258typename Map::mapped_type& bounded_cache_entry(Map& entries,
259 const Key& key,
260 const size_t capacity)
261{
262 if (const auto found = entries.find(key); found != entries.end())
263 return found->second;
264
265 make_bounded_cache_room(entries, capacity);
266
267 return entries.try_emplace(key).first->second;
268}
269
270}
271
272template <typename T, typename... Candidates>
273constexpr bool is_one_of(const T& value, const Candidates&... candidates)
274{
275 return ((value == candidates) || ...);
276}
277
278template <typename F>
280{
281public:
282
283 explicit ScopeExit(F new_cleanup)
284 : cleanup(std::move(new_cleanup))
285 {
286 }
287
288 ~ScopeExit() noexcept
289 {
290 if (!active) return;
291 try { cleanup(); }
292 catch (...) {}
293 }
294
295 ScopeExit(const ScopeExit&) = delete;
296 ScopeExit& operator=(const ScopeExit&) = delete;
297
298 void release() noexcept { active = false; }
299
300private:
301
302 F cleanup;
303 bool active = true;
304};
305
306template <typename F> ScopeExit(F) -> ScopeExit<F>;
307
308constexpr float EPSILON = numeric_limits<float>::epsilon();
309constexpr float MAX = numeric_limits<float>::max();
310constexpr float POS_INFINITY = numeric_limits<float>::infinity();
311constexpr float NEG_INFINITY = -numeric_limits<float>::infinity();
312constexpr float QUIET_NAN = numeric_limits<float>::quiet_NaN();
313constexpr float SOFTMAX_MASK_VALUE = float(-1e9f);
314
315template <typename T>
316ostream& operator<<(ostream& os, const vector<T>& vec)
317{
318 os << "[ ";
319 for (size_t i = 0; i < vec.size(); ++i)
320 {
321 os << vec[i];
322 if (i + 1 < vec.size()) os << "; ";
323 }
324 os << " ]";
325 return os;
326}
327}
328
329constexpr int Layout = Eigen::RowMajor;
330
331using MatrixR = Eigen::Matrix<float, Eigen::Dynamic, Eigen::Dynamic, Layout>;
332using MatrixI = Eigen::Matrix<Index, Eigen::Dynamic, Eigen::Dynamic, Layout>;
333using MatrixB = Eigen::Matrix<bool, Eigen::Dynamic, Eigen::Dynamic, Layout>;
334
335using VectorR = Eigen::Matrix<float, Eigen::Dynamic, 1>;
336using VectorI = Eigen::Matrix<Index, Eigen::Dynamic, 1>;
337using VectorB = Eigen::Matrix<bool, Eigen::Dynamic, 1>;
338
339using VectorMap = Eigen::Map<VectorR, Eigen::AlignedMax>;
340using ConstVectorMap = Eigen::Map<const VectorR, Eigen::AlignedMax>;
341using ConstUnalignedVectorMap = Eigen::Map<const VectorR>;
342using MatrixMap = Eigen::Map<MatrixR, Eigen::AlignedMax>;
343
344inline ConstUnalignedVectorMap as_vector_map(const span<const float> values)
345{
346 return ConstUnalignedVectorMap(values.data(), Index(values.size()));
347}
348
349using Tensor0 = Eigen::Tensor<float, 0, Layout | Eigen::AlignedMax>;
350using Tensor1 = Eigen::Tensor<float, 1, Layout | Eigen::AlignedMax>;
351using Tensor2 = Eigen::Tensor<float, 2, Layout | Eigen::AlignedMax>;
352using Tensor3 = Eigen::Tensor<float, 3, Layout | Eigen::AlignedMax>;
353using Tensor4 = Eigen::Tensor<float, 4, Layout | Eigen::AlignedMax>;
354
355template <int Rank>
356using TensorR = Eigen::Tensor<float, Rank, Layout | Eigen::AlignedMax>;
357
358using TensorMap3 = Eigen::TensorMap<Eigen::Tensor<float, 3, Layout | Eigen::AlignedMax>, Eigen::AlignedMax>;
359using TensorMap4 = Eigen::TensorMap<Eigen::Tensor<float, 4, Layout | Eigen::AlignedMax>, Eigen::AlignedMax>;
360
361template <int Rank>
362using TensorMapR = Eigen::TensorMap<Eigen::Tensor<float, Rank, Layout | Eigen::AlignedMax>, Eigen::AlignedMax>;
363
364#endif
Definition json.h:75
Definition json.h:92
Definition json.h:24
Definition opennn_types.h:280
ScopeExit & operator=(const ScopeExit &)=delete
~ScopeExit() noexcept
Definition opennn_types.h:288
ScopeExit(F new_cleanup)
Definition opennn_types.h:283
void release() noexcept
Definition opennn_types.h:298
ScopeExit(const ScopeExit &)=delete
Definition opennn_types.h:204
Map::mapped_type & bounded_cache_entry(Map &entries, const Key &key, const size_t capacity)
Definition opennn_types.h:258
void throw_formatted(string_view message, const source_location &loc=source_location::current())
Definition opennn_types.h:216
void make_bounded_cache_room(Map &entries, const size_t capacity)
Definition opennn_types.h:249
Definition configuration.h:10
constexpr float POS_INFINITY
Definition opennn_types.h:310
cudaDataType_t DeviceDataType
Definition opennn_types.h:168
@ Eigen
Definition configuration.h:37
constexpr float MAX
Definition opennn_types.h:309
constexpr float NEG_INFINITY
Definition opennn_types.h:311
cudaGraph_t DeviceGraph
Definition opennn_types.h:137
cudnnRNNDataDescriptor_t DnnRNNDataDescriptor
Definition opennn_types.h:150
constexpr float EPSILON
Definition opennn_types.h:308
cudaGraphExec_t DeviceGraphExec
Definition opennn_types.h:138
cublasLtHandle_t BlasLtHandle
Definition opennn_types.h:140
cudnnTensorDescriptor_t DnnTensorDescriptor
Definition opennn_types.h:149
cudnnRNNMode_t DnnRNNMode
Definition opennn_types.h:155
constexpr float SOFTMAX_MASK_VALUE
Definition opennn_types.h:313
cudnnPoolingDescriptor_t DnnPoolingDescriptor
Definition opennn_types.h:153
cudnnStatus_t DnnStatus
Definition opennn_types.h:145
cudnnHandle_t DnnHandle
Definition opennn_types.h:141
cudnnOpTensorDescriptor_t DnnOpTensorDescriptor
Definition opennn_types.h:142
constexpr bool is_one_of(const T &value, const Candidates &... candidates)
Definition opennn_types.h:273
constexpr float QUIET_NAN
Definition opennn_types.h:312
cudnnDropoutDescriptor_t DnnDropoutDescriptor
Definition opennn_types.h:152
cudnnRNNDescriptor_t DnnRNNDescriptor
Definition opennn_types.h:151
ostream & operator<<(ostream &os, const vector< T > &vec)
Definition opennn_types.h:316
cudnnDataType_t DnnDataType
Definition opennn_types.h:143
ScopeExit(F) -> ScopeExit< F >
cudaEvent_t DeviceEvent
Definition opennn_types.h:136
cublasComputeType_t BlasComputeType
Definition opennn_types.h:159
uint16_t float_to_bfloat16_host(const float value)
Definition opennn_types.h:178
cublasMath_t BlasMathMode
Definition opennn_types.h:162
cudaStream_t DeviceStream
Definition opennn_types.h:135
cublasHandle_t BlasHandle
Definition opennn_types.h:139
float bfloat16_to_float_host(const uint16_t value)
Definition opennn_types.h:173
cublasOperation_t BlasOperation
Definition opennn_types.h:167
void float_2_bfloat16_host(const Index count, const float *source, uint16_t *destination)
Definition opennn_types.h:188
__nv_bfloat16 bfloat16
Definition opennn_types.h:171
float type
Definition opennn_types.h:197
cublasPointerMode_t BlasPointerMode
Definition opennn_types.h:161
float type
Definition opennn_types.h:131
ConstUnalignedVectorMap as_vector_map(const span< const float > values)
Definition opennn_types.h:344
Eigen::Matrix< float, Eigen::Dynamic, 1 > VectorR
Definition opennn_types.h:335
Eigen::TensorMap< Eigen::Tensor< float, 4, Layout|Eigen::AlignedMax >, Eigen::AlignedMax > TensorMap4
Definition opennn_types.h:359
Eigen::TensorMap< Eigen::Tensor< float, Rank, Layout|Eigen::AlignedMax >, Eigen::AlignedMax > TensorMapR
Definition opennn_types.h:362
Eigen::Matrix< float, Eigen::Dynamic, Eigen::Dynamic, Layout > MatrixR
Definition opennn_types.h:331
Eigen::Map< const VectorR, Eigen::AlignedMax > ConstVectorMap
Definition opennn_types.h:340
Eigen::Map< VectorR, Eigen::AlignedMax > VectorMap
Definition opennn_types.h:339
Eigen::Matrix< Index, Eigen::Dynamic, Eigen::Dynamic, Layout > MatrixI
Definition opennn_types.h:332
Eigen::Tensor< float, 3, Layout|Eigen::AlignedMax > Tensor3
Definition opennn_types.h:352
Eigen::Tensor< float, 4, Layout|Eigen::AlignedMax > Tensor4
Definition opennn_types.h:353
Eigen::Matrix< bool, Eigen::Dynamic, 1 > VectorB
Definition opennn_types.h:337
void check_cuda_status(T status, const char *msg, source_location loc=source_location::current())
Definition opennn_types.h:77
Eigen::Matrix< Index, Eigen::Dynamic, 1 > VectorI
Definition opennn_types.h:336
Eigen::Tensor< float, 2, Layout|Eigen::AlignedMax > Tensor2
Definition opennn_types.h:351
Eigen::Tensor< float, 0, Layout|Eigen::AlignedMax > Tensor0
Definition opennn_types.h:349
#define throw_if(condition,...)
Definition opennn_types.h:243
Eigen::Map< const VectorR > ConstUnalignedVectorMap
Definition opennn_types.h:341
Eigen::TensorMap< Eigen::Tensor< float, 3, Layout|Eigen::AlignedMax >, Eigen::AlignedMax > TensorMap3
Definition opennn_types.h:358
Eigen::Tensor< float, Rank, Layout|Eigen::AlignedMax > TensorR
Definition opennn_types.h:356
Eigen::Map< MatrixR, Eigen::AlignedMax > MatrixMap
Definition opennn_types.h:342
Eigen::Matrix< bool, Eigen::Dynamic, Eigen::Dynamic, Layout > MatrixB
Definition opennn_types.h:333
constexpr int Layout
Definition opennn_types.h:329
Eigen::Tensor< float, 1, Layout|Eigen::AlignedMax > Tensor1
Definition opennn_types.h:350