Adding a section on interoperability
[charm.git] / doc / charm++ / mpi-interop.tex
1 Libraries written in Charm++ can also be used with pure MPI programs. Currently this
2 functionality is supported only if Charm 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 Charm-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 Charm: \\
13
14 {\bf void CharmLibInit(MPI\_Comm newComm, int argc, char **argv)}\\
15
16 \noindent Here, {\em newComm} is the MPI communicator that Charm 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 Charm instance. Different MPI ranks that belong to different communicators can 
20 make this call independently, and separate Charm 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 Charm 
22 instance. Arguments {\em argc and argv} should contain the information required by Charm 
23 such as the load balancing strategy etc.
24
25 During the initialization the control is transferred from MPI to Charm
26 RTS on the MPI ranks that made the call. Along with basic setup, Charm 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 Charm initialization is made via a function call from the pure MPI
30 program, Charm resides in the same memory space as the pure MPI program. This
31 makes transfer of data from MPI to Charm convenient (using pointers).
32
33 \section{Writing Interoperable Charm Libraries}
34 Minor modifications are required to make a Charm program interoperable with a pure
35 MPI program:
36 \begin{itemize}
37 \item An interoperable Charm library should not contain a main module.
38 \item {\em CkExit} should be used as one uses {\em return} statement 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 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 Charm RTS. Examples of such interface functions in can be found in hi
53 (HiStart), hello (HelloStart) and kNeighbor (kNeighbor) directories in 
54 examples/charm++/mpi-coexist/libs. Note that a scheduler call {\em
55 CsdScheduler(-1)} should be made from the interface functions to start the
56 message reception by Charm RTS.
57 \end{itemize}
58
59 \section{Writing Interoperable MPI Programs}
60 An MPI program that invokes Charm libraries should include {\em mpi-interoperate.h}. 
61 As mentioned earlier, an initialization call, {\em CharmLibInit} is 
62 required after invoking MPI\_Init to perform the initial set up of Charm. 
63 It is advisable to call an MPI\_Barrier after a control transfer between Charm 
64 and MPI to avoid any side effects. Thereafter, a Charm library can be invoked at
65 any point using the interface functions. One may look at
66 examples/charm++/mpi-coexist/multirun.cpp for a working example. Based on the
67 way interfaces are defined, a library can be invoked multiple times. In the end,
68 one should call {\em CharmLibExit} to free resources reserved by Charm.
69
70 \section{Compilation}
71 An interoperable Charm library can be compiled as usual using {\em charmc}.
72 Instead of producing an executable in the end, one should create a library (*.a)
73 as shown in examples/charm++/mpi-coexist/libs/hi/Makefile. The compilation
74 process of the MPI program, however, needs modification. One has to include the
75 charm directory (-I\$(CHARMDIR)/include) to help the compiler find the location of
76 included {\em mpi-interoperate.h}. The linking step to create the executable
77 should be done using {\em charmc}, which in turn uses the compiler used to build
78 charm. In the linking step, it is required to pass {\em -mpi} as an argument
79 because of which {\em charmc} performs the linking for interoperation. The charm
80 libraries, which one wants to be linked, should be passed using {\em -module}
81 option. Refer to examples/charm++/mpi-coexist/Makefile to view a working
82 example.
83
84