From e6e67305ecc66829721213aea23743f933b23b5d Mon Sep 17 00:00:00 2001 From: pini Date: Mon, 22 Nov 2010 17:21:01 +0000 Subject: [PATCH] Support for Fortran code in SMPI based on f2c, some perl and some dirty hacks. Only few MPI calls are implemented yet. git-svn-id: svn+ssh://scm.gforge.inria.fr/svn/simgrid/simgrid/trunk@8609 48e7efb5-ca39-0410-a469-dd3cf9ba447f --- buildtools/Cmake/AddTests.cmake | 2 + buildtools/Cmake/CompleteInFiles.cmake | 4 ++ buildtools/Cmake/DefinePackages.cmake | 5 ++ buildtools/Cmake/Distrib.cmake | 4 ++ include/smpi/mpif.h | 74 ++++++++++++++++++++ include/smpi/smpi.h | 3 + include/smpi/smpif.h | 18 +++++ src/smpi/private.h | 14 ++++ src/smpi/smpi_base.c | 26 ------- src/smpi/smpi_f77.c | 65 ++++++++++++++++++ src/smpi/smpi_global.c | 95 ++++++++++++++++++++++++-- src/smpi/smpicc.in | 24 ++++--- src/smpi/smpif2c.in | 49 +++++++++++++ src/smpi/smpiff.in | 28 ++++++++ src/smpi/smpirun.in | 1 + 15 files changed, 371 insertions(+), 41 deletions(-) create mode 100644 include/smpi/mpif.h create mode 100644 include/smpi/smpif.h create mode 100644 src/smpi/smpi_f77.c create mode 100755 src/smpi/smpif2c.in create mode 100644 src/smpi/smpiff.in diff --git a/buildtools/Cmake/AddTests.cmake b/buildtools/Cmake/AddTests.cmake index 18d2fca269..58c1248d82 100644 --- a/buildtools/Cmake/AddTests.cmake +++ b/buildtools/Cmake/AddTests.cmake @@ -2,6 +2,8 @@ exec_program("chmod a=rwx ${PROJECT_DIRECTORY}/buildtools/Cmake/test_java.sh" OUTPUT_VARIABLE "OKITOKI") if(enable_smpi) exec_program("chmod a=rwx ${CMAKE_BINARY_DIR}/bin/smpicc" OUTPUT_VARIABLE "OKITOKI") + exec_program("chmod a=rwx ${CMAKE_BINARY_DIR}/bin/smpif2c" OUTPUT_VARIABLE "OKITOKI") + exec_program("chmod a=rwx ${CMAKE_BINARY_DIR}/bin/smpiff" OUTPUT_VARIABLE "OKITOKI") exec_program("chmod a=rwx ${CMAKE_BINARY_DIR}/bin/smpirun" OUTPUT_VARIABLE "OKITOKI") endif(enable_smpi) diff --git a/buildtools/Cmake/CompleteInFiles.cmake b/buildtools/Cmake/CompleteInFiles.cmake index c6cc60e194..ba549716ee 100644 --- a/buildtools/Cmake/CompleteInFiles.cmake +++ b/buildtools/Cmake/CompleteInFiles.cmake @@ -801,10 +801,14 @@ set(CMAKE_LINKARGS "${CMAKE_CURRENT_BINARY_DIR}/lib") set(CMAKE_SMPI_COMMAND "export LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}/lib:${gtnets_path}/lib:$LD_LIBRARY_PATH") configure_file(${PROJECT_DIRECTORY}/src/smpi/smpicc.in ${CMAKE_CURRENT_BINARY_DIR}/bin/smpicc @ONLY) +configure_file(${PROJECT_DIRECTORY}/src/smpi/smpif2c.in ${CMAKE_CURRENT_BINARY_DIR}/bin/smpif2c @ONLY) +configure_file(${PROJECT_DIRECTORY}/src/smpi/smpiff.in ${CMAKE_CURRENT_BINARY_DIR}/bin/smpiff @ONLY) configure_file(${PROJECT_DIRECTORY}/src/smpi/smpirun.in ${CMAKE_CURRENT_BINARY_DIR}/bin/smpirun @ONLY) configure_file(${PROJECT_DIRECTORY}/examples/smpi/hostfile ${CMAKE_CURRENT_BINARY_DIR}/examples/smpi/hostfile COPYONLY) configure_file(${PROJECT_DIRECTORY}/examples/msg/small_platform.xml ${CMAKE_CURRENT_BINARY_DIR}/examples/msg/small_platform.xml COPYONLY) configure_file(${PROJECT_DIRECTORY}/examples/msg/small_platform_with_routers.xml ${CMAKE_CURRENT_BINARY_DIR}/examples/msg/small_platform_with_routers.xml COPYONLY) exec_program("chmod a=rwx ${CMAKE_CURRENT_BINARY_DIR}/bin/smpicc" OUTPUT_VARIABLE OKITOKI) +exec_program("chmod a=rwx ${CMAKE_CURRENT_BINARY_DIR}/bin/smpif2c" OUTPUT_VARIABLE OKITOKI) +exec_program("chmod a=rwx ${CMAKE_CURRENT_BINARY_DIR}/bin/smpiff" OUTPUT_VARIABLE OKITOKI) exec_program("chmod a=rwx ${CMAKE_CURRENT_BINARY_DIR}/bin/smpirun" OUTPUT_VARIABLE OKITOKI) diff --git a/buildtools/Cmake/DefinePackages.cmake b/buildtools/Cmake/DefinePackages.cmake index cfe55c71eb..b4c2639e2a 100644 --- a/buildtools/Cmake/DefinePackages.cmake +++ b/buildtools/Cmake/DefinePackages.cmake @@ -105,6 +105,7 @@ set(SMPI_SRC src/smpi/smpi_bench.c src/smpi/smpi_global.c src/smpi/smpi_mpi.c + src/smpi/smpi_f77.c src/smpi/smpi_comm.c src/smpi/smpi_group.c src/smpi/smpi_util.c @@ -399,7 +400,9 @@ include/msg/datatypes.h include/simdag/simdag.h include/simdag/datatypes.h include/smpi/smpi.h +include/smpi/smpif.h include/smpi/mpi.h +include/smpi/mpif.h include/surf/surfxml_parse.h include/surf/simgrid_dtd.h include/gras/datadesc.h @@ -613,6 +616,8 @@ file(GLOB_RECURSE add_src_files set(add_src_files ${add_src_files} src/smpi/smpicc.in + src/smpi/smpif2c.in + src/smpi/smpiff.in src/smpi/smpirun.in src/simix/smx_context_sysv_private.h src/simgrid_units_main.c diff --git a/buildtools/Cmake/Distrib.cmake b/buildtools/Cmake/Distrib.cmake index 6f61255f1e..753115d38b 100644 --- a/buildtools/Cmake/Distrib.cmake +++ b/buildtools/Cmake/Distrib.cmake @@ -20,6 +20,8 @@ endif(enable_doc) # binaries install(PROGRAMS ${CMAKE_BINARY_DIR}/bin/smpicc + ${CMAKE_BINARY_DIR}/bin/smpif2c + ${CMAKE_BINARY_DIR}/bin/smpiff ${CMAKE_BINARY_DIR}/bin/smpirun DESTINATION $ENV{DESTDIR}${prefix}/bin/) if(WIN32) @@ -120,6 +122,8 @@ COMMAND ${CMAKE_COMMAND} -E remove -f ${prefix}/lib/libsimgrid* COMMAND ${CMAKE_COMMAND} -E remove -f ${prefix}/lib/libsmpi* COMMAND ${CMAKE_COMMAND} -E echo "uninstall lib ok" COMMAND ${CMAKE_COMMAND} -E remove -f ${prefix}/bin/smpicc +COMMAND ${CMAKE_COMMAND} -E remove -f ${prefix}/bin/smpif2c +COMMAND ${CMAKE_COMMAND} -E remove -f ${prefix}/bin/smpiff COMMAND ${CMAKE_COMMAND} -E remove -f ${prefix}/bin/smpirun COMMAND ${CMAKE_COMMAND} -E remove -f ${prefix}/bin/tesh COMMAND ${CMAKE_COMMAND} -E remove -f ${prefix}/bin/simgrid-colorizer diff --git a/include/smpi/mpif.h b/include/smpi/mpif.h new file mode 100644 index 0000000000..b1d7d9d756 --- /dev/null +++ b/include/smpi/mpif.h @@ -0,0 +1,74 @@ +! -*- fortran -*- +! Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team. +! All rights reserved. + +! This program is free software; you can redistribute it and/or modify it +! under the terms of the license (GNU LGPL) which comes with this package. + +! SMPI's Fortran 77 include file + + integer MPI_THREAD_SINGLE, MPI_THREAD_FUNNELED, MPI_THREAD_SERIALIZED, MPI_THREAD_MULTIPLE + parameter(MPI_THREAD_SINGLE=0) + parameter(MPI_THREAD_FUNNELED=1) + parameter(MPI_THREAD_SERIALIZED=2) + parameter(MPI_THREAD_MULTIPLE=3) + + integer MPI_MAX_PROCESSOR_NAME, MPI_MAX_ERROR_STRING, + > MPI_MAX_DATAREP_STRIN, MPI_MAX_INFO_KEY, + > MPI_MAX_INFO_VAL, MPI_MAX_OBJECT_NAME, MPI_MAX_PORT_NAME, + > MPI_ANY_SOURCE, MPI_PROC_NULL, MPI_ANY_TAG, MPI_UNDEFINED + parameter(MPI_MAX_PROCESSOR_NAME=100) + parameter(MPI_MAX_ERROR_STRING=100) + parameter(MPI_MAX_DATAREP_STRIN =100) + parameter(MPI_MAX_INFO_KEY=100) + parameter(MPI_MAX_INFO_VAL=100) + parameter(MPI_MAX_OBJECT_NAME=100) + parameter(MPI_MAX_PORT_NAME=100) + parameter(MPI_ANY_SOURCE=-1) + parameter(MPI_PROC_NULL=-2) + parameter(MPI_ANY_TAG=-1) + parameter(MPI_UNDEFINED=-1) + + integer MPI_SUCCESS, MPI_ERR_COMM, MPI_ERR_ARG, MPI_ERR_TYPE, + > MPI_ERR_REQUEST, MPI_ERR_INTERN, MPI_ERR_COUNT, MPI_ERR_RANK, + > MPI_ERR_TAG, MPI_ERR_TRUNCATE, MPI_ERR_GROUP, MPI_ERR_OP, + > MPI_IDENT, MPI_SIMILAR, MPI_UNEQUAL, MPI_CONGRUENT, + > MPI_WTIME_IS_GLOBAL + parameter(MPI_SUCCESS=0) + parameter(MPI_ERR_COMM=1) + parameter(MPI_ERR_ARG=2) + parameter(MPI_ERR_TYPE=3) + parameter(MPI_ERR_REQUEST=4) + parameter(MPI_ERR_INTERN=5) + parameter(MPI_ERR_COUNT=6) + parameter(MPI_ERR_RANK=7) + parameter(MPI_ERR_TAG=8) + parameter(MPI_ERR_TRUNCATE=9) + parameter(MPI_ERR_GROUP=10) + parameter(MPI_ERR_OP=11) + parameter(MPI_IDENT=0) + parameter(MPI_SIMILAR=1) + parameter(MPI_UNEQUAL=2) + parameter(MPI_CONGRUENT=3) + parameter(MPI_WTIME_IS_GLOBAL=1) + +! This should be equal to the number of int fields in MPI_Status + integer MPI_STATUS_SIZE + parameter(MPI_STATUS_SIZE=4) + + integer MPI_STATUS_IGNORE(MPI_STATUS_SIZE) + common/smpi/ MPI_STATUS_IGNORE + + parameter(MPI_DATATYPE_NULL=0) + external MPI_BYTE, MPI_CHARACTER, MPI_LOGICAL, MPI_INTEGER, MPI_INTEGER1, + > MPI_INTEGER2, MPI_INTEGER4, MPI_INTEGER8, MPI_REAL, MPI_REAL4, + > MPI_REAL8, MPI_DOUBLE_PRECISION, MPI_COMPLEX, + > MPI_DOUBLE_COMPLEX, MPI_2INTEGER, MPI_LOGICAL1, MPI_LOGICAL2, + > MPI_LOGICAL4, MPI_LOGICAL8 + + external MPI_COMM_WORLD, MPI_COMM_SELF + + external MPI_INIT, MPI_FINALIZE, MPI_COMM_RANK, MPI_COMM_SIZE + + external MPI_WTIME + double precision MPI_WTIME diff --git a/include/smpi/smpi.h b/include/smpi/smpi.h index 32843b7520..d72ceeabe5 100644 --- a/include/smpi/smpi.h +++ b/include/smpi/smpi.h @@ -332,5 +332,8 @@ XBT_PUBLIC(void *) smpi_shared_malloc(size_t size, const char *file, XBT_PUBLIC(void) smpi_shared_free(void *data); #define SMPI_SHARED_FREE(data) smpi_shared_free(data) +/* Fortran specific stuff */ +XBT_PUBLIC(int) MAIN__(void); + SG_END_DECL() #endif diff --git a/include/smpi/smpif.h b/include/smpi/smpif.h new file mode 100644 index 0000000000..c0eca8ba33 --- /dev/null +++ b/include/smpi/smpif.h @@ -0,0 +1,18 @@ +/* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#ifndef SMPIF_H +#define SMPIF_H + +#include +#include + +XBT_PUBLIC(int) smpi_process_argc(void); +XBT_PUBLIC(int) smpi_process_getarg(integer* index, char* dst, ftnlen len); +XBT_PUBLIC(int) smpi_global_rank(void); +XBT_PUBLIC(int) smpi_global_size(void); + +#endif diff --git a/src/smpi/private.h b/src/smpi/private.h index cdbf7a9be4..66f9c3561d 100644 --- a/src/smpi/private.h +++ b/src/smpi/private.h @@ -11,6 +11,7 @@ #include "xbt/xbt_os_time.h" #include "simix/simix.h" #include "smpi/smpi.h" +#include "smpi/smpif.h" #include "instr/private.h" struct s_smpi_process_data; @@ -49,6 +50,7 @@ int smpi_process_index(void); xbt_os_timer_t smpi_process_timer(void); void smpi_process_simulated_start(void); double smpi_process_simulated_elapsed(void); + void print_request(const char *message, MPI_Request request); void smpi_process_post_send(MPI_Comm comm, MPI_Request request); void smpi_process_post_recv(MPI_Request request); @@ -180,4 +182,16 @@ void smpi_bench_destroy(void); void smpi_bench_begin(int rank, const char *mpi_call); void smpi_bench_end(int rank, const char *mpi_call); +// f77 wrappers +void mpi_init__(int*); +void mpi_finalize__(int*); +void mpi_comm_rank__(MPI_Comm** comm, int* rank, int* ierr); +void mpi_comm_size__(MPI_Comm** comm, int* size, int* ierr); +double mpi_wtime__(void); + +void mpi_send__(void* buf, int* count, MPI_Datatype** datatype, int* dst, + int* tag, MPI_Comm** comm, int* ierr); +void mpi_recv__(void* buf, int* count, MPI_Datatype** datatype, int* src, + int* tag, MPI_Comm** comm, MPI_Status* status, int* ierr); + #endif diff --git a/src/smpi/smpi_base.c b/src/smpi/smpi_base.c index acf0aac0df..688a805edf 100644 --- a/src/smpi/smpi_base.c +++ b/src/smpi/smpi_base.c @@ -19,32 +19,6 @@ XBT_LOG_EXTERNAL_CATEGORY(smpi_receiver); XBT_LOG_EXTERNAL_CATEGORY(smpi_sender); XBT_LOG_EXTERNAL_CATEGORY(smpi_util); -void smpi_process_init(int *argc, char ***argv) -{ - int index; - smpi_process_data_t data; - smx_process_t proc; - - proc = SIMIX_process_self(); - index = atoi((*argv)[1]); - data = smpi_process_remote_data(index); - SIMIX_process_set_data(proc, data); - if (*argc > 2) { - free((*argv)[1]); - memmove(&(*argv)[1], &(*argv)[2], sizeof(char *) * (*argc - 2)); - (*argv)[(*argc) - 1] = NULL; - } - (*argc)--; - DEBUG2("<%d> New process in the game: %p", index, proc); -} - -void smpi_process_destroy(void) -{ - int index = smpi_process_index(); - - DEBUG1("<%d> Process left the game", index); -} - static MPI_Request build_request(void *buf, int count, MPI_Datatype datatype, int src, int dst, int tag, MPI_Comm comm, unsigned flags) diff --git a/src/smpi/smpi_f77.c b/src/smpi/smpi_f77.c new file mode 100644 index 0000000000..5fe4c81dc0 --- /dev/null +++ b/src/smpi/smpi_f77.c @@ -0,0 +1,65 @@ +/* Copyright (c) 2007, 2008, 2009, 2010. The SimGrid Team. + * All rights reserved. */ + +/* This program is free software; you can redistribute it and/or modify it + * under the terms of the license (GNU LGPL) which comes with this package. */ + +#include "private.h" + +extern int xargc; +extern char** xargv; + +void* mpi_byte__ = &MPI_BYTE; +void* mpi_character__ = &MPI_CHAR; +void* mpi_logical__ = &MPI_INT; +void* mpi_integer__ = &MPI_INT; +void* mpi_integer1__ = &MPI_INT8_T; +void* mpi_integer2__ = &MPI_INT16_T; +void* mpi_integer4__ = &MPI_INT32_T; +void* mpi_integer8__ = &MPI_INT64_T; +void* mpi_real__ = &MPI_FLOAT; +void* mpi_real4__ = &MPI_FLOAT; +void* mpi_real8__ = &MPI_DOUBLE; +void* mpi_double_precision__ = &MPI_DOUBLE; +void* mpi_complex__ = &MPI_C_FLOAT_COMPLEX; +void* mpi_double_complex__ = &MPI_C_DOUBLE_COMPLEX; +void* mpi_2integer__ = &MPI_2INT; +void* mpi_logical1__ = &MPI_UINT8_T; +void* mpi_logical2__ = &MPI_UINT16_T; +void* mpi_logical4__ = &MPI_UINT32_T; +void* mpi_logical8__ = &MPI_UINT64_T; + +void* mpi_comm_world__ = &MPI_COMM_WORLD; + +void mpi_init__(int* ierr) { + /* smpif2c is responsible for generating a call with the final arguments */ + *ierr = MPI_Init(NULL, NULL); +} + +void mpi_finalize__(int* ierr) { + *ierr = MPI_Finalize(); +} + +void mpi_comm_rank__(MPI_Comm** comm, int* rank, int* ierr) { + /* Yes, you really get a MPI_Comm** here */ + *ierr = MPI_Comm_rank(**comm, rank); +} + +void mpi_comm_size__(MPI_Comm** comm, int* size, int* ierr) { + /* Yes, you really get a MPI_Comm** here */ + *ierr = MPI_Comm_size(**comm, size); +} + +double mpi_wtime__(void) { + return MPI_Wtime(); +} + +void mpi_send__(void* buf, int* count, MPI_Datatype** datatype, int* dst, + int* tag, MPI_Comm** comm, int* ierr) { + *ierr = MPI_Send(buf, *count, **datatype, *dst, *tag, **comm); +} + +void mpi_recv__(void* buf, int* count, MPI_Datatype** datatype, int* src, + int* tag, MPI_Comm** comm, MPI_Status* status, int* ierr) { + *ierr = MPI_Recv(buf, *count, **datatype, *src, *tag, **comm, status); +} diff --git a/src/smpi/smpi_global.c b/src/smpi/smpi_global.c index 3e45341be1..6e9e496296 100644 --- a/src/smpi/smpi_global.c +++ b/src/smpi/smpi_global.c @@ -5,6 +5,7 @@ * under the terms of the license (GNU LGPL) which comes with this package. */ #include +#include #include "private.h" #include "smpi_mpi_dt_private.h" @@ -17,6 +18,8 @@ XBT_LOG_NEW_DEFAULT_SUBCATEGORY(smpi_kernel, smpi, typedef struct s_smpi_process_data { int index; + int* argc; + char*** argv; xbt_fifo_t pending_sent; xbt_fifo_t pending_recv; xbt_os_timer_t timer; @@ -29,6 +32,74 @@ static int process_count = 0; MPI_Comm MPI_COMM_WORLD = MPI_COMM_NULL; +void smpi_process_init(int *argc, char ***argv) +{ + int index; + smpi_process_data_t data; + smx_process_t proc; + + if(argc && argv) { + proc = SIMIX_process_self(); + index = atoi((*argv)[1]); + data = smpi_process_remote_data(index); + SIMIX_process_set_data(proc, data); + if (*argc > 2) { + free((*argv)[1]); + memmove(&(*argv)[1], &(*argv)[2], sizeof(char *) * (*argc - 2)); + (*argv)[(*argc) - 1] = NULL; + } + (*argc)--; + data->argc = argc; + data->argv = argv; + DEBUG2("<%d> New process in the game: %p", index, proc); + } +} + +void smpi_process_destroy(void) +{ + int index = smpi_process_index(); + + DEBUG1("<%d> Process left the game", index); +} + +int smpi_process_argc(void) { + smpi_process_data_t data = smpi_process_data(); + + return data->argc ? *(data->argc) - 1 : 0; +} + +int smpi_process_getarg(integer* index, char* dst, ftnlen len) { + smpi_process_data_t data = smpi_process_data(); + char* arg; + size_t i; + + if(!data->argc || !data->argv + || *index < 1 || *index >= *(data->argc)) { + return -1; + } + arg = (*data->argv)[*index]; + for(i = 0; i < len && arg[i] != '\0'; i++) { + dst[i] = arg[i]; + } + for(; i < len; i++) { + dst[i] = ' '; + } + return 0; +} + +int smpi_global_rank(void) { + return smpi_process_index(); +} + +int smpi_global_size(void) { + char* value = getenv("SMPI_GLOBAL_SIZE"); + + if(!value) { + abort(); + } + return atoi(value); +} + smpi_process_data_t smpi_process_data(void) { return SIMIX_process_get_data(SIMIX_process_self()); @@ -157,6 +228,8 @@ void smpi_global_init(void) for (i = 0; i < process_count; i++) { process_data[i] = xbt_new(s_smpi_process_data_t, 1); process_data[i]->index = i; + process_data[i]->argc = NULL; + process_data[i]->argv = NULL; process_data[i]->pending_sent = xbt_fifo_new(); process_data[i]->pending_recv = xbt_fifo_new(); process_data[i]->timer = xbt_os_timer_new(); @@ -190,7 +263,19 @@ void smpi_global_destroy(void) process_data = NULL; } -int main(int argc, char **argv) +/* Fortran specific stuff */ +/* With smpicc, the following weak symbols are used */ +/* With smpiff, the following weak symbols are replaced by those in libf2c */ +int __attribute__((weak)) xargc; +char** __attribute__((weak)) xargv; + +int __attribute__((weak)) main(int argc, char** argv) { + xargc = argc; + xargv = argv; + return MAIN__(); +} + +int MAIN__(void) { srand(SMPI_RAND_SEED); @@ -219,20 +304,20 @@ int main(int argc, char **argv) NULL); #ifdef HAVE_TRACING - TRACE_global_init(&argc, argv); + TRACE_global_init(&xargc, xargv); #endif - SIMIX_global_init(&argc, argv); + SIMIX_global_init(&xargc, xargv); #ifdef HAVE_TRACING TRACE_smpi_start(); #endif // parse the platform file: get the host list - SIMIX_create_environment(argv[1]); + SIMIX_create_environment(xargv[1]); SIMIX_function_register("smpi_simulated_main", smpi_simulated_main); - SIMIX_launch_application(argv[2]); + SIMIX_launch_application(xargv[2]); smpi_global_init(); diff --git a/src/smpi/smpicc.in b/src/smpi/smpicc.in index c7786bf5ec..edbae0f9b0 100755 --- a/src/smpi/smpicc.in +++ b/src/smpi/smpicc.in @@ -15,18 +15,22 @@ CMDLINE="" while [ -n "$1" ]; do ARG="$1" shift - if [ "${ARG}" = "-c" ]; then + case "${ARG}" in + -c) LINKARGS="" CMDLINE="${CMDLINE} -c " - elif [ "${ARG%.c}" != "${ARG}" ]; then - SRCFILE="$(readlink -f ${ARG} 2>/dev/null)" - if [ -z $SRCFILE ] ; then - SRCFILE="$ARG" - fi - CMDLINE="${CMDLINE} ${SRCFILE} " - else - CMDLINE="${CMDLINE} ${ARG} " - fi + ;; + *.c) + SRCFILE="$(readlink -f ${ARG} 2>/dev/null)" + if [ -z $SRCFILE ] ; then + SRCFILE="$ARG" + fi + CMDLINE="${CMDLINE} ${SRCFILE} " + ;; + *) + CMDLINE="${CMDLINE} ${ARG} " + ;; + esac done CMDLINE="${CC} ${INCLUDEARGS} ${CFLAGS} ${CMDLINE} ${CMAKE_LINKARGS} ${LINKARGS}" diff --git a/src/smpi/smpif2c.in b/src/smpi/smpif2c.in new file mode 100755 index 0000000000..02330f352c --- /dev/null +++ b/src/smpi/smpif2c.in @@ -0,0 +1,49 @@ +#! /usr/bin/env perl + +use warnings; +use strict; +use File::Temp; +use File::Copy; + +my $include="-I@top_srcdir@/include -I@top_srcdir@/include/smpi -I@includedir@ -I@includedir@/smpi"; + +foreach my $fortran (@ARGV) { + my $output = $fortran; + $output =~ s/.f$/.c/; + my $tmp = new File::Temp; + $tmp->autoflush(1); + `f2c $include -w -a $fortran`; + die "F2C failed\n" if $?; + open F2C,"<$output"; + my $started = 0; + print $tmp "#include \n"; + print $tmp "#include \n"; + while() { + chomp; + if(/\/\* Common Block Declarations \*\//) { + $started = 1; + } + if($started) { + if(/^} (.*?);/) { + $_ = "}* $1 = NULL;\n"; + } elsif(/^#define\s*(\S*)\s*\(?([^.]*)(\..*?)?\)?$/) { + $_ = "#define $1 $2\[smpi_global_rank()\]"; + if(defined $3) { + $_ .= $3; + } + $_ .= "\n"; + $_ .= "\nvoid __attribute__((constructor)) __preinit_$1(void) {\n if(!$2) $2 = malloc(smpi_global_size() * sizeof(*$2));\n}\n"; + $_ .= "\nvoid __attribute__((destructor)) __postfini_$1(void) {\n free($2);\n $2 = NULL;\n}\n"; + } + } + if(/\/\* Table of constant values \*\// || /MAIN__/) { + $started = 0; + } + if(/\/* Main program alias \*\/\s*int\s+.*\s*\(\s*\)\s*{(.*)}/) { + $_ = "int smpi_simulated_main(int argc, char** argv) { smpi_process_init(&argc, &argv); $1 }\n"; + } + print $tmp "$_\n"; + } + close F2C; + copy($tmp->filename,$output) or die "Copy failed: $!\n"; +} diff --git a/src/smpi/smpiff.in b/src/smpi/smpiff.in new file mode 100644 index 0000000000..3d9000327a --- /dev/null +++ b/src/smpi/smpiff.in @@ -0,0 +1,28 @@ +#! /bin/bash +prefix="@prefix@" + +ARGS="-DMAIN__=user_main -Diargc_=smpi_process_argc -Dgetarg_=smpi_process_getarg -lf2c" +SRCFILES="" + +while [ -n "$1" ]; do + ARG="$1" + shift + case "${ARG}" in + *.f) + SRCFILE="$(readlink -f ${ARG} 2>/dev/null)" + if [ -z $SRCFILE ] ; then + SRCFILE="$ARG" + fi + SRCFILES="${SRCFILES} ${SRCFILE}" + ;; + *) + ARGS="${ARGS} ${ARG}" + ;; + esac +done + +for SRCFILE in "${SRCFILES}" +do + CFILE="${SRCFILE%.f}.c" + $prefix/bin/smpif2c ${SRCFILE} && $prefix/bin/smpicc ${ARGS} ${CFILE} +done diff --git a/src/smpi/smpirun.in b/src/smpi/smpirun.in index a5645738d2..6e5f71befa 100755 --- a/src/smpi/smpirun.in +++ b/src/smpi/smpirun.in @@ -205,6 +205,7 @@ APPLICATIONFOOT fi ##---------------------- end SMPI TRACING OPTIONS --------------------------------- +export SMPI_GLOBAL_SIZE=${NUMPROCS} if [ -n "${KEEP}" ] ; then echo ${EXEC} ${SIMOPTS} ${TRACEOPTIONS} ${PLATFORMTMP} ${APPLICATIONTMP} fi -- 2.20.1