Skip to content

Commit e1fefb9

Browse files
authored
build(unit_tests): custom CMake helper for adding unit tests (#196)
* build(unit_tests): add CMake util fn for easily adding new tests Signed-off-by: Gabriel Dos Santos <[email protected]> * build(unit_tests): rework test decls using new helper function Signed-off-by: Gabriel Dos Santos <[email protected]> * chore: update CMake format to hint custom function definitions Signed-off-by: Gabriel Dos Santos <[email protected]> * fix(unit_tests): find CMake module when building standalone Signed-off-by: Gabriel Dos Santos <[email protected]> --------- Signed-off-by: Gabriel Dos Santos <[email protected]>
1 parent 7c3d596 commit e1fefb9

File tree

3 files changed

+159
-173
lines changed

3 files changed

+159
-173
lines changed

.cmake-format

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
definitions: [./cmake/kc-test.cmake]
12
line_length: 120
23
list_expansion: favour-inlining
34
indent: 2

cmake/kc-test.cmake

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
function(kc_add_unit_test name)
2+
# gersemi: hints { FILES: command_line, OPTIONS: command_line, INCLUDES: command_line, LIBRARIES: command_line }
3+
set(options CORE MPI NCCL)
4+
set(oneValueArgs NUM_PES)
5+
set(multiValueArgs FILES OPTIONS INCLUDES LIBRARIES)
6+
cmake_parse_arguments(UT "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
7+
8+
add_executable(${name})
9+
target_sources(${name} PRIVATE ${UT_FILES})
10+
target_compile_features(${name} PRIVATE cxx_std_20)
11+
target_compile_options(${name} PRIVATE ${UT_OPTIONS})
12+
target_include_directories(${name} PRIVATE ${UT_INCLUDES})
13+
target_link_libraries(${name} PRIVATE gtest fmt::fmt ${UT_LIBRARIES})
14+
15+
if(UT_CORE)
16+
target_link_libraries(${name} PRIVATE KokkosComm::KokkosComm MPI::MPI_CXX)
17+
if(KOKKOSCOMM_ENABLE_NCCL)
18+
target_link_libraries(${name} PRIVATE NCCL::NCCL)
19+
endif()
20+
elseif(UT_MPI)
21+
target_link_libraries(${name} PRIVATE MPI::MPI_CXX)
22+
elseif(UT_NCCL)
23+
target_link_libraries(${name} PRIVATE NCCL::NCCL)
24+
endif()
25+
26+
add_test(NAME ${name} COMMAND ${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${UT_NUM_PES} ./${name})
27+
endfunction()

unit_tests/CMakeLists.txt

Lines changed: 131 additions & 173 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ cmake_minimum_required(VERSION 3.23) # same as KokkosComm
33
project(
44
KokkosCommUnitTests
55
VERSION 0.2.0
6-
LANGUAGES
7-
CXX
6+
LANGUAGES CXX
87
DESCRIPTION "Unit tests for the KokkosComm experimental communication interfaces"
98
)
109

@@ -43,196 +42,155 @@ FetchContent_Declare(
4342
)
4443
FetchContent_MakeAvailable(fmt)
4544

45+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
46+
include(kc-test)
47+
48+
# --- Core API unit tests --- #
49+
kc_add_unit_test(test.core.p2p CORE NUM_PES 2 FILES test_main.cpp test_sendrecv.cpp)
50+
51+
# --- MPI backend unit tests --- #
4652
if(KOKKOSCOMM_ENABLE_MPI)
4753
# Standalone MPI smoke tests (do not use KokkosComm)
48-
add_executable(test-mpi)
49-
target_sources(test-mpi PRIVATE mpi/test_mpi.cpp)
50-
# doesn't use KokkosComm, so explicitly link MPI
51-
target_link_libraries(test-mpi PRIVATE MPI::MPI_CXX)
52-
add_test(
53-
NAME test-mpi-1
54-
COMMAND
55-
${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 1 ./test-mpi
56-
)
57-
add_test(
58-
NAME test-mpi-2
59-
COMMAND
60-
${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ./test-mpi
61-
)
54+
kc_add_unit_test(smoke.mpi.1pe MPI NUM_PES 1 FILES mpi/test_mpi.cpp)
55+
kc_add_unit_test(smoke.mpi.2pes MPI NUM_PES 2 FILES mpi/test_mpi.cpp)
6256

6357
# KOKKOS_ENABLE_CUDA is not set?
6458
if(Kokkos_ENABLE_CUDA)
65-
add_executable(test-mpi-cuda-sendrecv)
66-
target_sources(test-mpi-cuda-sendrecv PRIVATE mpi/test_mpi_cuda_sendrecv.cpp)
67-
target_link_libraries(test-mpi-cuda-sendrecv PRIVATE MPI::MPI_CXX)
68-
59+
kc_add_unit_test(smoke.mpi.cuda-p2p MPI NUM_PES 2 FILES mpi/test_mpi_cuda_sendrecv.cpp)
6960
# MPICH needs dynamic cudart (we think, pmodels/mpich#7304)
7061
if(KOKKOSCOMM_IMPL_MPI_IS_MPICH)
7162
# Setting the CUDA_RUNTIME_LIBRARY property on this target to "Shared" doesn't work for
7263
# reasons I don't understand.
73-
target_compile_options(
74-
test-mpi-cuda-sendrecv
75-
PUBLIC
76-
--cudart
77-
shared
78-
)
79-
target_link_options(
80-
test-mpi-cuda-sendrecv
81-
PUBLIC
82-
--cudart
83-
shared
84-
)
64+
target_compile_options(smoke.mpi.cuda-p2p PUBLIC --cudart shared)
65+
target_link_options(smoke.mpi.cuda-p2p PUBLIC --cudart shared)
8566
endif()
86-
add_test(
87-
NAME test-mpi-cuda-sendrecv
88-
COMMAND
89-
${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ./test-mpi-cuda-sendrecv
90-
)
9167
endif()
9268

9369
if(Kokkos_ENABLE_HIP)
9470
find_package(hip REQUIRED)
95-
add_executable(test-mpi-hip-sendrecv)
96-
target_sources(test-mpi-hip-sendrecv PRIVATE mpi/test_mpi_hip_sendrecv.cpp)
97-
target_link_libraries(test-mpi-hip-sendrecv PRIVATE MPI::MPI_CXX)
98-
target_link_libraries(test-mpi-hip-sendrecv hip::host)
99-
target_compile_options(
100-
test-mpi-hip-sendrecv
101-
PUBLIC
102-
-x
103-
hip
104-
)
105-
add_test(
106-
NAME test-mpi-hip-sendrecv
107-
COMMAND
108-
${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ./test-mpi-hip-sendrecv
109-
)
71+
kc_add_unit_test(smoke.mpi.hip-p2p MPI NUM_PES 2 FILES mpi/test_mpi_cuda_sendrecv.cpp OPTIONS -xhip LIBRARIES hip::host)
11072
endif()
111-
endif()
112-
113-
if(KOKKOSCOMM_ENABLE_NCCL)
114-
# Standalone NCCL smoke tests (do not use KokkosComm)
115-
add_executable(test-nccl)
116-
target_sources(test-nccl PRIVATE nccl/test_nccl.cpp)
117-
target_compile_features(test-nccl PRIVATE cxx_std_20)
118-
# doesn't use KokkosComm, so explicitly link with NCCL
119-
target_link_libraries(test-nccl PRIVATE NCCL::NCCL)
120-
add_test(NAME test-nccl-smoke COMMAND ./test-nccl)
121-
endif()
12273

123-
# Tests using the MPI communication space
124-
function(add_mpi_test test_name num_procs)
125-
# Extract source files from remaining arguments
126-
set(source_files ${ARGN})
127-
# Add test_main.cpp and the provided source files
128-
add_executable(${test_name})
129-
target_sources(
130-
${test_name}
131-
PRIVATE
132-
test_main.cpp
133-
${source_files}
134-
)
135-
target_link_libraries(
136-
${test_name}
137-
PRIVATE
138-
KokkosComm::KokkosComm
139-
MPI::MPI_CXX # Explicitly link against MPI
140-
gtest
141-
fmt::fmt
142-
)
143-
add_test(
144-
NAME ${test_name}
145-
COMMAND
146-
${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${num_procs} ./${test_name}
147-
)
148-
endfunction()
149-
150-
# Tests using the NCCL communication space
151-
function(add_nccl_test test_name num_procs)
152-
# Extract source files from remaining arguments
153-
set(source_files ${ARGN})
154-
# Add test_main.cpp and the provided source files
155-
add_executable(${test_name})
156-
target_sources(
157-
${test_name}
158-
PRIVATE
159-
test_main.cpp
160-
${source_files}
161-
)
162-
target_link_libraries(
163-
${test_name}
164-
PRIVATE
165-
KokkosComm::KokkosComm
166-
NCCL::NCCL
167-
MPI::MPI_CXX # Explicitly link against MPI because it's needed to setup multi-node NCCL comms
168-
gtest
169-
fmt::fmt
170-
)
171-
add_test(
172-
NAME ${test_name}
173-
COMMAND
174-
${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} ${num_procs} ./${test_name}
175-
)
176-
endfunction()
177-
178-
# General KokkosComm tests
179-
add_executable(test-main)
180-
target_sources(
181-
test-main
182-
PRIVATE
183-
test_main.cpp
184-
test_sendrecv.cpp
185-
PRIVATE
186-
FILE_SET HEADERS
187-
BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}
188-
FILES logging.hpp
189-
)
190-
target_compile_features(test-main PRIVATE cxx_std_20)
191-
target_link_libraries(
192-
test-main
193-
PRIVATE
194-
GTest::gtest_main
195-
KokkosComm::KokkosComm
196-
MPI::MPI_CXX
197-
fmt::fmt
198-
)
199-
200-
if(KokkosComm_ENABLE_MPI)
201-
add_mpi_test(test-gtest-mpi 2 mpi/test_gtest_mpi.cpp) # make sure gtest is working
202-
add_mpi_test(test-mpi-view-access 2 mpi/test_mpi_view_access.cpp) # make sure MPI can access Kokkos::View data
203-
add_mpi_test(test-sendrecv 2 mpi/test_sendrecv.cpp)
204-
add_mpi_test(test-isendrecv 2 mpi/test_isendrecv.cpp)
205-
add_mpi_test(test-barrier 2 mpi/test_barrier.cpp)
206-
add_mpi_test(test-broadcast 2 mpi/test_broadcast.cpp)
207-
add_mpi_test(test-reduce 2 mpi/test_reduce.cpp)
208-
add_mpi_test(test-allreduce 2 mpi/test_allreduce.cpp)
209-
add_mpi_test(test-alltoall 2 mpi/test_alltoall.cpp)
210-
add_mpi_test(test-allgather 2 mpi/test_allgather.cpp)
211-
add_mpi_test(test-scan 2 mpi/test_scan.cpp)
74+
# Make sure GTest is working
75+
kc_add_unit_test(
76+
test.mpi.gtest
77+
MPI
78+
NUM_PES 2
79+
FILES test_main.cpp mpi/test_gtest_mpi.cpp
80+
LIBRARIES KokkosComm::KokkosComm
81+
)
82+
# Make sure MPI can access Kokkos::View data
83+
kc_add_unit_test(
84+
test.mpi.view-access
85+
MPI
86+
NUM_PES 2
87+
FILES test_main.cpp mpi/test_mpi_view_access.cpp
88+
LIBRARIES KokkosComm::KokkosComm
89+
)
21290

213-
add_test(
214-
NAME test-main
215-
COMMAND
216-
${MPIEXEC_EXECUTABLE} ${MPIEXEC_NUMPROC_FLAG} 2 ./test-main
91+
kc_add_unit_test(
92+
test.mpi.sendrecv
93+
MPI
94+
NUM_PES 2
95+
FILES test_main.cpp mpi/test_sendrecv.cpp
96+
LIBRARIES KokkosComm::KokkosComm
21797
)
98+
kc_add_unit_test(
99+
test.mpi.isendrecv
100+
MPI
101+
NUM_PES 2
102+
FILES test_main.cpp mpi/test_isendrecv.cpp
103+
LIBRARIES KokkosComm::KokkosComm
104+
)
105+
kc_add_unit_test(
106+
test.mpi.barrier
107+
MPI
108+
NUM_PES 2
109+
FILES test_main.cpp mpi/test_barrier.cpp
110+
LIBRARIES KokkosComm::KokkosComm
111+
)
112+
kc_add_unit_test(
113+
test.mpi.broadcast
114+
MPI
115+
NUM_PES 2
116+
FILES test_main.cpp mpi/test_broadcast.cpp
117+
LIBRARIES KokkosComm::KokkosComm
118+
)
119+
kc_add_unit_test(
120+
test.mpi.reduce
121+
MPI
122+
NUM_PES 2
123+
FILES test_main.cpp mpi/test_reduce.cpp
124+
LIBRARIES KokkosComm::KokkosComm
125+
)
126+
kc_add_unit_test(
127+
test.mpi.allreduce
128+
MPI
129+
NUM_PES 2
130+
FILES test_main.cpp mpi/test_allreduce.cpp
131+
LIBRARIES KokkosComm::KokkosComm
132+
)
133+
kc_add_unit_test(
134+
test.mpi.alltoall
135+
MPI
136+
NUM_PES 2
137+
FILES test_main.cpp mpi/test_alltoall.cpp
138+
LIBRARIES KokkosComm::KokkosComm
139+
)
140+
kc_add_unit_test(
141+
test.mpi.allgather
142+
MPI
143+
NUM_PES 2
144+
FILES test_main.cpp mpi/test_allgather.cpp
145+
LIBRARIES KokkosComm::KokkosComm
146+
)
147+
kc_add_unit_test(test.mpi.scan MPI NUM_PES 2 FILES test_main.cpp mpi/test_scan.cpp LIBRARIES KokkosComm::KokkosComm)
218148
endif()
219149

150+
# --- NCCL backend unit tests --- #
220151
if(KokkosComm_ENABLE_NCCL)
221-
# Add `unit_tests/nccl/` to included directories
222-
target_sources(
223-
test-main
224-
PRIVATE
225-
FILE_SET HEADERS
226-
BASE_DIRS ${CMAKE_CURRENT_SOURCE_DIR}
227-
FILES nccl/utils.hpp
228-
)
229-
# Link against NCCL because we depend on raw calls
230-
target_link_libraries(test-main PRIVATE NCCL::NCCL)
231-
232-
add_nccl_test(test-p2p 2 nccl/test_point_to_point.cpp)
233-
add_nccl_test(test-broadcast 2 nccl/test_broadcast.cpp)
234-
add_nccl_test(test-allgather 2 nccl/test_allgather.cpp)
235-
add_nccl_test(test-alltoall 2 nccl/test_alltoall.cpp)
236-
add_nccl_test(test-allreduce 2 nccl/test_allreduce.cpp)
237-
add_nccl_test(test-reduce 2 nccl/test_reduce.cpp)
152+
kc_add_unit_test(smoke.nccl.1pe-multi_gpu NCCL NUM_PES 1 FILES nccl/test_nccl.cpp)
153+
154+
kc_add_unit_test(
155+
test.nccl.p2p
156+
NCCL
157+
NUM_PES 2
158+
FILES test_main.cpp nccl/test_point_to_point.cpp
159+
LIBRARIES KokkosComm::KokkosComm MPI::MPI_CXX
160+
)
161+
kc_add_unit_test(
162+
test.nccl.broadcast
163+
NCCL
164+
NUM_PES 2
165+
FILES test_main.cpp nccl/test_broadcast.cpp
166+
LIBRARIES KokkosComm::KokkosComm MPI::MPI_CXX
167+
)
168+
kc_add_unit_test(
169+
test.nccl.allgather
170+
NCCL
171+
NUM_PES 2
172+
FILES test_main.cpp nccl/test_allgather.cpp
173+
LIBRARIES KokkosComm::KokkosComm MPI::MPI_CXX
174+
)
175+
kc_add_unit_test(
176+
test.nccl.alltoall
177+
NCCL
178+
NUM_PES 2
179+
FILES test_main.cpp nccl/test_alltoall.cpp
180+
LIBRARIES KokkosComm::KokkosComm MPI::MPI_CXX
181+
)
182+
kc_add_unit_test(
183+
test.nccl.allreduce
184+
NCCL
185+
NUM_PES 2
186+
FILES test_main.cpp nccl/test_allreduce.cpp
187+
LIBRARIES KokkosComm::KokkosComm MPI::MPI_CXX
188+
)
189+
kc_add_unit_test(
190+
test.nccl.reduce
191+
NCCL
192+
NUM_PES 2
193+
FILES test_main.cpp nccl/test_reduce.cpp
194+
LIBRARIES KokkosComm::KokkosComm MPI::MPI_CXX
195+
)
238196
endif()

0 commit comments

Comments
 (0)