Skip to content

Commit 8fef443

Browse files
committed
fix dynamic_loader more safe and error message on windows
1 parent b6eff44 commit 8fef443

File tree

5 files changed

+96
-45
lines changed

5 files changed

+96
-45
lines changed

CMakeLists.txt

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -193,10 +193,19 @@ if(WITH_BRPC_RDMA)
193193
endif()
194194
endif()
195195

196-
# lite subgraph compilation depends on CUDNN_ROOT,
197-
# so include(cudnn) needs to be in front of include(third_party/lite)
198-
include(cudnn) # set cudnn libraries, must before configure
199-
include(third_party) # download, build, install third_party
196+
if(WITH_GPU)
197+
include(cuda)
198+
# lite subgraph compilation depends on CUDNN_ROOT,
199+
# so include(cudnn) needs to be in front of include(third_party/lite)
200+
include(cudnn) # set cudnn libraries, must before configure
201+
include(tensorrt)
202+
# there is no official support of nccl, cupti in windows
203+
if(NOT WIN32)
204+
include(cupti)
205+
endif()
206+
endif()
207+
208+
include(third_party) # download, build, install third_party, Contains about 20+ dependencies
200209

201210
if(WITH_DISTRIBUTE)
202211
if(WITH_GRPC)
@@ -209,18 +218,8 @@ if(WITH_DISTRIBUTE)
209218
endif()
210219
endif()
211220

212-
# there is no official support of nccl, cupti in windows
213-
if(NOT WIN32)
214-
include(cupti)
215-
endif()
216-
217221
include(flags) # set paddle compile flags
218222

219-
if(WITH_GPU)
220-
include(cuda)
221-
include(tensorrt)
222-
endif()
223-
224223
if(WITH_PROFILER)
225224
find_package(Gperftools REQUIRED)
226225
include_directories(${GPERFTOOLS_INCLUDE_DIR})

cmake/cuda.cmake

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,9 @@ elseif (${CMAKE_CUDA_COMPILER_VERSION} LESS 12.0) # CUDA 11.x
198198
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -D__STRICT_ANSI__")
199199
endif()
200200

201-
add_definitions("-DPADDLE_CUDA_BINVER=\"${CUDA_VERSION_MAJOR}${CUDA_VERSION_MINOR}\"")
201+
add_definitions("-DCUDA_VERSION_MAJOR=\"${CUDA_VERSION_MAJOR}\"")
202+
add_definitions("-DCUDA_VERSION_MINOR=\"${CUDA_VERSION_MINOR}\"")
203+
add_definitions("-DCUDA_TOOLKIT_ROOT_DIR=\"${CUDA_TOOLKIT_ROOT_DIR}\"")
202204

203205
# setting nvcc arch flags
204206
select_nvcc_arch_flags(NVCC_FLAGS_EXTRA)
@@ -249,3 +251,4 @@ endif()
249251

250252
mark_as_advanced(CUDA_BUILD_CUBIN CUDA_BUILD_EMULATION CUDA_VERBOSE_BUILD)
251253
mark_as_advanced(CUDA_SDK_ROOT_DIR CUDA_SEPARABLE_COMPILATION)
254+

cmake/cudnn.cmake

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,17 +35,18 @@ list(APPEND CUDNN_CHECK_LIBRARY_DIRS
3535
${CUDA_TOOLKIT_ROOT_DIR}/lib/x64
3636
)
3737
set(CUDNN_LIB_NAME "")
38+
3839
if (LINUX)
39-
set(CUDNN_LIB_NAME "libcudnn.so")
40+
set(CUDNN_LIB_NAME "libcudnn.so")
4041
endif(LINUX)
4142

4243
if(WIN32)
43-
# only support cudnn7
44-
set(CUDNN_LIB_NAME "cudnn.lib" "cudnn64_7.dll")
44+
# only support cudnn7
45+
set(CUDNN_LIB_NAME "cudnn.lib" "cudnn64_7.dll")
4546
endif(WIN32)
4647

4748
if(APPLE)
48-
set(CUDNN_LIB_NAME "libcudnn.dylib" "libcudnn.so")
49+
set(CUDNN_LIB_NAME "libcudnn.dylib" "libcudnn.so")
4950
endif(APPLE)
5051

