safe_conversion.hpp
Go to the documentation of this file.
1/*
2 Copyright 2023 SINTEF AS
3
4 This file is part of the Open Porous Media project (OPM).
5
6 OPM is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 OPM is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with OPM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#ifndef OPM_CUISTL_SAFE_CONVERSION_HPP
20#define OPM_CUISTL_SAFE_CONVERSION_HPP
21
22#include <opm/common/ErrorMacros.hpp>
23
24#include <cstddef>
25#include <limits>
26#include <type_traits>
27#include <cuda_runtime.h>
28
29#if CUDA_VERSION >= 12100
30#include <fmt/format.h>
31#else
32#include <sstream>
33#endif
34
35
45{
46
55inline int
56to_int(std::size_t s)
57{
58 static_assert(
59 std::is_signed_v<int>,
60 "Weird architecture or my understanding of the standard is flawed. Better have a look at this function.");
61 static_assert(
62 !std::is_signed_v<std::size_t>,
63 "Weird architecture or my understanding of the standard is flawed. Better have a look at this function.");
64
65 static_assert(
66 sizeof(int) <= sizeof(std::size_t),
67 "Weird architecture or my understanding of the standard is flawed. Better have a look at this function.");
68
69
70 if (s > std::size_t(std::numeric_limits<int>::max())) {
71#if CUDA_VERSION >= 12100
72 OPM_THROW(std::invalid_argument,
73 fmt::format(fmt::runtime("Trying to convert {} to int, but it is out of range. Maximum possible int: {}. "),
74 s,
75 std::numeric_limits<int>::max()));
76#else
77 std::stringstream str;
78 str << "Trying to convert " << s << " to int, but it is out of range. Maximum possible int: "
79 << std::numeric_limits<int>::max() << " .";
80 OPM_THROW(std::invalid_argument, str.str());
81#endif
82 }
83
84 // We know it will be in range here:
85 return int(s);
86}
87
96__host__ __device__ inline std::size_t
98{
99 static_assert(
100 std::is_signed_v<int>,
101 "Weird architecture or my understanding of the standard is flawed. Better have a look at this function.");
102 static_assert(
103 !std::is_signed_v<std::size_t>,
104 "Weird architecture or my understanding of the standard is flawed. Better have a look at this function.");
105
106 static_assert(
107 sizeof(int) <= sizeof(std::size_t),
108 "Weird architecture or my understanding of the standard is flawed. Better have a look at this function.");
109
110#if defined(__CUDA_ARCH__) || defined(__HIP_DEVICE_COMPILE__)
111 assert(i >= int(0));
112#else
113 if (i < int(0)) {
114#if CUDA_VERSION >= 12100
115 OPM_THROW(std::invalid_argument, fmt::format(fmt::runtime("Trying to convert the negative number {} to size_t."), i));
116#else
117 std::stringstream str;
118 str << "Trying to convert the negative number " << i << " to size_t.";
119 OPM_THROW(std::invalid_argument, str.str());
120#endif
121 }
122#endif
123
124 return std::size_t(i);
125}
126} // namespace Opm::gpuistl::detail
127
128#endif
Definition: autotuner.hpp:30
int to_int(std::size_t s)
to_int converts a (on most relevant platforms) 64 bits unsigned size_t to a signed 32 bits signed int
Definition: safe_conversion.hpp:56
__host__ __device__ std::size_t to_size_t(int i)
to_size_t converts a (on most relevant platforms) a 32 bit signed int to a 64 bits unsigned int
Definition: safe_conversion.hpp:97