improved f90charm manual, explained some new features and constraints in more details.
[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++\footnote{last modified 3/3/2001 by Gengbin Zheng}}
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++ programming.  \\
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       ## your chare's data goes here, the integer below is an example ##
51       integer data
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 helper functions. However, for
67 Fortran90 charm, the syntax is a little different. First, it only support
68 Chare array(1D currently), you cannot define Chare and Group types. Second, 
69 for the message declaration, you must list all the data fields explicitly in
70 .ci files.  By this, the helper functions generated by translator know the 
71 contents of the messages and thus can do the message marshalling and 
72 unmarshalling for the fortran program. 
73
74 For each Chare defined in the .ci file, user must write these functions
75 for charm++ f90 runtime:
76
77   \verb+SUBROUTINE <ChareName>_allocate(objPtr, aid, index)+
78
79   You can think of this function as a constructor for each array element 
80 with array index [index]. In this function user must allocate memory for 
81 the Chare's user data. User can also initialize the data.       \\
82   For each chare entry method, you should write the fortran90 subroutine
83 for it:
84
85   \verb+SUBROUTINE entry(charePtr, myIndex, data1, data2 ... )+
86
87   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 
88 subroutine.
89
90 On the other side, for each Chare declared in .ci files, these subroutines are 
91 available for user to call in Fortran90 program:
92
93   \verb+<ChareName>_CkNew(integer n, integer*8 aid)+
94
95   This subroutine creates the chare array.
96
97 And for each entry method, this function is available for use:
98
99   \verb+SendTo_<ChareName>_<Entry>(charePtr, myIndex, data1, data2 ... )+
100
101   This subroutine will send a message to the array element with the index
102 as myIndex. Fortran90 charm runtime will pack the parameters into a message
103 and sent to the chare array element.
104
105 There are several others things you need to know.
106
107 First, as same in C++ Charm, each .ci file will generate two header files:
108 .decl.h and .def.h. However, in Fortran90 charm, you are not able to include 
109 these C++ files in Fortran90 code. Thus, currently, it is user's 
110 responsibility to write a simple C++ code to include these two headers files. 
111 You should also declare readonly variables in this file. This is as simple as 
112 this:
113
114 \begin{verbatim}
115 #include "hello.decl.h"
116 int chunkSize;  // readonly variables define here
117 #include "hello.def.h"
118 \end{verbatim}
119
120 In future, this file can be generated automatically by translator.
121 Second, you can still use readonly variables as in Charm++. However, since
122 fortran90 lacks the concepts of global variables as in C, you have to use it
123 explicitly. Here are the two helper functions that translator generates:
124 take the readonly variable chunkSize as an example,
125 \begin{verbatim}
126 Set_Chunksize(chunkSize);
127 Get_Chunksize(chunkSize);
128 \end{verbatim}
129 These two functions can be used in user's fortran program to set and get 
130 readonly variables.
131
132 Third, for user's convenience, several charm++ runtime library functions
133 have their Fortran interface defined in f90charm library. These currently
134 include:
135 \begin{verbatim}
136 CkExit()
137 CkMyPe(integer mype)
138 CkNumPes(integer pes)
139 CkPrintf(...)    // note, the format string must terminated with '$$'
140 \end{verbatim}
141
142 Here is a summary of current constraints to write f90 binding charm++ programs:
143 \begin{enumerate}
144 \item in .ci files, only 1D Chare array is supported.
145 \item messages defined in .ci files must be basic types or fixed size array.
146 \item readonly variables must be basic types.
147 \item instead of program main, your main program starts from subroutine 
148 f90charmmain.
149 \end{enumerate}
150
151 All these are best explained with an example: the hello program.  It is a
152 simple ring program.  When executed, an array of several parallel
153 CHAREs is created.  Each chare "says" hello when it receives a
154 message, and then sends a message to the next chare.  The Fortran main() 
155 subroutine starts off the events.  And the SayHi() subroutine does the 
156 say-hello and forward.
157
158 \section{Writing F90 Program}
159 To start, you need to create a Fortran Module to represent a chare,
160 e.g. \{ChareName\}Mod.
161
162 \begin{verbatim}
163
164       ## Just replace Hello throughout with your chare's name. ##
165       ## and add your chare's personal data below where indicated ##
166       ## Everything else remains the same ##
167       MODULE HelloMod
168
169       TYPE Hello
170       integer data
171       ## your chare's data goes here, the above integer is an example ##
172       END TYPE
173
174       TYPE HelloPtr
175       TYPE (Hello), POINTER ::  obj
176       integer*8 aid
177       END TYPE
178
179       END MODULE
180 \end{verbatim}
181
182 In the Fortran file you must write an allocate funtion for this chare
183 with the name: \{ChareName\}\_allocate.
184
185 \begin{verbatim}
186       ## Just replace Hello throughout with your chare's name. ##
187       ## Everything else remains the same ##
188       SUBROUTINE Hello_allocate(objPtr, aid, index)
189       USE HelloMod
190       TYPE(HelloPtr) objPtr 
191       integer*8 aid
192       integer index
193
194       allocate(objPtr%obj)
195       objPtr%aid = aid;
196       ## you can initialize the Chare user data here
197       objPtr%obj%data = index
198       END SUBROUTINE
199 \end{verbatim}
200
201 If you have written code for a chare array "Hello", as above, you will
202 have the following subroutine available to you:
203
204   \verb+<ChareName>_CkNew(integer n, integer*8 aid)+
205      This function creates a chare array at runtime
206      where n is the number of items in the array, and
207            aid is the array ID which is returned to you.
208
209 We will see an example of using this function below.
210
211 \section{Writing Charm++ Interface File}
212
213 Now that you have the chare, you need to write one or more ENTRY
214 POINTs for it.  This is nothing but a Fortran subroutine that uses the
215 above module.
216 \begin{verbatim}
217       ## p1, p2, etc represent user parameters
218       ## the "objPtr, myIndex" stuff is required in every Entry Point.
219       ## CkExit() must be called by the chare to terminate.
220       SUBROUTINE SayHi(objPtr, myIndex, p1)
221       USE HelloMod
222       IMPLICIT NONE
223
224       TYPE(HelloPtr) objPtr
225       integer myIndex
226       integer p1
227
228       objPtr%obj%data = 20
229       if (myIndex < 4) then
230           call SendTo_Hello_SayHi(objPtr%aid, myIndex+1, 1);
231       else 
232           call CkExit()
233       endif
234 \end{verbatim}
235 Once you have written code for an Entry Point, you now have available
236 to you the following subroutine:
237 \begin{verbatim}
238    SendTo_<ChareName>_<SubroutineName>(integer*8 aid, integer myIndex,
239                           other parameters ....)
240      where aid is the target chare array ID
241            myIndex is the specific within the array
242                    we wish to send a message to
243            other parameters are the parameters in the above function.
244 \end{verbatim}
245
246 \section{Compile and Link}
247 You must have a Fortran f90charmmain() subroutine where execution starts.
248 Typically this main function will create a chare array and send a
249 message to one of its members to get the computation started.
250 \begin{verbatim}
251       SUBROUTINE f90charmmain()
252       USE HelloMod
253       integer i
254       integer*8 aid
255
256       call CkPrintf("Hello\n $$")
257
258       call Hello_CkNew(5, aid)
259
260       call SendTo_Hello_SayHi(aid, 0, 1);
261
262       END
263 \end{verbatim}
264 \section{Writing Charm++ Interface File}
265 Now we move on to Step 2, the Charm Interface file.  This file must
266 have a different name from the Fortran file, and must have an
267 extension of .ci, e.g. if the above Fortran file is hellof.f90, this
268 file could be called hello.ci.  Basically, its purpose is to tell
269 Charm what you've done in the Fortran file, since Charm cannot read
270 Fortran as of now.
271 \begin{verbatim}
272       ## Just replace Hello throughout with your chare's name. ##
273       ## and add your chare's entry points below where indicated ##
274       ## Everything else remains the same ##
275       mainmodule hello {
276       
277         // Create some arbitrary message to hold your parameters
278         // The message must have a unique name for each Entry Point.
279         message HiMsg { int } ;
280       
281         array Hello {
282           entry Hello();
283
284           // Note how your Fortran function takes the above defined
285           // message instead of a list of parameters.
286           entry void SayHi(HiMsg *);
287
288           // Other entry points go here
289
290         };              
291       };
292 \end{verbatim}
293 If the function has more parameters: e.g. A Fortran function FF(int,
294 int, long) in module H, would be described in the .ci file as:
295 \begin{verbatim}
296   message MarshalParams { int, int, long };
297   array H {
298     entry H();
299     entry void FF(MarshalParams *);
300   }
301 \end{verbatim}
302 As mentioned above, the message must have a unique name.
303
304 \section{Compile and Link}
305 Lastly, you need to compile and link the Fortran program with the
306 Charm program as follows: (Let's say you have written hellof.f90, 
307 hello.ci and hello.C)
308 \begin{verbatim}
309   charmc hello.ci -language f90charm
310 \end{verbatim}
311     will create hello.decl.h, hello.def.h
312
313 \begin{verbatim}
314   charmc -c hello.C
315 \end{verbatim}
316     will compile the hello.C with hello.decl.h, hello.def.h.
317
318 \begin{verbatim}
319   charmc -c hellof.f90
320 \end{verbatim}
321     charmc will invoke fotran compiler;
322
323 \begin{verbatim}
324   charmc -o hello hello.o hellof.o -language f90charm
325 \end{verbatim}
326     will link hellof.o, hello.o against Charm's Fortran90 library
327     to create your executable program 'hello'.
328
329 \section{Run Program}
330
331 Finally, to run the program, type:
332
333 ./charmrun +p2 hello
334
335 which will run 'hello' on two virtual processors.
336
337
338 \end{document}