diff --git a/.gitignore b/.gitignore index c654990..2908301 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ **/Manifest.toml dev/t8code_include dev/Libt8.jl -Localpreferences.toml +LocalPreferences.toml diff --git a/Project.toml b/Project.toml index c0f4511..30bbb7d 100644 --- a/Project.toml +++ b/Project.toml @@ -5,6 +5,7 @@ version = "0.4.2" [deps] CEnum = "fa961155-64e5-5f13-b03f-caf6b980ea82" +Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" MPI = "da04e1cc-30fd-572f-bb4f-1f8673147195" MPIPreferences = "3da0fdf6-3ccc-4f1b-acd9-58baa6c99267" Preferences = "21216c6a-2e73-6563-6e65-726566657250" diff --git a/README.md b/README.md index b8122be..e8f69b8 100644 --- a/README.md +++ b/README.md @@ -67,18 +67,7 @@ To enable this, you first need to obtain a local binary installation of implementation used to build your local installation of [`t8code`](https://github.com/DLR-AMR/t8code), see [the documentation of MPI.jl](https://juliaparallel.org/MPI.jl/stable/configuration/). -At the time of writing, this can be done via - -```julia -julia> using MPIPreferences - -julia> MPIPreferences.use_system_binary() -``` - -if you use the default system MPI binary installation to build -[`t8code`](https://github.com/DLR-AMR/t8code). - -Next, you need to set up the +At the time of writing, this can be done by first setting up the [Preferences.jl](https://github.com/JuliaPackaging/Preferences.jl) setting containing the path to your local build of the shared library of [`t8code`](https://github.com/DLR-AMR/t8code). @@ -98,9 +87,51 @@ julia> set_preferences!( UUID("d0cc0030-9a40-4274-8435-baadcfd54fa1"), # UUID of T8code.jl "libsc" => "/path/to/your/libsc.so", force = true) ``` +Alternatively, you can use the convenience functions `set_library_t8code!`, +`set_library_p4est!` and `set_library_sc!` to set the paths: + +```julia +julia> using T8code + +julia> T8code.set_library_t8code!("/path/to/your/libt8.so") +[ Info: Please restart Julia and reload T8code.jl for the library changes to take effect + +julia> T8code.set_library_p4est!("/path/to/your/libp4est.so") +[ Info: Please restart Julia and reload T8code.jl for the library changes to take effect + +julia> T8code.set_library_sc!("/path/to/your/libsc.so") +[ Info: Please restart Julia and reload T8code.jl for the library changes to take effect + +``` + +If all libraries are located in the same directory and have the default names (`libt8.so`, +`libp4est.so` and `libsc.so` or other file endings according to your system), you can also +set all three preferences by only specifying the directory: + +```julia +julia> using T8code + +julia> T8code.set_libraries_path!("/path/to/your/lib/directory/") +[ Info: Please restart Julia and reload T8code.jl for the library changes to take effect +[ Info: Please restart Julia and reload T8code.jl for the library changes to take effect +[ Info: Please restart Julia and reload T8code.jl for the library changes to take effect +``` +To delete the preferences again, you can call `T8code.set_libraries_path!`() or for +each library `T8code.set_library_t8code!()`, `T8code.set_library_p4est!()` and +`T8code.set_library_sc!()`, respectively. Note that you should restart your Julia session after changing the preferences. +Next, you need to set up the preferences for MPI, which can be done by +```julia +julia> using MPIPreferences + +julia> MPIPreferences.use_system_binary() +``` + +if you use the default system MPI binary installation to build +[`p4est`](https://github.com/cburstedde/p4est). + Currently, custom builds of [`t8code`](https://github.com/DLR-AMR/t8code) without MPI support are not supported. diff --git a/dev/prologue.jl b/dev/prologue.jl index 1a2910a..5a1d14d 100644 --- a/dev/prologue.jl +++ b/dev/prologue.jl @@ -2,20 +2,27 @@ using t8code_jll: t8code_jll export t8code_jll using ..T8code: _PREFERENCE_LIBT8, _PREFERENCE_LIBP4EST, _PREFERENCE_LIBSC +using MPIPreferences: MPIPreferences -@static if _PREFERENCE_LIBT8 == "t8code_jll" +@static if _PREFERENCE_LIBT8 == "t8code_jll" && MPIPreferences.binary == "system" + @warn "System MPI version detected, but not a system t8code version. To make T8code.jl work, you need to set the preferences, see https://github.com/DLR-AMR/T8code.jl#using-a-custom-version-of-mpi-andor-t8code." +elseif _PREFERENCE_LIBP4EST == "t8code_jll" const libt8 = t8code_jll.libt8 else const libt8 = _PREFERENCE_LIBT8 end -@static if _PREFERENCE_LIBP4EST == "t8code_jll" +@static if _PREFERENCE_LIBP4EST == "t8code_jll" && MPIPreferences.binary == "system" + @warn "System MPI version detected, but not a system t8code version. To make T8code.jl work, you need to set the preferences, see https://github.com/DLR-AMR/T8code.jl#using-a-custom-version-of-mpi-andor-t8code." +elseif _PREFERENCE_LIBP4EST == "t8code_jll" const libp4est = t8code_jll.libp4est else const libp4est = _PREFERENCE_LIBP4EST end -@static if _PREFERENCE_LIBSC == "t8code_jll" +@static if _PREFERENCE_LIBSC == "t8code_jll" && MPIPreferences.binary == "system" + @warn "System MPI version detected, but not a system t8code version. To make T8code.jl work, you need to set the preferences, see https://github.com/DLR-AMR/T8code.jl#using-a-custom-version-of-mpi-andor-t8code." +elseif _PREFERENCE_LIBP4EST == "t8code_jll" const libsc = t8code_jll.libsc else const libsc = _PREFERENCE_LIBSC diff --git a/src/Libt8.jl b/src/Libt8.jl index 3f243a1..9fcc50b 100644 --- a/src/Libt8.jl +++ b/src/Libt8.jl @@ -11,20 +11,27 @@ using t8code_jll: t8code_jll export t8code_jll using ..T8code: _PREFERENCE_LIBT8, _PREFERENCE_LIBP4EST, _PREFERENCE_LIBSC +using MPIPreferences: MPIPreferences -@static if _PREFERENCE_LIBT8 == "t8code_jll" +@static if _PREFERENCE_LIBT8 == "t8code_jll" && MPIPreferences.binary == "system" + @warn "System MPI version detected, but not a system t8code version. To make T8code.jl work, you need to set the preferences, see https://github.com/DLR-AMR/T8code.jl#using-a-custom-version-of-mpi-andor-t8code." +elseif _PREFERENCE_LIBP4EST == "t8code_jll" const libt8 = t8code_jll.libt8 else const libt8 = _PREFERENCE_LIBT8 end -@static if _PREFERENCE_LIBP4EST == "t8code_jll" +@static if _PREFERENCE_LIBP4EST == "t8code_jll" && MPIPreferences.binary == "system" + @warn "System MPI version detected, but not a system t8code version. To make T8code.jl work, you need to set the preferences, see https://github.com/DLR-AMR/T8code.jl#using-a-custom-version-of-mpi-andor-t8code." +elseif _PREFERENCE_LIBP4EST == "t8code_jll" const libp4est = t8code_jll.libp4est else const libp4est = _PREFERENCE_LIBP4EST end -@static if _PREFERENCE_LIBSC == "t8code_jll" +@static if _PREFERENCE_LIBSC == "t8code_jll" && MPIPreferences.binary == "system" + @warn "System MPI version detected, but not a system t8code version. To make T8code.jl work, you need to set the preferences, see https://github.com/DLR-AMR/T8code.jl#using-a-custom-version-of-mpi-andor-t8code." +elseif _PREFERENCE_LIBP4EST == "t8code_jll" const libsc = t8code_jll.libsc else const libsc = _PREFERENCE_LIBSC diff --git a/src/T8code.jl b/src/T8code.jl index 6f9865f..76d697f 100644 --- a/src/T8code.jl +++ b/src/T8code.jl @@ -1,11 +1,14 @@ module T8code using Reexport: @reexport +using Libdl +using MPIPreferences: MPIPreferences # We need to load the preference setting from here and not from `Libt8.jl` # since `@load_preference` looks into the module it is running from. Thus, we # load all preferences here and access them from the `module Libt8`. -using Preferences: @load_preference +using Preferences: @load_preference, set_preferences!, delete_preferences! +using UUIDs: UUID const _PREFERENCE_LIBT8 = @load_preference("libt8", "t8code_jll") const _PREFERENCE_LIBP4EST = @load_preference("libp4est", "t8code_jll") const _PREFERENCE_LIBSC = @load_preference("libsc", "t8code_jll") @@ -40,6 +43,118 @@ Returns the version of the underlying `t8code` library (*not* of T8code.jl). """ version() = VersionNumber(T8_VERSION_MAJOR, T8_VERSION_MINOR) + +const T8CODE_UUID = UUID("d0cc0030-9a40-4274-8435-baadcfd54fa1") + +""" + T8Code.set_libraries_path!(path = nothing; force = true) + +Set the paths of all three libraries `libt8`, `libp4est` and `libsc` by +specifying the directory `path`, where all of these libraries are located. +It is assumed that the libraries are called `libt8.so`, `libp4est.so` and +`libsc.so` (or with the file endings `.dll`, `.dylib` depending on the system). +""" +function set_libraries_path!(path = nothing; force = true) + if isnothing(path) + set_library_t8code!(force = force) + set_library_p4est!(force = force) + set_library_sc!(force = force) + else + set_library_t8code!(joinpath(path, "libt8." * Libdl.dlext), force = force) + set_library_p4est!(joinpath(path, "libp4est." * Libdl.dlext), force = force) + set_library_sc!(joinpath(path, "libsc." * Libdl.dlext), force = force) + end +end + +""" + T8code.set_library_t8code!(path; force = true) + +Set the `path` to a system-provided `t8code` installation. Restart the Julia session +after executing this function so that the changes take effect. Calling this +function is necessary when you want to use a system-provided `t8code` +installation. +""" +function set_library_t8code!(path = nothing; force = true) + if isnothing(path) + delete_preferences!(T8CODE_UUID, "libt8"; force = force) + else + isfile(path) || throw(ArgumentError("$path is not a file that exists.")) + set_preferences!(T8CODE_UUID, "libt8" => path, force = force) + end + @info "Please restart Julia and reload T8code.jl for the library changes to take effect" +end + +""" + T8code.path_t8code_library() + +Return the path of the `t8code` library that is used, when a system-provided library +is configured via the preferences. Otherwise `t8code_jll` is returned, which means +that the default p4est version from t8code_jll.jl is used. +""" +path_t8code_library() = _PREFERENCE_LIBT8 + +""" + T8code.set_library_p4est!(path; force = true) + +Set the `path` to a system-provided `p4est` installation. Restart the Julia session +after executing this function so that the changes take effect. Calling this +function is necessary when you want to use a system-provided `t8code` +installation. +""" +function set_library_p4est!(path = nothing; force = true) + if isnothing(path) + delete_preferences!(T8CODE_UUID, "libp4est"; force = force) + else + isfile(path) || throw(ArgumentError("$path is not a file that exists.")) + set_preferences!(T8CODE_UUID, "libp4est" => path, force = force) + end + @info "Please restart Julia and reload T8code.jl for the library changes to take effect" +end + +""" + T8code.path_p4est_library() + +Return the path of the `p4est` library that is used, when a system-provided library +is configured via the preferences. Otherwise `t8code_jll` is returned, which means +that the default p4est version from t8code_jll.jl is used. +""" +path_p4est_library() = _PREFERENCE_LIBP4EST + +""" + T8code.set_library_sc!(path; force = true) + +Set the `path` to a system-provided `sc` installation. Restart the Julia session +after executing this function so that the changes take effect. Calling this +function is necessary, when you want to use a system-provided `t8code` +installation. +""" +function set_library_sc!(path = nothing; force = true) + if isnothing(path) + delete_preferences!(T8CODE_UUID, "libsc"; force = force) + else + isfile(path) || throw(ArgumentError("$path is not a file that exists.")) + set_preferences!(T8CODE_UUID, "libsc" => path, force = force) + end + @info "Please restart Julia and reload T8code.jl for the library changes to take effect" +end + +""" + T8code.path_sc_library() + +Return the path of the `sc` library that is used, when a system-provided library +is configured via the preferences. Otherwise `t8code_jll` is returned, which means +that the default sc version from t8code_jll.jl is used. +""" +path_sc_library() = _PREFERENCE_LIBSC + +""" + T8code.preferences_set_correctly() + +Returns `false` if a system-provided MPI installation is set via the MPIPreferences, but +not a system-provided `t8code` installation. In this case, T8code.jl is not usable. +""" +preferences_set_correctly() = !(_PREFERENCE_LIBT8 == "t8code_jll" && MPIPreferences.binary == "system") + const T8_QUAD_MAXLEVEL = 30 const T8_HEX_MAXLEVEL = 19 @@ -81,4 +196,10 @@ macro t8_replace_callback(callback) :( @cfunction($callback, Cvoid, (Ptr{Cvoid}, Ptr{Cvoid}, t8_locidx_t, Ptr{Cvoid}, Cint, Cint, t8_locidx_t, Cint, t8_locidx_t)) ) end +function __init__() + if !preferences_set_correctly() + @warn "System MPI version detected, but not a system t8code version. To make T8code.jl work, you need to set the preferences, see https://github.com/DLR-AMR/T8code.jl#using-a-custom-version-of-mpi-andor-t8code." + end +end + end