Skip to content

Commit 248e595

Browse files
committed
Add UCX Plugin Gtests
Add a plugin gtest infrastructure to test baackend plugin local xfer, remote xfer, progress and notification handling. Add ucx plugin gtests on top of the plugin infrastructure.
1 parent ad31f86 commit 248e595

File tree

7 files changed

+936
-1
lines changed

7 files changed

+936
-1
lines changed

meson.build

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,8 @@ if get_option('buildtype') == 'debug'
123123
run_command('truncate', '-s 0', plugfile, check: true)
124124
endif
125125

126-
nixl_inc_dirs = include_directories('src/api/cpp', 'src/infra', 'src/core')
126+
nixl_inc_dirs = include_directories('src/api/cpp', 'src/api/cpp/backend', 'src/infra', 'src/core')
127+
ucx_inc_dirs = include_directories('src/plugins/ucx')
127128
utils_inc_dirs = include_directories('src/utils')
128129

129130
subdir('src')

test/gtest/meson.build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ if not gtest_dep.found()
2323
endif
2424

2525
subdir('mocks')
26+
subdir('plugins')
2627

2728
plugin_dirs_arg = '--tests_plugin_dirs=' + mocks_dep.get_variable('path')
2829

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
/*
2+
* SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
3+
* SPDX-License-Identifier: Apache-2.0
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
#ifndef __MEMORY_HANDLER_H
18+
#define __MEMORY_HANDLER_H
19+
20+
template<nixl_mem_t MemType> struct MemoryHandler {
21+
static void *
22+
allocate(size_t len, int devId = 0) {
23+
std::cerr << "Unsupported memory type!" << std::endl;
24+
assert(0);
25+
}
26+
27+
static void
28+
deallocate(void *addr, int devId = 0) {
29+
std::cerr << "Unsupported memory type!" << std::endl;
30+
assert(0);
31+
}
32+
33+
static void
34+
set(void *addr, char byte, size_t size, int devId = 0) {
35+
std::cerr << "Unsupported memory type!" << std::endl;
36+
assert(0);
37+
}
38+
39+
static void *
40+
getPtr(void *addr, size_t len) {
41+
std::cerr << "Unsupported memory type!" << std::endl;
42+
assert(0);
43+
}
44+
45+
static void
46+
releasePtr(void *addr) {
47+
std::cerr << "Unsupported memory type!" << std::endl;
48+
assert(0);
49+
}
50+
};
51+
52+
template<> struct MemoryHandler<DRAM_SEG> {
53+
static void *
54+
allocate(size_t len, int devId = 0) {
55+
return new char[len];
56+
}
57+
58+
static void
59+
deallocate(void *addr, int devId = 0) {
60+
delete[] static_cast<char *>(addr);
61+
}
62+
63+
static void
64+
set(void *addr, char byte, size_t size, int devId = 0) {
65+
memset(addr, byte, size);
66+
}
67+
68+
static void *
69+
getPtr(void *addr, size_t len) {
70+
return addr;
71+
}
72+
73+
static void
74+
releasePtr(void *addr) {
75+
// No-op for host memory
76+
}
77+
};
78+
79+
#ifdef HAVE_CUDA
80+
template<> struct MemoryHandler<VRAM_SEG> {
81+
static void *
82+
allocate(size_t len, int devId = 0) {
83+
CUcontext ctx;
84+
CUdevice dev;
85+
bool is_dev;
86+
void *ptr;
87+
checkCudaError(cudaSetDevice(devId), "Failed to set device");
88+
checkCudaError(cudaMalloc(&ptr, len), "Failed to allocate CUDA buffer");
89+
if (cudaQueryAddr(ptr, is_dev, dev, ctx)) {
90+
std::cerr << "Failed to query CUDA addr: " << std::hex << ptr << " dev=" << std::dec
91+
<< dev << " ctx=" << std::hex << ctx << std::dec << std::endl;
92+
assert(0);
93+
}
94+
95+
return ptr;
96+
}
97+
98+
static void
99+
deallocate(void *addr, int devId = 0) {
100+
checkCudaError(cudaSetDevice(devId), "Failed to set device");
101+
checkCudaError(cudaFree(addr), "Failed to free CUDA buffer");
102+
}
103+
104+
static void
105+
set(void *addr, char byte, size_t size, int devId = 0) {
106+
checkCudaError(cudaSetDevice(devId), "Failed to set device");
107+
checkCudaError(cudaMemset(addr, byte, size), "Failed to memset");
108+
}
109+
110+
static void *
111+
getPtr(void *addr, size_t len) {
112+
void *ptr = new char[len];
113+
checkCudaError(cudaMemcpy(ptr, addr, len, cudaMemcpyDeviceToHost), "Failed to memcpy");
114+
return ptr;
115+
}
116+
117+
static void
118+
releasePtr(void *addr) {
119+
delete[] static_cast<char *>(addr);
120+
}
121+
};
122+
#endif // HAVE_CUDA
123+
#endif // __MEMORY_HANDLER_H

test/gtest/plugins/meson.build

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# SPDX-FileCopyrightText: Copyright (c) 2025 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
2+
# SPDX-License-Identifier: Apache-2.0
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
gtest_dep = dependency('gtest', version : '>=1.11.0', required : false)
17+
absl_strings_dep = abseil_proj.get_variable('absl_strings_dep')
18+
absl_time_dep = abseil_proj.get_variable('absl_time_dep')
19+
20+
if not gtest_dep.found()
21+
message('GTest not found, skipping gtest build')
22+
subdir_done()
23+
endif
24+
25+
if cuda_dep.found()
26+
cuda_dependencies = [cuda_dep]
27+
else
28+
cuda_dependencies = []
29+
endif
30+
31+
cpp_flags = []
32+
33+
if get_option('test_all_plugins')
34+
cpp_flags+='-DTEST_ALL_PLUGINS'
35+
endif
36+
37+
# for loading plugins from build directory
38+
cpp_flags += '-DBUILD_DIR="' + meson.project_build_root() + '"'
39+
40+
plugins_test_exe = executable('ucx_plugins_gtest',
41+
sources : ['../main.cpp', 'ucx_plugin.cpp', 'plugin_test.cpp'],
42+
include_directories: [nixl_inc_dirs, utils_inc_dirs, ucx_inc_dirs, '.'],
43+
cpp_args : cpp_flags,
44+
dependencies : [nixl_dep, cuda_dep, gtest_dep, absl_strings_dep, absl_time_dep, ucx_backend_interface, ucx_dep],
45+
link_with: [nixl_build_lib, ucx_backend_lib],
46+
install : true
47+
)
48+
49+
test('plugins_gtest', plugins_test_exe)
50+
51+
if get_option('b_sanitize').split(',').contains('thread')
52+
test_env = environment()
53+
test_env.set('TSAN_OPTIONS', 'halt_on_error=1')
54+
test_env.set('NIXL_PLUGIN_DIR', mocks_dep.get_variable('path'))
55+
56+
mt_test_exe = executable('mt_test',
57+
sources : ['main.cpp', 'multi_threading.cpp'],
58+
include_directories: [nixl_inc_dirs, utils_inc_dirs],
59+
cpp_args : cpp_flags,
60+
dependencies : [nixl_dep, nixl_infra, cuda_dep, gtest_dep],
61+
link_with: [nixl_build_lib],
62+
)
63+
64+
test('mt_test', mt_test_exe, is_parallel: false, env: test_env)
65+
endif

0 commit comments

Comments
 (0)