Remove unnecessary once flag usage (#143255)

Static variables in C++11 is guaranteed to be initialised exactly once, as mentioned [here](https://en.cppreference.com/w/cpp/language/storage_duration)
```
If multiple threads attempt to initialize the same static local variable concurrently,
the initialization occurs exactly once
(similar behavior can be obtained for arbitrary functions with std::call_once.
Usual implementations of this feature use variants
of the double-checked locking pattern,
which reduces runtime overhead for already-initialized local statics
 to a single non-atomic boolean comparison.
```
Given that static c10::once_flag is used before, why not just use the associated function to initialised the related static variables? That is the motivation behind this PR.

Pull Request resolved: https://github.com/pytorch/pytorch/pull/143255
Approved by: https://github.com/albanD
This commit is contained in:
cyy 2025-01-16 02:36:09 +00:00 committed by PyTorch MergeBot
parent 41ec2e8d3e
commit 843627b7b1
12 changed files with 73 additions and 112 deletions

View File

@ -1,13 +1,11 @@
#include <c10/core/Allocator.h>
#include <c10/core/thread_pool.h>
#include <c10/util/CallOnce.h>
#include <c10/util/flat_hash_map.h>
#include <c10/util/llvmMathExtras.h>
#include <optional>
#include <deque>
#include <mutex>
#include <set>
C10_DIAGNOSTIC_PUSH_AND_IGNORED_IF_DEFINED("-Wunused-parameter")
namespace at {
@ -147,15 +145,15 @@ struct CachingHostAllocatorImpl {
}
// Launch the background thread and process events in a loop.
static c10::once_flag background_thread_flag;
c10::call_once(background_thread_flag, [this] {
static bool background_thread_flag [[maybe_unused]] = [this] {
getBackgroundThreadPool()->run([&]() {
while (true) {
process_events();
std::this_thread::sleep_for(std::chrono::microseconds(100));
}
});
});
return true;
}();
}
// Slow path: if we can't allocate from the cached free list, we need

View File

@ -1,7 +1,5 @@
#include <ATen/detail/CUDAHooksInterface.h>
#include <memory>
namespace at {
namespace detail {
@ -22,16 +20,15 @@ namespace detail {
// you're probably losing only a word (the vptr in the allocated object.)
const CUDAHooksInterface& getCUDAHooks() {
auto create_impl= [] {
auto create_impl = [] {
#if !defined C10_MOBILE
auto cuda_hooks =
CUDAHooksRegistry()->Create("CUDAHooks", CUDAHooksArgs{});
if (cuda_hooks) {
return cuda_hooks;
auto hooks = CUDAHooksRegistry()->Create("CUDAHooks", CUDAHooksArgs{});
if (hooks) {
return hooks;
}
#endif
return std::make_unique<CUDAHooksInterface>();
};
};
// NB: The static initialization here implies that if you try to call any CUDA
// functionality before libATen_cuda.so is loaded, CUDA is permanently
// disabled for that copy of ATen. In principle, we can relax this
@ -39,8 +36,8 @@ const CUDAHooksInterface& getCUDAHooks() {
// for an example where we relax this restriction (but if you try to avoid
// needing a lock, be careful; it doesn't look like Registry.h is thread
// safe...)
static auto cuda_hooks = create_impl();
return *cuda_hooks;
static auto hooks = create_impl();
return *hooks;
}
} // namespace detail

View File

@ -1,30 +1,21 @@
#include <ATen/detail/HIPHooksInterface.h>
#include <c10/util/CallOnce.h>
#include <c10/util/Registry.h>
#include <memory>
namespace at {
namespace detail {
// See getCUDAHooks for some more commentary
const HIPHooksInterface& getHIPHooks() {
static std::unique_ptr<HIPHooksInterface> hip_hooks;
auto create_impl = [] {
#if !defined C10_MOBILE
static c10::once_flag once;
c10::call_once(once, [] {
hip_hooks = HIPHooksRegistry()->Create("HIPHooks", HIPHooksArgs{});
if (!hip_hooks) {
hip_hooks = std::make_unique<HIPHooksInterface>();
auto hooks = HIPHooksRegistry()->Create("HIPHooks", HIPHooksArgs{});
if (hooks) {
return hooks;
}
});
#else
if (hip_hooks == nullptr) {
hip_hooks = std::make_unique<HIPHooksInterface>();
}
#endif
return *hip_hooks;
return std::make_unique<HIPHooksInterface>();
};
static auto hooks = create_impl();
return *hooks;
}
} // namespace detail

View File

@ -1,20 +1,18 @@
#include <ATen/detail/HPUHooksInterface.h>
#include <c10/util/CallOnce.h>
#include <memory>
namespace at {
namespace detail {
TORCH_API const at::HPUHooksInterface& getHPUHooks() {
static std::unique_ptr<HPUHooksInterface> hpu_hooks;
static c10::once_flag once;
c10::call_once(once, [] {
hpu_hooks = HPUHooksRegistry()->Create("HPUHooks", HPUHooksArgs{});
if (!hpu_hooks) {
hpu_hooks = std::make_unique<HPUHooksInterface>();
auto create_impl = [] {
auto hooks = HPUHooksRegistry()->Create("HPUHooks", HPUHooksArgs{});
if (hooks) {
return hooks;
}
});
return *hpu_hooks;
return std::make_unique<HPUHooksInterface>();
};
static auto hooks = create_impl();
return *hooks;
}
} // namespace detail

View File

@ -1,19 +1,17 @@
#include <ATen/detail/IPUHooksInterface.h>
#include <c10/util/CallOnce.h>
namespace at {
namespace detail {
const IPUHooksInterface& getIPUHooks() {
static std::unique_ptr<IPUHooksInterface> hooks;
static c10::once_flag once;
c10::call_once(once, [] {
hooks = IPUHooksRegistry()->Create("IPUHooks", IPUHooksArgs{});
if (!hooks) {
hooks = std::make_unique<IPUHooksInterface>();
auto create_impl = [] {
auto hooks = IPUHooksRegistry()->Create("IPUHooks", IPUHooksArgs{});
if (hooks) {
return hooks;
}
});
return std::make_unique<IPUHooksInterface>();
};
static auto hooks = create_impl();
return *hooks;
}

View File

@ -1,25 +1,19 @@
#include <ATen/detail/MAIAHooksInterface.h>
#include <c10/util/CallOnce.h>
#include <c10/util/Registry.h>
#include <cstddef>
#include <memory>
namespace at {
namespace detail {
// See getCUDAHooks for some more commentary
const MAIAHooksInterface& getMAIAHooks() {
static std::unique_ptr<MAIAHooksInterface> maia_hooks;
static c10::once_flag once;
c10::call_once(once, [] {
maia_hooks = MAIAHooksRegistry()->Create("MAIAHooks", {});
if (!maia_hooks) {
maia_hooks = std::make_unique<MAIAHooksInterface>();
auto create_impl = [] {
auto hooks = MAIAHooksRegistry()->Create("MAIAHooks", {});
if (hooks) {
return hooks;
}
});
return *maia_hooks;
return std::make_unique<MAIAHooksInterface>();
};
static auto hooks = create_impl();
return *hooks;
}
} // namespace detail

View File

@ -1,27 +1,22 @@
// Copyright © 2022 Apple Inc.
#include <ATen/detail/MPSHooksInterface.h>
#include <c10/util/CallOnce.h>
namespace at {
namespace detail {
const MPSHooksInterface& getMPSHooks() {
static std::unique_ptr<MPSHooksInterface> mps_hooks;
auto create_impl = [] {
#if !defined C10_MOBILE
static c10::once_flag once;
c10::call_once(once, [] {
mps_hooks = MPSHooksRegistry()->Create("MPSHooks", MPSHooksArgs{});
if (!mps_hooks) {
mps_hooks = std::make_unique<MPSHooksInterface>();
auto hooks = MPSHooksRegistry()->Create("MPSHooks", MPSHooksArgs{});
if (hooks) {
return hooks;
}
});
#else
if (mps_hooks == nullptr) {
mps_hooks = std::make_unique<MPSHooksInterface>();
}
#endif
return *mps_hooks;
return std::make_unique<MPSHooksInterface>();
};
static auto hooks = create_impl();
return *hooks;
}
} // namespace detail

View File

@ -1,22 +1,18 @@
#include <ATen/detail/MTIAHooksInterface.h>
#include <c10/util/CallOnce.h>
#include <memory>
namespace at {
namespace detail {
const MTIAHooksInterface& getMTIAHooks() {
static std::unique_ptr<MTIAHooksInterface> mtia_hooks = nullptr;
static c10::once_flag once;
c10::call_once(once, [] {
mtia_hooks = MTIAHooksRegistry()->Create("MTIAHooks", MTIAHooksArgs{});
if (!mtia_hooks) {
mtia_hooks = std::make_unique<MTIAHooksInterface>();
auto create_impl = [] {
auto hooks = MTIAHooksRegistry()->Create("MTIAHooks", MTIAHooksArgs{});
if (hooks) {
return hooks;
}
});
return *mtia_hooks;
return std::make_unique<MTIAHooksInterface>();
};
static auto hooks = create_impl();
return *hooks;
}
bool isMTIAHooksBuilt() {

View File

@ -1,21 +1,18 @@
#include <ATen/detail/XPUHooksInterface.h>
#include <c10/util/CallOnce.h>
namespace at {
namespace detail {
const XPUHooksInterface& getXPUHooks() {
static XPUHooksInterface* xpu_hooks = nullptr;
static c10::once_flag once;
c10::call_once(once, [] {
xpu_hooks =
XPUHooksRegistry()->Create("XPUHooks", XPUHooksArgs{}).release();
if (!xpu_hooks) {
xpu_hooks = new XPUHooksInterface();
auto create_impl = [] {
auto hooks = XPUHooksRegistry()->Create("XPUHooks", XPUHooksArgs{});
if (hooks) {
return hooks;
}
});
return *xpu_hooks;
return std::make_unique<XPUHooksInterface>();
};
static auto hooks = create_impl();
return *hooks;
}
} // namespace detail

View File

@ -1359,8 +1359,11 @@ void Engine::initialize_device_threads_pool() {
!in_bad_autograd_fork,
"Unable to handle autograd's threading in combination with fork-based multiprocessing. "
"See https://github.com/pytorch/pytorch/wiki/Autograd-and-Fork");
c10::call_once(
start_device_threads_flag_, &Engine::start_device_threads, this);
// Ensures device_ready_queues_ are initialized only once
static bool start_device_threads_flag_ [[maybe_unused]] = [this]() {
this->start_device_threads();
return true;
}();
}
c10::intrusive_ptr<at::ivalue::Future> Engine::execute_with_graph_task(

View File

@ -230,9 +230,6 @@ struct TORCH_API Engine {
void reentrant_thread_init();
void add_thread_pool_task(const std::weak_ptr<GraphTask>& graph_task);
// Ensures device_ready_queues_ are initialized only once
// NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)
c10::once_flag start_device_threads_flag_;
// Safe to read device_ready_queues_ without synchronization after
// initialization
// NOLINTNEXTLINE(cppcoreguidelines-non-private-member-variables-in-classes)

View File

@ -38,8 +38,6 @@
#include <torch/csrc/distributed/c10d/logging.h>
#include <torch/csrc/distributed/c10d/socket_fmt.h>
#include <c10/util/CallOnce.h>
namespace c10d::detail {
namespace {
#ifdef _WIN32
@ -1027,17 +1025,16 @@ void SocketConnectOp::throwTimeoutError() const {
void Socket::initialize() {
#ifdef _WIN32
static c10::once_flag init_flag{};
// All processes that call socket functions on Windows must first initialize
// the Winsock library.
c10::call_once(init_flag, []() {
static bool init_flag [[maybe_unused]] = []() {
WSADATA data{};
if (::WSAStartup(MAKEWORD(2, 2), &data) != 0) {
C10D_THROW_ERROR(
SocketError, "The initialization of Winsock has failed.");
}
});
return true;
}();
#endif
}