f462a444d0574185a3285c30a0922921d078e27b
[charm.git] / doc / f90charm / manual.tex
1 \documentclass[11pt]{article}
2
3 \newif\ifpdf
4 \ifx\pdfoutput\undefined
5   \pdffalse
6 \else
7   \pdfoutput=1
8   \pdftrue
9 \fi
10
11 \ifpdf
12   \pdfcompresslevel=9
13   \usepackage[pdftex,colorlinks=true,plainpages=false]{hyperref}
14 \else
15 \fi
16
17 \pagestyle{headings}
18
19 \title{Fortran90 Bindings for Charm++}
20 \author{Gengbin Zheng, Jayant Desouza}
21
22 \begin{document}
23
24 \maketitle
25
26 To interface Fortran90 to Charm and thus obtain a parallel version of
27 your program you need to do the following things:
28 \begin{enumerate}
29 \item Write a Charm Interface file (extension .ci)
30 \item Write your F90 program with some constraints
31 \item Compile and Link with Charm's Fortran library
32 \item Run it !
33 \end{enumerate}
34
35 \section{Overview}
36
37 Here I suppose you've already known most concepts in charm++ and done some 
38 charm++ programing.  \\
39 Unlike in C++, we don't have class here in Fortran90. Thus, Chare is 
40 represented as a fortran type structure. Here is an example:
41
42 \begin{verbatim}
43
44       ## Just replace Hello throughout with your chare's name. ##
45       ## and add your chare's personal data below where indicated ##
46       ## Everything else remains the same ##
47       MODULE HelloMod
48
49       TYPE Hello
50       integer data
51       ## your chare's data goes here, the above integer is an example ##
52       END TYPE
53
54       TYPE HelloPtr
55       TYPE (Hello), POINTER ::  obj
56       integer*8 aid
57       END TYPE
58
59       END MODULE
60 \end{verbatim}
61 You can think of this module as a chare declaration. Type Hello defines 
62 arbitary user private data and HelloPtr defines the Chare pointer which 
63 fortran program will use later to communicate with the f90charm runtime 
64 library. \\
65 As same in C++ charm program, you need to write a .ci interface file
66 so that charm translator will generate some helper functions. However, for
67 Fortran90 charm, the syntax is a little different. First, it only support
68 Chare array, you cannot define Chare and Group types. Second, for the 
69 message declaration, you must list all the data fields explicitly.
70 By this, the translator generated helper functions will know the contents
71 of the messages and do the message marshalling and unmarshalling for 
72 the fortran program. 
73
74 For each Chare defined in the .ci file, you must define these functions
75 for charm++ runtime use:
76
77   \verb+SUBROUTINE <ChareName>_allocate(objPtr, aid)+
78
79   this function will allocate the chare user data.
80 And for each chare entry method, you should define the fortran90 subroutine
81 for it:
82
83   \verb+SUBROUTINE entry(charePtr, myIndex, data1, data2 ... )+
84
85   Note, the first argument is the Chare pointer as you declared previously, the second argument is the array index which will be passed from charm runtime. And you need to enumerate all the message fields declared in .ci file in the 
86 subroutine.
87
88 On the other side, for each Chare declared, these subroutines are available
89 for use in Fortran90 program:
90
91   \verb+<ChareName>_CkNew(integer n, integer*8 aid)+
92
93   This subroutine creates the chare array.
94
95 And for each entry method, this function is available for use:
96
97   \verb+SendTo_<ChareName>_<Entry>(charePtr, myIndex, data1, data2 ... )+
98   This subroutine will send a message to the array element with the index
99 as myIndex. Fortran90 charm runtime will pack the parameters into a message
100 and sent to the chare array element.
101
102 There are several others things you need to know.
103
104 First, as same in C++ Charm, each .ci file will generate two header files:
105 .decl.h and .def.h. However, in Fortran90 charm, you cannot use these C++
106 files in Fortran90 code. Thus, currently, it is user's responsibility to 
107 write a simple C++ code to include these two headers files. This is as simple
108 as this:
109
110 \begin{verbatim}
111 #include "hello.decl.h"
112 int chunkSize;  // readonly variables define here
113 #include "hello.def.h"
114 \end{verbatim}
115
116 Second, you can still use readonly variables as in Charm++. However, since
117 fortran90 lacks the concepts of global variables as in C, you have to use it
118 explicitly. Here are the two helper functions that translator generates:
119 take the chunkSize as an example,
120 \begin{verbatim}
121 Set_Chunksize(chunkSize);
122 Get_Chunksize(chunkSize);
123 \end{verbatim}
124 These two functions can be used in user's fortran program to set and get 
125 readonly variables.
126
127 Third, for user's convenience, several charm++ runtime library functions
128 have their Fortran interface defined in f90charm library. These currently
129 include:
130 \begin{verbatim}
131 CkExit()
132 CkMyPe(integer mype)
133 CkNumPes(integer pes)
134 CkPrintf(...)    // note, the format string must terminated with '$$'
135 \end{verbatim}
136
137 All these are best explained with an example: the hello program.  It is a
138 simple ring program.  When executed, an array of several parallel
139 CHAREs is created.  Each chare "says" hello when it receives a
140 message, and then sends a message to the next chare.  The Fortran main() 
141 subroutine starts off the events.  And the SayHi() subroutine does the 
142 say-hello and forward.
143
144 \section{Writing F90 Program}
145 To start, you need to create a Fortran Module to represent a chare,
146 e.g. \{ChareName\}Mod.
147
148 \begin{verbatim}
149
150       ## Just replace Hello throughout with your chare's name. ##
151       ## and add your chare's personal data below where indicated ##
152       ## Everything else remains the same ##
153       MODULE HelloMod
154
155       TYPE Hello
156       integer data
157       ## your chare's data goes here, the above integer is an example ##
158       END TYPE
159
160       TYPE HelloPtr
161       TYPE (Hello), POINTER ::  obj
162       integer*8 aid
163       END TYPE
164
165       END MODULE
166 \end{verbatim}
167
168 In the Fortran file you must write an allocate funtion for this chare
169 with the name: \{ChareName\}\_allocate.
170
171 \begin{verbatim}
172       ## Just replace Hello throughout with your chare's name. ##
173       ## Everything else remains the same ##
174       SUBROUTINE Hello_allocate(objPtr, aid)
175       USE HelloMod
176       TYPE(HelloPtr) objPtr 
177       integer*8 aid
178
179       allocate(objPtr%obj)
180       objPtr%aid = aid;
181       END SUBROUTINE
182 \end{verbatim}
183
184 If you have written code for a chare array "Hello", as above, you will
185 have the following subroutine available to you:
186
187   \verb+<ChareName>_CkNew(integer n, integer*8 aid)+
188      This function creates a chare array at runtime
189      where n is the number of items in the array, and
190            aid is the array ID which is returned to you.
191
192 We will see an example of using this function below.
193
194 \section{Writing Charm++ Interface File}
195
196 Now that you have the chare, you need to write one or more ENTRY
197 POINTs for it.  This is nothing but a Fortran subroutine that uses the
198 above module.
199 \begin{verbatim}
200       ## p1, p2, etc represent user parameters
201       ## the "objPtr, myIndex" stuff is required in every Entry Point.
202       ## CkExit() must be called by the chare to terminate.
203       SUBROUTINE SayHi(objPtr, myIndex, p1)
204       USE HelloMod
205       IMPLICIT NONE
206
207       TYPE(HelloPtr) objPtr
208       integer myIndex
209       integer p1
210
211       objPtr%obj%data = 20
212       if (myIndex < 4) then
213           call SendTo_Hello_SayHi(objPtr%aid, myIndex+1, 1);
214       else 
215           call CkExit()
216       endif
217 \end{verbatim}
218 Once you have written code for an Entry Point, you now have available
219 to you the following subroutine:
220 \begin{verbatim}
221    SendTo_<ChareName>_<SubroutineName>(integer*8 aid, integer myIndex,
222                           other parameters ....)
223      where aid is the target chare array ID
224            myIndex is the specific within the array
225                    we wish to send a message to
226            other parameters are the parameters in the above function.
227 \end{verbatim}
228
229 \section{Compile and Link}
230 You must have a Fortran f90charmmain() subroutine where execution starts.
231 Typically this main function will create a chare array and send a
232 message to one of its members to get the computation started.
233 \begin{verbatim}
234       SUBROUTINE f90charmmain()
235       USE HelloMod
236       integer i
237       integer*8 aid
238
239       print *, "hello"
240
241       call Hello_CkNew(5, aid)
242
243       call SendTo_Hello_SayHi(aid, 0, 1);
244
245       END
246 \end{verbatim}
247 \section{Writing Charm++ Interface File}
248 Now we move on to Step 2, the Charm Interface file.  This file must
249 have a different name from the Fortran file, and must have an
250 extension of .ci, e.g. if the above Fortran file is hellof.f90, this
251 file could be called hello.ci.  Basically, its purpose is to tell
252 Charm what you've done in the Fortran file, since Charm cannot read
253 Fortran as of now.
254 \begin{verbatim}
255       ## Just replace Hello throughout with your chare's name. ##
256       ## and add your chare's entry points below where indicated ##
257       ## Everything else remains the same ##
258       mainmodule hello {
259       
260         // Create some arbitrary message to hold your parameters
261         // The message must have a unique name for each Entry Point.
262         message HiMsg { int } ;
263       
264         array Hello {
265           entry Hello();
266
267           // Note how your Fortran function takes the above defined
268           // message instead of a list of parameters.
269           entry void SayHi(HiMsg *);
270
271           // Other entry points go here
272
273         };              
274       };
275 \end{verbatim}
276 If the function has more parameters: e.g. A Fortran function FF(int,
277 int, long) in module H, would be described in the .ci file as:
278 \begin{verbatim}
279   message MarshalParams { int, int, long };
280   array H {
281     entry H();
282     entry void FF(MarshalParams *);
283   }
284 \end{verbatim}
285 As mentioned above, the message must have a unique name.
286
287 \section{Compile and Link}
288 Lastly, you need to compile and link the Fortran program with the
289 Charm program as follows: (Let's say you have written hellof.f90, 
290 hello.ci and hello.C)
291 \begin{verbatim}
292   charmc hello.ci -language f90charm
293 \end{verbatim}
294     will create hello.decl.h, hello.def.h
295
296 \begin{verbatim}
297   charmc -c hello.C
298 \end{verbatim}
299     will compile the hello.decl.h, hello.def.h.
300
301 \begin{verbatim}
302   charmc -c hellof.f90
303 \end{verbatim}
304     charmc will invoke fotran compiler;
305
306 \begin{verbatim}
307   charmc -o hello hello.o hellof.o -language f90charm
308 \end{verbatim}
309     will link hellof.o, hello.o and Charm's Fortran library
310     to create your executable program 'hello'.
311
312 \section{Run Program}
313
314 Finally, to run the program, make sure you have a nodelist file called
315 "nodelist" and containing, for example,
316
317 group main
318 host <computername>.cs.uiuc.edu <login>
319
320 and then type
321
322 ./charmrun +p2 hello
323
324 which will run 'hello' on two virtual processors.
325 \end{document}