5152
find_library(CUDNN_LIBRARY NAMES ${CUDNN_LIB_NAME} # libcudnn_static.a
@@ -88,7 +89,7 @@ macro(find_cudnn_version cudnn_header_file)
8889
if(NOT CUDNN_MAJOR_VERSION)
8990
set(CUDNN_VERSION "???")
9091
else()
91-
add_definitions("-DPADDLE_CUDNN_BINVER=\"${CUDNN_MAJOR_VERSION}\"")
92+
add_definitions("-DCUDNN_MAJOR_VERSION=\"${CUDNN_MAJOR_VERSION}\"")
9293
math(EXPR CUDNN_VERSION
9394
"${CUDNN_MAJOR_VERSION} * 1000 +
9495
${CUDNN_MINOR_VERSION} * 100 + ${CUDNN_PATCHLEVEL_VERSION}")

paddle/fluid/platform/dynload/dynamic_loader.cc

Lines changed: 68 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,26 @@ struct PathNode {
5757

5858
static constexpr char cupti_lib_path[] = CUPTI_LIB_PATH;
5959

60-
// NOTE: In order to adapt to the default installation path of cuda on linux
61-
static constexpr char linux_cudnn_lib_path[] = "/usr/local/cuda/lib64";
60+
// NOTE: In order to adapt to the default installation path of cuda
61+
#if defined(_WIN32) && defined(PADDLE_WITH_CUDA)
62+
static constexpr char cuda_lib_path[] = CUDA_TOOLKIT_ROOT_DIR "/bin";
63+
#else
64+
static constexpr char cuda_lib_path[] = "/usr/local/cuda/lib64";
65+
#endif
6266

6367
static PathNode s_py_site_pkg_path;
6468

6569
#if defined(_WIN32) && defined(PADDLE_WITH_CUDA)
66-
static constexpr char* win_cublas_lib = "cublas64_" PADDLE_CUDA_BINVER ".dll";
67-
static constexpr char* win_curand_lib = "curand64_" PADDLE_CUDA_BINVER ".dll";
68-
static constexpr char* win_cudnn_lib = "cudnn64_" PADDLE_CUDNN_BINVER ".dll";
70+
static constexpr char* win_cublas_lib =
71+
"cublas64_" CUDA_VERSION_MAJOR CUDA_VERSION_MINOR
72+
".dll;cublas64_" CUDA_VERSION_MAJOR ".dll";
73+
static constexpr char* win_curand_lib =
74+
"curand64_" CUDA_VERSION_MAJOR CUDA_VERSION_MINOR
75+
".dll;curand64_" CUDA_VERSION_MAJOR ".dll";
76+
static constexpr char* win_cudnn_lib = "cudnn64_" CUDNN_MAJOR_VERSION ".dll";
6977
static constexpr char* win_cusolver_lib =
70-
"cusolver64_" PADDLE_CUDA_BINVER ".dll";
78+
"cusolver64_" CUDA_VERSION_MAJOR CUDA_VERSION_MINOR
79+
".dll;cusolver64_" CUDA_VERSION_MAJOR ".dll";
7180
#endif
7281

7382
static inline std::string join(const std::string& part1,
@@ -87,6 +96,24 @@ static inline std::string join(const std::string& part1,
8796
return ret;
8897
}
8998

99+
static inline std::vector<std::string> split(
100+
const std::string& str, const std::string separator = " ") {
101+
std::vector<std::string> str_list;
102+
std::string::size_type firstPos;
103+
firstPos = str.find_first_not_of(separator, 0);
104+
std::string::size_type lastPos;
105+
lastPos = str.find_first_of(separator, firstPos);
106+
while (std::string::npos != firstPos && std::string::npos != lastPos) {
107+
str_list.push_back(str.substr(firstPos, lastPos - firstPos));
108+
firstPos = str.find_first_not_of(separator, lastPos);
109+
lastPos = str.find_first_of(separator, firstPos);
110+
}
111+
if (std::string::npos == lastPos) {
112+
str_list.push_back(str.substr(firstPos, lastPos - firstPos));
113+
}
114+
return str_list;
115+
}
116+
90117
void SetPaddleLibPath(const std::string& py_site_pkg_path) {
91118
s_py_site_pkg_path.path = py_site_pkg_path;
92119
VLOG(3) << "Set paddle lib path : " << py_site_pkg_path;
@@ -147,26 +174,31 @@ static inline void* GetDsoHandleFromSearchPath(
147174
#else
148175
int dynload_flags = 0;
149176
#endif // !_WIN32
150-
// 1. search in user config path by FLAGS
151-
void* dso_handle =
152-
GetDsoHandleFromSpecificPath(config_path, dso_name, dynload_flags);
153-
// 2. search in system default path
154-
if (nullptr == dso_handle) {
155-
dso_handle = GetDsoHandleFromDefaultPath(dso_name, dynload_flags);
156-
}
157-
// 3. search in extra paths
158-
if (nullptr == dso_handle) {
159-
for (auto path : extra_paths) {
160-
dso_handle = GetDsoHandleFromSpecificPath(path, dso_name, dynload_flags);
177+
std::vector<std::string> dso_names = split(dso_name, ";");
178+
void* dso_handle = nullptr;
179+
for (auto dso : dso_names) {
180+
// 1. search in user config path by FLAGS
181+
dso_handle = GetDsoHandleFromSpecificPath(config_path, dso, dynload_flags);
182+
// 2. search in extra paths
183+
if (nullptr == dso_handle) {
184+
for (auto path : extra_paths) {
185+
VLOG(3) << "extra_paths: " << path;
186+
dso_handle = GetDsoHandleFromSpecificPath(path, dso, dynload_flags);
187+
}
188+
}
189+
// 3. search in system default path
190+
if (nullptr == dso_handle) {
191+
dso_handle = GetDsoHandleFromDefaultPath(dso, dynload_flags);
161192
}
193+
if (nullptr != dso_handle) break;
162194
}
163195

164-
// 4. [If Failed] logging warning if exists
196+
// 4. [If Failed for All dso_names] logging warning if exists
165197
if (nullptr == dso_handle && !warning_msg.empty()) {
166198
LOG(WARNING) << warning_msg;
167199
}
168200

169-
// 5. [If Failed] logging or throw error info
201+
// 5. [If Failed for All dso_names] logging or throw error info
170202
if (nullptr == dso_handle) {
171203
auto error_msg =
172204
"The third-party dynamic library (%s) that Paddle depends on is not "
@@ -203,7 +235,8 @@ void* GetCublasDsoHandle() {
203235
#if defined(__APPLE__) || defined(__OSX__)
204236
return GetDsoHandleFromSearchPath(FLAGS_cuda_dir, "libcublas.dylib");
205237
#elif defined(_WIN32) && defined(PADDLE_WITH_CUDA)
206-
return GetDsoHandleFromSearchPath(FLAGS_cuda_dir, win_cublas_lib);
238+
return GetDsoHandleFromSearchPath(FLAGS_cuda_dir, win_cublas_lib, true,
239+
{cuda_lib_path});
207240
#else
208241
return GetDsoHandleFromSearchPath(FLAGS_cuda_dir, "libcublas.so");
209242
#endif
@@ -220,10 +253,19 @@ void* GetCUDNNDsoHandle() {
220253
return GetDsoHandleFromSearchPath(FLAGS_cudnn_dir, "libcudnn.dylib", false,
221254
{}, mac_warn_meg);
222255
#elif defined(_WIN32) && defined(PADDLE_WITH_CUDA)
223-
return GetDsoHandleFromSearchPath(FLAGS_cudnn_dir, win_cudnn_lib);
256+
std::string win_warn_meg(
257+
"Note: [Recommend] copy cudnn into CUDA installation directory. \n "
258+
"For instance, download cudnn-10.0-windows10-x64-v7.6.5.32.zip from "
259+
"NVIDIA's official website, \n"
260+
"then, unzip it and copy it into C:\\Program Files\\NVIDIA GPU Computing "
261+
"Toolkit\\CUDA/v10.0\n"
262+
"You should do this according to your CUDA installation directory and "
263+
"CUDNN version.");
264+
return GetDsoHandleFromSearchPath(FLAGS_cudnn_dir, win_cudnn_lib, true,
265+
{cuda_lib_path}, win_warn_meg);
224266
#else
225267
return GetDsoHandleFromSearchPath(FLAGS_cudnn_dir, "libcudnn.so", false,
226-
{linux_cudnn_lib_path});
268+
{cuda_lib_path});
227269
#endif
228270
}
229271

@@ -241,7 +283,8 @@ void* GetCurandDsoHandle() {
241283
#if defined(__APPLE__) || defined(__OSX__)
242284
return GetDsoHandleFromSearchPath(FLAGS_cuda_dir, "libcurand.dylib");
243285
#elif defined(_WIN32) && defined(PADDLE_WITH_CUDA)
244-
return GetDsoHandleFromSearchPath(FLAGS_cuda_dir, win_curand_lib);
286+
return GetDsoHandleFromSearchPath(FLAGS_cuda_dir, win_curand_lib, true,
287+
{cuda_lib_path});
245288
#else
246289
return GetDsoHandleFromSearchPath(FLAGS_cuda_dir, "libcurand.so");
247290
#endif
@@ -251,7 +294,8 @@ void* GetCusolverDsoHandle() {
251294
#if defined(__APPLE__) || defined(__OSX__)
252295
return GetDsoHandleFromSearchPath(FLAGS_cuda_dir, "libcusolver.dylib");
253296
#elif defined(_WIN32) && defined(PADDLE_WITH_CUDA)
254-
return GetDsoHandleFromSearchPath(FLAGS_cuda_dir, win_cusolver_lib);
297+
return GetDsoHandleFromSearchPath(FLAGS_cuda_dir, win_cusolver_lib, true,
298+
{cuda_lib_path});
255299
#else
256300
return GetDsoHandleFromSearchPath(FLAGS_cuda_dir, "libcusolver.so");
257301
#endif

paddle/fluid/platform/port.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,11 @@ static void *dlopen(const char *filename, int flag) {
5656
std::string file_name(filename);
5757
HMODULE hModule = LoadLibrary(file_name.c_str());
5858
if (!hModule) {
59-
throw std::runtime_error(file_name + " not found.");
59+
if (flag) {
60+
throw std::runtime_error(file_name + " not found.");
61+
} else {
62+
return nullptr;
63+
}
6064
}
6165
return reinterpret_cast<void *>(hModule);
6266
}

0 commit comments

Comments
 (0)