diff --git a/CMakeLists.txt b/CMakeLists.txt index 36cd7d8..f760070 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,17 +1,34 @@ cmake_minimum_required(VERSION 3.9) -project(MyProject) +project(MyProject LANGUAGES CUDA CXX) + +add_compile_options(-Wall -Wextra -Wpedantic) set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CUDA_ARCHITECTURES 61) +set(CUDA_SEPARABLE_COMPILATION ON) + -set(SOURCE_FILES main.cpp) -add_executable(${CMAKE_PROJECT_NAME}_run ${SOURCE_FILES}) include_directories(src) +include_directories(kernels) +include_directories(/usr/local/cuda-12.8/include) + add_subdirectory(src) +add_subdirectory(kernels) add_subdirectory(tests) -target_link_libraries(${CMAKE_PROJECT_NAME}_run ${CMAKE_PROJECT_NAME}_lib) +add_executable(${CMAKE_PROJECT_NAME}_run main.cpp) + + + +target_link_libraries( + ${CMAKE_PROJECT_NAME}_run + PRIVATE + ${CMAKE_PROJECT_NAME}_lib + ${CMAKE_PROJECT_NAME}_cuda_lib + ${CUDA_LIBRARIES} +) # Doxygen Build option(BUILD_DOC "Build Documentation" ON) @@ -35,4 +52,4 @@ if(DOXYGEN_FOUND) VERBATIM) else(DOXYGEN_FOUND) message("Doxygen needs to be installed to generate the documentation.") -endif(DOXYGEN_FOUND) \ No newline at end of file +endif(DOXYGEN_FOUND) diff --git a/kernels/CMakeLists.txt b/kernels/CMakeLists.txt new file mode 100644 index 0000000..f9a1174 --- /dev/null +++ b/kernels/CMakeLists.txt @@ -0,0 +1,18 @@ +project(${CMAKE_PROJECT_NAME}_cuda_lib CUDA CXX) + +set(HEADER_FILES + hello_world.h +) +set(SOURCE_FILES + hello_world.cu +) + +# The library contains header and source files. +add_library(${CMAKE_PROJECT_NAME}_cuda_lib STATIC + ${SOURCE_FILES} + ${HEADER_FILES} +) + +if(CMAKE_COMPILER_IS_GNUCXX) + target_compile_options(${CMAKE_PROJECT_NAME}_cuda_lib PRIVATE -Wno-gnu-line-marker) +endif() diff --git a/kernels/hello_world.cu b/kernels/hello_world.cu new file mode 100644 index 0000000..7c65115 --- /dev/null +++ b/kernels/hello_world.cu @@ -0,0 +1,46 @@ +#include +#include + +__global__ void hello_cuda() { + printf("Hello CUDA from thread %d\n", threadIdx.x); +} + +extern "C" void launch_hello_cuda() { + // First check device properties + cudaDeviceProp prop; + cudaGetDeviceProperties(&prop, 1); + printf("Using device: %s with compute capability %d.%d\n", prop.name, + prop.major, prop.minor); + + hello_cuda<<<1, 10>>>(); + cudaDeviceSynchronize(); + fflush(stdout); +} + +extern "C" void check_cuda() { + int deviceCount = 0; + cudaError_t error = cudaGetDeviceCount(&deviceCount); + + if (error != cudaSuccess) { + printf("CUDA error: %s\n", cudaGetErrorString(error)); + } + + printf("Found %d CUDA devices\n", deviceCount); + + for (int i = 0; i < deviceCount; i++) { + cudaDeviceProp prop; + cudaGetDeviceProperties(&prop, i); + + printf("Device %d: %s\n", i, prop.name); + printf(" Compute capability: %d.%d\n", prop.major, prop.minor); + printf(" Total global memory: %.2f GB\n", + static_cast(prop.totalGlobalMem) / (1024 * 1024 * 1024)); + printf(" Multiprocessors: %d\n", prop.multiProcessorCount); + printf(" Max threads per block: %d\n", prop.maxThreadsPerBlock); + printf(" Max threads dimensions: (%d, %d, %d)\n", prop.maxThreadsDim[0], + prop.maxThreadsDim[1], prop.maxThreadsDim[2]); + printf(" Max grid dimensions: (%d, %d, %d)\n", prop.maxGridSize[0], + prop.maxGridSize[1], prop.maxGridSize[2]); + printf("\n"); + } +} diff --git a/kernels/hello_world.h b/kernels/hello_world.h new file mode 100644 index 0000000..4024e2e --- /dev/null +++ b/kernels/hello_world.h @@ -0,0 +1,10 @@ +#ifndef HELLO_WORLD_CU_H +#define HELLO_WORLD_CU_H + +extern "C" { +// Declaration of the CUDA function that will be called from C++ +void launch_hello_cuda(); +void check_cuda(); +} + +#endif // HELLO_WORLD_CU_H diff --git a/main.cpp b/main.cpp index d269c89..e3c8734 100644 --- a/main.cpp +++ b/main.cpp @@ -1,3 +1,10 @@ +#include "hello_world.h" +#include + int main() { + std::cout << "Starting CUDA example..." << std::endl; // Using endl to flush + check_cuda(); + launch_hello_cuda(); + std::cout << "Ending CUDA example" << std::endl; // Using endl to flush return 0; -} \ No newline at end of file +} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 94717aa..6c6cd8f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,17 +1,16 @@ -project(${CMAKE_PROJECT_NAME}_lib) +project(${CMAKE_PROJECT_NAME}_lib CUDA CXX) set(HEADER_FILES + ./test.h ) set(SOURCE_FILES + ./test.cpp ) -if (EXISTS ${SOURCE_FILES}) - # The library contains header and source files. - add_library(${CMAKE_PROJECT_NAME}_lib STATIC - ${SOURCE_FILES} - ${HEADER_FILES} - ) -else() - # The library only contains header files. - add_library(${CMAKE_PROJECT_NAME}_lib INTERFACE) -endif() \ No newline at end of file +# The library contains header and source files. +add_library(${CMAKE_PROJECT_NAME}_lib + ${SOURCE_FILES} + ${HEADER_FILES} +) + +target_include_directories(${CMAKE_PROJECT_NAME}_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) diff --git a/src/test.cpp b/src/test.cpp new file mode 100644 index 0000000..eec7934 --- /dev/null +++ b/src/test.cpp @@ -0,0 +1,4 @@ +#include "test.h" +#include + +void test_hello() { std::cout << "Hello!"; } diff --git a/src/test.h b/src/test.h new file mode 100644 index 0000000..b9c7ab1 --- /dev/null +++ b/src/test.h @@ -0,0 +1,2 @@ +#include +void test_hello();