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

Fix 1571 (CMake variable & detection of MPI CUDA awareness) #1602

Closed
wants to merge 6 commits into from

Conversation

mhoemmen
Copy link
Contributor

@mhoemmen mhoemmen commented Aug 14, 2017

@trilinos/tpetra Hi all! I wrote a PR that does the following:

  1. Defines a CMake variable, Tpetra_ASSUME_CUDA_AWARE_MPI, for whether Tpetra may assume that the MPI implementation is CUDA aware.
  2. Attempts to detect the default value of this variable (this currently only works with OpenMPI; it currently safely assumes OFF for other MPI implementations).
  3. Enforces CUDA_VERSION >= 7.5.

I took particular care to avoid breaking the cross-compilation case. The PR explicitly checks CMAKE_CROSSCOMPILING; if ON, Tpetra does not attempt to run executables. This is relevant because I know users who do cross-compilation with CUDA builds right now.

I welcome feedback! My only concern is that the PR forces Tpetra to decide whether MPI is CUDA aware at configure time. Some MPI implementations, like MVAPICH (see http://mvapich.cse.ohio-state.edu/userguide/gdr/2.2/ ), let users control this at run time, by setting an environment variable. This means that Tpetra may also need run-time environment variable control. However, we can always add that feature later. The CMake option is still useful, because it could determine the environment variable's default value. Thus, I think the PR is fine as it stands.

Mark Hoemmen added 3 commits August 13, 2017 21:19
@trilinos/tpetra If building with CUDA, explicitly enforce that
CUDA_VERSION be at least 7.5.  See #1278 for details.

Also, state CUDA_VERSION requirement explicitly in Tpetra's release
notes (packages/tpetra/ReleaseNotes.txt).
@trilinos/tpetra Add a CMake option Tpetra_ASSUME_CUDA_AWARE_MPI, with
associated macro TPETRA_ASSUME_CUDA_AWARE_MPI defined in
TpetraCore_config.h.  If the CMake option is ON, Tpetra may assume
that the MPI implementation it uses is CUDA aware.  See #1571 for
discussion, and #1088 for an application.

The option currently defaults to OFF.  #1571 requires that we actually
have a test for this option, at least for OpenMPI, so we haven't
finished the issue yet.
@trilinos/tpetra Tpetra's CMake logic now attempts to detect whether
the MPI implementation is CUDA aware.  If automatic detection does not
succeed, Tpetra just makes the safe assumption that MPI is not CUDA
aware.

Currently, automatic detection requires OpenMPI.  If not using
OpenMPI, Tpetra conservatively assumes lack of CUDA awareness.  It
would be wise for us to extend detection to support other MPI
implementations, but for now, this covers a common use case for
Trilinos testing.

Automatic detection depends on running an executable.  This is
relevant for cross compilation, so I have added two measures to
protect against misleading results in that case:

  1. If CMAKE_CROSSCOMPILING is ON, Tpetra skips detection and prints
     a configure-time message telling users that they may set
     Tpetra_ASSUME_CUDA_AWARE_MPI explicitly.

  2. If users set Tpetra_ASSUME_CUDA_AWARE_MPI explicitly, Tpetra
     skips detection and assumes the user's value as the default.
@mhoemmen mhoemmen added Framework tasks Framework tasks (used internally by Framework team) pkg: Tpetra labels Aug 14, 2017
@mhoemmen mhoemmen self-assigned this Aug 14, 2017
@mhoemmen mhoemmen requested a review from ibaned August 14, 2017 03:28
@mhoemmen mhoemmen added system: gpu stage: in review Primary work is completed and now is just waiting for human review and/or test feedback labels Aug 14, 2017
Copy link
Contributor

@ibaned ibaned left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've thrown in a few questions & suggestions for improvement. I'm not going to block this PR on anything, but replies are appreciated.

# The user set Tpetra_ASSUME_CUDA_AWARE_MPI explicitly.
# Just use that value as the default.

IF (Tpetra_ASSUME_CUDA_AWARE_MPI)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems a bit backwards... if the user explicitly set the value, why does this go back up and set the default?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before we set up the option, either the variable is undefined, or users set it explicitly. I think you're right, though, that it's not necessary to set a default value if the user has already set it. I would like some status messages regardless, though.

# The user did not set Tpetra_ASSUME_CUDA_AWARE_MPI explicitly.

# This is annoying, but necessary, because expressions like "DEFINED
# X AND (NOT X)" may not be valid CMake syntax.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the evidence that such statements may not be valid syntax?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ibaned Past experience ;-) I can try it, though!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ibaned I tried changing this to a one-level IF statement, as follows:

SET (Tpetra_CROSSCOMPILING OFF)
IF (DEFINED CMAKE_CROSSCOMPILING AND CMAKE_CROSSCOMPILING)
  SET (Tpetra_CROSSCOMPILING ON)
ENDIF ()

This worked when I ran CMake with CMAKE_CROSSCOMPILING=OFF set explicitly (I checked that CMake took that branch, by printing out a status message). With CMAKE_CROSSCOMPILING not explicitly set, CMake correctly deduced that I was not cross compiling, and everything worked as expected. Thanks for making me test this :-) .

