xref: /petsc/src/sys/objects/device/interface/petscdevice_interface_internal.hpp (revision 0e6b6b5985dd9b1172860d21fb88bd3966bf7c54)
1*0e6b6b59SJacob Faibussowitsch #ifndef PETSCDEVICE_INTERFACE_INTERNAL_HPP
2*0e6b6b59SJacob Faibussowitsch #define PETSCDEVICE_INTERFACE_INTERNAL_HPP
3*0e6b6b59SJacob Faibussowitsch 
4*0e6b6b59SJacob Faibussowitsch #include <petsc/private/deviceimpl.h>
5*0e6b6b59SJacob Faibussowitsch 
6*0e6b6b59SJacob Faibussowitsch #include <petsc/private/cpp/utility.hpp>    // std::pair
7*0e6b6b59SJacob Faibussowitsch #include <petsc/private/cpp/functional.hpp> //std::equal_to
8*0e6b6b59SJacob Faibussowitsch 
9*0e6b6b59SJacob Faibussowitsch #include <unordered_map>
10*0e6b6b59SJacob Faibussowitsch #include <unordered_set>
11*0e6b6b59SJacob Faibussowitsch 
12*0e6b6b59SJacob Faibussowitsch #if PetscDefined(USE_DEBUG) && PetscDefined(USE_INFO)
13*0e6b6b59SJacob Faibussowitsch #define PETSC_USE_DEBUG_AND_INFO  1
14*0e6b6b59SJacob Faibussowitsch #define PetscDebugInfo(dctx, ...) PetscInfo(dctx, __VA_ARGS__)
15*0e6b6b59SJacob Faibussowitsch #else
16*0e6b6b59SJacob Faibussowitsch #define PetscDebugInfo(dctx, ...) 0
17*0e6b6b59SJacob Faibussowitsch #endif
18*0e6b6b59SJacob Faibussowitsch 
19*0e6b6b59SJacob Faibussowitsch // this file contains functions needed to bridge the gap between dcontext.cxx and device.cxx
20*0e6b6b59SJacob Faibussowitsch // but are not useful enough to put in the impl header
21*0e6b6b59SJacob Faibussowitsch PETSC_INTERN PetscErrorCode PetscDeviceContextSetDefaultDeviceForType_Internal(PetscDeviceContext, PetscDeviceType);
22*0e6b6b59SJacob Faibussowitsch PETSC_INTERN PetscErrorCode PetscDeviceContextSetRootDeviceType_Internal(PetscDeviceType);
23*0e6b6b59SJacob Faibussowitsch PETSC_INTERN PetscErrorCode PetscDeviceContextSetRootStreamType_Internal(PetscStreamType);
24*0e6b6b59SJacob Faibussowitsch PETSC_INTERN PetscErrorCode PetscDeviceContextSyncClearMap_Internal(PetscDeviceContext);
25*0e6b6b59SJacob Faibussowitsch PETSC_INTERN PetscErrorCode PetscDeviceContextCheckNotOrphaned_Internal(PetscDeviceContext);
26*0e6b6b59SJacob Faibussowitsch 
27*0e6b6b59SJacob Faibussowitsch // open up namespace std to specialize equal_to for unordered_map
28*0e6b6b59SJacob Faibussowitsch namespace std {
29*0e6b6b59SJacob Faibussowitsch 
30*0e6b6b59SJacob Faibussowitsch template <>
31*0e6b6b59SJacob Faibussowitsch struct equal_to<PetscDeviceContext> {
32*0e6b6b59SJacob Faibussowitsch #if PETSC_CPP_VERSION <= 17
33*0e6b6b59SJacob Faibussowitsch   using result_type          = bool;
34*0e6b6b59SJacob Faibussowitsch   using first_argument_type  = PetscDeviceContext;
35*0e6b6b59SJacob Faibussowitsch   using second_argument_type = PetscDeviceContext;
36*0e6b6b59SJacob Faibussowitsch #endif
37*0e6b6b59SJacob Faibussowitsch 
38*0e6b6b59SJacob Faibussowitsch   constexpr bool operator()(const PetscDeviceContext &x, const PetscDeviceContext &y) const noexcept {
39*0e6b6b59SJacob Faibussowitsch     return PetscObjectCast(x)->id == PetscObjectCast(y)->id;
40*0e6b6b59SJacob Faibussowitsch   }
41*0e6b6b59SJacob Faibussowitsch };
42*0e6b6b59SJacob Faibussowitsch 
43*0e6b6b59SJacob Faibussowitsch } // namespace std
44*0e6b6b59SJacob Faibussowitsch 
45*0e6b6b59SJacob Faibussowitsch namespace {
46*0e6b6b59SJacob Faibussowitsch 
47*0e6b6b59SJacob Faibussowitsch struct CxxData {
48*0e6b6b59SJacob Faibussowitsch   struct parent_type {
49*0e6b6b59SJacob Faibussowitsch     PetscObjectId    id    = 0;
50*0e6b6b59SJacob Faibussowitsch     PetscObjectState state = 0;
51*0e6b6b59SJacob Faibussowitsch 
52*0e6b6b59SJacob Faibussowitsch     constexpr parent_type() noexcept = default;
53*0e6b6b59SJacob Faibussowitsch 
54*0e6b6b59SJacob Faibussowitsch     constexpr explicit parent_type(PetscDeviceContext dctx) noexcept : parent_type(PetscObjectCast(dctx)->id, PetscObjectCast(dctx)->state) { }
55*0e6b6b59SJacob Faibussowitsch 
56*0e6b6b59SJacob Faibussowitsch     constexpr parent_type(const parent_type &) noexcept                     = default;
57*0e6b6b59SJacob Faibussowitsch     PETSC_CONSTEXPR_14 parent_type &operator=(const parent_type &) noexcept = default;
58*0e6b6b59SJacob Faibussowitsch     constexpr parent_type(parent_type &&) noexcept                          = default;
59*0e6b6b59SJacob Faibussowitsch     PETSC_CONSTEXPR_14 parent_type &operator=(parent_type &&) noexcept      = default;
60*0e6b6b59SJacob Faibussowitsch 
61*0e6b6b59SJacob Faibussowitsch   private:
62*0e6b6b59SJacob Faibussowitsch     // make this private, we do not want to accept any old id and state pairing
63*0e6b6b59SJacob Faibussowitsch     constexpr parent_type(PetscObjectId id_, PetscObjectState state_) noexcept : id(id_), state(state_) { }
64*0e6b6b59SJacob Faibussowitsch   };
65*0e6b6b59SJacob Faibussowitsch 
66*0e6b6b59SJacob Faibussowitsch   using upstream_type = std::unordered_map<PetscDeviceContext, parent_type>;
67*0e6b6b59SJacob Faibussowitsch   using dep_type      = std::unordered_set<PetscObjectId>;
68*0e6b6b59SJacob Faibussowitsch 
69*0e6b6b59SJacob Faibussowitsch   // double check we didn't specialize for no reason
70*0e6b6b59SJacob Faibussowitsch   static_assert(std::is_same<typename upstream_type::key_equal, std::equal_to<PetscDeviceContext>>::value, "");
71*0e6b6b59SJacob Faibussowitsch 
72*0e6b6b59SJacob Faibussowitsch   upstream_type upstream{};
73*0e6b6b59SJacob Faibussowitsch   dep_type      deps{};
74*0e6b6b59SJacob Faibussowitsch 
75*0e6b6b59SJacob Faibussowitsch   PETSC_NODISCARD PetscErrorCode clear() noexcept;
76*0e6b6b59SJacob Faibussowitsch };
77*0e6b6b59SJacob Faibussowitsch 
78*0e6b6b59SJacob Faibussowitsch inline PetscErrorCode CxxData::clear() noexcept {
79*0e6b6b59SJacob Faibussowitsch   PetscFunctionBegin;
80*0e6b6b59SJacob Faibussowitsch   PetscCallCXX(this->upstream.clear());
81*0e6b6b59SJacob Faibussowitsch   PetscCallCXX(this->deps.clear());
82*0e6b6b59SJacob Faibussowitsch   PetscFunctionReturn(0);
83*0e6b6b59SJacob Faibussowitsch }
84*0e6b6b59SJacob Faibussowitsch 
85*0e6b6b59SJacob Faibussowitsch PETSC_NODISCARD inline CxxData *CxxDataCast(PetscDeviceContext dctx) noexcept {
86*0e6b6b59SJacob Faibussowitsch   return static_cast<CxxData *>(PetscObjectCast(dctx)->cpp);
87*0e6b6b59SJacob Faibussowitsch }
88*0e6b6b59SJacob Faibussowitsch 
89*0e6b6b59SJacob Faibussowitsch /*
90*0e6b6b59SJacob Faibussowitsch   needed because PetscInitialize() needs to also query these options to set the defaults. Since
91*0e6b6b59SJacob Faibussowitsch   it does not yet have a PetscDeviceContext to call this with, the actual options queries are
92*0e6b6b59SJacob Faibussowitsch   abstracted out, so you can call this without one.
93*0e6b6b59SJacob Faibussowitsch */
94*0e6b6b59SJacob Faibussowitsch inline PetscErrorCode PetscDeviceContextQueryOptions_Internal(PetscOptionItems *PetscOptionsObject, std::pair<PetscDeviceType, PetscBool> &deviceType, std::pair<PetscStreamType, PetscBool> &streamType) {
95*0e6b6b59SJacob Faibussowitsch   auto dtype = static_cast<PetscInt>(deviceType.first);
96*0e6b6b59SJacob Faibussowitsch   auto stype = static_cast<PetscInt>(streamType.first);
97*0e6b6b59SJacob Faibussowitsch 
98*0e6b6b59SJacob Faibussowitsch   PetscFunctionBegin;
99*0e6b6b59SJacob Faibussowitsch   /* set the device type first */
100*0e6b6b59SJacob Faibussowitsch   PetscCall(PetscOptionsEList("-device_context_device_type", "Underlying PetscDevice", "PetscDeviceContextSetDevice", PetscDeviceTypes, PETSC_DEVICE_MAX, PetscDeviceTypes[dtype], &dtype, &deviceType.second));
101*0e6b6b59SJacob Faibussowitsch   PetscCall(PetscOptionsEList("-device_context_stream_type", "PetscDeviceContext PetscStreamType", "PetscDeviceContextSetStreamType", PetscStreamTypes, PETSC_STREAM_MAX, PetscStreamTypes[stype], &stype, &streamType.second));
102*0e6b6b59SJacob Faibussowitsch   deviceType.first = PetscDeviceTypeCast(dtype);
103*0e6b6b59SJacob Faibussowitsch   streamType.first = PetscStreamTypeCast(stype);
104*0e6b6b59SJacob Faibussowitsch   PetscFunctionReturn(0);
105*0e6b6b59SJacob Faibussowitsch }
106*0e6b6b59SJacob Faibussowitsch 
107*0e6b6b59SJacob Faibussowitsch } // anonymous namespace
108*0e6b6b59SJacob Faibussowitsch 
109*0e6b6b59SJacob Faibussowitsch #endif // PETSCDEVICE_INTERFACE_INTERNAL_HPP
110