diff --git a/deps/.gitignore b/deps/.gitignore index 284b90588..3c9016ee1 100644 --- a/deps/.gitignore +++ b/deps/.gitignore @@ -1,4 +1,5 @@ deps.jl +consts.jl build.log gen_consts.c gen_consts diff --git a/deps/build.jl b/deps/build.jl index e9f0b08cf..f63ba49af 100644 --- a/deps/build.jl +++ b/deps/build.jl @@ -15,18 +15,34 @@ mpicc = get(ENV, "JULIA_MPICC") do end end -mpiexec = get(ENV, "JULIA_MPIEXEC") do - if MPI_PATH !== nothing +const mpiexec = get(ENV, "JULIA_MPIEXEC") do + if MPI_PATH !== nothing && Sys.isexecutable(joinpath(MPI_PATH,"bin","mpiexec")) joinpath(MPI_PATH,"bin","mpiexec") else - "mpiexec" + Sys.which("mpiexec") + end +end + +const libmpi = get(ENV, "JULIA_MPI_LIBRARY") do + libmpi = find_library(["libmpi", "msmpi", "libmpich"], + MPI_LIBRARY_PATH !== nothing ? [MPI_LIBRARY_PATH] : []) + try + # expand paths + dlpath(libmpi) + catch e + error("No MPI library found.\nEnsure an MPI implementation is loaded, or set the `JULIA_MPI_PATH` variable.") end end + if haskey(ENV, "JULIA_MPI_CFLAGS") CFLAGS = split(ENV["JULIA_MPI_CFLAGS"]) else - CFLAGS = ["-lmpi"] + lname, = split(basename(libmpi),'.') + if startswith(lname, "lib") + lname = lname[4:end] + end + CFLAGS = ["-l$lname"] if MPI_LIBRARY_PATH !== nothing push!(CFLAGS, "-L$(MPI_LIBRARY_PATH)") end @@ -35,19 +51,8 @@ else end end -const libmpi = find_library(Sys.iswindows() ? "msmpi.dll" : "libmpi", - MPI_LIBRARY_PATH !== nothing ? [MPI_LIBRARY_PATH] : []) - -if libmpi == "" - error("No MPI library found.\nEnsure an MPI implementation is loaded, or set the `JULIA_MPI_PATH` variable.") -end - -# expand paths -libmpi = dlpath(libmpi) libsize = filesize(libmpi) -mpiexec = Sys.which(mpiexec) - @info "Using MPI library $libmpi" function Get_version() @@ -74,18 +79,15 @@ open("deps.jl","w") do f println(f, :(const libmpi_size = $libsize)) println(f, :(const MPI_VERSION = $MPI_VERSION)) println(f, :(const mpiexec = $mpiexec)) -end -if Sys.iswindows() - open("deps.jl","a") do f + if Sys.iswindows() println(f, :(include("consts_msmpi.jl"))) - end -else - include("gen_consts.jl") + else + include("gen_consts.jl") - run(`$mpicc gen_consts.c -o gen_consts $CFLAGS`) + run(`$mpicc gen_consts.c -o gen_consts $CFLAGS`) + run(`$mpiexec -n 1 ./gen_consts`) - open("deps.jl","a") do f - run(pipeline(`./gen_consts`, stdout = f)) + println(f, :(include("consts.jl"))) end end diff --git a/deps/gen_consts.jl b/deps/gen_consts.jl index b885d83ed..f2db4680b 100644 --- a/deps/gen_consts.jl +++ b/deps/gen_consts.jl @@ -117,44 +117,50 @@ open("gen_consts.c","w") do f int main(int argc, char *argv[]) { MPI_Init(&argc, &argv); + FILE *fptr; + fptr = fopen("consts.jl", "w"); + + fprintf(fptr, "# This file is automatically generated\\n"); + fprintf(fptr, "# Do not edit\\n"); """) - println(f," printf(\"const MPI_Status_size = %d\\n\", (int)sizeof(MPI_Status));") - println(f," printf(\"const MPI_Status_Source_offset = %d\\n\", (int)offsetof(MPI_Status, MPI_SOURCE));") - println(f," printf(\"const MPI_Status_Tag_offset = %d\\n\", (int)offsetof(MPI_Status, MPI_TAG));") - println(f," printf(\"const MPI_Status_Error_offset = %d\\n\", (int)offsetof(MPI_Status, MPI_ERROR));") + println(f," fprintf(fptr, \"const MPI_Status_size = %d\\n\", (int)sizeof(MPI_Status));") + println(f," fprintf(fptr, \"const MPI_Status_Source_offset = %d\\n\", (int)offsetof(MPI_Status, MPI_SOURCE));") + println(f," fprintf(fptr, \"const MPI_Status_Tag_offset = %d\\n\", (int)offsetof(MPI_Status, MPI_TAG));") + println(f," fprintf(fptr, \"const MPI_Status_Error_offset = %d\\n\", (int)offsetof(MPI_Status, MPI_ERROR));") for (T,constants) in MPI_handle - println(f," printf(\"primitive type $T %d end\\n\", (int)(sizeof($T) * 8));") + println(f," fprintf(fptr, \"primitive type $T %d end\\n\", (int)(sizeof($T) * 8));") T_f2c = T == :MPI_Datatype ? :MPI_Type_f2c : Symbol(T, :_f2c) T_c2f = T == :MPI_Datatype ? :MPI_Type_c2f : Symbol(T, :_c2f) if Libdl.dlsym_e(libptr, T_f2c) == C_NULL - println(f," printf(\"$T(c::Cint) = reinterpret($T,c)\\n\");") + println(f," fprintf(fptr, \"$T(c::Cint) = reinterpret($T,c)\\n\");") for constant in constants - println(f," printf(\"const $constant = Cint(%i)\\n\", $constant);") + println(f," fprintf(fptr, \"const $constant = Cint(%i)\\n\", $constant);") end else - println(f," printf(\"$T(c::Cint) = ccall((:$T_f2c,libmpi),$T,(Cint,),c)\\n\");") + println(f," fprintf(fptr, \"$T(c::Cint) = ccall((:$T_f2c,libmpi),$T,(Cint,),c)\\n\");") for constant in constants - println(f," printf(\"const $constant = Cint(%i)\\n\", $T_c2f($constant));") + println(f," fprintf(fptr, \"const $constant = Cint(%i)\\n\", $T_c2f($constant));") end end end for constant in MPI_Cints - println(f," printf(\"const $constant = Cint(%i)\\n\", (int)($constant));") + println(f," fprintf(fptr, \"const $constant = Cint(%i)\\n\", (int)($constant));") end for constant in MPI_pointers if Sys.WORD_SIZE == 32 - println(f," printf(\"const $constant = reinterpret(SentinelPtr, 0x%08\" PRIx32 \")\\n\", (uint32_t)($constant));") + println(f," fprintf(fptr, \"const $constant = reinterpret(SentinelPtr, 0x%08\" PRIx32 \")\\n\", (uint32_t)($constant));") else - println(f," printf(\"const $constant = reinterpret(SentinelPtr, 0x%016\" PRIx64 \")\\n\", (uint64_t)($constant));") + println(f," fprintf(fptr, \"const $constant = reinterpret(SentinelPtr, 0x%016\" PRIx64 \")\\n\", (uint64_t)($constant));") end end print(f,""" + fclose(fptr); MPI_Finalize(); return 0; } diff --git a/docs/src/installation.md b/docs/src/installation.md index 2d4eecc86..1be2d2844 100644 --- a/docs/src/installation.md +++ b/docs/src/installation.md @@ -27,6 +27,7 @@ The build script will attempt to find the shared library and constants: this can controlled with the optional environment variables: - `JULIA_MPI_PATH`: the top-level installation directory of MPI. +- `JULIA_MPI_LIBRARY`: the path of the MPI shared library. - `JULIA_MPI_LIBRARY_PATH`: the directory containing the MPI library files. - `JULIA_MPI_INCLUDE_PATH`: the directory containing the MPI header files. - `JULIA_MPI_CFLAGS`: C flags passed to the constant generation build (default: `-lmpi`)