pytorch/caffe2/core/init.cc
Yangqing Jia 7d5f7ed270 Using c10 namespace across caffe2. (#12714)
Summary:
Pull Request resolved: https://github.com/pytorch/pytorch/pull/12714

This is a short change to enable c10 namespace in caffe2. We did not enable
it before due to gflags global variable confusion, but it should have been
mostly cleaned now. Right now, the plan on record is that namespace caffe2 and
namespace aten will fully be supersets of namespace c10.

Most of the diff is codemod, and only two places of non-codemod is in caffe2/core/common.h, where

```
using namespace c10;
```

is added, and in Flags.h, where instead of creating aliasing variables in c10 namespace, we directly put it in the global namespace to match gflags (and same behavior if gflags is not being built with).

Reviewed By: dzhulgakov

Differential Revision: D10390486

fbshipit-source-id: 5e2df730e28e29a052f513bddc558d9f78a23b9b
2018-10-17 12:57:19 -07:00

104 lines
3.6 KiB
C++

#include "caffe2/core/init.h"
#include "caffe2/core/operator.h" // for StaticLinkingProtector
#include "caffe2/core/scope_guard.h"
#include <iomanip>
#include <mutex>
C10_DEFINE_bool(
caffe2_version,
false,
"Print Caffe2 version and build options on startup");
namespace caffe2 {
namespace internal {
// Keep track of stages of initialization to differentiate between
// (a) Re-entrant calls to GlobalInit (e.g. caller registers a Caffe2 init
// function which might in turn indirectly invoke GlobalInit).
// (b) Successive calls to GlobalInit, which are handled as documented in
// init.h.
// Note that this is NOT attempting to address thread-safety, see comments
// in init.h.
enum class State {
Uninitialized,
Initializing,
Initialized,
};
Caffe2InitializeRegistry* Caffe2InitializeRegistry::Registry() {
static Caffe2InitializeRegistry gRegistry;
return &gRegistry;
}
State& GlobalInitState() {
static State state = State::Uninitialized;
return state;
}
} // namespace internal
bool GlobalInitAlreadyRun() {
return internal::GlobalInitState() == internal::State::Initialized;
}
bool GlobalInit(int* pargc, char*** pargv) {
static std::recursive_mutex init_mutex;
std::lock_guard<std::recursive_mutex> guard(init_mutex);
internal::State& init_state = internal::GlobalInitState();
static StaticLinkingProtector g_protector;
bool success = true;
// NOTE: if init_state == internal::State::Initializing at this point, do
// nothing because that indicates a re-entrant call
if (init_state == internal::State::Initialized) {
VLOG(1) << "GlobalInit has already been called: re-parsing gflags only.";
// Reparse command line flags
success &= c10::ParseCommandLineFlags(pargc, pargv);
UpdateLoggingLevelsFromFlags();
} else if (init_state == internal::State::Uninitialized) {
init_state = internal::State::Initializing;
auto init_state_guard = MakeGuard([&] {
// If an exception is thrown, go back to Uninitialized state
if (init_state == internal::State::Initializing) {
init_state = internal::State::Uninitialized;
}
});
success &= internal::Caffe2InitializeRegistry::Registry()
->RunRegisteredEarlyInitFunctions(pargc, pargv);
CAFFE_ENFORCE(
success, "Failed to run some early init functions for caffe2.");
success &= c10::ParseCommandLineFlags(pargc, pargv);
success &= InitCaffeLogging(pargc, *pargv);
// Print out the current build version. Using cerr as LOG(INFO) might be off
if (FLAGS_caffe2_version) {
std::cerr << "Caffe2 build configuration: " << std::endl;
for (const auto& it : GetBuildOptions()) {
std::cerr << " " << std::setw(25) << std::left << it.first << " : "
<< it.second << std::endl;
}
}
// All other initialization functions.
success &= internal::Caffe2InitializeRegistry::Registry()
->RunRegisteredInitFunctions(pargc, pargv);
init_state =
success ? internal::State::Initialized : internal::State::Uninitialized;
}
CAFFE_ENFORCE(success, "Failed to run some init functions for caffe2.");
// TODO: if we fail GlobalInit(), should we continue?
return success;
}
bool GlobalInit() {
// This is a version of the GlobalInit where no argument is passed in.
// On mobile devices, use this global init, since we cannot pass the
// command line options to caffe2, no arguments are passed.
int mobile_argc = 1;
static char caffe2_name[] = "caffe2";
char* mobile_name = &caffe2_name[0];
char** mobile_argv = &mobile_name;
return ::caffe2::GlobalInit(&mobile_argc, &mobile_argv);
}
} // namespace caffe2