# This only makes sense if MPI_USE_COMPILER_WRAPPERS is ON.

IF (DEFINED MPI_USE_COMPILER_WRAPPERS)
IF (MPI_USE_COMPILER_WRAPPERS AND DEFINED MPI_CXX_COMPILER AND (NOT Tpetra_FOUND_OMPI_INFO_EXECUTABLE))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how could Tpetra_FOUND_OMPI_INFO_EXECUTABLE be true at this point?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can't be, but I'm being explicit just to imitate the pattern of the cases below. I should probably break out each check into a CMake function, but I'm not sure if it would save many lines of code.

MESSAGE (STATUS " - While I found the \"ompi_info\" executable, it would not run. Thus, I will make the sane assumption that your MPI implementation is NOT CUDA aware.")
ENDIF ()
ELSE ()
MESSAGE (STATUS " - Tpetra did not find the \"ompi_info\" executable. This may not be bad; for example, if your MPI implementation is not OpenMPI, then you won't have this executable. Tpetra will conservatively assume that your MPI implementation is NOT CUDA aware. If you would like to change this, please set this CMake variable Tpetra_ASSUME_CUDA_AWARE_MPI:BOOL=ON explicitly at configure time.")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"please set this" -> "please set the"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! I'll fix that.

MESSAGE (STATUS " - Tpetra did not find the \"ompi_info\" executable. This may not be bad; for example, if your MPI implementation is not OpenMPI, then you won't have this executable. Tpetra will conservatively assume that your MPI implementation is NOT CUDA aware. If you would like to change this, please set this CMake variable Tpetra_ASSUME_CUDA_AWARE_MPI:BOOL=ON explicitly at configure time.")
ENDIF ()
ENDIF ()
ENDIF ()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you give the arguments to these ENDIFs? I believe the outermost if statement is quite long

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point -- I'll add those, or at least some comments.

TRIBITS_ADD_OPTION_AND_DEFINE(
Tpetra_ASSUME_CUDA_AWARE_MPI
TPETRA_ASSUME_CUDA_AWARE_MPI
"Assume that the MPI implementation that Tpetra uses is CUDA aware. \"CUDA aware\" means that MPI can use CUDA device allocations (the result of cudaMalloc) as send and receive buffers. If MPI is CUDA aware, then Tpetra can give CUDA device allocations directly to MPI sends and receives. MPI implementations might not support all MPI communication operations. For example, different versions of OpenMPI support different subsets of MPI operations (see https://www.open-mpi.org/faq/?category=runcuda ). Tpetra developers may safely assume that MPI_*[Ss]end and MPI*_[Rr]ecv work. Anything more than that should be considered specific to the MPI implementation."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the link to supported APIs... is the * in the right place in MPI*_[Rr]ecv ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually not -- it should be MPI_*[Rr]ecv. Thanks!

mhoemmen pushed a commit to mhoemmen/Trilinos that referenced this pull request Aug 14, 2017
@trilinos/tpetra Tpetra's CMake logic now attempts to detect whether
the MPI implementation is CUDA aware.  If automatic detection does not
succeed, Tpetra just makes the safe assumption that MPI is not CUDA
aware.

Currently, automatic detection requires OpenMPI.  If not using
OpenMPI, Tpetra conservatively assumes lack of CUDA awareness.  It
would be wise for us to extend detection to support other MPI
implementations, but for now, this covers a common use case for
Trilinos testing.

Automatic detection depends on running an executable.  This is
relevant for cross compilation, so I have added two measures to
protect against misleading results in that case:

  1. If CMAKE_CROSSCOMPILING is ON, Tpetra skips detection and prints
     a configure-time message telling users that they may set
     Tpetra_ASSUME_CUDA_AWARE_MPI explicitly if they want Tpetra to
     assume that MPI is CUDA aware.

  2. If users set Tpetra_ASSUME_CUDA_AWARE_MPI explicitly, Tpetra
     skips detection and assumes the user's value as the default.

Thanks to @ibaned for the review and suggestions!  I incorporated
these into the original pull request trilinos#1602.
@mhoemmen
Copy link
Contributor Author

I changed the commit using @ibaned 's kind suggestions, and let the remote check-in test script test and push my changes. Before that, I tested with CUDA (MPI both CUDA aware and not CUDA aware) and non-CUDA builds. Thanks!

@mhoemmen mhoemmen closed this Aug 14, 2017
@mhoemmen mhoemmen removed the stage: in review Primary work is completed and now is just waiting for human review and/or test feedback label Aug 14, 2017
@mhoemmen mhoemmen deleted the Fix-1571 branch August 14, 2017 18:53
crtrott pushed a commit to mndevec/Trilinos that referenced this pull request Aug 17, 2017
@trilinos/tpetra Tpetra's CMake logic now attempts to detect whether
the MPI implementation is CUDA aware.  If automatic detection does not
succeed, Tpetra just makes the safe assumption that MPI is not CUDA
aware.

Currently, automatic detection requires OpenMPI.  If not using
OpenMPI, Tpetra conservatively assumes lack of CUDA awareness.  It
would be wise for us to extend detection to support other MPI
implementations, but for now, this covers a common use case for
Trilinos testing.

Automatic detection depends on running an executable.  This is
relevant for cross compilation, so I have added two measures to
protect against misleading results in that case:

  1. If CMAKE_CROSSCOMPILING is ON, Tpetra skips detection and prints
     a configure-time message telling users that they may set
     Tpetra_ASSUME_CUDA_AWARE_MPI explicitly if they want Tpetra to
     assume that MPI is CUDA aware.

  2. If users set Tpetra_ASSUME_CUDA_AWARE_MPI explicitly, Tpetra
     skips detection and assumes the user's value as the default.

Thanks to @ibaned for the review and suggestions!  I incorporated
these into the original pull request trilinos#1602.
Copy link
Member

@bartlettroscoe bartlettroscoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pretty much all of this logic looks like it just defines or not the C preprocssor macro TPETRA_ASSUME_CUDA_AWARE_MPI. Since users can overdide the auto-logic with the CMake cache var Tpetra_ASSUME_CUDA_AWARE_MPI, this seems pretty low risk to add.

@mhoemmen
Copy link
Contributor Author

Thanks @bartlettroscoe ! :-D I was careful to have a fall-back, with useful messages, if users are cross-compiling. The environment variable can always override configure-time settings in that case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Framework tasks Framework tasks (used internally by Framework team) pkg: Tpetra system: gpu
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants