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