Extended CUDA Library (ecuda)  2.0
 All Classes Namespaces Files Functions Variables Typedefs Friends Macros
global.hpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2014-2016, Scott Zuyderduyn
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7 
8 1. Redistributions of source code must retain the above copyright notice, this
9  list of conditions and the following disclaimer.
10 2. Redistributions in binary form must reproduce the above copyright notice,
11  this list of conditions and the following disclaimer in the documentation
12  and/or other materials provided with the distribution.
13 
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
15 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
17 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
18 ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
19 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
20 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
21 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
23 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 
25 The views and conclusions contained in the software and documentation are those
26 of the authors and should not be interpreted as representing official policies,
27 either expressed or implied, of the FreeBSD Project.
28 */
29 
30 //----------------------------------------------------------------------------
31 // global.hpp
32 //
33 // Global defines and macros.
34 //
35 // Author: Scott D. Zuyderduyn, Ph.D. (scott.zuyderduyn@utoronto.ca)
36 //----------------------------------------------------------------------------
37 
38 #pragma once
39 #ifndef ECUDA_GLOBAL_HPP
40 #define ECUDA_GLOBAL_HPP
41 
42 #include <stdexcept>
43 #include <sstream>
44 
50 
51 // idea taken from the VTK-m project (https://gitlab.kitware.com/vtk/vtk-m)
52 // to suppress annoying warnings from the compiler about calling __host__
53 // code from a __host__ __device__ function
54 #ifdef __CUDACC__
55 #define ECUDA_SUPPRESS_HD_WARNINGS \
56  #pragma hd_warning_disable
57 #else
58 #define ECUDA_SUPPRESS_HD_WARNINGS
59 #endif
60 
61 #include "impl/host_emulation.hpp" // host-only replacements of CUDA C API functions
62 #include "cuda_error.hpp" // specialized std::exception for ecuda/CUDA runtime errors
63 
64 // Generic check for C++11 support
65 #if __cplusplus >= 201103L || defined(__GXX_EXPERIMENTAL_CXX0X__) // latter check works for GCC 4.6 because it has a bad __cplusplus flag
66 #define ECUDA_CPP11_AVAILABLE
67 #endif
68 // Windows check for C++11 support (Visual Studio 2013 and greater)
69 #if defined(_MSC_VER) && _MSC_VER >= 1800 // Visual Studio 2013
70 #define ECUDA_CPP11_AVAILABLE
71 #endif
72 
73 #ifdef __CUDACC__
74 // Macro function currently throws an ecuda::cuda_error exception containing a
75 // description of the problem error code.
76 #define CUDA_CALL(x) do { if((x)!=cudaSuccess) { std::ostringstream oss; oss << __FILE__; oss << ":"; oss << __LINE__; oss << " "; oss << cudaGetErrorString(cudaGetLastError()); throw ::ecuda::cuda_error(x,oss.str()); /*std::runtime_error(oss.str());*/ }} while(0);
77 #else
78 #define CUDA_CALL(x) x // cannot do CUDA calls when emulating with host only
84 #endif
85 
86 #define S(x) #x
87 #define S_(x) S(x)
88 #define S__LINE__ S_(__LINE__)
89 #define EXCEPTION_MSG(x) "" __FILE__ ":" S__LINE__ " " x
93 
94 #ifdef __CUDACC__
95 #define CUDA_CHECK_ERRORS() do { cudaError_t error = cudaGetLastError(); if( error != cudaSuccess ) throw ::ecuda::cuda_error(error,std::string(cudaGetErrorString(error))); } while(0);
96 #else
97 #define CUDA_CHECK_ERRORS() do {} while(0); // cannot check CUDA errors when emulating with host only
104 #endif
105 
106 #ifdef __CUDACC__
107 #define CUDA_CALL_KERNEL_AND_WAIT(...) do {\
108  __VA_ARGS__;\
109  { cudaError_t error = cudaGetLastError(); if( error != cudaSuccess ) throw ::ecuda::cuda_error(error,std::string(cudaGetErrorString(error))); }\
110  cudaDeviceSynchronize();\
111  { cudaError_t error = cudaGetLastError(); if( error != cudaSuccess ) throw ::ecuda::cuda_error(error,std::string(cudaGetErrorString(error))); }\
112  } while(0);
113 #else
114 #define CUDA_CALL_KERNEL_AND_WAIT(...) do {\
119  __VA_ARGS__;\
120  } while( 0 ); // cannot do CUDA calls when emulating with host only
121 #endif
122 
124 #ifndef ECUDA_CPP11_AVAILABLE
125 #define nullptr NULL
126 #endif
127 
129 #ifdef ECUDA_CPP11_AVAILABLE
130 #if defined(_MSC_VER) && _MSC_VER == 1800 // Visual Studio 2013 has only partial C++11 support and doesn't know these
131 #define __NOEXCEPT__
132 #define __CONSTEXPR__
133 #else
134 #define __NOEXCEPT__ noexcept
135 #define ECUDA_NOEXCEPT_KEYWORD_ENABLED
136 #define __CONSTEXPR__ constexpr
137 #define ECUDA_CONSTEXPR_KEYWORD_ENABLED
138 #endif
139 #else
140 #define __NOEXCEPT__
141 #define __CONSTEXPR__
142 #endif
143 
144 #ifdef __CUDACC__
145 #define __HOST__ __host__
146 #define __DEVICE__ __device__
147 #define __CONSTANT__ __constant__
148 #else
149 // strip all __host__ and __device__ declarations when using host only
150 #define __HOST__
151 #define __DEVICE__
152 #define __CONSTANT__
153 #endif
154 
155 //
156 // Quick implementation of compile-time assertions. If C++11 is available, then
157 // just use the new static_assert keyword.
158 //
159 // This approach was borrowed from the Eigen linear algebra template library
160 // (http://eigen.tuxfamily.org).
161 //
162 #ifdef ECUDA_CPP11_AVAILABLE
163 #define ECUDA_STATIC_ASSERT(x,msg) static_assert(x,#msg)
164 #else
165 
166 namespace ecuda {
167 
169 namespace impl {
170 
171 template<bool condition> struct static_assertion {};
172 template<> struct static_assertion<true>
173 {
174  enum {
175  CANNOT_USE_NONCONTIGUOUS_DEVICE_ITERATOR_AS_SOURCE_FOR_COPY,
176  CANNOT_USE_NONCONTIGUOUS_DEVICE_ITERATOR_AS_DESTINATION_FOR_COPY,
177  CANNOT_FILL_RANGE_REPRESENTED_BY_NONCONTIGUOUS_DEVICE_ITERATOR,
178  CANNOT_LEXICOGRAPHICALLY_COMPARE_RANGE_REPRESENTED_BY_NONCONTIGUOUS_DEVICE_MEMORY,
179  CANNOT_FIND_MAX_ELEMENT_IN_RANGE_REPRESENTED_BY_NONCONTIGUOUS_DEVICE_MEMORY,
180  CANNOT_REVERSE_RANGE_REPRESENTED_BY_NONCONTIGUOUS_DEVICE_MEMORY,
181  CANNOT_ACCUMULATE_RANGE_REPRESENTED_BY_NONCONTIGUOUS_DEVICE_MEMORY,
182  CANNOT_CALCULATE_DISTANCE_OF_NONCONTIGUOUS_DEVICE_ITERATOR_FROM_HOST_CODE
183  };
184 };
185 
186 } // namespace impl
188 
189 } // namespace ecuda
190 
191 #define ECUDA_STATIC_ASSERT(x,msg) if(ecuda::impl::static_assertion<static_cast<bool>(x)>::msg) {}
192 
193 #endif // ECUDA_CPP11_AVAILABLE
194 
195 #endif