diff --git a/doc/sphinx/src/using.rst b/doc/sphinx/src/using.rst index db78e1e8..909611ea 100644 --- a/doc/sphinx/src/using.rst +++ b/doc/sphinx/src/using.rst @@ -83,6 +83,14 @@ with `to` being the target location, from being the source location, and size_by the size of the transfer in bytes. This has implemenatations for kokkos and none portability strategies. +It may be useful to query the execution space, for example to know where memory needs to be copied. +To this end, a compile-time constant boolean can be queried: + +.. cpp:var:: PortsOfCall::EXECUTION_IS_HOST + +which is `true` if the host execution space can trivially access device memory space. For example, +for `PORTABILITY_STRATEGY_CUDA`, `PortsOfCall::EXECUTION_IS_HOST == false`. + portable_errors.hpp ^^^^^^^^^^^^^^^^^^^^ diff --git a/ports-of-call/portability.hpp b/ports-of-call/portability.hpp index ae8e322f..4f27d806 100644 --- a/ports-of-call/portability.hpp +++ b/ports-of-call/portability.hpp @@ -91,6 +91,18 @@ typedef float Real; typedef double Real; #endif +namespace PortsOfCall{ +// compile-time constant to check if execution of memory space +// will be done on the host or is offloaded +#if defined(PORTABILITY_STRATEGY_KOKKOS) +inline constexpr bool EXECUTION_IS_HOST{Kokkos::SpaceAccessibility::accessible}; +#elif defined(PORTABILITY_STRATEGY_CUDA) +inline constexpr bool EXECUTION_IS_HOST{false}; +#else +inline constexpr bool EXECUTION_IS_HOST{true}; +#endif +} // PortsOfCall + template void portableCopyToDevice(T * const to, T const * const from, size_t const size_bytes) { auto const length = size_bytes / sizeof(T); diff --git a/test/test_portsofcall.cpp b/test/test_portsofcall.cpp index 732ea83b..8fb615f4 100644 --- a/test/test_portsofcall.cpp +++ b/test/test_portsofcall.cpp @@ -18,6 +18,22 @@ #define CATCH_CONFIG_RUNNER #include "catch2/catch.hpp" +TEST_CASE("EXECUTION_IS_HOST is set correctly", + "[PortsOfCall]") { + // testing this is maybe nontrivial? + auto isHost = PortsOfCall::EXECUTION_IS_HOST; + +#if defined(PORTABILITY_STRATEGY_KOKKOS) + auto checkHost = std::is_same::value; + REQUIRE( isHost == checkHost ); +#elif defined(PORTABILITY_STRATEGY_CUDA) + REQUIRE( isHost == false ); +#else + REQUIRE( isHost == true ); +#endif + +} + // this test is lifted directly from `spiner`; // and there appears to be a significant amount of // ports-of-call testing done there.