Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kokkos::Serial::is_initialized always true #1184

Closed
ibaned opened this issue Oct 25, 2017 · 10 comments
Closed

Kokkos::Serial::is_initialized always true #1184

ibaned opened this issue Oct 25, 2017 · 10 comments
Labels
Bug Broken / incorrect code; it could be Kokkos' responsibility, or others’ (e.g., Trilinos)
Milestone

Comments

@ibaned
Copy link
Contributor

ibaned commented Oct 25, 2017

I have a library that does

bool do_finalize = false;
void my_initialize() {
  if (!Kokkos::DefaultExecutionSpace::is_initialized()) {
    Kokkos::initialize();
    do_finalize = true;
  }
}
void my_finalize() {
  if (do_finalize) Kokkos::finalize();
}

The problem is that Kokkos::Serial::is_initialized() is hardcoded to always return true (actually, the int 1, which is also inconsistent with the bool return types of other exec spaces).
Until Kokkos::is_initialized exists (#1060), this is the only way I know to properly protect calls to Kokkos::initialize within downstream library initialize calls.
Furthermore, Kokkos::Serial actually does manage scratch memory, so if its finalize method is not called then memory is leaked and my tests fail under Valgrind.

Edit: downstream*

@ibaned ibaned added the Bug Broken / incorrect code; it could be Kokkos' responsibility, or others’ (e.g., Trilinos) label Oct 25, 2017
ibaned added a commit that referenced this issue Oct 25, 2017
Change this function to return a boolean
which actually reflects the state of
initialize/finalize calls.
Also remove the calls to Profiling::initialize,
because those are already handled in Kokkos::initialize.
[#1184]
ibaned added a commit to sandialabs/omega_h that referenced this issue Oct 25, 2017
@mhoemmen
Copy link
Contributor

Huh, this is good to know. I've been simplifying how Tpetra initializes Kokkos, and due to #1060, my changes would have used the initialization status of the default execution space as a proxy for Kokkos' initialization state. Good to know that Kokkos::Serial isn't quite right.

@ibaned
Copy link
Contributor Author

ibaned commented Oct 25, 2017

@mhoemmen yea this really bugs me. I opened a pull request (#1185) to fix this, but we're in the middle of a promotion, so I don't know when it'll get merged.

@mhoemmen
Copy link
Contributor

@ibaned I'm tempted to apply it to Trilinos first, and reply if necessary until it gets merged in to Kokkos master. Would you object to this, post review?

@ibaned
Copy link
Contributor Author

ibaned commented Oct 25, 2017

@mhoemmen hopefully the Kokkos team can discuss this a bit at our noon meeting today, and come up with a plan. I'm all for applying it ASAP. If we decide we don't want to disrupt the promotion too much, we can patch it onto Trilinos using the checkin script either before or after the new Kokkos snapshot.

@dsunder
Copy link
Contributor

dsunder commented Oct 25, 2017

The global Kokkos::is_initialized() works correctly (it is on the current develop branch waiting to be push to master with the current promotion). The individual execution space initialize/finalize are being rewritten to call the global initialize/finalize and in version 3 of Kokkos they will be move to the Kokkos::Impl namespace.

The main difficulty in replacing the individual execution space initialize/finalize with the global stems from trying to reinitialize the Cuda execution space. The OpenMP, Threads, and Serial execution spaces can be safely reinitialized. I haven't tested the OpenMPTarget, Qthreads, or ROCm backends.

For example consider the following code

Kokkos::OpenMP::initialize(nt); // calls Kokkos::initialize(), Cuda initialized to GPU 0
Kokkos::Cuda::initialize(1); // Problematic: tries to reinitialize Cuda to GPU 1

A better way of doing this is to not call the individuals initializes at all.

Kokkos::InitArguments args;
args.num_threads = nt;
args.device_id = 1;
Kokkos::initialize(args);

@ibaned
Copy link
Contributor Author

ibaned commented Oct 25, 2017

@dsunder does Kokkos::is_initialized work correctly even when only the Serial space is enabled, i.e. does it not rely on the broken Serial::is_initialized ?

@dsunder
Copy link
Contributor

dsunder commented Oct 25, 2017

The global Kokkos::is_initialized currently only checks if the global Kokkos::initialize(...) has been called.

@ibaned
Copy link
Contributor Author

ibaned commented Oct 25, 2017

That works for my purposes! Thanks

ibaned added a commit to ibaned/Trilinos that referenced this issue Oct 27, 2017
Kokkos::Serial::is_initialized always
returned one, which breaks the way that
libraries decide to call Kokkos::initialize
and Kokkos::finalize, causing memory leaks.
I am patching this in Trilinos immediately
because the Kokkos promotion is taking too long.
Once the Kokkos promotion is done, users
are encouraged to instead call the long-awaited
Kokkos::is_initialized function instead.
@crtrott
Copy link
Member

crtrott commented Oct 29, 2017

Looks like this broke our nightlies

@crtrott
Copy link
Member

crtrott commented Oct 29, 2017

I believe what needs to happen is that kokkos initialize initializes serial always if it is configure time enabled, ie even if openmp is on

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Bug Broken / incorrect code; it could be Kokkos' responsibility, or others’ (e.g., Trilinos)
Projects
None yet
Development

No branches or pull requests

4 participants