[Debian-astro-commits] [gyoto] 21/221: Initial MPI version. Dummy implementation: calls are made to parallelize Scenery::rayTrace, but no raytracing actually occurs.
Thibaut Jean-Claude Paumard
thibaut at moszumanska.debian.org
Fri May 22 20:52:30 UTC 2015
This is an automated email from the git hooks/post-receive script.
thibaut pushed a commit to branch master
in repository gyoto.
commit bb1816d21691d2c3c5fb0f570ed5cb458ab50662
Author: Thibaut Paumard <paumard at users.sourceforge.net>
Date: Wed Oct 8 15:11:37 2014 +0200
Initial MPI version. Dummy implementation: calls are made to parallelize Scenery::rayTrace, but no raytracing actually occurs.
---
Makefile.in | 2 +
aclocal.m4 | 4 +-
bin/Makefile.am | 7 +-
bin/Makefile.in | 39 ++++++-
bin/gyoto-mpi-worker.C | 164 ++++++++++++++++++++++++++++++
configure | 268 ++++++++++++++++++++++++++++++++++++++++++++++++-
configure.ac | 19 +++-
include/GyotoScenery.h | 24 +++++
lib/Makefile.am | 2 +-
lib/Makefile.in | 4 +-
lib/Scenery.C | 134 ++++++++++++++++++++++++-
m4/ax_prog_cxx_mpi.m4 | 178 ++++++++++++++++++++++++++++++++
12 files changed, 833 insertions(+), 12 deletions(-)
diff --git a/Makefile.in b/Makefile.in
index d8721de..eb56cec 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -96,6 +96,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
$(top_srcdir)/m4/ax_append_flag.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \
+ $(top_srcdir)/m4/ax_prog_cxx_mpi.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/boost.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -272,6 +273,7 @@ MAKEINFO = @MAKEINFO@
MAKE_S = @MAKE_S@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
+MPICXX = @MPICXX@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
diff --git a/aclocal.m4 b/aclocal.m4
index 07ed599..b0883d5 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -573,7 +573,8 @@ to "yes", and re-run configure.
END
AC_MSG_ERROR([Your 'rm' program is bad, sorry.])
fi
-fi])
+fi
+])
dnl Hook into '_AC_COMPILER_EXEEXT' early to learn its expansion. Do not
dnl add the conditional right here, as _AC_COMPILER_EXEEXT may be further
@@ -1151,6 +1152,7 @@ m4_include([m4/ax_append_compile_flags.m4])
m4_include([m4/ax_append_flag.m4])
m4_include([m4/ax_check_compile_flag.m4])
m4_include([m4/ax_cxx_compile_stdcxx_11.m4])
+m4_include([m4/ax_prog_cxx_mpi.m4])
m4_include([m4/ax_pthread.m4])
m4_include([m4/boost.m4])
m4_include([m4/libtool.m4])
diff --git a/bin/Makefile.am b/bin/Makefile.am
index d08352f..6056ce9 100644
--- a/bin/Makefile.am
+++ b/bin/Makefile.am
@@ -4,13 +4,18 @@ AM_LDFLAGS = $(XERCESLDFLAGS) $(PTHREAD_LIBS)
AM_CXXFLAGS = $(PTHREAD_CFLAGS)
CLEANFILES=example-*.fits
-bin_PROGRAMS = gyoto
+bin_PROGRAMS = gyoto gyoto-mpi-worker
dist_man_MANS = gyoto.1
gyoto_SOURCES = gyoto.C
gyoto_LDADD = @top_builddir@/lib/libgyoto.la
gyoto_CPPFLAGS = $(AM_CPPFLAGS) $(CFITSIOCPPFLAGS)
gyoto_LDFLAGS = $(AM_LDFLAGS) $(CFITSIOLDFLAGS) -export-dynamic
+gyoto_mpi_worker_SOURCES = gyoto-mpi-worker.C
+gyoto_mpi_worker_LDADD = @top_builddir@/lib/libgyoto.la -lboost_mpi -lboost_serialization
+gyoto_mpi_worker_CPPFLAGS = $(AM_CPPFLAGS) $(CFITSIOCPPFLAGS)
+gyoto_mpi_worker_LDFLAGS = $(AM_LDFLAGS) $(CFITSIOLDFLAGS) -export-dynamic
+
CHECK_CMD = unset GYOTO_PLUGINS && ./gyoto --resolution=32 --nthreads=8
check: gyoto
$(CHECK_CMD) ../doc/examples/example-thin-disk.xml \
diff --git a/bin/Makefile.in b/bin/Makefile.in
index f08538f..ec89ac2 100644
--- a/bin/Makefile.in
+++ b/bin/Makefile.in
@@ -79,7 +79,7 @@ POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
target_triplet = @target@
-bin_PROGRAMS = gyoto$(EXEEXT)
+bin_PROGRAMS = gyoto$(EXEEXT) gyoto-mpi-worker$(EXEEXT)
subdir = bin
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp $(dist_man_MANS)
@@ -88,6 +88,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
$(top_srcdir)/m4/ax_append_flag.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \
+ $(top_srcdir)/m4/ax_prog_cxx_mpi.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/boost.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -112,6 +113,14 @@ am__v_lt_1 =
gyoto_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(gyoto_LDFLAGS) $(LDFLAGS) -o $@
+am_gyoto_mpi_worker_OBJECTS = \
+ gyoto_mpi_worker-gyoto-mpi-worker.$(OBJEXT)
+gyoto_mpi_worker_OBJECTS = $(am_gyoto_mpi_worker_OBJECTS)
+gyoto_mpi_worker_DEPENDENCIES = @top_builddir@/lib/libgyoto.la
+gyoto_mpi_worker_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
+ $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
+ $(AM_CXXFLAGS) $(CXXFLAGS) $(gyoto_mpi_worker_LDFLAGS) \
+ $(LDFLAGS) -o $@
AM_V_P = $(am__v_P_ at AM_V@)
am__v_P_ = $(am__v_P_ at AM_DEFAULT_V@)
am__v_P_0 = false
@@ -146,8 +155,8 @@ AM_V_CXXLD = $(am__v_CXXLD_ at AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_ at AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
-SOURCES = $(gyoto_SOURCES)
-DIST_SOURCES = $(gyoto_SOURCES)
+SOURCES = $(gyoto_SOURCES) $(gyoto_mpi_worker_SOURCES)
+DIST_SOURCES = $(gyoto_SOURCES) $(gyoto_mpi_worker_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
@@ -265,6 +274,7 @@ MAKEINFO = @MAKEINFO@
MAKE_S = @MAKE_S@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
+MPICXX = @MPICXX@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
@@ -380,6 +390,10 @@ gyoto_SOURCES = gyoto.C
gyoto_LDADD = @top_builddir@/lib/libgyoto.la
gyoto_CPPFLAGS = $(AM_CPPFLAGS) $(CFITSIOCPPFLAGS)
gyoto_LDFLAGS = $(AM_LDFLAGS) $(CFITSIOLDFLAGS) -export-dynamic
+gyoto_mpi_worker_SOURCES = gyoto-mpi-worker.C
+gyoto_mpi_worker_LDADD = @top_builddir@/lib/libgyoto.la -lboost_mpi -lboost_serialization
+gyoto_mpi_worker_CPPFLAGS = $(AM_CPPFLAGS) $(CFITSIOCPPFLAGS)
+gyoto_mpi_worker_LDFLAGS = $(AM_LDFLAGS) $(CFITSIOLDFLAGS) -export-dynamic
CHECK_CMD = unset GYOTO_PLUGINS && ./gyoto --resolution=32 --nthreads=8
all: all-am
@@ -469,6 +483,10 @@ gyoto$(EXEEXT): $(gyoto_OBJECTS) $(gyoto_DEPENDENCIES) $(EXTRA_gyoto_DEPENDENCIE
@rm -f gyoto$(EXEEXT)
$(AM_V_CXXLD)$(gyoto_LINK) $(gyoto_OBJECTS) $(gyoto_LDADD) $(LIBS)
+gyoto-mpi-worker$(EXEEXT): $(gyoto_mpi_worker_OBJECTS) $(gyoto_mpi_worker_DEPENDENCIES) $(EXTRA_gyoto_mpi_worker_DEPENDENCIES)
+ @rm -f gyoto-mpi-worker$(EXEEXT)
+ $(AM_V_CXXLD)$(gyoto_mpi_worker_LINK) $(gyoto_mpi_worker_OBJECTS) $(gyoto_mpi_worker_LDADD) $(LIBS)
+
mostlyclean-compile:
-rm -f *.$(OBJEXT)
@@ -476,6 +494,7 @@ distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gyoto-gyoto.Po at am__quote@
+ at AMDEP_TRUE@@am__include@ @am__quote at ./$(DEPDIR)/gyoto_mpi_worker-gyoto-mpi-worker.Po at am__quote@
.C.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@@ -512,6 +531,20 @@ gyoto-gyoto.obj: gyoto.C
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gyoto_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gyoto-gyoto.obj `if test -f 'gyoto.C'; then $(CYGPATH_W) 'gyoto.C'; else $(CYGPATH_W) '$(srcdir)/gyoto.C'; fi`
+gyoto_mpi_worker-gyoto-mpi-worker.o: gyoto-mpi-worker.C
+ at am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gyoto_mpi_worker_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gyoto_mpi_worker-gyoto-mpi-worker.o -MD -MP -MF $(DEPDIR)/gyoto_mpi_worker-gyoto-mpi-worker.Tpo -c -o gyoto_mpi_worker-gyoto-mpi-worker.o `test -f 'gyoto-mpi-worker.C' || echo '$(srcdir)/'`gyoto-mpi-worker.C
+ at am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gyoto_mpi_worker-gyoto-mpi-worker.Tpo $(DEPDIR)/gyoto_mpi_worker-gyoto-mpi-worker.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gyoto-mpi-worker.C' object='gyoto_mpi_worker-gyoto-mpi-worker.o' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gyoto_mpi_worker_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gyoto_mpi_worker-gyoto-mpi-worker.o `test -f 'gyoto-mpi-worker.C' || echo '$(srcdir)/'`gyoto-mpi-worker.C
+
+gyoto_mpi_worker-gyoto-mpi-worker.obj: gyoto-mpi-worker.C
+ at am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gyoto_mpi_worker_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -MT gyoto_mpi_worker-gyoto-mpi-worker.obj -MD -MP -MF $(DEPDIR)/gyoto_mpi_worker-gyoto-mpi-worker.Tpo -c -o gyoto_mpi_worker-gyoto-mpi-worker.obj `if test -f 'gyoto-mpi-worker.C'; then $(CYGPATH_W) 'gyoto-mpi-worker.C'; else $(CYGPATH_W) '$(srcdir)/gyoto-mpi-worker.C'; fi`
+ at am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/gyoto_mpi_worker-gyoto-mpi-worker.Tpo $(DEPDIR)/gyoto_mpi_worker-gyoto-mpi-worker.Po
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='gyoto-mpi-worker.C' object='gyoto_mpi_worker-gyoto-mpi-worker.obj' libtool=no @AMDEPBACKSLASH@
+ at AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+ at am__fastdepCXX_FALSE@ $(AM_V_CXX at am__nodep@)$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(gyoto_mpi_worker_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) -c -o gyoto_mpi_worker-gyoto-mpi-worker.obj `if test -f 'gyoto-mpi-worker.C'; then $(CYGPATH_W) 'gyoto-mpi-worker.C'; else $(CYGPATH_W) '$(srcdir)/gyoto-mpi-worker.C'; fi`
+
mostlyclean-libtool:
-rm -f *.lo
diff --git a/bin/gyoto-mpi-worker.C b/bin/gyoto-mpi-worker.C
new file mode 100644
index 0000000..e0096f1
--- /dev/null
+++ b/bin/gyoto-mpi-worker.C
@@ -0,0 +1,164 @@
+/*
+ Copyright 2011, 2013 Thibaut Paumard, Frederic Vincent
+
+ This file is part of Gyoto.
+
+ Gyoto is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Gyoto is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Gyoto. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+// Gyoto
+#include "GyotoDefs.h"
+#include "GyotoFactory.h"
+#include "GyotoUtils.h"
+#include "GyotoRegister.h"
+#include "GyotoScenery.h"
+
+// FITS I/O
+#include <fitsio.h>
+
+// signal()
+#include <csignal>
+
+// getpid()
+#include <sys/types.h>
+#include <unistd.h>
+
+using namespace std;
+using namespace Gyoto;
+
+static char* pixfile = NULL;
+static fitsfile* fptr = NULL;
+static int status = 0;
+static long fpixel[] = {1,1,1};
+static long nelements = 0;
+static double* vect = NULL;
+static double* impactcoords=NULL;
+static SmartPointer<Astrobj::Properties> data = NULL;
+
+static SmartPointer<Scenery> sc = NULL;
+
+#ifdef HAVE_MPI
+#include <boost/mpi/environment.hpp>
+#include <boost/mpi/communicator.hpp>
+#include <string>
+#include <boost/serialization/string.hpp>
+namespace mpi = boost::mpi;
+#endif
+
+void usage() {
+ cout << "Usage:" << endl <<
+ " rayXML [--imin=i0 --imax=i1 --jmin=j0 --jmax=j1] input.xml output.dat" << endl;
+}
+
+void sigint_handler(int sig)
+{
+ if (sig!=SIGINT) cerr << "\n********GYOTO: sigint_handler trapping signal " << sig << ", this should not happen !" << endl;
+ cerr << "GYOTO: SIGINT received: saving data to " << pixfile << "... ";
+ signal(SIGINT, SIG_DFL);
+
+ fits_write_pix(fptr, TDOUBLE, fpixel, nelements, vect, &status);
+ fits_close_file(fptr, &status);
+ fits_report_error(stderr, status);
+
+ cerr << "Killing self." << endl;
+ kill(getpid(), SIGINT);
+}
+
+static std::string curmsg = "";
+static int curretval = 1;
+
+void gyotoErrorHandler( const Gyoto::Error e ) {
+ cerr << curmsg << e << endl;
+ if (debug()) abort(); // to keep stack for debugger
+ exit (curretval);
+}
+
+int main(int argc, char** argv) {
+ /*
+ This program aims at computing the null geodesics of photons from
+ an observation screen to an astrophysical object (star orbit,
+ fixed star or disk). The final result is a list of illuminated
+ pixels.
+ */
+ // For debug output
+ debug(0);
+ // verbose(1);
+
+ mpi::environment env;
+
+
+ MPI_Comm parent_c;
+ MPI_Comm_get_parent(&parent_c);
+
+ mpi::communicator manager(parent_c,mpi::comm_take_ownership);
+ mpi::communicator world;
+
+ string pluglist= getenv("GYOTO_PLUGINS")?
+ getenv("GYOTO_PLUGINS"):
+ GYOTO_DEFAULT_PLUGINS;
+ Gyoto::Error::setHandler ( &gyotoErrorHandler );
+ curmsg = "In gyoto.C: Error initializing libgyoto: ";
+ curretval = 1;
+ Gyoto::Register::init(pluglist.c_str());
+
+ int rk=world.rank();
+ srand(rk);
+ long delay;
+
+
+ //Gyoto::debug(1);
+
+ Scenery::mpi_tag task=Scenery::give_task;
+ Scenery::is_worker=true;
+ while (task != Scenery::terminate) {
+ // std::cerr << "Worker #" << rk << " waiting for task " << endl;
+ manager.recv(0, Scenery::give_task, task);
+ // std::cerr << "Worker #" << rk << " received task " << task << endl;
+ switch (task) {
+ case Scenery::read_scenery: {
+ std::string parfile;
+ manager.recv(0, task, parfile);
+ std::cerr << "Worker #" << rk << " reading \""<<parfile<<"\""<<std::endl;
+ curmsg = "In gyoto.C: Error in Factory creation: ";
+ curretval = 1;
+ sc = Factory(const_cast<char*>(parfile.c_str())).getScenery();
+ break;
+ }
+ case Scenery::raytrace: {
+ size_t ij[2]={0, 0};
+ // std::cerr << "Worker #" << rk << " receiving ij for raytracing" <<std::endl;
+ manager.recv(0, task, ij, 2);
+ delay=long(double(rand())/double(RAND_MAX)*1e6);
+ std::cerr << "Worker #" << rk << " raytracing i="<<ij[0]<<", j="<<ij[1]
+ <<" (actually sleeping for "<<delay<<"µs)"<<std::endl;
+ usleep(delay);
+
+ manager.send(0, Scenery::raytrace_done, rk);
+ // std::cerr << "Worker #" << rk << " done raytracing i="<<ij[0]<<", j="<<ij[1]<<std::endl;
+
+ }
+ break;
+ case Scenery::terminate:
+ std::cerr << "Worker #" << rk << " terminating"<<std::endl;
+
+ break;
+ default:
+ std::cerr << "unknown task" << endl;
+ }
+ }
+
+ std::cerr << "Worker #" << rk << " done, exiting" << endl;
+
+ return 0;
+}
diff --git a/configure b/configure
index 2adc9a7..c921227 100755
--- a/configure
+++ b/configure
@@ -688,6 +688,7 @@ DOXYGEN
PKG_CONFIG_LIBDIR
PKG_CONFIG_PATH
PKG_CONFIG
+MPICXX
sovers
VERSINFO
CXXCPP
@@ -825,6 +826,7 @@ enable_dependency_tracking
with_gnu_ld
with_sysroot
enable_libtool_lock
+with_mpi
enable_native
enable_hardening
enable_deprecated
@@ -860,6 +862,7 @@ CXXFLAGS
CCC
CPP
CXXCPP
+MPICXX
PKG_CONFIG
PKG_CONFIG_PATH
PKG_CONFIG_LIBDIR
@@ -1520,6 +1523,9 @@ Optional Packages:
--with-gnu-ld assume the C compiler uses GNU ld [default=no]
--with-sysroot=DIR Search for dependent libraries within DIR
(or the compiler's sysroot if not specified).
+ --with-mpi compile with MPI (parallelization) support. If none
+ is found, MPI is not used. Default: auto
+
--with-boost=DIR prefix of Boost 1.53.1 [guess]
--with-yorick[=yorick-executable]
force using yorick and optionnally specify which one
@@ -1566,6 +1572,7 @@ Some influential environment variables:
CXXFLAGS C++ compiler flags
CPP C preprocessor
CXXCPP C++ preprocessor
+ MPICXX MPI C++ compiler command
PKG_CONFIG path to pkg-config utility
PKG_CONFIG_PATH
directories to add to pkg-config's search path
@@ -3284,6 +3291,7 @@ END
fi
+
ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -15453,7 +15461,139 @@ _ACEOF
# Checks for programs.
-ac_ext=cpp
+
+# If --with-mpi=auto is used, try to find MPI, but use standard C compiler if it is not found.
+# If --with-mpi=yes is used, try to find MPI and fail if it isn't found.
+# If --with-mpi=no is used, use a standard C compiler instead.
+
+# Check whether --with-mpi was given.
+if test "${with_mpi+set}" = set; then :
+ withval=$with_mpi;
+else
+ with_mpi=auto
+fi
+
+
+
+
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to compile using MPI" >&5
+$as_echo_n "checking whether to compile using MPI... " >&6; }
+ if test x"$with_mpi" != xno; then
+ _ax_prog_cxx_mpi_mpi_wanted=yes
+ else
+ _ax_prog_cxx_mpi_mpi_wanted=no
+ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_ax_prog_cxx_mpi_mpi_wanted" >&5
+$as_echo "$_ax_prog_cxx_mpi_mpi_wanted" >&6; }
+
+ if test x"$_ax_prog_cxx_mpi_mpi_wanted" = xyes; then
+ if test -z "$CXX" && test -n "$MPICXX"; then
+ CXX="$MPICXX"
+ else
+ if test -n "$ac_tool_prefix"; then
+ for ac_prog in mpic++ mpicxx mpiCC sxmpic++ hcp mpxlC_r mpxlC mpixlcxx_r mpixlcxx mpg++ mpc++ mpCC cmpic++ mpiFCC CCicpc pgCC pathCC sxc++ xlC_r xlC bgxlC_r bgxlC openCC sunCC crayCC g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC
+ do
+ # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args.
+set dummy $ac_tool_prefix$ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$CXX"; then
+ ac_cv_prog_CXX="$CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_CXX="$ac_tool_prefix$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+CXX=$ac_cv_prog_CXX
+if test -n "$CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CXX" >&5
+$as_echo "$CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$CXX" && break
+ done
+fi
+if test -z "$CXX"; then
+ ac_ct_CXX=$CXX
+ for ac_prog in mpic++ mpicxx mpiCC sxmpic++ hcp mpxlC_r mpxlC mpixlcxx_r mpixlcxx mpg++ mpc++ mpCC cmpic++ mpiFCC CCicpc pgCC pathCC sxc++ xlC_r xlC bgxlC_r bgxlC openCC sunCC crayCC g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC
+do
+ # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5
+$as_echo_n "checking for $ac_word... " >&6; }
+if ${ac_cv_prog_ac_ct_CXX+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ if test -n "$ac_ct_CXX"; then
+ ac_cv_prog_ac_ct_CXX="$ac_ct_CXX" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+ IFS=$as_save_IFS
+ test -z "$as_dir" && as_dir=.
+ for ac_exec_ext in '' $ac_executable_extensions; do
+ if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
+ ac_cv_prog_ac_ct_CXX="$ac_prog"
+ $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5
+ break 2
+ fi
+done
+ done
+IFS=$as_save_IFS
+
+fi
+fi
+ac_ct_CXX=$ac_cv_prog_ac_ct_CXX
+if test -n "$ac_ct_CXX"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CXX" >&5
+$as_echo "$ac_ct_CXX" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+fi
+
+
+ test -n "$ac_ct_CXX" && break
+done
+
+ if test "x$ac_ct_CXX" = x; then
+ CXX=""
+ else
+ case $cross_compiling:$ac_tool_warned in
+yes:)
+{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5
+$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;}
+ac_tool_warned=yes ;;
+esac
+ CXX=$ac_ct_CXX
+ fi
+fi
+
+ fi
+ fi
+ ac_ext=cpp
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
@@ -15839,6 +15979,132 @@ fi
+
+
+
+# Check for compiler
+# Needs to be split off into an extra macro to ensure right expansion
+# order.
+
+
+if test x"$_ax_prog_cxx_mpi_mpi_wanted" = xno; then :
+ _ax_prog_cxx_mpi_mpi_found=no
+else
+
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+ # test whether MPI_Init() is available
+ # We do not use AC_SEARCH_LIBS here, as it caches its outcome and
+ # thus disallows corresponding calls in the other AX_PROG_*_MPI
+ # macros.
+ for lib in NONE mpi mpich; do
+ save_LIBS=$LIBS
+ if test x"$lib" = xNONE; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for function MPI_Init" >&5
+$as_echo_n "checking for function MPI_Init... " >&6; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for function MPI_Init in -l$lib" >&5
+$as_echo_n "checking for function MPI_Init in -l$lib... " >&6; }
+ LIBS="-l$lib $LIBS"
+ fi
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+
+
+extern "C" { void MPI_Init(); }
+
+int
+main ()
+{
+MPI_Init();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ _ax_prog_cxx_mpi_mpi_found=yes
+else
+ _ax_prog_cxx_mpi_mpi_found=no
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $_ax_prog_cxx_mpi_mpi_found" >&5
+$as_echo "$_ax_prog_cxx_mpi_mpi_found" >&6; }
+ if test "x$_ax_prog_cxx_mpi_mpi_found" = "xyes"; then
+ break;
+ fi
+ LIBS=$save_LIBS
+ done
+
+ # Check for header
+ if test x"$_ax_prog_cxx_mpi_mpi_found" = xyes; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mpi.h" >&5
+$as_echo_n "checking for mpi.h... " >&6; }
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+#include <mpi.h>
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_compile "$LINENO"; then :
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ _ax_prog_cxx_mpi_mpi_found=no
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+fi
+ ac_ext=cpp
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+fi
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$_ax_prog_cxx_mpi_mpi_found" = xyes; then :
+
+ use_mpi=yes
+ :
+
+else
+
+
+ use_mpi=no
+ if test x"$with_mpi" = xyes; then
+ { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "MPI compiler requested, but couldn't use MPI.
+See \`config.log' for more details" "$LINENO" 5; }
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: No MPI compiler found, won't use MPI." >&5
+$as_echo "$as_me: WARNING: No MPI compiler found, won't use MPI." >&2;}
+ fi
+
+ :
+
+fi
+
+
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5
$as_echo_n "checking whether ln -s works... " >&6; }
LN_S=$as_ln_s
diff --git a/configure.ac b/configure.ac
index 7b05ad1..3ff44b2 100644
--- a/configure.ac
+++ b/configure.ac
@@ -21,7 +21,24 @@ AC_SUBST([sovers])
AC_DEFINE_UNQUOTED([GYOTO_SOVERS], ["${sovers}"], [Gyoto ABI version])
# Checks for programs.
-AC_PROG_CXX
+
+# If --with-mpi=auto is used, try to find MPI, but use standard C compiler if it is not found.
+# If --with-mpi=yes is used, try to find MPI and fail if it isn't found.
+# If --with-mpi=no is used, use a standard C compiler instead.
+AC_ARG_WITH(mpi, [AS_HELP_STRING([--with-mpi],
+ [compile with MPI (parallelization) support. If none is found,
+ MPI is not used. Default: auto])
+],,[with_mpi=auto])
+
+AX_PROG_CXX_MPI([test x"$with_mpi" != xno],[use_mpi=yes],[
+ use_mpi=no
+ if test x"$with_mpi" = xyes; then
+ AC_MSG_FAILURE([MPI compiler requested, but couldn't use MPI.])
+ else
+ AC_MSG_WARN([No MPI compiler found, won't use MPI.])
+ fi
+])
+
AC_PROG_INSTALL
AC_PROG_LN_S
AC_PROG_MAKE_SET
diff --git a/include/GyotoScenery.h b/include/GyotoScenery.h
index 1920134..5f39211 100644
--- a/include/GyotoScenery.h
+++ b/include/GyotoScenery.h
@@ -39,6 +39,15 @@ namespace Gyoto{
#include <GyotoPhoton.h>
#include <GyotoConverters.h>
+#define HAVE_MPI
+
+#ifdef HAVE_MPI
+#include "GyotoFactory.h"
+#include <boost/mpi/environment.hpp>
+#include <boost/mpi/communicator.hpp>
+#endif
+
+
/**
* \class Gyoto::Scenery
* \brief Ray-tracing scene
@@ -204,6 +213,21 @@ class Gyoto::Scenery : protected Gyoto::SmartPointee {
size_t maxiter_ ; ///< Maximum number of iterations when integrating
+# ifdef HAVE_MPI
+ boost::mpi::environment * mpi_env_;
+ boost::mpi::communicator * mpi_world_;
+ boost::mpi::intercommunicator * mpi_workers_;
+ int mpi_nbworkers_;
+ public:
+ static bool is_worker;
+ void mpiSpawn(int nbchildren);
+ void mpiTerminate (bool keep_env=false);
+ void mpiClone();
+ enum mpi_tag {give_task, read_scenery, terminate,
+ raytrace, raytrace_done, ready,
+ impactcoords, noimpactcoords};
+# endif
+
// Constructors - Destructor
// -------------------------
public:
diff --git a/lib/Makefile.am b/lib/Makefile.am
index d2e22c8..5dfec09 100644
--- a/lib/Makefile.am
+++ b/lib/Makefile.am
@@ -1,7 +1,7 @@
ACLOCAL_AMFLAGS = -I m4
AM_CPPFLAGS = -I at top_srcdir@/include $(XERCESCPPFLAGS) $(UDUNITS_CPPFLAGS) $(BOOST_CPPFLAGS)
AM_LDFLAGS = $(XERCESLDFLAGS) -export-dynamic $(PTHREAD_LIBS) \
- $(UDUNITS_LDFLAGS)
+ $(UDUNITS_LDFLAGS) -lboost_mpi -lboost_serialization
AM_CXXFLAGS = $(PTHREAD_CFLAGS) -DGYOTO_PREFIX=\"${prefix}\"
# HEADERS: where they are, where to install them
diff --git a/lib/Makefile.in b/lib/Makefile.in
index 5b22a3b..72b5321 100644
--- a/lib/Makefile.in
+++ b/lib/Makefile.in
@@ -93,6 +93,7 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/ax_append_compile_flags.m4 \
$(top_srcdir)/m4/ax_append_flag.m4 \
$(top_srcdir)/m4/ax_check_compile_flag.m4 \
$(top_srcdir)/m4/ax_cxx_compile_stdcxx_11.m4 \
+ $(top_srcdir)/m4/ax_prog_cxx_mpi.m4 \
$(top_srcdir)/m4/ax_pthread.m4 $(top_srcdir)/m4/boost.m4 \
$(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
$(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
@@ -302,6 +303,7 @@ MAKEINFO = @MAKEINFO@
MAKE_S = @MAKE_S@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
+MPICXX = @MPICXX@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
@@ -410,7 +412,7 @@ top_srcdir = @top_srcdir@
ACLOCAL_AMFLAGS = -I m4
AM_CPPFLAGS = -I at top_srcdir@/include $(XERCESCPPFLAGS) $(UDUNITS_CPPFLAGS) $(BOOST_CPPFLAGS)
AM_LDFLAGS = $(XERCESLDFLAGS) -export-dynamic $(PTHREAD_LIBS) \
- $(UDUNITS_LDFLAGS)
+ $(UDUNITS_LDFLAGS) -lboost_mpi -lboost_serialization
AM_CXXFLAGS = $(PTHREAD_CFLAGS) -DGYOTO_PREFIX=\"${prefix}\"
diff --git a/lib/Scenery.C b/lib/Scenery.C
index fef6b11..124a85f 100644
--- a/lib/Scenery.C
+++ b/lib/Scenery.C
@@ -27,6 +27,16 @@
#include <cstring>
#include <cstdlib>
+#ifdef HAVE_MPI
+#include "GyotoFactory.h"
+#include <boost/mpi/environment.hpp>
+#include <boost/mpi/communicator.hpp>
+#include <boost/mpi/intercommunicator.hpp>
+#include <string>
+#include <boost/serialization/string.hpp>
+namespace mpi = boost::mpi;
+#endif
+
#ifdef HAVE_PTHREAD
#include <pthread.h>
#endif
@@ -39,13 +49,16 @@ using namespace std;
Scenery::Scenery() :
screen_(NULL), delta_(GYOTO_DEFAULT_DELTA),
- quantities_(0), ph_(), nthreads_(0){}
+ quantities_(0), ph_(), nthreads_(0),
+ mpi_env_(NULL), mpi_world_(NULL), mpi_workers_(NULL)
+{}
Scenery::Scenery(SmartPointer<Metric::Generic> met,
SmartPointer<Screen> scr,
SmartPointer<Astrobj::Generic> obj) :
screen_(scr), delta_(GYOTO_DEFAULT_DELTA),
- quantities_(0), ph_(), nthreads_(0)
+ quantities_(0), ph_(), nthreads_(0),
+ mpi_env_(NULL), mpi_world_(NULL), mpi_workers_(NULL)
{
metric(met);
if (screen_) screen_->metric(met);
@@ -56,7 +69,8 @@ Scenery::Scenery(const Scenery& o) :
SmartPointee(o),
screen_(NULL), delta_(o.delta_),
quantities_(o.quantities_), ph_(o.ph_),
- nthreads_(o.nthreads_)
+ nthreads_(o.nthreads_),
+ mpi_env_(NULL), mpi_world_(NULL), mpi_workers_(NULL)
{
if (o.screen_()) {
screen_=o.screen_->clone();
@@ -70,6 +84,7 @@ Scenery::~Scenery() {
GYOTO_DEBUG << "freeing screen\n";
# endif
screen_ = NULL;
+ if (!Scenery::is_worker) mpiTerminate();
}
SmartPointer<Metric::Generic> Scenery::metric() const { return ph_.metric(); }
@@ -213,6 +228,8 @@ void Scenery::rayTrace(size_t imin, size_t imax,
Astrobj::Properties *data,
double * impactcoords) {
+
+
/*
Ray-trace now is multi-threaded. What it does is
- some initialization
@@ -225,6 +242,55 @@ void Scenery::rayTrace(size_t imin, size_t imax,
const size_t npix = screen_->resolution();
imax=(imax<=(npix)?imax:(npix));
jmax=(jmax<=(npix)?jmax:(npix));
+
+ //#if 0
+ if (mpi_workers_) {
+ // dispatch over workers and monitor
+
+ size_t ij[2]={imin, jmin};
+ int working = 0;
+
+ // initiate raytracing
+ for (int w=0; w<mpi_workers_->remote_size(); ++w) {
+ if (impactcoords) {
+ mpi_workers_->send(w, give_task, Scenery::impactcoords);
+ mpi_workers_->send(w, Scenery::impactcoords, impactcoords, npix*npix*8);
+ } else mpi_workers_->send(w, give_task, Scenery::noimpactcoords);
+ mpi_workers_ -> send(w, give_task, raytrace);
+ mpi_workers_ -> send(w, raytrace, ij, 2);
+ ++working;
+ if (++ij[0]>imax) {
+ cout << "\rj = " << ij[1] << " / " << jmax << " " << flush;
+ if (++ij[1]>jmax) break;
+ else ij[0]=imin;
+ }
+ cerr << "Manager sent data to all workers" << endl;
+ }
+
+ // continue
+ while (working) {
+ // receive one result, need to track back where it belongs and
+ // store it there
+ int w;
+ cerr << "Manager waiting for worker to send result" << endl;
+ mpi_workers_ -> recv(mpi::any_source, raytrace_done, w);
+ cerr << "Manager received result from worker #"<<w << endl;
+
+ // give new task or decrease working counter
+ if (ij[0]<=imax) {
+ mpi_workers_ -> send(w, give_task, raytrace);
+ mpi_workers_ -> send(w, raytrace, ij, 2);
+ if (++ij[0]>imax) {
+ cout << "\rj = " << ij[1] << " / " << jmax << " " << flush;
+ if (++ij[1]<=jmax) ij[0]=imin;
+ }
+ } else --working;
+ }
+
+ return;
+ }
+ //#endif
+
screen_->computeBaseVectors();
// Necessary for KS integration, computes relation between
// observer's x,y,z coord and KS X,Y,Z coord. Will be used to
@@ -606,7 +672,69 @@ SmartPointer<Scenery> Gyoto::Scenery::Subcontractor(FactoryMessenger* fmp) {
if (name=="RelTol") sc -> ph_ . relTol(atof(content.c_str()));
}
+#ifdef HAVE_MPI
+
+ if (!Scenery::is_worker) {
+ sc -> mpiSpawn(5);
+ sc -> mpiClone();
+ }
+
+#endif
+ sleep(5);
return sc;
}
#endif
+
+//#ifdef HAVE_MPI
+bool Gyoto::Scenery::is_worker=false;
+
+void Gyoto::Scenery::mpiSpawn(int nbchildren) {
+ if (mpi_workers_) {
+ if (mpi_workers_->size()==nbchildren) return;
+ mpiTerminate(true);
+ }
+ if (!mpi_env_) mpi_env_ = new mpi::environment();
+ if (!mpi_world_) mpi_world_ = new mpi::communicator();
+
+ MPI_Comm children_c;
+ MPI_Comm_spawn("./gyoto-mpi-worker", MPI_ARGV_NULL, nbchildren,
+ MPI_INFO_NULL, 0, MPI_COMM_SELF, &children_c,
+ MPI_ERRCODES_IGNORE);
+
+ mpi_workers_ = new mpi::intercommunicator (children_c, mpi::comm_take_ownership);
+ cerr<<"mpi_workers_->remote_size()=="<<mpi_workers_->remote_size()<< endl;
+ int size;
+ MPI_Comm_remote_size(children_c, &size);
+ cerr<<"MPI_Comm_size(children_c)=="<<size<<endl;
+}
+
+void Gyoto::Scenery::mpiTerminate(bool keep_env) {
+ cerr << "Manager terminating workers"<< endl;
+ if (mpi_workers_) {
+ for (int i=0; i < mpi_workers_->remote_size(); ++i) {
+ cerr << "Manager killing worker #"<< i <<endl;
+ mpi_workers_->send(i, give_task, terminate);
+ }
+ delete mpi_workers_;
+ }
+ if (mpi_world_ && !keep_env) delete mpi_world_;
+ if (mpi_env_ && !keep_env) delete mpi_env_;
+}
+
+void Gyoto::Scenery::mpiClone()
+{
+ char * tmpfile_c="tmp-gyoto-sc.xml";
+ std::string tmpfile(tmpfile_c);
+ Gyoto::Factory(this).write(tmpfile_c);
+ int errcode;
+ cerr<<"mpi_workers_->remote_size()=="<<mpi_workers_->remote_size()<< endl;
+ for (int i=0; i < mpi_workers_->remote_size(); ++i) {
+ //mpi_workers_->recv(i, ready, errcode);
+ mpi_workers_->send(i, give_task, read_scenery);
+ mpi_workers_->send(i, read_scenery, tmpfile);
+ }
+
+}
+
+ //#endif
diff --git a/m4/ax_prog_cxx_mpi.m4 b/m4/ax_prog_cxx_mpi.m4
new file mode 100644
index 0000000..0a81dae
--- /dev/null
+++ b/m4/ax_prog_cxx_mpi.m4
@@ -0,0 +1,178 @@
+# ===========================================================================
+# http://www.gnu.org/software/autoconf-archive/ax_prog_cxx_mpi.html
+# ===========================================================================
+#
+# SYNOPSIS
+#
+# AX_PROG_CXX_MPI([MPI-WANTED-TEST[, ACTION-IF-FOUND[, ACTION-IF-NOT-FOUND]]])
+#
+# DESCRIPTION
+#
+# This macro tries to find out how to compile C++ programs that use MPI
+# (Message Passing Interface), a standard API for parallel process
+# communication (see http://www-unix.mcs.anl.gov/mpi/). The macro has to
+# be used instead of the standard macro AC_PROG_CXX and will replace the
+# standard variable CXX with the found compiler.
+#
+# MPI-WANTED-TEST is used to test whether MPI is actually wanted by the
+# user. If MPI-WANTED_TEST is omitted or if it succeeds, the macro will
+# try to find out how to use MPI, if it fails, the macro will call
+# AC_PROG_CC to find a standard C compiler instead.
+#
+# When MPI is found, ACTION-IF-FOUND will be executed, if MPI is not found
+# (or MPI-WANTED-TEST fails) ACTION-IF-NOT-FOUND is executed. If
+# ACTION-IF-FOUND is not set, the macro will define HAVE_MPI.
+#
+# The following example demonstrates usage of the macro:
+#
+# # If --with-mpi=auto is used, try to find MPI, but use standard C compiler if it is not found.
+# # If --with-mpi=yes is used, try to find MPI and fail if it isn't found.
+# # If --with-mpi=no is used, use a standard C compiler instead.
+# AC_ARG_WITH(mpi, [AS_HELP_STRING([--with-mpi],
+# [compile with MPI (parallelization) support. If none is found,
+# MPI is not used. Default: auto])
+# ],,[with_mpi=auto])
+#
+# AX_PROG_CXX_MPI([test x"$with_mpi" != xno],[use_mpi=yes],[
+# use_mpi=no
+# if test x"$with_mpi" = xyes; then
+# AC_MSG_FAILURE([MPI compiler requested, but couldn't use MPI.])
+# else
+# AC_MSG_WARN([No MPI compiler found, won't use MPI.])
+# fi
+# ])
+#
+# LICENSE
+#
+# Copyright (c) 2010,2011 Olaf Lenz <olenz at icp.uni-stuttgart.de>
+#
+# This program is free software: you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by the
+# Free Software Foundation, either version 3 of the License, or (at your
+# option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
+# Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program. If not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception, the respective Autoconf Macro's copyright owner
+# gives unlimited permission to copy, distribute and modify the configure
+# scripts that are the output of Autoconf when processing the Macro. You
+# need not follow the terms of the GNU General Public License when using
+# or distributing such scripts, even though portions of the text of the
+# Macro appear in them. The GNU General Public License (GPL) does govern
+# all other use of the material that constitutes the Autoconf Macro.
+#
+# This special exception to the GPL applies to versions of the Autoconf
+# Macro released by the Autoconf Archive. When you make and distribute a
+# modified version of the Autoconf Macro, you may extend this special
+# exception to the GPL to apply to your modified version as well.
+
+#serial 2
+
+AC_DEFUN([AX_PROG_CXX_MPI], [
+AC_PREREQ(2.50)
+
+# Check for compiler
+# Needs to be split off into an extra macro to ensure right expansion
+# order.
+AC_REQUIRE([_AX_PROG_CXX_MPI],[_AX_PROG_CXX_MPI([$1])])
+
+AS_IF([test x"$_ax_prog_cxx_mpi_mpi_wanted" = xno],
+ [ _ax_prog_cxx_mpi_mpi_found=no ],
+ [
+ AC_LANG_PUSH([C++])
+
+ # test whether MPI_Init() is available
+ # We do not use AC_SEARCH_LIBS here, as it caches its outcome and
+ # thus disallows corresponding calls in the other AX_PROG_*_MPI
+ # macros.
+ for lib in NONE mpi mpich; do
+ save_LIBS=$LIBS
+ if test x"$lib" = xNONE; then
+ AC_MSG_CHECKING([for function MPI_Init])
+ else
+ AC_MSG_CHECKING([for function MPI_Init in -l$lib])
+ LIBS="-l$lib $LIBS"
+ fi
+ AC_LINK_IFELSE([
+ AC_LANG_PROGRAM([
+extern "C" { void MPI_Init(); }
+],[MPI_Init();])],
+ [ _ax_prog_cxx_mpi_mpi_found=yes ],
+ [ _ax_prog_cxx_mpi_mpi_found=no ])
+ AC_MSG_RESULT($_ax_prog_cxx_mpi_mpi_found)
+ if test "x$_ax_prog_cxx_mpi_mpi_found" = "xyes"; then
+ break;
+ fi
+ LIBS=$save_LIBS
+ done
+
+ # Check for header
+ AS_IF([test x"$_ax_prog_cxx_mpi_mpi_found" = xyes], [
+ AC_MSG_CHECKING([for mpi.h])
+ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([#include <mpi.h>])],
+ [ AC_MSG_RESULT(yes)],
+ [ AC_MSG_RESULT(no)
+ _ax_prog_cxx_mpi_mpi_found=no
+ ])
+ ])
+ AC_LANG_POP([C++])
+])
+
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+AS_IF([test x"$_ax_prog_cxx_mpi_mpi_found" = xyes], [
+ ifelse([$2],,[AC_DEFINE(HAVE_MPI,1,[Define if you have the MPI library.])],[$2])
+ :
+],[
+ $3
+ :
+])
+
+])dnl AX_PROG_CXX_MPI
+
+dnl _AX_PROG_CXX_MPI is an internal macro required by AX_PROG_CXX_MPI.
+dnl To ensure the right expansion order, the main function AX_PROG_CXX_MPI
+dnl has to be split into two parts.
+dnl
+dnl Known MPI C++ compilers:
+dnl mpic++
+dnl mpicxx
+dnl mpiCC
+dnl sxmpic++ NEC SX
+dnl hcp
+dnl mpxlC_r
+dnl mpxlC
+dnl mpixlcxx_r
+dnl mpixlcxx
+dnl mpg++
+dnl mpc++
+dnl mpCC
+dnl cmpic++
+dnl mpiFCC Fujitsu
+dnl CC
+dnl
+AC_DEFUN([_AX_PROG_CXX_MPI], [
+ AC_ARG_VAR(MPICXX,[MPI C++ compiler command])
+ ifelse([$1],,[_ax_prog_cxx_mpi_mpi_wanted=yes],[
+ AC_MSG_CHECKING([whether to compile using MPI])
+ if $1; then
+ _ax_prog_cxx_mpi_mpi_wanted=yes
+ else
+ _ax_prog_cxx_mpi_mpi_wanted=no
+ fi
+ AC_MSG_RESULT($_ax_prog_cxx_mpi_mpi_wanted)
+ ])
+ if test x"$_ax_prog_cxx_mpi_mpi_wanted" = xyes; then
+ if test -z "$CXX" && test -n "$MPICXX"; then
+ CXX="$MPICXX"
+ else
+ AC_CHECK_TOOLS([CXX], [mpic++ mpicxx mpiCC sxmpic++ hcp mpxlC_r mpxlC mpixlcxx_r mpixlcxx mpg++ mpc++ mpCC cmpic++ mpiFCC CCicpc pgCC pathCC sxc++ xlC_r xlC bgxlC_r bgxlC openCC sunCC crayCC g++ c++ gpp aCC CC cxx cc++ cl.exe FCC KCC RCC])
+ fi
+ fi
+ AC_PROG_CXX
+])dnl _AX_PROG_CXX_MPI
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-astro/packages/gyoto.git
More information about the Debian-astro-commits
mailing list