Compare commits

...

3 Commits

Author SHA1 Message Date
a65149a619 Remove unneeded shell files 2025-04-15 14:11:55 -04:00
942caf0f15 Update README 2025-04-15 14:11:34 -04:00
68f8b02f0a Update to add Cuda to build system 2025-04-15 14:10:01 -04:00
11 changed files with 121 additions and 139 deletions

View File

@ -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)
endif(DOXYGEN_FOUND)

View File

@ -6,75 +6,7 @@ following components:
- Directory Structure
- Make Build (CMake)
- CUDA integration
- Unit Test Framework (Google Test)
- API Documentation (Doxygen)
Feel free to fork this repository and tailor it to suit you.
## Procedure
1. Download Bash script to create new C++ projects
```bash
curl -O https://raw.githubusercontent.com/TimothyHelton/cpp_project_template/master/new_cpp_project.sh
chmod u+x new_cpp_project.sh
```
1. Create new C++ project
```bash
./new_cpp_project.sh NewProjectName
```
1. In the project top level **CMakeLists.txt**:
1. Line 2: Change the variable **MyProject** to the name of your project.
```cmake
project(NewProject)
```
- This variable will be used in a couple of different places.
- MyProject_run: will be the main executable name
- MyProject_lib: will be the project library name
1. Line 4: Set the version of C++ to use. For example, let's set up the
NewProject to use C++ 11.
```cmake
set(CMAKE_CXX_STANDARD 11)
```
1. Update project name and description in the `Doxyfile` located in the `docs`
directory.
1. Update line `PROJECT_NAME`
1. This name will appear on each documentation page.
1. Update line `PROJECT_NUMBER`
1. This is the version number of your project.
1. Update line `PROJECT_BRIEF`
1. Any text entered here will also appear on each documentation page.
Try not to make this one too long.
1. Reload the top CMake file.
## CLION IDE Specific Instructions
I started using an IDE from [JET Brains](https://www.jetbrains.com/) tailored
for Python called [PyCharm](https://www.jetbrains.com/pycharm/) and thought
it helped me write better code.
I'd been wanting to learn C++ and decided to give JET Brains C/C++ IDE called
[CLion](https://www.jetbrains.com/clion/) a try.
The code completion, interactive suggestions, debugger, introspection tools,
and built-in test execution are very handy.
There are a couple extra details to set when using this IDE.
1. The IDE allows you to mark directories with their desired purpose.
To mark a directory right click on the directory name in the `Project` window
and select `Mark Directory as` from the drop-down menu.
1. Mark the `src` directory as `Project Sources and Headers`
1. Mark the `tests/lib/googletest` directory as `Library Files`
1. Setup the `Run/Debug Configuration` by selecting `Edit Configurations...`
from the pull-down menu from the run button (green triangle) in the upper right
corner.
1. Update Doxygen Build to execute the unit test suite.
1. Select Doxygen from the Application menu on the left.
1. Choose the **executable** for Doxygen to be `Unit_Tests_run`.
1. Create a `Google Test` configuration
1. In the upper left corner select the plus symbol.
1. Chose `Google Test` from the drop-down menu.
1. Set **Name** to `Unit Tests`.
1. Set **Target** to `Unit_Tests_run`.
## Wrap Up
That should be all it takes to start writing code.
If you find any issues or bugs with this repository please file an issue on
[GitHub](https://github.com/TimothyHelton/cpp_project_template/issues).
Hope you find this template useful and enjoy learning C++!

View File

@ -1,33 +0,0 @@
#!/usr/bin/env bash
# Exit if name argument is not given
if [ -z "$*" ]; then
echo "A project name argument must be provided."
exit 0
fi
NAME=$1
################################################################################
# Clone template repository
git clone https://github.com/TimothyHelton/cpp_project_template
# Create bare repository
git --bare init ${NAME}
# Push template master branch to bare repository
cd cpp_project_template
git push ../${NAME} +master:master
# Convert bare repository into a normal repository
cd ../${NAME}
mkdir .git
mv * .git
git config --local --bool core.bare false
git reset --hard
# Clean Up
rm -rf ../cpp_project_template ../create_project.sh

18
kernels/CMakeLists.txt Normal file
View File

@ -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()

46
kernels/hello_world.cu Normal file
View File

@ -0,0 +1,46 @@
#include <cuda_runtime.h>
#include <stdio.h>
__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<float>(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");
}
}

10
kernels/hello_world.h Normal file
View File

@ -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

View File

@ -1,3 +1,10 @@
#include "hello_world.h"
#include <iostream>
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;
}
}

View File

@ -1,20 +0,0 @@
#!/usr/bin/env bash
# Exit if name argument is not given
if [ -z "$*" ]; then
echo "A project name argument must be provided."
exit 0
fi
NAME=$1
################################################################################
# Download latest version of the build file
curl -O https://raw.githubusercontent.com/TimothyHelton/cpp_project_template/master/create_project.sh
chmod u+x create_project.sh
# Create Project
./create_project.sh ${NAME}

View File

@ -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()
# 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})

4
src/test.cpp Normal file
View File

@ -0,0 +1,4 @@
#include "test.h"
#include <iostream>
void test_hello() { std::cout << "Hello!"; }

2
src/test.h Normal file
View File

@ -0,0 +1,2 @@
#include <iostream>
void test_hello();