Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Support for Fortran code in SMPI based on f2c, some perl and some dirty hacks.
authorpini <pini@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Mon, 22 Nov 2010 17:21:01 +0000 (17:21 +0000)
committerpini <pini@48e7efb5-ca39-0410-a469-dd3cf9ba447f>
Mon, 22 Nov 2010 17:21:01 +0000 (17:21 +0000)
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

15 files changed:
buildtools/Cmake/AddTests.cmake
buildtools/Cmake/CompleteInFiles.cmake
buildtools/Cmake/DefinePackages.cmake
buildtools/Cmake/Distrib.cmake
include/smpi/mpif.h [new file with mode: 0644]
include/smpi/smpi.h
include/smpi/smpif.h [new file with mode: 0644]
src/smpi/private.h
src/smpi/smpi_base.c
src/smpi/smpi_f77.c [new file with mode: 0644]
src/smpi/smpi_global.c
src/smpi/smpicc.in
src/smpi/smpif2c.in [new file with mode: 0755]
src/smpi/smpiff.in [new file with mode: 0644]
src/smpi/smpirun.in

index 18d2fca..58c1248 100644 (file)
@@ -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 ${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)
 
        exec_program("chmod a=rwx ${CMAKE_BINARY_DIR}/bin/smpirun" OUTPUT_VARIABLE "OKITOKI")
 endif(enable_smpi)
 
index c6cc60e..ba54971 100644 (file)
@@ -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)
 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)
 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)
 exec_program("chmod a=rwx ${CMAKE_CURRENT_BINARY_DIR}/bin/smpirun" OUTPUT_VARIABLE OKITOKI)
index cfe55c7..b4c2639 100644 (file)
@@ -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_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
        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/simdag/simdag.h
 include/simdag/datatypes.h
 include/smpi/smpi.h
+include/smpi/smpif.h
 include/smpi/mpi.h
 include/smpi/mpi.h
+include/smpi/mpif.h
 include/surf/surfxml_parse.h
 include/surf/simgrid_dtd.h
 include/gras/datadesc.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
 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
        src/smpi/smpirun.in
        src/simix/smx_context_sysv_private.h
        src/simgrid_units_main.c
index 6f61255..753115d 100644 (file)
@@ -20,6 +20,8 @@ endif(enable_doc)
 
 # binaries
 install(PROGRAMS ${CMAKE_BINARY_DIR}/bin/smpicc
 
 # 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)
                  ${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}/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
 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 (file)
index 0000000..b1d7d9d
--- /dev/null
@@ -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
index 32843b7..d72ceea 100644 (file)
@@ -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)
 
 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
 SG_END_DECL()
 #endif
diff --git a/include/smpi/smpif.h b/include/smpi/smpif.h
new file mode 100644 (file)
index 0000000..c0eca8b
--- /dev/null
@@ -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 <f2c.h>
+#include <xbt/misc.h>
+
+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
index cdbf7a9..66f9c35 100644 (file)
@@ -11,6 +11,7 @@
 #include "xbt/xbt_os_time.h"
 #include "simix/simix.h"
 #include "smpi/smpi.h"
 #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;
 #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);
 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);
 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);
 
 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
 #endif
index acf0aac..688a805 100644 (file)
@@ -19,32 +19,6 @@ XBT_LOG_EXTERNAL_CATEGORY(smpi_receiver);
 XBT_LOG_EXTERNAL_CATEGORY(smpi_sender);
 XBT_LOG_EXTERNAL_CATEGORY(smpi_util);
 
 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)
 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 (file)
index 0000000..5fe4c81
--- /dev/null
@@ -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);
+}
index 3e45341..6e9e496 100644 (file)
@@ -5,6 +5,7 @@
   * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include <stdint.h>
   * under the terms of the license (GNU LGPL) which comes with this package. */
 
 #include <stdint.h>
+#include <stdlib.h>
 
 #include "private.h"
 #include "smpi_mpi_dt_private.h"
 
 #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;
 
 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;
   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;
 
 
 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());
 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;
   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();
     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;
 }
 
   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);
 
 {
   srand(SMPI_RAND_SEED);
 
@@ -219,20 +304,20 @@ int main(int argc, char **argv)
                    NULL);
 
 #ifdef HAVE_TRACING
                    NULL);
 
 #ifdef HAVE_TRACING
-  TRACE_global_init(&argc, argv);
+  TRACE_global_init(&xargc, xargv);
 #endif
 
 #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
 
 #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_function_register("smpi_simulated_main", smpi_simulated_main);
-  SIMIX_launch_application(argv[2]);
+  SIMIX_launch_application(xargv[2]);
 
   smpi_global_init();
 
 
   smpi_global_init();
 
index c7786bf..edbae0f 100755 (executable)
@@ -15,18 +15,22 @@ CMDLINE=""
 while [ -n "$1" ]; do
   ARG="$1"
   shift
 while [ -n "$1" ]; do
   ARG="$1"
   shift
-  if [ "${ARG}" = "-c" ]; then
+  case "${ARG}" in
+   -c)
       LINKARGS=""
       CMDLINE="${CMDLINE} -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}"
 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 (executable)
index 0000000..02330f3
--- /dev/null
@@ -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 <stdlib.h>\n";
+   print $tmp "#include <smpif.h>\n";
+   while(<F2C>) {
+      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 (file)
index 0000000..3d90003
--- /dev/null
@@ -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
index a564573..6e5f71b 100755 (executable)
@@ -205,6 +205,7 @@ APPLICATIONFOOT
   fi
 ##---------------------- end SMPI TRACING OPTIONS ---------------------------------
 
   fi
 ##---------------------- end SMPI TRACING OPTIONS ---------------------------------
 
+export SMPI_GLOBAL_SIZE=${NUMPROCS}
 if [ -n "${KEEP}" ] ; then
   echo ${EXEC} ${SIMOPTS} ${TRACEOPTIONS} ${PLATFORMTMP} ${APPLICATIONTMP}
 fi
 if [ -n "${KEEP}" ] ; then
   echo ${EXEC} ${SIMOPTS} ${TRACEOPTIONS} ${PLATFORMTMP} ${APPLICATIONTMP}
 fi