changed the f90charm manual.
[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 4/1/2001 by Gengbin Zheng}}
20
21 \begin{document}
22
23 \maketitle
24
25 Charm++ is a parallel object language based on C++. The f90charm module is to
26 provide Fortran90 programs a f90 interface to Charm++. Using F90Charm interface,
27 users can write Fortran90 programs in a fashion simliar to Charm++, which allows
28 creation of parallel object arrays(Chare Arrays) and sending messages between 
29 them.
30
31 To interface Fortran90 to Charm++ and thus obtain a parallel version of your 
32 program you need to do the following things:
33 \begin{enumerate}
34 \item Write a Charm Interface file (extension .ci)
35 \item Write your F90 program with f90charmmain() as main program;
36 \item Write implementation of Chare entry functions in f90 program;
37 \item Compile and Link with Charm's Fortran library
38 \item Run it !
39 \end{enumerate}
40
41 \section{Overview}
42
43 Here I suppose you've already known most concepts in charm++ and done some 
44 charm++ programming.  \\
45 Unlike in C++, we don't have class here in Fortran90. Thus, Chare is 
46 represented as a fortran type structure. Here is an example:
47
48 \begin{verbatim}
49
50       ## Just replace Hello throughout with your chare's name. ##
51       ## and add your chare's personal data below where indicated ##
52       ## Everything else remains the same ##
53       MODULE HelloMod
54
55       TYPE Hello
56       ## your chare's data goes here, the integer below is an example ##
57       integer data
58       END TYPE
59
60       TYPE HelloPtr
61       TYPE (Hello), POINTER ::  obj
62       integer*8 aid
63       END TYPE
64
65       END MODULE
66 \end{verbatim}
67 You can think of this module as a chare declaration. Type [Hello] defines 
68 arbitary user program data and HelloPtr defines the Chare pointer which 
69 fortran program will use later to communicate with the f90charm runtime 
70 library, the [aid] is the handle of array returned by f90charm library, user 
71 shouldn't change it..
72
73 As same in C++ charm program, you need to write a .ci interface file
74 so that charm translator will generate helper functions. The syntax of .ci files
75 are the same as in Charm++, however, for Fortran90 charm, there are certain
76 constraints. First, you don't need to declare the main chare as like in Charm++;
77 Second, it currently only support 1D Chare array, you cannot define Chare and 
78 Group types. Third, there is no message declaration in .ci files, all the entry
79 functions must be declared in the parameter marshelling fashion as in Charm++.
80 So, what you can do in the .ci files is to define readonly variables and 1D
81 chare arrays with parameter marshelling entry functions.
82
83 It is programmer's responsibility to write the implementation of chare's
84 entry functions. The decl and def files generated by Charm++ translator define
85 the interface functions programmer need to write.
86
87 For each Chare defined in the .ci file, user must write these functions
88 for charm++ f90 runtime:
89
90   \verb+SUBROUTINE <ChareName>_allocate(objPtr, aid, index)+
91
92   You can think of this function as a constructor for each array element 
93 with array index [index]. In this function user must allocate memory for 
94 the Chare's user data and perform initialization.
95
96   For each chare entry method you declared, you should write the corresponding 
97 fortran90 subroutine for it:
98
99   \verb+SUBROUTINE entry(charePtr, myIndex, data1, data2 ... )+
100
101   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. 
102 The rest of the parameters should be the same as you declare the entry function
103 in .ci files.
104
105 On the other side, the decl/def files generated by Charm++ translator also
106 provide these functions for Chare creation and remote method invocation. 
107 for each Chare declared in .ci files, these subroutines are generated for use
108  in Fortran90 program:
109
110   \verb+<ChareName>_CkNew(integer n, integer*8 aid)+
111
112   This subroutine creates the chare array of size n.
113
114 And for each entry method, this function is available for use in f90 program:
115
116   \verb+SendTo_<ChareName>_<Entry>(charePtr, myIndex, data1, data2 ... )+
117
118   This subroutine will send a message to the array element with the index
119 as myIndex. 
120
121 There are several others things you need to know.
122
123 First, as same in Charm++, each .ci file will generate two header files:
124 .decl.h and .def.h. However, in Fortran90 charm, you are not able to include 
125 these C++ files in Fortran90 code. Thus, currently, it is user's 
126 task to write a simple C++ code to include these two headers files. 
127 You should also declare readonly variables as in C++ in this file. This is as 
128 simple as this:
129
130 \begin{verbatim}
131 #include "hello.decl.h"
132 int chunkSize;  // readonly variables define here
133 #include "hello.def.h"
134 \end{verbatim}
135
136 In future, this file can be generated automatically by translator.
137
138 Second, you can still use readonly variables as in Charm++. However, since
139 there is no global variables as in C++ in fortran90, you have to access them
140 explicitly via function call. Here are the two helper functions that 
141 translator generates:
142
143 take the readonly variable chunkSize as an example,
144 \begin{verbatim}
145 Set_Chunksize(chunkSize);
146 Get_Chunksize(chunkSize);
147 \end{verbatim}
148 These two functions can be used in user's fortran program to set and get 
149 readonly variables.
150
151 Third, for user's convenience, several charm++ runtime library functions
152 have their Fortran interface defined in f90charm library. These currently
153 include:
154 \begin{verbatim}
155 CkExit()
156 CkMyPe(integer mype)
157 CkNumPes(integer pes)
158 CkPrintf(...)    // note, the format string must terminated with '$$'
159 \end{verbatim}
160
161 Here is a summary of current constraints to write f90 binding charm++ programs:
162 \begin{enumerate}
163 \item in .ci files, only 1D Chare array is supported.
164 \item readonly variables must be basic types, ie. they have to be integer, 
165 float, etc scalar types or array types of these basic scalar types.
166 \item instead of program main, your f90 main program starts from subroutine 
167 f90charmmain.
168 \end{enumerate}
169
170 All these are best explained with an example: the hello program.  It is a
171 simple ring program.  When executed, an array of several parallel
172 Chares is created.  Each chare "says" hello when it receives a
173 message, and then sends a message to the next chare. The Fortran f90charmmain() 
174 subroutine starts off the events.  And the SayHi() subroutine does the 
175 say-hello and call next chare to forward.
176
177 \section{Writing Charm++ Interface File}
178 In this step, you need to write a Charm++ interface file with extension of
179 .ci. In this file you can declare parallel Chare Arrays and their entry 
180 functions. The syntax is same as in Charm++.
181 \begin{verbatim}
182       ## Just replace Hello throughout with your chare's name. ##
183       ## and add your chare's entry points below where indicated ##
184       ## Everything else remains the same ##
185       mainmodule hello {
186         // declare readonly variables which once set is available to all
187         // Chares across processors.      
188         readonly int chunkSize;
189
190         array [1D] Hello {
191           entry Hello();
192
193           // Note how your Fortran function takes the above defined
194           // message instead of a list of parameters.
195           entry void SayHi(int a, double b, int n, int arr[n]);
196
197           // Other entry points go here
198
199         };              
200       };
201 \end{verbatim}
202 Note, you cannot declare main chare in the interface file, you also are not 
203 supposed to declare messages. Furthermore, the entry functions must be 
204 declared with explicit parameters instead of using messages. 
205
206 \section{Writing F90 Program}
207 To start, you need to create a Fortran Module to represent a chare,
208 e.g. \{ChareName\}Mod.
209
210 \begin{verbatim}
211
212       ## Just replace Hello throughout with your chare's name. ##
213       ## and add your chare's personal data below where indicated ##
214       ## Everything else remains the same ##
215       MODULE HelloMod
216
217       TYPE Hello
218       ## your chare's data goes here ##
219       integer data
220       END TYPE
221
222       TYPE HelloPtr
223       TYPE (Hello), POINTER ::  obj
224       integer*8 aid
225       END TYPE
226
227       END MODULE
228 \end{verbatim}
229
230 In the Fortran file you must write an allocate funtion for this chare
231 with the name: Hello\_allocate.
232
233 \begin{verbatim}
234       ## Just replace Hello throughout with your chare's name. ##
235       ## Everything else remains the same ##
236       SUBROUTINE Hello_allocate(objPtr, aid, index)
237       USE HelloMod
238       TYPE(HelloPtr) objPtr 
239       integer*8 aid
240       integer index
241
242       allocate(objPtr%obj)
243       objPtr%aid = aid;
244       ## you can initialize the Chare user data here
245       objPtr%obj%data = index
246       END SUBROUTINE
247 \end{verbatim}
248
249 Now that you have the chare and the chare constructor function, you can start
250  to write one or more entry functions as declared in .ci files.
251 \begin{verbatim}
252       ## p1, p2, etc represent user parameters
253       ## the "objPtr, myIndex" stuff is required in every Entry Point.
254       ## CkExit() must be called by the chare to terminate.
255       SUBROUTINE SayHi(objPtr, myIndex, data, data2, len, s)
256       USE HelloMod
257       IMPLICIT NONE
258
259       TYPE(HelloPtr) objPtr
260       integer myIndex
261       integer data
262       double precision data2
263       integer len
264       integer s(len)
265
266       objPtr%obj%data = 20
267       if (myIndex < 4) then
268           call SendTo_Hello_SayHi(objPtr%aid, myIndex+1, 1, data2, len, s);
269       else 
270           call CkExit()
271       endif
272 \end{verbatim}
273
274 Now, you can write the main program to create the chare array and start the 
275 program by sending the first message.
276 \begin{verbatim}
277       SUBROUTINE f90charmmain()
278       USE HelloMod
279       integer i
280       double precision d
281       integer*8 aid
282       integer  s(8)
283
284       call Hello_CkNew(5, aid)
285
286       call set_ChunkSize(10);
287
288       do i=1,8
289           s(i) = i;
290       enddo
291       d = 2.50
292       call SendTo_Hello_SayHi(aid, 0, 1, d, 4, s(3:6));
293
294       END
295 \end{verbatim}
296 This main program creates an chare array Hello of size 5 and send a message with
297 an integer, an double and array of integers to the array element of index 0.
298
299 \section{Compile and Link}
300 Lastly, you need to compile and link the Fortran program with the
301 Charm program as follows: (Let's say you have written hellof.f90, 
302 hello.ci and hello.C)
303 \begin{verbatim}
304   charmc hello.ci -language f90charm
305 \end{verbatim}
306     will create hello.decl.h, hello.def.h
307
308 \begin{verbatim}
309   charmc -c hello.C
310 \end{verbatim}
311     will compile the hello.C with hello.decl.h, hello.def.h.
312
313 \begin{verbatim}
314   charmc -c hellof.f90
315 \end{verbatim}
316     charmc will invoke fotran compiler;
317
318 \begin{verbatim}
319   charmc -o hello hello.o hellof.o -language f90charm
320 \end{verbatim}
321     will link hellof.o, hello.o against Charm's Fortran90 library
322     to create your executable program 'hello'.
323
324 \section{Run Program}
325
326 To run the program, type:
327
328 ./charmrun +p2 hello
329
330 which will run 'hello' on two virtual processors.
331
332 \end{document}