Adding Esteban's suggestion to Interoperability section
[charm.git] / doc / charm++ / mpi-interop.tex
1 Libraries written in \charmpp{} can also be used with pure MPI programs. Currently this
2 functionality is supported only if \charmpp{} is built using MPI as the network layer
3 (e.g. mpi-linux-x86\_64 build). An example program to demonstrate the
4 interoperation is available in examples/charm++/mpi-coexist. We will be
5 referring to this example program for ease of understanding.
6
7 \section{Control Flow and Memory Structure}
8 The control flow and memory structure of a \charmpp{}-MPI interoperable program  is
9 similar to that of a pure MPI program that uses external MPI libraries. The
10 execution of program begins with pure MPI code's {\em main}. At some point after 
11 MPI\_Init() has been invoked, the following function call should be made to initialize
12 \charmpp{}: \\
13
14 {\bf void CharmLibInit(MPI\_Comm newComm, int argc, char **argv)}\\
15
16 \noindent Here, {\em newComm} is the MPI communicator that \charmpp{} will use for
17 the setup and communication. All the MPI ranks that belong to {\em newComm} should 
18 make this call. A collection of MPI ranks that make the CharmLibInit call defines a 
19 new \charmpp{} instance. Different MPI ranks that belong to different communicators can 
20 make this call independently, and separate \charmpp{} instances (that are not aware of each other) 
21 will be created. As of now, a particular MPI rank can only be part of one unique \charmpp{} 
22 instance. Arguments {\em argc and argv} should contain the information required by \charmpp{} 
23 such as the load balancing strategy etc.
24
25 During the initialization the control is transferred from MPI to \charmpp{}
26 RTS on the MPI ranks that made the call. Along with basic setup, \charmpp{} RTS also invokes
27 the constructors of all mainchares during initialization. Once the intial set up
28 is done, control is transferred back to MPI as if returning from a function call. 
29 Since \charmpp{} initialization is made via a function call from the pure MPI
30 program, \charmpp{} resides in the same memory space as the pure MPI program. This
31 makes transfer of data from MPI to \charmpp{} convenient (using pointers).
32
33 \section{Writing Interoperable \charmpp{} Libraries}
34 Minor modifications are required to make a \charmpp{} program interoperable with a pure
35 MPI program:
36 \begin{itemize}
37 \item An interoperable \charmpp{} library should not contain a main module.
38 \item {\em CkExit} should be used the same way {\em return} statement is used for returning
39 back from a function call. It is advisable to make sure that only one chare
40 invokes {\em CkExit}.
41 \item Include {\em mpi-interoperate.h} - if not included, invoking {\em CkExit} will result 
42 in random output.
43 \item Since the CharmLibInit call invokes the constructors of mainchares, the
44 constructors of mainchares should only perform basic set up such as creation of chare
45 arrays etc. The set up should not result in invocation of actual work, which
46 should be done using interface functions (when desired from the pure MPI
47 program). One may avoid use of mainchares, and perform the necessary
48 initializations in an interface function as demonstrated in the interoperable
49 library examples/charm++/mpi-coexist/libs/hello.
50 \item Interface functions - Every library needs to define interface function(s) 
51 that can be invoked from pure MPI programs, and transfers the control to the 
52 \charmpp{} RTS. The interface functions are simple functions whose task is to
53 start work for the \charmpp{} libraries. Here is an example interface function for the
54 {\em hello} library. 
55 \begin{alltt}
56   void HelloStart(int elems)
57   \{
58     if(CkMyPe() == 0) \{
59       CkPrintf("HelloStart - Starting lib by calling constructor of MainHello\\n");
60       CProxy\_MainHello mainhello = CProxy\_MainHello::ckNew(elems);
61     \}
62     CsdScheduler(-1);
63   \}
64 \end{alltt}
65
66 This function creates a new chare (mainHello) defined in the {\em hello} library which
67 subsequently results in work being done in {\em hello} library.
68 More examples of such interface functions can 
69 be found in hi (HiStart) and kNeighbor (kNeighbor) directories in 
70 examples/charm++/mpi-coexist/libs. Note that a scheduler call {\em
71 CsdScheduler(-1)} should be made from the interface functions to start the
72 message reception by \charmpp{} RTS.
73 \end{itemize}
74
75 \section{Writing Interoperable MPI Programs}
76 An MPI program that invokes \charmpp{} libraries should include {\em mpi-interoperate.h}. 
77 As mentioned earlier, an initialization call, {\em CharmLibInit} is 
78 required after invoking MPI\_Init to perform the initial set up of \charmpp{}. 
79 It is advisable to call an MPI\_Barrier after a control transfer between \charmpp{} 
80 and MPI to avoid any side effects. Thereafter, a \charmpp{} library can be invoked at
81 any point using the interface functions. One may look at
82 examples/charm++/mpi-coexist/multirun.cpp for a working example. Based on the
83 way interfaces are defined, a library can be invoked multiple times. In the end,
84 one should call {\em CharmLibExit} to free resources reserved by \charmpp{}.
85
86 \section{Compilation}
87 An interoperable \charmpp{} library can be compiled as usual using {\em charmc}.
88 Instead of producing an executable in the end, one should create a library (*.a)
89 as shown in examples/charm++/mpi-coexist/libs/hi/Makefile. The compilation
90 process of the MPI program, however, needs modification. One has to include the
91 charm directory (-I\$(CHARMDIR)/include) to help the compiler find the location of
92 included {\em mpi-interoperate.h}. The linking step to create the executable
93 should be done using {\em charmc}, which in turn uses the compiler used to build
94 charm. In the linking step, it is required to pass {\em -mpi} as an argument
95 because of which {\em charmc} performs the linking for interoperation. The charm
96 libraries, which one wants to be linked, should be passed using {\em -module}
97 option. Refer to examples/charm++/mpi-coexist/Makefile to view a working
98 example.
99
100