Add CUDA support

This commit is contained in:
Alex Selimov 2025-04-16 18:00:55 -04:00
parent fbc34a0bdd
commit 3d288e4778
4 changed files with 35 additions and 9 deletions

View File

@ -2,6 +2,10 @@ cmake_minimum_required(VERSION 3.9)
set(NAME "Vec3") set(NAME "Vec3")
project(${NAME}) project(${NAME})
# Check for CUDA
include(CheckLanguage)
check_language(CUDA)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON) set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
add_compile_options(-Wall -Wextra -Wpedantic) add_compile_options(-Wall -Wextra -Wpedantic)

View File

@ -21,4 +21,5 @@ endif()
## Features ## Features
* Guards all testing code to only be run when Vec3 is the main project * Guards all testing code to only be run when Vec3 is the main project
* Compatible with both CUDA and C++

View File

@ -3,35 +3,44 @@
#include <cmath> #include <cmath>
#include <limits> #include <limits>
#ifdef __CUDACC__
#define CUDA_CALLABLE __host__ __device__
#else
#define CUDA_CALLABLE
#endif
template <typename T> struct Vec3 { template <typename T> struct Vec3 {
T x; T x;
T y; T y;
T z; T z;
inline Vec3<T> operator+(Vec3<T> other) const { CUDA_CALLABLE inline Vec3<T> operator+(Vec3<T> other) const {
return {x + other.x, y + other.y, z + other.z}; return {x + other.x, y + other.y, z + other.z};
}; };
inline Vec3<T> operator-(Vec3<T> other) const { CUDA_CALLABLE inline Vec3<T> operator-(Vec3<T> other) const {
return {x - other.x, y - other.y, z - other.z}; 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<T> other) const { CUDA_CALLABLE inline T dot(Vec3<T> other) const {
return x * other.x + y * other.y + z * other.z; return x * other.x + y * other.y + z * other.z;
} }
inline Vec3<T> cross(Vec3<T> other) const { CUDA_CALLABLE inline Vec3<T> cross(Vec3<T> other) const {
return {y * other.z - z * other.y, z * other.x - x * other.z, return {y * other.z - z * other.y, z * other.x - x * other.z,
x * other.y - y * other.x}; 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<T> normalized() { CUDA_CALLABLE inline Vec3<T> normalized() {
// Add epsilon to the norm for stability when the norm is 0 // Add epsilon to the norm for stability when the norm is 0
T norm = std::max(norm2(), std::numeric_limits<T>::epsilon()); T norm = std::max(norm2(), std::numeric_limits<T>::epsilon());
return {x / norm, y / norm, z / norm}; return {x / norm, y / norm, z / norm};

View File

@ -10,4 +10,16 @@ if(NOT EXISTS ${GOOGLETEST_DIR})
endif() endif()
add_subdirectory(lib/googletest) add_subdirectory(lib/googletest)
add_subdirectory(unit_tests) 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()