AMPI #943: Rename AMPI extensions (breaking API change) 93/1093/17
authorSam White <white67@illinois.edu>
Thu, 25 Feb 2016 19:32:49 +0000 (13:32 -0600)
committerSam White <samt.white@gmail.com>
Fri, 15 Apr 2016 02:17:42 +0000 (21:17 -0500)
This change breaks existing AMPI codes that use its extensions.

AMPI_Migrate subsumes the functionality of MPI_Migrate, MPI_Checkpoint,
and MPI_MemCheckpoint.

AMPI extension names are now all prefixed by AMPI_ and follow MPI's
naming conventions for C and Fortran.

Examples, tests, and documentation have been updated as well.

Change-Id: I87883b3c7f288e2ced1e7b63bb17206cd8ed448e

25 files changed:
README.ampi
doc/ampi/manual.tex
doc/charm++/checkpoint.tex
doc/projections/manual.tex
examples/ampi/Cjacobi3D/jacobi-cpp.C
examples/ampi/Cjacobi3D/jacobi-get.C
examples/ampi/Cjacobi3D/jacobi.C
examples/ampi/alltoall/alltoall_VPtest.c
examples/ampi/creduce/test.C
examples/ampi/onesided/IgetTest.C [moved from examples/ampi/onesided/IGetTest.C with 65% similarity]
examples/ampi/onesided/Makefile
examples/ampi/pingpong/pingpong-2way.c
src/libs/ck-libs/ampi/ampi.C
src/libs/ck-libs/ampi/ampi.ci
src/libs/ck-libs/ampi/ampi.h
src/libs/ck-libs/ampi/ampiOneSided.C
src/libs/ck-libs/ampi/ampif.C
src/libs/ck-libs/ampi/ampiimpl.h
tests/ampi/chkpt/hello.c
tests/ampi/fallreduce/Makefile
tests/ampi/fallreduce/pgm.f90 [new file with mode: 0644]
tests/ampi/fallreduce/test.f90 [deleted file]
tests/ampi/jacobi3d/jacobi.C
tests/ampi/megampi/test.C
tests/ampi/migration/test.C

index 204571f41f11d1d634b46675e28d23a42b82e19f..57f45dc2bb131c68d2ae891c925d040792b1cb27 100644 (file)
@@ -85,26 +85,23 @@ AMPI has some known flaws and incompatibilities with other MPI implementations:
     * The PMPI profiling interface is not implemented in AMPI.
 
 AMPI also has extensions to the MPI standard to enable use of the high-level
-features provided by the Charm++ adaptive runtime system:
-    * MPI_Migrate checks for load imbalance and rebalances the load using
-      the strategy linked in and specified at job launch.
-    * MPI_Checkpoint performs a checkpoint to disk.
-    * MPI_MemCheckpoint performs a double in-memory checkpoint.
-    * MPI_Register is used to register PUP routines and user data.
-    * MPI_Get_userdata returns a pointer to user data managed by the runtime.
-    * MPI_Register_main is used to register multiple AMPI modules.
-    * MPI_Set_load sets the calling rank's load to the given user value.
-    * MPI_Start_measure starts load balance information collection.
-    * MPI_Stop_measure stops load balance information collection.
-    * MPI_MigrateTo migrates the calling rank to the given PE.
-    * MPI_Setmigratable sets the migratability of the given communicator.
-    * MPI_Num_nodes returns the total number of nodes.
-    * MPI_Num_pes returns the total number of PEs.
-    * MPI_My_node returns the local node number.
-    * MPI_My_pe returns the local node number.
-    * MPI_Command_argument_count returns the number of command line arguments
+features provided by the Charm++ adaptive runtime system. All extensions are
+prefixed with AMPI_:
+    * AMPI_Migrate tells the runtime system that the application has reached a
+      point at which the runtime system may serialize and migrate ranks.
+      It is used for dynamic load balancing and fault tolerance. See the AMPI
+      manual for more information on how to use it.
+    * AMPI_Register_pup is used to register PUP routines and user data.
+    * AMPI_Get_pup_data returns a pointer to user data managed by the runtime.
+    * AMPI_Register_main is used to register multiple AMPI modules.
+    * AMPI_Load_set_value sets the calling rank's load to the given user value.
+    * AMPI_Load_start_measure starts load balance information collection.
+    * AMPI_Load_stop_measure stops load balance information collection.
+    * AMPI_Migrate_to_pe migrates the calling rank to the given PE.
+    * AMPI_Comm_set_migratable sets the migratability of the given communicator.
+    * AMPI_Command_argument_count returns the number of command line arguments
       given to a Fortran AMPI program excluding charmrun and AMPI parameters.
-    * MPI_Get_command_argument returns an argument from the command line
+    * AMPI_Get_command_argument returns an argument from the command line
       to a Fortran AMPI program.
 
 Note that AMPI defines a preprocessor symbol "AMPI" so that user codes can
index 723cb7061a3e53828369de20e696f73d4e4928ae..dca4f15208f3dd9b27d290fe8ff7901319cc2399 100644 (file)
@@ -16,12 +16,13 @@ derived data types support, has been developed by Neelam Saboo.
 
 \section{Introduction}
 
-This manual describes Adaptive MPI~(\ampi{}), which is an implementation of a
-significant subset\footnote{Currently, the PMPI profiling interface is missing
-from \ampi{} and the MPI-3.0 standard is under development.} of the MPI-2.0
-Standard over \charmpp{}. \charmpp{} is a \CC{}-based parallel programming
-library being developed by Prof. Laxmikant (Sanjay) Kal\'{e} and his students
-since 1992 at the University of Illinois at Urbana-Champaign.
+This manual describes Adaptive MPI~(\ampi{}), which is an implementation of the
+MPI-2.2 standard\footnote{Currently, MPI-2.2's PMPI profiling interface is missing
+from \ampi{} and the MPI-3.1 standard is under active development, though we already
+support non-blocking and neighborhood collectives.} on top of \charmpp{}. \charmpp{} is a
+\CC{}-based parallel programming library being developed by Prof.
+Laxmikant (Sanjay) Kale and his students since 1992 at the University of
+Illinois at Urbana-Champaign.
 
 We first describe the philosophy behind Adaptive MPI. Then we give a brief
 introduction to \charmpp{} and rationale for \ampi{}. We then describe
@@ -222,8 +223,7 @@ advantage of dynamic load balancing and other \charmpp{} features. This is
 indeed impractical. However, \converse{} -- the runtime system of \charmpp{} --
 supports interoperability between different parallel programming paradigms
 such as parallel objects and threads. Using this feature, we developed
-\ampi{}, an implementation of a significant subset of the MPI-2.0
-standard over \charmpp{}.  \ampi{} is described in the next section.
+\ampi{}, which is described in more detail in the next section.
 
 \section{AMPI}
 
@@ -236,19 +236,19 @@ track of the computational loads of each thread as well as the communication gra
 between \ampi{} threads, and can migrate these threads in order to balance the
 overall load while simultaneously minimizing communication overhead.
 
-\subsection{AMPI Status}
+\subsection{AMPI Compliance to MPI Standards}
 
