From ab00218c1364c57212f139eca00c60b65a4fa0cd Mon Sep 17 00:00:00 2001 From: David Dickinson Date: Wed, 6 Feb 2019 15:21:27 +0000 Subject: [PATCH 01/19] Add pybind11 as a submodule --- .gitmodules | 3 +++ externalpackages/pybind11 | 1 + 2 files changed, 4 insertions(+) create mode 160000 externalpackages/pybind11 diff --git a/.gitmodules b/.gitmodules index c696c41a66..bcdc4d16c7 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "externalpackages/git-archive-all.sh"] path = externalpackages/git-archive-all.sh url = https://github.com/meitar/git-archive-all.sh/ +[submodule "externalpackages/pybind11"] + path = externalpackages/pybind11 + url = https://github.com/pybind/pybind11.git diff --git a/externalpackages/pybind11 b/externalpackages/pybind11 new file mode 160000 index 0000000000..25abf7efba --- /dev/null +++ b/externalpackages/pybind11 @@ -0,0 +1 @@ +Subproject commit 25abf7efba0b2990f5a6dfb0a31bc65c0f2f4d17 From 03c1ed2e34cc21fc29d0a55726177632e44de49c Mon Sep 17 00:00:00 2001 From: David Dickinson Date: Wed, 6 Feb 2019 16:19:12 +0000 Subject: [PATCH 02/19] Add pybind11 setup to configure --- configure | 89 +++++++++++++++++++++++++++++++++++++++------------- configure.ac | 23 ++++++++++++++ 2 files changed, 90 insertions(+), 22 deletions(-) diff --git a/configure b/configure index e6b2c4a800..3692cedbd9 100755 --- a/configure +++ b/configure @@ -624,6 +624,7 @@ ac_includes_default="\ gt_needs= ac_subst_vars='HAS_FFTW HAS_NLS +HAS_PYBIND11 HAS_OPENMP SLEPC_ARCH SLEPC_DIR @@ -767,6 +768,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -799,6 +801,7 @@ with_lapack with_petsc with_slepc with_pvode +with_pybind11 with_mumps with_arkode with_scorep @@ -879,6 +882,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -1131,6 +1135,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1268,7 +1281,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1421,6 +1434,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1486,6 +1500,7 @@ Optional Packages: --with-petsc Enable PETSc interface --with-slepc Enable SLEPc interface --with-pvode Build and enable PVODE 98 (DEFAULT) + --with-pybind11 Enable pybind11 bindings (DEFAULT) --with-mumps Link with MUMPS library for direct matrix inversions --with-arkode Use the SUNDIALS ARKODE solver --with-scorep Enable support for scorep based instrumentation @@ -2610,6 +2625,14 @@ if test "${with_pvode+set}" = set; then : fi +# Check whether --with-pybind11 was given. +if test "${with_pybind11+set}" = set; then : + withval=$with_pybind11; +else + with_pybind11=yes +fi + + # Check whether --with-mumps was given. if test "${with_mumps+set}" = set; then : withval=$with_mumps; @@ -12218,6 +12241,38 @@ fi fi +############################################################# +# Enable pybind11 -- fetch submodule if required +############################################################# + +HAS_PYBIND11="no" +if test "$with_pybind11" != "no"; then : + + if test -f externalpackages/pybind11/README.md; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: Using existing pybind11 submodule" >&5 +$as_echo "$as_me: Using existing pybind11 submodule" >&6;} + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: Getting pybind11 submodule" >&5 +$as_echo "$as_me: Getting pybind11 submodule" >&6;} + if git submodule update --init --recursive -- externalpackages/pybind11; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: Success in getting pybind11" >&5 +$as_echo "$as_me: Success in getting pybind11" >&6;} +else + as_fn_error $? "Failed to get pybind11" "$LINENO" 5 +fi + +fi + CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11" + HAS_PYBIND11="yes" + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: Building without pybind11 submodule" >&5 +$as_echo "$as_me: Building without pybind11 submodule" >&6;} +fi + ############################################################# # Localisation (i18n) with gettext ############################################################# @@ -13437,21 +13492,16 @@ else /* end confdefs.h. */ #include -#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +$gt_revision_test_code extern int _nl_msg_cat_cntr; extern int *_nl_domain_bindings; -#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_domain_bindings) -#else -#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 -#endif -$gt_revision_test_code int main () { bindtextdomain ("", ""); -return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_domain_bindings ; return 0; @@ -14204,25 +14254,20 @@ else /* end confdefs.h. */ #include -#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +$gt_revision_test_code extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); -#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) -#else -#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 -#endif -$gt_revision_test_code int main () { bindtextdomain ("", ""); -return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") ; return 0; @@ -14241,25 +14286,20 @@ rm -f core conftest.err conftest.$ac_objext \ /* end confdefs.h. */ #include -#ifndef __GNU_GETTEXT_SUPPORTED_REVISION +$gt_revision_test_code extern int _nl_msg_cat_cntr; extern #ifdef __cplusplus "C" #endif const char *_nl_expand_alias (const char *); -#define __GNU_GETTEXT_SYMBOL_EXPRESSION (_nl_msg_cat_cntr + *_nl_expand_alias ("")) -#else -#define __GNU_GETTEXT_SYMBOL_EXPRESSION 0 -#endif -$gt_revision_test_code int main () { bindtextdomain ("", ""); -return * gettext ("")$gt_expression_test_code + __GNU_GETTEXT_SYMBOL_EXPRESSION +return * gettext ("")$gt_expression_test_code + _nl_msg_cat_cntr + *_nl_expand_alias ("") ; return 0; @@ -15845,6 +15885,7 @@ BOUT_INCLUDE_PATH=$PWD/include + ac_config_files="$ac_config_files bin/bout-config" @@ -17179,6 +17220,8 @@ $as_echo "$as_me: PETSc support : $HAS_PETSC (has SUNDIALS: $PETSC_H $as_echo "$as_me: SLEPc support : $HAS_SLEPC" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: IDA support : $HAS_IDA" >&5 $as_echo "$as_me: IDA support : $HAS_IDA" >&6;} +{ $as_echo "$as_me:${as_lineno-$LINENO}: PVODE support : $HAS_PVODE" >&5 +$as_echo "$as_me: PVODE support : $HAS_PVODE" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: CVODE support : $HAS_CVODE" >&5 $as_echo "$as_me: CVODE support : $HAS_CVODE" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: ARKODE support : $HAS_ARKODE" >&5 @@ -17197,6 +17240,8 @@ $as_echo "$as_me: MUMPS support : $HAS_MUMPS" >&6;} $as_echo "$as_me: Lapack support : $HAS_LAPACK" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: Scorep support : $HAS_SCOREP" >&5 $as_echo "$as_me: Scorep support : $HAS_SCOREP" >&6;} +{ $as_echo "$as_me:${as_lineno-$LINENO}: PyBind11 support : $HAS_PYBIND11" >&5 +$as_echo "$as_me: PyBind11 support : $HAS_PYBIND11" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: OpenMP support : $HAS_OPENMP (schedule: $OPENMP_SCHEDULE)" >&5 $as_echo "$as_me: OpenMP support : $HAS_OPENMP (schedule: $OPENMP_SCHEDULE)" >&6;} { $as_echo "$as_me:${as_lineno-$LINENO}: Natural language support: $HAS_NLS (path: $localedir)" >&5 diff --git a/configure.ac b/configure.ac index a0ac467667..37ca27c818 100644 --- a/configure.ac +++ b/configure.ac @@ -56,6 +56,8 @@ AC_ARG_WITH(slepc, [AS_HELP_STRING([--with-slepc], [Enable SLEPc interface])],,[with_slepc=no]) AC_ARG_WITH(pvode, [AS_HELP_STRING([--with-pvode], [Build and enable PVODE 98 (DEFAULT)])],,[]) +AC_ARG_WITH(pybind11, [AS_HELP_STRING([--with-pybind11], + [Enable pybind11 bindings (DEFAULT)])],,[with_pybind11=yes]) AC_ARG_WITH(mumps, [AS_HELP_STRING([--with-mumps], [Link with MUMPS library for direct matrix inversions])],,[]) AC_ARG_WITH(arkode, [AS_HELP_STRING([--with-arkode], @@ -1150,6 +1152,24 @@ AS_IF([test "$with_pvode" != "no"], [ HAS_PVODE="yes" ]) +############################################################# +# Enable pybind11 -- fetch submodule if required +############################################################# + +HAS_PYBIND11="no" +AS_IF([test "$with_pybind11" != "no"], [ + AS_IF([test -f externalpackages/pybind11/README.md], [ + AC_MSG_NOTICE([Using existing pybind11 submodule]) + ], [ + AC_MSG_NOTICE([Getting pybind11 submodule]) + AS_IF([git submodule update --init --recursive -- externalpackages/pybind11], + [AC_MSG_NOTICE([Success in getting pybind11])], + [AC_MSG_ERROR([Failed to get pybind11])]) + ]) + CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11" + HAS_PYBIND11="yes" +], [AC_MSG_NOTICE([Building without pybind11 submodule])]) + ############################################################# # Localisation (i18n) with gettext ############################################################# @@ -1293,6 +1313,7 @@ AC_SUBST(SLEPC_MAKE_INCLUDE) AC_SUBST(SLEPC_DIR) AC_SUBST(SLEPC_ARCH) AC_SUBST(HAS_OPENMP) +AC_SUBST(HAS_PYBIND11) AC_SUBST(HAS_NLS) AC_SUBST(HAS_FFTW) @@ -1311,6 +1332,7 @@ AC_MSG_NOTICE([-------------------------]) AC_MSG_NOTICE([ PETSc support : $HAS_PETSC (has SUNDIALS: $PETSC_HAS_SUNDIALS)]) AC_MSG_NOTICE([ SLEPc support : $HAS_SLEPC]) AC_MSG_NOTICE([ IDA support : $HAS_IDA]) +AC_MSG_NOTICE([ PVODE support : $HAS_PVODE]) AC_MSG_NOTICE([ CVODE support : $HAS_CVODE]) AC_MSG_NOTICE([ ARKODE support : $HAS_ARKODE]) AC_MSG_NOTICE([ FFTW support : $HAS_FFTW]) @@ -1320,6 +1342,7 @@ AC_MSG_NOTICE([ HDF5 support : $HAS_HDF5 (parallel: $HAS_PHDF5)]) AC_MSG_NOTICE([ MUMPS support : $HAS_MUMPS]) AC_MSG_NOTICE([ Lapack support : $HAS_LAPACK]) AC_MSG_NOTICE([ Scorep support : $HAS_SCOREP]) +AC_MSG_NOTICE([ PyBind11 support : $HAS_PYBIND11]) AC_MSG_NOTICE([ OpenMP support : $HAS_OPENMP (schedule: $OPENMP_SCHEDULE)]) AC_MSG_NOTICE([ Natural language support: $HAS_NLS (path: $localedir)]) From bded50fba4e0e593df96bee728368dd44544779c Mon Sep 17 00:00:00 2001 From: David Dickinson Date: Wed, 6 Feb 2019 16:23:39 +0000 Subject: [PATCH 03/19] Ensure building unit tests only fetches required submodules rather than all --- tests/unit/makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/makefile b/tests/unit/makefile index dc971e959c..92f5b95732 100644 --- a/tests/unit/makefile +++ b/tests/unit/makefile @@ -44,7 +44,7 @@ clean :: # Download Google Test $(GTEST_SENTINEL) : echo "Downloading Google Test" - git submodule update --init --recursive + git submodule update --init --recursive -- ${GTEST_BASE} # For simplicity and to avoid depending on Google Test's # implementation details, the dependencies specified below are From 33c4c558799f8f54627bfdff285c1718b59641d9 Mon Sep 17 00:00:00 2001 From: David Dickinson Date: Wed, 6 Feb 2019 16:40:47 +0000 Subject: [PATCH 04/19] Add the required extra python headers to EXTRA_INCS In the long run we may want to put these into a separate variable as only required when building the wrappers --- configure | 3 ++- configure.ac | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/configure b/configure index 3692cedbd9..22e0546af9 100755 --- a/configure +++ b/configure @@ -12265,7 +12265,8 @@ else fi fi - CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11" + CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11 -fPIC" + EXTRA_INCS="$EXTRA_INCS $(PYTHONPATH=${PYTHONPATH}:${PWD}/externalpackages/pybind11 python3 -m pybind11 --includes)" HAS_PYBIND11="yes" else diff --git a/configure.ac b/configure.ac index 37ca27c818..fa73508b27 100644 --- a/configure.ac +++ b/configure.ac @@ -1166,7 +1166,8 @@ AS_IF([test "$with_pybind11" != "no"], [ [AC_MSG_NOTICE([Success in getting pybind11])], [AC_MSG_ERROR([Failed to get pybind11])]) ]) - CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11" + CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11 -fPIC" + EXTRA_INCS="$EXTRA_INCS $(PYTHONPATH=${PYTHONPATH}:${PWD}/externalpackages/pybind11 python3 -m pybind11 --includes)" HAS_PYBIND11="yes" ], [AC_MSG_NOTICE([Building without pybind11 submodule])]) From 24228737dd9355dc4261d897dc1a4019c47ea70c Mon Sep 17 00:00:00 2001 From: David Dickinson Date: Wed, 6 Feb 2019 16:51:18 +0000 Subject: [PATCH 05/19] Make links to the pybind11 headers in include --- .gitignore | 2 +- configure | 91 +++++++++++++++++++++++++++++++++++++++++++++++++--- configure.ac | 14 +++++--- 3 files changed, 97 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index ace943d4ef..3dbce03c59 100644 --- a/.gitignore +++ b/.gitignore @@ -39,4 +39,4 @@ bout-coverage/ src/.libfast .*.mk *.mo - +include/pybind11 diff --git a/configure b/configure index 22e0546af9..56020d9f4a 100755 --- a/configure +++ b/configure @@ -12246,9 +12246,10 @@ fi ############################################################# HAS_PYBIND11="no" +PYBIND_TARGET_DIR=externalpackages/pybind11 if test "$with_pybind11" != "no"; then : - if test -f externalpackages/pybind11/README.md; then : + if test -f ${PYBIND_TARGET_DIR}/README.md; then : { $as_echo "$as_me:${as_lineno-$LINENO}: Using existing pybind11 submodule" >&5 $as_echo "$as_me: Using existing pybind11 submodule" >&6;} @@ -12257,7 +12258,7 @@ else { $as_echo "$as_me:${as_lineno-$LINENO}: Getting pybind11 submodule" >&5 $as_echo "$as_me: Getting pybind11 submodule" >&6;} - if git submodule update --init --recursive -- externalpackages/pybind11; then : + if git submodule update --init --recursive -- ${PYBIND_TARGET_DIR}; then : { $as_echo "$as_me:${as_lineno-$LINENO}: Success in getting pybind11" >&5 $as_echo "$as_me: Success in getting pybind11" >&6;} else @@ -12265,10 +12266,16 @@ else fi fi + #Note the following overlap with --enable-shared, we should probably force enabled_shared here CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11 -fPIC" - EXTRA_INCS="$EXTRA_INCS $(PYTHONPATH=${PYTHONPATH}:${PWD}/externalpackages/pybind11 python3 -m pybind11 --includes)" + EXTRA_INCS="$EXTRA_INCS $(PYTHONPATH=${PYTHONPATH}:${PWD}/${PYBIND_TARGET_DIR} python3 -m pybind11 --includes)" HAS_PYBIND11="yes" + #Now copy the pybind headers into bout includes + #AS_MKDIR_P(include/pybind11) + ac_config_links="$ac_config_links include/pybind11:${PYBIND_TARGET_DIR}/include/pybind11/" + + else { $as_echo "$as_me:${as_lineno-$LINENO}: Building without pybind11 submodule" >&5 $as_echo "$as_me: Building without pybind11 submodule" >&6;} @@ -15092,6 +15099,7 @@ esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" +config_links="$ac_config_links" config_commands="$ac_config_commands" _ACEOF @@ -15117,6 +15125,9 @@ Usage: $0 [OPTION]... [TAG]... Configuration files: $config_files +Configuration links: +$config_links + Configuration commands: $config_commands @@ -15250,6 +15261,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 for ac_config_target in $ac_config_targets do case $ac_config_target in + "include/pybind11") CONFIG_LINKS="$CONFIG_LINKS include/pybind11:${PYBIND_TARGET_DIR}/include/pybind11/" ;; "po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;; "make.config") CONFIG_FILES="$CONFIG_FILES make.config" ;; @@ -15264,6 +15276,7 @@ done # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi @@ -15453,7 +15466,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" -eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" +eval set X " :F $CONFIG_FILES :L $CONFIG_LINKS :C $CONFIG_COMMANDS" shift for ac_tag do @@ -15673,7 +15686,38 @@ which seems to be undefined. Please make sure it is defined" >&2;} || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + :L) + # + # CONFIG_LINK + # + if test "$ac_source" = "$ac_file" && test "$srcdir" = '.'; then + : + else + # Prefer the file from the source tree if names are identical. + if test "$ac_source" = "$ac_file" || test ! -r "$ac_source"; then + ac_source=$srcdir/$ac_source + fi + + { $as_echo "$as_me:${as_lineno-$LINENO}: linking $ac_source to $ac_file" >&5 +$as_echo "$as_me: linking $ac_source to $ac_file" >&6;} + + if test ! -r "$ac_source"; then + as_fn_error $? "$ac_source: file not found" "$LINENO" 5 + fi + rm -f "$ac_file" + + # Try a relative symlink, then a hard link, then a copy. + case $ac_source in + [\\/$]* | ?:[\\/]* ) ac_rel_source=$ac_source ;; + *) ac_rel_source=$ac_top_build_prefix$ac_source ;; + esac + ln -s "$ac_rel_source" "$ac_file" 2>/dev/null || + ln "$ac_source" "$ac_file" 2>/dev/null || + cp -p "$ac_source" "$ac_file" || + as_fn_error $? "cannot link or copy $ac_source to $ac_file" "$LINENO" 5 + fi + ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; @@ -16460,6 +16504,7 @@ esac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 # Files that config.status was made for. config_files="$ac_config_files" +config_links="$ac_config_links" config_commands="$ac_config_commands" _ACEOF @@ -16485,6 +16530,9 @@ Usage: $0 [OPTION]... [TAG]... Configuration files: $config_files +Configuration links: +$config_links + Configuration commands: $config_commands @@ -16618,6 +16666,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 for ac_config_target in $ac_config_targets do case $ac_config_target in + "include/pybind11") CONFIG_LINKS="$CONFIG_LINKS include/pybind11:${PYBIND_TARGET_DIR}/include/pybind11/" ;; "po-directories") CONFIG_COMMANDS="$CONFIG_COMMANDS po-directories" ;; "make.config") CONFIG_FILES="$CONFIG_FILES make.config" ;; "bin/bout-config") CONFIG_FILES="$CONFIG_FILES bin/bout-config" ;; @@ -16633,6 +16682,7 @@ done # bizarre bug on SunOS 4.1.3. if $ac_need_defaults; then test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files + test "${CONFIG_LINKS+set}" = set || CONFIG_LINKS=$config_links test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands fi @@ -16822,7 +16872,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 fi # test -n "$CONFIG_FILES" -eval set X " :F $CONFIG_FILES :C $CONFIG_COMMANDS" +eval set X " :F $CONFIG_FILES :L $CONFIG_LINKS :C $CONFIG_COMMANDS" shift for ac_tag do @@ -17042,7 +17092,38 @@ which seems to be undefined. Please make sure it is defined" >&2;} || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; + :L) + # + # CONFIG_LINK + # + + if test "$ac_source" = "$ac_file" && test "$srcdir" = '.'; then + : + else + # Prefer the file from the source tree if names are identical. + if test "$ac_source" = "$ac_file" || test ! -r "$ac_source"; then + ac_source=$srcdir/$ac_source + fi + { $as_echo "$as_me:${as_lineno-$LINENO}: linking $ac_source to $ac_file" >&5 +$as_echo "$as_me: linking $ac_source to $ac_file" >&6;} + + if test ! -r "$ac_source"; then + as_fn_error $? "$ac_source: file not found" "$LINENO" 5 + fi + rm -f "$ac_file" + + # Try a relative symlink, then a hard link, then a copy. + case $ac_source in + [\\/$]* | ?:[\\/]* ) ac_rel_source=$ac_source ;; + *) ac_rel_source=$ac_top_build_prefix$ac_source ;; + esac + ln -s "$ac_rel_source" "$ac_file" 2>/dev/null || + ln "$ac_source" "$ac_file" 2>/dev/null || + cp -p "$ac_source" "$ac_file" || + as_fn_error $? "cannot link or copy $ac_source to $ac_file" "$LINENO" 5 + fi + ;; :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 $as_echo "$as_me: executing $ac_file commands" >&6;} ;; diff --git a/configure.ac b/configure.ac index fa73508b27..6df3db76da 100644 --- a/configure.ac +++ b/configure.ac @@ -1157,18 +1157,24 @@ AS_IF([test "$with_pvode" != "no"], [ ############################################################# HAS_PYBIND11="no" +PYBIND_TARGET_DIR=externalpackages/pybind11 AS_IF([test "$with_pybind11" != "no"], [ - AS_IF([test -f externalpackages/pybind11/README.md], [ + AS_IF([test -f ${PYBIND_TARGET_DIR}/README.md], [ AC_MSG_NOTICE([Using existing pybind11 submodule]) ], [ AC_MSG_NOTICE([Getting pybind11 submodule]) - AS_IF([git submodule update --init --recursive -- externalpackages/pybind11], + AS_IF([git submodule update --init --recursive -- ${PYBIND_TARGET_DIR}], [AC_MSG_NOTICE([Success in getting pybind11])], [AC_MSG_ERROR([Failed to get pybind11])]) ]) - CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11 -fPIC" - EXTRA_INCS="$EXTRA_INCS $(PYTHONPATH=${PYTHONPATH}:${PWD}/externalpackages/pybind11 python3 -m pybind11 --includes)" + #Note the following overlap with --enable-shared, we should probably force enabled_shared here + CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11 -fPIC" + EXTRA_INCS="$EXTRA_INCS $(PYTHONPATH=${PYTHONPATH}:${PWD}/${PYBIND_TARGET_DIR} python3 -m pybind11 --includes)" HAS_PYBIND11="yes" + + #Now copy/link the pybind headers into bout includes + AC_CONFIG_LINKS(include/pybind11:${PYBIND_TARGET_DIR}/include/pybind11/) + ], [AC_MSG_NOTICE([Building without pybind11 submodule])]) ############################################################# From 331c1f6a89632b940622887674ebdbea2e9b872a Mon Sep 17 00:00:00 2001 From: David Dickinson Date: Wed, 6 Feb 2019 19:37:22 +0000 Subject: [PATCH 06/19] Provide full set of flags needed to link a program using python through pybind11 --- configure | 287 ++++++++++++++++++++++++++++++++++++++++++++++++++- configure.ac | 11 +- 2 files changed, 294 insertions(+), 4 deletions(-) diff --git a/configure b/configure index 56020d9f4a..f9a944f784 100755 --- a/configure +++ b/configure @@ -680,6 +680,15 @@ GMSGFMT MSGFMT GETTEXT_MACRO_VERSION USE_NLS +pkgpyexecdir +pyexecdir +pkgpythondir +pythondir +PYTHON_PLATFORM +PYTHON_EXEC_PREFIX +PYTHON_PREFIX +PYTHON_VERSION +PYTHON SCOREPPATH sundials_config PARALLELHDF5_TYPE @@ -843,7 +852,8 @@ CCC CXXCPP CC CFLAGS -CPP' +CPP +PYTHON' # Initialize some variables set by options. @@ -1530,6 +1540,7 @@ Some influential environment variables: CC C compiler command CFLAGS C compiler flags CPP C preprocessor + PYTHON the Python interpreter Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -12268,14 +12279,284 @@ fi fi #Note the following overlap with --enable-shared, we should probably force enabled_shared here CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11 -fPIC" + + #We require python if using pybind11 so check we have access to it + #Note strictly pybind11 can work with python 2 and 3, but here we + #restrict ourselves to >= v3.0. This will abort configure if a suitable + #interpreter isn't found + + + + + + + if test -n "$PYTHON"; then + # If the user set $PYTHON, use it and don't search something else. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version is >= 3" >&5 +$as_echo_n "checking whether $PYTHON version is >= 3... " >&6; } + prog="import sys +# split strings by '.' and convert to numeric. Append some zeros +# because we need at least 4 digits for the hex conversion. +# map returns an iterator in Python 3.0 and a list in 2.x +minver = list(map(int, '3'.split('.'))) + [0, 0, 0] +minverhex = 0 +# xrange is not present in Python 3.0 and range returns an iterator +for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] +sys.exit(sys.hexversion < minverhex)" + if { echo "$as_me:$LINENO: $PYTHON -c "$prog"" >&5 + ($PYTHON -c "$prog") >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; 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; } + as_fn_error $? "Python interpreter is too old" "$LINENO" 5 +fi + am_display_PYTHON=$PYTHON + else + # Otherwise, try each interpreter until we find one that satisfies + # VERSION. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a Python interpreter with version >= 3" >&5 +$as_echo_n "checking for a Python interpreter with version >= 3... " >&6; } +if ${am_cv_pathless_PYTHON+:} false; then : + $as_echo_n "(cached) " >&6 +else + + for am_cv_pathless_PYTHON in python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do + test "$am_cv_pathless_PYTHON" = none && break + prog="import sys +# split strings by '.' and convert to numeric. Append some zeros +# because we need at least 4 digits for the hex conversion. +# map returns an iterator in Python 3.0 and a list in 2.x +minver = list(map(int, '3'.split('.'))) + [0, 0, 0] +minverhex = 0 +# xrange is not present in Python 3.0 and range returns an iterator +for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] +sys.exit(sys.hexversion < minverhex)" + if { echo "$as_me:$LINENO: $am_cv_pathless_PYTHON -c "$prog"" >&5 + ($am_cv_pathless_PYTHON -c "$prog") >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then : + break +fi + done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_pathless_PYTHON" >&5 +$as_echo "$am_cv_pathless_PYTHON" >&6; } + # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. + if test "$am_cv_pathless_PYTHON" = none; then + PYTHON=: + else + # Extract the first word of "$am_cv_pathless_PYTHON", so it can be a program name with args. +set dummy $am_cv_pathless_PYTHON; 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_path_PYTHON+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $PYTHON in + [\\/]* | ?:[\\/]*) + ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. + ;; + *) + 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_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" + $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 + + ;; +esac +fi +PYTHON=$ac_cv_path_PYTHON +if test -n "$PYTHON"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 +$as_echo "$PYTHON" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + fi + am_display_PYTHON=$am_cv_pathless_PYTHON + fi + + + if test "$PYTHON" = :; then + as_fn_error $? "no suitable Python interpreter found" "$LINENO" 5 + else + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON version" >&5 +$as_echo_n "checking for $am_display_PYTHON version... " >&6; } +if ${am_cv_python_version+:} false; then : + $as_echo_n "(cached) " >&6 +else + am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5 +$as_echo "$am_cv_python_version" >&6; } + PYTHON_VERSION=$am_cv_python_version + + + + PYTHON_PREFIX='${prefix}' + + PYTHON_EXEC_PREFIX='${exec_prefix}' + + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON platform" >&5 +$as_echo_n "checking for $am_display_PYTHON platform... " >&6; } +if ${am_cv_python_platform+:} false; then : + $as_echo_n "(cached) " >&6 +else + am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_platform" >&5 +$as_echo "$am_cv_python_platform" >&6; } + PYTHON_PLATFORM=$am_cv_python_platform + + + # Just factor out some code duplication. + am_python_setup_sysconfig="\ +import sys +# Prefer sysconfig over distutils.sysconfig, for better compatibility +# with python 3.x. See automake bug#10227. +try: + import sysconfig +except ImportError: + can_use_sysconfig = 0 +else: + can_use_sysconfig = 1 +# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs: +# +try: + from platform import python_implementation + if python_implementation() == 'CPython' and sys.version[:3] == '2.7': + can_use_sysconfig = 0 +except ImportError: + pass" + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5 +$as_echo_n "checking for $am_display_PYTHON script directory... " >&6; } +if ${am_cv_python_pythondir+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$prefix" = xNONE + then + am_py_prefix=$ac_default_prefix + else + am_py_prefix=$prefix + fi + am_cv_python_pythondir=`$PYTHON -c " +$am_python_setup_sysconfig +if can_use_sysconfig: + sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'}) +else: + from distutils import sysconfig + sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') +sys.stdout.write(sitedir)"` + case $am_cv_python_pythondir in + $am_py_prefix*) + am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` + am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` + ;; + *) + case $am_py_prefix in + /usr|/System*) ;; + *) + am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pythondir" >&5 +$as_echo "$am_cv_python_pythondir" >&6; } + pythondir=$am_cv_python_pythondir + + + + pkgpythondir=\${pythondir}/$PACKAGE + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory" >&5 +$as_echo_n "checking for $am_display_PYTHON extension module directory... " >&6; } +if ${am_cv_python_pyexecdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$exec_prefix" = xNONE + then + am_py_exec_prefix=$am_py_prefix + else + am_py_exec_prefix=$exec_prefix + fi + am_cv_python_pyexecdir=`$PYTHON -c " +$am_python_setup_sysconfig +if can_use_sysconfig: + sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'}) +else: + from distutils import sysconfig + sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix') +sys.stdout.write(sitedir)"` + case $am_cv_python_pyexecdir in + $am_py_exec_prefix*) + am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` + am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` + ;; + *) + case $am_py_exec_prefix in + /usr|/System*) ;; + *) + am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pyexecdir" >&5 +$as_echo "$am_cv_python_pyexecdir" >&6; } + pyexecdir=$am_cv_python_pyexecdir + + + + pkgpyexecdir=\${pyexecdir}/$PACKAGE + + + { $as_echo "$as_me:${as_lineno-$LINENO}: Found python version $PYTHON_VERSION" >&5 +$as_echo "$as_me: Found python version $PYTHON_VERSION" >&6;} + fi + + EXTRA_INCS="$EXTRA_INCS $(PYTHONPATH=${PYTHONPATH}:${PWD}/${PYBIND_TARGET_DIR} python3 -m pybind11 --includes)" + EXTRA_LIBS="$EXTRA_LIBS $(python3-config --libs)" + LDFLAGS="$LDFLAGS $(python3-config --ldflags)" + HAS_PYBIND11="yes" - #Now copy the pybind headers into bout includes - #AS_MKDIR_P(include/pybind11) + #Now copy/link the pybind headers into bout includes ac_config_links="$ac_config_links include/pybind11:${PYBIND_TARGET_DIR}/include/pybind11/" + else { $as_echo "$as_me:${as_lineno-$LINENO}: Building without pybind11 submodule" >&5 $as_echo "$as_me: Building without pybind11 submodule" >&6;} diff --git a/configure.ac b/configure.ac index 6df3db76da..54ec6e113e 100644 --- a/configure.ac +++ b/configure.ac @@ -1168,8 +1168,17 @@ AS_IF([test "$with_pybind11" != "no"], [ [AC_MSG_ERROR([Failed to get pybind11])]) ]) #Note the following overlap with --enable-shared, we should probably force enabled_shared here - CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11 -fPIC" + CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11 -fPIC" + + #We require python if using pybind11 so check we have access to it + #Note strictly pybind11 can work with python 2 and 3, but here we + #restrict ourselves to >= v3.0. This will abort configure if a suitable + #interpreter isn't found + AM_PATH_PYTHON([3],AC_MSG_NOTICE([Found python version $PYTHON_VERSION])) EXTRA_INCS="$EXTRA_INCS $(PYTHONPATH=${PYTHONPATH}:${PWD}/${PYBIND_TARGET_DIR} python3 -m pybind11 --includes)" + EXTRA_LIBS="$EXTRA_LIBS $(python3-config --libs)" + LDFLAGS="$LDFLAGS $(python3-config --ldflags)" + HAS_PYBIND11="yes" #Now copy/link the pybind headers into bout includes From b1d4c42542547089dfee7c2b1427cbd46b55d1f9 Mon Sep 17 00:00:00 2001 From: David Dickinson Date: Wed, 6 Feb 2019 19:44:22 +0000 Subject: [PATCH 07/19] Adding simple example demonstrating the use of pybind11 for calling python from C++ --- examples/pybind-embed/.gitignore | 1 + examples/pybind-embed/README.md | 4 ++++ examples/pybind-embed/makefile | 8 +++++++ examples/pybind-embed/pybind_embed.cxx | 29 ++++++++++++++++++++++++++ 4 files changed, 42 insertions(+) create mode 100644 examples/pybind-embed/.gitignore create mode 100644 examples/pybind-embed/README.md create mode 100644 examples/pybind-embed/makefile create mode 100644 examples/pybind-embed/pybind_embed.cxx diff --git a/examples/pybind-embed/.gitignore b/examples/pybind-embed/.gitignore new file mode 100644 index 0000000000..2f8392e7bb --- /dev/null +++ b/examples/pybind-embed/.gitignore @@ -0,0 +1 @@ +pybind_embed \ No newline at end of file diff --git a/examples/pybind-embed/README.md b/examples/pybind-embed/README.md new file mode 100644 index 0000000000..8bfeaf2a4e --- /dev/null +++ b/examples/pybind-embed/README.md @@ -0,0 +1,4 @@ +# Example: PyBind_embed + +A very simple example demonstrating the use of pybind11 to embed a +python interpreter inside a C++ program. \ No newline at end of file diff --git a/examples/pybind-embed/makefile b/examples/pybind-embed/makefile new file mode 100644 index 0000000000..5833b41ccd --- /dev/null +++ b/examples/pybind-embed/makefile @@ -0,0 +1,8 @@ + +BOUT_TOP = ../.. + +SOURCEC = pybind_embed.cxx + +BOUT_LIBS+=$(python3-config --libs) + +include $(BOUT_TOP)/make.config diff --git a/examples/pybind-embed/pybind_embed.cxx b/examples/pybind-embed/pybind_embed.cxx new file mode 100644 index 0000000000..412675b0c7 --- /dev/null +++ b/examples/pybind-embed/pybind_embed.cxx @@ -0,0 +1,29 @@ +#ifdef BOUT_HAS_PYBIND11 +#include + +namespace py = pybind11; +using namespace py::literals; + +// Provide a simple function that returns an int +int myFunc(){ + return 42; +}; + +int main() { + // Get access to a python interpreter with lifetime of the current scope + py::scoped_interpreter guard{}; + + // Construct a python dictionary -- note this includes a call + // to a native C++ method as well as including constants. + auto kwargs = py::dict("name"_a="BOUT++ user", + "number"_a=myFunc(), + "floatNumber"_a=1.2345 + ); + // Format the string using the dictionary constructed above + auto message = "Hello, {name}! The answer is {number} and not {floatNumber}"_s.format(**kwargs); + // Display message + py::print(message); +} +#else +#error Must configure with `--with-pybind11` to be able to build pybind_embed example. +#endif From d11fbed03fe0b594ef09208be14c135beaec968f Mon Sep 17 00:00:00 2001 From: David Dickinson Date: Wed, 6 Feb 2019 19:56:29 +0000 Subject: [PATCH 08/19] Require active enabling of pybind11 Require enable-shared=yes if we turn on pybind11 --- configure | 1323 +++++++++++++++++++++++++------------------------- configure.ac | 74 +-- 2 files changed, 703 insertions(+), 694 deletions(-) diff --git a/configure b/configure index f9a944f784..a1dd9dbe24 100755 --- a/configure +++ b/configure @@ -680,15 +680,6 @@ GMSGFMT MSGFMT GETTEXT_MACRO_VERSION USE_NLS -pkgpyexecdir -pyexecdir -pkgpythondir -pythondir -PYTHON_PLATFORM -PYTHON_EXEC_PREFIX -PYTHON_PREFIX -PYTHON_VERSION -PYTHON SCOREPPATH sundials_config PARALLELHDF5_TYPE @@ -715,6 +706,15 @@ AWK NCMPIDUMP_PATH NCCONF fftw_path +pkgpyexecdir +pyexecdir +pkgpythondir +pythondir +PYTHON_PLATFORM +PYTHON_EXEC_PREFIX +PYTHON_PREFIX +PYTHON_VERSION +PYTHON works COVERAGE_FLAGS CODE_COVERAGE_RULES @@ -850,10 +850,10 @@ CXX CPPFLAGS CCC CXXCPP +PYTHON CC CFLAGS -CPP -PYTHON' +CPP' # Initialize some variables set by options. @@ -1510,7 +1510,7 @@ Optional Packages: --with-petsc Enable PETSc interface --with-slepc Enable SLEPc interface --with-pvode Build and enable PVODE 98 (DEFAULT) - --with-pybind11 Enable pybind11 bindings (DEFAULT) + --with-pybind11 Enable pybind11 bindings --with-mumps Link with MUMPS library for direct matrix inversions --with-arkode Use the SUNDIALS ARKODE solver --with-scorep Enable support for scorep based instrumentation @@ -1537,10 +1537,10 @@ Some influential environment variables: CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if you have headers in a nonstandard directory CXXCPP C++ preprocessor + PYTHON the Python interpreter CC C compiler command CFLAGS C compiler flags CPP C preprocessor - PYTHON the Python interpreter Use these variables to override the choices made by `configure' or to help it to find libraries and programs with nonstandard names/locations. @@ -2640,7 +2640,7 @@ fi if test "${with_pybind11+set}" = set; then : withval=$with_pybind11; else - with_pybind11=yes + with_pybind11=no fi @@ -6186,67 +6186,131 @@ fi fi + ############################################################# -# Build into shared object (pic) +# Enable pybind11 -- fetch submodule if required ############################################################# -if test "x$enable_shared" = "xyes"; then : +HAS_PYBIND11="no" +PYBIND_TARGET_DIR=externalpackages/pybind11 +if test "$with_pybind11" != "no"; then : - # compile as position independent code. - # -fpic is apparently faster then -fPIC, but -fPIC works always. - # From a SO comment (https://stackoverflow.com/a/3544211/3384414): - # What's more: I did a little experiment here (on x86_64 - # platform), -fPIC and -fpic appears to have generated the same - # code. It seems they generate a different code only on m68k, - # PowerPC and SPARC. - # Therfore use -fPIC for now - CXXFLAGS="$CXXFLAGS -fPIC" + if test -f ${PYBIND_TARGET_DIR}/README.md; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: Using existing pybind11 submodule" >&5 +$as_echo "$as_me: Using existing pybind11 submodule" >&6;} + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: Getting pybind11 submodule" >&5 +$as_echo "$as_me: Getting pybind11 submodule" >&6;} + if git submodule update --init --recursive -- ${PYBIND_TARGET_DIR}; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: Success in getting pybind11" >&5 +$as_echo "$as_me: Success in getting pybind11" >&6;} +else + as_fn_error $? "Failed to get pybind11" "$LINENO" 5 fi -############################################################# -# Git revision number -############################################################# +fi -rev=`git rev-parse HEAD` -if test $? = 0; then : + #Ensure we have asked to enable_shared as well as -fPIC is required + #in CXXFLAGS. We could of course just add -fPIC to CXXFLAGS here but + #probably better to force consistent options + if test "x$enable_shared" != "xyes"; then : + as_fn_error $? "Configuring with pybind11 requires --enable-shared=yes" "$LINENO" 5 +fi - { $as_echo "$as_me:${as_lineno-$LINENO}: Git revision: $rev" >&5 -$as_echo "$as_me: Git revision: $rev" >&6;} - GIT_REVISION=$rev + #We require python if using pybind11 so check we have access to it + #Note strictly pybind11 can work with python 2 and 3, but here we + #restrict ourselves to >= v3.0. This will abort configure if a suitable + #interpreter isn't found -else - GIT_REVISION= -fi -############################################################# -# FFT routines -############################################################# -if test "x$with_fftw" != "xno"; then : -# Extract the first word of "fftw-wisdom", so it can be a program name with args. -set dummy fftw-wisdom; ac_word=$2 + if test -n "$PYTHON"; then + # If the user set $PYTHON, use it and don't search something else. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version is >= 3" >&5 +$as_echo_n "checking whether $PYTHON version is >= 3... " >&6; } + prog="import sys +# split strings by '.' and convert to numeric. Append some zeros +# because we need at least 4 digits for the hex conversion. +# map returns an iterator in Python 3.0 and a list in 2.x +minver = list(map(int, '3'.split('.'))) + [0, 0, 0] +minverhex = 0 +# xrange is not present in Python 3.0 and range returns an iterator +for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] +sys.exit(sys.hexversion < minverhex)" + if { echo "$as_me:$LINENO: $PYTHON -c "$prog"" >&5 + ($PYTHON -c "$prog") >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; 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; } + as_fn_error $? "Python interpreter is too old" "$LINENO" 5 +fi + am_display_PYTHON=$PYTHON + else + # Otherwise, try each interpreter until we find one that satisfies + # VERSION. + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a Python interpreter with version >= 3" >&5 +$as_echo_n "checking for a Python interpreter with version >= 3... " >&6; } +if ${am_cv_pathless_PYTHON+:} false; then : + $as_echo_n "(cached) " >&6 +else + + for am_cv_pathless_PYTHON in python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do + test "$am_cv_pathless_PYTHON" = none && break + prog="import sys +# split strings by '.' and convert to numeric. Append some zeros +# because we need at least 4 digits for the hex conversion. +# map returns an iterator in Python 3.0 and a list in 2.x +minver = list(map(int, '3'.split('.'))) + [0, 0, 0] +minverhex = 0 +# xrange is not present in Python 3.0 and range returns an iterator +for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] +sys.exit(sys.hexversion < minverhex)" + if { echo "$as_me:$LINENO: $am_cv_pathless_PYTHON -c "$prog"" >&5 + ($am_cv_pathless_PYTHON -c "$prog") >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; then : + break +fi + done +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_pathless_PYTHON" >&5 +$as_echo "$am_cv_pathless_PYTHON" >&6; } + # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. + if test "$am_cv_pathless_PYTHON" = none; then + PYTHON=: + else + # Extract the first word of "$am_cv_pathless_PYTHON", so it can be a program name with args. +set dummy $am_cv_pathless_PYTHON; 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_path_fftw_path+:} false; then : +if ${ac_cv_path_PYTHON+:} false; then : $as_echo_n "(cached) " >&6 else - case $fftw_path in + case $PYTHON in [\\/]* | ?:[\\/]*) - ac_cv_path_fftw_path="$fftw_path" # Let the user override the test with a path. + ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $with_fftw$PATH_SEPARATOR$PATH +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_path_fftw_path="$as_dir/$ac_word$ac_exec_ext" + ac_cv_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -6254,107 +6318,358 @@ done done IFS=$as_save_IFS - test -z "$ac_cv_path_fftw_path" && ac_cv_path_fftw_path="no" ;; esac fi -fftw_path=$ac_cv_path_fftw_path -if test -n "$fftw_path"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $fftw_path" >&5 -$as_echo "$fftw_path" >&6; } +PYTHON=$ac_cv_path_PYTHON +if test -n "$PYTHON"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 +$as_echo "$PYTHON" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi + fi + am_display_PYTHON=$am_cv_pathless_PYTHON + fi - if test "x$fftw_path" != "xno"; then : - fftw_wisdom0=`$as_dirname -- "$fftw_path" || -$as_expr X"$fftw_path" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$fftw_path" : 'X\(//\)[^/]' \| \ - X"$fftw_path" : 'X\(//\)$' \| \ - X"$fftw_path" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$fftw_path" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - fftw_wisdom=`$as_dirname -- "$fftw_wisdom0" || -$as_expr X"$fftw_wisdom0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$fftw_wisdom0" : 'X\(//\)[^/]' \| \ - X"$fftw_wisdom0" : 'X\(//\)$' \| \ - X"$fftw_wisdom0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$fftw_wisdom0" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - with_fftw="$with_fftw $fftw_wisdom" + if test "$PYTHON" = :; then + as_fn_error $? "no suitable Python interpreter found" "$LINENO" 5 + else + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON version" >&5 +$as_echo_n "checking for $am_display_PYTHON version... " >&6; } +if ${am_cv_python_version+:} false; then : + $as_echo_n "(cached) " >&6 else - { $as_echo "$as_me:${as_lineno-$LINENO}: FFTW3 requested but fftw-wisdom not found" >&5 -$as_echo "$as_me: FFTW3 requested but fftw-wisdom not found" >&6;} + am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"` fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5 +$as_echo "$am_cv_python_version" >&6; } + PYTHON_VERSION=$am_cv_python_version - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fftw3.h" >&5 -$as_echo_n "checking for fftw3.h... " >&6; } - - save_CPPFLAGS=$CPPFLAGS - BACH_found=no - if test ."$with_fftw" != .yes; then : - extra_prefix="$with_fftw" -else - extra_prefix="" -fi + PYTHON_PREFIX='${prefix}' - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ + PYTHON_EXEC_PREFIX='${exec_prefix}' - #include -int -main () -{ - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - BACH_found=yes + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON platform" >&5 +$as_echo_n "checking for $am_display_PYTHON platform... " >&6; } +if ${am_cv_python_platform+:} false; then : + $as_echo_n "(cached) " >&6 +else + am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"` +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_platform" >&5 +$as_echo "$am_cv_python_platform" >&6; } + PYTHON_PLATFORM=$am_cv_python_platform - break + # Just factor out some code duplication. + am_python_setup_sysconfig="\ +import sys +# Prefer sysconfig over distutils.sysconfig, for better compatibility +# with python 3.x. See automake bug#10227. +try: + import sysconfig +except ImportError: + can_use_sysconfig = 0 +else: + can_use_sysconfig = 1 +# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs: +# +try: + from platform import python_implementation + if python_implementation() == 'CPython' and sys.version[:3] == '2.7': + can_use_sysconfig = 0 +except ImportError: + pass" + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5 +$as_echo_n "checking for $am_display_PYTHON script directory... " >&6; } +if ${am_cv_python_pythondir+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$prefix" = xNONE + then + am_py_prefix=$ac_default_prefix + else + am_py_prefix=$prefix + fi + am_cv_python_pythondir=`$PYTHON -c " +$am_python_setup_sysconfig +if can_use_sysconfig: + sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'}) +else: + from distutils import sysconfig + sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') +sys.stdout.write(sitedir)"` + case $am_cv_python_pythondir in + $am_py_prefix*) + am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` + am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` + ;; + *) + case $am_py_prefix in + /usr|/System*) ;; + *) + am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pythondir" >&5 +$as_echo "$am_cv_python_pythondir" >&6; } + pythondir=$am_cv_python_pythondir + + + + pkgpythondir=\${pythondir}/$PACKAGE + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory" >&5 +$as_echo_n "checking for $am_display_PYTHON extension module directory... " >&6; } +if ${am_cv_python_pyexecdir+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test "x$exec_prefix" = xNONE + then + am_py_exec_prefix=$am_py_prefix + else + am_py_exec_prefix=$exec_prefix + fi + am_cv_python_pyexecdir=`$PYTHON -c " +$am_python_setup_sysconfig +if can_use_sysconfig: + sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'}) +else: + from distutils import sysconfig + sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix') +sys.stdout.write(sitedir)"` + case $am_cv_python_pyexecdir in + $am_py_exec_prefix*) + am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` + am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` + ;; + *) + case $am_py_exec_prefix in + /usr|/System*) ;; + *) + am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages + ;; + esac + ;; + esac + +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pyexecdir" >&5 +$as_echo "$am_cv_python_pyexecdir" >&6; } + pyexecdir=$am_cv_python_pyexecdir + + + + pkgpyexecdir=\${pyexecdir}/$PACKAGE + + + { $as_echo "$as_me:${as_lineno-$LINENO}: Found python version $PYTHON_VERSION" >&5 +$as_echo "$as_me: Found python version $PYTHON_VERSION" >&6;} + fi + + + EXTRA_INCS="$EXTRA_INCS $(PYTHONPATH=${PYTHONPATH}:${PWD}/${PYBIND_TARGET_DIR} python3 -m pybind11 --includes)" + EXTRA_LIBS="$EXTRA_LIBS $(python3-config --libs)" + LDFLAGS="$LDFLAGS $(python3-config --ldflags)" + + HAS_PYBIND11="yes" + + #Now copy/link the pybind headers into bout includes + ac_config_links="$ac_config_links include/pybind11:${PYBIND_TARGET_DIR}/include/pybind11/" + + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: Building without pybind11 submodule" >&5 +$as_echo "$as_me: Building without pybind11 submodule" >&6;} +fi + +############################################################# +# Build into shared object (pic) +############################################################# + +if test "x$enable_shared" = "xyes"; then : + + # compile as position independent code. + # -fpic is apparently faster then -fPIC, but -fPIC works always. + # From a SO comment (https://stackoverflow.com/a/3544211/3384414): + # What's more: I did a little experiment here (on x86_64 + # platform), -fPIC and -fpic appears to have generated the same + # code. It seems they generate a different code only on m68k, + # PowerPC and SPARC. + # Therfore use -fPIC for now + CXXFLAGS="$CXXFLAGS -fPIC" + +fi + +############################################################# +# Git revision number +############################################################# + +rev=`git rev-parse HEAD` +if test $? = 0; then : + + { $as_echo "$as_me:${as_lineno-$LINENO}: Git revision: $rev" >&5 +$as_echo "$as_me: Git revision: $rev" >&6;} + GIT_REVISION=$rev + +else + + GIT_REVISION= + +fi + +############################################################# +# FFT routines +############################################################# + +if test "x$with_fftw" != "xno"; then : + +# Extract the first word of "fftw-wisdom", so it can be a program name with args. +set dummy fftw-wisdom; 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_path_fftw_path+:} false; then : + $as_echo_n "(cached) " >&6 +else + case $fftw_path in + [\\/]* | ?:[\\/]*) + ac_cv_path_fftw_path="$fftw_path" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $with_fftw$PATH_SEPARATOR$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_path_fftw_path="$as_dir/$ac_word$ac_exec_ext" + $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 + + test -z "$ac_cv_path_fftw_path" && ac_cv_path_fftw_path="no" + ;; +esac +fi +fftw_path=$ac_cv_path_fftw_path +if test -n "$fftw_path"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $fftw_path" >&5 +$as_echo "$fftw_path" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + + + if test "x$fftw_path" != "xno"; then : + + fftw_wisdom0=`$as_dirname -- "$fftw_path" || +$as_expr X"$fftw_path" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$fftw_path" : 'X\(//\)[^/]' \| \ + X"$fftw_path" : 'X\(//\)$' \| \ + X"$fftw_path" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$fftw_path" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + fftw_wisdom=`$as_dirname -- "$fftw_wisdom0" || +$as_expr X"$fftw_wisdom0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$fftw_wisdom0" : 'X\(//\)[^/]' \| \ + X"$fftw_wisdom0" : 'X\(//\)$' \| \ + X"$fftw_wisdom0" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$fftw_wisdom0" | + sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ + s//\1/ + q + } + /^X\(\/\/\)[^/].*/{ + s//\1/ + q + } + /^X\(\/\/\)$/{ + s//\1/ + q + } + /^X\(\/\).*/{ + s//\1/ + q + } + s/.*/./; q'` + with_fftw="$with_fftw $fftw_wisdom" + +else + { $as_echo "$as_me:${as_lineno-$LINENO}: FFTW3 requested but fftw-wisdom not found" >&5 +$as_echo "$as_me: FFTW3 requested but fftw-wisdom not found" >&6;} +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for fftw3.h" >&5 +$as_echo_n "checking for fftw3.h... " >&6; } + + save_CPPFLAGS=$CPPFLAGS + BACH_found=no + + if test ."$with_fftw" != .yes; then : + extra_prefix="$with_fftw" +else + extra_prefix="" +fi + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + + #include + +int +main () +{ + + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + BACH_found=yes + + + break fi rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext @@ -11915,452 +12230,174 @@ $as_echo "$sundials_module_lib_path_found" >&6; } fi LIBS=$save_LIBS LDFLAGS=$save_LDFLAGS - CPPFLAGS="$save_CPPFLAGS" - done - 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 - - - SUNDIALS_MODULE_LDFLAGS="-L$sundials_module_lib_path" - -fi - - if test "x$sundials_module_lib_path_found" = "xno"; 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 $? "Cannot compile $module_upper program -See \`config.log' for more details" "$LINENO" 5; } -fi - - # Compile in the $module_upper solver - { $as_echo "$as_me:${as_lineno-$LINENO}: => $module_upper solver enabled" >&5 -$as_echo "$as_me: => $module_upper solver enabled" >&6;} - EXTRA_LIBS="$EXTRA_LIBS $SUNDIALS_MODULE_LDFLAGS $sundials_module_libs" - EXTRA_INCS="$EXTRA_INCS $sundials_module_includes" - CXXFLAGS="$CXXFLAGS -DBOUT_HAS_$module_upper" - - eval "`$as_echo "BOUT_HAS_$module_upper" | $as_tr_sh`=yes" - eval "`$as_echo "${module_upper}LIBS" | $as_tr_sh`=\"\$SUNDIALS_MODULE_LDFLAGS \$sundials_module_libs\"" - eval "`$as_echo "${module_upper}INCS" | $as_tr_sh`=\"\$sundials_module_includes\"" - - # Now we have successfully found the library, we need to determine - # whether $module_upper uses int or long. Try to compile a simple - # program to check - save_CXXFLAGS=$CXXFLAGS - { $as_echo "$as_me:${as_lineno-$LINENO}: \"checking $module_upper types...\"" >&5 -$as_echo "$as_me: \"checking $module_upper types...\"" >&6;} - 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 - - - for sundials_int_type in int long; do - { $as_echo "$as_me:${as_lineno-$LINENO}: checking $sundials_int_type" >&5 -$as_echo_n "checking $sundials_int_type... " >&6; } - eval sundials_type_name=`$as_echo "${module_upper}INT" | $as_tr_sh` - CXXFLAGS="$CXXFLAGS $sundials_module_includes -D$sundials_type_name=$sundials_int_type" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - - - - #include - extern int arkode_bbd_rhs(ARKODEINT, double, N_Vector, N_Vector, void *); - - -int -main () -{ -ARKBBDPrecInit(nullptr, 0, 0, 0, 0, 0, 0, arkode_bbd_rhs, nullptr); - ; - return 0; -} -_ACEOF -if ac_fn_cxx_try_compile "$LINENO"; then : - sundials_int_type_found=yes -else - sundials_int_type_found=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sundials_int_type_found" >&5 -$as_echo "$sundials_int_type_found" >&6; } - if test "x$sundials_int_type_found" = "xyes"; then - break; - fi - CXXFLAGS=$save_CXXFLAGS - done - - if test "x$sundials_int_type_found" = "xno"; 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 $? "*** Cannot compile $module_upper with either long or int -See \`config.log' for more details" "$LINENO" 5; } - -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 - - - # We can now add that macro definition to the compilation flags - CXXFLAGS="$save_CXXFLAGS -D$sundials_type_name=$sundials_int_type" - - -fi - -############################################################# -# Scorep setup -############################################################# - -HAS_SCOREP="no" -if test "$with_scorep" != "no"; then : - - - if test "$with_scorep" != "yes"; then : - - { $as_echo "$as_me:${as_lineno-$LINENO}: Searching for Scorep executable in $with_scorep" >&5 -$as_echo "$as_me: Searching for Scorep executable in $with_scorep" >&6;} - # Extract the first word of "scorep", so it can be a program name with args. -set dummy scorep; 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_path_SCOREPPATH+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $SCOREPPATH in - [\\/]* | ?:[\\/]*) - ac_cv_path_SCOREPPATH="$SCOREPPATH" # Let the user override the test with a path. - ;; - *) - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $with_scorep -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_path_SCOREPPATH="$as_dir/$ac_word$ac_exec_ext" - $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 - - ;; -esac -fi -SCOREPPATH=$ac_cv_path_SCOREPPATH -if test -n "$SCOREPPATH"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SCOREPPATH" >&5 -$as_echo "$SCOREPPATH" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Searching for Scorep executable" >&5 -$as_echo "$as_me: Searching for Scorep executable" >&6;} - # Extract the first word of "scorep", so it can be a program name with args. -set dummy scorep; 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_path_SCOREPPATH+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $SCOREPPATH in - [\\/]* | ?:[\\/]*) - ac_cv_path_SCOREPPATH="$SCOREPPATH" # Let the user override the test with a path. - ;; - *) - 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_path_SCOREPPATH="$as_dir/$ac_word$ac_exec_ext" - $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 - - ;; -esac -fi -SCOREPPATH=$ac_cv_path_SCOREPPATH -if test -n "$SCOREPPATH"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SCOREPPATH" >&5 -$as_echo "$SCOREPPATH" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - -fi - - if test "$SCOREPPATH" = ""; 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 $? "*** Scorep requested, but executable not found. -Please supply the path using --with-scorep=/path/to/scorep -See \`config.log' for more details" "$LINENO" 5; } - -else - - # Set a compile-time flag - CXXFLAGS="$CXXFLAGS -DBOUT_HAS_SCOREP" - MPICXX="$SCOREPPATH --user --nocompiler $MPICXX" - - 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 - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking does C++ compiler support __PRETTY_FUNCTION__" >&5 -$as_echo_n "checking does C++ compiler support __PRETTY_FUNCTION__... " >&6; } - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -const char* name = __PRETTY_FUNCTION__; - ; - 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; } - CXXFLAGS="$CXXFLAGS -DHAS_PRETTY_FUNCTION" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_ext=cpp + CPPFLAGS="$save_CPPFLAGS" + done + 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 - HAS_SCOREP="yes" - { $as_echo "$as_me:${as_lineno-$LINENO}: Scorep support enabled" >&5 -$as_echo "$as_me: Scorep support enabled" >&6;} + SUNDIALS_MODULE_LDFLAGS="-L$sundials_module_lib_path" fi - -else - - { $as_echo "$as_me:${as_lineno-$LINENO}: Scorep support disabled" >&5 -$as_echo "$as_me: Scorep support disabled" >&6;} - + if test "x$sundials_module_lib_path_found" = "xno"; 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 $? "Cannot compile $module_upper program +See \`config.log' for more details" "$LINENO" 5; } fi -############################################################# -# Download + Build PVODE '98 -############################################################# + # Compile in the $module_upper solver + { $as_echo "$as_me:${as_lineno-$LINENO}: => $module_upper solver enabled" >&5 +$as_echo "$as_me: => $module_upper solver enabled" >&6;} + EXTRA_LIBS="$EXTRA_LIBS $SUNDIALS_MODULE_LDFLAGS $sundials_module_libs" + EXTRA_INCS="$EXTRA_INCS $sundials_module_includes" + CXXFLAGS="$CXXFLAGS -DBOUT_HAS_$module_upper" -as_dir=externalpackages; as_fn_mkdir_p -as_dir=lib; as_fn_mkdir_p -as_dir=include; as_fn_mkdir_p + eval "`$as_echo "BOUT_HAS_$module_upper" | $as_tr_sh`=yes" + eval "`$as_echo "${module_upper}LIBS" | $as_tr_sh`=\"\$SUNDIALS_MODULE_LDFLAGS \$sundials_module_libs\"" + eval "`$as_echo "${module_upper}INCS" | $as_tr_sh`=\"\$sundials_module_includes\"" -HAS_PVODE="no" -if test "$with_pvode" != "no"; then : + # Now we have successfully found the library, we need to determine + # whether $module_upper uses int or long. Try to compile a simple + # program to check + save_CXXFLAGS=$CXXFLAGS + { $as_echo "$as_me:${as_lineno-$LINENO}: \"checking $module_upper types...\"" >&5 +$as_echo "$as_me: \"checking $module_upper types...\"" >&6;} + 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 - if test "$enable_pvode_openmp" != "no" ; then : - if test "$enable_openmp" != "no" ; then : + for sundials_int_type in int long; do + { $as_echo "$as_me:${as_lineno-$LINENO}: checking $sundials_int_type" >&5 +$as_echo_n "checking $sundials_int_type... " >&6; } + eval sundials_type_name=`$as_echo "${module_upper}INT" | $as_tr_sh` + CXXFLAGS="$CXXFLAGS $sundials_module_includes -D$sundials_type_name=$sundials_int_type" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - PVODE_FLAGS="$CXXFLAGS $OPENMP_CXXFLAGS $CXX11_FLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: PVODE being built with OpenMP support" >&5 -$as_echo "$as_me: PVODE being built with OpenMP support" >&6;} -else - as_fn_error $? "Cannot enable openmp in PVODE as configuring with OpenMP disabled" "$LINENO" 5 + #include + extern int arkode_bbd_rhs(ARKODEINT, double, N_Vector, N_Vector, void *); -fi +int +main () +{ +ARKBBDPrecInit(nullptr, 0, 0, 0, 0, 0, 0, arkode_bbd_rhs, nullptr); + ; + return 0; +} +_ACEOF +if ac_fn_cxx_try_compile "$LINENO"; then : + sundials_int_type_found=yes else - - PVODE_FLAGS="$CXXFLAGS $CXX11_FLAGS" - { $as_echo "$as_me:${as_lineno-$LINENO}: PVODE being built without OpenMP support" >&5 -$as_echo "$as_me: PVODE being built without OpenMP support" >&6;} - + sundials_int_type_found=no fi - # Clean PVODE - CXX="$MPICXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE clean -C externalpackages/PVODE/precon/ >> config-build.log 2>&1 - CXX="$MPICXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE clean -C externalpackages/PVODE/source/ >> config-build.log 2>&1 - - { $as_echo "$as_me:${as_lineno-$LINENO}: Building PVODE" >&5 -$as_echo "$as_me: Building PVODE" >&6;} - echo "* Building PVODE" >> config-build.log - echo "*************************************************************" >> config-build.log - - CXX="$MPICXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE -C externalpackages/PVODE/precon/ >> config-build.log 2>&1 - CXX="$MPICXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE -C externalpackages/PVODE/source/ >> config-build.log 2>&1 - - if test -f externalpackages/PVODE/lib/libpvode.a ; then : +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $sundials_int_type_found" >&5 +$as_echo "$sundials_int_type_found" >&6; } + if test "x$sundials_int_type_found" = "xyes"; then + break; + fi + CXXFLAGS=$save_CXXFLAGS + done - { $as_echo "$as_me:${as_lineno-$LINENO}: Successfully built PVODE" >&5 -$as_echo "$as_me: Successfully built PVODE" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: Installing PVODE into BOUT++ sourcetree" >&5 -$as_echo "$as_me: Installing PVODE into BOUT++ sourcetree" >&6;} + if test "x$sundials_int_type_found" = "xno"; then : - echo "*************************************************************" >> config-build.log - echo "* Successfully built PVODE" >> config-build.log - echo "*************************************************************" >> config-build.log - echo "* Installing PVODE into BOUT++ sourcetree" >> config-build.log - echo "*************************************************************" >> config-build.log + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "*** Cannot compile $module_upper with either long or int +See \`config.log' for more details" "$LINENO" 5; } -else +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 - as_fn_error $? "Could not build PVODE. See config-build.log for errors" "$LINENO" 5 -fi + # We can now add that macro definition to the compilation flags + CXXFLAGS="$save_CXXFLAGS -D$sundials_type_name=$sundials_int_type" - # Set the correct libraries and copy them to bout - as_dir=include/pvode; as_fn_mkdir_p - cp externalpackages/PVODE/precon/pvbbdpre.h externalpackages/PVODE/include/*.h include/pvode - cp externalpackages/PVODE/lib/*.a lib/ - EXTRA_LIBS="$EXTRA_LIBS -L\$(BOUT_LIB_PATH) -lpvode -lpvpre" - CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PVODE" - HAS_PVODE="yes" fi ############################################################# -# Enable pybind11 -- fetch submodule if required +# Scorep setup ############################################################# -HAS_PYBIND11="no" -PYBIND_TARGET_DIR=externalpackages/pybind11 -if test "$with_pybind11" != "no"; then : - - if test -f ${PYBIND_TARGET_DIR}/README.md; then : +HAS_SCOREP="no" +if test "$with_scorep" != "no"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: Using existing pybind11 submodule" >&5 -$as_echo "$as_me: Using existing pybind11 submodule" >&6;} -else + if test "$with_scorep" != "yes"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: Getting pybind11 submodule" >&5 -$as_echo "$as_me: Getting pybind11 submodule" >&6;} - if git submodule update --init --recursive -- ${PYBIND_TARGET_DIR}; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: Success in getting pybind11" >&5 -$as_echo "$as_me: Success in getting pybind11" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: Searching for Scorep executable in $with_scorep" >&5 +$as_echo "$as_me: Searching for Scorep executable in $with_scorep" >&6;} + # Extract the first word of "scorep", so it can be a program name with args. +set dummy scorep; 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_path_SCOREPPATH+:} false; then : + $as_echo_n "(cached) " >&6 else - as_fn_error $? "Failed to get pybind11" "$LINENO" 5 -fi + case $SCOREPPATH in + [\\/]* | ?:[\\/]*) + ac_cv_path_SCOREPPATH="$SCOREPPATH" # Let the user override the test with a path. + ;; + *) + as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $with_scorep +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_path_SCOREPPATH="$as_dir/$ac_word$ac_exec_ext" + $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 + ;; +esac fi - #Note the following overlap with --enable-shared, we should probably force enabled_shared here - CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11 -fPIC" - - #We require python if using pybind11 so check we have access to it - #Note strictly pybind11 can work with python 2 and 3, but here we - #restrict ourselves to >= v3.0. This will abort configure if a suitable - #interpreter isn't found - - - - - - - if test -n "$PYTHON"; then - # If the user set $PYTHON, use it and don't search something else. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $PYTHON version is >= 3" >&5 -$as_echo_n "checking whether $PYTHON version is >= 3... " >&6; } - prog="import sys -# split strings by '.' and convert to numeric. Append some zeros -# because we need at least 4 digits for the hex conversion. -# map returns an iterator in Python 3.0 and a list in 2.x -minver = list(map(int, '3'.split('.'))) + [0, 0, 0] -minverhex = 0 -# xrange is not present in Python 3.0 and range returns an iterator -for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] -sys.exit(sys.hexversion < minverhex)" - if { echo "$as_me:$LINENO: $PYTHON -c "$prog"" >&5 - ($PYTHON -c "$prog") >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } +SCOREPPATH=$ac_cv_path_SCOREPPATH +if test -n "$SCOREPPATH"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SCOREPPATH" >&5 +$as_echo "$SCOREPPATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } - as_fn_error $? "Python interpreter is too old" "$LINENO" 5 -fi - am_display_PYTHON=$PYTHON - else - # Otherwise, try each interpreter until we find one that satisfies - # VERSION. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for a Python interpreter with version >= 3" >&5 -$as_echo_n "checking for a Python interpreter with version >= 3... " >&6; } -if ${am_cv_pathless_PYTHON+:} false; then : - $as_echo_n "(cached) " >&6 -else - - for am_cv_pathless_PYTHON in python python2 python3 python3.3 python3.2 python3.1 python3.0 python2.7 python2.6 python2.5 python2.4 python2.3 python2.2 python2.1 python2.0 none; do - test "$am_cv_pathless_PYTHON" = none && break - prog="import sys -# split strings by '.' and convert to numeric. Append some zeros -# because we need at least 4 digits for the hex conversion. -# map returns an iterator in Python 3.0 and a list in 2.x -minver = list(map(int, '3'.split('.'))) + [0, 0, 0] -minverhex = 0 -# xrange is not present in Python 3.0 and range returns an iterator -for i in list(range(0, 4)): minverhex = (minverhex << 8) + minver[i] -sys.exit(sys.hexversion < minverhex)" - if { echo "$as_me:$LINENO: $am_cv_pathless_PYTHON -c "$prog"" >&5 - ($am_cv_pathless_PYTHON -c "$prog") >&5 2>&5 - ac_status=$? - echo "$as_me:$LINENO: \$? = $ac_status" >&5 - (exit $ac_status); }; then : - break -fi - done -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_pathless_PYTHON" >&5 -$as_echo "$am_cv_pathless_PYTHON" >&6; } - # Set $PYTHON to the absolute path of $am_cv_pathless_PYTHON. - if test "$am_cv_pathless_PYTHON" = none; then - PYTHON=: - else - # Extract the first word of "$am_cv_pathless_PYTHON", so it can be a program name with args. -set dummy $am_cv_pathless_PYTHON; ac_word=$2 +fi + + + +else + + { $as_echo "$as_me:${as_lineno-$LINENO}: Searching for Scorep executable" >&5 +$as_echo "$as_me: Searching for Scorep executable" >&6;} + # Extract the first word of "scorep", so it can be a program name with args. +set dummy scorep; 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_path_PYTHON+:} false; then : +if ${ac_cv_path_SCOREPPATH+:} false; then : $as_echo_n "(cached) " >&6 else - case $PYTHON in + case $SCOREPPATH in [\\/]* | ?:[\\/]*) - ac_cv_path_PYTHON="$PYTHON" # Let the user override the test with a path. + ac_cv_path_SCOREPPATH="$SCOREPPATH" # Let the user override the test with a path. ;; *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR @@ -12370,7 +12407,7 @@ do 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_path_PYTHON="$as_dir/$ac_word$ac_exec_ext" + ac_cv_path_SCOREPPATH="$as_dir/$ac_word$ac_exec_ext" $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 break 2 fi @@ -12381,185 +12418,153 @@ IFS=$as_save_IFS ;; esac fi -PYTHON=$ac_cv_path_PYTHON -if test -n "$PYTHON"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $PYTHON" >&5 -$as_echo "$PYTHON" >&6; } +SCOREPPATH=$ac_cv_path_SCOREPPATH +if test -n "$SCOREPPATH"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $SCOREPPATH" >&5 +$as_echo "$SCOREPPATH" >&6; } else { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 $as_echo "no" >&6; } fi - fi - am_display_PYTHON=$am_cv_pathless_PYTHON - fi - - - if test "$PYTHON" = :; then - as_fn_error $? "no suitable Python interpreter found" "$LINENO" 5 - else - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON version" >&5 -$as_echo_n "checking for $am_display_PYTHON version... " >&6; } -if ${am_cv_python_version+:} false; then : - $as_echo_n "(cached) " >&6 -else - am_cv_python_version=`$PYTHON -c "import sys; sys.stdout.write(sys.version[:3])"` fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_version" >&5 -$as_echo "$am_cv_python_version" >&6; } - PYTHON_VERSION=$am_cv_python_version + if test "$SCOREPPATH" = ""; 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 $? "*** Scorep requested, but executable not found. +Please supply the path using --with-scorep=/path/to/scorep +See \`config.log' for more details" "$LINENO" 5; } - PYTHON_PREFIX='${prefix}' +else - PYTHON_EXEC_PREFIX='${exec_prefix}' + # Set a compile-time flag + CXXFLAGS="$CXXFLAGS -DBOUT_HAS_SCOREP" + MPICXX="$SCOREPPATH --user --nocompiler $MPICXX" + 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 + { $as_echo "$as_me:${as_lineno-$LINENO}: checking does C++ compiler support __PRETTY_FUNCTION__" >&5 +$as_echo_n "checking does C++ compiler support __PRETTY_FUNCTION__... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON platform" >&5 -$as_echo_n "checking for $am_display_PYTHON platform... " >&6; } -if ${am_cv_python_platform+:} false; then : - $as_echo_n "(cached) " >&6 +int +main () +{ +const char* name = __PRETTY_FUNCTION__; + ; + 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; } + CXXFLAGS="$CXXFLAGS -DHAS_PRETTY_FUNCTION" else - am_cv_python_platform=`$PYTHON -c "import sys; sys.stdout.write(sys.platform)"` + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_platform" >&5 -$as_echo "$am_cv_python_platform" >&6; } - PYTHON_PLATFORM=$am_cv_python_platform +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + 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 - # Just factor out some code duplication. - am_python_setup_sysconfig="\ -import sys -# Prefer sysconfig over distutils.sysconfig, for better compatibility -# with python 3.x. See automake bug#10227. -try: - import sysconfig -except ImportError: - can_use_sysconfig = 0 -else: - can_use_sysconfig = 1 -# Can't use sysconfig in CPython 2.7, since it's broken in virtualenvs: -# -try: - from platform import python_implementation - if python_implementation() == 'CPython' and sys.version[:3] == '2.7': - can_use_sysconfig = 0 -except ImportError: - pass" + HAS_SCOREP="yes" + { $as_echo "$as_me:${as_lineno-$LINENO}: Scorep support enabled" >&5 +$as_echo "$as_me: Scorep support enabled" >&6;} + +fi - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON script directory" >&5 -$as_echo_n "checking for $am_display_PYTHON script directory... " >&6; } -if ${am_cv_python_pythondir+:} false; then : - $as_echo_n "(cached) " >&6 else - if test "x$prefix" = xNONE - then - am_py_prefix=$ac_default_prefix - else - am_py_prefix=$prefix - fi - am_cv_python_pythondir=`$PYTHON -c " -$am_python_setup_sysconfig -if can_use_sysconfig: - sitedir = sysconfig.get_path('purelib', vars={'base':'$am_py_prefix'}) -else: - from distutils import sysconfig - sitedir = sysconfig.get_python_lib(0, 0, prefix='$am_py_prefix') -sys.stdout.write(sitedir)"` - case $am_cv_python_pythondir in - $am_py_prefix*) - am__strip_prefix=`echo "$am_py_prefix" | sed 's|.|.|g'` - am_cv_python_pythondir=`echo "$am_cv_python_pythondir" | sed "s,^$am__strip_prefix,$PYTHON_PREFIX,"` - ;; - *) - case $am_py_prefix in - /usr|/System*) ;; - *) - am_cv_python_pythondir=$PYTHON_PREFIX/lib/python$PYTHON_VERSION/site-packages - ;; - esac - ;; - esac + + { $as_echo "$as_me:${as_lineno-$LINENO}: Scorep support disabled" >&5 +$as_echo "$as_me: Scorep support disabled" >&6;} fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pythondir" >&5 -$as_echo "$am_cv_python_pythondir" >&6; } - pythondir=$am_cv_python_pythondir +############################################################# +# Download + Build PVODE '98 +############################################################# + +as_dir=externalpackages; as_fn_mkdir_p +as_dir=lib; as_fn_mkdir_p +as_dir=include; as_fn_mkdir_p + +HAS_PVODE="no" +if test "$with_pvode" != "no"; then : + if test "$enable_pvode_openmp" != "no" ; then : - pkgpythondir=\${pythondir}/$PACKAGE + if test "$enable_openmp" != "no" ; then : + PVODE_FLAGS="$CXXFLAGS $OPENMP_CXXFLAGS $CXX11_FLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: PVODE being built with OpenMP support" >&5 +$as_echo "$as_me: PVODE being built with OpenMP support" >&6;} - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $am_display_PYTHON extension module directory" >&5 -$as_echo_n "checking for $am_display_PYTHON extension module directory... " >&6; } -if ${am_cv_python_pyexecdir+:} false; then : - $as_echo_n "(cached) " >&6 else - if test "x$exec_prefix" = xNONE - then - am_py_exec_prefix=$am_py_prefix - else - am_py_exec_prefix=$exec_prefix - fi - am_cv_python_pyexecdir=`$PYTHON -c " -$am_python_setup_sysconfig -if can_use_sysconfig: - sitedir = sysconfig.get_path('platlib', vars={'platbase':'$am_py_prefix'}) -else: - from distutils import sysconfig - sitedir = sysconfig.get_python_lib(1, 0, prefix='$am_py_prefix') -sys.stdout.write(sitedir)"` - case $am_cv_python_pyexecdir in - $am_py_exec_prefix*) - am__strip_prefix=`echo "$am_py_exec_prefix" | sed 's|.|.|g'` - am_cv_python_pyexecdir=`echo "$am_cv_python_pyexecdir" | sed "s,^$am__strip_prefix,$PYTHON_EXEC_PREFIX,"` - ;; - *) - case $am_py_exec_prefix in - /usr|/System*) ;; - *) - am_cv_python_pyexecdir=$PYTHON_EXEC_PREFIX/lib/python$PYTHON_VERSION/site-packages - ;; - esac - ;; - esac + + as_fn_error $? "Cannot enable openmp in PVODE as configuring with OpenMP disabled" "$LINENO" 5 fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $am_cv_python_pyexecdir" >&5 -$as_echo "$am_cv_python_pyexecdir" >&6; } - pyexecdir=$am_cv_python_pyexecdir +else + PVODE_FLAGS="$CXXFLAGS $CXX11_FLAGS" + { $as_echo "$as_me:${as_lineno-$LINENO}: PVODE being built without OpenMP support" >&5 +$as_echo "$as_me: PVODE being built without OpenMP support" >&6;} - pkgpyexecdir=\${pyexecdir}/$PACKAGE +fi + # Clean PVODE + CXX="$MPICXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE clean -C externalpackages/PVODE/precon/ >> config-build.log 2>&1 + CXX="$MPICXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE clean -C externalpackages/PVODE/source/ >> config-build.log 2>&1 + { $as_echo "$as_me:${as_lineno-$LINENO}: Building PVODE" >&5 +$as_echo "$as_me: Building PVODE" >&6;} + echo "* Building PVODE" >> config-build.log + echo "*************************************************************" >> config-build.log - { $as_echo "$as_me:${as_lineno-$LINENO}: Found python version $PYTHON_VERSION" >&5 -$as_echo "$as_me: Found python version $PYTHON_VERSION" >&6;} - fi + CXX="$MPICXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE -C externalpackages/PVODE/precon/ >> config-build.log 2>&1 + CXX="$MPICXX" CXXFLAGS=$PVODE_FLAGS MKDIR="$MKDIR_P" RANLIB="$RANLIB" $MAKE -C externalpackages/PVODE/source/ >> config-build.log 2>&1 + if test -f externalpackages/PVODE/lib/libpvode.a ; then : - EXTRA_INCS="$EXTRA_INCS $(PYTHONPATH=${PYTHONPATH}:${PWD}/${PYBIND_TARGET_DIR} python3 -m pybind11 --includes)" - EXTRA_LIBS="$EXTRA_LIBS $(python3-config --libs)" - LDFLAGS="$LDFLAGS $(python3-config --ldflags)" + { $as_echo "$as_me:${as_lineno-$LINENO}: Successfully built PVODE" >&5 +$as_echo "$as_me: Successfully built PVODE" >&6;} + { $as_echo "$as_me:${as_lineno-$LINENO}: Installing PVODE into BOUT++ sourcetree" >&5 +$as_echo "$as_me: Installing PVODE into BOUT++ sourcetree" >&6;} - HAS_PYBIND11="yes" + echo "*************************************************************" >> config-build.log + echo "* Successfully built PVODE" >> config-build.log + echo "*************************************************************" >> config-build.log + echo "* Installing PVODE into BOUT++ sourcetree" >> config-build.log + echo "*************************************************************" >> config-build.log - #Now copy/link the pybind headers into bout includes - ac_config_links="$ac_config_links include/pybind11:${PYBIND_TARGET_DIR}/include/pybind11/" +else + as_fn_error $? "Could not build PVODE. See config-build.log for errors" "$LINENO" 5 +fi + + # Set the correct libraries and copy them to bout + as_dir=include/pvode; as_fn_mkdir_p + cp externalpackages/PVODE/precon/pvbbdpre.h externalpackages/PVODE/include/*.h include/pvode + cp externalpackages/PVODE/lib/*.a lib/ + EXTRA_LIBS="$EXTRA_LIBS -L\$(BOUT_LIB_PATH) -lpvode -lpvpre" + CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PVODE" + HAS_PVODE="yes" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: Building without pybind11 submodule" >&5 -$as_echo "$as_me: Building without pybind11 submodule" >&6;} fi ############################################################# diff --git a/configure.ac b/configure.ac index 54ec6e113e..2ab21645ed 100644 --- a/configure.ac +++ b/configure.ac @@ -57,7 +57,7 @@ AC_ARG_WITH(slepc, [AS_HELP_STRING([--with-slepc], AC_ARG_WITH(pvode, [AS_HELP_STRING([--with-pvode], [Build and enable PVODE 98 (DEFAULT)])],,[]) AC_ARG_WITH(pybind11, [AS_HELP_STRING([--with-pybind11], - [Enable pybind11 bindings (DEFAULT)])],,[with_pybind11=yes]) + [Enable pybind11 bindings])],,[with_pybind11=no]) AC_ARG_WITH(mumps, [AS_HELP_STRING([--with-mumps], [Link with MUMPS library for direct matrix inversions])],,[]) AC_ARG_WITH(arkode, [AS_HELP_STRING([--with-arkode], @@ -371,6 +371,44 @@ AS_IF([test "x$enable_backtrace" = "xyes" || test "x$enable_backtrace" = "xmaybe ]) ]) + +############################################################# +# Enable pybind11 -- fetch submodule if required +############################################################# + +HAS_PYBIND11="no" +PYBIND_TARGET_DIR=externalpackages/pybind11 +AS_IF([test "$with_pybind11" != "no"], [ + AS_IF([test -f ${PYBIND_TARGET_DIR}/README.md], [ + AC_MSG_NOTICE([Using existing pybind11 submodule]) + ], [ + AC_MSG_NOTICE([Getting pybind11 submodule]) + AS_IF([git submodule update --init --recursive -- ${PYBIND_TARGET_DIR}], + [AC_MSG_NOTICE([Success in getting pybind11])], + [AC_MSG_ERROR([Failed to get pybind11])]) + ]) + + #Ensure we have asked to enable_shared as well as -fPIC is required + #in CXXFLAGS. We could of course just add -fPIC to CXXFLAGS here but + #probably better to force consistent options + AS_IF([test "x$enable_shared" != "xyes"], + [AC_MSG_ERROR([Configuring with pybind11 requires --enable-shared=yes])]) + + #We require python if using pybind11 so check we have access to it + #Note strictly pybind11 can work with python 2 and 3, but here we + #restrict ourselves to >= v3.0. This will abort configure if a suitable + #interpreter isn't found + AM_PATH_PYTHON([3],AC_MSG_NOTICE([Found python version $PYTHON_VERSION])) + EXTRA_INCS="$EXTRA_INCS $(PYTHONPATH=${PYTHONPATH}:${PWD}/${PYBIND_TARGET_DIR} python3 -m pybind11 --includes)" + EXTRA_LIBS="$EXTRA_LIBS $(python3-config --libs)" + LDFLAGS="$LDFLAGS $(python3-config --ldflags)" + + HAS_PYBIND11="yes" + + #Now copy/link the pybind headers into bout includes + AC_CONFIG_LINKS(include/pybind11:${PYBIND_TARGET_DIR}/include/pybind11/) +], [AC_MSG_NOTICE([Building without pybind11 submodule])]) + ############################################################# # Build into shared object (pic) ############################################################# @@ -1152,40 +1190,6 @@ AS_IF([test "$with_pvode" != "no"], [ HAS_PVODE="yes" ]) -############################################################# -# Enable pybind11 -- fetch submodule if required -############################################################# - -HAS_PYBIND11="no" -PYBIND_TARGET_DIR=externalpackages/pybind11 -AS_IF([test "$with_pybind11" != "no"], [ - AS_IF([test -f ${PYBIND_TARGET_DIR}/README.md], [ - AC_MSG_NOTICE([Using existing pybind11 submodule]) - ], [ - AC_MSG_NOTICE([Getting pybind11 submodule]) - AS_IF([git submodule update --init --recursive -- ${PYBIND_TARGET_DIR}], - [AC_MSG_NOTICE([Success in getting pybind11])], - [AC_MSG_ERROR([Failed to get pybind11])]) - ]) - #Note the following overlap with --enable-shared, we should probably force enabled_shared here - CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11 -fPIC" - - #We require python if using pybind11 so check we have access to it - #Note strictly pybind11 can work with python 2 and 3, but here we - #restrict ourselves to >= v3.0. This will abort configure if a suitable - #interpreter isn't found - AM_PATH_PYTHON([3],AC_MSG_NOTICE([Found python version $PYTHON_VERSION])) - EXTRA_INCS="$EXTRA_INCS $(PYTHONPATH=${PYTHONPATH}:${PWD}/${PYBIND_TARGET_DIR} python3 -m pybind11 --includes)" - EXTRA_LIBS="$EXTRA_LIBS $(python3-config --libs)" - LDFLAGS="$LDFLAGS $(python3-config --ldflags)" - - HAS_PYBIND11="yes" - - #Now copy/link the pybind headers into bout includes - AC_CONFIG_LINKS(include/pybind11:${PYBIND_TARGET_DIR}/include/pybind11/) - -], [AC_MSG_NOTICE([Building without pybind11 submodule])]) - ############################################################# # Localisation (i18n) with gettext ############################################################# From c6007bcb78fb3f3022e04ec96ed2ac5da26a2445 Mon Sep 17 00:00:00 2001 From: David Dickinson Date: Wed, 6 Feb 2019 20:08:09 +0000 Subject: [PATCH 09/19] Restore missing define line from configure --- configure | 1 + configure.ac | 1 + 2 files changed, 2 insertions(+) diff --git a/configure b/configure index a1dd9dbe24..96d0946b69 100755 --- a/configure +++ b/configure @@ -6490,6 +6490,7 @@ $as_echo "$as_me: Found python version $PYTHON_VERSION" >&6;} EXTRA_LIBS="$EXTRA_LIBS $(python3-config --libs)" LDFLAGS="$LDFLAGS $(python3-config --ldflags)" + CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11" HAS_PYBIND11="yes" #Now copy/link the pybind headers into bout includes diff --git a/configure.ac b/configure.ac index 2ab21645ed..b1a19b3106 100644 --- a/configure.ac +++ b/configure.ac @@ -403,6 +403,7 @@ AS_IF([test "$with_pybind11" != "no"], [ EXTRA_LIBS="$EXTRA_LIBS $(python3-config --libs)" LDFLAGS="$LDFLAGS $(python3-config --ldflags)" + CXXFLAGS="$CXXFLAGS -DBOUT_HAS_PYBIND11" HAS_PYBIND11="yes" #Now copy/link the pybind headers into bout includes From 0b9f2faf1e9454b85a08478911889e81d13ebb2c Mon Sep 17 00:00:00 2001 From: David Dickinson Date: Wed, 6 Feb 2019 20:08:29 +0000 Subject: [PATCH 10/19] Show use of python module in example --- examples/pybind-embed/pybind_embed.cxx | 35 +++++++++++++++++--------- 1 file changed, 23 insertions(+), 12 deletions(-) diff --git a/examples/pybind-embed/pybind_embed.cxx b/examples/pybind-embed/pybind_embed.cxx index 412675b0c7..bb25ce8950 100644 --- a/examples/pybind-embed/pybind_embed.cxx +++ b/examples/pybind-embed/pybind_embed.cxx @@ -10,19 +10,30 @@ int myFunc(){ }; int main() { - // Get access to a python interpreter with lifetime of the current scope - py::scoped_interpreter guard{}; + { + // Get access to a python interpreter with lifetime of the current scope + py::scoped_interpreter guard{}; - // Construct a python dictionary -- note this includes a call - // to a native C++ method as well as including constants. - auto kwargs = py::dict("name"_a="BOUT++ user", - "number"_a=myFunc(), - "floatNumber"_a=1.2345 - ); - // Format the string using the dictionary constructed above - auto message = "Hello, {name}! The answer is {number} and not {floatNumber}"_s.format(**kwargs); - // Display message - py::print(message); + // Construct a python dictionary -- note this includes a call + // to a native C++ method as well as including constants. + auto kwargs = py::dict("name"_a="BOUT++ user", + "number"_a=myFunc(), + "floatNumber"_a=1.2345 + ); + // Format the string using the dictionary constructed above + auto message = "Hello, {name}! The answer is {number} and not {floatNumber}"_s.format(**kwargs); + // Display message + py::print(message); + } + + { + // Get access to another python interpreter + py::scoped_interpreter guard{}; + + py::module sys = py::module::import("sys"); + py::print("The python path is:"); + py::print(sys.attr("path")); + } } #else #error Must configure with `--with-pybind11` to be able to build pybind_embed example. From bf289ec67587e209f3eb999cdb50b3d219b9f524 Mon Sep 17 00:00:00 2001 From: David Dickinson Date: Wed, 6 Feb 2019 21:08:32 +0000 Subject: [PATCH 11/19] Add a demo of using, accessing and modifying a numpy array --- examples/pybind-embed/makefile | 2 -- examples/pybind-embed/pybind_embed.cxx | 17 +++++++++++++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/examples/pybind-embed/makefile b/examples/pybind-embed/makefile index 5833b41ccd..4c0e802fef 100644 --- a/examples/pybind-embed/makefile +++ b/examples/pybind-embed/makefile @@ -3,6 +3,4 @@ BOUT_TOP = ../.. SOURCEC = pybind_embed.cxx -BOUT_LIBS+=$(python3-config --libs) - include $(BOUT_TOP)/make.config diff --git a/examples/pybind-embed/pybind_embed.cxx b/examples/pybind-embed/pybind_embed.cxx index bb25ce8950..b90b2a36ee 100644 --- a/examples/pybind-embed/pybind_embed.cxx +++ b/examples/pybind-embed/pybind_embed.cxx @@ -24,6 +24,7 @@ int main() { auto message = "Hello, {name}! The answer is {number} and not {floatNumber}"_s.format(**kwargs); // Display message py::print(message); + py::print(); } { @@ -33,6 +34,22 @@ int main() { py::module sys = py::module::import("sys"); py::print("The python path is:"); py::print(sys.attr("path")); + py::print(""); + + py::module np = py::module::import("numpy"); + py::print(np); + py::print("Numpy version is", np.attr("__version__")); + auto linspaceTest = np.attr("linspace")(0.0,1.0,20); + py::print(linspaceTest); + py::print(); + py::print(linspaceTest[py::make_tuple(2)]); + linspaceTest[py::make_tuple(2)] = 2.0; + py::print(linspaceTest[py::make_tuple(2)]); + py::print(); + for(int i=0; i<20; i++) { + linspaceTest[py::make_tuple(i)] = i; + } + py::print(linspaceTest); } } #else From e882ae4ede7bf5fc63910fdf9d6d92be344f3ecf Mon Sep 17 00:00:00 2001 From: David Dickinson Date: Thu, 7 Feb 2019 10:45:04 +0000 Subject: [PATCH 12/19] Add a helper for getting values from python to C++ Adds a helper struct for compile time compatibility checking. --- examples/pybind-embed/pybind_embed.cxx | 41 +++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/examples/pybind-embed/pybind_embed.cxx b/examples/pybind-embed/pybind_embed.cxx index b90b2a36ee..59fd131787 100644 --- a/examples/pybind-embed/pybind_embed.cxx +++ b/examples/pybind-embed/pybind_embed.cxx @@ -1,6 +1,9 @@ #ifdef BOUT_HAS_PYBIND11 #include +#include +#include + namespace py = pybind11; using namespace py::literals; @@ -9,6 +12,37 @@ int myFunc(){ return 42; }; +template +struct has_cast { +private: + // Routine to check if the result of the cast of In to Out works -- + // this fails if the types are different but also if In doesn't have + // a template cast method. The type of this will either be + // std::false_type or std::true_type depending on if In and Out are + // compatible + template + static constexpr typename std::is_same().template cast()), Out>::type check(T*); + + // Fall back check type should the above check fail to be + // available (i.e. because In doesn't have a valid cast method) + template + static constexpr std::false_type check(...); + + // Find the type of invoking the check, this will either be true + // or false. + using type = decltype(check(nullptr)); + +public: + static constexpr bool value = type::value; +}; + +template +void getVal(U in, T& out) { + static_assert(has_cast::value,"Error: Can't cast U to T in getVal, did you pass a pybind11 object as the first argument?"); + out = in.template cast(); + return; +}; + int main() { { // Get access to a python interpreter with lifetime of the current scope @@ -49,7 +83,12 @@ int main() { for(int i=0; i<20; i++) { linspaceTest[py::make_tuple(i)] = i; } - py::print(linspaceTest); + py::print(linspaceTest); + + double theValue = linspaceTest[py::make_tuple(10)].cast(); + std::cout<<"The value is "< Date: Thu, 7 Feb 2019 11:39:12 +0000 Subject: [PATCH 13/19] Add an example of getting access to members of a numpy array in a loop --- examples/pybind-embed/pybind_embed.cxx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/examples/pybind-embed/pybind_embed.cxx b/examples/pybind-embed/pybind_embed.cxx index 59fd131787..cbd042f699 100644 --- a/examples/pybind-embed/pybind_embed.cxx +++ b/examples/pybind-embed/pybind_embed.cxx @@ -89,6 +89,14 @@ int main() { std::cout<<"The value is "<>(); + for (const auto &i: tmp){ + std::cout<<" with value "<< i.cast() << std::endl; + } + + // Here's another way of indexing the python array + auto buf = tmp.request(); + std::cout<<((double *) buf.ptr)[3]< Date: Thu, 7 Feb 2019 11:51:00 +0000 Subject: [PATCH 14/19] Demo an nd-Array and how to find the shape --- examples/pybind-embed/pybind_embed.cxx | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/examples/pybind-embed/pybind_embed.cxx b/examples/pybind-embed/pybind_embed.cxx index cbd042f699..db785e91eb 100644 --- a/examples/pybind-embed/pybind_embed.cxx +++ b/examples/pybind-embed/pybind_embed.cxx @@ -95,9 +95,15 @@ int main() { } // Here's another way of indexing the python array - auto buf = tmp.request(); - std::cout<<((double *) buf.ptr)[3]<>().request(); + std::cout<<"Element 3 from buffer with shape [ "; + for(const auto &i: buf.shape){ + std::cout< Date: Thu, 7 Feb 2019 20:04:26 +0000 Subject: [PATCH 15/19] Start to add a python based field generator with example Currently very hacky and ugly --- examples/fieldgen_python/.gitignore | 1 + examples/fieldgen_python/data/BOUT.inp | 22 +++++++ examples/fieldgen_python/fieldgen_python.cxx | 20 +++++++ examples/fieldgen_python/makefile | 6 ++ src/field/field_factory.cxx | 5 ++ src/field/fieldgenerators.cxx | 32 ++++++++++ src/field/fieldgenerators.hxx | 15 +++++ src/sys/expressionparser.cxx | 62 ++++++++++++++++++-- 8 files changed, 159 insertions(+), 4 deletions(-) create mode 100644 examples/fieldgen_python/.gitignore create mode 100644 examples/fieldgen_python/data/BOUT.inp create mode 100644 examples/fieldgen_python/fieldgen_python.cxx create mode 100644 examples/fieldgen_python/makefile diff --git a/examples/fieldgen_python/.gitignore b/examples/fieldgen_python/.gitignore new file mode 100644 index 0000000000..d8ee86bbc1 --- /dev/null +++ b/examples/fieldgen_python/.gitignore @@ -0,0 +1 @@ +fieldgen_python \ No newline at end of file diff --git a/examples/fieldgen_python/data/BOUT.inp b/examples/fieldgen_python/data/BOUT.inp new file mode 100644 index 0000000000..b70163a41b --- /dev/null +++ b/examples/fieldgen_python/data/BOUT.inp @@ -0,0 +1,22 @@ + +NOUT = 0 +TIMESTEP = 0.0 + +MZ = 8 +MXG = 1 +MYG = 1 + +[mesh] +nx = 3 +ny = 1 +symmetricGlobalX = true + +[solver] +type = rkgeneric + +[all] +bndry_all = none + +[f] +scale = 1 +function = python(\{z\}-\{y\}) diff --git a/examples/fieldgen_python/fieldgen_python.cxx b/examples/fieldgen_python/fieldgen_python.cxx new file mode 100644 index 0000000000..f4ee8fd284 --- /dev/null +++ b/examples/fieldgen_python/fieldgen_python.cxx @@ -0,0 +1,20 @@ +#include + + +class FieldGenPython : public PhysicsModel { +public: + int init(bool restarting) { + SOLVE_FOR(f); + return 0; + } + int rhs(BoutReal time) { + ddt(f) = 0.; + return 0; + } + +private: + Field3D f; +}; + + +BOUTMAIN(FieldGenPython); diff --git a/examples/fieldgen_python/makefile b/examples/fieldgen_python/makefile new file mode 100644 index 0000000000..d22ed46ce7 --- /dev/null +++ b/examples/fieldgen_python/makefile @@ -0,0 +1,6 @@ + +BOUT_TOP = ../.. + +SOURCEC = fieldgen_python.cxx + +include $(BOUT_TOP)/make.config diff --git a/src/field/field_factory.cxx b/src/field/field_factory.cxx index a281e97779..bc0cd6ef3b 100644 --- a/src/field/field_factory.cxx +++ b/src/field/field_factory.cxx @@ -93,6 +93,11 @@ FieldFactory::FieldFactory(Mesh * localmesh, Options *opt) : fieldmesh(localmesh // TanhHat function addGenerator("tanhhat", std::make_shared(nullptr, nullptr, nullptr, nullptr)); + + // Python function + addGenerator("python", + std::make_shared(nullptr)); + } FieldFactory::~FieldFactory() { diff --git a/src/field/fieldgenerators.cxx b/src/field/fieldgenerators.cxx index 0cc1f83953..0c83f559ab 100644 --- a/src/field/fieldgenerators.cxx +++ b/src/field/fieldgenerators.cxx @@ -278,3 +278,35 @@ BoutReal FieldTanhHat::generate(double x, double y, double z, double t) { - tanh( s*(X->generate(x,y,z,t) - (c + 0.5*w)) ) ); } + +////////////////////////////////////////////////////////// +// Python +FieldGeneratorPtr FieldPython::clone(const std::list args) { + // Call the constructor + return std::make_shared(args.front()); +} + +#undef _() +#include +#include + +namespace py = pybind11; +using namespace py::literals; + +BoutReal FieldPython::generate(double x, double y, double z, double t) { + py::scoped_interpreter guard{}; + // Evaluate in scope of main module + py::object scope = py::module::import("__main__").attr("__dict__"); + + auto kwargs = py::dict("x"_a=x, + "y"_a=y, + "z"_a=z, + "t"_a=t + ); + + // Evaluate an isolated expression + auto message = "{func}"_s.format(**py::dict("func"_a=(*gen).str())); + auto result = py::eval(message.format(**kwargs), scope).template cast(); + + return result; +} diff --git a/src/field/fieldgenerators.hxx b/src/field/fieldgenerators.hxx index 1da1cbfc3d..5995d1cdc5 100644 --- a/src/field/fieldgenerators.hxx +++ b/src/field/fieldgenerators.hxx @@ -337,4 +337,19 @@ private: FieldGeneratorPtr width, center, steepness; }; +////////////////////////////////////////////////////////// +// Python +class FieldPython : public FieldGenerator { +public: + // Constructor + FieldPython(): gen(nullptr) {}; + FieldPython(FieldGeneratorPtr g) : gen(g) {}; + + // Clone containing the list of arguments + FieldGeneratorPtr clone(const std::list args); + BoutReal generate(double x, double y, double z, double t); +private: + FieldGeneratorPtr gen = nullptr; +}; + #endif // __FIELDGENERATORS_H__ diff --git a/src/sys/expressionparser.cxx b/src/sys/expressionparser.cxx index dc14c22815..caf3debc21 100644 --- a/src/sys/expressionparser.cxx +++ b/src/sys/expressionparser.cxx @@ -58,7 +58,7 @@ namespace { // These classes only visible in this file } const std::string str() override { return std::string("y"); } }; - + class FieldZ : public FieldGenerator { public: FieldGeneratorPtr clone(const list UNUSED(args)) override { @@ -82,6 +82,54 @@ namespace { // These classes only visible in this file } const std::string str() override { return std::string("t"); } }; + + class FieldPyX : public FieldGenerator { + public: + FieldGeneratorPtr clone(const list UNUSED(args)) override { + return std::make_shared(); + } + double generate(double x, UNUSED(double) y, double UNUSED(z), + double UNUSED(t)) override { + return x; + } + const std::string str() override { return std::string("{x}"); } + }; + + class FieldPyY : public FieldGenerator { + public: + FieldGeneratorPtr clone(const list UNUSED(args)) override { + return std::make_shared(); + } + double generate(double UNUSED(x), double y, double UNUSED(z), + double UNUSED(t)) override { + return y; + } + const std::string str() override { return std::string("{y}"); } + }; + + class FieldPyZ : public FieldGenerator { + public: + FieldGeneratorPtr clone(const list UNUSED(args)) override { + return std::make_shared(); + } + double generate(double UNUSED(x), double UNUSED(y), double z, + double UNUSED(t)) override { + return z; + } + const std::string str() override { return std::string("{z}"); } + }; + + class FieldPyT : public FieldGenerator { + public: + FieldGeneratorPtr clone(const list UNUSED(args)) override { + return std::make_shared(); + } + double generate(double UNUSED(x), double UNUSED(y), double UNUSED(z), + double t) override { + return t; + } + const std::string str() override { return std::string("{t}"); } + }; } FieldGeneratorPtr FieldBinary::clone(const list args) { @@ -120,6 +168,12 @@ ExpressionParser::ExpressionParser() { addGenerator("y", std::make_shared()); addGenerator("z", std::make_shared()); addGenerator("t", std::make_shared()); + + addGenerator("{y}", std::make_shared()); + addGenerator("{y}", std::make_shared()); + addGenerator("{z}", std::make_shared()); + addGenerator("{t}", std::make_shared()); + } void ExpressionParser::addGenerator(const string &name, FieldGeneratorPtr g) { @@ -147,7 +201,7 @@ FieldGeneratorPtr ExpressionParser::parseIdentifierExpr(LexInfo &lex) { string name = lowercase(lex.curident); lex.nextToken(); - if(lex.curtok == '(') { + if(lex.curtok == '(' || lex.curtok == '{') { // Argument list. Find if a generator or function auto it = gen.find(name); @@ -158,7 +212,7 @@ FieldGeneratorPtr ExpressionParser::parseIdentifierExpr(LexInfo &lex) { list args; lex.nextToken(); - if(lex.curtok == ')') { + if(lex.curtok == ')' || lex.curtok == '}') { // Empty list lex.nextToken(); return it->second->clone(args); @@ -169,7 +223,7 @@ FieldGeneratorPtr ExpressionParser::parseIdentifierExpr(LexInfo &lex) { // Now either a comma or ')' - if(lex.curtok == ')') { + if(lex.curtok == ')' || lex.curtok == '}') { // Finished list lex.nextToken(); return it->second->clone(args); From cf8f5ccc3b786dc2ac4b8cc4f042e8c79e7c2f6e Mon Sep 17 00:00:00 2001 From: David Dickinson Date: Fri, 8 Feb 2019 09:51:48 +0000 Subject: [PATCH 16/19] Revert "Start to add a python based field generator with example" This reverts commit 98d9d7869f76d7bee02fc335f6eeaaa3cce8e73a. This commit serves as a record of one way to approach this. In the long run a larger rewrite is probably more useful and PR #1494 already provides some changes in this area. --- examples/fieldgen_python/.gitignore | 1 - examples/fieldgen_python/data/BOUT.inp | 22 ------- examples/fieldgen_python/fieldgen_python.cxx | 20 ------- examples/fieldgen_python/makefile | 6 -- src/field/field_factory.cxx | 5 -- src/field/fieldgenerators.cxx | 32 ---------- src/field/fieldgenerators.hxx | 15 ----- src/sys/expressionparser.cxx | 62 ++------------------ 8 files changed, 4 insertions(+), 159 deletions(-) delete mode 100644 examples/fieldgen_python/.gitignore delete mode 100644 examples/fieldgen_python/data/BOUT.inp delete mode 100644 examples/fieldgen_python/fieldgen_python.cxx delete mode 100644 examples/fieldgen_python/makefile diff --git a/examples/fieldgen_python/.gitignore b/examples/fieldgen_python/.gitignore deleted file mode 100644 index d8ee86bbc1..0000000000 --- a/examples/fieldgen_python/.gitignore +++ /dev/null @@ -1 +0,0 @@ -fieldgen_python \ No newline at end of file diff --git a/examples/fieldgen_python/data/BOUT.inp b/examples/fieldgen_python/data/BOUT.inp deleted file mode 100644 index b70163a41b..0000000000 --- a/examples/fieldgen_python/data/BOUT.inp +++ /dev/null @@ -1,22 +0,0 @@ - -NOUT = 0 -TIMESTEP = 0.0 - -MZ = 8 -MXG = 1 -MYG = 1 - -[mesh] -nx = 3 -ny = 1 -symmetricGlobalX = true - -[solver] -type = rkgeneric - -[all] -bndry_all = none - -[f] -scale = 1 -function = python(\{z\}-\{y\}) diff --git a/examples/fieldgen_python/fieldgen_python.cxx b/examples/fieldgen_python/fieldgen_python.cxx deleted file mode 100644 index f4ee8fd284..0000000000 --- a/examples/fieldgen_python/fieldgen_python.cxx +++ /dev/null @@ -1,20 +0,0 @@ -#include - - -class FieldGenPython : public PhysicsModel { -public: - int init(bool restarting) { - SOLVE_FOR(f); - return 0; - } - int rhs(BoutReal time) { - ddt(f) = 0.; - return 0; - } - -private: - Field3D f; -}; - - -BOUTMAIN(FieldGenPython); diff --git a/examples/fieldgen_python/makefile b/examples/fieldgen_python/makefile deleted file mode 100644 index d22ed46ce7..0000000000 --- a/examples/fieldgen_python/makefile +++ /dev/null @@ -1,6 +0,0 @@ - -BOUT_TOP = ../.. - -SOURCEC = fieldgen_python.cxx - -include $(BOUT_TOP)/make.config diff --git a/src/field/field_factory.cxx b/src/field/field_factory.cxx index bc0cd6ef3b..a281e97779 100644 --- a/src/field/field_factory.cxx +++ b/src/field/field_factory.cxx @@ -93,11 +93,6 @@ FieldFactory::FieldFactory(Mesh * localmesh, Options *opt) : fieldmesh(localmesh // TanhHat function addGenerator("tanhhat", std::make_shared(nullptr, nullptr, nullptr, nullptr)); - - // Python function - addGenerator("python", - std::make_shared(nullptr)); - } FieldFactory::~FieldFactory() { diff --git a/src/field/fieldgenerators.cxx b/src/field/fieldgenerators.cxx index 0c83f559ab..0cc1f83953 100644 --- a/src/field/fieldgenerators.cxx +++ b/src/field/fieldgenerators.cxx @@ -278,35 +278,3 @@ BoutReal FieldTanhHat::generate(double x, double y, double z, double t) { - tanh( s*(X->generate(x,y,z,t) - (c + 0.5*w)) ) ); } - -////////////////////////////////////////////////////////// -// Python -FieldGeneratorPtr FieldPython::clone(const std::list args) { - // Call the constructor - return std::make_shared(args.front()); -} - -#undef _() -#include -#include - -namespace py = pybind11; -using namespace py::literals; - -BoutReal FieldPython::generate(double x, double y, double z, double t) { - py::scoped_interpreter guard{}; - // Evaluate in scope of main module - py::object scope = py::module::import("__main__").attr("__dict__"); - - auto kwargs = py::dict("x"_a=x, - "y"_a=y, - "z"_a=z, - "t"_a=t - ); - - // Evaluate an isolated expression - auto message = "{func}"_s.format(**py::dict("func"_a=(*gen).str())); - auto result = py::eval(message.format(**kwargs), scope).template cast(); - - return result; -} diff --git a/src/field/fieldgenerators.hxx b/src/field/fieldgenerators.hxx index 5995d1cdc5..1da1cbfc3d 100644 --- a/src/field/fieldgenerators.hxx +++ b/src/field/fieldgenerators.hxx @@ -337,19 +337,4 @@ private: FieldGeneratorPtr width, center, steepness; }; -////////////////////////////////////////////////////////// -// Python -class FieldPython : public FieldGenerator { -public: - // Constructor - FieldPython(): gen(nullptr) {}; - FieldPython(FieldGeneratorPtr g) : gen(g) {}; - - // Clone containing the list of arguments - FieldGeneratorPtr clone(const std::list args); - BoutReal generate(double x, double y, double z, double t); -private: - FieldGeneratorPtr gen = nullptr; -}; - #endif // __FIELDGENERATORS_H__ diff --git a/src/sys/expressionparser.cxx b/src/sys/expressionparser.cxx index caf3debc21..dc14c22815 100644 --- a/src/sys/expressionparser.cxx +++ b/src/sys/expressionparser.cxx @@ -58,7 +58,7 @@ namespace { // These classes only visible in this file } const std::string str() override { return std::string("y"); } }; - + class FieldZ : public FieldGenerator { public: FieldGeneratorPtr clone(const list UNUSED(args)) override { @@ -82,54 +82,6 @@ namespace { // These classes only visible in this file } const std::string str() override { return std::string("t"); } }; - - class FieldPyX : public FieldGenerator { - public: - FieldGeneratorPtr clone(const list UNUSED(args)) override { - return std::make_shared(); - } - double generate(double x, UNUSED(double) y, double UNUSED(z), - double UNUSED(t)) override { - return x; - } - const std::string str() override { return std::string("{x}"); } - }; - - class FieldPyY : public FieldGenerator { - public: - FieldGeneratorPtr clone(const list UNUSED(args)) override { - return std::make_shared(); - } - double generate(double UNUSED(x), double y, double UNUSED(z), - double UNUSED(t)) override { - return y; - } - const std::string str() override { return std::string("{y}"); } - }; - - class FieldPyZ : public FieldGenerator { - public: - FieldGeneratorPtr clone(const list UNUSED(args)) override { - return std::make_shared(); - } - double generate(double UNUSED(x), double UNUSED(y), double z, - double UNUSED(t)) override { - return z; - } - const std::string str() override { return std::string("{z}"); } - }; - - class FieldPyT : public FieldGenerator { - public: - FieldGeneratorPtr clone(const list UNUSED(args)) override { - return std::make_shared(); - } - double generate(double UNUSED(x), double UNUSED(y), double UNUSED(z), - double t) override { - return t; - } - const std::string str() override { return std::string("{t}"); } - }; } FieldGeneratorPtr FieldBinary::clone(const list args) { @@ -168,12 +120,6 @@ ExpressionParser::ExpressionParser() { addGenerator("y", std::make_shared()); addGenerator("z", std::make_shared()); addGenerator("t", std::make_shared()); - - addGenerator("{y}", std::make_shared()); - addGenerator("{y}", std::make_shared()); - addGenerator("{z}", std::make_shared()); - addGenerator("{t}", std::make_shared()); - } void ExpressionParser::addGenerator(const string &name, FieldGeneratorPtr g) { @@ -201,7 +147,7 @@ FieldGeneratorPtr ExpressionParser::parseIdentifierExpr(LexInfo &lex) { string name = lowercase(lex.curident); lex.nextToken(); - if(lex.curtok == '(' || lex.curtok == '{') { + if(lex.curtok == '(') { // Argument list. Find if a generator or function auto it = gen.find(name); @@ -212,7 +158,7 @@ FieldGeneratorPtr ExpressionParser::parseIdentifierExpr(LexInfo &lex) { list args; lex.nextToken(); - if(lex.curtok == ')' || lex.curtok == '}') { + if(lex.curtok == ')') { // Empty list lex.nextToken(); return it->second->clone(args); @@ -223,7 +169,7 @@ FieldGeneratorPtr ExpressionParser::parseIdentifierExpr(LexInfo &lex) { // Now either a comma or ')' - if(lex.curtok == ')' || lex.curtok == '}') { + if(lex.curtok == ')') { // Finished list lex.nextToken(); return it->second->clone(args); From ea4f1f457c05e6f2614c6f4721ba6e0acf7246a3 Mon Sep 17 00:00:00 2001 From: David Dickinson Date: Wed, 22 May 2019 11:42:19 +0100 Subject: [PATCH 17/19] Bugfix for pybind11 example --- examples/pybind-embed/pybind_embed.cxx | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/pybind-embed/pybind_embed.cxx b/examples/pybind-embed/pybind_embed.cxx index db785e91eb..55f3ad8d0e 100644 --- a/examples/pybind-embed/pybind_embed.cxx +++ b/examples/pybind-embed/pybind_embed.cxx @@ -1,4 +1,5 @@ #ifdef BOUT_HAS_PYBIND11 +#include #include #include From 2672e524f2bb0332e877df82bc8733f07e3f5f3f Mon Sep 17 00:00:00 2001 From: David Dickinson Date: Wed, 22 May 2019 11:42:30 +0100 Subject: [PATCH 18/19] Add plotting to pybind11 example. --- examples/pybind-embed/pybind_embed.cxx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/examples/pybind-embed/pybind_embed.cxx b/examples/pybind-embed/pybind_embed.cxx index 55f3ad8d0e..fe533972fe 100644 --- a/examples/pybind-embed/pybind_embed.cxx +++ b/examples/pybind-embed/pybind_embed.cxx @@ -85,7 +85,12 @@ int main() { linspaceTest[py::make_tuple(i)] = i; } py::print(linspaceTest); - + py::module matplot = py::module::import("matplotlib.pyplot"); + matplot.attr("ioff")(); + matplot.attr("plot")(linspaceTest,"-o"); + matplot.attr("xlabel")("This is the x axis label"); + matplot.attr("ylabel")("$\\alpha$ is alpha"); + matplot.attr("show")(); double theValue = linspaceTest[py::make_tuple(10)].cast(); std::cout<<"The value is "< Date: Wed, 22 May 2019 11:44:21 +0100 Subject: [PATCH 19/19] Correct the googletest version --- externalpackages/googletest | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externalpackages/googletest b/externalpackages/googletest index 4bab34d208..8b6d3f9c4a 160000 --- a/externalpackages/googletest +++ b/externalpackages/googletest @@ -1 +1 @@ -Subproject commit 4bab34d2084259cba67f3bfb51217c10d606e175 +Subproject commit 8b6d3f9c4a774bef3081195d422993323b6bb2e0