Repository: acts-project/traccc
Pull request #960: Alpaka: Vecmem Interface
Author: login: CrossR
Created: 2025-05-02T11:42:43Z | Merged: 2025-05-15T13:44:18Z

Based on the code in #959, just with a few small changes:

 - Test + examples updated (where appropriate) to use the new code.
 - ~~`ifdef` guard around `async_copy` init in the `CUDA || HIP` bit, just whilst we are still on an older vecmem release. Can be updated when we update that, though no rush as the async copy is not used in Alpaka yet.~~
 - I swapped the `alpaka::Queue` to default to device 0 in cases where there is no device given. Any opinions on this welcomed. I didn't / couldn't go down the CUDA route (which is `if device == INVALID_DEVICE get_current_device()`), as Alpaka has no concept of the current device. Could instead just remove the default and force a device ID to be given? I think either is preferable to just silently failing.

I've deleted the previous code now as well, which removes Alpaka from the `traccc::alpaka` public headers once again.


Diff:
diff --git a/device/alpaka/CMakeLists.txt b/device/alpaka/CMakeLists.txt
index 2770bc7322..3cc4db1f78 100644
--- a/device/alpaka/CMakeLists.txt
+++ b/device/alpaka/CMakeLists.txt
@@ -26,10 +26,15 @@ endif()
 traccc_add_alpaka_library( traccc_alpaka alpaka TYPE SHARED
   # Utility definitions.
   "include/traccc/alpaka/utils/get_device_info.hpp"
-  "include/traccc/alpaka/utils/get_vecmem_resource.hpp"
   "include/traccc/alpaka/utils/make_prefix_sum_buff.hpp"
   "src/utils/make_prefix_sum_buff.cpp"
   "src/utils/get_device_info.cpp"
+  "include/traccc/alpaka/utils/queue.hpp"
+  "src/utils/queue.cpp"
+  "src/utils/get_queue.hpp"
+  "src/utils/get_queue.cpp"
+  "include/traccc/alpaka/utils/vecmem_objects.hpp"
+  "src/utils/vecmem_objects.cpp"
   # Clusterization
   "include/traccc/alpaka/clusterization/clusterization_algorithm.hpp"
   "src/clusterization/clusterization_algorithm.cpp"
diff --git a/device/alpaka/include/traccc/alpaka/utils/device_tag.hpp b/device/alpaka/include/traccc/alpaka/utils/device_tag.hpp
deleted file mode 100644
index 2c3a21eb2b..0000000000
--- a/device/alpaka/include/traccc/alpaka/utils/device_tag.hpp
+++ /dev/null
@@ -1,31 +0,0 @@
-/** TRACCC library, part of the ACTS project (R&D line)
- *
- * (c) 2024 CERN for the benefit of the ACTS project
- *
- * Mozilla Public License Version 2.0
- */
-
-#pragma once
-
-#include <alpaka/acc/Tag.hpp>
-
-namespace traccc::alpaka {
-
-// Get alpaka tag for current device
-#if defined(ALPAKA_ACC_GPU_CUDA_ENABLED)
-using AccTag = ::alpaka::TagGpuCudaRt;
-#elif defined(ALPAKA_ACC_GPU_HIP_ENABLED)
-using AccTag = ::alpaka::TagGpuHipRt;
-#elif defined(ALPAKA_ACC_SYCL_ENABLED)
-#if defined(ALPAKA_SYCL_ONEAPI_CPU)
-using AccTag = ::alpaka::TagCpuSycl;
-#elif defined(ALPAKA_SYCL_ONEAPI_FPGA)
-using AccTag = ::alpaka::TagFpgaSyclIntel;
-#elif defined(ALPAKA_SYCL_ONEAPI_GPU)
-using AccTag = ::alpaka::TagGpuSyclIntel;
-#endif
-#elif defined(ALPAKA_ACC_CPU_B_SEQ_T_THREADS_ENABLED)
-using AccTag = ::alpaka::TagCpuThreads;
-#endif
-
-}  // namespace traccc::alpaka
diff --git a/device/alpaka/include/traccc/alpaka/utils/get_vecmem_resource.hpp b/device/alpaka/include/traccc/alpaka/utils/get_vecmem_resource.hpp
deleted file mode 100644
index c5cb927b61..0000000000
--- a/device/alpaka/include/traccc/alpaka/utils/get_vecmem_resource.hpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/**
- * traccc library, part of the ACTS project (R&D line)
- *
- * (c) 2024-2025 CERN for the benefit of the ACTS project
- *
- * Mozilla Public License Version 2.0
- */
-
-#pragma once
-
-// VecMem include(s).
-#ifdef ALPAKA_ACC_GPU_CUDA_ENABLED
-#include <vecmem/memory/cuda/device_memory_resource.hpp>
-#include <vecmem/memory/cuda/host_memory_resource.hpp>
-#include <vecmem/memory/cuda/managed_memory_resource.hpp>
-#include <vecmem/utils/cuda/copy.hpp>
-
-#elif defined(ALPAKA_ACC_GPU_HIP_ENABLED)
-#include <vecmem/memory/hip/device_memory_resource.hpp>
-#include <vecmem/memory/hip/host_memory_resource.hpp>
-#include <vecmem/memory/hip/managed_memory_resource.hpp>
-#include <vecmem/utils/hip/copy.hpp>
-
-#elif defined(ALPAKA_ACC_SYCL_ENABLED)
-#include <vecmem/memory/sycl/device_memory_resource.hpp>
-#include <vecmem/memory/sycl/host_memory_resource.hpp>
-#include <vecmem/memory/sycl/shared_memory_resource.hpp>
-#include <vecmem/utils/sycl/copy.hpp>
-
-#else
-#include <vecmem/memory/memory_resource.hpp>
-#include <vecmem/utils/copy.hpp>
-#endif
-
-#include "traccc/alpaka/utils/device_tag.hpp"
-
-// Forward declarations so we can compile the types below
-namespace vecmem {
-class host_memory_resource;
-class copy;
-namespace cuda {
-class host_memory_resource;
-class device_memory_resource;
-class managed_memory_resource;
-class copy;
-}  // namespace cuda
-namespace hip {
-class host_memory_resource;
-class device_memory_resource;
-class managed_memory_resource;
-class copy;
-}  // namespace hip
-namespace sycl {
-class host_memory_resource;
-class device_memory_resource;
-class shared_memory_resource;
-class copy;
-}  // namespace sycl
-}  // namespace vecmem
-
-namespace traccc::alpaka::vecmem_resources {
-// For all CPU accelerators (except SYCL), just use host
-template <typename T>
-struct host_device_types {
-    using device_memory_resource = vecmem::host_memory_resource;
-    using host_memory_resource = vecmem::host_memory_resource;
-    using managed_memory_resource = vecmem::host_memory_resource;
-    using device_copy = vecmem::copy;
-};
-template <>
-struct host_device_types<::alpaka::TagGpuCudaRt> {
-    using device_memory_resource = vecmem::cuda::device_memory_resource;
-    using host_memory_resource = vecmem::cuda::host_memory_resource;
-    using managed_memory_resource = vecmem::cuda::managed_memory_resource;
-    using device_copy = vecmem::cuda::copy;
-};
-template <>
-struct host_device_types<::alpaka::TagGpuHipRt> {
-    using device_memory_resource = vecmem::hip::device_memory_resource;
-    using host_memory_resource = vecmem::hip::host_memory_resource;
-    using managed_memory_resource = vecmem::hip::managed_memory_resource;
-    using device_copy = vecmem::hip::copy;
-};
-template <>
-struct host_device_types<::alpaka::TagCpuSycl> {
-    using device_memory_resource = vecmem::sycl::device_memory_resource;
-    using host_memory_resource = vecmem::sycl::host_memory_resource;
-    using managed_memory_resource = vecmem::sycl::shared_memory_resource;
-    using device_copy = vecmem::sycl::copy;
-};
-template <>
-struct host_device_types<::alpaka::TagFpgaSyclIntel> {
-    using device_memory_resource = vecmem::sycl::device_memory_resource;
-    using host_memory_resource = vecmem::sycl::host_memory_resource;
-    using managed_memory_resource = vecmem::sycl::shared_memory_resource;
-    using device_copy = vecmem::sycl::copy;
-};
-template <>
-struct host_device_types<::alpaka::TagGpuSyclIntel> {
-    using device_memory_resource = vecmem::sycl::device_memory_resource;
-    using host_memory_resource = vecmem::sycl::host_memory_resource;
-    using managed_memory_resource = vecmem::sycl::shared_memory_resource;
-    using device_copy = vecmem::sycl::copy;
-};
-
-using device_memory_resource =
-    typename host_device_types<AccTag>::device_memory_resource;
-using host_memory_resource =
-    typename host_device_types<AccTag>::host_memory_resource;
-using managed_memory_resource =
-    typename host_device_types<AccTag>::managed_memory_resource;
-using device_copy = typename host_device_types<AccTag>::device_copy;
-
-}  // namespace traccc::alpaka::vecmem_resources
diff --git a/device/alpaka/include/traccc/alpaka/utils/queue.hpp b/device/alpaka/include/traccc/alpaka/utils/queue.hpp
new file mode 100644
index 0000000000..94a66a376f
--- /dev/null
+++ b/device/alpaka/include/traccc/alpaka/utils/queue.hpp
@@ -0,0 +1,60 @@
+/**
+ * traccc library, part of the ACTS project (R&D line)
+ *
+ * (c) 2025 CERN for the benefit of the ACTS project
+ *
+ * Mozilla Public License Version 2.0
+ */
+
+#pragma once
+
+// System include(s).
+#include <cstddef>
+#include <limits>
+#include <memory>
+
+namespace traccc::alpaka {
+
+/// Owning wrapper around @c ::alpaka::Queue
+class queue {
+
+    public:
+    /// Invalid/default device identifier
+    static constexpr std::size_t INVALID_DEVICE =
+        std::numeric_limits<std::size_t>::max();
+
+    /// Construct a new stream (possibly for a specified device)
+    explicit queue(std::size_t device = INVALID_DEVICE);
+
+    /// Wrap an existing ::alpaka::Queue object
+    ///
+    /// Without taking ownership of it!
+    ///
+    explicit queue(void* input_queue);
+
+    /// Move constructor
+    queue(queue&& parent) noexcept;
+
+    /// Destructor
+    ~queue();
+
+    /// Move assignment
+    queue& operator=(queue&& rhs) noexcept;
+
+    /// Access a typeless pointer to the managed @c ::alpaka::Queue object
+    void* alpakaQueue();
+    /// Access a typeless pointer to the managed @c ::alpaka::Queue object
+    const void* alpakaQueue() const;
+
+    /// Wait for all queued tasks from the stream to complete
+    void synchronize();
+
+    private:
+    /// Type holing the implementation
+    struct impl;
+    /// Smart pointer to the implementation
+    std::unique_ptr<impl> m_impl;
+
+};  // class queue
+
+}  // namespace traccc::alpaka
diff --git a/device/alpaka/include/traccc/alpaka/utils/vecmem_objects.hpp b/device/alpaka/include/traccc/alpaka/utils/vecmem_objects.hpp
new file mode 100644
index 0000000000..3b7b4918d0
--- /dev/null
+++ b/device/alpaka/include/traccc/alpaka/utils/vecmem_objects.hpp
@@ -0,0 +1,55 @@
+/**
+ * traccc library, part of the ACTS project (R&D line)
+ *
+ * (c) 2025 CERN for the benefit of the ACTS project
+ *
+ * Mozilla Public License Version 2.0
+ */
+
+#pragma once
+
+// Local include(s).
+#include "traccc/alpaka/utils/queue.hpp"
+
+// VecMem include(s).
+#include <vecmem/memory/memory_resource.hpp>
+#include <vecmem/utils/copy.hpp>
+
+namespace traccc::alpaka {
+
+/// Helper class for instantiating the correct vecmem objects for the way
+/// the @c traccc::alpaka library was built.
+class vecmem_objects {
+
+    public:
+    /// Constructor from a queue
+    explicit vecmem_objects(queue& q);
+    /// Move constructor
+    vecmem_objects(vecmem_objects&&) noexcept;
+    /// Destructor
+    ~vecmem_objects();
+
+    /// Move assignment
+    vecmem_objects& operator=(vecmem_objects&&) noexcept;
+
+    /// The host memory resource to use
+    vecmem::memory_resource& host_mr() const;
+    /// The device memory resource to use
+    vecmem::memory_resource& device_mr() const;
+    /// The shared/managed memory resource to use
+    vecmem::memory_resource& shared_mr() const;
+
+    /// The (synchronous) copy object to use
+    vecmem::copy& copy() const;
+    /// The asynchronous copy object to use
+    vecmem::copy& async_copy() const;
+
+    private:
+    /// Type holing the implementation
+    struct impl;
+    /// Smart pointer to the implementation
+    std::unique_ptr<impl> m_impl;
+
+};  // class vecmem_objects
+
+}  // namespace traccc::alpaka
diff --git a/device/alpaka/src/utils/get_queue.cpp b/device/alpaka/src/utils/get_queue.cpp
new file mode 100644
index 0000000000..f69642ee4a
--- /dev/null
+++ b/device/alpaka/src/utils/get_queue.cpp
@@ -0,0 +1,29 @@
+/**
+ * traccc library, part of the ACTS project (R&D line)
+ *
+ * (c) 2025 CERN for the benefit of the ACTS project
+ *
+ * Mozilla Public License Version 2.0
+ */
+
+// Local include(s).
+#include "get_queue.hpp"
+
+// System include(s).
+#include <cassert>
+
+namespace traccc::alpaka::details {
+
+Queue& get_queue(queue& q) {
+
+    assert(q.alpakaQueue() != nullptr);
+    return *(reinterpret_cast<Queue*>(q.alpakaQueue()));
+}
+
+const Queue& get_queue(const queue& q) {
+
+    assert(q.alpakaQueue() != nullptr);
+    return *(reinterpret_cast<const Queue*>(q.alpakaQueue()));
+}
+
+}  // namespace traccc::alpaka::details
diff --git a/device/alpaka/src/utils/get_queue.hpp b/device/alpaka/src/utils/get_queue.hpp
new file mode 100644
index 0000000000..2ad727a99a
--- /dev/null
+++ b/device/alpaka/src/utils/get_queue.hpp
@@ -0,0 +1,23 @@
+/**
+ * traccc library, part of the ACTS project (R&D line)
+ *
+ * (c) 2025 CERN for the benefit of the ACTS project
+ *
+ * Mozilla Public License Version 2.0
+ */
+
+#pragma once
+
+// Local include(s).
+#include "traccc/alpaka/utils/queue.hpp"
+#include "utils.hpp"
+
+namespace traccc::alpaka::details {
+
+/// Helper function for getting a @c Queue out of @c queue (non-const)
+Queue& get_queue(queue& q);
+
+/// Helper function for getting a @c Queue out of @c queue (const)
+const Queue& get_queue(const queue& q);
+
+}  // namespace traccc::alpaka::details
diff --git a/device/alpaka/src/utils/queue.cpp b/device/alpaka/src/utils/queue.cpp
new file mode 100644
index 0000000000..1b34866f80
--- /dev/null
+++ b/device/alpaka/src/utils/queue.cpp
@@ -0,0 +1,63 @@
+/**
+ * traccc library, part of the ACTS project (R&D line)
+ *
+ * (c) 2025 CERN for the benefit of the ACTS project
+ *
+ * Mozilla Public License Version 2.0
+ */
+
+// Local include(s).
+#include "traccc/alpaka/utils/queue.hpp"
+
+#include "utils.hpp"
+
+// Alpaka include(s).
+#include <alpaka/alpaka.hpp>
+
+namespace traccc::alpaka {
+
+struct queue::impl {
+    /// Bare pointer to the wrapped queue object
+    Queue* m_queue = nullptr;
+    /// Unique pointer to the managed Queue object
+    std::unique_ptr<Queue> m_managedQueue;
+};  // struct queue::impl
+
+queue::queue(std::size_t device) : m_impl{std::make_unique<impl>()} {
+
+    m_impl->m_managedQueue = std::make_unique<Queue>(::alpaka::getDevByIdx(
+        ::alpaka::Platform<Acc>{}, device == INVALID_DEVICE ? 0 : device));
+    m_impl->m_queue = m_impl->m_managedQueue.get();
+}
+
+queue::queue(void* input_queue) : m_impl{std::make_unique<impl>()} {
+
+    assert(input_queue != nullptr);
+    m_impl->m_queue = static_cast<Queue*>(input_queue);
+}
+
+queue::queue(queue&&) noexcept = default;
+
+queue::~queue() = default;
+
+queue& queue::operator=(queue&& rhs) noexcept = default;
+
+void* queue::alpakaQueue() {
+
+    assert(m_impl->m_queue != nullptr);
+    return m_impl->m_queue;
+}
+
+const void* queue::alpakaQueue() const {
+
+    assert(m_impl->m_queue != nullptr);
+    return m_impl->m_queue;
+}
+
+void queue::synchronize() {
+
+    assert(m_impl->m_queue != nullptr);
+    ::alpaka::wait(*m_impl->m_queue);
+}
+
+}  // namespace traccc::alpaka
diff --git a/device/alpaka/src/utils/vecmem_objects.cpp b/device/alpaka/src/utils/vecmem_objects.cpp
new file mode 100644
index 0000000000..4f933c40cf
--- /dev/null
+++ b/device/alpaka/src/utils/vecmem_objects.cpp
@@ -0,0 +1,126 @@
+/**
+ * traccc library, part of the ACTS project (R&D line)
+ *
+ * (c) 2025 CERN for the benefit of the ACTS project
+ *
+ * Mozilla Public License Version 2.0
+ */
+
+// Local include(s).
+#include "traccc/alpaka/utils/vecmem_objects.hpp"
+
+#include "get_queue.hpp"
+
+// VecMem include(s).
+#if defined(ALPAKA_ACC_GPU_CUDA_ENABLED)
+#include <vecmem/memory/cuda/device_memory_resource.hpp>
+#include <vecmem/memory/cuda/host_memory_resource.hpp>
+#include <vecmem/memory/cuda/managed_memory_resource.hpp>
+#include <vecmem/utils/cuda/async_copy.hpp>
+#include <vecmem/utils/cuda/copy.hpp>
+#elif defined(ALPAKA_ACC_GPU_HIP_ENABLED)
+#include <vecmem/memory/hip/device_memory_resource.hpp>
+#include <vecmem/memory/hip/host_memory_resource.hpp>
+#include <vecmem/memory/hip/managed_memory_resource.hpp>
+#include <vecmem/utils/hip/async_copy.hpp>
+#include <vecmem/utils/hip/copy.hpp>
+#elif defined(ALPAKA_ACC_SYCL_ENABLED)
+#include <vecmem/memory/sycl/device_memory_resource.hpp>
+#include <vecmem/memory/sycl/host_memory_resource.hpp>
+#include <vecmem/memory/sycl/shared_memory_resource.hpp>
+#include <vecmem/utils/sycl/async_copy.hpp>
+#include <vecmem/utils/sycl/copy.hpp>
+#else
+#include <vecmem/memory/host_memory_resource.hpp>
+#include <vecmem/utils/copy.hpp>
+#endif
+
+namespace traccc::alpaka {
+
+struct vecmem_objects::impl {
+
+    /// Constructor
+    explicit impl([[maybe_unused]] queue& q)
+        :
+#if defined(ALPAKA_ACC_GPU_CUDA_ENABLED) || defined(ALPAKA_ACC_GPU_HIP_ENABLED)
+          m_host_mr(),
+          m_device_mr(::alpaka::getNativeHandle(
+              ::alpaka::getDev(details::get_queue(q)))),
+          m_shared_mr(),
+          m_copy(),
+          m_async_copy(::alpaka::getNativeHandle(details::get_queue(q)))
+#elif defined(ALPAKA_ACC_SYCL_ENABLED)
+          m_queue(::alpaka::getNativeHandle(details::get_queue(q))),
+          m_host_mr(&m_queue),
+          m_device_mr(&m_queue),
+          m_shared_mr(&m_queue),
+          m_copy(&m_queue),
+          m_async_copy(&m_queue)
+#else
+          m_host_mr(),
+          m_device_mr(),
+          m_shared_mr(),
+          m_copy(),
+          m_async_copy()
+#endif
+    {
+    }
+
+#if defined(ALPAKA_ACC_GPU_CUDA_ENABLED)
+    vecmem::cuda::host_memory_resource m_host_mr;
+    vecmem::cuda::device_memory_resource m_device_mr;
+    vecmem::cuda::managed_memory_resource m_shared_mr;
+    vecmem::cuda::copy m_copy;
+    vecmem::cuda::async_copy m_async_copy;
+#elif defined(ALPAKA_ACC_GPU_HIP_ENABLED)
+    vecmem::hip::host_memory_resource m_host_mr;
+    vecmem::hip::device_memory_resource m_device_mr;
+    vecmem::hip::managed_memory_resource m_shared_mr;
+    vecmem::hip::copy m_copy;
+    vecmem::hip::async_copy m_async_copy;
+#elif defined(ALPAKA_ACC_SYCL_ENABLED)
+    ::sycl::queue m_queue;
+    vecmem::sycl::host_memory_resource m_host_mr;
+    vecmem::sycl::device_memory_resource m_device_mr;
+    vecmem::sycl::shared_memory_resource m_shared_mr;
+    vecmem::sycl::copy m_copy;
+    vecmem::sycl::async_copy m_async_copy;
+#else
+    vecmem::host_memory_resource m_host_mr;
+    vecmem::host_memory_resource m_device_mr;
+    vecmem::host_memory_resource m_shared_mr;
+    vecmem::copy m_copy;
+    vecmem::copy m_async_copy;
+#endif
+
+};  // struct vecmem_objects::impl
+
+vecmem_objects::vecmem_objects(queue& q) : m_impl{std::make_unique<impl>(q)} {}
+
+vecmem_objects::vecmem_objects(vecmem_objects&&) noexcept = default;
+
+vecmem_objects::~vecmem_objects() = default;
+
+vecmem_objects& vecmem_objects::operator=(vecmem_objects&&) noexcept = default;
+
+vecmem::memory_resource& vecmem_objects::host_mr() const {
+    return m_impl->m_host_mr;
+}
+
+vecmem::memory_resource& vecmem_objects::device_mr() const {
+    return m_impl->m_device_mr;
+}
+
+vecmem::memory_resource& vecmem_objects::shared_mr() const {
+    return m_impl->m_shared_mr;
+}
+
+vecmem::copy& vecmem_objects::copy() const {
+    return m_impl->m_copy;
+}
+
+vecmem::copy& vecmem_objects::async_copy() const {
+    return m_impl->m_async_copy;
+}
+
+}  // namespace traccc::alpaka
diff --git a/examples/run/alpaka/CMakeLists.txt b/examples/run/alpaka/CMakeLists.txt
index 5d4ff36d0b..de3a55c1a4 100644
--- a/examples/run/alpaka/CMakeLists.txt
+++ b/examples/run/alpaka/CMakeLists.txt
@@ -9,9 +9,6 @@ include( traccc-alpaka-functions )
 
 set(EXTRA_LIBS)
 
-include(traccc-alpaka-functions)
-traccc_enable_language_alpaka()
-
 if(alpaka_ACC_GPU_CUDA_ENABLE)
   list (APPEND EXTRA_LIBS vecmem::cuda)
 elseif(alpaka_ACC_GPU_HIP_ENABLE)
@@ -22,7 +19,7 @@ elseif(alpaka_ACC_SYCL_ENABLE)
 endif()
 
 set(LIBRARIES vecmem::core traccc::io traccc::performance
-    traccc::core traccc::device_common traccc::alpaka alpaka::alpaka
+    traccc::core traccc::device_common traccc::alpaka
     traccc::options ${EXTRA_LIBS})
 set(DETRAY detray::io detray::detectors)
 
@@ -38,7 +35,7 @@ add_library( traccc_examples_alpaka STATIC
    "full_chain_algorithm.hpp"
    "full_chain_algorithm.cpp" )
 target_link_libraries( traccc_examples_alpaka
-   PUBLIC alpaka::alpaka vecmem::core detray::core detray::detectors
+   PUBLIC vecmem::core detray::core detray::detectors
    traccc::core traccc::device_common traccc::alpaka ${EXTRA_LIBS})
 
 traccc_add_executable( throughput_st_alpaka "throughput_st.cpp"
diff --git a/examples/run/alpaka/full_chain_algorithm.cpp b/examples/run/alpaka/full_chain_algorithm.cpp
index 464a7c3d3f..4836751c92 100644
--- a/examples/run/alpaka/full_chain_algorithm.cpp
+++ b/examples/run/alpaka/full_chain_algorithm.cpp
@@ -25,18 +25,12 @@ full_chain_algorithm::full_chain_algorithm(
     const silicon_detector_description::host& det_descr,
     host_detector_type* detector, std::unique_ptr<const traccc::Logger> logger)
     : messaging(logger->clone()),
+      m_queue(),
+      m_vecmem_objects(m_queue),
       m_host_mr(host_mr),
-#if defined(ALPAKA_ACC_SYCL_ENABLED)
-      m_queue(::sycl::queue()),
-      m_queue_wrapper(&m_queue),
-      m_device_mr(m_queue_wrapper),
-      m_copy(m_queue_wrapper),
-#else
-      m_device_mr(),
-      m_copy(),
-#endif
       m_cached_device_mr(
-          std::make_unique<::vecmem::binary_page_memory_resource>(m_device_mr)),
+          std::make_unique<::vecmem::binary_page_memory_resource>(
+              m_vecmem_objects.device_mr())),
       m_field_vec{0.f, 0.f, finder_config.bFieldInZ},
       m_field(traccc::construct_const_bfield<host_detector_type::scalar_type>(
           m_field_vec)),
@@ -44,25 +38,27 @@ full_chain_algorithm::full_chain_algorithm(
       m_device_det_descr(
           static_cast<silicon_detector_description::buffer::size_type>(
               m_det_descr.get().size()),
-          m_device_mr),
+          m_vecmem_objects.device_mr()),
       m_detector(detector),
-      m_clusterization(memory_resource{*m_cached_device_mr, &m_host_mr}, m_copy,
-                       clustering_config),
-      m_measurement_sorting(m_copy, logger->cloneWithSuffix("MeasSortingAlg")),
+      m_clusterization(memory_resource{*m_cached_device_mr, &m_host_mr},
+                       m_vecmem_objects.copy(), clustering_config),
+      m_measurement_sorting(m_vecmem_objects.copy(),
+                            logger->cloneWithSuffix("MeasSortingAlg")),
       m_spacepoint_formation(memory_resource{*m_cached_device_mr, &m_host_mr},
-                             m_copy, logger->cloneWithSuffix("SpFormationAlg")),
+                             m_vecmem_objects.copy(),
+                             logger->cloneWithSuffix("SpFormationAlg")),
       m_seeding(finder_config, grid_config, filter_config,
-                memory_resource{*m_cached_device_mr, &m_host_mr}, m_copy,
-                logger->cloneWithSuffix("SeedingAlg")),
+                memory_resource{*m_cached_device_mr, &m_host_mr},
+                m_vecmem_objects.copy(), logger->cloneWithSuffix("SeedingAlg")),
       m_track_parameter_estimation(
-          memory_resource{*m_cached_device_mr, &m_host_mr}, m_copy,
-          logger->cloneWithSuffix("TrackParamEstAlg")),
-      m_finding(finding_config,
-                memory_resource{*m_cached_device_mr, &m_host_mr}, m_copy,
-                logger->cloneWithSuffix("TrackFindingAlg")),
-      m_fitting(fitting_config,
-                memory_resource{*m_cached_device_mr, &m_host_mr}, m_copy,
-                logger->cloneWithSuffix("TrackFittingAlg")),
+          memory_resource{*m_cached_device_mr, &m_host_mr},
+          m_vecmem_objects.copy(), logger->cloneWithSuffix("TrackParamEstAlg")),
+      m_finding(
+          finding_config, memory_resource{*m_cached_device_mr, &m_host_mr},
+          m_vecmem_objects.copy(), logger->cloneWithSuffix("TrackFindingAlg")),
+      m_fitting(
+          fitting_config, memory_resource{*m_cached_device_mr, &m_host_mr},
+          m_vecmem_objects.copy(), logger->cloneWithSuffix("TrackFittingAlg")),
       m_clustering_config(clustering_config),
       m_finder_config(finder_config),
       m_grid_config(grid_config),
