1 \documentclass[11pt
]{article
}
5 \title{Fortran90 Bindings for Charm++
}
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
17 To interface Fortran90 to Charm++ and thus obtain a parallel version of your
18 program you need to do the following things:
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
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:
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 ##
42 ## your chare's data goes here, the integer below is an example ##
47 TYPE (Hello), POINTER :: obj
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
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
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
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
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
128 #include "hello.decl.h"
129 int chunkSize; // readonly variables define here
130 #include "hello.def.h"
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:
142 Set_Chunksize(chunkSize);
143 Get_Chunksize(chunkSize);
145 These two functions can be used in user's Fortran program to set and get
148 Third, for user's convenience, several Charm++ runtime library functions
149 have their Fortran interface defined in the F90Charm library. These currently
154 CkNumPes(integer pes)
155 CkPrintf(...) // note, the format string must terminated with '$$'
158 Here is a summary of current constraints to write F90 binding Charm++ programs:
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
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++.
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 ##
183 // declare readonly variables which once set is available to all
184 // Chares across processors.
185 readonly int chunkSize;
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);
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.
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 ##
215 ## your chare's data goes here ##
220 TYPE (Hello), POINTER :: obj
227 In the Fortran file you must write an allocate function for this chare
228 with the name: Hello
\_allocate.
231 ## Just replace Hello throughout with your chare's name. ##
232 ## Everything else remains the same ##
233 SUBROUTINE Hello_allocate(objPtr, aid, index)
235 TYPE(HelloPtr) objPtr
241 ## you can initialize the Chare user data here
242 objPtr
%obj%data = index
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.
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)
256 TYPE(HelloPtr) objPtr
259 double precision data2
264 if (myIndex <
4) then
265 call Hello_Invoke_SayHi(objPtr
%aid, myIndex+1, 1, data2, len, s);
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
278 external Hello_ReductionTarget_MyReduction
280 call Hello_contribute(objPtr
%aid, myIndex, sizeof(myIndex), myValue, CHARM_SUM_INT, Hello_ReductionTarget_MyReduction)
283 Now, you can write the main program to create the chare array and start the
284 program by sending the first message.
286 SUBROUTINE f90charmmain()
293 call Hello_CkNew(
5, aid)
295 call set_ChunkSize(
10);
301 call Hello_Invoke_SayHi(aid,
0,
1, d,
4, s(
3:
6));
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)
313 charmc hello.ci -language f90charm
315 will create hello.decl.h, hello.def.h
320 will compile the hello.C with hello.decl.h, hello.def.h.
325 charmc will invoke fotran compiler;
328 charmc -o hello hello.o hellof.o -language f90charm
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:
341 which will run 'hello' on two virtual processors.