From 9f7b2675bf6f102e6f0bfa442b52df8ba86a2ebc Mon Sep 17 00:00:00 2001 From: Gabriel Mitterrutzner Date: Tue, 13 Oct 2026 17:39:45 +0200 Subject: [PATCH] Add workaround for ACPP allocation tracker destruction order --- src/backend/sycl_backend.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/backend/sycl_backend.cc b/src/backend/sycl_backend.cc index c5b76ec8..d7b83c5e 100644 --- a/src/backend/sycl_backend.cc +++ b/src/backend/sycl_backend.cc @@ -181,6 +181,14 @@ struct sycl_backend::impl { }; sycl_backend::sycl_backend(const std::vector& devices, const configuration& config) : m_impl(new impl(devices, config)) { +#if CELERITY_WORKAROUND(ACPP) + // AdaptiveCpp tracks USM allocations in a function-local static that is created by the first allocation. The runtime (and with it, all backend + // allocations) is torn down from an atexit handler that is registered right after the backend has been constructed. Unless the tracker already exists + // at that point it will be destroyed before that handler runs, and every sycl::free() during shutdown then operates on a dead object, which corrupts the + // heap (observed as a hang in release builds and a segfault in debug builds). Allocating once here establishes the correct destruction order. + sycl::free(sycl::aligned_alloc_host(alignof(std::max_align_t), 1, m_impl->host.sycl_context), m_impl->host.sycl_context); +#endif + // Initialize a submission thread with hydrator for each device, if they are enabled if(m_impl->config.per_device_submission_threads) { for(device_id did = 0; did < m_impl->system.devices.size(); ++did) {