-Currently all the MPI-1.1 Standard functions are supported in \ampi{}, with a
-collection of our extentions explained in detail in this manual. One-sided
+Currently \ampi{} supports the MPI-2.2 standard, with preliminary support for some MPI-3.1
+features and a collection of extensions explained in detail in this manual. One-sided
 communication calls in MPI-2 and MPI-3 are implemented, but they do not yet
 take advantage of RMA features. Non-blocking collectives have been defined in
 \ampi{} since before MPI-3.0's adoption of them. Also
 ROMIO\footnote{http://www-unix.mcs.anl.gov/romio/} has been integrated into
-\ampi{}to support parallel I/O features. Link with {\tt -lampiromio}
-to take advantage of this library.
+\ampi{} to support parallel I/O features. Build \ampi{} with {\tt --with-romio}
+and link your application with {\tt -lampiromio} to take advantage of this library.
 
-The following MPI-1.1 basic datatypes are supported in \ampi{}. (Some are not
-available in Fortran binding. Refer to the MPI-1.1 Standard for details.)
+The following MPI basic datatypes are supported in \ampi{}. (Some are not
+available in the Fortran binding. Refer to the MPI Standard for details.)
 \begin{alltt}
 MPI_DATATYPE_NULL  MPI_BYTE            MPI_UNSIGNED_LONG MPI_LONG_DOUBLE_INT
 MPI_DOUBLE         MPI_PACKED          MPI_LONG_DOUBLE   MPI_2FLOAT
@@ -259,23 +259,37 @@ MPI_LOGICAL        MPI_UNSIGNED_SHORT  MPI_2INT
 MPI_CHAR           MPI_UNSIGNED        MPI_SHORT_INT
 \end{alltt}
 
-The following MPI-1.1 reduction operations are supported in \ampi{}.
+The following MPI reduction operations are supported in \ampi{}.
 
 \begin{alltt}
-MPI_MAX   MPI_MIN   MPI_SUM   MPI_PROD  MPI_MAXLOC  MPI_MINLOC
-MPI_LAND  MPI_LOR   MPI_LXOR  MPI_BAND  MPI_BOR     MPI_BXOR
+MPI_MAX   MPI_MIN   MPI_SUM   MPI_PROD  MPI_MAXLOC  MPI_MINLOC  MPI_REPLACE
+MPI_LAND  MPI_LOR   MPI_LXOR  MPI_BAND  MPI_BOR     MPI_BXOR    MPI_NO_OP
 \end{alltt}
 
-The following are AMPI extension calls, which will be explained in detail in this
-manual.
+The following are AMPI extensions to the MPI standard, which will be explained in
+detail in this manual. All AMPI extensions to the MPI standard are prefixed with
+\texttt{AMPI\_} rather than \texttt{MPI\_}. All extensions are available in C, C++, and Fortran,
+with the exception of \texttt{AMPI\_Command\_argument\_count} and
+\texttt{AMPI\_Get\_command\_argument} which are only available in Fortran.
+
 \begin{alltt}
-MPI_Migrate        MPI_Checkpoint     MPI_MemCheckpoint  MPI_Register
-MPI_MigrateTo      MPI_Register_main  MPI_Setmigratable  MPI_Get_userdata
-MPI_Start_measure  MPI_Stop_measure   MPI_Just_migrated  MPI_About_to_migrate
-MPI_My_pe          MPI_My_node        MPI_Num_pes        MPI_Num_nodes
-MPI_Set_load       MPI_Command_argument_count            MPI_Get_command_argument
+AMPI_Migrate          AMPI_Register_pup            AMPI_Get_pup_data
+AMPI_Migrate_to_pe    AMPI_Comm_set_migratable     AMPI_Evacuate
+AMPI_Load_set_value   AMPI_Load_start_measure      AMPI_Load_stop_measure
+AMPI_Iget             AMPI_Iget_wait               AMPI_Iget_data
+AMPI_Iget_free        AMPI_Type_is_contiguous      AMPI_Register_main
+AMPI_Alltoall_iget    AMPI_Alltoall_medium         AMPI_Alltoall_long
+AMPI_Yield            AMPI_Suspend                 AMPI_Resume
+AMPI_Register_just_migrated         AMPI_Register_about_to_migrate
+AMPI_Command_argument_count         AMPI_Get_command_argument
 \end{alltt}
 
+AMPI also provides a set of built-in attributes on all communicators and windows
+to find the PE or Node number that a virtual processor is currently running on,
+as well as the total number of PEs and Nodes in the job. The built-in attributes
+are \texttt{AMPI\_MY\_PE}, \texttt{AMPI\_MY\_NODE}, \texttt{AMPI\_NUM\_PES}, and
+\texttt{AMPI\_NUM\_NODES}. These attributes are accessible from any rank by
+calling \texttt{MPI\_Comm\_get\_attr}.
 
 \subsection{Name for Main Program}
 
@@ -597,7 +611,7 @@ Scheme     & X86 & IA64 & Opteron & Mac OS X & IBM SP & SUN & BG/P & Cray/XT & W
                                                           \end{table*}
 \subsection{Extensions for Migrations}
 
-AMPI provides fully automated support for migrating MPI ranks between nodes of a
+\ampi{} provides fully automated support for migrating MPI ranks between nodes of a
 system without any application-specific code at all. We do so using a memory
 allocator, Isomalloc, that allocates memory per user-level thread to globally
 unique virtual memory addresses. This means that every PE in the system reserves
@@ -630,13 +644,12 @@ cannot determine what size the data is, or whether the registered data contains
 pointers to other places in memory. For this purpose, a packing subroutine also
 needs to be provided to the \ampi{} runtime system along with registered data.
 (See next section for writing packing subroutines.) The call provided by
-\ampi{} for doing this is \texttt{MPI\_Register}. This function takes two
-arguments: A data item to be transported along with the rank, and the pack
-subroutine, and returns an integer denoting the registration identifier. In
-C/\CC{} programs, it may be necessary to use this return value after migration
-completes and control returns to the rank, using function
-\texttt{MPI\_Get\_userdata}. Therefore, the return value should be stored in a
-local variable.
+\ampi{} for doing this is \texttt{AMPI\_Register\_pup}. This function takes three
+arguments: a data item to be transported along with the rank, the pack
+subroutine, and a pointer to an integer which denotes the registration identifier.
+In C/\CC{} programs, it may be necessary to use this integer value after migration
+completes and control returns to the rank with the function
+\texttt{AMPI\_Get\_pup\_data}.
 
 \subsubsection{Migration}
 
@@ -651,11 +664,11 @@ only once in the beginning, load imbalance at that stage would not matter much.
 Therefore, we want the demand to perform load balance check to be initiated by
 the application.
 
-\ampi{} provides a subroutine \texttt{MPI\_Migrate} for this purpose. Each
-rank periodically calls \texttt{MPI\_Migrate}. Typical CSE applications are
-iterative and perform multiple time-steps. One should call
-\texttt{MPI\_Migrate} in each rank at the end of some fixed number of
-timesteps. The frequency of \texttt{MPI\_Migrate} should be determined by a
+\ampi{} provides a subroutine \texttt{AMPI\_Migrate(MPI\_Info hints);} for
+this purpose. Each rank periodically calls \texttt{AMPI\_Migrate}. Typical
+CSE applications are iterative and perform multiple time-steps. One should call
+\texttt{AMPI\_Migrate} in each rank at the end of some fixed number of
+timesteps. The frequency of \texttt{AMPI\_Migrate} should be determined by a
 tradeoff between conflicting factors such as the load balancing overhead, and
 performance degradation caused by load imbalance. In some other applications,
 where application suspects that load imbalance may have occurred, as in the
@@ -663,21 +676,60 @@ case of adaptive mesh refinement; it would be more effective if it performs a
 couple of timesteps before telling the system to re-map ranks. This will give
 the \ampi{} runtime system some time to collect the new load and communication
 statistics upon which it bases its migration decisions. Note that
-\texttt{MPI\_Migrate} does NOT tell the system to migrate the rank, but
+\texttt{AMPI\_Migrate} does NOT tell the system to migrate the rank, but
 merely tells the system to check the load balance after all the ranks call
-\texttt{MPI\_Migrate}. To migrate the rank or not is decided only by the
-system's load balancing strategy. We also provide callbacks that user code
-can register with the runtime system to be invoked just before and right after
-migration: \texttt{MPI\_About\_to\_migrate} and \texttt{MPI\_Just\_migrated}
-respectively.
+\texttt{AMPI\_Migrate}. To migrate the rank or not is decided only by the
+system's load balancing strategy.
+
+Essentially, a call to \texttt{AMPI\_Migrate} signifies to the runtime system
+that the application has reached a point at which it is safe to serialize
+the local state. Knowing this, the runtime system can act in several ways.
+
+The MPI\_Info object taken as a parameter by \texttt{AMPI\_Migrate} gives
+users a way to influence the runtime system's decision-making and behavior.
+Users should set the \texttt{MPI\_Info} key \texttt{"ampi\_load\_balance"} to one
+of the following values: \texttt{"sync"}, \texttt{"async"}, or \texttt{"false"}.
+Synchronous load balancing assumes that the application is already at a
+synchronization point. Asynchronous load balancing does not assume this, and a
+value of \texttt{"false"} is the same as not requesting load balancing at all.
+
+\begin{alltt}
+// Setup
+MPI_Info hints;
+MPI_Info_create(&hints);
+MPI_Info_set(hints, "ampi_load_balance", "sync");
+
+...
+
+// Main time-stepping loop
+for (int iter=0; iter < max_iters; iter++) \{
+
+  // Time step work ...
+
+  if (iter \% lb_freq == 0)
+    AMPI_Migrate(hints);
+\}
+\end{alltt}
+
+We also provide callbacks that user code can register with the runtime system
+to be invoked just before and right after migration:
+\texttt{AMPI\_Register\_about\_to\_migrate} and
+\texttt{AMPI\_Register\_just\_migrated} respectively. We also provide routines
+for starting and stopping load measurements, and for users to explicitly set the
+load value of a rank using the following: \texttt{AMPI\_Load\_start\_measure},
+\texttt{AMPI\_Load\_stop\_measure}, and \texttt{AMPI\_Load\_set\_value}.
+And since \ampi{} builds on top of \charmpp{}, users can experiment with the
+suite of load balancing strategies included with \charmpp{}, as well as write
+their own strategies based on user-level information and heuristics.
 
 \subsubsection{Packing/Unpacking Thread Data}
 
 Once the \ampi{} runtime system decides which ranks to send to which
 processors, it calls the specified pack subroutine for that rank, with the
 rank-specific data that was registered with the system using
-\texttt{MPI\_Register}. This section explains how a subroutine should be
-written for performing pack/unpack.
+\texttt{AMPI\_Register\_pup}. If an \ampi{} application uses Isomalloc, then
+the system will define the Pack/Unpack routines for the user. This section
+explains how a subroutine should be written for performing explicit pack/unpack.
 
 There are three steps for transporting the rank's data to another processor.
 First, the system calls a subroutine to get the size of the buffer required to
@@ -889,18 +941,56 @@ Just as in load balancing, no application specific code is required when using
 Isomalloc: the \ampi{} runtime takes care of all the details involved in
 migrating data.
 
-A subroutine for checkpoint purpose has been added to AMPI:
-\texttt{void MPI\_Checkpoint(char *dirname);}
-This subroutine takes a directory name as its argument. It is a collective
-function, meaning every virtual processor in the program needs to call this
-subroutine and specify the same directory name. (Typically, in an
-iterative AMPI program, the iteration number, converted to a character string,
-can serve as a checkpoint directory name.) This directory is created, and the
-entire state of the program is checkpointed to this directory.  One can restart
-the program from the checkpointed state by specifying \texttt{"+restart
-dirname"} on the command-line. This capability is powered by the \charmpp{}
-runtime system. For more information about checkpoint/restart
-mechanisms in \charmpp{} please refer to \charmpp{} manual.
+To perform a checkpoint in an \ampi{} program, all you have to do is make a call
+to \texttt{int AMPI\_Migrate(MPI\_Info hints)} with an \texttt{MPI\_Info} object that
+specifies how you would like to checkpoint. Checkpointing can be thought of as
+migrating \ampi{} ranks to storage. Users set the checkpointing policy
+on an \texttt{MPI\_Info} object's \texttt{"ampi\_checkpoint"} key to one of the
+following values: \texttt{"to\_file=directory\_name"}, \texttt{"in\_memory"},
+or \texttt{"false"}.
+
+Checkpointing to file tells the runtime system to save checkpoints in a given
+directory. (Typically, in an iterative program, the iteration number, converted to a
+character string, can serve as a checkpoint directory name.) This directory
+is created, and the entire state of the program is checkpointed to this directory.
+One can restart the program from the checkpointed state (using the same, more, or
+fewer physical processors than were checkpointed with) by specifying \texttt{"+restart
+directory\_name"} on the command-line.
+
+Checkpointing in memory allows applications to transparently tolerate failures online.
+The checkpointing scheme used here is a double in-memory checkpoint, in which
+virtual processors exchange checkpoints pairwise across nodes in each other's memory
+such that if one node fails, that failed node's \ampi{} ranks can be restarted by its
+buddy once the failure is detected by the runtime system. As long as no two buddy
+nodes fail in the same checkpointing interval, the system can restart online without
+intervention from the user (provided the job scheduler does not revoke its allocation).
+Any load imbalance resulting from the restart can then be managed by the runtime system.
+Use of this scheme is illustrated in the code snippet below.
+
+\begin{alltt}
+// Setup
+MPI_Info hints;
+MPI_Info_create(&hints);
+MPI_Info_set(hints, "ampi_checkpoint", "in_memory");
+
+...
+
+// Main time-stepping loop
+for (int iter=0; iter < max_iters; iter++) \{
+
+  // Time step work ...
+
+  if (iter \% chkpt_freq == 0)
+    AMPI_Migrate(hints);
+\}
+\end{alltt}
+
+A value of \texttt{"false"} results in no checkpoint being done that step.
+Note that \texttt{AMPI\_Migrate} is a collective function, meaning every
+virtual processor in the program needs to call this subroutine with the
+same MPI\_Info object. The checkpointing capabilities of \ampi{} are powered by
+the \charmpp{} runtime system. For more information about checkpoint/restart
+mechanisms please refer to the \charmpp{} manual~\ref{sec:checkpoint}.
 
 \subsection{Extensions for Memory Efficiency}
 
@@ -909,26 +999,25 @@ functions being called. For unblocking communication primitives, sometimes the u
 like to do lazy memory allocation until the data actually arrives, which gives the
 oppotunities to write more memory efficient programs.
 We provide a set of \ampi{} functions as an extension to the standard MPI-2 one-sided calls,
-where we provide a split phase MPI\_Get called MPI\_IGet. MPI\_IGet preserves the similar
-semantics as MPI\_Get except that no user buffer is provided to hold incoming data.
-MPI\_IGet\_Wait will block until the requested data arrives and runtime system takes
+where we provide a split phase \texttt{MPI\_Get} called \texttt{AMPI\_Iget}. \texttt{AMPI\_Iget} preserves the similar
+semantics as \texttt{MPI\_Get} except that no user buffer is provided to hold incoming data.
+\texttt{AMPI\_Iget\_wait} will block until the requested data arrives and runtime system takes
 care to allocate space, do appropriate unpacking based on data type, and return.
-MPI\_IGet\_Free lets the runtime system free the resources being used for this get request
-including the data buffer. And MPI\_IGet\_Data is the utility program that returns the
-actual data.
+\texttt{AMPI\_Iget\_free} lets the runtime system free the resources being used for this get request
+including the data buffer. Finally, \texttt{AMPI\_Iget\_data} is the routine used to access the data.
  
 
 \begin{alltt}
 
-int MPI_IGet(MPI_Aint orgdisp, int orgcnt, MPI_Datatype orgtype, int rank,
-             MPI_Aint targdisp, int targcnt, MPI_Datatype targtype, MPI_Win win,
-             MPI_Request *request);
+int AMPI_Iget(MPI_Aint orgdisp, int orgcnt, MPI_Datatype orgtype, int rank,
+              MPI_Aint targdisp, int targcnt, MPI_Datatype targtype, MPI_Win win,
+              MPI_Request *request);
 
-int MPI_IGet_Wait(MPI_Request *request, MPI_Status *status, MPI_Win win);
+int AMPI_Iget_wait(MPI_Request *request, MPI_Status *status, MPI_Win win);
 
-int MPI_IGet_Free(MPI_Request *request, MPI_Status *status, MPI_Win win);
+int AMPI_Iget_free(MPI_Request *request, MPI_Status *status, MPI_Win win);
 
-char* MPI_IGet_Data(MPI_Status status);
+int AMPI_Iget_data(void *data, MPI_Status status);
 
 \end{alltt}
 
@@ -960,14 +1049,14 @@ subroutine called \texttt{MPI\_Setup}.
 !FORTRAN EXAMPLE
 SUBROUTINE MPI_Setup
   USE ampi
-  CALL MPI_Register_main(Solids_Main)
-  CALL MPI_Register_main(Fluids_Main)
+  CALL AMPI_Register_main(Solids_Main)
+  CALL AMPI_Register_main(Fluids_Main)
 END SUBROUTINE
 
 //C Example
 void MPI_Setup()\{
-  MPI_Register_main(Solids_Main);
-  MPI_Register_main(Fluids_Main);
+  AMPI_Register_main(Solids_Main);
+  AMPI_Register_main(Fluids_Main);
 \}
 \end{alltt}
 
@@ -1075,34 +1164,6 @@ command line options are required as well.
 > ./pgm +msgLogRead +msgLogRank 2 +msgLogFilename "msg2.log"
 \end{alltt}
 
-\subsection{Communication Optimizations for AMPI}
-AMPI is powered by the \charmpp{} communication optimization support now!
-Currently the user needs to specify the communication pattern by command
-line option. In the future this can be done automatically by the system.
-
-Currently there are four strategies available: USE\_DIRECT, USE\_MESH,
-USE\_HYPERCUBE and USE\_GRID. USE\_DIRECT sends the message directly. 
-USE\_MESH imposes a 2d Mesh virtual topology on the processors so each 
-processor sends messages to its neighbors in its row and column of the 
-mesh which forward the messages to their correct destinations. USE\_HYPERCUBE 
-and USE\_GRID impose a hypercube and a 3d Grid topologies on the processors. 
-USE\_HYPERCUBE will do best for very small messages and small number of 
-processors, 3d has better performance for slightly higher message sizes 
-and then Mesh starts performing best. The programmer is encouraged to try 
-out all the strategies. (Stolen from the CommLib manual by Sameer :)
-
-For more details please refer to the CommLib paper \footnote{L. V. Kale and 
-Sameer Kumar and Krishnan Vardarajan, 2002. 
-http://finesse.cs.uiuc.edu/papers/CommLib.pdf}. 
-
-Specifying the strategy is as simple as a command line option +strategy. For
-example:
-\begin{alltt}
-> ./charmrun +p64 alltoall +vp64 1000 100 +strategy USE\_MESH
-\end{alltt}
-tells the system to use MESH strategy for CommLib. By default USE\_DIRECT is
-used.
-
 \subsection{User Defined Initial Mapping}
                                                                                 
 You can define the initial mapping of virtual processors (vp) to physical
@@ -1152,6 +1213,23 @@ the load balancing framework aware of the heterogeneity of the system, the flag
 
 If you want to define your own mapping scheme, please contact us for assistance.
 
+\subsection{Performance Visualization}
+\ampi{} users can take advantage of \charmpp{}'s tracing framework and
+associated performance visualization tool, Projections. Projections
+provides a number of different views of performance data that help
+users diagnose performance issues.
+
+\ampi{} defines the following extensions for tracing support:
+
+\begin{alltt}
+AMPI_Trace_begin                      AMPI_Trace_end
+AMPI_Trace_register_function_name     AMPI_Trace_register_function_id
+AMPI_Trace_start_function_name        AMPI_Trace_start_function_id
+AMPI_Trace_end_function_name          AMPI_Trace_end_function_id
+\end{alltt}
+
+See the Projections manual for information on how to visualize traces.
+
 \subsection{Compiling AMPI Programs}
 
 \charmpp{} provides a cross-platform compile-and-link script called \charmc{}
@@ -1170,7 +1248,8 @@ In spite of the platform-neutral syntax of \charmc{}, one may have to specify
 some platform-specific options for compiling and building \ampi{} codes.
 Fortunately, if \charmc{} does not recognize any particular options on its
 command line, it promptly passes it to all the individual compilers and linkers
-it invokes to compile the program.
+it invokes to compile the program. See the appendix for more details on
+building and running AMPI programs.
 
 \appendix
 
@@ -1196,15 +1275,15 @@ libraries needed by \ampi{}), specify \verb+<target>+ to be \verb+AMPI+. And
 script.  Common compile time options such as \texttt{-g, -O, -Ipath, -Lpath,
 -llib} are accepted.
 
-To build a debugging version of \ampi{}, use the option: ``\texttt{-g}''. 
-To build a production version of \ampi{}, use the options: ``\texttt{
---with-production}''.
+To build a debugging version of \ampi{}, use the option: \texttt{-g}.
+To build a production version of \ampi{}, use the option\texttt{
+--with-production}.
 
 \verb+<version>+ depends on the machine, operating system, and the underlying
 communication library one wants to use for running \ampi{} programs.
 See the charm/README file for details on picking the proper version.
 Following is an example of how to build a production version of AMPI under
-linux and ethernet environment, with debugging info produced:
+linux and ethernet environment, with debugging symbols produced:
 
 \begin{alltt}
 > build AMPI netlrts-linux-x86_64 --with-production -g
index 5dbd9f1c001cd3ae6d423c2f7876f55b44014cff..3bb046db04421933ee3634bd77373cd28d42687f 100644 (file)
@@ -208,12 +208,34 @@ programmer is responsible for choosing when to activate checkpointing
 so that the size of a global checkpoint state, and consequently the
 time to record it, is minimized.
 
-In AMPI applications, the user just needs to call the following
-function to record a checkpoint:
+In AMPI applications, the user just needs to create an MPI\_Info object with
+the key ``ampi\_checkpoint'' and a value of either ``in\_memory'' (for a double
+in-memory checkpoint) or ``to\_file=file\_name'' (to checkpoint to disk), and
+pass that object to the function AMPI\_Migrate() as in the following:
+
 \begin{alltt}
-      void AMPI_MemCheckpoint()
+// Setup
+MPI_Info in_memory, to_file;
+
+MPI_Info_create(&in_memory);
+MPI_Info_set(in_memory, "ampi_checkpoint", "in_memory");
+
+MPI_Info_create(&to_file);
+MPI_Info_set(to_file, "ampi_checkpoint", "to_file=chkpt_dir");
+
+...
+
+// Main time-stepping loop
+for (int iter=0; iter < max_iters; iter++) \{
+
+  // Time step work ...
+
+  if (iter \% chkpt_freq == 0)
+    AMPI_Migrate(in_memory);
+\}
 \end{alltt}
 
+
 \subsection{Restarting}
 
 When a processor crashes, the restart protocol will be automatically
index 342ebc9beb4ce025be1c73c1ef631a0aba719daf..895d2f694737866a53796e00b4ca0e79c4582653 100644 (file)
@@ -36,7 +36,9 @@ Chee Wai Lee, Isaac Dooley, and Sindhura Bandhakavi
 Adaptive MPI (AMPI) is an implementation of the MPI interface on top
 of \charmpp{}. As with standard MPI programs, the appropriate semantic
 context for performance analysis is captured through the observation
-of MPI calls within C/C++/Fortran functions. Unfortunately, AMPI's
+of MPI calls within C/C++/Fortran functions. Users can selectively begin
+and end tracing in AMPI programs using the routines \texttt{AMPI\_Trace\_begin}
+and \texttt{AMPI\_Trace\_end}. Unfortunately, AMPI's
 implementation does not grant the runtime access to information about
 user function calls. As a result, the tracing framework must provide
 an explicit API for capturing this piece of performance information in
@@ -48,7 +50,7 @@ follows:
 \begin{itemize}
 \item 
 \begin{verbatim}
-int _TRACE_REGISTER_FUNCTION_NAME(const char *name);
+int AMPI_Trace_register_function_name(const char *name);
 \end{verbatim}
 This function registers an AMPI function {\tt name}. The tracing
 framework assigns to function {\tt name} a unique id and returns
@@ -60,7 +62,7 @@ application, just after {\tt MPI\_Init}.
 
 \item
 \begin{verbatim}
-int _TRACE_REGISTER_FUNCTION_ID(const char *name, int idx);
+int AMPI_Trace_register_function_id(const char *name, int idx);
 \end{verbatim}
 This function registers an AMPI function {\tt name} to be associated
 explicitly to the id {\tt idx}. It is the user's responsibility to 
@@ -72,7 +74,7 @@ the start of the application just after {\tt MPI\_Init}.
 
 \item
 \begin{verbatim}
-void _TRACE_BEGIN_FUNCTION_NAME(const char *name);
+void AMPI_Trace_begin_function_name(const char *name);
 \end{verbatim}
 This function tells the tracing framework to record a begin event
 associated with the registered function {\tt name}. If this were called
@@ -81,7 +83,7 @@ the function call will also be recorded.
 
 \item
 \begin{verbatim}
-void _TRACE_BEGIN_FUNCTION_ID(int idx);
+void AMPI_Trace_begin_function_id(int idx);
 \end{verbatim}
 This function tells the tracing framework to record a begin event
 associated with the registered function indexed by {\tt idx}. If this were
@@ -90,14 +92,14 @@ of the function call will also be recorded.
 
 \item
 \begin{verbatim}
-void _TRACE_END_FUNCTION_NAME(const char *name);
+void AMPI_Trace_end_function_name(const char *name);
 \end{verbatim}
 This function tells the tracing framework to record a end event
 associated with the registered function {\tt name}.
 
 \item
 \begin{verbatim}
-void _TRACE_END_FUNCTION_ID(int idx);
+void AMPI_Trace_end_function_id(int idx);
 \end{verbatim}
 This function tells the tracing framework to record a end event
 associated with the registered function indexed by {\tt idx}.
index e57414b853a611d28ded6e00e27c5af09c74c744..c9dd0200726257b9746ba640bb47fd18b83957b3 100644 (file)
@@ -205,6 +205,7 @@ int main(int ac, char** av)
   int i,j,k,m,cidx;
   int iter, niter;
   MPI_Status status;
+  MPI_Info hints;
   double error, tval, maxerr, tmpmaxerr, starttime, endtime, itertime;
   chunk *cp;
   int thisIndex, ierr, nblocks;
@@ -232,6 +233,10 @@ int main(int ac, char** av)
   else
     niter = 10;
 
+  /* Set up MPI_Info hints for AMPI_Migrate() */
+  MPI_Info_create(&hints);
+  MPI_Info_set(hints, "ampi_load_balance", "true");
+
   DIMX = DIM/NX;
   DIMY = DIM/NY;
   DIMZ = DIM/NZ;
@@ -276,7 +281,7 @@ int main(int ac, char** av)
 
 #ifdef AMPI
     if(iter%20 == 10) {
-      MPI_Migrate();
+      AMPI_Migrate(hints);
     }
 #endif
   }
index 75797a1bd171ba5323f8c035921f4d03a0e17e34..4b2bbacb704dedb30bc46cc5898cbd88960f3eeb 100644 (file)
@@ -79,8 +79,9 @@ static void copyin(double *d, double t[DIMX][DIMY][DIMZ],
 int main(int ac, char** av)
 {
   int i,j,k,m,cidx;
-  int iter, niter;
+  int iter, niter, cp_idx;
   MPI_Status status;
+  MPI_Info hints;
   double error, tval, maxerr, tmpmaxerr, starttime, endtime, itertime;
   chunk *cp;
   int thisIndex, ierr, nblocks;
@@ -110,11 +111,15 @@ int main(int ac, char** av)
   else
     niter = 20;
 
+  /* Set up MPI_Info hints for AMPI_Migrate() */
+  MPI_Info_create(&hints);
+  MPI_Info_set(hints, "ampi_load_balance", "true");
+
   MPI_Bcast(&niter, 1, MPI_INT, 0, MPI_COMM_WORLD);
 
   cp = new chunk;
 #if defined(AMPI) && ! defined(NO_PUP)
-  MPI_Register((void*)&cp, (MPI_PupFn) chunk_pup);
+  AMPI_Register_pup((MPI_PupFn)chunk_pup, (void*)&cp, &cp_idx);
 #endif
 
   index3d(thisIndex, cp->xidx, cp->yidx, cp->zidx);
@@ -161,26 +166,26 @@ int main(int ac, char** av)
     copyout(cp->sbzm, cp->t, 1, DIMX, 1, DIMY, 1, 1);
     copyout(cp->sbzp, cp->t, 1, DIMX, 1, DIMY, DIMZ, DIMZ);
 */
-    MPI_IGet(0, DIMY*DIMZ, MPI_DOUBLE, cp->xp, 0, DIMY*DIMZ, MPI_DOUBLE, win, &reqxp);
-    MPI_IGet(0, DIMY*DIMZ, MPI_DOUBLE, cp->xm, (DIMX-1)*DIMY*DIMZ, DIMY*DIMZ, MPI_DOUBLE, win, &reqxm);
-    MPI_IGet(0, DIMX*DIMZ, MPI_DOUBLE, cp->yp, 0, DIMZ, linevec, win, &reqyp);
-    MPI_IGet(0, DIMX*DIMZ, MPI_DOUBLE, cp->yp, (DIMY-1), DIMZ, linevec, win, &reqym);
-    MPI_IGet(0, DIMX*DIMY, MPI_DOUBLE, cp->zp, 0, DIMX*DIMY, planevec, win, &reqzp);
-    MPI_IGet(0, DIMX*DIMY, MPI_DOUBLE, cp->zp, 0, DIMX*DIMY, planevec, win, &reqzm);
-
-    MPI_IGet_Wait(&reqxp, &stsxp, win);
-    MPI_IGet_Wait(&reqxm, &stsxm, win);
-    MPI_IGet_Wait(&reqyp, &stsyp, win);
-    MPI_IGet_Wait(&reqym, &stsym, win);
-    MPI_IGet_Wait(&reqzp, &stszp, win);
-    MPI_IGet_Wait(&reqzm, &stszm, win);
-
-    cp->sbxp = (double*)MPI_IGet_Data(stsxp);
-    cp->sbxm = (double*)MPI_IGet_Data(stsxm);
-    cp->sbyp = (double*)MPI_IGet_Data(stsyp);
-    cp->sbym = (double*)MPI_IGet_Data(stsym);
-    cp->sbzp = (double*)MPI_IGet_Data(stszp);
-    cp->sbzm = (double*)MPI_IGet_Data(stszm);
+    AMPI_Iget(0, DIMY*DIMZ, MPI_DOUBLE, cp->xp, 0, DIMY*DIMZ, MPI_DOUBLE, win, &reqxp);
+    AMPI_Iget(0, DIMY*DIMZ, MPI_DOUBLE, cp->xm, (DIMX-1)*DIMY*DIMZ, DIMY*DIMZ, MPI_DOUBLE, win, &reqxm);
+    AMPI_Iget(0, DIMX*DIMZ, MPI_DOUBLE, cp->yp, 0, DIMZ, linevec, win, &reqyp);
+    AMPI_Iget(0, DIMX*DIMZ, MPI_DOUBLE, cp->yp, (DIMY-1), DIMZ, linevec, win, &reqym);
+    AMPI_Iget(0, DIMX*DIMY, MPI_DOUBLE, cp->zp, 0, DIMX*DIMY, planevec, win, &reqzp);
+    AMPI_Iget(0, DIMX*DIMY, MPI_DOUBLE, cp->zp, 0, DIMX*DIMY, planevec, win, &reqzm);
+
+    AMPI_Iget_wait(&reqxp, &stsxp, win);
+    AMPI_Iget_wait(&reqxm, &stsxm, win);
+    AMPI_Iget_wait(&reqyp, &stsyp, win);
+    AMPI_Iget_wait(&reqym, &stsym, win);
+    AMPI_Iget_wait(&reqzp, &stszp, win);
+    AMPI_Iget_wait(&reqzm, &stszm, win);
+
+    AMPI_Iget_data((double*)cp->sbxp, stsxp);
+    AMPI_Iget_data((double*)cp->sbxm, stsxm);
+    AMPI_Iget_data((double*)cp->sbyp, stsyp);
+    AMPI_Iget_data((double*)cp->sbym, stsym);
+    AMPI_Iget_data((double*)cp->sbzp, stszp);
+    AMPI_Iget_data((double*)cp->sbzm, stszm);
 
 
     if(iter > 25 &&  iter < 85 && thisIndex == 35)
@@ -395,12 +400,12 @@ cp->sbxm[j*DIMZ+i])/7.0;
 
     }
 
-    MPI_IGet_Free(&reqxp, &stsxp, win);
-    MPI_IGet_Free(&reqxm, &stsxm, win);
-    MPI_IGet_Free(&reqyp, &stsyp, win);
-    MPI_IGet_Free(&reqym, &stsym, win);
-    MPI_IGet_Free(&reqzp, &stszp, win);
-    MPI_IGet_Free(&reqzm, &stszm, win);
+    AMPI_Iget_free(&reqxp, &stsxp, win);
+    AMPI_Iget_free(&reqxm, &stsxm, win);
+    AMPI_Iget_free(&reqyp, &stsyp, win);
+    AMPI_Iget_free(&reqym, &stsym, win);
+    AMPI_Iget_free(&reqzp, &stszp, win);
+    AMPI_Iget_free(&reqzm, &stszm, win);
 
     MPI_Allreduce(&maxerr, &tmpmaxerr, 1, MPI_DOUBLE, MPI_MAX, 
                    MPI_COMM_WORLD);
@@ -416,7 +421,7 @@ cp->sbxm[j*DIMZ+i])/7.0;
     starttime = MPI_Wtime();
 #ifdef AMPI
     if(iter%20 == 10) {
-      MPI_Migrate();
+      AMPI_Migrate(hints);
     }
 #endif
   }