@@ -73,55 +69,56 @@ full_chain_algorithm::full_chain_algorithm(
     std::cout << traccc::alpaka::get_device_info() << std::endl;
 
     // Copy the detector (description) to the device.
-    m_copy(::vecmem::get_data(m_det_descr.get()), m_device_det_descr)->ignore();
+    m_vecmem_objects
+        .copy()(::vecmem::get_data(m_det_descr.get()), m_device_det_descr)
+        ->ignore();
     if (m_detector != nullptr) {
         m_device_detector = detray::get_buffer(detray::get_data(*m_detector),
-                                               m_device_mr, m_copy);
+                                               m_vecmem_objects.device_mr(),
+                                               m_vecmem_objects.copy());
         m_device_detector_view = detray::get_data(m_device_detector);
     }
 }
 
 full_chain_algorithm::full_chain_algorithm(const full_chain_algorithm& parent)
     : messaging(parent.logger().clone()),
+      m_queue(),
+      m_vecmem_objects(m_queue),
       m_host_mr(parent.m_host_mr),
-#if defined(ALPAKA_ACC_SYCL_ENABLED)
-      m_queue(parent.m_queue),
-      m_queue_wrapper(&m_queue),
-      m_device_mr(m_queue_wrapper),
-      m_copy(m_queue_wrapper),
-#else
-      m_device_mr(),
-      m_copy(),
-#endif
       m_cached_device_mr(
-          std::make_unique<::vecmem::binary_page_memory_resource>(m_device_mr)),
+          std::make_unique<::vecmem::binary_page_memory_resource>(
+              m_vecmem_objects.device_mr())),
       m_field_vec(parent.m_field_vec),
       m_field(parent.m_field),
       m_det_descr(parent.m_det_descr),
       m_device_det_descr(
           static_cast<silicon_detector_description::buffer::size_type>(
               m_det_descr.get().size()),
-          m_device_mr),
+          m_vecmem_objects.device_mr()),
       m_detector(parent.m_detector),
