From 3e847c19f0a170cb39d674a2d06f4dabb657cff7 Mon Sep 17 00:00:00 2001 From: Josh Hursey Date: Tue, 26 May 2009 20:49:35 +0000 Subject: [PATCH] Per RFC: MPI Interface Extensions Infrastructure Add infrastructure for MPI Interface Extensions. This allows a developer to create new MPI interfaces that are non-standard. The following email thread describes the functionality proposed in the RFC: http://www.open-mpi.org/community/lists/devel/2009/05/5997.php The following wiki page describes how to use and enable the extensions: https://svn.open-mpi.org/trac/ompi/wiki/MPIExtensions This commit was SVN r21272. --- acinclude.m4 | 14 +- autogen.sh | 364 ++++++++++++- config/ompi_ext.m4 | 689 +++++++++++++++++++++++++ configure.ac | 18 +- ompi/Makefile.am | 8 +- ompi/include/Makefile.am | 6 +- ompi/mpiext/Makefile.am | 10 + ompi/mpiext/example/Makefile.am | 29 ++ ompi/mpiext/example/c/progress.c | 26 + ompi/mpiext/example/configure.m4 | 17 + ompi/mpiext/example/configure.params | 12 + ompi/mpiext/example/mpiext_example_c.h | 12 + ompi/tools/ompi_info/ompi_info.h | 8 +- ompi/tools/ompi_info/output.cc | 37 +- ompi/tools/ompi_info/param.cc | 8 +- 15 files changed, 1234 insertions(+), 24 deletions(-) create mode 100644 config/ompi_ext.m4 create mode 100644 ompi/mpiext/Makefile.am create mode 100644 ompi/mpiext/example/Makefile.am create mode 100644 ompi/mpiext/example/c/progress.c create mode 100644 ompi/mpiext/example/configure.m4 create mode 100644 ompi/mpiext/example/configure.params create mode 100644 ompi/mpiext/example/mpiext_example_c.h diff --git a/acinclude.m4 b/acinclude.m4 index 6cbb7ad852..747670520c 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1,6 +1,6 @@ dnl -*- shell-script -*- dnl -dnl Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +dnl Copyright (c) 2004-2009 The Trustees of Indiana University and Indiana dnl University Research and Technology dnl Corporation. All rights reserved. dnl Copyright (c) 2004-2005 The University of Tennessee and The University @@ -29,8 +29,20 @@ m4_include(config/ompi_get_version.m4) # m4_include(config/mca_no_configure_components.m4) +# +# The config/ext_no_configure_components.m4 file is generated by +# autogen.sh +# +m4_include(config/ext_no_configure_components.m4) + # # mca_m4_config_include.m4 is generated by autogen.sh. It includes # the list of all component configure.m4 macros. # m4_include(config/mca_m4_config_include.m4) + +# +# ext_m4_config_include.m4 is generated by autogen.sh. It includes +# the list of all interface extension component configure.m4 macros. +# +m4_include(config/ext_m4_config_include.m4) diff --git a/autogen.sh b/autogen.sh index 590daee90b..44a6916fa0 100755 --- a/autogen.sh +++ b/autogen.sh @@ -1,6 +1,6 @@ #! /usr/bin/env bash # -# Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana +# Copyright (c) 2004-2009 The Trustees of Indiana University and Indiana # University Research and Technology # Corporation. All rights reserved. # Copyright (c) 2004-2005 The University of Tennessee and The University @@ -87,6 +87,13 @@ mca_no_config_list_file="mca_no_config_list" mca_no_config_env_file="mca_no_config_env" mca_m4_include_file="config/mca_m4_config_include.m4" mca_m4_config_env_file="mca_m4_config_env" + +ext_no_configure_components_file="config/ext_no_configure_components.m4" +ext_no_config_list_file="ext_no_config_list" +ext_no_config_env_file="ext_no_config_env" +ext_m4_include_file="config/ext_m4_config_include.m4" +ext_m4_config_env_file="ext_m4_config_env" + autogen_subdir_file="autogen.subdirs" topdir_file="opal/include/opal_config_bottom.h" @@ -587,8 +594,13 @@ run_no_configure_component() { noconf_component="$5" # Write out to two files (they're merged at the end) - noconf_list_file="$noconf_ompi_topdir/$mca_no_config_list_file" - noconf_env_file="$noconf_ompi_topdir/$mca_no_config_env_file" + if test $6 = "mca" ; then + noconf_list_file="$noconf_ompi_topdir/$mca_no_config_list_file" + noconf_env_file="$noconf_ompi_topdir/$mca_no_config_env_file" + else + noconf_list_file="$noconf_ompi_topdir/$ext_no_config_list_file" + noconf_env_file="$noconf_ompi_topdir/$ext_no_config_env_file" + fi cat >> "$noconf_list_file" <> "$m4conf_list_file" <> "$m4conf_ompi_topdir/$mca_m4_include_file" + if test $6 = "mca" ; then + echo "m4_include(${m4conf_project}/mca/${m4conf_framework}/${m4conf_component}/configure.m4)" >> "$m4conf_ompi_topdir/$mca_m4_include_file" + else + echo "m4_include(${m4conf_project}/${m4conf_framework}/${m4conf_component}/configure.m4)" >> "$m4conf_ompi_topdir/$ext_m4_include_file" + fi cat < Adding to top-level configure m4-configure subdirs: @@ -878,7 +899,7 @@ EOF rm -f "configure" "configure.ac*" "acinclude*" "aclocal.m4" run_m4_configure_component "$pd_dir" "$pd_ompi_topdir" \ - "$pd_project" "$pd_framework" "$pd_component" + "$pd_project" "$pd_framework" "$pd_component" "mca" fi elif test -f configure.ac -o -f configure.in; then @@ -917,7 +938,198 @@ EOF EOF else run_no_configure_component "$pd_dir" "$pd_ompi_topdir" \ - "$pd_project" "$pd_framework" "$pd_component" + "$pd_project" "$pd_framework" "$pd_component" "mca" + fi + else + cat < Found $autogen_subdir_file -- sub-traversing..." + echo "" + for dir in `cat $autogen_subdir_file`; do + if test -d "$dir"; then + echo "*** Running autogen.sh in $dir" + echo "*** (started in $pd_subdir_start_dir)" + cd "$dir" + $pd_ompi_topdir/autogen.sh -l + if test ! $? -eq 0 ; then + echo "Error running autogen.sh -l in $dir. Aborting." + exit 1 + fi + cd "$pd_subdir_start_dir" + echo "" + fi + done + echo "<== Back in $pd_subdir_start_dir" + echo "<== autogen.sh continuing..." + fi + + # Go back to the topdir + + cd "$pd_cur_dir" + fi + unset PARAM_CONFIG_FILES PARAM_VERSION_FILE + unset pd_dir pd_ompi_topdir pd_cur_dir pd_component_type +} + +process_ext_dir() { + pd_dir="$1" + pd_ompi_topdir="$2" + pd_project="$3" + pd_framework="$4" + pd_component="$5" + + pd_cur_dir="`pwd`" + + # Convert to absolutes + + if test -d "$pd_dir"; then + cd "$pd_dir" + pd_abs_dir="`pwd`" + cd "$pd_cur_dir" + fi + + if test -d "$pd_ompi_topdir"; then + cd "$pd_ompi_topdir" + pd_ompi_topdir="`pwd`" + cd "$pd_cur_dir" + fi + + # clean our environment a bit, since we might evaluate a configure.params + unset PARAM_CONFIG_FILES + PARAM_CONFIG_PRIORITY="0" + + if test -d "$pd_dir"; then + cd "$pd_dir" + + # See if the package doesn't want us to set it up + + if test -f .ompi_no_gnu; then + cat <> "$ext_m4_include_file" + fi + echo "AC_CONFIG_FILES(${framework_path}/Makefile)" >> "$ext_no_config_list_file" + + rm -f "$ext_no_config_env_file" "$ext_m4_config_env_file" + touch "$ext_no_config_env_file" "$ext_m4_config_env_file" + + for component_path in "$framework_path"/*; do + if test -d "$component_path"; then + if test -f "$component_path/configure.in" -o \ + -f "$component_path/configure.params" -o \ + -f "$component_path/configure.ac"; then + + component=`basename "$component_path"` + + process_ext_dir "$component_path" "$rg_cwd" \ + "$project" "$framework" "$component" + fi + fi + done + + # make list of components that are "no configure". + # Sort the list by priority (stable, so things stay in + # alphabetical order at the same priority), then munge + # it into form we like + component_list= + component_list_sort $ext_no_config_env_file + component_list_define="m4_define([ext_${framework}_no_config_component_list], [" + component_list_define_first="1" + for component in $component_list ; do + if test "$component_list_define_first" = "1"; then + component_list_define="${component_list_define}${component}" + component_list_define_first="0" + else + component_list_define="${component_list_define}, ${component}" + fi + done + component_list_define="${component_list_define}])" + echo "$component_list_define" >> "$ext_no_configure_components_file" + + # make list of components that are "m4 configure" + component_list= + component_list_sort $ext_m4_config_env_file + component_list_define="m4_define([ext_${framework}_m4_config_component_list], [" + component_list_define_first="1" + for component in $component_list ; do + if test "$component_list_define_first" = "1"; then + component_list_define="${component_list_define}${component}" + component_list_define_first="0" + else + component_list_define="${component_list_define}, ${component}" + fi + done + component_list_define="${component_list_define}])" + echo "$component_list_define" >> "$ext_no_configure_components_file" + fi +} + process_project() { project_path="$1" rg_cwd="$2" @@ -1069,6 +1351,27 @@ process_project() { process_dir $contrib_path $rg_cwd done fi + + # Extensions interface only applicable to ompi project + if test $project = "ompi" ; then + # Process interface extensions + framework_ext_list="" + process_ext_framework $project_path/mpiext $rg_cwd $project "mpiext" + + # make list of frameworks for this project + framework_ext_list_define="m4_define([ext_${project}_framework_list], [" + framework_ext_list_define_first="1" + for framework in $framework_ext_list ; do + if test "$framework_ext_list_define_first" = "1"; then + framework_ext_list_define="${framework_ext_list_define}${framework}" + framework_ext_list_define_first="0" + else + framework_ext_list_define="${framework_ext_list_define}, ${framework}" + fi + done + framework_ext_list_define="${framework_ext_list_define}])" + echo "$framework_ext_list_define" >> "$ext_no_configure_components_file" + fi } @@ -1113,6 +1416,34 @@ dnl dnl This file is automatically created by autogen.sh; it should not dnl be edited by hand!! +EOF + + # [Re-]Create the ext_component_list file + rm -f "$ext_no_configure_components_file" "$ext_no_config_list_file" \ + "$ext_no_config_env_file" "$ext_m4_config_env_file" "$ext_m4_include_file" + touch "$ext_no_configure_components_file" "$ext_no_config_list_file" \ + "$ext_m4_config_env_file" "$ext_m4_include_file" + + # create header for the component m4 include file + cat > "$ext_m4_include_file" < "$ext_no_configure_components_file" </mca/*/* @@ -1150,6 +1481,11 @@ EOF project_list_define="${project_list_define}])" echo "$project_list_define" >> "$mca_no_configure_components_file" + # create the m4 defines for the list of projects where MPI Extensions + # apply, which is only 'ompi' + project_list_define="m4_define([ext_project_list], [ompi])" + echo "$project_list_define" >> "$ext_no_configure_components_file" + cat >> "$mca_no_configure_components_file" <> "$ext_no_configure_components_file" < $mpi_ext_h <> $mpi_ext_h <__CONFIG + # macro, print a friendly warning and abort. + [AC_MSG_WARN([*** The $2:$3 did not define an]) + AC_MSG_WARN([*** EXT_$2_$3_CONFIG macro in the]) + AC_MSG_WARN([*** $1/$2/$3/configure.m4 file]) + AC_MSG_ERROR([Cannot continue])]) + ]) + + AS_IF([test "$should_build" = "1"], + [EXT_PROCESS_COMPONENT($1, $2, $3, $4, $6, $compile_mode) + # add component to static component list + $5="$$5 $3" ], + [EXT_PROCESS_DEAD_COMPONENT($1, $2, $3) + # add component to all component list + $4="$$4 $3"]) + + m4_ifdef([EXT_$2_$3_POST_CONFIG], + [EXT_$2_$3_POST_CONFIG($should_build)]) + + AS_IF([test "$should_build" = "1"],[$8], [$9]) + + unset compile_mode +]) + + +###################################################################### +# +# EXT_CONFIGURE_ALL_CONFIG_COMPONENTS +# +# configure all components in the given framework that have configure +# scripts and should be configured according to the usual rules... +# +# USAGE: +# EXT_CONFIGURE_ALL_CONFIG_COMPONENTS(project_name, +# framework_name, +# all_components_variable, +# static_ltlibs_variable) +# +###################################################################### +AC_DEFUN([EXT_CONFIGURE_ALL_CONFIG_COMPONENTS],[ + for component_path in $srcdir/$1/$2/* ; do + component="`basename $component_path`" + if test -d $component_path -a -x $component_path/configure ; then + ompi_show_subsubsubtitle "EXT component $2:$component (need to configure)" + + EXT_COMPONENT_BUILD_CHECK($1, $2, $component, + [should_build=1], [should_build=0]) + EXT_COMPONENT_COMPILE_MODE($1, $2, $component, compile_mode) + + if test "$should_build" = "1" ; then + OMPI_CONFIG_SUBDIR([$1/$2/$component], + [$ompi_subdir_args], + [should_build=1], [should_build=2]) + fi + + if test "$should_build" = "1" ; then + EXT_PROCESS_COMPONENT($1, $2, $component, $3, $4, $compile_mode) + else + EXT_PROCESS_DEAD_COMPONENT($1, $2, $component) + fi + fi + done +]) + + +###################################################################### +# +# EXT_COMPONENT_COMPILE_MODE +# +# set compile_mode_variable to the compile mode for the given component +# +# USAGE: +# EXT_COMPONENT_COMPILE_MODE(project_name, +# framework_name, component_name +# compile_mode_variable) +# +# NOTE: component_name may not be determined until runtime.... +# +###################################################################### +AC_DEFUN([EXT_COMPONENT_COMPILE_MODE],[ + project=$1 + framework=$2 + component=$3 + + # Extensions are always static, no need for further checks + $4="static" + + #AC_MSG_CHECKING([for EXT component $framework:$component compile mode]) + #AC_MSG_RESULT([$$4]) +]) + + +###################################################################### +# +# EXT_PROCESS_COMPONENT +# +# does all setup work for given component. It should be known before +# calling that this component can build properly (and exists) +# +# USAGE: +# EXT_CONFIGURE_ALL_CONFIG_COMPONENTS(project_name, +# framework_name, component_name +# all_components_variable (4), +# static_ltlibs_variable (5), +# compile_mode_variable (6)) +# +# NOTE: component_name may not be determined until runtime.... +# +# M4 directive to disable language support in configure.m4 +# Need to build a list of .la for each lang. to pull into final library +# List ext_c_headers, ext_c_libs {same for other lang.} +# C: framework_component_c{.h, .la} +# CXX: framework_component_cxx{.h, .la} +# F77: framework_component_f77{.h, .la} +# F90: framework_component_f90{.h, .la} ??? +###################################################################### +AC_DEFUN([EXT_PROCESS_COMPONENT],[ + AC_REQUIRE([AC_PROG_GREP]) + + project=$1 + framework=$2 + component=$3 + + # Output pretty results + AC_MSG_CHECKING([if EXT component $framework:$component can compile]) + AC_MSG_RESULT([yes]) + + # Save the list of headers and convenience libraries that this component will output + # There *must* be C bindings + EXT_C_HEADERS="$EXT_C_HEADERS $framework/$component/${framework}_${component}_c.h" + EXT_C_LIBS="$EXT_C_LIBS $framework/$component/libext_${framework}_${component}.la" + + component_header="${framework}_${component}_c.h" + tmp[=]m4_translit([$3],[a-z],[A-Z]) + component_define="OMPI_HAVE_MPI_EXT_${tmp}" + + cat >> $mpi_ext_h < + +#include "ompi/mpi/c/bindings.h" +#include "ompi/mpiext/example/mpiext_example_c.h" + +static const char FUNC_NAME[] = "OMPI_Progress"; + + +int OMPI_Progress(char * stmt) +{ + printf("%s!!!\n", stmt); + + return MPI_SUCCESS; +} + diff --git a/ompi/mpiext/example/configure.m4 b/ompi/mpiext/example/configure.m4 new file mode 100644 index 0000000000..adbe190811 --- /dev/null +++ b/ompi/mpiext/example/configure.m4 @@ -0,0 +1,17 @@ +# -*- shell-script -*- +# +# Copyright (c) 2004-2009 The Trustees of Indiana University. +# All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +# EXT_ompi_example_CONFIG([action-if-found], [action-if-not-found]) +# ----------------------------------------------------------- +AC_DEFUN([EXT_mpiext_example_CONFIG],[ + # Left empty as a stub for copy-paste of new extensions + echo "MPIEXT Example: Inside configure.m4" +])dnl diff --git a/ompi/mpiext/example/configure.params b/ompi/mpiext/example/configure.params new file mode 100644 index 0000000000..ab1618d600 --- /dev/null +++ b/ompi/mpiext/example/configure.params @@ -0,0 +1,12 @@ +# -*- shell-script -*- +# +# Copyright (c) 2004-2009 The Trustees of Indiana University. +# All rights reserved. +# $COPYRIGHT$ +# +# Additional copyrights may follow +# +# $HEADER$ +# + +PARAM_CONFIG_FILES="Makefile" diff --git a/ompi/mpiext/example/mpiext_example_c.h b/ompi/mpiext/example/mpiext_example_c.h new file mode 100644 index 0000000000..8c250af2e8 --- /dev/null +++ b/ompi/mpiext/example/mpiext_example_c.h @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2004-2009 The Trustees of Indiana University. + * All rights reserved. + * $COPYRIGHT$ + * + * Additional copyrights may follow + * + * $HEADER$ + * + */ + +OMPI_DECLSPEC int OMPI_Progress(char * stmt); diff --git a/ompi/tools/ompi_info/ompi_info.h b/ompi/tools/ompi_info/ompi_info.h index ba284f78dc..c844aa3eab 100644 --- a/ompi/tools/ompi_info/ompi_info.h +++ b/ompi/tools/ompi_info/ompi_info.h @@ -1,5 +1,5 @@ // -// Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +// Copyright (c) 2004-2009 The Trustees of Indiana University and Indiana // University Research and Technology // Corporation. All rights reserved. // Copyright (c) 2004-2005 The University of Tennessee and The University @@ -9,7 +9,7 @@ // University of Stuttgart. All rights reserved. // Copyright (c) 2004-2005 The Regents of the University of California. // All rights reserved. -// Copyright (c) 2007-2008 Cisco Systems, Inc. All rights reserved. +// Copyright (c) 2007-2009 Cisco Systems, Inc. All rights reserved. // $COPYRIGHT$ // // Additional copyrights may follow @@ -110,7 +110,9 @@ namespace ompi_info { int value); void out(const std::string& pretty_message, const std::string &plain_message, - const std::string& value); + const std::string& value, + bool strip_leading_whitespace = true, + bool strip_trailing_whitespace = true); // // Component-related functions diff --git a/ompi/tools/ompi_info/output.cc b/ompi/tools/ompi_info/output.cc index 9cb8b3dfff..d7e363db73 100644 --- a/ompi/tools/ompi_info/output.cc +++ b/ompi/tools/ompi_info/output.cc @@ -1,5 +1,5 @@ // -// Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +// Copyright (c) 2004-2009 The Trustees of Indiana University and Indiana // University Research and Technology // Corporation. All rights reserved. // Copyright (c) 2004-2006 The University of Tennessee and The University @@ -9,6 +9,7 @@ // University of Stuttgart. All rights reserved. // Copyright (c) 2004-2005 The Regents of the University of California. // All rights reserved. +// Copyright (c) 2009 Cisco Systems, Inc. All rights reserved. // $COPYRIGHT$ // // Additional copyrights may follow @@ -57,8 +58,11 @@ static int screen_width = 78; // Prints the passed strings in a pretty or parsable format. // void ompi_info::out(const string& pretty_message, const string &plain_message, - const string& value) + const string& value, bool strip_leading_whitespace, + bool strip_trailing_whitespace) { + string local_value = value; + #ifdef HAVE_ISATTY // If we have isatty(), if this is not a tty, then disable // wrapping for grep-friendly behavior @@ -76,10 +80,33 @@ void ompi_info::out(const string& pretty_message, const string &plain_message, } #endif + if (strip_leading_whitespace) { + string::size_type i = 0; + while (i < local_value.length() && isspace(local_value[i])) { + ++i; + } + if (i > local_value.length()) { + local_value = ""; + } else if (i > 0) { + local_value = local_value.substr(i); + } + } + if (strip_trailing_whitespace) { + string::size_type i = local_value.length(); + while (i >= 0 && isspace(local_value[i])) { + --i; + } + if (i < 0) { + local_value = ""; + } else if (i >= 0) { + local_value = local_value.substr(0, i); + } + } + if (pretty) { string::size_type pos, max_value_width; string spaces; - string v = value; + string v = local_value; string filler; int num_spaces = (int)(centerpoint - pretty_message.length()); @@ -135,9 +162,9 @@ void ompi_info::out(const string& pretty_message, const string &plain_message, } } else { if (!plain_message.empty()) { - cout << plain_message << ":" << value << endl; + cout << plain_message << ":" << local_value << endl; } else { - cout << value << endl; + cout << local_value << endl; } } } diff --git a/ompi/tools/ompi_info/param.cc b/ompi/tools/ompi_info/param.cc index dd7380ce57..8fbe946443 100644 --- a/ompi/tools/ompi_info/param.cc +++ b/ompi/tools/ompi_info/param.cc @@ -1,5 +1,5 @@ // -// Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana +// Copyright (c) 2004-2009 The Trustees of Indiana University and Indiana // University Research and Technology // Corporation. All rights reserved. // Copyright (c) 2004-2006 The University of Tennessee and The University @@ -9,7 +9,7 @@ // University of Stuttgart. All rights reserved. // Copyright (c) 2004-2005 The Regents of the University of California. // All rights reserved. -// Copyright (c) 2007-2008 Cisco Systems, Inc. All rights reserved. +// Copyright (c) 2007-2009 Cisco Systems, Inc. All rights reserved. // Copyright (c) 2009 Oak Ridge National Labs. All rights reserved. // $COPYRIGHT$ // @@ -549,7 +549,7 @@ void ompi_info::do_config(bool want_all) string ft_support; ft_support = OPAL_ENABLE_FT ? "yes" : "no"; - ft_support += " (checkpoint thread: "; + ft_support += " (checkpoint thread: "; ft_support += OPAL_ENABLE_FT_THREAD ? "yes" : "no"; ft_support += ")"; @@ -781,5 +781,7 @@ void ompi_info::do_config(bool want_all) out("MPI_WTIME support", "options:mpi-wtime", wtime_support); out("Symbol visibility support", "options:visibility", symbol_visibility); + out("MPI extensions", "options:mpi_ext", OMPI_EXT_COMPONENTS); + out("FT Checkpoint support", "options:ft_support", ft_support); }