ScopeGuard#
Defined in header <Kokkos_Core.hpp>
Usage:
Kokkos::ScopeGuard guard(argc, argv);
Kokkos::ScopeGuard guard(Kokkos::InitializationSettings() // (since 3.7)
.set_map_device_id_by("random")
.set_num_threads(1));
ScopeGuard is a class which ensure thats Kokkos::initialize and
Kokkos::finalize are called correctly even in the presence of unhandled
exceptions.
It calls Kokkos::intialize with the provided arguments in the
constructor and Kokkos::finalize in the destructor.
WARNING: change of behavior in version 3.7 (see note below)
Interface#
class ScopeGuard {
public:
ScopeGuard(ScopeGuard const&) = delete;
ScopeGuard(ScopeGuard&&) = delete;
ScopeGuard& operator=(ScopeGuard const&) = delete;
ScopeGuard& operator=(ScopeGuard&&) = delete;
ScopeGuard(int& argc, char* argv[]); // (until 3.7)
ScopeGuard(InitArguments const& arguments = InitArguments()); // (until 3.7)
template <class... Args>
ScopeGuard(Args&&... args) { // (since 3.7)
// possible implementation
initialize(std::forward<Args>(args)...);
}
~ScopeGuard() {
// possible implementation
finalize();
}
Parameters#
argc: number of command line argumentsargv: array of character pointers to null-terminated strings storing the command line argumentsarguments:structobject with valid initialization argumentsargs: arguments to pass toKokkos::initialize
Note that all of the parameters above are passed to the Kokkos::initialize called internally. See Kokkos::initialize for more details.
Notes#
Since Kokkos version 3.7, ScopeGuard unconditionally forwards the provided
arguments to Kokkos::initialize, which means they have the same
preconditions. Until version 3.7, ScopeGuard was calling
Kokkos::initialize in its constructor only if Kokkos::is_initialized() was
false, and it was calling Kokkos::finalize in its destructor only if it
called Kokkos::initialize in its constructor.
We dropped support for the old behavior. If you think you really need it, you may do:
auto guard = std::unique_ptr<Kokkos::ScopeGuard>(
Kokkos::is_initialized() ? new Kokkos::ScopeGuard() : nullptr);
or
auto guard = Kokkos::is_initialized() ? std::make_optional<Kokkos::ScopeGuard>()
: std::nullopt;
with C++17. This will work regardless of the Kokkos version.
Example#
int main(int argc, char* argv[]) {
Kokkos::ScopeGuard guard(argc, argv);
Kokkos::View<double*> my_view("my_view", 10);
// my_view destructor called before Kokkos::finalize
// ScopeGuard destructor called, calls Kokkos::finalize
}