diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index 97305bb..697e59e 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -74,10 +74,6 @@ RUN if id -u $USERNAME >/dev/null 2>&1; then \ USER $USERNAME -# * Post-installation Actions for CUDA -RUN echo "export PATH=\${PATH}:/usr/local/cuda/bin" >> ~/.bashrc -RUN echo "export LD_LIBRARY_PATH=\${LD_LIBRARY_PATH}:/usr/local/cuda/lib64" >> ~/.bashrc - # * Setup python virtual environment # RUN python3 -m venv venv \ # && . venv/bin/activate \ diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index dc00770..67a65d4 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -36,6 +36,11 @@ "gpu": "optional" }, + "remoteEnv": { + "PATH": "${containerEnv:PATH}:/usr/local/cuda/bin", + "LD_LIBRARY_PATH": "${containerEnv:LD_LIBRARY_PATH}:/usr/local/cuda/lib64" + }, + // Use 'postCreateCommand' to run commands after the container is created. "postCreateCommand": "/bin/bash -c 'uname -a && source ~/.bashrc && pre-commit install --install-hooks' && /bin/bash", diff --git a/.vscode/settings.json b/.vscode/settings.json index 59aa686..723e9f3 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -20,6 +20,7 @@ "c-cpp-flylint.excludeFromWorkspacePaths": [ "/usr/include/**", "/usr/local/include/**", + // "/usr/local/cuda/include/**" ], "c-cpp-flylint.standard": [ "c11", diff --git a/CMakeLists.txt b/CMakeLists.txt index d6d9bbb..d380121 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,7 @@ # See the License for the specific language governing permissions and # limitations under the License. -cmake_minimum_required(VERSION 3.16) +cmake_minimum_required(VERSION 3.18) # Include cmake module path list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") @@ -46,6 +46,9 @@ cmake_dependent_option(BUILD_TESTING "Enable testing" ON "CMAKE_PROJECT_NAME STR # Set the default position-independent code option cmake_dependent_option(CMAKE_POSITION_INDEPENDENT_CODE "Generate position-independent code" ON "BUILD_SHARED_LIBS" OFF) +# Dependencies Setup +include(cuda) + # Setup the test if(CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME) include(CTest) @@ -101,6 +104,13 @@ target_compile_options(example_debug PUBLIC -g # Generate debug information ) +# CUDA executable example +if(CMAKE_CUDA_COMPILER) + add_executable(example_cuda + src/example_cuda.cu + ) +endif() + # Setup sanitizers add_custom_target(sanitizer) include(cppcheck) diff --git a/README.md b/README.md index fea3f6a..9c10da6 100644 --- a/README.md +++ b/README.md @@ -80,6 +80,7 @@ This template is designed with a primary focus on enabling individuals to set up ┃ ┣ 📜ExampleProjectConfig.cmake.in ┃ ┣ 📜Version.h.in ┃ ┣ 📜clang-tidy.cmake + ┃ ┣ 📜cuda.cmake ┃ ┗ 📜cppcheck.cmake ┣ 📦docs ┃ ┣ 📜index.md @@ -88,7 +89,8 @@ This template is designed with a primary focus on enabling individuals to set up ┃ ┃ ┗ 📜Version.h ┣ 📂src ┃ ┣ 📜example_debug.cpp - ┃ ┗ 📜example_project.cpp + ┃ ┣ 📜example_project.cpp + ┃ ┗ 📜example_cuda.cu ┣ 📂test ┃ ┣ 📜CMakeLists.txt ┃ ┗ 📜test_example.cpp @@ -110,6 +112,13 @@ This template is designed with a primary focus on enabling individuals to set up - Rename folder name of [***include/ExampleProject***](include) - Rename [***cmake/ExampleProjectConfig.cmake.in***](cmake) +3. CUDA (Optional) + - Uncomment cuda features in [***devcontainer.json***](.devcontainer/devcontainer.json) + +4. Documentations via mkdocs (Optional) + - Check **GitHub Pages** and Select **Deploy from a branch**, Branch as **gh-pages**, **/(root)**. + - Check [***docs workflow***](.github/workflows/docs.yml), [***mkdocs configuration***](mkdocs.yml) + --- ## 📜 License @@ -129,7 +138,7 @@ For any inquiries or support, please contact timetravelCat@gmail.com --- ## ✅ TODO -- [ ] Automatically detect CUDA and CUDA hardware. +- [x] Automatically detect CUDA and CUDA hardware. - [ ] ROS2 branch, for ROS2-based packages. - [x] Project documentation template (using mkdocs). - [ ] Option for direct use of Docker image including all major features. diff --git a/cmake/cuda.cmake b/cmake/cuda.cmake new file mode 100644 index 0000000..d79c414 --- /dev/null +++ b/cmake/cuda.cmake @@ -0,0 +1,27 @@ +# Copyright 2024 timetravelCat +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +include(CheckLanguage) +check_language(CUDA) + +if(CMAKE_CUDA_COMPILER) + enable_language(CUDA) + set(CMAKE_CUDA_STANDARD 17) + set(CMAKE_CUDA_STANDARD_REQUIRED ON) + set(CMAKE_CUDA_SEPARABLE_COMPILATION ON) + + # https://developer.nvidia.com/cuda-gpus + # native is available in 3.24 https://cmake.org/cmake/help/latest/prop_tgt/CUDA_ARCHITECTURES.html#prop_tgt:CUDA_ARCHITECTURES + set(CMAKE_CUDA_ARCHITECTURES 86) +endif() diff --git a/src/example_cuda.cu b/src/example_cuda.cu new file mode 100644 index 0000000..e9aa90a --- /dev/null +++ b/src/example_cuda.cu @@ -0,0 +1,49 @@ +/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of NVIDIA CORPORATION nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +// System includes +#include + +// CUDA runtime +#include + +__global__ void testKernel(int val) { + printf("[%d, %d]:\t\tValue is:%d\n", blockIdx.y * gridDim.x + blockIdx.x, threadIdx.z * blockDim.x * blockDim.y + threadIdx.y * blockDim.x + threadIdx.x, val); +} + +int main(int argc, char** argv) { + printf("printf() is called. Output:\n\n"); + + // Kernel configuration, where a two-dimensional grid and + // three-dimensional blocks are configured. + dim3 dimGrid(2, 2); + dim3 dimBlock(2, 2, 2); + testKernel<<>>(10); + cudaDeviceSynchronize(); + + return EXIT_SUCCESS; +}