xref: /petsc/src/sys/objects/device/interface/petscdevice_interface_internal.hpp (revision d71ae5a4db6382e7f06317b8d368875286fe9008)
10e6b6b59SJacob Faibussowitsch #ifndef PETSCDEVICE_INTERFACE_INTERNAL_HPP
20e6b6b59SJacob Faibussowitsch #define PETSCDEVICE_INTERFACE_INTERNAL_HPP
30e6b6b59SJacob Faibussowitsch 
40e6b6b59SJacob Faibussowitsch #include <petsc/private/deviceimpl.h>
50e6b6b59SJacob Faibussowitsch 
60e6b6b59SJacob Faibussowitsch #include <petsc/private/cpp/utility.hpp>    // std::pair
70e6b6b59SJacob Faibussowitsch #include <petsc/private/cpp/functional.hpp> //std::equal_to
80e6b6b59SJacob Faibussowitsch 
90e6b6b59SJacob Faibussowitsch #include <unordered_map>
100e6b6b59SJacob Faibussowitsch #include <unordered_set>
110e6b6b59SJacob Faibussowitsch 
120e6b6b59SJacob Faibussowitsch #if PetscDefined(USE_DEBUG) && PetscDefined(USE_INFO)
130e6b6b59SJacob Faibussowitsch   #define PETSC_USE_DEBUG_AND_INFO  1
140e6b6b59SJacob Faibussowitsch   #define PetscDebugInfo(dctx, ...) PetscInfo(dctx, __VA_ARGS__)
150e6b6b59SJacob Faibussowitsch #else
160e6b6b59SJacob Faibussowitsch   #define PetscDebugInfo(dctx, ...) 0
170e6b6b59SJacob Faibussowitsch #endif
180e6b6b59SJacob Faibussowitsch 
190e6b6b59SJacob Faibussowitsch // this file contains functions needed to bridge the gap between dcontext.cxx and device.cxx
200e6b6b59SJacob Faibussowitsch // but are not useful enough to put in the impl header
210e6b6b59SJacob Faibussowitsch PETSC_INTERN PetscErrorCode PetscDeviceContextSetDefaultDeviceForType_Internal(PetscDeviceContext, PetscDeviceType);
220e6b6b59SJacob Faibussowitsch PETSC_INTERN PetscErrorCode PetscDeviceContextSetRootDeviceType_Internal(PetscDeviceType);
230e6b6b59SJacob Faibussowitsch PETSC_INTERN PetscErrorCode PetscDeviceContextSetRootStreamType_Internal(PetscStreamType);
240e6b6b59SJacob Faibussowitsch PETSC_INTERN PetscErrorCode PetscDeviceContextSyncClearMap_Internal(PetscDeviceContext);
250e6b6b59SJacob Faibussowitsch PETSC_INTERN PetscErrorCode PetscDeviceContextCheckNotOrphaned_Internal(PetscDeviceContext);
260e6b6b59SJacob Faibussowitsch 
270e6b6b59SJacob Faibussowitsch // open up namespace std to specialize equal_to for unordered_map
28*d71ae5a4SJacob Faibussowitsch namespace std
29*d71ae5a4SJacob Faibussowitsch {
300e6b6b59SJacob Faibussowitsch 
310e6b6b59SJacob Faibussowitsch template <>
320e6b6b59SJacob Faibussowitsch struct equal_to<PetscDeviceContext> {
330e6b6b59SJacob Faibussowitsch #if PETSC_CPP_VERSION <= 17
340e6b6b59SJacob Faibussowitsch   using result_type          = bool;
350e6b6b59SJacob Faibussowitsch   using first_argument_type  = PetscDeviceContext;
360e6b6b59SJacob Faibussowitsch   using second_argument_type = PetscDeviceContext;
370e6b6b59SJacob Faibussowitsch #endif
380e6b6b59SJacob Faibussowitsch 
39*d71ae5a4SJacob Faibussowitsch   constexpr bool operator()(const PetscDeviceContext &x, const PetscDeviceContext &y) const noexcept { return PetscObjectCast(x)->id == PetscObjectCast(y)->id; }
400e6b6b59SJacob Faibussowitsch };
410e6b6b59SJacob Faibussowitsch 
420e6b6b59SJacob Faibussowitsch } // namespace std
430e6b6b59SJacob Faibussowitsch 
44*d71ae5a4SJacob Faibussowitsch namespace
45*d71ae5a4SJacob Faibussowitsch {
460e6b6b59SJacob Faibussowitsch 
470e6b6b59SJacob Faibussowitsch struct CxxData {
480e6b6b59SJacob Faibussowitsch   struct parent_type {
490e6b6b59SJacob Faibussowitsch     PetscObjectId    id    = 0;
500e6b6b59SJacob Faibussowitsch     PetscObjectState state = 0;
510e6b6b59SJacob Faibussowitsch 
520e6b6b59SJacob Faibussowitsch     constexpr parent_type() noexcept = default;
530e6b6b59SJacob Faibussowitsch 
540e6b6b59SJacob Faibussowitsch     constexpr explicit parent_type(PetscDeviceContext dctx) noexcept : parent_type(PetscObjectCast(dctx)->id, PetscObjectCast(dctx)->state) { }
550e6b6b59SJacob Faibussowitsch 
560e6b6b59SJacob Faibussowitsch     constexpr parent_type(const parent_type &) noexcept                     = default;
570e6b6b59SJacob Faibussowitsch     PETSC_CONSTEXPR_14 parent_type &operator=(const parent_type &) noexcept = default;
580e6b6b59SJacob Faibussowitsch     constexpr parent_type(parent_type &&) noexcept                          = default;
590e6b6b59SJacob Faibussowitsch     PETSC_CONSTEXPR_14 parent_type &operator=(parent_type &&) noexcept      = default;
600e6b6b59SJacob Faibussowitsch 
610e6b6b59SJacob Faibussowitsch   private:
620e6b6b59SJacob Faibussowitsch     // make this private, we do not want to accept any old id and state pairing
630e6b6b59SJacob Faibussowitsch     constexpr parent_type(PetscObjectId id_, PetscObjectState state_) noexcept : id(id_), state(state_) { }
640e6b6b59SJacob Faibussowitsch   };
650e6b6b59SJacob Faibussowitsch 
660e6b6b59SJacob Faibussowitsch   using upstream_type = std::unordered_map<PetscDeviceContext, parent_type>;
670e6b6b59SJacob Faibussowitsch   using dep_type      = std::unordered_set<PetscObjectId>;
680e6b6b59SJacob Faibussowitsch 
690e6b6b59SJacob Faibussowitsch   // double check we didn't specialize for no reason
700e6b6b59SJacob Faibussowitsch   static_assert(std::is_same<typename upstream_type::key_equal, std::equal_to<PetscDeviceContext>>::value, "");
710e6b6b59SJacob Faibussowitsch 
720e6b6b59SJacob Faibussowitsch   upstream_type upstream{};
730e6b6b59SJacob Faibussowitsch   dep_type      deps{};
740e6b6b59SJacob Faibussowitsch 
750e6b6b59SJacob Faibussowitsch   PETSC_NODISCARD PetscErrorCode clear() noexcept;
760e6b6b59SJacob Faibussowitsch };
770e6b6b59SJacob Faibussowitsch 
78*d71ae5a4SJacob Faibussowitsch inline PetscErrorCode CxxData::clear() noexcept
79*d71ae5a4SJacob Faibussowitsch {
800e6b6b59SJacob Faibussowitsch   PetscFunctionBegin;
810e6b6b59SJacob Faibussowitsch   PetscCallCXX(this->upstream.clear());
820e6b6b59SJacob Faibussowitsch   PetscCallCXX(this->deps.clear());
830e6b6b59SJacob Faibussowitsch   PetscFunctionReturn(0);
840e6b6b59SJacob Faibussowitsch }
850e6b6b59SJacob Faibussowitsch 
86*d71ae5a4SJacob Faibussowitsch PETSC_NODISCARD inline CxxData *CxxDataCast(PetscDeviceContext dctx) noexcept
87*d71ae5a4SJacob Faibussowitsch {
880e6b6b59SJacob Faibussowitsch   return static_cast<CxxData *>(PetscObjectCast(dctx)->cpp);
890e6b6b59SJacob Faibussowitsch }
900e6b6b59SJacob Faibussowitsch 
910e6b6b59SJacob Faibussowitsch /*
920e6b6b59SJacob Faibussowitsch   needed because PetscInitialize() needs to also query these options to set the defaults. Since
930e6b6b59SJacob Faibussowitsch   it does not yet have a PetscDeviceContext to call this with, the actual options queries are
940e6b6b59SJacob Faibussowitsch   abstracted out, so you can call this without one.
950e6b6b59SJacob Faibussowitsch */
96*d71ae5a4SJacob Faibussowitsch inline PetscErrorCode PetscDeviceContextQueryOptions_Internal(PetscOptionItems *PetscOptionsObject, std::pair<PetscDeviceType, PetscBool> &deviceType, std::pair<PetscStreamType, PetscBool> &streamType)
97*d71ae5a4SJacob Faibussowitsch {
980e6b6b59SJacob Faibussowitsch   auto dtype = static_cast<PetscInt>(deviceType.first);
990e6b6b59SJacob Faibussowitsch   auto stype = static_cast<PetscInt>(streamType.first);
1000e6b6b59SJacob Faibussowitsch 
1010e6b6b59SJacob Faibussowitsch   PetscFunctionBegin;
1020e6b6b59SJacob Faibussowitsch   /* set the device type first */
1030e6b6b59SJacob Faibussowitsch   PetscCall(PetscOptionsEList("-device_context_device_type", "Underlying PetscDevice", "PetscDeviceContextSetDevice", PetscDeviceTypes, PETSC_DEVICE_MAX, PetscDeviceTypes[dtype], &dtype, &deviceType.second));
1040e6b6b59SJacob Faibussowitsch   PetscCall(PetscOptionsEList("-device_context_stream_type", "PetscDeviceContext PetscStreamType", "PetscDeviceContextSetStreamType", PetscStreamTypes, PETSC_STREAM_MAX, PetscStreamTypes[stype], &stype, &streamType.second));
1050e6b6b59SJacob Faibussowitsch   deviceType.first = PetscDeviceTypeCast(dtype);
1060e6b6b59SJacob Faibussowitsch   streamType.first = PetscStreamTypeCast(stype);
1070e6b6b59SJacob Faibussowitsch   PetscFunctionReturn(0);
1080e6b6b59SJacob Faibussowitsch }
1090e6b6b59SJacob Faibussowitsch 
1100e6b6b59SJacob Faibussowitsch } // anonymous namespace
1110e6b6b59SJacob Faibussowitsch 
1120e6b6b59SJacob Faibussowitsch #endif // PETSCDEVICE_INTERFACE_INTERNAL_HPP
113