diff --git a/CMakeLists.txt b/CMakeLists.txt index d2bebc5..d2b2491 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 3.9) set(NAME "Vec3") project(${NAME}) +# Check for CUDA +include(CheckLanguage) +check_language(CUDA) + set(CMAKE_EXPORT_COMPILE_COMMANDS ON) add_compile_options(-Wall -Wextra -Wpedantic) diff --git a/README.md b/README.md index 9cfb835..b68a789 100644 --- a/README.md +++ b/README.md @@ -21,4 +21,5 @@ endif() ## Features * Guards all testing code to only be run when Vec3 is the main project +* Compatible with both CUDA and C++ diff --git a/include/vec3.h b/include/vec3.h index 6e37d1e..54dcf4e 100644 --- a/include/vec3.h +++ b/include/vec3.h @@ -3,35 +3,44 @@ #include #include + +#ifdef __CUDACC__ +#define CUDA_CALLABLE __host__ __device__ +#else +#define CUDA_CALLABLE +#endif + template struct Vec3 { T x; T y; T z; - inline Vec3 operator+(Vec3 other) const { + CUDA_CALLABLE inline Vec3 operator+(Vec3 other) const { return {x + other.x, y + other.y, z + other.z}; }; - inline Vec3 operator-(Vec3 other) const { + CUDA_CALLABLE inline Vec3 operator-(Vec3 other) const { return {x - other.x, y - other.y, z - other.z}; }; - inline Vec3 scale(T scalar) { return {x * scalar, y * scalar, z * scalar}; }; + CUDA_CALLABLE inline Vec3 scale(T scalar) { + return {x * scalar, y * scalar, z * scalar}; + }; - inline T dot(Vec3 other) const { + CUDA_CALLABLE inline T dot(Vec3 other) const { return x * other.x + y * other.y + z * other.z; } - inline Vec3 cross(Vec3 other) const { + CUDA_CALLABLE inline Vec3 cross(Vec3 other) const { return {y * other.z - z * other.y, z * other.x - x * other.z, x * other.y - y * other.x}; } - inline T squared_norm2() const { return x * x + y * y + z * z; } + CUDA_CALLABLE inline T squared_norm2() const { return x * x + y * y + z * z; } - inline T norm2() const { return std::sqrt(squared_norm2()); } + CUDA_CALLABLE inline T norm2() const { return std::sqrt(squared_norm2()); } - inline Vec3 normalized() { + CUDA_CALLABLE inline Vec3 normalized() { // Add epsilon to the norm for stability when the norm is 0 T norm = std::max(norm2(), std::numeric_limits::epsilon()); return {x / norm, y / norm, z / norm}; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 85a8157..ae6b103 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -10,4 +10,16 @@ if(NOT EXISTS ${GOOGLETEST_DIR}) endif() add_subdirectory(lib/googletest) -add_subdirectory(unit_tests) \ No newline at end of file +add_subdirectory(unit_tests) + +# Only run Cuda tests if cuda is available +if (CMAKE_CUDA_COMPILER) + set(CMAKE_CUDA_ARCHITECTURES 61) + set(CUDA_SEPARABLE_COMPILATION ON) + + add_subdirectory(cuda_unit_tests) + message(STATUS "CUDA found. CUDA tests will be build") +else() + message(STATUS "CUDA not found. Skipping CUDA tests") +endif() +