-      m_clusterization(memory_resource{*m_cached_device_mr, &m_host_mr}, m_copy,
-                       parent.m_clustering_config),
-      m_measurement_sorting(m_copy,
+      m_clusterization(memory_resource{*m_cached_device_mr, &m_host_mr},
+                       m_vecmem_objects.copy(), parent.m_clustering_config),
+      m_measurement_sorting(m_vecmem_objects.copy(),
                             parent.logger().cloneWithSuffix("MeasSortingAlg")),
       m_spacepoint_formation(memory_resource{*m_cached_device_mr, &m_host_mr},
-                             m_copy,
+                             m_vecmem_objects.copy(),
                              parent.logger().cloneWithSuffix("SpFormationAlg")),
       m_seeding(parent.m_finder_config, parent.m_grid_config,
                 parent.m_filter_config,
-                memory_resource{*m_cached_device_mr, &m_host_mr}, m_copy,
+                memory_resource{*m_cached_device_mr, &m_host_mr},
+                m_vecmem_objects.copy(),
                 parent.logger().cloneWithSuffix("SeedingAlg")),
       m_track_parameter_estimation(
-          memory_resource{*m_cached_device_mr, &m_host_mr}, m_copy,
+          memory_resource{*m_cached_device_mr, &m_host_mr},
+          m_vecmem_objects.copy(),
           parent.logger().cloneWithSuffix("TrackParamEstAlg")),
       m_finding(parent.m_finding_config,
-                memory_resource{*m_cached_device_mr, &m_host_mr}, m_copy,
+                memory_resource{*m_cached_device_mr, &m_host_mr},
+                m_vecmem_objects.copy(),
                 parent.logger().cloneWithSuffix("TrackFindingAlg")),
       m_fitting(parent.m_fitting_config,
-                memory_resource{*m_cached_device_mr, &m_host_mr}, m_copy,
+                memory_resource{*m_cached_device_mr, &m_host_mr},
+                m_vecmem_objects.copy(),
                 parent.logger().cloneWithSuffix("TrackFittingAlg")),
       m_clustering_config(parent.m_clustering_config),
       m_finder_config(parent.m_finder_config),
@@ -131,10 +128,13 @@ full_chain_algorithm::full_chain_algorithm(const full_chain_algorithm& parent)
       m_fitting_config(parent.m_fitting_config) {
 
     // Copy the detector (description) to the device.
-    m_copy(::vecmem::get_data(m_det_descr.get()), m_device_det_descr)->ignore();
+    m_vecmem_objects
+        .copy()(::vecmem::get_data(m_det_descr.get()), m_device_det_descr)
+        ->ignore();
     if (m_detector != nullptr) {
         m_device_detector = detray::get_buffer(detray::get_data(*m_detector),
-                                               m_device_mr, m_copy);
+                                               m_vecmem_objects.device_mr(),
+                                               m_vecmem_objects.copy());
         m_device_detector_view = detray::get_data(m_device_detector);
     }
 }
