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)
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)
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
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
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
# 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)
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
--- /dev/null
+! -*- 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
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
--- /dev/null
+/* 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
#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;
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 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
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)
--- /dev/null
+/* 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);
+}
* 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"
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;
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());
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 = 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);
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();
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}"
--- /dev/null
+#! /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";
+}
--- /dev/null
+#! /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
fi
##---------------------- end SMPI TRACING OPTIONS ---------------------------------
+export SMPI_GLOBAL_SIZE=${NUMPROCS}
if [ -n "${KEEP}" ] ; then
echo ${EXEC} ${SIMOPTS} ${TRACEOPTIONS} ${PLATFORMTMP} ${APPLICATIONTMP}
fi