diff --git a/.github/workflows/Format-check.yml b/.github/workflows/Format-check.yml index d7e65ac7d..1a559b2a9 100644 --- a/.github/workflows/Format-check.yml +++ b/.github/workflows/Format-check.yml @@ -25,7 +25,8 @@ jobs: - name: Install JuliaFormatter and format run: | julia -e 'using Pkg; Pkg.add(PackageSpec(name="JuliaFormatter"))' - julia -e 'using JuliaFormatter; format(["src", "test", "filters", "gen"], verbose=true)' + julia -e 'using JuliaFormatter; format(["src", "test", "ext", "filters", "gen"], verbose=true)' + - name: Format check run: | julia -e ' diff --git a/Project.toml b/Project.toml index ee554fd73..bd1d247fb 100644 --- a/Project.toml +++ b/Project.toml @@ -14,9 +14,16 @@ Requires = "ae029012-a4dd-5104-9daa-d747884805df" UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" MPIPreferences = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" +[weakdeps] +MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" + +[extensions] +MPIExt = "MPI" + [compat] Compat = "3.1.0, 4" HDF5_jll = "~1.10.5, ~1.12.0, ~1.14.0" +MPI = "0.20" MPIPreferences = "0.1.7" Preferences = "1.3" Requires = "1.0" diff --git a/src/drivers/mpio.jl b/ext/MPIExt.jl similarity index 67% rename from src/drivers/mpio.jl rename to ext/MPIExt.jl index ea39d5f57..6547609fb 100644 --- a/src/drivers/mpio.jl +++ b/ext/MPIExt.jl @@ -1,6 +1,8 @@ -using .MPI +module MPIExt + +isdefined(Base, :get_extension) ? (using MPI) : (using ..MPI) import Libdl -import HDF5: h5open +using HDF5: HDF5, API, Drivers, Drivers.Driver, Properties, h5doc, h5open ### ### MPIO @@ -43,34 +45,16 @@ function API.h5p_get_fapl_mpio(fapl_id, comm, info) return nothing end -""" - MPIO(comm::MPI.Comm, info::MPI.Info) - MPIO(comm::MPI.Comm; kwargs....) - -The parallel MPI file driver. This requires the use of -[MPI.jl](https://github.com/JuliaParallel/MPI.jl), and a custom HDF5 binary that has been -built with MPI support. - -- `comm` is the communicator over which the file will be opened. -- `info`/`kwargs` are MPI-IO options, and are passed to `MPI_FILE_OPEN`. - -# See also - -- [`HDF5.has_parallel`](@ref) -- [Parallel HDF5](@ref) - -# External links - -- $(h5doc("H5P_SET_FAPL_MPIO")) -- [Parallel HDF5](https://portal.hdfgroup.org/display/HDF5/Parallel+HDF5) -""" +# The docstring for `MPIO` is included in the function `MPIO` in +# src/drivers/drivers.jl. struct MPIO <: Driver comm::MPI.Comm info::MPI.Info end -MPIO(comm::MPI.Comm; kwargs...) = MPIO(comm, MPI.Info(; kwargs...)) +Drivers.MPIO(comm::MPI.Comm, info::MPI.Info) = MPIO(comm, info) +Drivers.MPIO(comm::MPI.Comm; kwargs...) = MPIO(comm, MPI.Info(; kwargs...)) -function set_driver!(fapl::Properties, mpio::MPIO) +function Drivers.set_driver!(fapl::Properties, mpio::MPIO) HDF5.has_parallel() || error( "HDF5.jl has no parallel support." * " Make sure that you're using MPI-enabled HDF5 libraries, and that" * @@ -79,11 +63,11 @@ function set_driver!(fapl::Properties, mpio::MPIO) ) # Note: HDF5 creates a COPY of the comm and info objects, so we don't need to keep a reference around. API.h5p_set_fapl_mpio(fapl, mpio.comm, mpio.info) - DRIVERS[API.h5p_get_driver(fapl)] = MPIO + Drivers.DRIVERS[API.h5p_get_driver(fapl)] = MPIO return nothing end -function get_driver(fapl::Properties, ::Type{MPIO}) +function Drivers.get_driver(fapl::Properties, ::Type{MPIO}) comm = MPI.Comm() info = MPI.Info() API.h5p_get_fapl_mpio(fapl, comm, info) @@ -102,15 +86,17 @@ support. See the [HDF5 docs](https://portal.hdfgroup.org/display/HDF5/H5P_SET_FAPL_MPIO) for details on the `comm` and `info` arguments. """ -function h5open( +function HDF5.h5open( filename::AbstractString, mode::AbstractString, comm::MPI.Comm, info::MPI.Info=MPI.Info(); pv... ) - h5open(filename, mode; driver=MPIO(comm, info), pv...) + HDF5.h5open(filename, mode; driver=MPIO(comm, info), pv...) end -h5open(filename::AbstractString, comm::MPI.Comm, args...; pv...) = - h5open(filename, "r", comm, args...; pv...) +HDF5.h5open(filename::AbstractString, comm::MPI.Comm, args...; pv...) = + HDF5.h5open(filename, "r", comm, args...; pv...) + +end diff --git a/src/drivers/drivers.jl b/src/drivers/drivers.jl index dd788b51d..402775873 100644 --- a/src/drivers/drivers.jl +++ b/src/drivers/drivers.jl @@ -6,7 +6,9 @@ import ..API import ..HDF5: HDF5, Properties, h5doc using Libdl: dlopen, dlsym -using Requires: @require +if !isdefined(Base, :get_extension) + using Requires: @require +end function get_driver(p::Properties) driver_id = API.h5p_get_driver(p) @@ -89,8 +91,37 @@ function __init__() HDF5.HAS_PARALLEL[] = API._has_symbol(:H5Pset_fapl_mpio) HDF5.HAS_ROS3[] = API._has_symbol(:H5Pset_fapl_ros3) - @require MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" include("mpio.jl") + @static if !isdefined(Base, :get_extension) + @require MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" include("../../ext/MPIExt.jl") + end end +# The docstring for `MPIO` basically belongs to the struct `MPIO` in +# ext/MPIExt/MPIExt.jl. However, we need to document it here to make it +# work smoothly both for Julia without package extensions (up to v1.8) and +# with package extensions (v1.9 and newer). +@doc """ + MPIO(comm::MPI.Comm, info::MPI.Info) + MPIO(comm::MPI.Comm; kwargs....) + +The parallel MPI file driver. This requires the use of +[MPI.jl](https://github.com/JuliaParallel/MPI.jl), and a custom HDF5 binary that has been +built with MPI support. + +- `comm` is the communicator over which the file will be opened. +- `info`/`kwargs` are MPI-IO options, and are passed to `MPI_FILE_OPEN`. + +# See also + +- [`HDF5.has_parallel`](@ref) +- [Parallel HDF5](@ref) + +# External links + +- $(h5doc("H5P_SET_FAPL_MPIO")) +- [Parallel HDF5](https://portal.hdfgroup.org/display/HDF5/Parallel+HDF5) +""" +function MPIO end + include("ros3.jl") end # module