Skip to content

Add a lightweight MPIABI sub-package that controls the MPI ABI #529

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

Closed
wants to merge 1 commit into from

Conversation

vchuravy
Copy link
Member

@vchuravy vchuravy commented Dec 17, 2021

The goal is to have a central source of truth to query the MPI ABI used by Julia and by binary dependencies.

With this we can change the ABI, and after a restart the user will download the appropriate binaries/complain that they are incompatible.

With this I can change JuliaPackaging/Yggdrasil#4073 to contain

augmented_platform_block = """
    using Base.BinaryPlatforms
    using MPIABI
    function augmented_platform(platform)
        abi = MPI.abi
        BinaryPlatforms.add_tag!(platform.tags, "mpi", string(abi))
        return platform
    end
"""

and have the LAMMPS_jll use the right ABI.

Open questions are:

  • ABI vs System and Library? E.g. Can we assume that binaries built against OpenMPI_jll are compatible with a system OpenMPI? I think so, so switching on the ABI and not the library used "should" work.
  • Do we need to have a separate package? I think so, we want the choice to be as lightweight as possible, and MPI.jl might use MPIABI to what it includes itself.

cc: @eschnett @staticfloat @simonbyrne

@simonbyrne
Copy link
Member

Can we assume that binaries built against OpenMPI_jll are compatible with a system OpenMPI?

I seem to recall that the .so version number is baked into the binaries, so maybe not.

using Preferences

function known_abis()
return (:MicrosoftMPI, :MPICH, :OpenMPI, :MPItrampoline)
Copy link
Member

Choose a reason for hiding this comment

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

should we make these all lowercase?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think JLLWrapper&Co normalize these to lower-case. I don't have a strong preference.

$(known_abis())
""")
end
@set_preferences!("abi" => abi)
Copy link
Member

Choose a reason for hiding this comment

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

In #524, I suggested the following:

#  binary   = "" (default) | "system" | "MPICH_jll" | "OpenMPI_jll" | "MicrosoftMPI_jll"
#  path     = "" (default) | top-level directory location
#  library  = "" (default) | library name/path | list of library names/paths
#  abi      = "" (default) | "MPICH" | "OpenMPI" | "MicrosoftMPI" | "unknown"
#  mpiexec  = "" (default) | executable name/path

Copy link
Member Author

Choose a reason for hiding this comment

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

path, library, mpiexec are dependent on which actual MPI installation is being loaded and the intention is for this to be used to choose which MPI installation to be loaded.

The question is: Do we bifurcate along the _jll package used or along the ABI used. Thinking about the library versioning issue I think we need to make this mean with _jll is being used by MPI.jl (which is a shame) I would like it to be the ABI.

Right now if the ABI is set to OpenMPI we will load OpenMPI_jll as part of LAMMPS_jll, so that would not be compatible with binary==system && abi==openmpi IIUC, except if we also set libmpi_path for OpenMPI_jll?

But then we could still run into a library version mismatch?

Copy link
Member

Choose a reason for hiding this comment

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

How do you figure out the ABI without knowing the library etc?

Copy link
Member Author

Choose a reason for hiding this comment

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

That's why this package doesn't do it. It is a communication channel for ABI aware JLL packages.

I was thinking MPI.jl would figure out the details and then set it here.

Copy link
Member

Choose a reason for hiding this comment

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

Ah: so how would this work? a user would call MPI.set_library(...), which would find the library and set the preferences (in MPI.jl), and also call MPIABI.set_abi(...)?

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah, pretty much.

Copy link
Member

Choose a reason for hiding this comment

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

There are some advantages to setting them all in the same package:

  • it's easier to ensure that they stay in sync (e.g. that the preferences are set in the same location)
  • it might help avoid an unnecessary round of precompilation

Copy link
Member Author

Choose a reason for hiding this comment

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

Yeah I making this up here as we go along :)
I don't think we have a good idea of what the best practices should be.

The other extreme is to just use MPI.jl And make all the JLL packages depend on it

Copy link
Member

@simonbyrne simonbyrne Dec 22, 2021

Choose a reason for hiding this comment

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

I like the idea of a subpackage, but if e.g. Yggdrasil binaries built against MPICH are only valid for MPICH_jll and not the system MPICH, it would make sense to have binary in the subpackage. And once you have that, you might as well put them all in the same place.


using Preferences

function known_abis()
Copy link
Member

Choose a reason for hiding this comment

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

Out of curiosity, why a function and not a constant?

Copy link
Member Author

Choose a reason for hiding this comment

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

constants are just 0-arity functions, without participation in the cache invalidation scheme xD

const abi = @load_preference("abi", Sys.iswindows() ? :MicrosoftMPI : :MPICH)

function __init__()
if Sys.iswindows()
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
if Sys.iswindows()
@static if Sys.iswindows()

?

@set_preferences!("abi" => abi)
@warn "The MPI abi has changed, you will need to restart Julia for the change to take effect" abi

if VERSION <= v"1.6.5" || VERSION == v"1.7.0"
Copy link
Member

Choose a reason for hiding this comment

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

Maybe @static also here?

version = "0.1.0"

[deps]
Preferences = "21216c6a-2e73-6563-6e65-726566657250"
Copy link
Member

Choose a reason for hiding this comment

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

Compat for Preferences.jl and Julia

@@ -0,0 +1,7 @@
name = "MPIABI"
uuid = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267"
authors = []
Copy link
Member

Choose a reason for hiding this comment

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

Poor package, no one wants to claim authorship 😔

"""

uuid = Preferences.get_uuid(@__MODULE__)
project_toml, pkg_name = Preferences.find_first_project_with_uuid(uuid)
Copy link
Member

@giordano giordano Dec 18, 2021

Choose a reason for hiding this comment

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

Wouldn't Pkg.add be much easier? But you probably don't want to require Pkg just for a workaround?

Copy link
Member Author

Choose a reason for hiding this comment

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

I am tempted to fix this in Preferences.jl, which is where I stole this code from.

Copy link
Member Author

Choose a reason for hiding this comment

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

If version 1.6.5 was already released I would just make that the compat xD

Copy link
Member

Choose a reason for hiding this comment

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

@simonbyrne
Copy link
Member

I've been thinking about this a bit more, and prompted by @staticfloat's comment here: JuliaInterop/CxxWrap.jl#309 (comment), could we somehow encapsulate all this (and JuliaPackaging/Yggdrasil#4073) by creating a new MPI_jll package?

What I was vaguely thinking is that this would act like an ordinary jll package, but with some extra constants (which could be set by Preferences):

  • binary: specify which jll package to use, or "system" if using a non-jll binary.
  • abi: as defined in this PR
  • libmpi, mpiexec, etc: these would import the appropriate jll package bindings, or if binary == "system", would be set by libmpi_path, etc.

@simonbyrne
Copy link
Member

Ideally this would also handle the platform PackageSpec stuff (i.e. adding MPI_jll as a PackageSpec would automatically expand the platforms)

@vchuravy
Copy link
Member Author

vchuravy commented Mar 6, 2022

Closed in favor of #541

@vchuravy vchuravy closed this Mar 6, 2022
@giordano giordano deleted the vc/MPIABI branch September 16, 2022 19:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants