From 97e8ce80a9dc4d03eb8e32f998342b067f916a3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E3=81=99=E3=81=91=E3=82=84?= <64895419+sukeya@users.noreply.github.com> Date: Tue, 18 Jul 2023 11:55:52 +0900 Subject: [PATCH 1/6] Fix calling default constructor to use uniform initialization. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: すけや <64895419+sukeya@users.noreply.github.com> --- src/Imath/ImathTypeTraits.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/Imath/ImathTypeTraits.h b/src/Imath/ImathTypeTraits.h index 60c85e1c..c3ad212a 100644 --- a/src/Imath/ImathTypeTraits.h +++ b/src/Imath/ImathTypeTraits.h @@ -85,8 +85,8 @@ template struct has_xy // Valid only if .x, .y exist and are the right type: return a Yes. template < typename C, - IMATH_ENABLE_IF (std::is_same::value), - IMATH_ENABLE_IF (std::is_same::value)> + IMATH_ENABLE_IF (std::is_same::value), + IMATH_ENABLE_IF (std::is_same::value)> static Yes& test (int); // Fallback, default to returning a No. @@ -113,9 +113,9 @@ template struct has_xyz // Valid only if .x, .y, .z exist and are the right type: return a Yes. template < typename C, - IMATH_ENABLE_IF (std::is_same::value), - IMATH_ENABLE_IF (std::is_same::value), - IMATH_ENABLE_IF (std::is_same::value)> + IMATH_ENABLE_IF (std::is_same::value), + IMATH_ENABLE_IF (std::is_same::value), + IMATH_ENABLE_IF (std::is_same::value)> static Yes& test (int); // Fallback, default to returning a No. @@ -142,10 +142,10 @@ template struct has_xyzw // Valid only if .x, .y, .z, .w exist and are the right type: return a Yes. template < typename C, - IMATH_ENABLE_IF (std::is_same::value), - IMATH_ENABLE_IF (std::is_same::value), - IMATH_ENABLE_IF (std::is_same::value), - IMATH_ENABLE_IF (std::is_same::value)> + IMATH_ENABLE_IF (std::is_same::value), + IMATH_ENABLE_IF (std::is_same::value), + IMATH_ENABLE_IF (std::is_same::value), + IMATH_ENABLE_IF (std::is_same::value)> static Yes& test (int); // Fallback, default to returning a No. @@ -173,7 +173,7 @@ template struct has_subscript template < typename C, IMATH_ENABLE_IF (std::is_same< - typename std::decay::type, + typename std::decay::type, Base>::value)> static Yes& test (int); @@ -208,7 +208,7 @@ struct has_double_subscript template < typename C, IMATH_ENABLE_IF (std::is_same< - typename std::decay::type, + typename std::decay::type, Base>::value)> static Yes& test (int); From d807215c0798c5649eb83a9ee58adbe94cb83fbb Mon Sep 17 00:00:00 2001 From: Yuya Asano <64895419+sukeya@users.noreply.github.com> Date: Wed, 19 Jul 2023 21:25:39 +0900 Subject: [PATCH 2/6] Add a test case for vectors in CUDA(#334). Signed-off-by: Yuya Asano <64895419+sukeya@users.noreply.github.com> --- config/ImathConfig.h.in | 9 ++ src/Imath/ImathMath.h | 55 ++++---- src/Imath/ImathTypeTraits.h | 46 +++--- src/Imath/ImathVec.h | 56 ++++---- src/ImathTest/CMakeLists.txt | 22 ++- src/ImathTest/main.cpp | 6 + src/ImathTest/testVecCUDA.cu | 265 +++++++++++++++++++++++++++++++++++ src/ImathTest/testVecCUDA.h | 6 + 8 files changed, 392 insertions(+), 73 deletions(-) create mode 100644 src/ImathTest/testVecCUDA.cu create mode 100644 src/ImathTest/testVecCUDA.h diff --git a/config/ImathConfig.h.in b/config/ImathConfig.h.in index 132f6235..3bdf7043 100644 --- a/config/ImathConfig.h.in +++ b/config/ImathConfig.h.in @@ -107,6 +107,15 @@ # define IMATH_HOSTDEVICE #endif +// +// The namespace of C++ standard library +// +#ifdef __CUDACC__ +# define IMATH_STD_NAMESPACE cuda::std +#else +# define IMATH_STD_NAMESPACE std +#endif + // // Some compilers define a special intrinsic to use in conditionals that can // speed up extremely performance-critical spots if the conditional is diff --git a/src/Imath/ImathMath.h b/src/Imath/ImathMath.h index b3d2845a..12c31ce0 100644 --- a/src/Imath/ImathMath.h +++ b/src/Imath/ImathMath.h @@ -13,8 +13,13 @@ #include "ImathNamespace.h" #include "ImathPlatform.h" -#include -#include +#ifdef __CUDACC__ +# include +# include +#else +# include +# include +#endif IMATH_INTERNAL_NAMESPACE_HEADER_ENTER @@ -38,93 +43,93 @@ template struct Math { IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T acos (T x) { return std::acos (x); } + static T acos (T x) { return IMATH_STD_NAMESPACE::acos (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T asin (T x) { return std::asin (x); } + static T asin (T x) { return IMATH_STD_NAMESPACE::asin (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T atan (T x) { return std::atan (x); } + static T atan (T x) { return IMATH_STD_NAMESPACE::atan (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T atan2 (T x, T y) { return std::atan2 (x, y); } + static T atan2 (T x, T y) { return IMATH_STD_NAMESPACE::atan2 (x, y); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T cos (T x) { return std::cos (x); } + static T cos (T x) { return IMATH_STD_NAMESPACE::cos (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T sin (T x) { return std::sin (x); } + static T sin (T x) { return IMATH_STD_NAMESPACE::sin (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T tan (T x) { return std::tan (x); } + static T tan (T x) { return IMATH_STD_NAMESPACE::tan (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T cosh (T x) { return std::cosh (x); } + static T cosh (T x) { return IMATH_STD_NAMESPACE::cosh (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T sinh (T x) { return std::sinh (x); } + static T sinh (T x) { return IMATH_STD_NAMESPACE::sinh (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T tanh (T x) { return std::tanh (x); } + static T tanh (T x) { return IMATH_STD_NAMESPACE::tanh (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T exp (T x) { return std::exp (x); } + static T exp (T x) { return IMATH_STD_NAMESPACE::exp (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T log (T x) { return std::log (x); } + static T log (T x) { return IMATH_STD_NAMESPACE::log (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T log10 (T x) { return std::log10 (x); } + static T log10 (T x) { return IMATH_STD_NAMESPACE::log10 (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE static T modf (T x, T* iptr) { T ival; - T rval (std::modf (T (x), &ival)); + T rval (IMATH_STD_NAMESPACE::modf (T (x), &ival)); *iptr = ival; return rval; } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T pow (T x, T y) { return std::pow (x, y); } + static T pow (T x, T y) { return IMATH_STD_NAMESPACE::pow (x, y); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T sqrt (T x) { return std::sqrt (x); } + static T sqrt (T x) { return IMATH_STD_NAMESPACE::sqrt (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T ceil (T x) { return std::ceil (x); } + static T ceil (T x) { return IMATH_STD_NAMESPACE::ceil (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T fabs (T x) { return std::fabs (x); } + static T fabs (T x) { return IMATH_STD_NAMESPACE::fabs (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T floor (T x) { return std::floor (x); } + static T floor (T x) { return IMATH_STD_NAMESPACE::floor (x); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T fmod (T x, T y) { return std::fmod (x, y); } + static T fmod (T x, T y) { return IMATH_STD_NAMESPACE::fmod (x, y); } IMATH_DEPRECATED ("use std::math functions") IMATH_HOSTDEVICE - static T hypot (T x, T y) { return std::hypot (x, y); } + static T hypot (T x, T y) { return IMATH_STD_NAMESPACE::hypot (x, y); } }; /// @endcond @@ -134,10 +139,10 @@ template IMATH_HOSTDEVICE inline T sinx_over_x (T x) { - if (x * x < std::numeric_limits::epsilon ()) + if (x * x < IMATH_STD_NAMESPACE::numeric_limits::epsilon ()) return T (1); else - return std::sin (x) / x; + return IMATH_STD_NAMESPACE::sin (x) / x; } /// Compare two numbers and test if they are "approximately equal": diff --git a/src/Imath/ImathTypeTraits.h b/src/Imath/ImathTypeTraits.h index c3ad212a..0d325c57 100644 --- a/src/Imath/ImathTypeTraits.h +++ b/src/Imath/ImathTypeTraits.h @@ -10,19 +10,23 @@ #ifndef INCLUDED_IMATHTYPETRAITS_H #define INCLUDED_IMATHTYPETRAITS_H -#include +#ifdef __CUDACC__ +# include +#else +# include +#endif #include "ImathPlatform.h" IMATH_INTERNAL_NAMESPACE_HEADER_ENTER -/// Define Imath::enable_if_t to be std for C++14, equivalent for C++11. +/// Define Imath::enable_if_t to be IMATH_STD_NAMESPACE for C++14, equivalent for C++11. #if (IMATH_CPLUSPLUS_VERSION >= 14) -using std::enable_if_t; // Use C++14 std::enable_if_t +using IMATH_STD_NAMESPACE::enable_if_t; // Use C++14 IMATH_STD_NAMESPACE::enable_if_t #else // Define enable_if_t for C++11 template -using enable_if_t = typename std::enable_if::type; +using enable_if_t = typename IMATH_STD_NAMESPACE::enable_if::type; #endif /// An enable_if helper to be used in template parameters which results in @@ -63,14 +67,14 @@ using enable_if_t = typename std::enable_if::type; /// an Imath::V3f by subscripting: /// /// template<> -/// struct Imath::has_subscript : public std::true_type { }; +/// struct Imath::has_subscript : public IMATH_STD_NAMESPACE::true_type { }; /// /// And similarly, user code may correct a potential false positive (that /// is, a `mytype` looks like it should be convertible to a V3f, but you /// don't want it to ever happen): /// /// template -/// struct Imath::has_subscript : public std::false_type { }; +/// struct Imath::has_subscript : public IMATH_STD_NAMESPACE::false_type { }; /// /// `has_xy::value` will be true if type `T` has member variables @@ -85,8 +89,8 @@ template struct has_xy // Valid only if .x, .y exist and are the right type: return a Yes. template < typename C, - IMATH_ENABLE_IF (std::is_same::value), - IMATH_ENABLE_IF (std::is_same::value)> + IMATH_ENABLE_IF (IMATH_STD_NAMESPACE::is_same::value), + IMATH_ENABLE_IF (IMATH_STD_NAMESPACE::is_same::value)> static Yes& test (int); // Fallback, default to returning a No. @@ -113,9 +117,9 @@ template struct has_xyz // Valid only if .x, .y, .z exist and are the right type: return a Yes. template < typename C, - IMATH_ENABLE_IF (std::is_same::value), - IMATH_ENABLE_IF (std::is_same::value), - IMATH_ENABLE_IF (std::is_same::value)> + IMATH_ENABLE_IF (IMATH_STD_NAMESPACE::is_same::value), + IMATH_ENABLE_IF (IMATH_STD_NAMESPACE::is_same::value), + IMATH_ENABLE_IF (IMATH_STD_NAMESPACE::is_same::value)> static Yes& test (int); // Fallback, default to returning a No. @@ -142,10 +146,10 @@ template struct has_xyzw // Valid only if .x, .y, .z, .w exist and are the right type: return a Yes. template < typename C, - IMATH_ENABLE_IF (std::is_same::value), - IMATH_ENABLE_IF (std::is_same::value), - IMATH_ENABLE_IF (std::is_same::value), - IMATH_ENABLE_IF (std::is_same::value)> + IMATH_ENABLE_IF (IMATH_STD_NAMESPACE::is_same::value), + IMATH_ENABLE_IF (IMATH_STD_NAMESPACE::is_same::value), + IMATH_ENABLE_IF (IMATH_STD_NAMESPACE::is_same::value), + IMATH_ENABLE_IF (IMATH_STD_NAMESPACE::is_same::value)> static Yes& test (int); // Fallback, default to returning a No. @@ -172,8 +176,8 @@ template struct has_subscript // Valid only if T[] is possible and is the right type: return a Yes. template < typename C, - IMATH_ENABLE_IF (std::is_same< - typename std::decay::type, + IMATH_ENABLE_IF (IMATH_STD_NAMESPACE::is_same< + typename IMATH_STD_NAMESPACE::decay::type, Base>::value)> static Yes& test (int); @@ -191,7 +195,7 @@ template struct has_subscript /// C arrays of just the right length also are qualified for has_subscript. template -struct has_subscript : public std::true_type +struct has_subscript : public IMATH_STD_NAMESPACE::true_type {}; /// `has_double_subscript::value` will be true if type `T` @@ -207,8 +211,8 @@ struct has_double_subscript // Valid only if T[][] is possible and is the right type: return a Yes. template < typename C, - IMATH_ENABLE_IF (std::is_same< - typename std::decay::type, + IMATH_ENABLE_IF (IMATH_STD_NAMESPACE::is_same< + typename IMATH_STD_NAMESPACE::decay::type, Base>::value)> static Yes& test (int); @@ -227,7 +231,7 @@ struct has_double_subscript /// C arrays of just the right length also are qualified for has_double_subscript. template struct has_double_subscript - : public std::true_type + : public IMATH_STD_NAMESPACE::true_type {}; /// @} diff --git a/src/Imath/ImathVec.h b/src/Imath/ImathVec.h index 49d69256..6bfe7c71 100644 --- a/src/Imath/ImathVec.h +++ b/src/Imath/ImathVec.h @@ -17,8 +17,6 @@ #include "ImathMath.h" #include -#include -#include #include #if (defined _WIN32 || defined _WIN64) && defined _MSC_VER @@ -27,6 +25,14 @@ # pragma warning(disable : 4290) #endif +#ifdef __CUDACC__ +# include +# include +#else +# include +# include +#endif + IMATH_INTERNAL_NAMESPACE_HEADER_ENTER template class Vec2; @@ -299,25 +305,25 @@ template class IMATH_EXPORT_TEMPLATE_TYPE Vec2 /// Largest possible negative value IMATH_HOSTDEVICE constexpr static T baseTypeLowest () IMATH_NOEXCEPT { - return std::numeric_limits::lowest (); + return IMATH_STD_NAMESPACE::numeric_limits::lowest (); } /// Largest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeMax () IMATH_NOEXCEPT { - return std::numeric_limits::max (); + return IMATH_STD_NAMESPACE::numeric_limits::max (); } /// Smallest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeSmallest () IMATH_NOEXCEPT { - return std::numeric_limits::min (); + return IMATH_STD_NAMESPACE::numeric_limits::min (); } /// Smallest possible e for which 1+e != 1 IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon () IMATH_NOEXCEPT { - return std::numeric_limits::epsilon (); + return IMATH_STD_NAMESPACE::numeric_limits::epsilon (); } /// @} @@ -620,25 +626,25 @@ template class IMATH_EXPORT_TEMPLATE_TYPE Vec3 /// Largest possible negative value IMATH_HOSTDEVICE constexpr static T baseTypeLowest () IMATH_NOEXCEPT { - return std::numeric_limits::lowest (); + return IMATH_STD_NAMESPACE::numeric_limits::lowest (); } /// Largest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeMax () IMATH_NOEXCEPT { - return std::numeric_limits::max (); + return IMATH_STD_NAMESPACE::numeric_limits::max (); } /// Smallest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeSmallest () IMATH_NOEXCEPT { - return std::numeric_limits::min (); + return IMATH_STD_NAMESPACE::numeric_limits::min (); } /// Smallest possible e for which 1+e != 1 IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon () IMATH_NOEXCEPT { - return std::numeric_limits::epsilon (); + return IMATH_STD_NAMESPACE::numeric_limits::epsilon (); } /// @} @@ -896,25 +902,25 @@ template class IMATH_EXPORT_TEMPLATE_TYPE Vec4 /// Largest possible negative value IMATH_HOSTDEVICE constexpr static T baseTypeLowest () IMATH_NOEXCEPT { - return std::numeric_limits::lowest (); + return IMATH_STD_NAMESPACE::numeric_limits::lowest (); } /// Largest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeMax () IMATH_NOEXCEPT { - return std::numeric_limits::max (); + return IMATH_STD_NAMESPACE::numeric_limits::max (); } /// Smallest possible positive value IMATH_HOSTDEVICE constexpr static T baseTypeSmallest () IMATH_NOEXCEPT { - return std::numeric_limits::min (); + return IMATH_STD_NAMESPACE::numeric_limits::min (); } /// Smallest possible e for which 1+e != 1 IMATH_HOSTDEVICE constexpr static T baseTypeEpsilon () IMATH_NOEXCEPT { - return std::numeric_limits::epsilon (); + return IMATH_STD_NAMESPACE::numeric_limits::epsilon (); } /// @} @@ -1466,8 +1472,8 @@ template IMATH_HOSTDEVICE IMATH_CONSTEXPR14 inline T Vec2::lengthTiny () const IMATH_NOEXCEPT { - T absX = std::abs (x); - T absY = std::abs (y); + T absX = IMATH_STD_NAMESPACE::abs (x); + T absY = IMATH_STD_NAMESPACE::abs (y); T max = absX; @@ -1484,7 +1490,7 @@ Vec2::lengthTiny () const IMATH_NOEXCEPT absX /= max; absY /= max; - return max * std::sqrt (absX * absX + absY * absY); + return max * IMATH_STD_NAMESPACE::sqrt (absX * absX + absY * absY); } template @@ -1493,10 +1499,10 @@ Vec2::length () const IMATH_NOEXCEPT { T length2 = dot (*this); - if (IMATH_UNLIKELY (length2 < T (2) * std::numeric_limits::min ())) + if (IMATH_UNLIKELY (length2 < T (2) * IMATH_STD_NAMESPACE::numeric_limits::min ())) return lengthTiny (); - return std::sqrt (length2); + return IMATH_STD_NAMESPACE::sqrt (length2); } template @@ -1954,7 +1960,7 @@ Vec3::lengthTiny () const IMATH_NOEXCEPT absY /= max; absZ /= max; - return max * std::sqrt (absX * absX + absY * absY + absZ * absZ); + return max * IMATH_STD_NAMESPACE::sqrt (absX * absX + absY * absY + absZ * absZ); } template @@ -1963,10 +1969,10 @@ Vec3::length () const IMATH_NOEXCEPT { T length2 = dot (*this); - if (IMATH_UNLIKELY (length2 < T (2) * std::numeric_limits::min ())) + if (IMATH_UNLIKELY (length2 < T (2) * IMATH_STD_NAMESPACE::numeric_limits::min ())) return lengthTiny (); - return std::sqrt (length2); + return IMATH_STD_NAMESPACE::sqrt (length2); } template @@ -2339,7 +2345,7 @@ Vec4::lengthTiny () const IMATH_NOEXCEPT absW /= max; return max * - std::sqrt (absX * absX + absY * absY + absZ * absZ + absW * absW); + IMATH_STD_NAMESPACE::sqrt (absX * absX + absY * absY + absZ * absZ + absW * absW); } template @@ -2348,10 +2354,10 @@ Vec4::length () const IMATH_NOEXCEPT { T length2 = dot (*this); - if (IMATH_UNLIKELY (length2 < T (2) * std::numeric_limits::min ())) + if (IMATH_UNLIKELY (length2 < T (2) * IMATH_STD_NAMESPACE::numeric_limits::min ())) return lengthTiny (); - return std::sqrt (length2); + return IMATH_STD_NAMESPACE::sqrt (length2); } template diff --git a/src/ImathTest/CMakeLists.txt b/src/ImathTest/CMakeLists.txt index 58820316..3f021425 100644 --- a/src/ImathTest/CMakeLists.txt +++ b/src/ImathTest/CMakeLists.txt @@ -11,6 +11,24 @@ if("${CMAKE_PROJECT_NAME}" STREQUAL "") find_package(Imath) endif() +set(CMAKE_CUDA_ARCHITECTURES 75) +enable_language(CUDA) + +add_library(ImathTestVecCuda + testVecCUDA.h + testVecCUDA.cu +) + +find_package(CUDAToolkit 12 REQUIRED) + +target_compile_features(ImathTestVecCuda PRIVATE cuda_std_20) + +target_link_libraries(ImathTestVecCuda PRIVATE CUDA::cudart Imath::Imath) + +set_target_properties(ImathTestVecCuda PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" +) + add_executable(ImathTest main.cpp testBox.cpp @@ -48,10 +66,10 @@ add_executable(ImathTest testNoInterop.cpp ) -target_link_libraries(ImathTest Imath::Imath) +target_link_libraries(ImathTest Imath::Imath ImathTestVecCuda) set_target_properties(ImathTest PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" - ) +) if(NOT "${CMAKE_PROJECT_NAME}" STREQUAL "ImathTest") diff --git a/src/ImathTest/main.cpp b/src/ImathTest/main.cpp index cc8ab569..e9568edc 100644 --- a/src/ImathTest/main.cpp +++ b/src/ImathTest/main.cpp @@ -40,6 +40,7 @@ #include "testTinySVD.h" #include "testToFloat.h" #include "testVec.h" +#include "testVecCUDA.h" #include #include @@ -88,6 +89,11 @@ main (int argc, char* argv[]) TEST (testFrustumTest); TEST (testInterop); TEST (testNoInterop); + + std::cout << "Testing some basic vector operations in CUDA" << std::endl; + TEST (testVecCUDA); + std::cout << "ok\n" << std::endl; + // NB: If you add a test here, make sure to enumerate it in the // CMakeLists.txt so it runs as part of the test suite diff --git a/src/ImathTest/testVecCUDA.cu b/src/ImathTest/testVecCUDA.cu new file mode 100644 index 00000000..e09eb05a --- /dev/null +++ b/src/ImathTest/testVecCUDA.cu @@ -0,0 +1,265 @@ +// +// SPDX-License-Identifier: BSD-3-Clause +// Copyright Contributors to the OpenEXR Project. +// + +#ifdef NDEBUG +# undef NDEBUG +#endif + +#include "testVecCUDA.h" +#include +#include +#include +#include + +// Include ImathForward *after* other headers to validate forward declarations +#include + +using namespace cuda::std; +using namespace IMATH_INTERNAL_NAMESPACE; + +namespace +{ + +template +void +testLength2T () +{ + const T s = sqrt (numeric_limits::min ()); + const T e = 4 * numeric_limits::epsilon (); + + Vec2 v; + + v = Vec2 (0, 0); + assert (v.length () == 0); + assert (v.normalized ().length () == 0); + + v = Vec2 (3, 4); + assert (v.length () == 5); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + v = Vec2 (3000, 4000); + assert (v.length () == 5000); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + T t = s * (1 << 4); + + v = Vec2 (t, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec2 (0, t); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec2 (-t, -t); + assert (IMATH_INTERNAL_NAMESPACE::equal ( + v.length (), t * sqrt (2), t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + t = s / (1 << 4); + + v = Vec2 (t, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec2 (0, t); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec2 (-t, -t); + assert (IMATH_INTERNAL_NAMESPACE::equal ( + v.length (), t * sqrt (2), t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + t = s / (1 << 20); + + v = Vec2 (t, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec2 (0, t); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec2 (-t, -t); + assert (IMATH_INTERNAL_NAMESPACE::equal ( + v.length (), t * sqrt (2), t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); +} + +template +void +testLength3T () +{ + const T s = sqrt (numeric_limits::min ()); + const T e = 4 * numeric_limits::epsilon (); + + Vec3 v; + + v = Vec3 (0, 0, 0); + assert (v.length () == 0); + assert (v.normalized ().length () == 0); + + v = Vec3 (3, 4, 0); + assert (v.length () == 5); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + v = Vec3 (3000, 4000, 0); + assert (v.length () == 5000); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + v = Vec3 (1, -1, 1); + assert ( + IMATH_INTERNAL_NAMESPACE::equal (v.length (), 1 * sqrt (3), e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + v = Vec3 (1000, -1000, 1000); + assert (IMATH_INTERNAL_NAMESPACE::equal ( + v.length (), 1000 * sqrt (3), 1000 * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + T t = s * (1 << 4); + + v = Vec3 (t, 0, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec3 (0, t, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec3 (0, 0, t); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec3 (-t, -t, -t); + assert (IMATH_INTERNAL_NAMESPACE::equal ( + v.length (), t * sqrt (3), t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + t = s / (1 << 4); + + v = Vec3 (t, 0, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec3 (0, t, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec3 (0, 0, t); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec3 (-t, -t, -t); + assert (IMATH_INTERNAL_NAMESPACE::equal ( + v.length (), t * sqrt (3), t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + t = s / (1 << 20); + + v = Vec3 (t, 0, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec3 (0, t, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec3 (0, 0, t); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec3 (-t, -t, -t); + assert (IMATH_INTERNAL_NAMESPACE::equal ( + v.length (), t * sqrt (3), t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); +} + +template +void +testLength4T () +{ + const T s = sqrt (numeric_limits::min ()); + const T e = 4 * numeric_limits::epsilon (); + + Vec4 v; + + v = Vec4 (0, 0, 0, 0); + assert (v.length () == 0); + assert (v.normalized ().length () == 0); + + v = Vec4 (3, 4, 0, 0); + assert (v.length () == 5); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + v = Vec4 (3000, 4000, 0, 0); + assert (v.length () == 5000); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + v = Vec4 (1, -1, 1, 1); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), 2, e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + v = Vec4 (1000, -1000, 1000, 1000); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), 2000, 1000 * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + T t = s * (1 << 4); + + v = Vec4 (t, 0, 0, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec4 (0, t, 0, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec4 (0, 0, t, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec4 (0, 0, 0, t); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec4 (-t, -t, -t, -t); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t * 2, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + t = s / (1 << 4); + + v = Vec4 (t, 0, 0, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec4 (0, t, 0, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec4 (0, 0, t, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec4 (0, 0, 0, t); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec4 (-t, -t, -t, -t); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t * 2, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + + t = s / (1 << 20); + + v = Vec4 (t, 0, 0, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec4 (0, t, 0, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec4 (0, 0, t, 0); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec4 (0, 0, 0, t); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); + v = Vec4 (-t, -t, -t, -t); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.length (), t * 2, t * e)); + assert (IMATH_INTERNAL_NAMESPACE::equal (v.normalized ().length (), 1, e)); +} + +} // namespace + +void +testVecCUDA () +{ + testLength2T (); + testLength2T (); + testLength3T (); + testLength3T (); + testLength4T (); + testLength4T (); + + // Test template parameter checks pass an alias of a correct type. + using R = double; + testLength4T (); +} diff --git a/src/ImathTest/testVecCUDA.h b/src/ImathTest/testVecCUDA.h new file mode 100644 index 00000000..4c0c2daa --- /dev/null +++ b/src/ImathTest/testVecCUDA.h @@ -0,0 +1,6 @@ +// +// SPDX-License-Identifier: BSD-3-Clause +// Copyright Contributors to the OpenEXR Project. +// + +void testVecCUDA (); From 3f67d82fa7f66f28ef5d5162370ff9996e4c2095 Mon Sep 17 00:00:00 2001 From: Yuya Asano <64895419+sukeya@users.noreply.github.com> Date: Wed, 19 Jul 2023 22:12:38 +0900 Subject: [PATCH 3/6] Fix failing to build if CUDA isn't installed. Signed-off-by: Yuya Asano <64895419+sukeya@users.noreply.github.com> --- src/ImathTest/CMakeLists.txt | 41 ++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/src/ImathTest/CMakeLists.txt b/src/ImathTest/CMakeLists.txt index 3f021425..0b30e7d1 100644 --- a/src/ImathTest/CMakeLists.txt +++ b/src/ImathTest/CMakeLists.txt @@ -11,23 +11,31 @@ if("${CMAKE_PROJECT_NAME}" STREQUAL "") find_package(Imath) endif() -set(CMAKE_CUDA_ARCHITECTURES 75) -enable_language(CUDA) +set(EXTRA_LIBS Imath::Imath) -add_library(ImathTestVecCuda - testVecCUDA.h - testVecCUDA.cu -) +find_package(CUDAToolkit 12) +if(CUDAToolkit_FOUND) + # TODO investigate minimum CUDA architecture. + set(CMAKE_CUDA_ARCHITECTURES 75) -find_package(CUDAToolkit 12 REQUIRED) + enable_language(CUDA) -target_compile_features(ImathTestVecCuda PRIVATE cuda_std_20) + add_library(ImathTestVecCuda + testVecCUDA.h + testVecCUDA.cu + ) -target_link_libraries(ImathTestVecCuda PRIVATE CUDA::cudart Imath::Imath) + # TODO investigate minimum CUDA C++ std. + target_compile_features(ImathTestVecCuda PRIVATE cuda_std_20) -set_target_properties(ImathTestVecCuda PROPERTIES - RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" -) + target_link_libraries(ImathTestVecCuda PRIVATE CUDA::cudart Imath::Imath) + + set_target_properties(ImathTestVecCuda PROPERTIES + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" + ) + + list(APPEND EXTRA_LIBS ImathTestVecCuda) +endif() add_executable(ImathTest main.cpp @@ -66,7 +74,7 @@ add_executable(ImathTest testNoInterop.cpp ) -target_link_libraries(ImathTest Imath::Imath ImathTestVecCuda) +target_link_libraries(ImathTest ${EXTRA_LIBS}) set_target_properties(ImathTest PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" ) @@ -102,7 +110,7 @@ function(DEFINE_IMATH_TESTS) endforeach() endfunction() -define_imath_tests( +set(TestCases testToFloat testSize testArithmetic @@ -141,3 +149,8 @@ define_imath_tests( testNoInterop ) +if(CUDAToolkit_FOUND) + list(APPEND TestCases testVecCUDA) +endif() + +define_imath_tests(${TestCases}) From 3e108759390920d92b6097e75f213f7e38463c08 Mon Sep 17 00:00:00 2001 From: Yuya Asano <64895419+sukeya@users.noreply.github.com> Date: Thu, 20 Jul 2023 08:45:10 +0900 Subject: [PATCH 4/6] Fix a compile error not found testVecCuda func def. Signed-off-by: Yuya Asano <64895419+sukeya@users.noreply.github.com> --- src/ImathTest/CMakeLists.txt | 10 +++++++--- src/ImathTest/ImathTestConfig.h.in | 1 + src/ImathTest/main.cpp | 9 ++++++++- 3 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 src/ImathTest/ImathTestConfig.h.in diff --git a/src/ImathTest/CMakeLists.txt b/src/ImathTest/CMakeLists.txt index 0b30e7d1..75556473 100644 --- a/src/ImathTest/CMakeLists.txt +++ b/src/ImathTest/CMakeLists.txt @@ -15,6 +15,8 @@ set(EXTRA_LIBS Imath::Imath) find_package(CUDAToolkit 12) if(CUDAToolkit_FOUND) + set(IMATH_CUDA_FOUND ON) + # TODO investigate minimum CUDA architecture. set(CMAKE_CUDA_ARCHITECTURES 75) @@ -37,6 +39,8 @@ if(CUDAToolkit_FOUND) list(APPEND EXTRA_LIBS ImathTestVecCuda) endif() +configure_file(ImathTestConfig.h.in ImathTestConfig.h) + add_executable(ImathTest main.cpp testBox.cpp @@ -110,7 +114,7 @@ function(DEFINE_IMATH_TESTS) endforeach() endfunction() -set(TestCases +set(TEST_CASES testToFloat testSize testArithmetic @@ -150,7 +154,7 @@ set(TestCases ) if(CUDAToolkit_FOUND) - list(APPEND TestCases testVecCUDA) + list(APPEND TEST_CASES testVecCUDA) endif() -define_imath_tests(${TestCases}) +define_imath_tests(${TEST_CASES}) diff --git a/src/ImathTest/ImathTestConfig.h.in b/src/ImathTest/ImathTestConfig.h.in new file mode 100644 index 00000000..288ad52f --- /dev/null +++ b/src/ImathTest/ImathTestConfig.h.in @@ -0,0 +1 @@ +#cmakedefine IMATH_CUDA_FOUND \ No newline at end of file diff --git a/src/ImathTest/main.cpp b/src/ImathTest/main.cpp index e9568edc..c1114968 100644 --- a/src/ImathTest/main.cpp +++ b/src/ImathTest/main.cpp @@ -7,6 +7,8 @@ # undef NDEBUG #endif +#include "ImathTestConfig.h" + #include "testArithmetic.h" #include "testBitPatterns.h" #include "testBox.h" @@ -40,7 +42,10 @@ #include "testTinySVD.h" #include "testToFloat.h" #include "testVec.h" -#include "testVecCUDA.h" + +#ifdef IMATH_CUDA_FOUND +# include "testVecCUDA.h" +#endif #include #include @@ -90,9 +95,11 @@ main (int argc, char* argv[]) TEST (testInterop); TEST (testNoInterop); +#ifdef IMATH_CUDA_FOUND std::cout << "Testing some basic vector operations in CUDA" << std::endl; TEST (testVecCUDA); std::cout << "ok\n" << std::endl; +#endif // NB: If you add a test here, make sure to enumerate it in the // CMakeLists.txt so it runs as part of the test suite From 440d4a3905be7a5be8a58188a8348391430bf05d Mon Sep 17 00:00:00 2001 From: Yuya Asano <64895419+sukeya@users.noreply.github.com> Date: Thu, 20 Jul 2023 08:56:40 +0900 Subject: [PATCH 5/6] Fix include directories for main in ImathTest. Signed-off-by: Yuya Asano <64895419+sukeya@users.noreply.github.com> --- src/ImathTest/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/ImathTest/CMakeLists.txt b/src/ImathTest/CMakeLists.txt index 75556473..ed813b09 100644 --- a/src/ImathTest/CMakeLists.txt +++ b/src/ImathTest/CMakeLists.txt @@ -78,6 +78,11 @@ add_executable(ImathTest testNoInterop.cpp ) +target_include_directories(ImathTest + PRIVATE + $ + $ +) target_link_libraries(ImathTest ${EXTRA_LIBS}) set_target_properties(ImathTest PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin" From 7c76cb4d57ee64b2bb01aebac0683df4acf36b38 Mon Sep 17 00:00:00 2001 From: Yuya Asano <64895419+sukeya@users.noreply.github.com> Date: Fri, 21 Jul 2023 10:50:37 +0900 Subject: [PATCH 6/6] Remove two unnecessary BUILD_INTERFACEs. Signed-off-by: Yuya Asano <64895419+sukeya@users.noreply.github.com> --- src/ImathTest/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ImathTest/CMakeLists.txt b/src/ImathTest/CMakeLists.txt index ed813b09..92857ac0 100644 --- a/src/ImathTest/CMakeLists.txt +++ b/src/ImathTest/CMakeLists.txt @@ -80,8 +80,8 @@ add_executable(ImathTest target_include_directories(ImathTest PRIVATE - $ - $ + ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_BINARY_DIR} ) target_link_libraries(ImathTest ${EXTRA_LIBS}) set_target_properties(ImathTest PROPERTIES