Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion tests/cpp/util/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,6 @@ target_link_libraries(test_util PUBLIC
target_compile_options(test_util PRIVATE -O2 -fopenmp)

include(GoogleTest)
gtest_discover_tests(test_util DISCOVERY_TIMEOUT 600)
# MALLOC_PERTURB_ makes glibc overwrite freed memory, so a destructor that reads a destroyed object
# at exit crashes the test process, which ctest reports as a failure, instead of passing silently.
gtest_discover_tests(test_util DISCOVERY_TIMEOUT 600 PROPERTIES ENVIRONMENT "MALLOC_PERTURB_=165")
4 changes: 3 additions & 1 deletion transformer_engine/common/fused_attn/graph_cache.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,9 @@ std::shared_ptr<CacheEntry<GraphAndTensors>> cache_graph(GraphCache<GraphAndTens
// Create a cache for each (backend, pass) pair, and either get cached entry or build anew.
template <Backend kBackend, Pass kPass, auto kCreateGraphFn>
auto get_graph(const FusedAttnConfig &cfg, cudnnHandle_t handle) {
static GraphCache<decltype(kCreateGraphFn(cfg))> cache;
// Never destroyed: destroying cached cuDNN plans calls into CUDA, which must not be used during
// program termination.
static auto &cache = *new GraphCache<decltype(kCreateGraphFn(cfg))>;
cfg.check_derived();
return detail::cache_graph(cache, cfg.make_cache_key(kPass), kBackend, kPass, handle,
[&] { return kCreateGraphFn(cfg); });
Expand Down
6 changes: 4 additions & 2 deletions transformer_engine/common/util/cuda_driver.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,10 @@ template <typename... ArgTs>
inline CUresult call(const char *symbol, ArgTs... args) {
using FuncT = CUresult(ArgTs...);

static std::unordered_map<std::string, void *> symbol_cache;
static std::mutex cache_mutex;
// Never destroyed, so a lookup never reads a destroyed map, whatever order statics are
// constructed and destroyed in.
static auto &symbol_cache = *new std::unordered_map<std::string, void *>();
static auto &cache_mutex = *new std::mutex();
FuncT *func;

{
Expand Down
4 changes: 3 additions & 1 deletion transformer_engine/common/util/rtc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,9 @@ int Kernel::occupancy_max_active_blocks_per_sm(int device_id, int block_size,

KernelManager& KernelManager::instance() {
NVTE_CHECK(is_enabled(), "NVRTC support is not enabled");
static KernelManager instance_;
// Never destroyed: ~Kernel unloads modules through the CUDA driver, and CUDA must not be used
// during program termination.
static KernelManager& instance_ = *new KernelManager;
return instance_;
}

Expand Down
Loading