index 9239738b5dc33c093cb51f2e4acd895bc5d58a23..adb069a831e420c0fafb99f47affe9da885ee84c 100644 (file)
@@ -107,8 +107,9 @@ static void copyin(double *d, double t[DIMX+2][DIMY+2][DIMZ+2],
 int main(int ac, char** av)
 {
   int i,j,k,m,cidx;
-  int iter, niter;
+  int iter, niter, cp_idx;
   MPI_Status status;
+  MPI_Info hints;
   double error, tval, maxerr, tmpmaxerr, starttime, endtime, itertime;
   chunk *cp;
   int thisIndex, ierr, nblocks;
@@ -135,10 +136,9 @@ int main(int ac, char** av)
   else
     niter = 20;
 
-/*
-  if(thisIndex == 0)
-    niter = 20;
-*/
+  /* Set up MPI_Info hints for AMPI_Migrate() */
+  MPI_Info_create(&hints);
+  MPI_Info_set(hints, "ampi_load_balance", "true");
 
   MPI_Bcast(&niter, 1, MPI_INT, 0, MPI_COMM_WORLD);
 
@@ -148,7 +148,7 @@ int main(int ac, char** av)
   cp = new chunk;
 #endif
 #if defined(AMPI) && ! defined(NO_PUP)
-  MPI_Register((void*)&cp, (MPI_PupFn) chunk_pup);
+  AMPI_Register_pup((MPI_PupFn)chunk_pup, (void*)&cp, &cp_idx);
 #endif
 
   index3d(thisIndex, cp->xidx, cp->yidx, cp->zidx);
@@ -231,7 +231,7 @@ int main(int ac, char** av)
     starttime = MPI_Wtime();
 #ifdef AMPI
     if(iter%20 == 10) {
-      MPI_Migrate();
+      AMPI_Migrate(hints);
     }
 #endif
   }
index 07c267f3d15a97f9f0ccf03d15e9ef4d723b39e1..8e616683d6639ca6ff46d21e3fe4634a6475394f 100644 (file)
@@ -116,7 +116,7 @@ main(int argc, char **argv){
   if(1){
        // warm up, not instrumented
        for(i=0; i<max_msgs; i++) {
-         MPI_Alltoall_long(sndbuf, msg_size, MPI_CHAR, recvbuf, msg_size, MPI_CHAR, MPI_COMM_WORLD);
+         AMPI_Alltoall_long(sndbuf, msg_size, MPI_CHAR, recvbuf, msg_size, MPI_CHAR, MPI_COMM_WORLD);
        }
 
        memset(recvbuf,0,msg_size*p);
@@ -129,7 +129,7 @@ main(int argc, char **argv){
          Start_Timer (0, ITIMER_REAL); 
        }
        for(i=0; i<max_msgs; i++) {
-         MPI_Alltoall_long(sndbuf, msg_size, MPI_CHAR, recvbuf, msg_size, MPI_CHAR, MPI_COMM_WORLD);
+         AMPI_Alltoall_long(sndbuf, msg_size, MPI_CHAR, recvbuf, msg_size, MPI_CHAR, MPI_COMM_WORLD);
        }
        MPI_Barrier(MPI_COMM_WORLD);
        memory_after = CmiMemoryUsage();
@@ -157,7 +157,7 @@ main(int argc, char **argv){
   {
        // warm up, not instrumented
        for(i=0; i<max_msgs; i++) {
-         MPI_Alltoall_short(sndbuf, msg_size, MPI_CHAR, recvbuf, msg_size, MPI_CHAR, MPI_COMM_WORLD);
+         AMPI_Alltoall_short(sndbuf, msg_size, MPI_CHAR, recvbuf, msg_size, MPI_CHAR, MPI_COMM_WORLD);
        }
 
        memset(recvbuf,0,msg_size*p);
@@ -170,7 +170,7 @@ main(int argc, char **argv){
          Start_Timer (0, ITIMER_REAL); 
        }
        for(i=0; i<max_msgs; i++) {
-         MPI_Alltoall_short(sndbuf, msg_size, MPI_CHAR, recvbuf, msg_size, MPI_CHAR, MPI_COMM_WORLD);
+         AMPI_Alltoall_short(sndbuf, msg_size, MPI_CHAR, recvbuf, msg_size, MPI_CHAR, MPI_COMM_WORLD);
        }
        MPI_Barrier(MPI_COMM_WORLD);
        memory_after = CmiMemoryUsage();
@@ -196,7 +196,7 @@ main(int argc, char **argv){
   if(1){
        // warm up, not instrumented
        for(i=0; i<max_msgs; i++) {
-         MPI_Alltoall_medium(sndbuf, msg_size, MPI_CHAR, recvbuf, msg_size, MPI_CHAR, MPI_COMM_WORLD);
+         AMPI_Alltoall_medium(sndbuf, msg_size, MPI_CHAR, recvbuf, msg_size, MPI_CHAR, MPI_COMM_WORLD);
        }
 
        memset(recvbuf,0,msg_size*p);
@@ -209,7 +209,7 @@ main(int argc, char **argv){
          Start_Timer (0, ITIMER_REAL); 
        }
        for(i=0; i<max_msgs; i++) {
-         MPI_Alltoall_medium(sndbuf, msg_size, MPI_CHAR, recvbuf, msg_size, MPI_CHAR, MPI_COMM_WORLD);
+         AMPI_Alltoall_medium(sndbuf, msg_size, MPI_CHAR, recvbuf, msg_size, MPI_CHAR, MPI_COMM_WORLD);
        }
        MPI_Barrier(MPI_COMM_WORLD);
        memory_after = CmiMemoryUsage();
index e7dd7fab30899c64c8a3ed0f35952058c8d43f45..19dc7ef3b0720dcbfaf59ea07b196a9bbb1baf66 100644 (file)
@@ -1,25 +1,42 @@
 #include <stdio.h>
 #include "mpi.h"
 
-int main(int argc,char **argv)
+int main(int argc, char **argv)
 {
-       MPI_Init(&argc,&argv);
-       double inval,outval;
-       int rank,size;
-       MPI_Comm_rank(MPI_COMM_WORLD, &rank);
-       MPI_Comm_size(MPI_COMM_WORLD, &size);
-       inval = rank+1;
-       MPI_Reduce(&inval, &outval, 1, MPI_DOUBLE, MPI_SUM, 
-                     0, MPI_COMM_WORLD);
-       int expect = (size*(size+1))/2;
-       if(rank == 0) {
-         if (outval == expect) 
-           printf("reduce test passed\n");
-         else {
-           printf("reduce test failed!\n");
-           return 1;
-          }
-       }
-       MPI_Finalize();
-       return 0;
+  double inval, outval;
+  int rank, size, expect;
+  MPI_Request req;
+
+  MPI_Init(&argc,&argv);
+  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+  MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+  inval = rank+1;
+  expect = (size*(size+1))/2;
+
+  MPI_Reduce(&inval, &outval, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);
+  if (rank == 0) {
+    if (outval == expect)
+      printf("MPI_Reduce test passed\n");
+    else {
+      printf("MPI_Reduce test failed!\n");
+      MPI_Finalize();
+      return 1;
+    }
+  }
+
+  MPI_Ireduce(&inval, &outval, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &req);
+  if (rank == 0) {
+    MPI_Wait(&req, MPI_STATUS_IGNORE);
+    if (outval == expect)
+      printf("MPI_Ireduce test passed\n");
+    else {
+      printf("MPI_Ireduce test failed!\n");
+      MPI_Finalize();
+      return 1;
+    }
+  }
+
+  MPI_Finalize();
+  return 0;
 }
similarity index 65%
rename from examples/ampi/onesided/IGetTest.C
rename to examples/ampi/onesided/IgetTest.C
index 010f7d5d01ec359d7c13a1db2c021ab08f97c109..fb2c455b4456374c5b4ea542597b0024d4a22726 100644 (file)
 
 int main(int argc, char **argv)
 {
-  int my_id,next_id;            /* process id */
-  int p;                /* number of processes */
+  int my_id, next_id;           /* process id */
+  int p;                        /* number of processes */
   char* message_s, *message_r;  /* storage for the message */
   int i, j, max_msgs, msg_size;
-  MPI_Status status;    /* return status for receive */
+  MPI_Status status;            /* return status for receive */
   double elapsed_time_sec;
   double bandwidth;
   double startTime = 0;
@@ -35,7 +35,7 @@ int main(int argc, char **argv)
   //allocate data   
   message_s = (char*)malloc (msg_size);
 
-  //init data for verifying purpose
+  //init data for verification
   message_s[0] = 'a';
 
   //create window
@@ -46,26 +46,26 @@ int main(int argc, char **argv)
   startTime = MPI_Wtime();
 
   next_id = my_id+1>=p ? 0 : my_id+1;
-  // combined local transpose with global all-to-all
+  //combined local transpose with global all-to-all
   for(i=0; i<max_msgs; i++){
-      MPI_IGet(0, msg_size, MPI_CHAR, next_id, 0, msg_size, MPI_CHAR, win, &req);
-      MPI_IGet_Wait(&req, &status, win);       
-      message_r = (char*)MPI_IGet_Data(status); //MPI_IGet_Data(status);
-      fprintf(stdout, "[%d] get %c\n", my_id, message_r[0]);
-      MPI_IGet_Free(&req, &status, win);
+      AMPI_Iget(0, msg_size, MPI_CHAR, next_id, 0, msg_size, MPI_CHAR, win, &req);
+      AMPI_Iget_wait(&req, &status, win);
+      AMPI_Iget_data((char*)message_r, status);
+      //fprintf(stdout, "[%d] get %c\n", my_id, message_r[0]);
+      AMPI_Iget_free(&req, &status, win);
   }
   MPI_Win_fence(0, win);
 
   MPI_Barrier(MPI_COMM_WORLD);
   elapsed_time_sec = MPI_Wtime() - startTime;
-  fprintf(stdout, "Get Performance:\n");
-  fprintf(stdout, "Totaltime: %8.3f s\n",elapsed_time_sec);
+  fprintf(stdout, "Iget Performance:\n");
+  fprintf(stdout, "Totaltime: %8.3f s\n", elapsed_time_sec);
   elapsed_time_sec /= max_msgs; //time for each message
   bandwidth = msg_size / elapsed_time_sec; //bandwidth
 
-  fprintf (stdout, "%5d %7d\t ", max_msgs, msg_size);
-  fprintf (stdout,"%8.3f us,\t %8.3f MB/sec\n",
-           elapsed_time_sec * 1e6, bandwidth / 1e6);
+  fprintf(stdout, "%5d %7d\t ", max_msgs, msg_size);
+  fprintf(stdout, "%8.3f us,\t %8.3f MB/sec\n",
+          elapsed_time_sec * 1e6, bandwidth / 1e6);
 
   //deallocate data and stuff
   MPI_Win_free(&win);
index bc7f4e64a36e98c6fe71a1b8da4214de3abef332..2fd954a6f32ef050bd26b2f0be27fdaeeb9eacd0 100644 (file)
@@ -1,25 +1,25 @@
 -include ../../common.mk
-OPTS=-O3 
+OPTS=-O3
 CHARMBASE=../../../
 CHARMC=../../../bin/charmc -language ampi $(OPTS)
 MPICC=mpicc $(OPTS)
 TOKENS=6
 
-all: GetPutTest IGetTest
+all: GetPutTest IgetTest
 
 GetPutTest: GetPutTest.C
        $(CHARMC) GetPutTest.C -language ampi  -o GetPutTest
 #      $(MPICC) GetPutTest.C -o GetPutTest-mpi
-IGetTest: IGetTest.C
-       $(CHARMC) IGetTest.C -language ampi  -o IGetTest
+IgetTest: IgetTest.C
+       $(CHARMC) IgetTest.C -language ampi  -o IgetTest
 
-IGetTest-tokens:
+IgetTest-tokens:
        cd $(CHARMBASE)/tmp; touch machine.c; touch ckfutures.C; make AMPI OPTS="-DIGET_FLOWCONTROL=1 -DIGET_TOKENNUM=$(TOKENS) $(OPTS)"; cd -;
-       rm IGetTest; make IGetTest OPTS="$(OPTS)";
+       rm IgetTest; make IgetTest OPTS="$(OPTS)";
        
 test: all
-       $(call run, +p2 ./pgm 100000 16 +vp2)
+       $(call run, +p2 ./IgetTest 100000 16 +vp2)
 
 clean:
-       rm -rf charmrun conv-host moduleinit* *.o GetPutTest IGetTest GetPutTest-mpi *~ *.sts core
+       rm -rf charmrun conv-host moduleinit* *.o GetPutTest IgetTest GetPutTest-mpi *~ *.sts core
 
index 891dddb800aa9702ecab5080cc521057cfa03c0e..7d19d816cf65099ee7911ac17eeb92fb55e7b81d 100644 (file)
@@ -39,9 +39,6 @@ int main(int argc, char **argv)
   
   if( my_id < p/2 ) {
     startTime = MPI_Wtime();
-#ifdef AMPI
-    AMPI_Install_Idle_Timer();
-#endif
     
     MPI_Send(message_s, msg_size, MPI_CHAR, my_id+p/2, 0, MPI_COMM_WORLD);
     for(i=0; i<max_msgs; i++){
@@ -53,9 +50,6 @@ int main(int argc, char **argv)
     MPI_Barrier(MPI_COMM_WORLD); 
 
     elapsed_time_sec = MPI_Wtime() - startTime; 
-#ifdef AMPI
-    AMPI_Uninstall_Idle_Timer();
-#endif
     fprintf(stdout, "Totaltime: %8.6f s\n",elapsed_time_sec);
     elapsed_time_sec /= 2;  //We want the ping performance not round-trip.
     elapsed_time_sec /= max_msgs; //time for each message
@@ -67,9 +61,6 @@ int main(int argc, char **argv)
     
   }
   else {
-#ifdef AMPI
-    AMPI_Install_Idle_Timer();
-#endif
     MPI_Send(message_s, msg_size, MPI_CHAR, my_id-p/2, 0, MPI_COMM_WORLD);
     for(i=0; i<max_msgs; i++){
       MPI_Recv(message_r, msg_size, MPI_CHAR, my_id-p/2, 0, MPI_COMM_WORLD, 
@@ -78,9 +69,6 @@ int main(int argc, char **argv)
     }
     
     MPI_Barrier(MPI_COMM_WORLD); 
-#ifdef AMPI
-    AMPI_Uninstall_Idle_Timer();
-#endif
   }        
   
   free(message_s);
index 9f125f17f1c70c5bacbbed0e06859f1c1583bed9..b020cda3da5e69fb074e2baf8ed955fb091b0f3b 100644 (file)
@@ -655,20 +655,6 @@ static inline int record_msglog(int rank){
 }
 #endif
 
-void AMPI_Install_Idle_Timer(){
-#if AMPI_PRINT_IDLE
-  beginHandle = CcdCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE,(CcdVoidFn)BeginIdle,NULL);
-  endHandle = CcdCallOnConditionKeep(CcdPROCESSOR_END_IDLE,(CcdVoidFn)EndIdle,NULL);
-#endif
-}
-
-void AMPI_Uninstall_Idle_Timer(){
-#if AMPI_PRINT_IDLE
-  CcdCancelCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE,beginHandle);
-  CcdCancelCallOnConditionKeep(CcdPROCESSOR_BEGIN_BUSY,endHandle);
-#endif
-}
-
 PUPfunctionpointer(MPI_MainFn)
 
   class MPI_threadstart_t {
@@ -2227,7 +2213,7 @@ ampi::bcastraw(void* buf, int len, CkArrayID aid)
 
 
   AmpiMsg* 
-ampi::Alltoall_RemoteIGet(int disp, int cnt, MPI_Datatype type, int tag)
+ampi::Alltoall_RemoteIget(int disp, int cnt, MPI_Datatype type, int tag)
 {
   CkAssert(tag==MPI_ATA_TAG && AlltoallGetFlag);
   int unit;
@@ -2474,108 +2460,6 @@ int testRequestNoFree(MPI_Request *reqIdx, int *flag, MPI_Status *sts){
   return MPI_SUCCESS;
 }
 
-CDECL void AMPI_Migrate(void)
-{
-  //  AMPIAPI("AMPI_Migrate");
-#if 0
-#if CMK_BIGSIM_CHARM
-  TRACE_BG_AMPI_SUSPEND();
-#endif
-#endif
-  TCHARM_Migrate();
-
-#if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
-  ampi *currentAmpi = getAmpiInstance(MPI_COMM_WORLD);
-  CpvAccess(_currentObj) = currentAmpi;
-#endif
-
-#if CMK_BIGSIM_CHARM
-  //  TRACE_BG_AMPI_START(getAmpiInstance(MPI_COMM_WORLD)->getThread(), "AMPI_MIGRATE")
-  TRACE_BG_ADD_TAG("AMPI_MIGRATE");
-#endif
-}
-
-
-CDECL void AMPI_Evacuate(void)
-{
-  TCHARM_Evacuate();
-}
-
-
-
-CDECL void AMPI_Migrateto(int destPE)
-{
-  AMPIAPI("AMPI_MigrateTo");
-#if 0
-#if CMK_BIGSIM_CHARM
-  TRACE_BG_AMPI_SUSPEND();
-#endif
-#endif
-  TCHARM_Migrate_to(destPE);
-#if CMK_BIGSIM_CHARM
-  //TRACE_BG_AMPI_START(getAmpiInstance(MPI_COMM_WORLD)->getThread(), "AMPI_MIGRATETO")
-  TRACE_BG_ADD_TAG("AMPI_MIGRATETO");
-#endif
-}
-
-CDECL void AMPI_MigrateTo(int destPE)
-{
-  AMPI_Migrateto(destPE);
-}
-
-CDECL void AMPI_Async_Migrate(void)
-{
-  AMPIAPI("AMPI_Async_Migrate");
-#if 0
-#if CMK_BIGSIM_CHARM
-  TRACE_BG_AMPI_SUSPEND();
-#endif
-#endif
-  TCHARM_Async_Migrate();
-#if CMK_BIGSIM_CHARM
-  //TRACE_BG_AMPI_START(getAmpiInstance(MPI_COMM_WORLD)->getThread(), "AMPI_MIGRATE")
-  TRACE_BG_ADD_TAG("AMPI_ASYNC_MIGRATE");
-#endif
-}
-
-CDECL void AMPI_Allow_Migrate(void)
-{
-  AMPIAPI("AMPI_Allow_Migrate");
-#if 0
-#if CMK_BIGSIM_CHARM
-  TRACE_BG_AMPI_SUSPEND();
-#endif
-#endif
-  TCHARM_Allow_Migrate();
-#if CMK_BIGSIM_CHARM
-  TRACE_BG_ADD_TAG("AMPI_ALLOW_MIGRATE");
-#endif
-}
-
-CDECL void AMPI_Setmigratable(MPI_Comm comm, int mig){
-#if CMK_LBDB_ON
-  //AMPIAPI("AMPI_Setmigratable");
-  ampi *ptr=getAmpiInstance(comm);
-  ptr->setMigratable(mig);
-#else
-  CkPrintf("Warning: MPI_Setmigratable and load balancing are not supported in this version.\n");
-#endif
-}
-
-CDECL void AMPI_About_to_migrate(MPI_MigrateFn f)
-{
-  AMPIAPI("AMPI_About_to_migrate");
-  ampiParent *thisParent = getAmpiParent();
-  thisParent->setUserAboutToMigrateFn(f);
-}
-
-CDECL void AMPI_Just_migrated(MPI_MigrateFn f)
-{
-  AMPIAPI("AMPI_Just_migrated");
-  ampiParent *thisParent = getAmpiParent();
-  thisParent->setUserJustMigratedFn(f);
-}
-
 CDECL int AMPI_Is_thread_main(int *flag)
 {
   AMPIAPI("AMPI_Is_thread_main");
@@ -5748,15 +5632,15 @@ int AMPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
 }
 
   CDECL
-int AMPI_Alltoall2(void *sendbuf, int sendcount, MPI_Datatype sendtype,
+int AMPI_Alltoall_iget(void *sendbuf, int sendcount, MPI_Datatype sendtype,
     void *recvbuf, int recvcount, MPI_Datatype recvtype,
     MPI_Comm comm)
 {
-  AMPIAPI("AMPI_Alltoall2");
+  AMPIAPI("AMPI_Alltoall_iget");
 
 #if CMK_ERROR_CHECKING
   if (sendbuf == MPI_IN_PLACE || recvbuf == MPI_IN_PLACE)
-    CkAbort("AMPI_Alltoall2 does not accept MPI_IN_PLACE");
+    CkAbort("AMPI_Alltoall_iget does not accept MPI_IN_PLACE");
 
   int ret;
   ret = errorCheck(comm, 1, sendcount, 1, sendtype, 1, 0, 0, 0, 0, sendbuf, 1);
@@ -5767,7 +5651,7 @@ int AMPI_Alltoall2(void *sendbuf, int sendcount, MPI_Datatype sendtype,
     return ret;
 #endif
 
-  if(getAmpiParent()->isInter(comm)) CkAbort("MPI_Alltoall not allowed for Inter-communicator!");
+  if(getAmpiParent()->isInter(comm)) CkAbort("AMPI_Alltoall_iget not allowed for Inter-communicator!");
   if(comm==MPI_COMM_SELF) return copyDatatype(comm,sendtype,sendcount,sendbuf,recvbuf);
   ampi *ptr = getAmpiInstance(comm);
   CProxy_ampi pa(ptr->ckGetArrayID());
@@ -5778,7 +5662,7 @@ int AMPI_Alltoall2(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   int myrank;
   int i;
   // Set flags for others to get
-  ptr->setA2AIGetFlag((void*)sendbuf);
+  ptr->setA2AIgetFlag((void*)sendbuf);
   MPI_Comm_rank(comm,&myrank);
   recvdisp = myrank*recvcount;
 
@@ -5786,7 +5670,7 @@ int AMPI_Alltoall2(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   // post receives
   MPI_Request *reqs = new MPI_Request[size];
   for(i=0;i<size;i++) {
-    reqs[i] = pa[i].Alltoall_RemoteIGet(recvdisp, recvcount, recvtype,
+    reqs[i] = pa[i].Alltoall_RemoteIget(recvdisp, recvcount, recvtype,
         MPI_ATA_TAG);
   }
 
@@ -5803,7 +5687,7 @@ int AMPI_Alltoall2(void *sendbuf, int sendcount, MPI_Datatype sendtype,
   AMPI_Barrier(comm);
 
   // Reset flags 
-  ptr->resetA2AIGetFlag();
+  ptr->resetA2AIgetFlag();
 
 #if AMPI_COUNTER
   getAmpiParent()->counters.alltoall++;
@@ -7180,94 +7064,6 @@ int AMPI_Comm_create(MPI_Comm comm, MPI_Group group, MPI_Comm* newcomm)
   return MPI_SUCCESS;
 }
 
-/* Charm++ Extentions to MPI standard: */
-  CDECL
-void AMPI_Checkpoint(char *dname)
-{
-  AMPI_Barrier(MPI_COMM_WORLD);
-  AMPIAPI("AMPI_Checkpoint");
-  getAmpiParent()->startCheckpoint(dname);
-}
-
-  CDECL
-void AMPI_MemCheckpoint()
-{
-#if CMK_MEM_CHECKPOINT
-  AMPI_Barrier(MPI_COMM_WORLD);
-  AMPIAPI("AMPI_Checkpoint");
-  getAmpiParent()->startCheckpoint("");
-#else
-  CkPrintf("Error: In memory checkpoint/restart is not on! \n");
-  CkAbort("Error: recompile Charm++ with CMK_MEM_CHECKPOINT. \n");
-#endif
-}
-
-  CDECL
-void AMPI_Print(char *str)
-{
-  AMPIAPI("AMPI_Print");
-  ampiParent *ptr = getAmpiParent();
-  CkPrintf("[%d] %s\n", ptr->thisIndex, str);
-}
-
-  CDECL
-int AMPI_Register(void *d, MPI_PupFn f)
-{
-  AMPIAPI("AMPI_Register");
-  return TCHARM_Register(d,f);
-}
-
-  CDECL
-void *MPI_Get_userdata(int idx)
-{
-  AMPIAPI("AMPI_Get_userdata");
-  return TCHARM_Get_userdata(idx);
-}
-
-  CDECL
-void AMPI_Start_measure()
-{
-  AMPIAPI("AMPI_Start_measure");
-  ampiParent *ptr = getAmpiParent();
-  ptr->start_measure();
-}
-
-  CDECL
-void AMPI_Stop_measure()
-{
-  AMPIAPI("AMPI_Stop_measure");
-  ampiParent *ptr = getAmpiParent();
-  ptr->stop_measure();
-}
-
-  CDECL
-void AMPI_Set_load(double load)
-{
-  AMPIAPI("AMPI_Set_load");
-  ampiParent *ptr = getAmpiParent();
-  ptr->setObjTime(load);
-}
-
-  CDECL
-void AMPI_Register_main(MPI_MainFn mainFn,const char *name)
-{
-  AMPIAPI("AMPI_Register_main");
-  if (TCHARM_Element()==0)
-  { // I'm responsible for building the TCHARM threads:
-    ampiCreateMain(mainFn,name,strlen(name));
-  }
-}
-  FDECL
-  void FTN_NAME(MPI_REGISTER_MAIN,mpi_register_main)
-(MPI_MainFn mainFn,const char *name,int nameLen)
-{
-  AMPIAPI("AMPI_register_main");
-  if (TCHARM_Element()==0)
-  { // I'm responsible for building the TCHARM threads:
-    ampiCreateMain(mainFn,name,nameLen);
-  }
-}
-
 CDECL
 int AMPI_Comm_set_name(MPI_Comm comm, const char *comm_name){
   AMPIAPI("AMPI_Comm_set_name");
@@ -7834,15 +7630,6 @@ int AMPI_Cart_sub(MPI_Comm comm, int *remain_dims, MPI_Comm *newcomm) {
   return MPI_SUCCESS;
 }
 
-void _registerampif(void)
-{
-  _registerampi();
-}
-
-void AMPI_Datatype_iscontig(MPI_Datatype datatype, int *flag){
-  *flag = getDDT()->isContig(datatype);
-}
-
 CDECL
 int AMPI_Type_get_envelope(MPI_Datatype datatype, int *ni, int *na, int *nd, int *combiner){
   AMPIAPI("AMPI_Type_get_envelope");
@@ -7855,66 +7642,304 @@ int AMPI_Type_get_contents(MPI_Datatype datatype, int ni, int na, int nd, int i[
   return getDDT()->getContents(datatype,ni,na,nd,i,a,d);
 }
 
-/******** AMPI-specific (not standard MPI) calls *********/
+CDECL
+int AMPI_Pcontrol(const int level, ...) {
+  return MPI_SUCCESS;
+}
+
+/******** AMPI Extensions to the MPI standard *********/
 
 CDECL
-void AMPI_My_pe(int *my_pe) {
-  AMPIAPI("AMPI_My_pe");
-  *my_pe = CkMyPe();
+int AMPI_Migrate(MPI_Info hints)
+{
+#if 0 && CMK_BIGSIM_CHARM
+  TRACE_BG_AMPI_SUSPEND();
+#endif
+  int nkeys, exists;
+  char key[MPI_MAX_INFO_KEY], value[MPI_MAX_INFO_VAL];
+
+  AMPI_Info_get_nkeys(hints, &nkeys);
+
+  for (int i=0; i<nkeys; i++) {
+    AMPI_Info_get_nthkey(hints, i, key);
+    AMPI_Info_get(hints, key, MPI_MAX_INFO_VAL, value, &exists);
+    if (!exists) {
+      continue;
+    }
+    else if (strncmp(key, "ampi_load_balance", MPI_MAX_INFO_KEY) == 0) {
+
+      if (strncmp(value, "sync", MPI_MAX_INFO_VAL) == 0) {
+        TCHARM_Migrate();
+      }
+      else if (strncmp(value, "async", MPI_MAX_INFO_VAL) == 0) {
+        TCHARM_Async_Migrate();
+      }
+      else if (strncmp(value, "false", MPI_MAX_INFO_VAL) == 0) {
+        /* do nothing */
+      }
+      else {
+        CkPrintf("WARNING: Unknown MPI_Info value (%s) given to AMPI_Migrate for key: %s\n", value, key);
+      }
+    }
+    else if (strncmp(key, "ampi_checkpoint", MPI_MAX_INFO_KEY) == 0) {
+
+      if (strncmp(value, "true", MPI_MAX_INFO_VAL) == 0) {
+        CkAbort("AMPI> Error: Value \"true\" is not supported for AMPI_Migrate key \"ampi_checkpoint\"!\n");
+      }
+      else if (strncmp(value, "to_file=", strlen("to_file=")) == 0) {
+        int offset = strlen("to_file=");
+        int restart_dir_name_len = 0;
+        AMPI_Info_get_valuelen(hints, key, &restart_dir_name_len, &exists);
+        if (restart_dir_name_len > offset) {
+          value[restart_dir_name_len] = '\0';
+        }
+        else {
+          CkAbort("AMPI> Error: No checkpoint directory name given to AMPI_Migrate\n");
+        }
+        AMPI_Barrier(MPI_COMM_WORLD);
+        getAmpiParent()->startCheckpoint(&value[offset]);
+      }
+      else if (strncmp(value, "in_memory", MPI_MAX_INFO_VAL) == 0) {
+#if CMK_MEM_CHECKPOINT
+        AMPI_Barrier(MPI_COMM_WORLD);
+        getAmpiParent()->startCheckpoint("");
+#else
+        CkPrintf("AMPI> Error: In-memory checkpoint/restart is not enabled!\n");
+        CkAbort("AMPI> Error: Recompile Charm++/AMPI with CMK_MEM_CHECKPOINT.\n");
+#endif
+      }
+      else if (strncmp(value, "message_logging", MPI_MAX_INFO_VAL) == 0) {
+#if CMK_MESSAGE_LOGGING
+        TCHARM_Migrate();
+#else
+        CkPrintf("AMPI> Error: Message logging is not enabled!\n");
+        CkAbort("AMPI> Error: Recompile Charm++/AMPI with CMK_MESSAGE_LOGGING.\n");
+#endif
+      }
+      else if (strncmp(value, "false", MPI_MAX_INFO_VAL) == 0) {
+        /* do nothing */
+      }
+      else {
+        CkPrintf("WARNING: Unknown MPI_Info value (%s) given to AMPI_Migrate for key: %s\n", value, key);
+      }
+    }
+    else {
+      CkPrintf("WARNING: Unknown MPI_Info key given to AMPI_Migrate: %s\n", key);
+    }
+  }
+
+#if (defined(_FAULT_MLOG_) || defined(_FAULT_CAUSAL_))
+  ampi *currentAmpi = getAmpiInstance(MPI_COMM_WORLD);
+  CpvAccess(_currentObj) = currentAmpi;
+#endif
+
+#if CMK_BIGSIM_CHARM
+  //TRACE_BG_AMPI_START(getAmpiInstance(MPI_COMM_WORLD)->getThread(), "AMPI_MIGRATE")
+  TRACE_BG_ADD_TAG("AMPI_MIGRATE");
+#endif
+  return MPI_SUCCESS;
+}
+
+CDECL
+int AMPI_Evacuate(void)
+{
+  TCHARM_Evacuate();
+  return MPI_SUCCESS;
+}
+
+CDECL
+int AMPI_Migrate_to_pe(int dest)
+{
+  AMPIAPI("AMPI_Migrate_to_pe");
+#if 0 && CMK_BIGSIM_CHARM
+  TRACE_BG_AMPI_SUSPEND();
+#endif
+  TCHARM_Migrate_to(dest);
+#if CMK_BIGSIM_CHARM
+  //TRACE_BG_AMPI_START(getAmpiInstance(MPI_COMM_WORLD)->getThread(), "AMPI_MIGRATE_TO_PE")
+  TRACE_BG_ADD_TAG("AMPI_MIGRATE_TO_PE");
+#endif
+  return MPI_SUCCESS;
+}
+
+CDECL
+int AMPI_Comm_set_migratable(MPI_Comm comm, int mig){
+#if CMK_LBDB_ON
+  //AMPIAPI("AMPI_Comm_set_migratable");
+  ampi *ptr=getAmpiInstance(comm);
+  ptr->setMigratable(mig);
+#else
+  CkPrintf("WARNING: MPI_Comm_set_migratable is not supported in this build of Charm++/AMPI.\n");
+#endif
+  return MPI_SUCCESS;
+}
+
+CDECL
+int AMPI_Load_start_measure(void)
+{
+  AMPIAPI("AMPI_Load_start_measure");
+  ampiParent *ptr = getAmpiParent();
+  ptr->start_measure();
+  return MPI_SUCCESS;
+}
+
+CDECL
+int AMPI_Load_stop_measure(void)
+{
+  AMPIAPI("AMPI_Load_stop_measure");
+  ampiParent *ptr = getAmpiParent();
+  ptr->stop_measure();
+  return MPI_SUCCESS;
+}
+
+CDECL
+int AMPI_Load_set_value(double value)
+{
+  AMPIAPI("AMPI_Load_set_value");
+  ampiParent *ptr = getAmpiParent();
+  ptr->setObjTime(value);
+  return MPI_SUCCESS;
+}
+
+void _registerampif(void) {
+  _registerampi();
 }
 
 CDECL
-void AMPI_My_node(int *my_node) {
-  AMPIAPI("AMPI_My_node");
-  *my_node = CkMyNode();
+int AMPI_Register_main(MPI_MainFn mainFn,const char *name)
+{
+  AMPIAPI("AMPI_Register_main");
+  if (TCHARM_Element()==0)
+  { // I'm responsible for building the TCHARM threads:
+    ampiCreateMain(mainFn,name,strlen(name));
+  }
+  return MPI_SUCCESS;
+}
+
+FDECL
+void FTN_NAME(MPI_REGISTER_MAIN,mpi_register_main)
+(MPI_MainFn mainFn,const char *name,int nameLen)
+{
+  AMPIAPI("AMPI_register_main");
+  if (TCHARM_Element()==0)
+  { // I'm responsible for building the TCHARM threads:
+    ampiCreateMain(mainFn,name,nameLen);
+  }
 }
 
 CDECL
-void AMPI_Num_pes(int *num_pes) {
-  AMPIAPI("AMPI_Num_pes");
-  *num_pes = CkNumPes();
+int AMPI_Register_pup(MPI_PupFn fn, void *data, int *idx)
+{
+  AMPIAPI("AMPI_Register_pup");
+  *idx = TCHARM_Register(data, fn);
+  return MPI_SUCCESS;
+}
+
+CDECL
+int AMPI_Register_about_to_migrate(MPI_MigrateFn fn)
+{
+  AMPIAPI("AMPI_Register_about_to_migrate");
+  ampiParent *thisParent = getAmpiParent();
+  thisParent->setUserAboutToMigrateFn(fn);
+  return MPI_SUCCESS;
+}
+
+CDECL
+int AMPI_Register_just_migrated(MPI_MigrateFn fn)
+{
+  AMPIAPI("AMPI_Register_just_migrated");
+  ampiParent *thisParent = getAmpiParent();
+  thisParent->setUserJustMigratedFn(fn);
+  return MPI_SUCCESS;
+}
+
+CDECL
+int AMPI_Get_pup_data(int idx, void *data)
+{
+  AMPIAPI("AMPI_Get_pup_data");
+  data = TCHARM_Get_userdata(idx);
+  return MPI_SUCCESS;
+}
+
+CDECL
+int AMPI_Type_is_contiguous(MPI_Datatype datatype, int *flag)
+{
+  *flag = getDDT()->isContig(datatype);
+  return MPI_SUCCESS;
 }
 
 CDECL
-void AMPI_Num_nodes(int *num_nodes) {
-  AMPIAPI("AMPI_Num_nodes");
-  *num_nodes = CkNumNodes();
+int AMPI_Print(char *str)
+{
+  AMPIAPI("AMPI_Print");
+  ampiParent *ptr = getAmpiParent();
+  CkPrintf("[%d] %s\n", ptr->thisIndex, str);
+  return MPI_SUCCESS;
 }
 
 CDECL
-int AMPI_Suspend(int comm) {
+int AMPI_Suspend(MPI_Comm comm)
+{
   AMPIAPI("AMPI_Suspend");
   getAmpiInstance(comm)->block();
   return MPI_SUCCESS;
 }
 
 CDECL
-int AMPI_Yield(int comm) {
+int AMPI_Yield(MPI_Comm comm)
+{
   AMPIAPI("AMPI_Yield");
   getAmpiInstance(comm)->yield();
   return MPI_SUCCESS;
 }
 
 CDECL
-int AMPI_Resume(int dest, int comm) {
+int AMPI_Resume(int dest, MPI_Comm comm)
+{
   AMPIAPI("AMPI_Resume");
   getAmpiInstance(comm)->getProxy()[dest].unblock();
   return MPI_SUCCESS;
 }
 
 CDECL
-int AMPI_System(const char *cmd) {
+int AMPI_System(const char *cmd)
+{
   return TCHARM_System(cmd);
 }
 
 CDECL
-int AMPI_Pcontrol(const int level, ...)
+int AMPI_Trace_begin(void)
 {
-    return MPI_SUCCESS;
+  traceBegin();
+  return MPI_SUCCESS;
 }
 
-#if CMK_BIGSIM_CHARM
+CDECL
+int AMPI_Trace_end(void)
+{
+  traceEnd();
+  return MPI_SUCCESS;
+}
 
+int AMPI_Install_idle_timer(void)
+{
+#if AMPI_PRINT_IDLE
+  beginHandle = CcdCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE,(CcdVoidFn)BeginIdle,NULL);
+  endHandle = CcdCallOnConditionKeep(CcdPROCESSOR_END_IDLE,(CcdVoidFn)EndIdle,NULL);
+#endif
+  return MPI_SUCCESS;
+}
+
+int AMPI_Uninstall_idle_timer(void)
+{
+#if AMPI_PRINT_IDLE
+  CcdCancelCallOnConditionKeep(CcdPROCESSOR_BEGIN_IDLE,beginHandle);
+  CcdCancelCallOnConditionKeep(CcdPROCESSOR_BEGIN_BUSY,endHandle);
+#endif
+  return MPI_SUCCESS;
+}
+
+#if CMK_BIGSIM_CHARM
 extern "C" void startCFnCall(void *param,void *msg)
 {
   BgSetStartEvent();
@@ -7923,8 +7948,8 @@ extern "C" void startCFnCall(void *param,void *msg)
   delete (CkReductionMsg*)msg;
 }
 
-  CDECL
-int AMPI_Set_startevent(MPI_Comm comm)
+CDECL
+int AMPI_Set_start_event(MPI_Comm comm)
 {
   AMPIAPI("AMPI_BgSetStartEvent");
   CkAssert(comm == MPI_COMM_WORLD);
@@ -7948,12 +7973,12 @@ int AMPI_Set_startevent(MPI_Comm comm)
 }
 
 CDECL
-int AMPI_Set_endevent() 
+int AMPI_Set_end_event(void)
 {
   AMPIAPI("AMPI_BgSetEndEvent");
+  return MPI_SUCCESS;
 }
-
-#endif
+#endif // CMK_BIGSIM_CHARM
 
 #if CMK_CUDA
 GPUReq::GPUReq()
@@ -8039,8 +8064,7 @@ int AMPI_GPU_Invoke(workRequest *to_call)
 
   return MPI_SUCCESS;
 }
-
-#endif
+#endif // CMK_CUDA
 
 #include "ampi.def.h"
 
index 8f6df3f951fbd5a96810e56c87f617e23a2b9003..cd7e48982a07f748d8a0f82a6ebd8bff1b0cade7 100644 (file)
@@ -38,9 +38,9 @@ module ampi {
                                  MPI_Op op, int winIndex, CkFutureID ftHandle, int pe_src);
     entry void winRemoteLock(int lock_type, int winIndex, CkFutureID ftHandle, int pe_src, int requestRank);
     entry void winRemoteUnlock(int winIndex, CkFutureID ftHandle, int pe_src, int requestRank);
-    entry [iget] AmpiMsg *winRemoteIGet(int orgdisp, int orgcnt, MPI_Datatype orgtype,
+    entry [iget] AmpiMsg *winRemoteIget(int orgdisp, int orgcnt, MPI_Datatype orgtype,
                            MPI_Aint targdisp, int targcnt, MPI_Datatype targtype, int winIndex);
-    entry [iget] AmpiMsg *Alltoall_RemoteIGet(int disp, int cnt, MPI_Datatype type, int tag);
+    entry [iget] AmpiMsg *Alltoall_RemoteIget(int disp, int cnt, MPI_Datatype type, int tag);
   };
 
   group [migratable] ampiWorlds {
index 17396d0789346b87278890972af06a01ed6b9fcb..e7eafaff1dd906c77e029e26b02c7ef8a8883e59 100644 (file)
@@ -23,6 +23,8 @@ extern "C" {
 
 int AMPI_Main(int argc,char **argv); /* prototype for C main routine */
 
+typedef void (*MPI_MainFn) (int,char**);
+
 typedef int MPI_Datatype;
 typedef int MPI_Aint;/* should be "long", but must be "int" for f90... */
 typedef int MPI_Fint;
@@ -406,6 +408,13 @@ int AMPI_Type_create_struct(int count, int* arrBLength, MPI_Aint* arrDisp,
 #define MPI_Type_struct AMPI_Type_struct
 int AMPI_Type_struct(int count, int* arrBLength, MPI_Aint* arrDisp,
                      MPI_Datatype *oldType, MPI_Datatype *newType);
+#define MPI_Type_get_envelope AMPI_Type_get_envelope
+int AMPI_Type_get_envelope(MPI_Datatype datatype, int *num_integers, int *num_addresses,
+                          int *num_datatypes, int *combiner);
+#define MPI_Type_get_contents AMPI_Type_get_contents
+int AMPI_Type_get_contents(MPI_Datatype datatype, int max_integers, int max_addresses,
+                          int max_datatypes, int array_of_integers[], MPI_Aint array_of_addresses[],
+                          MPI_Datatype array_of_datatypes[]);
 #define MPI_Type_commit AMPI_Type_commit
 int AMPI_Type_commit(MPI_Datatype *datatype);
 #define MPI_Type_free AMPI_Type_free
@@ -504,10 +513,10 @@ int AMPI_Iallgatherv(void *sendbuf, int sendcount, MPI_Datatype sendtype,
 int AMPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                  void *recvbuf, int recvcount, MPI_Datatype recvtype,
                  MPI_Comm comm);
-#define MPI_Alltoall2 AMPI_Alltoall2
-int AMPI_Alltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
+#define MPI_Ialltoall AMPI_Ialltoall
+int AMPI_Ialltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                  void *recvbuf, int recvcount, MPI_Datatype recvtype,
-                 MPI_Comm comm);
+                 MPI_Comm comm, MPI_Request *request);
 #define MPI_Alltoallv AMPI_Alltoallv
 int AMPI_Alltoallv(void *sendbuf, int *sendcounts, int *sdispls,
                   MPI_Datatype sendtype, void *recvbuf, int *recvcounts,
@@ -534,10 +543,6 @@ int  MPICH_AlltoAll_long(void *sendbuf, int sendcount, MPI_Datatype sendtype,
 int  MPICH_AlltoAll_medium(void *sendbuf, int sendcount, MPI_Datatype sendtype,
                  void *recvbuf, int recvcount, MPI_Datatype recvtype,
                  MPI_Comm comm);
-#define MPI_Ialltoall AMPI_Ialltoall
-int AMPI_Ialltoall(void *sendbuf, int sendcount, MPI_Datatype sendtype,
-                 void *recvbuf, int recvcount, MPI_Datatype recvtype,
-                 MPI_Comm comm, MPI_Request *request);
 #define MPI_Reduce AMPI_Reduce
 int AMPI_Reduce(void *inbuf, void *outbuf, int count, int type,
                MPI_Op op, int root, MPI_Comm comm);
@@ -786,84 +791,6 @@ int AMPI_Abort(MPI_Comm comm, int errorcode);
 #define MPI_Pcontrol AMPI_Pcontrol
 int AMPI_Pcontrol(const int level, ...);
 
-/***extras***/
-#define MPI_My_pe AMPI_My_pe
-void AMPI_My_pe(int *my_pe);
-#define MPI_My_node AMPI_My_node
-void AMPI_My_node(int *my_node);
-#define MPI_Num_pes AMPI_Num_pes
-void AMPI_Num_pes(int *num_pes);
-#define MPI_Num_nodes AMPI_Num_nodes
-void AMPI_Num_nodes(int *num_nodes);
-#define MPI_Yield AMPI_Yield
-int AMPI_Yield(int comm);
-#define MPI_Resume AMPI_Resume
-int AMPI_Resume(int dest, int comm);
-#define MPI_Print AMPI_Print
-void AMPI_Print(char *str);
-
-/* for load balancing */
-#define MPI_Register AMPI_Register
-int AMPI_Register(void *, MPI_PupFn);
-
-#define MPI_Start_measure AMPI_Start_measure
-void AMPI_Start_measure();
-#define MPI_Stop_measure AMPI_Stop_measure
-void AMPI_Stop_measure();
-#define MPI_Set_load AMPI_Set_load
-void AMPI_Set_load(double load);
-
-#define MPI_Migrate AMPI_Migrate
-void AMPI_Migrate(void);
-
-#define MPI_Evacuate AMPI_Evacuate
-void AMPI_Evacuate(void);
-
-#define MPI_Migrateto AMPI_Migrateto
-void AMPI_Migrateto(int destPE);
-
-#define MPI_Async_Migrate AMPI_Async_Migrate
-void AMPI_Async_Migrate(void);
-#define MPI_Allow_Migrate AMPI_Allow_Migrate
-void AMPI_Allow_Migrate(void);
-#define MPI_Setmigratable AMPI_Setmigratable
-void AMPI_Setmigratable(int comm, int mig);
-#define MPI_About_to_migrate AMPI_About_to_migrate
-void AMPI_About_to_migrate(MPI_MigrateFn f);
-#define MPI_Just_migrated AMPI_Just_migrated
-void AMPI_Just_migrated(MPI_MigrateFn f);
-#define MPI_Checkpoint AMPI_Checkpoint
-void AMPI_Checkpoint(char *dname);
-#define MPI_MemCheckpoint AMPI_MemCheckpoint
-void AMPI_MemCheckpoint();
-#define MPI_Get_userdata AMPI_Get_userdata
-void *AMPI_Get_userdata(int);
-#define MPI_Datatype_iscontig AMPI_Datatype_iscontig
-void AMPI_Datatype_iscontig(MPI_Datatype datatype, int *flag);
-/*Create a new threads array and attach to it*/
-typedef void (*MPI_MainFn) (int,char**);
-#define MPI_Register_main AMPI_Register_main
-void AMPI_Register_main(MPI_MainFn mainFn, const char *name);
-/* Execute this shell command (just like "system()") */
-int AMPI_System(const char *cmd);
-
-/*** MPI-2 Functions (Unsorted, no Fortran support) ***/
-#define MPI_Type_get_envelope AMPI_Type_get_envelope
-int AMPI_Type_get_envelope(MPI_Datatype datatype, int *num_integers, int *num_addresses,
-                          int *num_datatypes, int *combiner);
-#define MPI_Type_get_contents AMPI_Type_get_contents
-int AMPI_Type_get_contents(MPI_Datatype datatype, int max_integers, int max_addresses,
-                          int max_datatypes, int array_of_integers[], MPI_Aint array_of_addresses[],
-                          MPI_Datatype array_of_datatypes[]);
-
-#if CMK_CUDA
-typedef struct workRequest workRequest;
-
-/* AMPI GPU Request interface */
-int AMPI_GPU_Iinvoke(workRequest *to_call, MPI_Request *request);
-int AMPI_GPU_Invoke(workRequest *to_call);
-#endif
-
 /*********************One sided communication routines *****************/ 
 /*  MPI_Win : an index into a list in ampiParent (just like MPI_Group) */
 /* name length for COMM, TYPE and WIN */
@@ -967,16 +894,6 @@ int AMPI_Accumulate(void *orgaddr, int orgcnt, MPI_Datatype orgtype, int rank,
                    MPI_Aint targdisp, int targcnt, MPI_Datatype targtype,
                    MPI_Op op, MPI_Win win);
 
-#define MPI_IGet AMPI_IGet
-int AMPI_IGet(MPI_Aint orgdisp, int orgcnt, MPI_Datatype orgtype, int rank,
-        MPI_Aint targdisp, int targcnt, MPI_Datatype targtype, MPI_Win win,
-       MPI_Request *request);
-#define MPI_IGet_Wait AMPI_IGet_Wait
-int AMPI_IGet_Wait(MPI_Request *request, MPI_Status *status, MPI_Win win);
-#define MPI_IGet_Free AMPI_IGet_Free
-int AMPI_IGet_Free(MPI_Request *request, MPI_Status *status, MPI_Win win);
-char* MPI_IGet_Data(MPI_Status status);
-
 #define MPI_Info_create AMPI_Info_create
 int AMPI_Info_create(MPI_Info *info);
 #define MPI_Info_set AMPI_Info_set
@@ -1013,8 +930,59 @@ int AMPI_Info_free(MPI_Info *info);
 #define MPI_Win_c2f(win)   (MPI_Fint)(win)
 #define MPI_Win_f2c(win)   (MPI_Win)(win)
 
-void AMPI_Install_Idle_Timer();
-void AMPI_Uninstall_Idle_Timer();
+/*** AMPI Extensions ***/
+int AMPI_Migrate(MPI_Info hints);
+int AMPI_Load_start_measure(void);
+int AMPI_Load_stop_measure(void);
+int AMPI_Load_set_value(double value);
+int AMPI_Migrate_to_pe(int dest);
+int AMPI_Comm_set_migratable(MPI_Comm comm, int mig);
+int AMPI_Register_pup(MPI_PupFn fn, void *data, int *idx);
+int AMPI_Get_pup_data(int idx, void *data);
+int AMPI_Register_main(MPI_MainFn mainFn, const char *name);
+int AMPI_Register_about_to_migrate(MPI_MigrateFn fn);
+int AMPI_Register_just_migrated(MPI_MigrateFn fn);
+int AMPI_Iget(MPI_Aint orgdisp, int orgcnt, MPI_Datatype orgtype, int rank,
+              MPI_Aint targdisp, int targcnt, MPI_Datatype targtype,
+              MPI_Win win, MPI_Request *request);
+int AMPI_Iget_wait(MPI_Request *request, MPI_Status *status, MPI_Win win);
+int AMPI_Iget_free(MPI_Request *request, MPI_Status *status, MPI_Win win);
+int AMPI_Iget_data(void *data, MPI_Status status);
+int AMPI_Type_is_contiguous(MPI_Datatype datatype, int *flag);
+int AMPI_Evacuate(void);
+int AMPI_Yield(MPI_Comm comm);
+int AMPI_Suspend(MPI_Comm comm);
+int AMPI_Resume(int dest, MPI_Comm comm);
+int AMPI_Print(char *str);
+int AMPI_Trace_begin(void);
+int AMPI_Trace_end(void);
+int AMPI_Alltoall_iget(void *sendbuf, int sendcount, MPI_Datatype sendtype,
+                       void *recvbuf, int recvcount, MPI_Datatype recvtype,
+                       MPI_Comm comm);
+#define AMPI_Alltoall_medium MPICH_AlltoAll_medium
+int  MPICH_AlltoAll_medium(void *sendbuf, int sendcount, MPI_Datatype sendtype,
+                           void *recvbuf, int recvcount, MPI_Datatype recvtype,
+                           MPI_Comm comm);
+#define AMPI_Alltoall_long MPICH_AlltoAll_long
+int  MPICH_AlltoAll_long(void *sendbuf, int sendcount, MPI_Datatype sendtype,
+                         void *recvbuf, int recvcount, MPI_Datatype recvtype,
+                         MPI_Comm comm);
+
+#if CMK_BIGSIM_CHARM
+int AMPI_Set_start_event(MPI_Comm comm);
+int AMPI_Set_end_event(void);
+void beginTraceBigSim(char* msg);
+void endTraceBigSim(char* msg, char* param);
+#endif
+
+#if CMK_CUDA
+typedef struct workRequest workRequest;
+int AMPI_GPU_Iinvoke(workRequest *to_call, MPI_Request *request);
+int AMPI_GPU_Invoke(workRequest *to_call);
+#endif
+
+/* Execute this shell command (just like "system()") */
+int AMPI_System(const char *cmd);
 
 extern int traceRegisterFunction(const char *name, int idx);
 extern void traceBeginFuncProj(char *,char *,int);
@@ -1022,35 +990,16 @@ extern void traceEndFuncProj(char *);
 extern void traceBeginFuncIndexProj(int, char *, int);
 extern void traceEndFuncIndexProj(int);
 
-#if CMK_BIGSIM_CHARM
-#define MPI_Set_startevent AMPI_Set_startevent
-#define MPI_Set_endevent AMPI_Set_endevent
-int AMPI_Set_startevent(MPI_Comm comm);
-int AMPI_Set_endevent();
-#endif
-
 /* Determine approximate depth of stack at the point of this call */
 extern long ampiCurrentStackUsage();
 
+#define AMPI_Trace_register_function_id(x, id) traceRegisterFunction(x, id);
+#define AMPI_Trace_begin_function_id(id) traceBeginFuncIndexProj(id, __FILE__, __LINE__);
+#define AMPI_Trace_end_function_id(id) traceEndFuncIndexProj(id);
 
-/*
-#define TRACEFUNC(code,name) traceBeginFuncProj(name,__FILE__,__LINE__); \
-code;\
-traceEndFuncProj(name);
-#define REGISTER_FUNCTION(x) traceRegisterFunction(x, -999);
-#define REG_FUNC_WITHID(x, id) traceRegisterFunction(x, id);
-*/
-
-#define _TRACE_REGISTER_FUNCTION_ID(x, id) traceRegisterFunction(x, id);
-#define _TRACE_BEGIN_FUNCTION_ID(id) traceBeginFuncIndexProj(id, __FILE__, __LINE__);
-#define _TRACE_END_FUNCTION_ID(id) traceEndFuncIndexProj(id);
-
-#define _TRACE_REGISTER_FUNCTION_NAME(x) traceRegisterFunction(x, -999);
-#define _TRACE_BEGIN_FUNCTION_NAME(name) traceBeginFuncProj(name, __FILE__, __LINE__);
-#define _TRACE_END_FUNCTION_NAME(name) traceEndFuncProj(name);
-
-void beginTraceBigSim(char* msg);
-void endTraceBigSim(char* msg, char* param);
+#define AMPI_Trace_register_function_name(x) traceRegisterFunction(x, -999);
+#define AMPI_Trace_begin_function_name(name) traceBeginFuncProj(name, __FILE__, __LINE__);
+#define AMPI_Trace_end_function_name(name) traceEndFuncProj(name);
 
 #include "ampiProjections.h"
 #ifdef __cplusplus
index 88308453680da2d729de349d2df49989ce34387a..558d9b20b0dc93a25e494e721ca3524ce72d073d 100644 (file)
@@ -342,21 +342,21 @@ ampi::winRemoteGet(int orgcnt, MPI_Datatype orgtype, MPI_Aint targdisp, int targ
 
 
 int
-ampi::winIGet(MPI_Aint orgdisp, int orgcnt, MPI_Datatype orgtype, int rank,
+ampi::winIget(MPI_Aint orgdisp, int orgcnt, MPI_Datatype orgtype, int rank,
              MPI_Aint targdisp, int targcnt, MPI_Datatype targtype, WinStruct win, 
             MPI_Request *req){
   // Send the request to data and handle of Future to remote side
   CProxy_ampi pa(thisArrayID);
   AMPI_DEBUG("    Rank[%d:%d] request Remote iget at [%d]\n", thisIndex, myRank, rank);
-  *req = pa[rank].winRemoteIGet(orgdisp, orgcnt, orgtype, targdisp, targcnt, targtype, win.index);
+  *req = pa[rank].winRemoteIget(orgdisp, orgcnt, orgtype, targdisp, targcnt, targtype, win.index);
   return MPI_SUCCESS;
 }
 
 
 AmpiMsg*
-ampi::winRemoteIGet(int orgdisp, int orgcnt, MPI_Datatype orgtype, MPI_Aint targdisp, int targcnt,
+ampi::winRemoteIget(int orgdisp, int orgcnt, MPI_Datatype orgtype, MPI_Aint targdisp, int targcnt,
                    MPI_Datatype targtype, int winIndex) {
-  AMPI_DEBUG("    RemoteIGet invoked at Rank[%d:%d]\n", thisIndex, myRank);
+  AMPI_DEBUG("    RemoteIget invoked at Rank[%d:%d]\n", thisIndex, myRank);
 // FIX: no need for stargaddr??
 // FIX: what is targaddr pointing??
   int orgunit, targunit;
@@ -384,21 +384,22 @@ stargtotalsize,myComm.getComm());
  }
 
 int
-ampi::winIGetWait(MPI_Request *request, MPI_Status *status) {
+ampi::winIgetWait(MPI_Request *request, MPI_Status *status) {
   // Wait on the Future object
-  AMPI_DEBUG("    [%d] IGet Waiting\n", thisIndex, *request);
+  AMPI_DEBUG("    [%d] Iget Waiting\n", thisIndex, *request);
   status->msg = (AmpiMsg*)CkWaitReleaseFuture(*request);
-  AMPI_DEBUG("    [%d] IGet Waiting [%d] awaken\n", thisIndex, *request);
+  AMPI_DEBUG("    [%d] Iget Waiting [%d] awaken\n", thisIndex, *request);
   return MPI_SUCCESS;
 }
 
 int
-ampi::winIGetFree(MPI_Request *request, MPI_Status *status) {
-  AMPI_DEBUG("    [%d] : IGet [%d] frees buffer\n", thisIndex, *request);
+ampi::winIgetFree(MPI_Request *request, MPI_Status *status) {
+  AMPI_DEBUG("    [%d] : Iget [%d] frees buffer\n", thisIndex, *request);
 
-  
-  if(!(MPI_IGet_Data(*status))) {
-    AMPI_DEBUG("    [%d] IGet [%d] attempt to free NULL buffer \n", thisIndex, *request);
+  void *data;
+  AMPI_Iget_data(data, *status);
+  if(!data) {
+    AMPI_DEBUG("    [%d] Iget [%d] attempt to free NULL buffer \n", thisIndex, *request);
     return MPI_ERR_BUFFER;
   }
   else {
@@ -788,38 +789,40 @@ int AMPI_Win_complete(MPI_Win win){
 
 // FIX PLACE II
 CDECL
-int AMPI_IGet(MPI_Aint orgdisp, int orgcnt, MPI_Datatype orgtype, int rank,
+int AMPI_Iget(MPI_Aint orgdisp, int orgcnt, MPI_Datatype orgtype, int rank,
         MPI_Aint targdisp, int targcnt, MPI_Datatype targtype, MPI_Win win,
         MPI_Request *request) {
-  AMPIAPI("AMPI_IGet");
+  AMPIAPI("AMPI_Iget");
   WinStruct winStruct = getAmpiParent()->getWinStruct(win);
   ampi *ptr = getAmpiInstance(winStruct.comm);
   // winGet is a local function which will call the remote method on #rank processor
-  return  ptr->winIGet(orgdisp, orgcnt, orgtype, rank, targdisp, targcnt, targtype, winStruct,
+  return  ptr->winIget(orgdisp, orgcnt, orgtype, rank, targdisp, targcnt, targtype, winStruct,
                       request);
 }
 
 CDECL
-int AMPI_IGet_Wait(MPI_Request *request, MPI_Status *status, MPI_Win win) {
-  AMPIAPI("AMPI_IGet_Wait");
+int AMPI_Iget_wait(MPI_Request *request, MPI_Status *status, MPI_Win win) {
+  AMPIAPI("AMPI_Iget_wait");
   WinStruct winStruct = getAmpiParent()->getWinStruct(win);
   ampi *ptr = getAmpiInstance(winStruct.comm);
   // winGet is a local function which will call the remote method on #rank processor
-  return  ptr->winIGetWait(request,status);
+  return  ptr->winIgetWait(request,status);
 }
 
 CDECL
-int AMPI_IGet_Free(MPI_Request *request, MPI_Status *status, MPI_Win win) {
-  AMPIAPI("AMPI_IGet_Free");
+int AMPI_Iget_free(MPI_Request *request, MPI_Status *status, MPI_Win win) {
+  AMPIAPI("AMPI_Iget_free");
   WinStruct winStruct = getAmpiParent()->getWinStruct(win);
   ampi *ptr = getAmpiInstance(winStruct.comm);
   // winGet is a local function which will call the remote method on #rank processor
-  return  ptr->winIGetFree(request, status);
+  return  ptr->winIgetFree(request, status);
 }
 
-char* 
-MPI_IGet_Data(MPI_Status status) 
-{ return (char*)((AmpiMsg*)status.msg)->data; }
+CDECL
+int AMPI_Iget_data(void *data, MPI_Status status) {
+  data = (void*)((AmpiMsg*)status.msg)->data;
+  return MPI_SUCCESS;
+}
 
 /*
  * int AMPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr) 
index 04d88c0b487c43e510a910cf10b1d67bd4282cce..34d0c4e265a05bf37d8030fc038e6f6cdd1022ab 100644 (file)
@@ -183,37 +183,10 @@ FDECL {
 #define mpi_init_thread FTN_NAME( MPI_INIT_THREAD , mpi_init_thread )
 #define mpi_init FTN_NAME( MPI_INIT , mpi_init )
 #define mpi_initialized FTN_NAME( MPI_INITIALIZED , mpi_initialized )
-#define mpi_init_universe FTN_NAME( MPI_INIT_UNIVERSE , mpi_init_universe )
 #define mpi_finalize FTN_NAME( MPI_FINALIZE , mpi_finalize )
 #define mpi_finalized FTN_NAME( MPI_FINALIZED , mpi_finalized )
 #define mpi_abort FTN_NAME( MPI_ABORT , mpi_abort )
 
-#define mpi_my_pe FTN_NAME ( MPI_MY_PE , mpi_my_pe )
-#define mpi_my_node FTN_NAME ( MPI_MY_NODE , mpi_my_node )
-#define mpi_num_pes FTN_NAME ( MPI_NUM_PES , mpi_num_pes )
-#define mpi_num_nodes FTN_NAME ( MPI_NUM_NODES , mpi_num_nodes )
-#define mpi_yield FTN_NAME ( MPI_YIELD , mpi_yield )
-#define mpi_resume FTN_NAME ( MPI_RESUME, mpi_resume )
-#define mpi_print FTN_NAME( MPI_PRINT , mpi_print )
-#define mpi_Start_measure FTN_NAME( MPI_START_MEASURE, mpi_start_measure)
-#define mpi_Stop_measure FTN_NAME( MPI_STOP_MEASURE, mpi_stop_measure)
-#define mpi_set_load FTN_NAME( MPI_SET_LOAD, mpi_set_load)
-#define mpi_register FTN_NAME( MPI_REGISTER , mpi_register )
-#define mpi_migrate FTN_NAME( MPI_MIGRATE , mpi_migrate )
-#define mpi_migrateto FTN_NAME( MPI_MIGRATETO , mpi_migrateto )
-#define mpi_async_migrate FTN_NAME( MPI_ASYNC_MIGRATE , mpi_async_migrate )
-#define mpi_allow_migrate FTN_NAME( MPI_ALLOW_MIGRATE , mpi_allow_migrate )
-#define mpi_setmigratable FTN_NAME (MPI_SETMIGRATABLE , mpi_setmigratable )
-#define mpi_about_to_migrate FTN_NAME (MPI_ABOUT_TO_MIGRATE , mpi_about_to_migrate )
-#define mpi_just_migrated FTN_NAME (MPI_JUST_MIGRATED , mpi_just_migrated )
-#define mpi_checkpoint FTN_NAME( MPI_CHECKPOINT , mpi_checkpoint )
-#define mpi_memcheckpoint FTN_NAME( MPI_MEMCHECKPOINT , mpi_memcheckpoint )
-
-#define mpi_command_argument_count FTN_NAME( MPI_COMMAND_ARGUMENT_COUNT , mpi_command_argument_count )
-#define mpi_get_command_argument FTN_NAME( MPI_GET_COMMAND_ARGUMENT , mpi_get_command_argument )
-#define mpi_iargc FTN_NAME( MPI_IARGC , mpi_iargc )
-#define mpi_getarg FTN_NAME( MPI_GETARG , mpi_getarg )
-
 /* MPI-2 */
 #define mpi_type_get_envelope FTN_NAME ( MPI_TYPE_GET_ENVELOPE , mpi_type_get_envelope )
 #define mpi_type_get_contents FTN_NAME ( MPI_TYPE_GET_CONTENTS , mpi_type_get_contents )
@@ -256,14 +229,56 @@ FDECL {
 
 #define mpi_pcontrol FTN_NAME ( MPI_PCONTROL , mpi_pcontrol )
 
+/* AMPI extensions */
+#define ampi_migrate FTN_NAME( AMPI_MIGRATE , ampi_migrate )
+#define ampi_load_start_measure FTN_NAME( AMPI_LOAD_START_MEASURE, ampi_load_start_measure )
+#define ampi_load_stop_measure FTN_NAME( AMPI_LOAD_STOP_MEASURE, ampi_load_stop_measure )
+#define ampi_load_set_value FTN_NAME( AMPI_SET_LOAD_VALUE, ampi_load_set_value )
+#define ampi_evacuate FTN_NAME ( AMPI_EVACUATE , ampi_evacuate )
+#define ampi_migrate_to_pe FTN_NAME( AMPI_MIGRATE_TO_PE , ampi_migrate_to_pe )
+#define ampi_comm_set_migratable FTN_NAME ( AMPI_COMM_SET_MIGRATABLE , ampi_comm_set_migratable )
+#define ampi_init_universe FTN_NAME( AMPI_INIT_UNIVERSE , ampi_init_universe )
+#define ampi_register_main FTN_NAME( AMPI_REGISTER_MAIN , ampi_register_main )
+#define ampi_register_pup FTN_NAME( AMPI_REGISTER_PUP , ampi_register_pup )
+#define ampi_register_about_to_migrate FTN_NAME ( AMPI_REGISTER_ABOUT_TO_MIGRATE , ampi_register_about_to_migrate )
+#define ampi_register_just_migrated FTN_NAME ( AMPI_REGISTER_JUST_MIGRATED , ampi_register_just_migrated )
+#define ampi_type_is_contiguous FTN_NAME ( AMPI_TYPE_IS_CONTIGUOUS , ampi_type_is_contiguous )
+#define ampi_get_pup_data FTN_NAME ( AMPI_GET_PUP_DATA , ampi_get_pup_data )
+#define ampi_iget FTN_NAME ( AMPI_IGET  , ampi_iget )
+#define ampi_iget_wait FTN_NAME ( AMPI_IGET_WAIT  , ampi_iget_wait )
+#define ampi_iget_data FTN_NAME ( AMPI_IGET_DATA  , ampi_iget_data )
+#define ampi_iget_free FTN_NAME ( AMPI_IGET_FREE  , ampi_iget_free )
+#define ampi_alltoall_iget FTN_NAME( AMPI_ALLTOALL_IGET , ampi_alltoall_iget )
+#define ampi_alltoall_medium FTN_NAME( AMPI_ALLTOALL_MEDIUM , ampi_alltoall_medium )
+#define ampi_alltoall_long FTN_NAME( AMPI_ALLTOALL_LONG , ampi_alltoall_long )
+#define ampi_yield FTN_NAME ( AMPI_YIELD , ampi_yield )
+#define ampi_suspend FTN_NAME ( AMPI_SUSPEND , ampi_suspend )
+#define ampi_resume FTN_NAME ( AMPI_RESUME, ampi_resume )
+#define ampi_print FTN_NAME( AMPI_PRINT , ampi_print )
+#define ampi_install_idle_timer FTN_NAME( AMPI_INSTALL_IDLE_TIMER , ampi_install_idle_timer )
+#define ampi_uninstall_idle_timer FTN_NAME( AMPI_UNINSTALL_IDLE_TIMER , ampi_uninstall_idle_timer )
+
+/* Fortran-specific AMPI extensions */
+#define ampi_command_argument_count FTN_NAME( AMPI_COMMAND_ARGUMENT_COUNT , ampi_command_argument_count )
+#define ampi_get_command_argument FTN_NAME( AMPI_GET_COMMAND_ARGUMENT , ampi_get_command_argument )
+
+#if CMK_BIGSIM_CHARM
+#define ampi_set_start_event FTN_NAME( AMPI_SET_START_EVENT , ampi_set_start_event )
+#define ampi_set_end_event FTN_NAME( AMPI_SET_END_EVENT , ampi_set_end_event )
+#define begintracebigsim FTN_NAME (BEGINTRACEBIGSIM , begintracebigsim)
+#define endtracebigsim FTN_NAME (ENDTRACEBIGSIM , endtracebigsim)
+#endif
+
+#if CMK_CUDA
+#define ampi_gpu_invoke FTN_NAME ( AMPI_GPU_INVOKE  , ampi_gpu_invoke )
+#define ampi_gpu_iinvoke FTN_NAME ( AMPI_GPU_IINVOKE  , ampi_gpu_iinvoke )
+#endif
+
 #define REDUCERF(caps, nocaps) \
 void FTN_NAME(caps, nocaps)(void *iv, void *iov, int *len, MPI_Datatype *dt){ \
   caps(iv, iov, len, dt); \
 }
 
-#define mpi_info_maxmemory FTN_NAME (MPI_INFO_MAXMEMORY, mpi_info_maxmemory)
-#define mpi_info_memory FTN_NAME (MPI_INFO_MEMORY, mpi_info_memory)    
-
 #if !CMK_FORTRAN_USES_ALLCAPS
 REDUCERF(MPI_MAX    , mpi_max)
 REDUCERF(MPI_MIN    , mpi_min)
@@ -291,15 +306,6 @@ CtvExtern(int, mpi_opc);
 //#define GET_MPI_OP(idx)      (CkAssert(idx - MPI_OP_FIRST >= 0 && idx - MPI_OP_FIRST < CtvAccess(mpi_opc)), CtvAccess(mpi_ops)[idx - MPI_OP_FIRST])
 inline MPI_Op & GET_MPI_OP(int idx)      { MPI_Op *tab=CtvAccess(mpi_ops); return tab[idx - MPI_OP_FIRST]; }
 
-void mpi_init_universe(int *unicomm)
-{
-  AMPIAPI("mpi_init_universe");
-  for(int i=0;i<_mpi_nworlds; i++)
-  {
-    unicomm[i] = MPI_COMM_UNIVERSE[i];
-  }
-}
-
 void mpi_is_thread_main(int *flag, int *ierr){
   *ierr = AMPI_Is_thread_main(flag);
 }
@@ -416,16 +422,6 @@ void mpi_ibarrier(int *comm, int *request, int *ierr)
   *ierr = AMPI_Ibarrier(*comm, request);
 }
 
-void mpi_yield(int *comm, int *ierr)
-{
-  *ierr = AMPI_Yield(*comm);
-}
-
-void mpi_resume(int *dest, int *comm, int *ierr)
-{
-  *ierr = AMPI_Resume(*dest, *comm);
-}
-
 void mpi_bcast(void *buf, int *count, int *type, int *root, int *comm, 
    int *ierr)
 {
@@ -1212,117 +1208,6 @@ void mpi_get_count(int *sts, int *dtype, int *cnt, int *ierr)
   *ierr = AMPI_Get_count((MPI_Status*) sts, *dtype, cnt);
 }
 
-void mpi_print(char *str, int *len)
-{
-  char *buf = new char[*len+1];
-  memcpy(buf, str, *len);
-  buf[*len] = '\0';
-  AMPI_Print(buf);
-  delete [] buf;
-}
-
-void mpi_migrate(void)
-{
-  AMPI_Migrate();
-}
-
-void mpi_setmigratable(int *comm, int *mig)
-{
-  AMPI_Setmigratable(*comm, * mig);
-}
-
-void mpi_migrateto(int *destPE)
-{
-  AMPI_Migrateto(*destPE);
-}
-
-void mpi_about_to_migrate(MPI_MigrateFn f)
-{
-  AMPI_About_to_migrate(f);
-}
-
-void mpi_just_migrated(MPI_MigrateFn f)
-{
-  AMPI_Just_migrated(f);
-}
-
-void mpi_start_measure()           /* turn on auto load instrumentation */
-{
-  AMPI_Start_measure();
-}
-
-void mpi_stop_measure()
-{
-  AMPI_Stop_measure();
-}
-
-void mpi_set_load(double *load)
-{
-  AMPI_Set_load(*load);
-}
-
-void mpi_register(void *d, MPI_PupFn f)
-{
-  AMPI_Register(d,f);
-}
-
-void mpi_get_userdata(int* dn, void *data)
-{
-  data = AMPI_Get_userdata(*dn); 
-}
-
-void mpi_checkpoint(char *dname){
-  AMPI_Checkpoint(dname);
-}
-
-void mpi_memcheckpoint(){
-  AMPI_MemCheckpoint();
-}
-
-/* Fortran2003 standard cmd line arg parsing functions:
- *    - command_argument_count() returns the number of arguments
- *      NOT including the program name.
- *    - get_command_argument() returns the i'th argument, where
- *      if 'i' is zero the program name is returned.
- */
-void mpi_command_argument_count(int *count)
-{
-  *count = CkGetArgc()-1;
-}
-
-void mpi_get_command_argument(int *c, char *str, int *len, int *ierr)
-{
-  char **argv = CkGetArgv();
-  int nc = CkGetArgc()-1;
-  int arglen = strlen(argv[*c]);
-
-  if (*c >= 0 && *c <= nc) {
-    if (arglen <= *len) {
-      memcpy(str, argv[*c], arglen);
-      for (int j=arglen; j<*len; j++) str[j] = ' ';
-      *ierr = 0;
-    } else {
-      memcpy(str, argv[*c], *len);
-      *ierr = -1;
-    }
-  }
-  else {
-    memset(str, ' ', *len);
-    *ierr = 1;
-  }
-}
-
-/* Fortran77-style GNU extensions for cmd line arg parsing functions */
-void mpi_iargc(int *count)
-{
-  mpi_command_argument_count(count);
-}
-
-void mpi_getarg(int *c, char *str, int *len, int *ierr)
-{
-  mpi_get_command_argument(c, str, len, ierr);
-}
-
 void mpi_comm_remote_size(int *comm, int *size, int *ierr){
   *ierr = AMPI_Comm_remote_size(*comm, size);
 }
@@ -1515,16 +1400,16 @@ void mpi_accumulate(void *orgaddr, int *orgcnt, int *orgtype, int *rank,
 void mpi_info_create(int* info, int* ierr){
   *ierr = MPI_Info_create(info);
 }
-void mpi_info_set(int* info, char *key, char *value, int* ierr){
+void mpi_info_set(int* info, const char *key, const char *value, int* ierr){
   *ierr = MPI_Info_set(*info, key, value);
 }
-void mpi_info_delete(int* info, char* key, int* ierr){
+void mpi_info_delete(int* info, const char* key, int* ierr){
   *ierr = MPI_Info_delete(*info, key);
 }
-void mpi_info_get(int* info, char *key, int *valuelen, char *value, int *flag, int* ierr){
+void mpi_info_get(int* info, const char *key, int *valuelen, char *value, int *flag, int* ierr){
   *ierr = MPI_Info_get(*info, key, *valuelen, value, flag);
 }
-void mpi_info_get_valuelen(int* info, char *key, int *valuelen, int *flag, int* ierr){
+void mpi_info_get_valuelen(int* info, const char *key, int *valuelen, int *flag, int* ierr){
   *ierr = MPI_Info_get_valuelen(*info, key, valuelen, flag);
 }
 void mpi_info_get_nkeys(int* info, int *nkeys, int* ierr){
@@ -1540,42 +1425,189 @@ void mpi_info_free(int* info, int* ierr){
   *ierr = MPI_Info_free(info);
 }
 
-void mpi_info_maxmemory(){
-  CkPrintf("MaxMemory %ld\n", CmiMaxMemoryUsage());
+void mpi_pcontrol(int *level) {
+  AMPI_Pcontrol(*level);
 }
 
-void mpi_info_memory(){
-  CkPrintf("Memory %ld\n", CmiMemoryUsage());
+/* AMPI Extensions */
+void ampi_migrate(int *hints, int *ierr) {
+  *ierr = AMPI_Migrate(*hints);
 }
 
-void mpi_pcontrol(int *level) {
-  AMPI_Pcontrol(*level);
+void ampi_load_start_measure(int *ierr) {
+  *ierr = AMPI_Load_start_measure();
 }
 
-void mpi_my_pe(int *my_pe) {
-  AMPI_My_pe(my_pe);
+void ampi_load_stop_measure(int *ierr) {
+  *ierr = AMPI_Load_stop_measure();
 }
 
-void mpi_my_node(int *my_node) {
-  AMPI_My_node(my_node);
+void ampi_load_set_value(double *value, int *ierr) {
+  *ierr = AMPI_Load_set_value(*value);
 }
 
-void mpi_num_pes(int *num_pes) {
-  AMPI_Num_pes(num_pes);
+void ampi_evacuate(int *ierr) {
+  *ierr = AMPI_Evacuate();
 }
 
-void mpi_num_nodes(int *num_nodes) {
-  AMPI_Num_nodes(num_nodes);
+void ampi_migrate_to_pe(int *dest, int *ierr) {
+  *ierr = AMPI_Migrate_to_pe(*dest);
+}
+
+void ampi_comm_set_migratable(int *comm, int *mig, int *ierr) {
+  *ierr = AMPI_Comm_set_migratable(*comm, *mig);
+}
+
+void ampi_register_main(MPI_MainFn fn, const char *name, int *ierr) {
+  *ierr = AMPI_Register_main(fn, name);
+}
+
+void ampi_register_pup(MPI_PupFn fn, void *data, int *idx, int *ierr) {
+  *ierr = AMPI_Register_pup(fn, data, idx);
+}
+
+void ampi_register_about_to_migrate(MPI_MigrateFn fn, int *ierr) {
+  *ierr = AMPI_Register_about_to_migrate(fn);
+}
+
+void ampi_register_just_migrated(MPI_MigrateFn fn, int *ierr) {
+  *ierr = AMPI_Register_just_migrated(fn);
+}
+
+void ampi_type_is_contiguous(int *datatype, int *flag, int *ierr) {
+  *ierr = AMPI_Type_is_contiguous(*datatype, flag);
+}
+
+void ampi_get_pup_data(int *idx, void *data, int *ierr) {
+  *ierr = AMPI_Get_pup_data(*idx, data);
+}
+
+void ampi_iget(int *orgdisp, int *orgcnt, int *orgtype, int *rank,
+        int *targdisp, int *targcnt, int *targtype, int *win,
+        int *request, int *ierr) {
+  *ierr = AMPI_Iget(*orgdisp, *orgcnt, *orgtype, *rank, *targdisp, *targcnt,
+                    *targtype, *win, request);
+}
+
+void ampi_iget_wait(int *request, int *status, int *win, int *ierr) {
+  *ierr = AMPI_Iget_wait(request, (MPI_Status*)status, *win);
+}
+
+void ampi_iget_free(int *request, int *status, int *win, int *ierr) {
+  *ierr = AMPI_Iget_free(request, (MPI_Status*)status, *win);
+}
+
+void ampi_iget_data(void *data, int *status, int *ierr) {
+  *ierr = AMPI_Iget_data(data, *((MPI_Status*)status));
+}
+
+void ampi_alltoall_iget(void *data, int *sendcount, int *sendtype,
+                        void *recvbuf, int *recvcount, int *recvtype,
+                        int *comm, int *ierr) {
+  *ierr = AMPI_Alltoall_iget(data, *sendcount, *sendtype, recvbuf,
+                             *recvcount, *recvtype, *comm);
+}
+
+void ampi_alltoall_medium(void *data, int *sendcount, int *sendtype,
+                          void *recvbuf, int *recvcount, int *recvtype,
+                          int *comm, int *ierr) {
+  *ierr = MPICH_AlltoAll_medium(data, *sendcount, *sendtype, recvbuf,
+                                *recvcount, *recvtype, *comm);
+}
+
+void ampi_alltoall_long(void *data, int *sendcount, int *sendtype,
+                        void *recvbuf, int *recvcount, int *recvtype,
+                        int *comm, int *ierr) {
+  *ierr = MPICH_AlltoAll_long(data, *sendcount, *sendtype, recvbuf,
+                              *recvcount, *recvtype, *comm);
+}
+
+void ampi_yield(int *comm, int *ierr) {
+  *ierr = AMPI_Yield(*comm);
+}
+
+void ampi_suspend(int *comm, int *ierr) {
+  *ierr = AMPI_Suspend(*comm);
+}
+
+void ampi_resume(int *dest, int *comm, int *ierr) {
+  *ierr = AMPI_Resume(*dest, *comm);
+}
+
+void ampi_print(char *str, int *ierr) {
+  char *buf = new char[MPI_MAX_ERROR_STRING];
+  memcpy(buf, str, MPI_MAX_ERROR_STRING);
+  buf[MPI_MAX_ERROR_STRING-1] = '\0';
+  AMPI_Print(buf);
+  delete [] buf;
+}
+
+#if CMK_BIGSIM_CHARM
+int ampi_set_start_event(int *comm, int *ierr) {
+  *ierr = AMPI_Set_start_event(*comm);
+}
+
+void ampi_set_end_event(int *ierr) {
+  *ierr = AMPI_Set_end_event();
 }
 
-#define begintracebigsim FTN_NAME (BEGINTRACEBIGSIM , begintracebigsim)
-#define endtracebigsim FTN_NAME (ENDTRACEBIGSIM , endtracebigsim)
 void begintracebigsim(char* msg){
   beginTraceBigSim(msg);
 }
+
 void endtracebigsim(char* msg, char* param){
   endTraceBigSim(msg, param);
 }
+#endif
+
+#if CMK_CUDA
+void ampi_gpu_iinvoke(int *to_call, int *request, int *ierr) {
+  *ierr = AMPI_GPU_Iinvoke(to_call, request);
+}
+
+void ampi_gpu_invoke(int *to_call, int *ierr) {
+  *ierr = AMPI_GPU_Invoke(to_call);
+}
+#endif
+
+/* Fortran2003 standard cmd line arg parsing functions:
+ *    - command_argument_count() returns the number of arguments
+ *      NOT including the program name.
+ *    - get_command_argument() returns the i'th argument, where
+ *      if 'i' is zero the program name is returned.
+ */
+void ampi_command_argument_count(int *count) {
+  *count = CkGetArgc()-1;
+}
+
+void ampi_get_command_argument(int *c, char *str, int *len, int *ierr) {
+  char **argv = CkGetArgv();
+  int nc = CkGetArgc()-1;
+  int arglen = strlen(argv[*c]);
+
+  if (*c >= 0 && *c <= nc) {
+    if (arglen <= *len) {
+      memcpy(str, argv[*c], arglen);
+      for (int j=arglen; j<*len; j++) str[j] = ' ';
+      *ierr = 0;
+    } else {
+      memcpy(str, argv[*c], *len);
+      *ierr = -1;
+    }
+  }
+  else {
+    memset(str, ' ', *len);
+    *ierr = 1;
+  }
+}
+
+void ampi_init_universe(int *unicomm, int *ierr) {
+  AMPIAPI("AMPI_Init_universe");
+  for(int i=0; i<_mpi_nworlds; i++) {
+    unicomm[i] = MPI_COMM_UNIVERSE[i];
+  }
+  *ierr = MPI_SUCCESS;
+}
 
 } // extern "C"
 
index 549126545b7c9e8c38dce790ed9a5cf301931cca..d79217a002e5c32de59faef1d366e1ae57b428ce 100644 (file)
@@ -1528,18 +1528,18 @@ friend class SReq;
               MPI_Aint targdisp, int targcnt, MPI_Datatype targtype, WinStruct win);
     int winGet(void *orgaddr, int orgcnt, MPI_Datatype orgtype, int rank, 
               MPI_Aint targdisp, int targcnt, MPI_Datatype targtype, WinStruct win);
-    int winIGet(MPI_Aint orgdisp, int orgcnt, MPI_Datatype orgtype, int rank,
+    int winIget(MPI_Aint orgdisp, int orgcnt, MPI_Datatype orgtype, int rank,
                MPI_Aint targdisp, int targcnt, MPI_Datatype targtype, WinStruct win, 
               MPI_Request *req);
-    int winIGetWait(MPI_Request *request, MPI_Status *status);
-    int winIGetFree(MPI_Request *request, MPI_Status *status);
+    int winIgetWait(MPI_Request *request, MPI_Status *status);
+    int winIgetFree(MPI_Request *request, MPI_Status *status);
     void winRemotePut(int orgtotalsize, char* orgaddr, int orgcnt, MPI_Datatype orgtype,
                      MPI_Aint targdisp, int targcnt, MPI_Datatype targtype, 
                      int winIndex, CkFutureID ftHandle, int pe_src);
     void winRemoteGet(int orgcnt, MPI_Datatype orgtype, MPI_Aint targdisp, 
                      int targcnt, MPI_Datatype targtype, 
                      int winIndex, CkFutureID ftHandle, int pe_src);
-    AmpiMsg* winRemoteIGet(int orgdisp, int orgcnt, MPI_Datatype orgtype, MPI_Aint targdisp,
+    AmpiMsg* winRemoteIget(int orgdisp, int orgcnt, MPI_Datatype orgtype, MPI_Aint targdisp,
                           int targcnt, MPI_Datatype targtype, int winIndex);
     int winLock(int lock_type, int rank, WinStruct win);
     int winUnlock(int rank, WinStruct win);
@@ -1557,13 +1557,13 @@ friend class SReq;
     win_obj* getWinObjInstance(WinStruct win); 
     int getNewSemaId(); 
 
-    AmpiMsg* Alltoall_RemoteIGet(int disp, int targcnt, MPI_Datatype targtype, int tag);
+    AmpiMsg* Alltoall_RemoteIget(int disp, int targcnt, MPI_Datatype targtype, int tag);
 private:
     int AlltoallGetFlag;
     void *Alltoallbuff;
 public:
-    void setA2AIGetFlag(void* ptr) {AlltoallGetFlag=1;Alltoallbuff=ptr;}
-    void resetA2AIGetFlag() {AlltoallGetFlag=0;Alltoallbuff=NULL;} 
+    void setA2AIgetFlag(void* ptr) {AlltoallGetFlag=1;Alltoallbuff=ptr;}
+    void resetA2AIgetFlag() {AlltoallGetFlag=0;Alltoallbuff=NULL;}
     //------------------------ End of code by YAN ---------------------
 };
 
index 5bb4bd957ebdb88ec592e39364dd147bf14c74e4..59265f1e458a5503bcad7b78660c309f950f6283 100644 (file)
@@ -8,11 +8,16 @@ int main(int argc, char **argv) {
   int i;
   double a[2]={.1,.3},b[2]={.5,.7};
   MPI_Status sts;
+  MPI_Info hints;
 
   MPI_Init(&argc, &argv);
   MPI_Comm_rank(MPI_COMM_WORLD,&myrank);
   MPI_Comm_size(MPI_COMM_WORLD,&size);
 
+  /* Set up MPI_Info hints for AMPI_Migrate() */
+  MPI_Info_create(&hints);
+  MPI_Info_set(hints, "ampi_checkpoint", "to_file=log");
+
   for(step=0;step<6;step++){
     leftnbr = (myrank+size-1)%size;
     rightnbr = (myrank+1)%size;
@@ -20,10 +25,10 @@ int main(int argc, char **argv) {
     MPI_Recv(b,2,MPI_DOUBLE,leftnbr,0,MPI_COMM_WORLD,&sts);
     if(myrank==0) printf("[%d]step %d,a={%f,%f},b={%f,%f}\n",myrank,step,a[0],a[1],b[0],b[1]);
     if(step==2){
-      MPI_Checkpoint("log");
+      AMPI_Migrate(hints);
     }
   }
-  
+
   MPI_Finalize();
   return 0;
 }
index 2289cac20a637bbd990e065b8cb94b184f2ab239..db5c876bf23c2b23c708f4248f1b7443907c7663 100644 (file)
@@ -1,13 +1,19 @@
+-include ../../common.mk
 CHARMC=../../../bin/charmc $(OPTS)
 
-pgm: test.o
-       $(CHARMC) -o pgm test.o -language ampif
+all: pgm
 
-test.o: test.f90
-       $(CHARMC) -c test.f90
+pgm: pgm.o
+       $(CHARMC) -o pgm pgm.o -language ampif
+
+pgm.o: pgm.f90
+       $(CHARMC) -c pgm.f90
 
 #
 # clean up .o, .mod, .exe and EMACS backup files
 #
 clean:
        rm -f *.o *.mod pgm *~ conv-host charmrun
+
+test: pgm
+       $(call run, ./pgm +p2 +vp4 )
diff --git a/tests/ampi/fallreduce/pgm.f90 b/tests/ampi/fallreduce/pgm.f90
new file mode 100644 (file)
index 0000000..2c0aeef
--- /dev/null
@@ -0,0 +1,40 @@
+subroutine MPI_Main
+  implicit none
+  include 'mpif.h'
+
+  integer :: myrank, ierr, numranks, req
+  double precision :: inval, outval, expect
+
+  call MPI_Init(ierr)
+  call MPI_Comm_rank(MPI_COMM_WORLD, myrank, ierr)
+  call MPI_Comm_size(MPI_COMM_WORLD, numranks, ierr)
+
+  inval = myrank + 1
+  expect = (numranks*(numranks+1))/2
+
+  call MPI_Allreduce(inval, outval, 1, MPI_DOUBLE_PRECISION, MPI_SUM, &
+                     MPI_COMM_WORLD, ierr)
+
+  if (myrank .eq. 0) then
+    if (outval .eq. expect) then
+      print *, 'MPI_Allreduce test passes'
+    else
+      print *, 'MPI_Allreduce test failed'
+    end if
+  end if
+
+  call MPI_Iallreduce(inval, outval, 1, MPI_DOUBLE_PRECISION, MPI_SUM, &
+                      MPI_COMM_WORLD, req, ierr)
+
+  if (myrank .eq. 0) then
+    call MPI_Wait(req, MPI_STATUS_IGNORE, ierr)
+    if (outval .eq. expect) then
+      print *, 'MPI_Iallreduce test passes'
+    else
+      print *, 'MPI_Iallreduce test failed'
+    end if
+  end if
+
+  call MPI_Finalize(ierr)
+
+end subroutine
diff --git a/tests/ampi/fallreduce/test.f90 b/tests/ampi/fallreduce/test.f90
deleted file mode 100644 (file)
index b8886f4..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-recursive subroutine MPI_Main
-  implicit none
-  include 'mpif.h'
-
-  integer :: thisIndex, ierr, nblocks, i
-  double precision :: inval, outval, expect
-
-  call MPI_Init(ierr)
-  call MPI_Comm_rank(MPI_COMM_WORLD, thisIndex, ierr)
-  call MPI_Comm_size(MPI_COMM_WORLD, nblocks, ierr)
-
-  inval = thisIndex + 1
-  call MPI_Allreduce(inval, outval, 1, MPI_DOUBLE_PRECISION, MPI_SUM, &
-&                     MPI_COMM_WORLD, ierr)
-
-  expect = (nblocks*(nblocks+1))/2
-  if (outval .eq. expect) then
-    call MPI_Print('allreduce test passed',21)
-  else
-    call MPI_Print('allreduce test failed',21)
-  end if
-  call MPI_Finalize(ierr)
-
-end subroutine
index da992fc64d00ef9a3cde81022fa585bd1a9e0bf4..7065fb908c8feaac33f9778cd999a235e3c39dff 100644 (file)
@@ -109,8 +109,9 @@ static void copyin(double *d, double t[DIMX+2][DIMY+2][DIMZ+2],
 int main(int ac, char** av)
 {
   int i,j,k,m,cidx;
-  int iter, niter;
+  int iter, niter, cp_idx;
   MPI_Status status;
+  MPI_Info hints;
   double error, tval, maxerr, tmpmaxerr, starttime, endtime, itertime;
   chunk *cp;
   int thisIndex, ierr, nblocks;
@@ -137,6 +138,11 @@ int main(int ac, char** av)
   else
     niter = 20;
 
+  /* Set up MPI_Info hints for AMPI_Migrate() */
+  MPI_Info_create(&hints);
+  MPI_Info_set(hints, "ampi_checkpoint", "in_memory");
+  MPI_Info_set(hints, "ampi_checkpoint", "message_logging");
+
   MPI_Bcast(&niter, 1, MPI_INT, 0, MPI_COMM_WORLD);
 
 #if CMK_AIX
@@ -145,7 +151,7 @@ int main(int ac, char** av)
   cp = new chunk;
 #endif
 #if defined(AMPI) && ! defined(NO_PUP)
-  MPI_Register((void*)&cp, (MPI_PupFn) chunk_pup);
+  AMPI_Register_pup((MPI_PupFn)chunk_pup, (void*)&cp, &cp_idx);
 #endif
 
   index3d(thisIndex, cp->xidx, cp->yidx, cp->zidx);
@@ -228,11 +234,7 @@ int main(int ac, char** av)
     starttime = MPI_Wtime();
 #ifdef AMPI
     if(iter%CKPT_FREQ == 50) {
-#ifdef CMK_MEM_CHECKPOINT
-               AMPI_MemCheckpoint();
-#elif CMK_MESSAGE_LOGGING
-               MPI_Migrate();
-#endif
+               AMPI_Migrate(hints);
     }
 #endif
   }
index 67548b7c5d16884735bfaebe3b48b22ad0bfd113..18e4f446295289c67d744ca15684a4e5fea2b240 100644 (file)
@@ -242,6 +242,10 @@ void MPI_Tester::drain(void) {
 void MPI_Tester::testMigrate(void) {
        beginTest(2,"Migration");
        int srcPe=CkMyPe();
+    MPI_Info hints;
+
+    MPI_Info_create(&hints);
+    MPI_Info_set(hints, "ampi_load_balance", "true");
        
        // Before migrating, send a message to the next guy:
        //    this tests out migration with pending messages
@@ -250,7 +254,7 @@ void MPI_Tester::testMigrate(void) {
        TEST_MPI(MPI_Send,(&dest,1,MPI_INT, dest,tag,comm));
        TEST_MPI(MPI_Barrier,(comm));
        
-       MPI_Migrate();
+       AMPI_Migrate(hints);
        
        TEST_MPI(MPI_Barrier,(comm));
        int recv=-1; MPI_Status sts;
index 55030fc3a801a0e09bd3619449e62d1b1bf762cb..809336d359e358f9fd70f69258a9c0fdc9182438 100644 (file)
@@ -13,7 +13,7 @@ int main(int argc,char **argv)
 
   int rank;            /* process id */
   int p;                /* number of processes */
-  
+
   MPI_Init( &argc, &argv );
   MPI_Comm_rank( MPI_COMM_WORLD, &rank);
   MPI_Comm_size( MPI_COMM_WORLD, &p );
@@ -36,7 +36,7 @@ int main(int argc,char **argv)
               "CkMyPe() is %d, migrate_test is %d\n",
               rank, CkMyPe(), migrate_test);
        //fflush(stdout);
-       AMPI_Migrateto(destination_pe);
+       AMPI_Migrate_to_pe(destination_pe);
        printf("Leaving TCHARM_Migrate_to, "
                "FEM_My_partition is %d, "
               "CkMyPe() is %d, migrate_test is %d\n",