Skip to content

Commit

Permalink
Revert "Refactor LibraryInitializer so it's thread safe. Fixes random…
Browse files Browse the repository at this point in the history
… sporadical concurrency crashes. (apache#15762)"

This reverts commit bfd3bb8.
  • Loading branch information
larroy committed Dec 5, 2019
1 parent fc565d8 commit 232905b
Show file tree
Hide file tree
Showing 9 changed files with 247 additions and 345 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ mxnet_option(USE_CUDA "Build with CUDA support" ON)
mxnet_option(USE_OLDCMAKECUDA "Build with old cmake cuda" OFF)
mxnet_option(USE_NCCL "Use NVidia NCCL with CUDA" OFF)
mxnet_option(USE_OPENCV "Build with OpenCV support" ON)
mxnet_option(USE_OPENMP "Build with Openmp support" ON) # OFF | ON | PLATFORM | BUNDLED
mxnet_option(USE_OPENMP "Build with Openmp support" PLATFORM) # OFF | ON | PLATFORM | BUNDLED
mxnet_option(USE_CUDNN "Build with cudnn support" ON) # one could set CUDNN_ROOT for search path
mxnet_option(USE_SSE "Build with x86 SSE instruction support" ON IF NOT ARM)
mxnet_option(USE_F16C "Build with x86 F16C instruction support" ON) # autodetects support if ON
Expand Down
4 changes: 2 additions & 2 deletions src/c_api/c_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -46,12 +46,12 @@
#include "mxnet/libinfo.h"
#include "mxnet/imperative.h"
#include "mxnet/lib_api.h"
#include "../initialize.h"
#include "./c_api_common.h"
#include "../operator/custom/custom-inl.h"
#include "../operator/tensor/matrix_op-inl.h"
#include "../operator/tvmop/op_module.h"
#include "../common/utils.h"
#include "../common/library.h"

using namespace mxnet;

Expand Down Expand Up @@ -95,7 +95,7 @@ inline int MXAPIGetFunctionRegInfo(const FunRegType *e,
// Loads library and initializes it
int MXLoadLib(const char *path) {
API_BEGIN();
void *lib = LibraryInitializer::Get()->lib_load(path);
void *lib = load_lib(path);
if (!lib)
LOG(FATAL) << "Unable to load library";

Expand Down
125 changes: 125 additions & 0 deletions src/common/library.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/*!
* Copyright (c) 2015 by Contributors
* \file library.cc
* \brief Dynamically loading accelerator library
* and accessing its functions
*/

#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
#include <windows.h>
#else
#include <dlfcn.h>
#endif

#include <string>
#include "library.h"

#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
/*!
* \brief Retrieve the system error message for the last-error code
* \param err string that gets the error message
*/
void win_err(char **err) {
uint32_t dw = GetLastError();
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_IGNORE_INSERTS,
NULL,
dw,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
reinterpret_cast<char*>(err),
0, NULL);
}
#endif


/*!
* \brief Loads the dynamic shared library file
* \param path library file location
* \return handle a pointer for the loaded library, nullptr if loading unsuccessful
*/
void* load_lib(const char* path) {
void *handle = nullptr;
std::string path_str(path);
// check if library was already loaded
if (loaded_libs.find(path_str) == loaded_libs.end()) {
// if not, load it
#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
handle = LoadLibrary(path);
if (!handle) {
char *err_msg = nullptr;
win_err(&err_msg);
LOG(FATAL) << "Error loading library: '" << path << "'\n" << err_msg;
LocalFree(err_msg);
return nullptr;
}
#else
handle = dlopen(path, RTLD_LAZY);
if (!handle) {
LOG(FATAL) << "Error loading library: '" << path << "'\n" << dlerror();
return nullptr;
}
#endif // _WIN32 or _WIN64 or __WINDOWS__
// then store the pointer to the library
loaded_libs[path_str] = handle;
} else {
// otherwise just look up the pointer
handle = loaded_libs[path_str];
}
return handle;
}

/*!
* \brief Closes the loaded dynamic shared library file
* \param handle library file handle
*/
void close_lib(void* handle) {
#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
FreeLibrary((HMODULE)handle);
#else
dlclose(handle);
#endif // _WIN32 or _WIN64 or __WINDOWS__
}

/*!
* \brief Obtains address of given function in the loaded library
* \param handle pointer for the loaded library
* \param func function pointer that gets output address
* \param name function name to be fetched
*/
void get_sym(void* handle, void** func, char* name) {
#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
*func = GetProcAddress((HMODULE)handle, name);
if (!(*func)) {
char *err_msg = nullptr;
win_err(&err_msg);
LOG(FATAL) << "Error getting function '" << name << "' from library\n" << err_msg;
LocalFree(err_msg);
}
#else
*func = dlsym(handle, name);
if (!(*func)) {
LOG(FATAL) << "Error getting function '" << name << "' from library\n" << dlerror();
}
#endif // _WIN32 or _WIN64 or __WINDOWS__
}
57 changes: 57 additions & 0 deletions src/common/library.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

/*!
* Copyright (c) 2015 by Contributors
* \file library.h
* \brief Defining library loading functions
*/
#ifndef MXNET_COMMON_LIBRARY_H_
#define MXNET_COMMON_LIBRARY_H_

#include <iostream>
#include <map>
#include <string>
#include "dmlc/io.h"

// map of libraries loaded
static std::map<std::string, void*> loaded_libs;

void* load_lib(const char* path);
void close_lib(void* handle);
void get_sym(void* handle, void** func, char* name);

/*!
* \brief a templated function that fetches from the library
* a function pointer of any given datatype and name
* \param T a template parameter for data type of function pointer
* \param lib library handle
* \param func_name function name to search for in the library
* \return func a function pointer
*/
template<typename T>
T get_func(void *lib, char *func_name) {
T func;
get_sym(lib, reinterpret_cast<void**>(&func), func_name);
if (!func)
LOG(FATAL) << "Unable to get function '" << func_name << "' from library";
return func;
}

#endif // MXNET_COMMON_LIBRARY_H_
12 changes: 0 additions & 12 deletions src/common/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,9 @@
#include "../operator/nn/mkldnn/mkldnn_base-inl.h"
#endif

#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
#include <windows.h>
#else
#include <unistd.h>
#endif


namespace mxnet {
namespace common {

#if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__)
inline size_t current_process_id() { return ::GetCurrentProcessId(); }
#else
inline size_t current_process_id() { return getpid(); }
#endif
/*!
* \brief IndPtr should be non-negative, in non-decreasing order, start with 0
* and end with value equal with size of indices.
Expand Down
4 changes: 1 addition & 3 deletions src/engine/threaded_engine_perdevice.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#include <dmlc/parameter.h>
#include <dmlc/concurrency.h>
#include <dmlc/thread_group.h>
#include "../initialize.h"
#include "./threaded_engine.h"
#include "./thread_pool.h"
#include "../common/lazy_alloc_array.h"
Expand Down Expand Up @@ -77,8 +76,7 @@ class ThreadedEnginePerDevice : public ThreadedEngine {
void Start() override {
if (is_worker_) return;
gpu_worker_nthreads_ = common::GetNumThreadsPerGPU();
// MXNET_CPU_WORKER_NTHREADS
cpu_worker_nthreads_ = LibraryInitializer::Get()->cpu_worker_nthreads_;
cpu_worker_nthreads_ = dmlc::GetEnv("MXNET_CPU_WORKER_NTHREADS", 1);
gpu_copy_nthreads_ = dmlc::GetEnv("MXNET_GPU_COPY_NTHREADS", 2);
// create CPU task
int cpu_priority_nthreads = dmlc::GetEnv("MXNET_CPU_PRIORITY_NTHREADS", 4);
Expand Down
Loading

0 comments on commit 232905b

Please sign in to comment.