doc: minor cleanup in modules section
[charm.git] / doc / charm++ / modules.tex
1 \subsection{Program and File Structure}
2
3 A \charm program is essentially a \CC program where some components describe
4 its parallel structure. Sequential code can be written using any programming
5 technologies that cooperate with the \CC toolchain. This includes C and
6 Fortran. Parallel entities in the user's code are written in \CC{}. These
7 entities interact with the \charm framework via inherited classes and function
8 calls.
9
10
11 \subsubsection{.ci Files}
12 \index{ci}
13 All user program components that comprise its parallel interface (such as
14 messages, chares, entry methods, etc.) are granted this elevated status by
15 declaring or describing them in separate \emph{charm interface} description
16 files. These files have a \emph{.ci} suffix and adopt a \CC-like declaration
17 syntax with several additional keywords. In some declaration contexts, they
18 may also contain some sequential \CC source code.
19 %that is embedded unmodified into the generated code.
20 \charm parses these interface descriptions and generates \CC code (base
21 classes, utility classes, wrapper functions etc.) that facilitates the
22 interaction of the user program's entities with the framework.  A program may
23 have several interface description files.
24
25
26 \subsubsection{Modules}
27 \index{module}
28 The top-level construct in a \ci file is a named container for interface
29 declarations called a \kw{module}. Modules allow related declarations to be
30 grouped together, and cause generated code for these declarations to be grouped
31 into files named after the module. Modules cannot be nested, but each \ci file
32 can have several modules. Modules are specified using the keyword \kw{module}.
33
34 \begin{alltt}
35 module myFirstModule \{
36     // Parallel interface declarations go here
37     ...
38 \};
39 \end{alltt}
40
41
42 \subsubsection{Generated Files}
43 \index{decl}\index{def}
44
45 Each module present in a \ci file is parsed to generate two files. The basename
46 of these files is the same as the name of the module and their suffixes are
47 \emph{.decl.h} and \emph{.def.h}. For e.g., the module defined earlier will
48 produce the files ``myFirstModule.decl.h'' and ``myFirstModule.def.h''. As the
49 suffixes indicate, they contain the declarations and definitions respectively,
50 of all the classes and functions that are generated based on the parallel
51 interface description.
52
53 We recommend that the header file containing the declarations (decl.h) be
54 included at the top of the files that contain the declarations or definitions
55 of the user program entities mentioned in the corresponding module. The def.h
56 is not actually a header file because it contains definitions for the generated
57 entities. To avoid multiple definition errors, it should be compiled into just
58 one object file. A convention we find useful is to place the def.h file at the
59 bottom of the source file (.C, .cpp, .cc etc.) which includes the definitions
60 of the corresponding user program entities.
61
62 \experimental
63 It should be noted that the generated files have no dependence on the name of the \ci
64 file, but only on the names of the modules. This can make automated dependency-based
65 build systems slightly more complicated. We adopt some conventions to ease this process.
66 This is described in~\ref{AppendixSectionDescribingPhilRamsWorkOnCi.stampAndCharmc-M}.
67
68
69 \subsubsection{Module Dependencies}
70 \index{extern}
71
72 A module may depend on the parallel entities declared in another module. It can
73 express this dependency using the \kw{extern} keyword. \kw{extern}ed modules
74 do not have to be present in the same \ci file.
75
76 \begin{alltt}
77 module mySecondModule \{
78
79     // Entities in this module depend on those declared in another module
80     extern module myFirstModule;
81
82     // More parallel interface declarations
83     ...
84 \};
85 \end{alltt}
86
87 The \kw{extern} keyword places an include statement for the decl.h file of the
88 \kw{extern}ed module in the generated code of the current module. Hence,
89 decl.h files generated from \kw{extern}ed modules are required during the
90 compilation of the source code for the current module. This is usually required
91 anyway because of the dependencies between user program entities across the two
92 modules.
93
94 \subsubsection{The Main Module and Reachable Modules}
95 \index{mainmodule}
96
97 \charm software can contain several module definitions from several
98 independently developed libraries / components. However, the user program must
99 specify exactly one module as containing the starting point of the program's
100 execution. This module is called the \kw{mainmodule}. Every \charm program
101 has to contain precisely one \kw{mainmodule}.
102
103 All modules that are ``reachable'' from the \kw{mainmodule} via a chain of
104 \kw{extern}ed module dependencies are included in a \charm program. More
105 precisely, during program execution, the \charm runtime system will recognize
106 only the user program entities that are declared in reachable modules. The
107 decl.h and def.h files may be generated for other modules, but the runtime
108 system is not aware of entities declared in such unreachable modules.
109
110 \begin{alltt}
111 module A \{
112     ...
113 \};
114
115 module B \{
116     extern module A;
117     ...
118 \};
119
120 module C \{
121     extern module A;
122     ...
123 \};
124
125 module D \{
126     extern module B;
127     ...
128 \};
129
130 module E \{
131     ...
132 \};
133
134 mainmodule M \{
135     extern module C;
136     extern module D;
137     // Only modules A, B, C and D are reachable and known to the runtime system
138     // Module E is unreachable via any chain of externed modules
139     ...
140 \};
141 \end{alltt}
142
143
144 \subsubsection{Including other headers}
145 \index{include}
146
147 There can be occasions where code generated from the module definitions
148 requires other declarations / definitions in the user program's sequential
149 code. Usually, this can be achieved by placing such user code before the point
150 of inclusion of the decl.h file. However, this can become laborious if the
151 decl.h file has to included in several places. \charm supports the keyword
152 \kw{include} in \ci files to permit the inclusion of any header directly into
153 the generated decl.h files.
154
155 \begin{alltt}
156 module A \{
157     include "myUtilityClass.h"; //< Note the semicolon
158     // Interface declarations that depend on myUtilityClass
159     ...
160 \};
161
162 module B \{
163     include "someUserTypedefs.h";
164     // Interface declarations that require user typedefs
165     ...
166 \};
167
168 module C \{
169     extern module A;
170     extern module B;
171     // The user includes will be indirectly visible here too
172     ...
173 \};
174 \end{alltt}
175
176
177 \subsubsection{main()}
178
179 The \charmpp framework implements its own main\(\) function and retains control
180 until the parallel execution environment is initialized and ready for executing
181 user code. Hence, the user program must not define a \emph{main()} function.
182 Control enters the user code via the \kw{mainchare} of the \kw{mainmodule}.
183 This will be discussed in further detail in~\ref{mainchare}.
184
185 Using the facilities described thus far, the parallel interface declarations
186 for a \charm program can be spread across multiple ci files and multiple
187 modules, permitting good control over the grouping and export of parallel API.
188 This aids the encapsulation of parallel software.
189
190 \zap{
191 A simple \charmpp\ program is given below:
192
193 \begin{alltt}
194 ///////////////////////////////////////
195 // File: pgm.ci
196
197 mainmodule Hello \{
198   readonly CProxy_HelloMain mainProxy;
199   mainchare HelloMain \{
200     entry HelloMain(); // implicit CkArgMsg * as argument
201     entry void PrintDone(void);
202   \};
203   group HelloGroup \{
204     entry HelloGroup(void);
205   \};
206 \};
207
208 ////////////////////////////////////////
209 // File: pgm.h
210 #include "Hello.decl.h" // Note: not pgm.decl.h
211
212 class HelloMain : public CBase_HelloMain \{
213   public:
214     HelloMain(CkArgMsg *);
215     void PrintDone(void);
216   private:
217     int count;
218 \};
219
220 class HelloGroup: public Group \{
221   public:
222     HelloGroup(void);
223 \};
224
225 /////////////////////////////////////////
226 // File: pgm.C
227 #include "pgm.h"
228
229 CProxy_HelloMain mainProxy;
230
231 HelloMain::HelloMain(CkArgMsg *msg) \{
232   delete msg;
233   count = 0;
234   mainProxy = thisProxy;
235   CProxy_HelloGroup::ckNew(); // Create a new "HelloGroup"
236 \}
237
238 void HelloMain::PrintDone(void) \{
239   count++;
240   if (count == CkNumPes()) \{ // Wait for all group members to finish the printf
241     CkExit();
242   \}
243 \}
244
245 HelloGroup::HelloGroup(void) \{
246   ckout << "Hello World from processor " << CkMyPe() << endl;
247   mainProxy.PrintDone();
248 \}
249
250 #include "Hello.def.h" // Include the Charm++ object implementations
251
252 /////////////////////////////////////////
253 // File: Makefile
254
255 pgm: pgm.ci pgm.h pgm.C
256       charmc -c pgm.ci
257       charmc -c pgm.C
258       charmc -o pgm pgm.o -language charm++
259
260 \end{alltt}
261
262 \uw{HelloMain} is designated a \kw{mainchare}. Thus the Charm RTS starts
263 execution of this program by creating an instance of \uw{HelloMain} on
264 processor 0. The HelloMain constructor creates a chare group
265 \uw{HelloGroup}, and stores a handle to itself and returns. The call to
266 create the group returns immediately after directing Charm RTS to perform
267 the actual creation and invocation.  Shortly after, the Charm RTS will
268 create an object of type \uw{HelloGroup} on each processor, and call its
269 constructor. The constructor will then print ``Hello World...'' and then
270 call the \uw{PrintDone} method of \uw{HelloMain}. The \uw{PrintDone} method
271 calls \kw{CkExit} after all group members have called it (i.e., they have
272 finished printing ``Hello World...''), and the \charmpp program exits.
273
274 \subsubsection{Functions in the ``decl.h'' and ``def.h'' files}
275
276 The \texttt{decl.h} file provides declarations for the proxy classes of the
277 concurrent objects declared in the ``.ci'' file (from which the \texttt{decl.h}
278 file is generated). So the \uw{Hello.decl.h} file will have the declaration of
279 the class CProxy\_HelloMain. Similarly it will also have the declaration for
280 the HelloGroup class. 
281
282 This class will have functions to create new instances of the chares and
283 groups, like the function \kw{ckNew}. For \uw{HelloGroup} this function creates
284 an instance of the class \uw{HelloGroup} on all the processors. 
285
286 The proxy class also has functions corresponding to the entry methods defined
287 in the ``.ci'' file. In the above program the method wait is declared in
288 \uw{CProxy\_HelloMain} (proxy class for \uw{HelloMain}).
289
290 The proxy class also provides static registration functions used by the
291 \charmpp{} runtime.  The \texttt{def.h} file has a registration function
292 (\uw{\_\_registerHello} in the above program) which calls all the registration
293 functions corresponding to the readonly variables and entry methods declared in
294 the module.
295 } % end zap
296