Skip to content

Commit 71183df

Browse files
rootlipracer
authored andcommitted
refine && add load test
1 parent 6ec9de2 commit 71183df

5 files changed

Lines changed: 82 additions & 51 deletions

File tree

plugins/klx_backend/CMakeLists.txt

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,6 @@ set(PY_EXT_SUFFIX ".so")
3232
set(PYTHON_EXTENSION_NAME
3333
"${MODULE_NAME}.${PY_SOABI}${PY_EXT_SUFFIX}"
3434
)
35-
# add_library(fserver SHARED IMPORTED)
36-
# set_target_properties(fserver PROPERTIES
37-
# IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/../../${PYTHON_EXTENSION_NAME}
38-
# )
3935

4036
find_package(CUDAToolkit REQUIRED)
4137
target_link_libraries(klx_backend
@@ -45,16 +41,15 @@ target_link_libraries(klx_backend
4541
${TORCH_PYTHON_LIBRARY}
4642
)
4743

48-
target_link_options(klx_backend PRIVATE
49-
-Wl,-rpath,${CMAKE_CURRENT_SOURCE_DIR}/../../${PYTHON_EXTENSION_NAME}
50-
)
51-
5244
install(TARGETS klx_backend
5345
LIBRARY DESTINATION lib
5446
)
5547

56-
#set_target_properties(klx_backend PROPERTIES
57-
# BUILD_RPATH "${CMAKE_BINARY_DIR}/../"
58-
# INSTALL_RPATH "\$ORIGIN"
59-
# BUILD_WITH_INSTALL_RPATH TRUE
60-
#)
48+
# Note: If you are building your own Python package,
49+
# please update this path to point to your own relative directory.
50+
set_target_properties(klx_backend PROPERTIES
51+
BUILD_RPATH "${CMAKE_BINARY_DIR}/../"
52+
INSTALL_RPATH "\$ORIGIN"
53+
BUILD_WITH_INSTALL_RPATH TRUE
54+
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../.."
55+
)

plugins/klx_backend/klx_backend.cc

Lines changed: 22 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,11 @@
66
#include <ATen/cuda/CUDAEvent.h>
77
#include <sys/mman.h>
88

9-
#include <unordered_map>
9+
#include <mutex>
1010

1111
#include "dmlc/backend_registry.h"
1212
#include "ps/backend.h"
13+
#include "ps/hash_table8.hpp"
1314
#include "ps/internal/gpu_backend.h"
1415

1516
#define KLX_RT_CALL(func, ...) \
@@ -19,9 +20,6 @@
1920
<< #func << " failed err:" << cudaGetErrorString(klx_errno); \
2021
} while (0)
2122

