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

Improve build process #305

Merged
merged 1 commit into from
Aug 29, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions deps/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
deps.jl
consts.jl
build.log
gen_consts.c
gen_consts
Expand Down
50 changes: 26 additions & 24 deletions deps/build.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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()
Expand All @@ -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`)
Copy link
Member

Choose a reason for hiding this comment

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

Really that's needed? :/

Copy link
Member Author

Choose a reason for hiding this comment

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

Yup, because gen_consts calls MPI_Init: on Cray MPI it needs to be launched inside aprun.


open("deps.jl","a") do f
run(pipeline(`./gen_consts`, stdout = f))
println(f, :(include("consts.jl")))
end
end
30 changes: 18 additions & 12 deletions deps/gen_consts.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions docs/src/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -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`)
Expand Down