-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Initial CMake build files. Still a work in progress. * Fix typo. * Update defines. * Add NVSHMEM include path. * Refresh CMake build files. Add modifications for Cray/HPE build environments. * Add NCCL and NVSHMEM overrides to CMake build. * Small updates. * Do not use Cray compiler wrappers. * Update libnvshmem_host link in CMake so it sets rpath. * Set default CMake build to RelWithDebInfo. * Update README.md with CMake build instructions. * Update README.md. * Update NCCL and NVSHMEM path naming to be consistent with Makefile build configuration.
- Loading branch information
1 parent
e30142a
commit a0cfb18
Showing
12 changed files
with
690 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,263 @@ | ||
cmake_minimum_required(VERSION 3.16) | ||
set(CMAKE_CXX_STANDARD 14) | ||
set(CMAKE_DISABLE_SOURCE_CHANGES ON) | ||
set(CMAKE_DISABLE_IN_SOURCE_BUILD ON) | ||
if (NOT CMAKE_BUILD_TYPE) | ||
set(CMAKE_BUILD_TYPE RelWithDebInfo) | ||
endif() | ||
|
||
# User-defined build options | ||
option(CUDECOMP_BUILD_FORTRAN "Build Fortran bindings" ON) | ||
option(CUDECOMP_ENABLE_NVTX "Enable NVTX ranges" ON) | ||
option(CUDECOMP_ENABLE_NVSHMEM "Enable NVSHMEM" OFF) | ||
option(CUDECOMP_BUILD_EXTRAS "Build benchmark, examples, and tests" OFF) | ||
set(CUDECOMP_CUDA_CC_LIST "70;80;90" CACHE STRING "List of CUDA compute capabilities to build cuDecomp for.") | ||
set(CUDECOMP_NCCL_HOME CACHE STRING "Path to search for NCCL installation. Use to override NVHPC provided NCCL version.") | ||
set(CUDECOMP_NVSHMEM_HOME CACHE STRING "Path to search for NVSHMEM installation. Use to override NVHPC provided NVSHMEM version.") | ||
|
||
# Use NVHPC compilers by default | ||
set(CMAKE_CXX_COMPILER "nvc++") | ||
set(CMAKE_Fortran_COMPILER "nvfortran") | ||
|
||
# Locate and use NVHPC CMake configuration | ||
find_program(NVHPC_CXX_BIN "nvc++") | ||
string(REPLACE "compilers/bin/nvc++" "cmake" NVHPC_CMAKE_DIR ${NVHPC_CXX_BIN}) | ||
set(CMAKE_PREFIX_PATH ${NVHPC_CMAKE_DIR}) | ||
|
||
if (CUDECOMP_BUILD_FORTRAN) | ||
set(LANGS CXX CUDA Fortran) | ||
else() | ||
set(LANGS CXX CUDA) | ||
endif() | ||
|
||
project(cudecomp LANGUAGES ${LANGS}) | ||
|
||
# Detect if Cray compiler wrappers are available to assess if in Cray environment. | ||
# We do not use the Cray compiler wrappers directly for greater flexibility. | ||
find_program(CRAY_CC_BIN "CC") | ||
|
||
if (CRAY_CC_BIN) | ||
message(STATUS "Found Cray CC wrapper. Compiling for Cray programming environment.") | ||
endif() | ||
|
||
# MPI | ||
find_package(MPI REQUIRED) | ||
|
||
if (CRAY_CC_BIN) | ||
# FindMPI does not include Cray GTL (e.g. CUDA-aware) libs | ||
# automatically in Cray environment. Locate it to include in linking. | ||
string(REPLACE ":" ";" CRAY_LIB_PATHS $ENV{CRAY_LD_LIBRARY_PATH}) | ||
find_library(CRAY_MPI_GTL_CUDA_LIBRARY REQUIRED | ||
NAMES mpi_gtl_cuda | ||
HINTS ${CRAY_LIB_PATHS} | ||
) | ||
|
||
# Cray GTL libs benefit from linking against gdrcopy, so also | ||
# locating that library. | ||
find_library(GDRCOPY_LIBRARY REQUIRED | ||
NAMES gdrapi | ||
) | ||
|
||
message(STATUS "Found Cray GTL library: " ${CRAY_MPI_GTL_CUDA_LIBRARY}) | ||
message(STATUS "Found GDRCopy library: " ${GDRCOPY_LIBRARY}) | ||
endif() | ||
|
||
# TODO: Check for MPICH to define `-DMPICH` flag | ||
|
||
# HPC SDK | ||
find_package(NVHPC REQUIRED COMPONENTS CUDA MATH) | ||
|
||
# Set up required include directory flags, NVHPC CMake config only defined library directories | ||
string(REPLACE "/lib64" "/include" NVHPC_CUDA_INCLUDE_DIR ${NVHPC_CUDA_LIBRARY_DIR}) | ||
string(REPLACE "/lib64" "/include" NVHPC_CUFFT_INCLUDE_DIR ${NVHPC_MATH_LIBRARY_DIR}) | ||
string(REPLACE "/lib64" "/include" NVHPC_CUTENSOR_INCLUDE_DIR ${NVHPC_MATH_LIBRARY_DIR}) | ||
|
||
# Get NCCL library (with optional override) | ||
if (CUDECOMP_NCCL_HOME) | ||
find_path(NCCL_INCLUDE_DIR REQUIRED | ||
NAMES nccl.h | ||
HINTS ${CUDECOMP_NCCL_HOME}/include | ||
) | ||
|
||
find_library(NCCL_LIBRARY REQUIRED | ||
NAMES nccl | ||
HINTS ${CUDECOMP_NCCL_HOME}/lib | ||
) | ||
else() | ||
find_package(NVHPC REQUIRED COMPONENTS NCCL) | ||
find_library(NCCL_LIBRARY | ||
NAMES nccl | ||
HINTS ${NVHPC_NCCL_LIBRARY_DIR} | ||
) | ||
string(REPLACE "/lib" "/include" NCCL_INCLUDE_DIR ${NVHPC_NCCL_LIBRARY_DIR}) | ||
endif() | ||
|
||
message(STATUS "Using NCCL library: ${NCCL_LIBRARY}") | ||
|
||
if (CUDECOMP_ENABLE_NVSHMEM) | ||
# Get NVSHMEM library (with optional override) | ||
if (CUDECOMP_NVSHMEM_HOME) | ||
find_path(NVSHMEM_INCLUDE_DIR REQUIRED | ||
NAMES nvshmem.h | ||
HINTS ${CUDECOMP_NVSHMEM_HOME}/include | ||
) | ||
|
||
find_path(NVSHMEM_LIBRARY_DIR REQUIRED | ||
NAMES libnvshmem.a | ||
HINTS ${CUDECOMP_NVSHMEM_HOME}/lib | ||
) | ||
else() | ||
find_package(NVHPC REQUIRED COMPONENTS NVSHMEM) | ||
set(NVSHMEM_LIBRARY_DIR ${NVHPC_NVSHMEM_LIBRARY_DIR}) | ||
string(REPLACE "/lib" "/include" NVSHMEM_INCLUDE_DIR ${NVHPC_NVSHMEM_LIBRARY_DIR}) | ||
endif() | ||
|
||
message(STATUS "Using NVSHMEM installation at: ${NVSHMEM_LIBRARY_DIR}") | ||
|
||
endif() | ||
|
||
# Building cuDecomp shared lib | ||
add_library(cudecomp SHARED) | ||
set_target_properties(cudecomp PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) | ||
|
||
# Set NVCC flags for requested compute capability | ||
if (CMAKE_VERSION VERSION_LESS 3.18) | ||
foreach(CUDA_CC ${CUDECOMP_CUDA_CC_LIST}) | ||
list(APPEND CUDA_CC_FLAGS -gencode=arch=compute_${CUDA_CC},code=sm_${CUDA_CC}) | ||
endforeach() | ||
target_compile_options(cudecomp PRIVATE $<$<COMPILE_LANGUAGE:CUDA>: ${CUDA_CC_FLAGS}>) | ||
else() | ||
set_target_properties(cudecomp PROPERTIES CUDA_ARCHITECTURES "${CUDECOMP_CUDA_CC_LIST}") | ||
endif() | ||
target_sources(cudecomp | ||
PRIVATE | ||
${CMAKE_CURRENT_SOURCE_DIR}/src/autotune.cc | ||
${CMAKE_CURRENT_SOURCE_DIR}/src/cudecomp_kernels.cu | ||
${CMAKE_CURRENT_SOURCE_DIR}/src/cudecomp.cc | ||
) | ||
|
||
target_include_directories(cudecomp | ||
PRIVATE | ||
${CMAKE_CURRENT_SOURCE_DIR}/include | ||
${MPI_CXX_INCLUDE_DIRS} | ||
${NVHPC_CUDA_INCLUDE_DIR} | ||
${NVHPC_CUTENSOR_INCLUDE_DIR} | ||
${NCCL_INCLUDE_DIR} | ||
) | ||
|
||
target_link_libraries(cudecomp PUBLIC NVHPC::CUDART) | ||
target_link_libraries(cudecomp PUBLIC MPI::MPI_CXX) | ||
target_link_libraries(cudecomp PRIVATE NVHPC::CUTENSOR) | ||
target_link_libraries(cudecomp PRIVATE ${NCCL_LIBRARY}) | ||
if (CRAY_CC_BIN) | ||
# In Cray environments, add links to GTL and GDRCopy libs for CUDA-aware support | ||
target_link_libraries(cudecomp PRIVATE ${CRAY_MPI_GTL_CUDA_LIBRARY}) | ||
target_link_libraries(cudecomp PRIVATE ${GDRCOPY_LIBRARY}) | ||
endif() | ||
|
||
if (CUDECOMP_ENABLE_NVTX) | ||
target_compile_definitions(cudecomp PRIVATE ENABLE_NVTX) | ||
endif() | ||
|
||
if (CUDECOMP_ENABLE_NVSHMEM) | ||
target_compile_definitions(cudecomp PRIVATE ENABLE_NVSHMEM) | ||
target_include_directories(cudecomp | ||
PRIVATE | ||
${NVSHMEM_INCLUDE_DIR} | ||
) | ||
|
||
# Get NVSHMEM version from header | ||
if (EXISTS ${NVSHMEM_INCLUDE_DIR}/nvshmem_version.h) | ||
file(READ ${NVSHMEM_INCLUDE_DIR}/nvshmem_version.h NVSHMEM_VERSION_RAW) | ||
else() | ||
file(READ ${NVSHMEM_INCLUDE_DIR}/common/nvshmem_version.h NVSHMEM_VERSION_RAW) | ||
endif() | ||
string(REGEX MATCH "NVSHMEM_VENDOR_MAJOR_VERSION ([0-9]*)" _ ${NVSHMEM_VERSION_RAW}) | ||
list(APPEND NVSHMEM_VERSION ${CMAKE_MATCH_1}) | ||
string(REGEX MATCH "NVSHMEM_VENDOR_MINOR_VERSION ([0-9]*)" _ ${NVSHMEM_VERSION_RAW}) | ||
list(APPEND NVSHMEM_VERSION ${CMAKE_MATCH_1}) | ||
list(JOIN NVSHMEM_VERSION "." NVSHMEM_VERSION) | ||
|
||
if (NVSHMEM_VERSION VERSION_LESS "2.7") | ||
# NVSHMEM versions before 2.7 will export NCCL symbols erroneously, need to define this flag | ||
target_compile_definitions(cudecomp PRIVATE NVSHMEM_USE_NCCL) | ||
endif() | ||
|
||
if (NVSHMEM_VERSION VERSION_LESS "2.5") | ||
target_link_libraries(cudecomp PRIVATE ${NVSHMEM_LIBRARY_DIR}/libnvshmem.a) | ||
else() | ||
target_link_libraries(cudecomp PRIVATE ${NVSHMEM_LIBRARY_DIR}/libnvshmem_host.so) | ||
target_link_libraries(cudecomp PRIVATE ${NVSHMEM_LIBRARY_DIR}/libnvshmem_device.a) | ||
target_link_libraries(cudecomp PUBLIC -L${NVHPC_CUDA_LIBRARY_DIR}/stubs -lnvidia-ml) | ||
endif() | ||
target_link_libraries(cudecomp PUBLIC -L${NVHPC_CUDA_LIBRARY_DIR}/stubs -lcuda) | ||
set_target_properties(cudecomp PROPERTIES CUDA_SEPARABLE_COMPILATION ON) | ||
set_target_properties(cudecomp PROPERTIES CUDA_RESOLVE_DEVICE_SYMBOLS ON) | ||
endif() | ||
|
||
set_target_properties(cudecomp PROPERTIES PUBLIC_HEADER ${CMAKE_CURRENT_SOURCE_DIR}/include/cudecomp.h) | ||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/include/cudecomp.h ${CMAKE_BINARY_DIR}/include/cudecomp.h) | ||
|
||
install( | ||
TARGETS cudecomp | ||
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib | ||
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_PREFIX}/include | ||
) | ||
|
||
# Building Fortran shared lib and module | ||
if (CUDECOMP_BUILD_FORTRAN) | ||
# Creating -gpu argument string for Fortran files | ||
foreach(CUDA_CC ${CUDECOMP_CUDA_CC_LIST}) | ||
list(APPEND CUF_GPU_ARG "cc${CUDA_CC}") | ||
endforeach() | ||
list(APPEND CUF_GPU_ARG "cuda${NVHPC_CUDA_VERSION}") | ||
list(JOIN CUF_GPU_ARG "," CUF_GPU_ARG) | ||
|
||
add_library(cudecomp_fort SHARED) | ||
set_target_properties(cudecomp_fort PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) | ||
set_target_properties(cudecomp_fort PROPERTIES Fortran_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/include) | ||
set_target_properties(cudecomp_fort PROPERTIES LINKER_LANGUAGE Fortran) | ||
target_compile_options(cudecomp_fort PRIVATE $<$<COMPILE_LANGUAGE:Fortran>:-cpp -cuda -gpu=${CUF_GPU_ARG}>) | ||
target_sources( | ||
cudecomp_fort | ||
PRIVATE | ||
${CMAKE_CURRENT_SOURCE_DIR}/src/cudecomp_m.cuf | ||
) | ||
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/src/cudecomp_m.cuf PROPERTIES LANGUAGE Fortran) | ||
|
||
target_link_libraries(cudecomp_fort PUBLIC MPI::MPI_Fortran) | ||
|
||
# Test for MPI_Comm_f2c/c2f | ||
try_compile( | ||
TEST_F2C_RESULT | ||
${CMAKE_BINARY_DIR} | ||
${CMAKE_CURRENT_SOURCE_DIR}/cmake/test_mpi_f2c.f90 | ||
LINK_LIBRARIES MPI::MPI_Fortran | ||
) | ||
if (NOT TEST_F2C_RESULT) | ||
message(STATUS "Could not link MPI_Comm_f2c in Fortran module. Setting -DMPICH flag during module compilation.") | ||
target_compile_definitions(cudecomp_fort PRIVATE MPICH) | ||
endif() | ||
|
||
install( | ||
TARGETS cudecomp_fort | ||
LIBRARY DESTINATION ${CMAKE_INSTALL_PREFIX}/lib | ||
) | ||
# Install cuDecomp module | ||
install(FILES ${CMAKE_BINARY_DIR}/include/cudecomp.mod DESTINATION ${CMAKE_INSTALL_PREFIX}/include) | ||
endif() | ||
|
||
if (CUDECOMP_BUILD_EXTRAS) | ||
add_subdirectory(benchmark) | ||
|
||
add_subdirectory(tests/cc) | ||
add_subdirectory(examples/cc/basic_usage) | ||
add_subdirectory(examples/cc/taylor_green) | ||
|
||
if (CUDECOMP_BUILD_FORTRAN) | ||
add_subdirectory(tests/fortran) | ||
add_subdirectory(examples/fortran/basic_usage) | ||
add_subdirectory(examples/fortran/poisson) | ||
endif() | ||
endif() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
set(benchmark_targets | ||
benchmark_r2c | ||
benchmark_c2c | ||
benchmark_r2c_f | ||
benchmark_c2c_f | ||
) | ||
|
||
foreach(tgt ${benchmark_targets}) | ||
add_executable(${tgt}) | ||
if (CMAKE_VERSION VERSION_LESS 3.18) | ||
target_compile_options(${tgt} PRIVATE $<$<COMPILE_LANGUAGE:CUDA>: ${CUDA_CC_FLAGS}>) | ||
else() | ||
set_target_properties(${tgt} PROPERTIES CUDA_ARCHITECTURES "${CUDECOMP_CUDA_CC_LIST}") | ||
endif() | ||
target_sources(${tgt} | ||
PRIVATE | ||
benchmark.cu | ||
) | ||
target_include_directories(${tgt} | ||
PRIVATE | ||
${CMAKE_CURRENT_SOURCE_DIR}/../include | ||
${NVHPC_CUFFT_INCLUDE_DIR} | ||
${NCCL_INCLUDE_DIR} | ||
${MPI_CXX_INCLUDE_DIRS}) | ||
target_link_libraries(${tgt} PRIVATE cudecomp) | ||
target_link_libraries(${tgt} PRIVATE NVHPC::CUFFT) | ||
set_target_properties(${tgt} PROPERTIES LINKER_LANGUAGE CXX) | ||
endforeach() | ||
|
||
target_compile_definitions(benchmark_r2c PRIVATE R2C) | ||
target_compile_definitions(benchmark_c2c PRIVATE C2C) | ||
target_compile_definitions(benchmark_r2c_f PRIVATE R2C USE_FLOAT) | ||
target_compile_definitions(benchmark_c2c_f PRIVATE R2C USE_FLOAT) | ||
|
||
install( | ||
TARGETS ${benchmark_targets} | ||
RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}/bin/benchmark | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
! SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved. | ||
! SPDX-License-Identifier: BSD-3-Clause | ||
! | ||
! Redistribution and use in source and binary forms, with or without | ||
! modification, are permitted provided that the following conditions are met: | ||
! | ||
! 1. Redistributions of source code must retain the above copyright notice, this | ||
! list of conditions and the following disclaimer. | ||
! | ||
! 2. 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. | ||
! | ||
! 3. Neither the name of the copyright holder 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 AND CONTRIBUTORS "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 HOLDER 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. | ||
|
||
module test_f2c | ||
use iso_c_binding | ||
implicit none | ||
|
||
type, bind(c) :: MPI_C_Comm | ||
integer(c_int64_t) :: comm | ||
end type MPI_C_Comm | ||
|
||
type, bind(c) :: MPI_F_Comm | ||
integer(c_int) :: comm | ||
end type MPI_F_Comm | ||
|
||
interface | ||
function MPI_Comm_f2c(fcomm) bind(C,name='MPI_Comm_f2c') result(res) | ||
import | ||
type(MPI_F_Comm), value :: fcomm | ||
type(MPI_C_Comm) :: res | ||
end function MPI_Comm_f2c | ||
end interface | ||
end module | ||
|
||
program main | ||
use mpi | ||
use test_f2c | ||
implicit none | ||
|
||
type(MPI_F_Comm) :: fcomm | ||
type(MPI_C_Comm) :: ccomm | ||
|
||
fcomm%comm = MPI_COMM_WORLD | ||
|
||
ccomm = MPI_Comm_f2c(fcomm) | ||
end program |
Oops, something went wrong.