Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:09:37

0001 //------------------------------- -*- C++ -*- -------------------------------//
0002 // Copyright Celeritas contributors: see top-level COPYRIGHT file for details
0003 // SPDX-License-Identifier: (Apache-2.0 OR MIT)
0004 //---------------------------------------------------------------------------//
0005 //! \file corecel/data/CollectionMirror.hh
0006 //---------------------------------------------------------------------------//
0007 #pragma once
0008 
0009 #include <utility>
0010 
0011 #include "corecel/Assert.hh"
0012 #include "corecel/Types.hh"
0013 #include "corecel/sys/Device.hh"
0014 
0015 #include "ParamsDataInterface.hh"
0016 
0017 namespace celeritas
0018 {
0019 //---------------------------------------------------------------------------//
0020 /*!
0021  * Helper class for copying setup-time Collection groups to host and device.
0022  *
0023  * This should generally be an implementation detail of Params classes, which
0024  * are constructed on host and must have the same data both on host and device.
0025  * The template `P` must be a `FooData` class that:
0026  * - Is templated on ownership and memory space
0027  * - Has a templated assignment operator to copy from one space to another
0028  * - Has a boolean operator returning whether it's in a valid state.
0029  *
0030  * On assignment, it will copy the data to the device if the GPU is enabled.
0031  *
0032  * Example:
0033  * \code
0034  * class FooParams
0035  * {
0036  *   public:
0037  *     using CollectionDeviceRef = FooData<Ownership::const_reference,
0038  *                                         MemSpace::device>;
0039  *
0040  *     const CollectionDeviceRef& device_ref() const
0041  *     {
0042  *         return data_.device_ref();
0043  *     }
0044  *   private:
0045  *     CollectionMirror<FooData> data_;
0046  * };
0047  * \endcode
0048  */
0049 template<template<Ownership, MemSpace> class P>
0050 class CollectionMirror final : public ParamsDataInterface<P>
0051 {
0052   public:
0053     //!@{
0054     //! \name Type aliases
0055     using HostValue = celeritas::HostVal<P>;
0056     using HostRef = celeritas::HostCRef<P>;
0057     using DeviceRef = celeritas::DeviceCRef<P>;
0058     //!@}
0059 
0060   public:
0061     //! Default constructor leaves in an "unassigned" state
0062     CollectionMirror() = default;
0063 
0064     // Construct from host data
0065     explicit inline CollectionMirror(HostValue&& host);
0066 
0067     //! Whether the data is assigned
0068     explicit operator bool() const { return static_cast<bool>(host_); }
0069 
0070     //! Access data on host
0071     HostRef const& host_ref() const final { return host_ref_; }
0072 
0073     //! Access data on device
0074     DeviceRef const& device_ref() const final { return device_ref_; }
0075 
0076     using ParamsDataInterface<P>::ref;
0077 
0078   private:
0079     HostValue host_;
0080     HostRef host_ref_;
0081     P<Ownership::value, MemSpace::device> device_;
0082     DeviceRef device_ref_;
0083 };
0084 
0085 //---------------------------------------------------------------------------//
0086 // INLINE DEFINITIONS
0087 //---------------------------------------------------------------------------//
0088 /*!
0089  * Construct with defaults.
0090  */
0091 template<template<Ownership, MemSpace> class P>
0092 CollectionMirror<P>::CollectionMirror(HostValue&& host)
0093     : host_(std::move(host))
0094 {
0095     CELER_EXPECT(host_);
0096     host_ref_ = host_;
0097     if (celeritas::device())
0098     {
0099         // Copy data to device and save reference
0100         device_ = host_;
0101         device_ref_ = device_;
0102     }
0103 }
0104 
0105 //---------------------------------------------------------------------------//
0106 }  // namespace celeritas