@@ -147,7 +147,7 @@ full_chain_algorithm::output_type full_chain_algorithm::operator()(
     // Create device copy of input collections
     edm::silicon_cell_collection::buffer cells_buffer(
         static_cast<unsigned int>(cells.size()), *m_cached_device_mr);
-    m_copy(::vecmem::get_data(cells), cells_buffer)->ignore();
+    m_vecmem_objects.copy()(::vecmem::get_data(cells), cells_buffer)->ignore();
 
     // Run the clusterization.
     const clusterization_algorithm::output_type measurements =
@@ -174,7 +174,7 @@ full_chain_algorithm::output_type full_chain_algorithm::operator()(
 
         // Copy a limited amount of result data back to the host.
         output_type result{&m_host_mr};
-        m_copy(track_states.headers, result)->wait();
+        m_vecmem_objects.copy()(track_states.headers, result)->wait();
         return result;
 
     }
@@ -184,7 +184,7 @@ full_chain_algorithm::output_type full_chain_algorithm::operator()(
 
         // Copy the measurements back to the host.
         measurement_collection_types::host measurements_host(&m_host_mr);
-        m_copy(measurements, measurements_host)->wait();
+        m_vecmem_objects.copy()(measurements, measurements_host)->wait();
 
         // Return an empty object.
         return {};
diff --git a/examples/run/alpaka/full_chain_algorithm.hpp b/examples/run/alpaka/full_chain_algorithm.hpp
index aed52c824c..7e6e1a35de 100644
--- a/examples/run/alpaka/full_chain_algorithm.hpp
+++ b/examples/run/alpaka/full_chain_algorithm.hpp
@@ -16,7 +16,7 @@
 #include "traccc/alpaka/seeding/spacepoint_formation_algorithm.hpp"
 #include "traccc/alpaka/seeding/track_params_estimation.hpp"
 #include "traccc/alpaka/utils/get_device_info.hpp"
-#include "traccc/alpaka/utils/get_vecmem_resource.hpp"
+#include "traccc/alpaka/utils/vecmem_objects.hpp"
 #include "traccc/clusterization/clustering_config.hpp"
 #include "traccc/edm/silicon_cell_collection.hpp"
 #include "traccc/edm/track_state.hpp"
@@ -33,6 +33,7 @@
 #include <vecmem/memory/binary_page_memory_resource.hpp>
 
 // System include(s).
+#include <functional>
 #include <memory>
 
 namespace traccc::alpaka {
@@ -120,19 +121,13 @@ class full_chain_algorithm
         const edm::silicon_cell_collection::host& cells) const override;
 
     private:
+    /// Alpaka Queue
+    traccc::alpaka::queue m_queue;
+    /// Alpaka Vecmem objects, to get the memory resources
+    traccc::alpaka::vecmem_objects m_vecmem_objects;
+
     /// Host memory resource
     ::vecmem::memory_resource& m_host_mr;
-
-#if defined(ALPAKA_ACC_SYCL_ENABLED)
-    /// The SYCL queue to use for the computations
-    ::sycl::queue m_queue;
-    vecmem::sycl::queue_wrapper m_queue_wrapper;
-#endif
-
-    /// Device memory resource
-    traccc::alpaka::vecmem_resources::device_memory_resource m_device_mr;
-    /// Memory copy object
-    traccc::alpaka::vecmem_resources::device_copy m_copy;
     /// Device caching memory resource
     std::unique_ptr<::vecmem::binary_page_memory_resource> m_cached_device_mr;
 
diff --git a/examples/run/alpaka/seeding_example_alpaka.cpp b/examples/run/alpaka/seeding_example_alpaka.cpp
index ab929d3909..fcd87a002b 100644
--- a/examples/run/alpaka/seeding_example_alpaka.cpp
+++ b/examples/run/alpaka/seeding_example_alpaka.cpp
@@ -10,7 +10,7 @@
 #include "traccc/alpaka/fitting/fitting_algorithm.hpp"
 #include "traccc/alpaka/seeding/seeding_algorithm.hpp"
 #include "traccc/alpaka/seeding/track_params_estimation.hpp"
-#include "traccc/alpaka/utils/get_vecmem_resource.hpp"
+#include "traccc/alpaka/utils/vecmem_objects.hpp"
 #include "traccc/definitions/common.hpp"
 #include "traccc/device/container_d2h_copy_alg.hpp"
 #include "traccc/device/container_h2d_copy_alg.hpp"
@@ -44,11 +44,6 @@
 #include "traccc/seeding/track_params_estimation.hpp"
 #include "traccc/utils/propagation.hpp"
 
-#ifdef ALPAKA_ACC_SYCL_ENABLED
-#include <sycl/sycl.hpp>
-#include <vecmem/utils/sycl/queue_wrapper.hpp>
-#endif
-
 // System include(s).
 #include <cmath>
 #include <exception>
@@ -80,22 +75,14 @@ int seq_run(const traccc::opts::track_seeding& seeding_opts,
     using device_fitter_type =
         traccc::kalman_fitter<rk_stepper_type, device_navigator_type>;
 
-#ifdef ALPAKA_ACC_SYCL_ENABLED
-    ::sycl::queue q;
-    vecmem::sycl::queue_wrapper qw{&q};
-    traccc::alpaka::vecmem_resources::device_copy copy(qw);
-    traccc::alpaka::vecmem_resources::host_memory_resource host_mr(qw);
-    traccc::alpaka::vecmem_resources::device_memory_resource device_mr(qw);
-    traccc::alpaka::vecmem_resources::managed_memory_resource mng_mr(qw);
-    traccc::memory_resource mr{device_mr, &host_mr};
-#else
-    traccc::alpaka::vecmem_resources::device_copy copy;
-    traccc::alpaka::vecmem_resources::host_memory_resource host_mr;
-    traccc::alpaka::vecmem_resources::device_memory_resource device_mr;
-    traccc::alpaka::vecmem_resources::managed_memory_resource mng_mr;
+    // Memory resources used by the application.
+    traccc::alpaka::queue queue;
+    traccc::alpaka::vecmem_objects vo(queue);
+
+    vecmem::memory_resource& host_mr = vo.host_mr();
+    vecmem::memory_resource& device_mr = vo.device_mr();
+    vecmem::memory_resource& mng_mr = vo.shared_mr();
     traccc::memory_resource mr{device_mr, &host_mr};
-#endif
-    vecmem::copy host_copy;
 
     // Performance writer
     traccc::seeding_performance_writer sd_performance_writer(
@@ -143,6 +130,9 @@ int seq_run(const traccc::opts::track_seeding& seeding_opts,
     traccc::default_detector::view det_view = detray::get_data(host_det);
 
     // Copy objects
+    vecmem::copy host_copy;
+    vecmem::copy& copy = vo.copy();
+
     traccc::device::container_d2h_copy_alg<
         traccc::track_candidate_container_types>
         track_candidate_d2h{mr, copy,
diff --git a/examples/run/alpaka/seq_example_alpaka.cpp b/examples/run/alpaka/seq_example_alpaka.cpp
index cdbbdfe82b..78470b2daa 100644
--- a/examples/run/alpaka/seq_example_alpaka.cpp
+++ b/examples/run/alpaka/seq_example_alpaka.cpp
@@ -13,7 +13,7 @@
 #include "traccc/alpaka/seeding/seeding_algorithm.hpp"
 #include "traccc/alpaka/seeding/spacepoint_formation_algorithm.hpp"
 #include "traccc/alpaka/seeding/track_params_estimation.hpp"
-#include "traccc/alpaka/utils/get_vecmem_resource.hpp"
+#include "traccc/alpaka/utils/vecmem_objects.hpp"
 #include "traccc/clusterization/clusterization_algorithm.hpp"
 #include "traccc/device/container_d2h_copy_alg.hpp"
 #include "traccc/efficiency/seeding_performance_writer.hpp"
@@ -63,20 +63,19 @@ int seq_run(const traccc::opts::detector& detector_opts,
     TRACCC_LOCAL_LOGGER(std::move(ilogger));
 
     // Memory resources used by the application.
-#ifdef ALPAKA_ACC_SYCL_ENABLED
-    ::sycl::queue q;
-    vecmem::sycl::queue_wrapper qw{&q};
-    traccc::alpaka::vecmem_resources::device_copy copy(qw);
-    traccc::alpaka::vecmem_resources::host_memory_resource host_mr(qw);
-    traccc::alpaka::vecmem_resources::device_memory_resource device_mr(qw);
-#else
-    traccc::alpaka::vecmem_resources::device_copy copy;
-    traccc::alpaka::vecmem_resources::host_memory_resource host_mr;
-    traccc::alpaka::vecmem_resources::device_memory_resource device_mr;
-#endif
+    traccc::alpaka::queue queue;
+    traccc::alpaka::vecmem_objects vo(queue);
+
+    vecmem::memory_resource& host_mr = vo.host_mr();
+    vecmem::memory_resource& device_mr = vo.device_mr();
     traccc::memory_resource mr{device_mr, &host_mr};
+
+    // Host copy object
     vecmem::copy host_copy;
 
+    // Device types used.
+    vecmem::copy& copy = vo.copy();
+
     // Construct the detector description object.
     traccc::silicon_detector_description::host host_det_descr{host_mr};
     traccc::io::read_detector_description(
diff --git a/examples/run/alpaka/throughput_mt.cpp b/examples/run/alpaka/throughput_mt.cpp
index 3c53a7e969..958ae518be 100644
--- a/examples/run/alpaka/throughput_mt.cpp
+++ b/examples/run/alpaka/throughput_mt.cpp
@@ -5,20 +5,17 @@
  * Mozilla Public License Version 2.0
  */
 
-// Project include(s).
-#include "traccc/alpaka/utils/get_vecmem_resource.hpp"
-
 // Local include(s).
 #include "../common/throughput_mt.hpp"
+
 #include "full_chain_algorithm.hpp"
 
 int main(int argc, char* argv[]) {
 
     // Execute the throughput test.
     static const bool use_host_caching = true;
-    return traccc::throughput_mt<
-        traccc::alpaka::full_chain_algorithm,
-        traccc::alpaka::vecmem_resources::host_memory_resource>(
+    return traccc::throughput_mt<traccc::alpaka::full_chain_algorithm,
+                                 vecmem::host_memory_resource>(
         "Multi-threaded Alpaka GPU throughput tests", argc, argv,
         use_host_caching);
 }
diff --git a/examples/run/alpaka/throughput_st.cpp b/examples/run/alpaka/throughput_st.cpp
index 4a9ecd033f..8c51cdf05e 100644
--- a/examples/run/alpaka/throughput_st.cpp
+++ b/examples/run/alpaka/throughput_st.cpp
@@ -5,20 +5,17 @@
  * Mozilla Public License Version 2.0
  */
 
-// Project include(s).
-#include "traccc/alpaka/utils/get_vecmem_resource.hpp"
-
 // Local include(s).
 #include "../common/throughput_st.hpp"
+
 #include "full_chain_algorithm.hpp"
 
 int main(int argc, char* argv[]) {
 
     // Execute the throughput test.
     static const bool use_host_caching = true;
-    return traccc::throughput_st<
-        traccc::alpaka::full_chain_algorithm,
-        traccc::alpaka::vecmem_resources::host_memory_resource>(
+    return traccc::throughput_st<traccc::alpaka::full_chain_algorithm,
+                                 vecmem::host_memory_resource>(
         "Single-threaded Alpaka GPU throughput tests", argc, argv,
         use_host_caching);
 }
diff --git a/tests/alpaka/alpaka_basic.cpp b/tests/alpaka/alpaka_basic.cpp
index 083e5ad713..8814283558 100644
--- a/tests/alpaka/alpaka_basic.cpp
+++ b/tests/alpaka/alpaka_basic.cpp
@@ -6,20 +6,22 @@
  * Mozilla Public License Version 2.0
  */
 
-// Alpaka include(s).
-#include <alpaka/alpaka.hpp>
-#include <alpaka/example/ExampleDefaultAcc.hpp>
+// Project include(s).
+#include "traccc/alpaka/utils/vecmem_objects.hpp"
+
+// VecMem include(s).
 #include <vecmem/containers/data/vector_buffer.hpp>
 #include <vecmem/containers/device_vector.hpp>
 #include <vecmem/containers/vector.hpp>
-#include <vecmem/memory/host_memory_resource.hpp>
-#include <vecmem/utils/copy.hpp>
 
-#include "traccc/alpaka/utils/get_vecmem_resource.hpp"
+// Alpaka include(s).
+#include <alpaka/alpaka.hpp>
+#include <alpaka/example/ExampleDefaultAcc.hpp>
 
 // GoogleTest include(s).
 #include <gtest/gtest.h>
 
+// Standard include(s).
 #include <cstdint>
 #include <iostream>
 
@@ -121,7 +123,7 @@ GTEST_TEST(AlpakaBasic, VecMemOp) {
     auto const devAcc = getDevByIdx(platformAcc, 0u);
 
     using Queue = Queue<Acc, Blocking>;
-    auto queue = Queue{devAcc};
+    auto alpaka_queue = Queue{devAcc};
 
     uint32_t n = 10000;
 
@@ -131,16 +133,12 @@ GTEST_TEST(AlpakaBasic, VecMemOp) {
     using WorkDiv = WorkDivMembers<Dim, Idx>;
     auto workDiv = WorkDiv{blocksPerGrid, threadsPerBlock, elementsPerThread};
 
-#ifdef ALPAKA_ACC_SYCL_ENABLED
-    ::sycl::queue q;
-    vecmem::sycl::queue_wrapper qw{&q};
-    traccc::alpaka::vecmem_resources::device_copy vm_copy(qw);
-#else
-    traccc::alpaka::vecmem_resources::device_copy vm_copy;
-#endif
+    traccc::alpaka::queue traccc_queue(&alpaka_queue);
+    traccc::alpaka::vecmem_objects vo(traccc_queue);
 
-    traccc::alpaka::vecmem_resources::host_memory_resource host_mr;
-    traccc::alpaka::vecmem_resources::device_memory_resource device_mr;
+    vecmem::memory_resource& host_mr = vo.host_mr();
+    vecmem::memory_resource& device_mr = vo.device_mr();
+    vecmem::copy& vm_copy = vo.copy();
 
     vecmem::vector<float> host_vector{n, &host_mr};
 
@@ -152,12 +150,9 @@ GTEST_TEST(AlpakaBasic, VecMemOp) {
     std::cout << "Using alpaka accelerator: " << alpaka::getAccName<Acc>()
               << std::endl;
 
-    // Create a device for host for memory allocation, using the first CPU
-    // available
-    auto const platformDevCpu = alpaka::Platform<DevCpu>{};
-    auto devHost = getDevByIdx(platformDevCpu, 0u);
-
-    alpaka::exec<Acc>(queue, workDiv, VecMemOpKernel{}, data_dev_vec_buf);
+    alpaka::exec<Acc>(alpaka_queue, workDiv, VecMemOpKernel{},
+                      data_dev_vec_buf);
+    alpaka::wait(alpaka_queue);
 
     vm_copy(device_buffer, host_buffer, vecmem::copy::type::device_to_host)
         ->wait();
diff --git a/tests/alpaka/test_cca.cpp b/tests/alpaka/test_cca.cpp
index f2543e1458..30ee9a2759 100644
--- a/tests/alpaka/test_cca.cpp
+++ b/tests/alpaka/test_cca.cpp
@@ -5,21 +5,20 @@
  * Mozilla Public License Version 2.0
  */
 
-#include <gtest/gtest.h>
-
-#include <functional>
-#include <vecmem/memory/host_memory_resource.hpp>
-
-#ifdef ALPAKA_ACC_SYCL_ENABLED
-#include <sycl/sycl.hpp>
-#include <vecmem/utils/sycl/queue_wrapper.hpp>
-#endif
-
+// Local include(s).
 #include "tests/cca_test.hpp"
+
+// Project include(s).
 #include "traccc/alpaka/clusterization/clusterization_algorithm.hpp"
-#include "traccc/alpaka/utils/get_vecmem_resource.hpp"
+#include "traccc/alpaka/utils/vecmem_objects.hpp"
 #include "traccc/geometry/silicon_detector_description.hpp"
 
+// GoogleTest include(s).
+#include <gtest/gtest.h>
+
+// Standard include(s).
+#include <functional>
+
 namespace {
 
 // template <TAccTag>
@@ -29,17 +28,12 @@ cca_function_t get_f_with(traccc::clustering_config cfg) {
         std::map<traccc::geometry_id, vecmem::vector<traccc::measurement>>
             result;
 
-#ifdef ALPAKA_ACC_SYCL_ENABLED
-        ::sycl::queue q;
-        vecmem::sycl::queue_wrapper qw{&q};
-        traccc::alpaka::vecmem_resources::host_memory_resource host_mr(qw);
-        traccc::alpaka::vecmem_resources::device_copy copy(qw);
-        traccc::alpaka::vecmem_resources::device_memory_resource device_mr;
-#else
-        traccc::alpaka::vecmem_resources::host_memory_resource host_mr;
-        traccc::alpaka::vecmem_resources::device_copy copy;
-        traccc::alpaka::vecmem_resources::device_memory_resource device_mr;
-#endif
+        traccc::alpaka::queue queue;
+        traccc::alpaka::vecmem_objects vo(queue);
+
+        vecmem::memory_resource& host_mr = vo.host_mr();
+        vecmem::memory_resource& device_mr = vo.device_mr();
+        vecmem::copy& copy = vo.copy();
 
         traccc::alpaka::clusterization_algorithm cc({device_mr}, copy, cfg);
 
diff --git a/tests/hip/test_thrust.hip b/tests/hip/test_thrust.hip
index 0e9243fbe7..65d8efad59 100644
--- a/tests/hip/test_thrust.hip
+++ b/tests/hip/test_thrust.hip
@@ -44,7 +44,8 @@ TEST(thrust, sort) {
 
     thrust::sort(thrust::device, device_vector.begin(), device_vector.end());
 
-    copy(device_buffer, host_buffer, vecmem::copy::type::device_to_host);
+    copy(device_buffer, host_buffer, vecmem::copy::type::device_to_host)
+        ->wait();
 
     ASSERT_EQ(host_vector[0], 1);
     ASSERT_EQ(host_vector[1], 2);
@@ -66,7 +67,8 @@ TEST(thrust, scan) {
     thrust::inclusive_scan(thrust::device, device_vector.begin(),
                            device_vector.end(), device_vector.begin());
 
-    copy(device_buffer, host_buffer, vecmem::copy::type::device_to_host);
+    copy(device_buffer, host_buffer, vecmem::copy::type::device_to_host)
+        ->wait();
 
     ASSERT_EQ(host_vector[0], 3);
     ASSERT_EQ(host_vector[1], 5);
@@ -89,7 +91,8 @@ TEST(thrust, fill) {
     thrust::fill(thrust::device, device_vector.begin(), device_vector.end(),
                  112);
 
-    copy(device_buffer, host_buffer, vecmem::copy::type::device_to_host);
+    copy(device_buffer, host_buffer, vecmem::copy::type::device_to_host)
+        ->wait();
 
     ASSERT_EQ(host_vector[0], 112);
     ASSERT_EQ(host_vector[1], 112);


Reviews:
user: login: CrossR
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-02T11:50:37Z
user: login: krasznaa
body: I like how things look, but let's do one other kind of cleanup as part of this PR!

Now that `traccc::alpaka` takes care of everything internally, practically all executables should become "simple C\+\+ code". I.e.

https://github.com/acts-project/traccc/blob/main/examples/run/alpaka/CMakeLists.txt#L12-L13

should no longer be needed **I believe**. (But you'll need to test this.)
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-05-07T13:07:56Z
user: login: CrossR
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-07T17:01:40Z
user: login: CrossR
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T08:31:00Z
user: login: CrossR
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T09:00:29Z
user: login: krasznaa
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-08T09:26:53Z
user: login: CrossR
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-08T11:28:22Z
user: login: krasznaa
body: Sorry to continue the unpleasantness like this. :frowning: But I'd really like to get the behaviour of `traccc::alpaka::queue` "correct" from the start. :wink:
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-05-12T11:59:48Z
user: login: CrossR
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-12T15:07:14Z
user: login: krasznaa
body: I like it. Hopefully the CI does too. 🤞 
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-13T06:50:08Z
user: login: krasznaa
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-05-13T07:16:02Z
user: login: CrossR
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-13T10:51:38Z
user: login: krasznaa
body: To translate: I think `traccc::alpaka::queue::impl::m_device` should just be removed. If anything depends on it at the moment (which I don't believe is the case...), that should be removed. As I don't think that variable has any useful meaning.
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-05-13T13:01:28Z
user: login: CrossR
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-05-13T13:20:41Z
user: login: krasznaa
body: Let's get it in finally.
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-15T12:37:06Z

Review comments:
diff_hunk: @@ -5,20 +5,17 @@
  * Mozilla Public License Version 2.0
  */
 
-// Project include(s).
-#include "traccc/alpaka/utils/get_vecmem_resource.hpp"
-
 // Local include(s).
 #include "../common/throughput_mt.hpp"
+
 #include "full_chain_algorithm.hpp"
 
 int main(int argc, char* argv[]) {
 
     // Execute the throughput test.
     static const bool use_host_caching = true;
-    return traccc::throughput_mt<
-        traccc::alpaka::full_chain_algorithm,
-        traccc::alpaka::vecmem_resources::host_memory_resource>(
+    return traccc::throughput_mt<traccc::alpaka::full_chain_algorithm,
+                                 vecmem::host_memory_resource>(
path: examples/run/alpaka/throughput_mt.cpp
user: login: CrossR
body: This is the only bit I'm still not 100% sure on the impact of.

I.e. we now always use the default `vecmem::host_memory_resource`, rather than `vecmem::cuda::host_memory_resource` etc as appropriate.

I guess there is some performance impact around missing out on the pinning the going via `cudaMallocHost` gives? Not sure on the most appropriate way to surface this type though, or if it is easier to change the interface instead.
created_at: 2025-05-02T11:50:37Z
author_association: CONTRIBUTOR
diff_hunk: @@ -120,19 +121,17 @@ class full_chain_algorithm
         const edm::silicon_cell_collection::host& cells) const override;
 
     private:
+    /// Alpaka Queue
+    traccc::alpaka::queue m_queue;
+    /// Alpaka Vecmem objects, to get the memory resources
+    traccc::alpaka::vecmem_objects m_vecmem_objects;
+
     /// Host memory resource
     ::vecmem::memory_resource& m_host_mr;
-
-#if defined(ALPAKA_ACC_SYCL_ENABLED)
-    /// The SYCL queue to use for the computations
-    ::sycl::queue m_queue;
-    vecmem::sycl::queue_wrapper m_queue_wrapper;
-#endif
-
     /// Device memory resource
-    traccc::alpaka::vecmem_resources::device_memory_resource m_device_mr;
+    ::vecmem::memory_resource& m_device_mr;
     /// Memory copy object
-    traccc::alpaka::vecmem_resources::device_copy m_copy;
+    mutable std::reference_wrapper<::vecmem::copy> m_copy;
path: examples/run/alpaka/full_chain_algorithm.hpp
user: login: krasznaa
body: Now you have access to the underlying memory resource and copy objects through `m_vecmem_objects`. I think you could get rid of all these variables.
created_at: 2025-05-07T12:58:31Z
author_association: MEMBER
diff_hunk: @@ -5,20 +5,17 @@
  * Mozilla Public License Version 2.0
  */
 
-// Project include(s).
-#include "traccc/alpaka/utils/get_vecmem_resource.hpp"
-
 // Local include(s).
 #include "../common/throughput_mt.hpp"
+
 #include "full_chain_algorithm.hpp"
 
 int main(int argc, char* argv[]) {
 
     // Execute the throughput test.
     static const bool use_host_caching = true;
-    return traccc::throughput_mt<
-        traccc::alpaka::full_chain_algorithm,
-        traccc::alpaka::vecmem_resources::host_memory_resource>(
+    return traccc::throughput_mt<traccc::alpaka::full_chain_algorithm,
+                                 vecmem::host_memory_resource>(
path: examples/run/alpaka/throughput_mt.cpp
user: login: krasznaa
body: The throughput executables could indeed do with a bit of a re-design. But in this PR I think this is the pragmatic thing to do. Let's just accept the small performance degradation, and use unpinned host memory in all cases for now.
created_at: 2025-05-07T13:01:04Z
author_association: MEMBER
diff_hunk: @@ -15,7 +15,24 @@
 #include <vecmem/memory/host_memory_resource.hpp>
 #include <vecmem/utils/copy.hpp>
 
-#include "traccc/alpaka/utils/get_vecmem_resource.hpp"
+// VecMem include(s).
path: tests/alpaka/alpaka_basic.cpp
user: login: krasznaa
body: I'm not sure why you went this way here. :confused:

This source file does need to remain an "Alpaka source file", but you could still make use of the new class for figuring out which VecMem types to use. :thinking:
created_at: 2025-05-07T13:03:28Z
author_association: MEMBER
diff_hunk: @@ -15,7 +15,24 @@
 #include <vecmem/memory/host_memory_resource.hpp>
 #include <vecmem/utils/copy.hpp>
 
-#include "traccc/alpaka/utils/get_vecmem_resource.hpp"
+// VecMem include(s).
path: tests/alpaka/alpaka_basic.cpp
user: login: CrossR
body: The bit I'm struggling with here, is keeping all the types consistent.

All the Alpaka types used here (Dim, Idx, Acc, Queue, WorkDiv) are private, so they could technically be different to the ones used in `traccc::alpaka`.

That means whilst I can totally setup a wrapped queue and a `vecmem_object` object to pull vecmem types out of, I couldn't think of a good way of keeping things in sync between the two things. The chosen accelerator and queue type (blocking vs not) could be made different in `traccc::alpaka` and here.

It is entirely possible that I am missing some smart way of getting around that though... since this was a one-off test, I decided to go with the dumb way for now.


created_at: 2025-05-07T17:01:40Z
author_association: CONTRIBUTOR
diff_hunk: @@ -120,19 +121,17 @@ class full_chain_algorithm
         const edm::silicon_cell_collection::host& cells) const override;
 
     private:
+    /// Alpaka Queue
+    traccc::alpaka::queue m_queue;
+    /// Alpaka Vecmem objects, to get the memory resources
+    traccc::alpaka::vecmem_objects m_vecmem_objects;
+
     /// Host memory resource
     ::vecmem::memory_resource& m_host_mr;
-
-#if defined(ALPAKA_ACC_SYCL_ENABLED)
-    /// The SYCL queue to use for the computations
-    ::sycl::queue m_queue;
-    vecmem::sycl::queue_wrapper m_queue_wrapper;
-#endif
-
     /// Device memory resource
-    traccc::alpaka::vecmem_resources::device_memory_resource m_device_mr;
+    ::vecmem::memory_resource& m_device_mr;
     /// Memory copy object
-    traccc::alpaka::vecmem_resources::device_copy m_copy;
+    mutable std::reference_wrapper<::vecmem::copy> m_copy;
path: examples/run/alpaka/full_chain_algorithm.hpp
user: login: CrossR
body: Done for all but `host_mr` (as it is passed into the algorithm and may be cached or not), and `m_cached_device_mr`.
created_at: 2025-05-08T08:31:00Z
author_association: CONTRIBUTOR
diff_hunk: @@ -38,7 +35,7 @@ add_library( traccc_examples_alpaka STATIC
    "full_chain_algorithm.hpp"
    "full_chain_algorithm.cpp" )
 target_link_libraries( traccc_examples_alpaka
-   PUBLIC alpaka::alpaka vecmem::core detray::core detray::detectors
+   PUBLIC vecmem::core detray::core detray::detectors
path: examples/run/alpaka/CMakeLists.txt
user: login: CrossR
body: `alpaka` calls now removed from the `examples` CMakeLists.
created_at: 2025-05-08T09:00:29Z
author_association: CONTRIBUTOR
diff_hunk: @@ -15,7 +15,24 @@
 #include <vecmem/memory/host_memory_resource.hpp>
 #include <vecmem/utils/copy.hpp>
 
-#include "traccc/alpaka/utils/get_vecmem_resource.hpp"
+// VecMem include(s).
path: tests/alpaka/alpaka_basic.cpp
user: login: krasznaa
body: I don't quite understand your points about `Dim`, etc., but I think the problem here is that `traccc::alpaka::queue` needs to become a little smarter. :thinking: I think it will need to be like [vecmem::sycl::queue_wrapper](https://github.com/acts-project/vecmem/blob/main/sycl/include/vecmem/utils/sycl/queue_wrapper.hpp). (At the same time, at one point we should figure out if we want/need these `_wrapper` postfixes. I'm really not sure...)

The main thing being that `traccc::alpaka::queue` should be able to both own its personal `::alpaka::Queue` object, or be given one from the outside. So that this test's code could become:

```c++
auto alpakaQueue = Queue{devAcc};
traccc::alpaka::queue tracccQueue{&alpakaQueue};
traccc::alpaka::vecmem_objects vo{tracccQueue};
```

This way the logic of choosing the VecMem objects could still be taken from `traccc::alpaka` all the time. Even when the client code wants to use its own Alpaka queue/code.
created_at: 2025-05-08T09:26:53Z
author_association: MEMBER
diff_hunk: @@ -15,7 +15,24 @@
 #include <vecmem/memory/host_memory_resource.hpp>
 #include <vecmem/utils/copy.hpp>
 
-#include "traccc/alpaka/utils/get_vecmem_resource.hpp"
+// VecMem include(s).
path: tests/alpaka/alpaka_basic.cpp
user: login: CrossR
body: I was over-complicating things, and worrying about what happens if the `Acc` definition in this file and `traccc::alpaka` become out of sync, so what would happen if one decided they were using a CUDA device and one decided they were using a CPU device.

I think in reality, that couldn't end up happening, so it shouldn't be an issue.
I've added the sort of wrapper you linked to now, and that seems happy.
created_at: 2025-05-08T11:28:21Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,63 @@
+/**
+ * traccc library, part of the ACTS project (R&D line)
+ *
+ * (c) 2025 CERN for the benefit of the ACTS project
+ *
+ * Mozilla Public License Version 2.0
+ */
+
+#pragma once
+
+// System include(s).
+#include <cstddef>
+#include <limits>
+#include <memory>
+
+namespace traccc::alpaka {
+
+/// Owning wrapper around @c ::alpaka::Queue
+class queue {
+
+    public:
+    /// Invalid/default device identifier
+    static constexpr std::size_t INVALID_DEVICE =
+        std::numeric_limits<std::size_t>::max();
+
+    /// Construct a new stream (possibly for a specified device)
+    explicit queue(std::size_t device = INVALID_DEVICE);
+
+    /// Wrap an existing ::alpaka::Queue object
+    ///
+    /// Without taking ownership of it!
+    ///
+    queue(void* input_queue);
path: device/alpaka/include/traccc/alpaka/utils/queue.hpp
user: login: krasznaa
body: To be **very** safe, you could add `explicit` to this constructor. Just as how SonarCloud recommends.
created_at: 2025-05-12T11:49:31Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,70 @@
+/**
+ * traccc library, part of the ACTS project (R&D line)
+ *
+ * (c) 2025 CERN for the benefit of the ACTS project
+ *
+ * Mozilla Public License Version 2.0
+ */
+
+// Local include(s).
+#include "traccc/alpaka/utils/queue.hpp"
+
+#include "utils.hpp"
+
+// Alpaka include(s).
+#include <alpaka/alpaka.hpp>
+
+namespace traccc::alpaka {
+
+struct queue::impl {
+
+    /// Constructor
+    /// @param device The device to create the queue for
+    explicit impl(std::size_t device)
+        : m_device(device == INVALID_DEVICE ? 0 : device),
+          m_queue(::alpaka::getDevByIdx(::alpaka::Platform<Acc>{}, m_device)) {}
+
+    /// The device the queue is created for
+    std::size_t m_device;
+
+    /// The real Alpaka queue object
+    Queue m_queue;
+
+};  // struct queue::impl
+
+queue::queue(std::size_t device) : m_impl{std::make_unique<impl>(device)} {}
+
+queue::queue(void* input_queue)
+    : m_impl{std::make_unique<impl>(INVALID_DEVICE)} {
+
+    // Copy the queue pointer
+    m_impl->m_queue = *static_cast<Queue*>(input_queue);
path: device/alpaka/src/utils/queue.cpp
user: login: krasznaa
body: :thinking: This is not exactly how I imagined it...

This interface, with a `void*` pointer suggests that it just wraps around an existing `alpaka::Queue`. Not make a copy of it, and then use the copy from there on.

I rather imagined making the `impl` struct something like this:

https://github.com/acts-project/vecmem/blob/main/sycl/src/utils/sycl/queue_wrapper.sycl#L20-L25

**Not** with a `shared_ptr`, but rather with a `unique_ptr`. (Since this class, unlike `vecmem::sycl::queue_wrapper`, cannot be copied.) So the main thing is that there would be both a bare pointer, and a unique pointer inside of `impl`. Which would be set up according to how the main class was created.
created_at: 2025-05-12T11:57:21Z
author_association: MEMBER
diff_hunk: @@ -38,7 +35,7 @@ add_library( traccc_examples_alpaka STATIC
    "full_chain_algorithm.hpp"
    "full_chain_algorithm.cpp" )
 target_link_libraries( traccc_examples_alpaka
-   PUBLIC alpaka::alpaka vecmem::core detray::core detray::detectors
+   PUBLIC vecmem::core detray::core detray::detectors
path: examples/run/alpaka/CMakeLists.txt
user: login: krasznaa
body: :+1: 
created_at: 2025-05-12T11:57:54Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,70 @@
+/**
+ * traccc library, part of the ACTS project (R&D line)
+ *
+ * (c) 2025 CERN for the benefit of the ACTS project
+ *
+ * Mozilla Public License Version 2.0
+ */
+
+// Local include(s).
+#include "traccc/alpaka/utils/queue.hpp"
+
+#include "utils.hpp"
+
+// Alpaka include(s).
+#include <alpaka/alpaka.hpp>
+
+namespace traccc::alpaka {
+
+struct queue::impl {
+
+    /// Constructor
+    /// @param device The device to create the queue for
+    explicit impl(std::size_t device)
+        : m_device(device == INVALID_DEVICE ? 0 : device),
+          m_queue(::alpaka::getDevByIdx(::alpaka::Platform<Acc>{}, m_device)) {}
+
+    /// The device the queue is created for
+    std::size_t m_device;
+
+    /// The real Alpaka queue object
+    Queue m_queue;
+
+};  // struct queue::impl
+
+queue::queue(std::size_t device) : m_impl{std::make_unique<impl>(device)} {}
+
+queue::queue(void* input_queue)
+    : m_impl{std::make_unique<impl>(INVALID_DEVICE)} {
+
+    // Copy the queue pointer
+    m_impl->m_queue = *static_cast<Queue*>(input_queue);
path: device/alpaka/src/utils/queue.cpp
user: login: CrossR
body: I *think* I've done this now.

Also updated this new constructor to pull out the correct device number.
created_at: 2025-05-12T15:07:14Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,73 @@
+/**
+ * traccc library, part of the ACTS project (R&D line)
+ *
+ * (c) 2025 CERN for the benefit of the ACTS project
+ *
+ * Mozilla Public License Version 2.0
+ */
+
+// Local include(s).
+#include "traccc/alpaka/utils/queue.hpp"
+
+#include "utils.hpp"
+
+// Alpaka include(s).
+#include <alpaka/alpaka.hpp>
+
+namespace traccc::alpaka {
+
+struct queue::impl {
+    /// The device the queue is created for
+    std::size_t m_device{INVALID_DEVICE};
+    /// Bare pointer to the wrapped queue object
+    Queue* m_queue = nullptr;
+    /// Unique pointer to the managed Queue object
+    std::unique_ptr<Queue> m_managedQueue;
+};  // struct queue::impl
+
+queue::queue(std::size_t device) : m_impl{std::make_unique<impl>()} {
+
+    m_impl->m_device = device == INVALID_DEVICE ? 0 : device;
+    m_impl->m_managedQueue = std::make_unique<Queue>(
+        ::alpaka::getDevByIdx(::alpaka::Platform<Acc>{}, m_impl->m_device));
+    m_impl->m_queue = m_impl->m_managedQueue.get();
+}
+
+queue::queue(void* input_queue) : m_impl{std::make_unique<impl>()} {
+
+    assert(input_queue != nullptr);
+    m_impl->m_queue = static_cast<Queue*>(input_queue);
+    m_impl->m_device =
+        ::alpaka::getNativeHandle(::alpaka::getDev(*m_impl->m_queue));
path: device/alpaka/src/utils/queue.cpp
user: login: krasznaa
body: Argh... I didn't check, I thought the failure was because of an infrastructure issue.

But this is a new bug. I believe `::alpaka::getDev(...)` gets exactly the integer that you're after here. The `::alpaka::getNativeHandle(...)` "surrounding" should be removed.

But of course test it before pushing my suggestion. 😉
created_at: 2025-05-13T07:15:55Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,73 @@
+/**
+ * traccc library, part of the ACTS project (R&D line)
+ *
+ * (c) 2025 CERN for the benefit of the ACTS project
+ *
+ * Mozilla Public License Version 2.0
+ */
+
+// Local include(s).
+#include "traccc/alpaka/utils/queue.hpp"
+
+#include "utils.hpp"
+
+// Alpaka include(s).
+#include <alpaka/alpaka.hpp>
+
+namespace traccc::alpaka {
+
+struct queue::impl {
+    /// The device the queue is created for
+    std::size_t m_device{INVALID_DEVICE};
+    /// Bare pointer to the wrapped queue object
+    Queue* m_queue = nullptr;
+    /// Unique pointer to the managed Queue object
+    std::unique_ptr<Queue> m_managedQueue;
+};  // struct queue::impl
+
+queue::queue(std::size_t device) : m_impl{std::make_unique<impl>()} {
+
+    m_impl->m_device = device == INVALID_DEVICE ? 0 : device;
+    m_impl->m_managedQueue = std::make_unique<Queue>(
+        ::alpaka::getDevByIdx(::alpaka::Platform<Acc>{}, m_impl->m_device));
+    m_impl->m_queue = m_impl->m_managedQueue.get();
+}
+
+queue::queue(void* input_queue) : m_impl{std::make_unique<impl>()} {
+
+    assert(input_queue != nullptr);
+    m_impl->m_queue = static_cast<Queue*>(input_queue);
+    m_impl->m_device =
+        ::alpaka::getNativeHandle(::alpaka::getDev(*m_impl->m_queue));
path: device/alpaka/src/utils/queue.cpp
user: login: CrossR
body: Looking into this, I think the way I am doing it is correct (`getDev` returns the actual `alpaka::DevUniformCudaHipRt` or `alpaka::DevGenericSycl` etc, rather than the device num)...but only for CUDA + HIP.

For SYCL, `getNativeHandle(dev)` returns the `sycl::device` + `sycl::context`, rather than the device int (I guess because the "device" in use is a lot harder to distinguish, with the larger set of devices it could be), so I may just need to special case SYCL to pull out the `sycl::info::device::vendor_id` or whatever the appropriate ID is there from the `sycl::device`. 
created_at: 2025-05-13T10:51:38Z
author_association: CONTRIBUTOR
diff_hunk: @@ -0,0 +1,81 @@
+/**
+ * traccc library, part of the ACTS project (R&D line)
+ *
+ * (c) 2025 CERN for the benefit of the ACTS project
+ *
+ * Mozilla Public License Version 2.0
+ */
+
+// Local include(s).
+#include "traccc/alpaka/utils/queue.hpp"
+
+#include "utils.hpp"
+
+// Alpaka include(s).
+#include <alpaka/alpaka.hpp>
+
+namespace traccc::alpaka {
+
+struct queue::impl {
+    /// The device the queue is created for
+    std::size_t m_device{INVALID_DEVICE};
+    /// Bare pointer to the wrapped queue object
+    Queue* m_queue = nullptr;
+    /// Unique pointer to the managed Queue object
+    std::unique_ptr<Queue> m_managedQueue;
+};  // struct queue::impl
+
+queue::queue(std::size_t device) : m_impl{std::make_unique<impl>()} {
+
+    m_impl->m_device = device == INVALID_DEVICE ? 0 : device;
+    m_impl->m_managedQueue = std::make_unique<Queue>(
+        ::alpaka::getDevByIdx(::alpaka::Platform<Acc>{}, m_impl->m_device));
+    m_impl->m_queue = m_impl->m_managedQueue.get();
+}
+
+queue::queue(void* input_queue) : m_impl{std::make_unique<impl>()} {
+
+    assert(input_queue != nullptr);
+    m_impl->m_queue = static_cast<Queue*>(input_queue);
+
+#if defined(ALPAKA_ACC_SYCL_ENABLED)
+    auto sycl_device =
+        ::alpaka::getNativeHandle(::alpaka::getDev(*m_impl->m_queue)).first;
+    m_impl->m_device = static_cast<std::size_t>(
+        sycl_device.get_info<::sycl::info::device::vendor_id>());
+#else
+    m_impl->m_device = static_cast<std::size_t>(
+        ::alpaka::getNativeHandle(::alpaka::getDev(*m_impl->m_queue)));
+#endif
path: device/alpaka/src/utils/queue.cpp
user: login: krasznaa
body: 🤔 What's the point of this `m_device` variable in the end? Why do we need it? It seems to me that Alpaka itself doesn't care about this variable a whole lot either.

To step back a bit: I think we're doing something silly with both CUDA(HIP) and SYCL in this code. The `std::size_t` index that Alpaka uses to choose a concrete device from all the available devices on a given platform is fairly close to how CUDA(HIP) defines a device. But it's still not the same. Alpaka, I believe on purpose, defined its own device identifier as an `std::size_t`, while CUDA(HIP) defines it as an `unsigned int`.

But the `vendor_id` from SYCL absolutely has nothing to do with the way that "device 0" (as an example) would be chosen from the available SYCL devices.

So to get back to my first question: Why do we need to provide this info from `traccc::alpaka::queue`, if clearly `::alpaka::Queue` doesn't provide such an ID itself in any convenient way? Even if we want to make a copy of an `::alpaka::Queue` (which we currently don't), we'd have better options for doing that than to use this integer. 🤔
created_at: 2025-05-13T13:00:13Z
author_association: MEMBER
diff_hunk: @@ -0,0 +1,81 @@
+/**
+ * traccc library, part of the ACTS project (R&D line)
+ *
+ * (c) 2025 CERN for the benefit of the ACTS project
+ *
+ * Mozilla Public License Version 2.0
+ */
+
+// Local include(s).
+#include "traccc/alpaka/utils/queue.hpp"
+
+#include "utils.hpp"
+
+// Alpaka include(s).
+#include <alpaka/alpaka.hpp>
+
+namespace traccc::alpaka {
+
+struct queue::impl {
+    /// The device the queue is created for
+    std::size_t m_device{INVALID_DEVICE};
+    /// Bare pointer to the wrapped queue object
+    Queue* m_queue = nullptr;
+    /// Unique pointer to the managed Queue object
+    std::unique_ptr<Queue> m_managedQueue;
+};  // struct queue::impl
+
+queue::queue(std::size_t device) : m_impl{std::make_unique<impl>()} {
+
+    m_impl->m_device = device == INVALID_DEVICE ? 0 : device;
+    m_impl->m_managedQueue = std::make_unique<Queue>(
+        ::alpaka::getDevByIdx(::alpaka::Platform<Acc>{}, m_impl->m_device));
+    m_impl->m_queue = m_impl->m_managedQueue.get();
+}
+
+queue::queue(void* input_queue) : m_impl{std::make_unique<impl>()} {
+
+    assert(input_queue != nullptr);
+    m_impl->m_queue = static_cast<Queue*>(input_queue);
+
+#if defined(ALPAKA_ACC_SYCL_ENABLED)
+    auto sycl_device =
+        ::alpaka::getNativeHandle(::alpaka::getDev(*m_impl->m_queue)).first;
+    m_impl->m_device = static_cast<std::size_t>(
+        sycl_device.get_info<::sycl::info::device::vendor_id>());
+#else
+    m_impl->m_device = static_cast<std::size_t>(
+        ::alpaka::getNativeHandle(::alpaka::getDev(*m_impl->m_queue)));
+#endif
path: device/alpaka/src/utils/queue.cpp
user: login: CrossR
body: It was mostly to have some way to programatically surface "This specific device is in use" (alongside the more user facing "get device name as a string" method elsewhere).

That said, I think as you've said if a user does want more than just a basic understanding of the device, we can assume they'll include Alpaka and get things that way, and be in control of it themselves. I'll push up with it removed in a mo.
created_at: 2025-05-13T13:20:41Z
author_association: CONTRIBUTOR

PR comments:
user: login: CrossR
created_at: 2025-05-02T14:18:55Z
body: Tested with my async branch too, and after a few minor changes to the Queue using code, works there too.


author_association: CONTRIBUTOR
user: login: sonarqubecloud[bot]
created_at: 2025-05-15T12:40:03Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=acts-project_traccc&pullRequest=960) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [6 New issues](https://sonarcloud.io/project/issues?id=acts-project_traccc&pullRequest=960&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=acts-project_traccc&pullRequest=960&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=acts-project_traccc&pullRequest=960&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Coverage on New Code](https://sonarcloud.io/component_measures?id=acts-project_traccc&pullRequest=960&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=acts-project_traccc&pullRequest=960&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=acts-project_traccc&pullRequest=960)


author_association: NONE