22-
#define USE_MMAP_ALLOC
23-
#undef USE_MMAP_ALLOC
24-
2523
namespace klx {
2624

2725
using namespace ps;
@@ -61,7 +59,7 @@ class KlxBackend : public Backend {
6159
static thread_local int gpu_idx = -1;
6260
if (gpu_idx == -1) {
6361
PS_CHECK_GE(gpu_idx_, 0)
64-
<< "cannot set device " << gpu_idx_ << " for gpu backend";
62+
<< "cannot set device " << gpu_idx_ << " for klx backend";
6563
SetDevice(gpu_idx_);
6664
gpu_idx = gpu_idx_;
6765
}
@@ -71,7 +69,8 @@ class KlxBackend : public Backend {
7169
int gpu_idx_ = -1;
7270
int mem_sync_ = 1;
7371
// host address to device address map
74-
std::unordered_map<void*, void*> ha_da_map_;
72+
std::mutex mtx_;
73+
emhash8::HashMap<void*, void*> ha_da_map_;
7574
};
7675

7776
KlxBackend::KlxBackend() {
@@ -80,8 +79,10 @@ KlxBackend::KlxBackend() {
8079
}
8180

8281
int KlxBackend::SetDevice(int dev) {
83-
PS_CHECK_GE(dev, 0) << "cannot set dev=" << dev << " for gpu backend";
84-
PS_CHECK_LE(dev, 7) << "cannot set dev=" << dev << " for gpu backend";
82+
static thread_local int max_num_dev = GetEnv("MAX_NUM_DEVICES_PER_NODE", 7);
83+
PS_CHECK_GE(dev, 0) << "cannot set dev=" << dev << " for klx backend";
84+
PS_CHECK_LE(dev, max_num_dev)
85+
<< "cannot set dev=" << dev << " for klx backend";
8586
static thread_local int gpu_idx = -1;
8687

8788
gpu_idx_ = dev;
@@ -102,7 +103,7 @@ int KlxBackend::GetDeviceId() {
102103
}
103104

104105
at::Device KlxBackend::GetDevice() {
105-
PS_CHECK_GE(gpu_idx_, 0) << "device index is not initialized for gpu backend";
106+
PS_CHECK_GE(gpu_idx_, 0) << "device index is not initialized for klx backend";
106107
return {at::kCUDA, static_cast<char>(gpu_idx_)};
107108
}
108109

@@ -115,43 +116,29 @@ void* KlxBackend::Alloc(uint64_t size) {
115116
}
116117

117118
void KlxBackend::Free(void* m) {
118-
#ifdef USE_MMAP_ALLOC
119-
if (ha_da_map_.find(m) != ha_da_map_.end()) {
120-
m = ha_da_map_[m];
121-
free(m);
122-
}
123-
#endif
124119
PS_CHECK_NE(m, nullptr) << "backend cannot free null memory";
125-
PS_VLOG(3) << "free gpu memory " << m;
126-
if (ha_da_map_.erase(m)) {
127-
m = ha_da_map_[m];
120+
PS_VLOG(3) << "free klx memory " << m;
121+
{
122+
std::lock_guard<std::mutex> lg(mtx_);
123+
if (ha_da_map_.erase(m)) {
124+
m = ha_da_map_[m];
125+
}
128126
}
129127
KLX_RT_CALL(cudaFree, m);
130128
}
131129

132130
void* KlxBackend::GetAccessibleAddr(void* devicePtr, size_t size) {
133-
#ifdef USE_MMAP_ALLOC
134-
void* buf = mmap(nullptr, size, PROT_READ | PROT_WRITE,
135-
MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
136-
cudaMemcpy(buf, devicePtr, size, cudaMemcpyDeviceToHost);
137-
ha_da_map_.emplace(buf, devicePtr);
138-
return buf;
139-
#endif
140-
141131
struct cudaPointerAttributes attrs;
142132
KLX_RT_CALL(cudaPointerGetAttributes, &attrs, devicePtr);
143133
PS_LOG(INFO) << "GetAccessibleAddr devicePtr=" << devicePtr
144134
<< " hostPtr=" << attrs.hostPointer;
145-
// size_t pagesz = sysconf(_SC_PAGESIZE);
146-
// PS_CHECK_EQ(((uintptr_t)attrs.hostPointer % pagesz), 0) << "unaligned host
147-
// ptr";
148-
135+
std::lock_guard<std::mutex> lg(mtx_);
149136
if (ha_da_map_.find(attrs.hostPointer) != ha_da_map_.end()) {
150137
return reinterpret_cast<char*>(attrs.hostPointer) +
151138
(reinterpret_cast<intptr_t>(devicePtr) -
152139
reinterpret_cast<intptr_t>(ha_da_map_[attrs.hostPointer]));
153140
}
154-
ha_da_map_.emplace(attrs.hostPointer, devicePtr);
141+
ha_da_map_.emplace_unique(attrs.hostPointer, devicePtr);
155142

156143
return attrs.hostPointer;
157144
}
@@ -166,11 +153,8 @@ void* KlxBackend::GetAccessibleAddr(const at::Tensor& tensor) {
166153
}
167154

168155
void* KlxBackend::GetDeviceAddrFromHostPtr(void* hostPtr, size_t size) {
156+
std::lock_guard<std::mutex> lg(mtx_);
169157
PS_CHECK_NE(ha_da_map_.find(hostPtr), ha_da_map_.end());
170-
#ifdef USE_MMAP_ALLOC
171-
KLX_RT_CALL(cudaMemcpy, ha_da_map_[hostPtr], hostPtr, size,
172-
cudaMemcpyHostToDevice);
173-
#endif
174158
return ha_da_map_[hostPtr];
175159
}
176160

@@ -218,7 +202,7 @@ void* KlxBackend::CreateCudaEvent() {
218202
cudaMallocHost(&ev, sizeof(cudaEvent_t));
219203
auto status = cudaEventCreateWithFlags(ev, cudaEventDisableTiming);
220204
PS_CHECK_EQ(status, cudaSuccess)
221-
<< "cudaEventCreateWithFlags failed for gpu " << gpu_idx_;
205+
<< "cudaEventCreateWithFlags failed for klx " << gpu_idx_;
222206
return reinterpret_cast<void*>(ev);
223207
}
224208

@@ -245,7 +229,7 @@ int KlxBackend::RecordCudaEvent(void* event, void* stream) {
245229
if (status == cudaSuccess) {
246230
return BACKEND_OK;
247231
} else {
248-
PS_LOG(WARNING) << "failed to record cuda event: "
232+
PS_LOG(WARNING) << "failed to record klx event: "
249233
<< " (" << cudaGetErrorString(status) << ")";
250234
return BACKEND_FAILED;
251235
}
@@ -263,7 +247,7 @@ int KlxBackend::SyncCudaEvent(void* event) {
263247
break;
264248
}
265249
if (status != cudaSuccess) {
266-
PS_LOG(WARNING) << "failed to sync cuda event: "
250+
PS_LOG(WARNING) << "failed to sync klx event: "
267251
<< " (" << cudaGetErrorString(status) << ")";
268252
return BACKEND_FAILED;
269253
}

setup.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,8 @@ def filte_cuda_arch_and_code(cuda_dir, arch_list, code_list):
9797
author='StepFun',
9898
version=get_version(),
9999
packages=['fserver'],
100+
package_data={'fserver': [os.path.join(__PS_PATH__, 'libklx_backend.so')]},
101+
include_package_data=True,
100102
url='',
101103
ext_modules=[
102104
CUDAExtension(

tests/fserver/run_load_plugin.sh

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
THIS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )"
2+
function cleanup() {
3+
echo "kill all testing process of ps lite for user $USER"
4+
# pkill -9 -f test_bench
5+
pkill -9 -f test_load_plugin
6+
sleep 1
7+
}
8+
trap cleanup EXIT
9+
# cleanup
10+
11+
# common setup
12+
export BIN=${BIN:-test_load_plugin}
13+
# export DMLC_INTERFACE=${RNIC:-brainpf_bond0}
14+
export SCHEDULER_IP=$(ip -o -4 addr | grep ${RNIC} | awk '{print $4}' | cut -d'/' -f1)
15+
export DMLC_NUM_WORKER=1
16+
export DMLC_NUM_SERVER=1
17+
export DMLC_PS_ROOT_URI=$SCHEDULER_IP # scheduler's RDMA interface IP
18+
export DMLC_PS_ROOT_PORT=8123 # scheduler's port (can random choose)
19+
export DMLC_ENABLE_RDMA=ibverbs
20+
export DMLC_INTERFACE=auto
21+
# export STEPMESH_BIND_CPU_CORE=1
22+
23+
export DMLC_NODE_HOST=${SCHEDULER_IP}
24+
export DMLC_INTERFACE=auto
25+
export STEPMESH_SPLIT_QP_LAG=0
26+
export STEPMESH_BIND_CPU_CORE=1
27+
export STEPMESH_GPU=0
28+
export PS_VERBOSE=1
29+
30+
DMLC_ROLE=scheduler numactl -m 0 python3 $THIS_DIR/$BIN.py &
31+
export STEPMESH_CPU_START_OFFSET=10
32+
DMLC_ROLE=server numactl -m 0 python3 $THIS_DIR/$BIN.py $@ &
33+
# DMLC_ROLE=worker python3 $THIS_DIR/$BIN.py $@ &
34+
# export STEPMESH_DROP_RATE=1
35+
export STEPMESH_CPU_START_OFFSET=15
36+
DMLC_ROLE=worker numactl -m 0 python3 $THIS_DIR/$BIN.py $@
37+
38+
wait

tests/fserver/test_load_plugin.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import torch, os, sys
2+
import time
3+
4+
old_flags = sys.getdlopenflags()
5+
sys.setdlopenflags(sys.getdlopenflags() | 0x100)
6+
import fserver_lib as f
7+
sys.setdlopenflags(old_flags)
8+
9+
is_worker = os.environ.get('DMLC_ROLE') == 'worker'
10+
is_server = os.environ.get('DMLC_ROLE') == 'server'
11+
12+
f.init("libklx_backend.so")

0 commit comments

Comments
 (0)