Update references to hapi_src to hapi_impl and revert hapiRegisterCallbacks
[charm.git] / doc / f90charm / manual.tex
blobd3c659f4de4bc832d83b03f452ed4216a8d7dde8
1 \documentclass[11pt]{article}
3 \pagestyle{headings}
5 \title{Fortran90 Bindings for Charm++}
7 \begin{document}
9 \maketitle
11 Charm++ is a parallel object language based on C++. The f90charm module is to
12 provide Fortran90 programs a f90 interface to Charm++. Using the F90Charm interface,
13 users can write Fortran90 programs in a fashion similar to Charm++, which allows
14 creation of parallel object arrays (Chare Arrays) and sending messages between
15 them.
17 To interface Fortran90 to Charm++ and thus obtain a parallel version of your
18 program you need to do the following things:
19 \begin{enumerate}
20 \item Write a Charm Interface file (extension .ci)
21 \item Write your F90 program with f90charmmain() as main program;
22 \item Write implementations of Chare entry methods in the F90 program;
23 \item Compile and Link with Charm's Fortran library
24 \item Run it!
25 \end{enumerate}
27 \section{Overview}
29 Here we suppose you already know most concepts in Charm++ and have done some
30 Charm++ programming. \\
31 Unlike in C++, we don't have classes in Fortran90. Thus, a Chare in F90Charm is
32 represented as a Fortran type structure. Here is an example:
34 \begin{verbatim}
36 ## Just replace Hello throughout with your chare's name. ##
37 ## and add your chare's personal data below where indicated ##
38 ## Everything else remains the same ##
39 MODULE HelloMod
41 TYPE Hello
42 ## your chare's data goes here, the integer below is an example ##
43 integer data
44 END TYPE
46 TYPE HelloPtr
47 TYPE (Hello), POINTER :: obj
48 integer*8 aid
49 END TYPE
51 END MODULE
52 \end{verbatim}
53 You can think of this module as a Chare declaration. Type [Hello] defines
54 arbitrary user program data and HelloPtr defines the Chare pointer which the
55 Fortran program will use later to communicate with the F90Charm runtime
56 library, the [aid] is the handle of the array returned by the F90Charm library, user
57 shouldn't change it.
59 Same as in Charm++ programs, you need to write a .ci interface file
60 so that the Charm translator will generate helper functions. The syntax of .ci files
61 is the same as in Charm++, however, for F90Charm, there are certain
62 constraints. First, you don't need to declare the main chare as like in Charm++;
63 Second, F90Charm currently only supports up to 3D Chare arrays, and you cannot define
64 Chare, Group, and Node Group types. Third, there are no message declarations in .ci files,
65 all the entry functions must be declared in the parameter marshalling
66 fashion of Charm++.
67 Essentially, users can declare in .ci files readonly variables and 1-3D
68 chare arrays with parameter marshalled entry methods.
70 It is the programmer's responsibility to write the implementation of Chare
71 entry methods. The decl and def files generated by Charm++'s translator define
72 the interface functions programmer need to write.
74 For each Chare defined in the .ci file, the user must write these functions
75 for F90Charm's runtime:
77 \verb+SUBROUTINE <ChareName>_allocate(objPtr, aid, index)+
79 You can think of this function as a constructor for each array element
80 with array index [index]. For a 3D array, for example, you can replace index in the
81 example by a 3D array index [index1, index2, index3].
82 In this function the user must allocate memory for
83 the Chare's user data and perform any initialization.
85 For each Chare entry method you have declared, you should write the corresponding
86 Fortran90 subroutine for it:
88 \verb+SUBROUTINE <ChareName>_Entry_<EntryName>(charePtr, myIndex, data1, data2 ... )+
90 Note, the first argument is the Chare pointer as you declared previously, the second argument is the array index which will be passed from the Charm runtime.
91 The rest of the parameters should be the same as you declare the entry methods
92 in .ci files. For higher dimensional arrays, replace myIndex by "myIndex1, myIndex2" for example.
94 On the other side, the decl/def files generated by Charm++'s translator also
95 provide these functions for Chare creation and remote method invocation.
96 for each Chare declared in .ci files, these subroutines are generated for use
97 in the Fortran90 program:
99 \verb+<ChareName>_CkNew(integer n, integer*8 aid)+
101 This subroutine creates the chare array of size n. For higher dimensional
102 array creation, specify one integer for each dimension. For example, to create
103 a 3D array:
105 \verb+<ChareName>_CkNew(integer dim1, integer dim2, integer dim3, integer*8 aid)+
107 And for each entry method, this function is available for use in F90 program
108 if it is 1D array:
110 \verb+<ChareName>_Invoke_<EntryName>(charePtr, myIndex, data1, data2 ... )+
112 This subroutine will send a message to the array element with the index
113 as myIndex. Similarly for arrays with higher dimensions, replace myIndex by
114 corresponding number of array indices. Broadcasts are supported as well:
116 \verb+<ChareName>_Broadcast_<EntryName>(charePtr, data1, data2 ... )+
118 There are several others things you need to know.
120 First, as same in Charm++, each .ci file will generate two header files:
121 .decl.h and .def.h. However, in Fortran90 charm, you are not able to include
122 these C++ files in Fortran90 code. Thus, currently, it is user's
123 task to write a simple C++ code to include these two headers files.
124 You should also declare readonly variables as in C++ in this file. This is as
125 simple as this:
127 \begin{verbatim}
128 #include "hello.decl.h"
129 int chunkSize; // readonly variables define here
130 #include "hello.def.h"
131 \end{verbatim}
133 In the future, this file could be generated automatically by the translator.
135 Second, you can still use readonly variables as in Charm++. However, since
136 there are no global variables as in C++ in Fortran90, you have to access them
137 explicitly via function call. Here are the two helper functions that the
138 translator generates:
140 Take the readonly variable chunkSize as an example:
141 \begin{verbatim}
142 Set_Chunksize(chunkSize);
143 Get_Chunksize(chunkSize);
144 \end{verbatim}
145 These two functions can be used in user's Fortran program to set and get
146 readonly variables.
148 Third, for user's convenience, several Charm++ runtime library functions
149 have their Fortran interface defined in the F90Charm library. These currently
150 include:
151 \begin{verbatim}
152 CkExit()
153 CkMyPe(integer mype)
154 CkNumPes(integer pes)
155 CkPrintf(...) // note, the format string must terminated with '$$'
156 \end{verbatim}
158 Here is a summary of current constraints to write F90 binding Charm++ programs:
159 \begin{enumerate}
160 \item in .ci files, only 1-3D Chare array is supported.
161 \item readonly variables must be basic types, ie. they have to be integer,
162 float, etc scalar types or array types of these basic scalar types.
163 \item instead of program main, your f90 main program starts from subroutine
164 f90charmmain.
165 \end{enumerate}
167 All these are best explained with an example: the hello program. It is a
168 simple ring program. When executed, an array of several parallel
169 Chares is created. Each chare "says" hello when it receives a
170 message, and then sends a message to the next chare. The Fortran f90charmmain()
171 subroutine starts off the events. And the SayHi() subroutine does the
172 say-hello and call next chare to forward.
174 \section{Writing Charm++ Interface File}
175 In this step, you need to write a Charm++ interface file with extension of
176 .ci. In this file you can declare parallel Chare Arrays and their entry
177 functions. The syntax is same as in Charm++.
178 \begin{verbatim}
179 ## Just replace Hello throughout with your chare's name. ##
180 ## and add your chare's entry points below where indicated ##
181 ## Everything else remains the same ##
182 mainmodule hello {
183 // declare readonly variables which once set is available to all
184 // Chares across processors.
185 readonly int chunkSize;
187 array [1D] Hello {
188 entry Hello();
190 // Note how your Fortran function takes the above defined
191 // message instead of a list of parameters.
192 entry void SayHi(int a, double b, int n, int arr[n]);
194 // Other entry points go here
195 entry [reductiontarget] void MyReduction(int result);
198 \end{verbatim}
199 Note, you cannot declare a main chare in the interface file, and you also are not
200 supposed to declare messages. Furthermore, the entry functions must be
201 declared with explicit parameters instead of using messages.
203 \section{Writing F90 Program}
204 To start, you need to create a Fortran Module to represent a chare,
205 e.g. \{ChareName\}Mod.
207 \begin{verbatim}
209 ## Just replace Hello throughout with your chare's name. ##
210 ## and add your chare's personal data below where indicated ##
211 ## Everything else remains the same ##
212 MODULE HelloMod
214 TYPE Hello
215 ## your chare's data goes here ##
216 integer data
217 END TYPE
219 TYPE HelloPtr
220 TYPE (Hello), POINTER :: obj
221 integer*8 aid
222 END TYPE
224 END MODULE
225 \end{verbatim}
227 In the Fortran file you must write an allocate function for this chare
228 with the name: Hello\_allocate.
230 \begin{verbatim}
231 ## Just replace Hello throughout with your chare's name. ##
232 ## Everything else remains the same ##
233 SUBROUTINE Hello_allocate(objPtr, aid, index)
234 USE HelloMod
235 TYPE(HelloPtr) objPtr
236 integer*8 aid
237 integer index
239 allocate(objPtr%obj)
240 objPtr%aid = aid;
241 ## you can initialize the Chare user data here
242 objPtr%obj%data = index
243 END SUBROUTINE
244 \end{verbatim}
246 Now that you have the chare and the chare constructor function, you can start
247 to write one or more entry functions as declared in .ci files.
248 \begin{verbatim}
249 ## p1, p2, etc represent user parameters
250 ## the "objPtr, myIndex" stuff is required in every Entry Point.
251 ## CkExit() must be called by the chare to terminate.
252 SUBROUTINE Hello_Entry_SayHi(objPtr, myIndex, data, data2, len, s)
253 USE HelloMod
254 IMPLICIT NONE
256 TYPE(HelloPtr) objPtr
257 integer myIndex
258 integer data
259 double precision data2
260 integer len
261 integer s(len)
263 objPtr%obj%data = 20
264 if (myIndex < 4) then
265 call Hello_Invoke_SayHi(objPtr%aid, myIndex+1, 1, data2, len, s);
266 else
267 call CkExit()
268 endif
269 \end{verbatim}
271 Preliminary support for reductions is available as well. Support is limited to
272 reducing from a chare array to the first member of the same array. Only basic
273 built-in reducers are available. For an entry method named MyReduction, tagged
274 as a reduction target in the interface file, a contribution can be made as
275 follows:
277 \begin{verbatim}
278 external Hello_ReductionTarget_MyReduction
280 call Hello_contribute(objPtr%aid, myIndex, sizeof(myIndex), myValue, CHARM_SUM_INT, Hello_ReductionTarget_MyReduction)
281 \end{verbatim}
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)
293 call Hello_CkNew(5, aid)
295 call set_ChunkSize(10);
297 do i=1,8
298 s(i) = i;
299 enddo
300 d = 2.50
301 call Hello_Invoke_SayHi(aid, 0, 1, d, 4, s(3:6));
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.
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
317 \begin{verbatim}
318 charmc -c hello.C
319 \end{verbatim}
320 will compile the hello.C with hello.decl.h, hello.def.h.
322 \begin{verbatim}
323 charmc -c hellof.f90
324 \end{verbatim}
325 charmc will invoke fotran compiler;
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'.
333 There is a 2D array example at charm/examples/charm++/f90charm/hello2D.
335 \section{Run Program}
337 To run the program, type:
339 ./charmrun +p2 hello
341 which will run 'hello' on two virtual processors.
343 \end{document}