A CHARM++ program is structurally similar to a C++ program. Most of a CHARM++ program is C++ code.8 The main syntactic units in a CHARM++ program are class definitions. A CHARM++ program can be distributed across several source code files.
There are five disjoint categories of objects (classes) in CHARM++:
The user's code is written in C++ and interfaces with the CHARM++ system as if it were a library containing base classes, functions, etc. A translator is used to generate the special code needed to handle CHARM++ constructs. This translator generates C++ code that needs to be compiled with the user's code.
Interfaces to the CHARM++ objects (such as messages, chares, readonly variables etc.) have to be declared in CHARM++ interface files. Typically, such entities are grouped into modules. A CHARM++ program may consist of multiple modules. One of these modules is declared to be a mainmodule. All the modules that are ``reachable'' from the mainmodule via the extern construct are included in a CHARM++ program.
The CHARM++ interface file has the suffix ``.ci''. The CHARM++ interface translator parses this file and produces two files (with suffixes ``.decl.h'' and ``.def.h'', for each module declared in the ``.ci'' file), that contain declarations (interface) and definitions (implementation)of various translator-generated entities. If the name of a module is MOD, then the files produced by the CHARM++ interface translator are named MOD.decl.h and MOD.def.h.9 We recommend that the declarations header file be included at the top of the header file (MOD.h) for module MOD, and the definitions file be included at the bottom of the code for module (MOD.C).10
A simple CHARM++ program is given below:
HelloMain is designated a mainchare. Thus the Charm Kernel starts execution of this program by creating an instance of HelloMain on processor 0. The HelloMain constructor creates a chare group HelloGroup, and stores a handle to itself and returns. The call to create the group returns immediately after directing Charm Kernel to perform the actual creation and invocation. Shortly after, the Charm Kernel will create an object of type HelloGroup on each processor, and call its constructor. The constructor will then print ``Hello World...'' and then call the PrintDone method of HelloMain. The PrintDone method calls CkExit after all group members have called it (i.e., they have finished printing ``Hello World...''), and the CHARM++program exits.
The decl.h file provides declarations for the proxy classes of the concurrent objects declared in the ``.ci'' file (from which the decl.h file is generated). So the Hello.decl.h file will have the declaration of the class CProxy_HelloMain. Similarly it will also have the declaration for the HelloGroup class.
This class will have functions to create new instances of the chares and groups, like the function ckNew. For HelloGroup this function creates an instance of the class HelloGroup on all the processors.
The proxy class also has functions corresponding to the entry methods defined in the ``.ci'' file. In the above program the method wait is declared in CProxy_HelloMain (proxy class for HelloMain).
The proxy class also provides static registration functions used by the CHARM++ runtime. The def.h file has a registration function (__registerHello in the above program) which calls all the registration functions corresponding to the readonly variables and entry methods declared in the module.
June 29, 2008
Charm Homepage