LiveViz (using the 2D Jacobi Program)
LiveViz is a library (module) that enables a Charm++ application to present output to the user in a graphical form as the program continues to execute. More specifically, an image is created for a chare array. Each chare object in the chare array contributes to the image. Once all of the chare objects in the chare array have contributed their portion of the image, the combined image is presented to the user via a LiveViz client application which displays the image.
How to Use LiveViz
First, a special entry method is declared for the chare array. Specifically, an entry method that takes a liveVizRequestMsg message. This message contains various peices of information including the size of the display area in the LiveViz client program (that is, the size of the area where the chare array can draw to). A callback object is created that points to this partictular entry method.
Second, after the chare array is created, LiveViz must be configured. LiveViz can be configured to create both grayscale and color images (and floating-point images which will be converted to a color images). LiveViz can also be configured to control when the image is updated: when the program triggers it, when the client triggers it, or to be continuously updated. The configuration is contained in an object called a liveVizConfig object.
Third, LiveViz is then initialized for a chare array and configuration object pair. Once this occures, the chare array can create a LiveViz image which can give the user information related to its current state.
Revisiting the Basic 2D Jacobi Program
The Basic 2D Jacobi program (which was originally presented here) will be extended to provide LiveViz support. In the original Basic 2D Jacobi program, there was only a single point being held constant over the entire value matrix. To make the LiveViz output more interesting, the Basic 2D Jacobi program has been modified to have several areas held constant. In particular, every chare object (except for the first row of chare objects) will hold the first row of its local value sub-matrix at a constant value. The constant values will alternate for neighboring chare objects (to create a checkerboard like pattern).
The values in the value matrix fall between the values of 0.0 and 1.0. If we imagine that they represent a temperature value on a 2D surface, with 0.0 being cold and 1.0 being hot, then the resulting image will be a temperature image of the 2D surface.
Modifying the Basic 2D Jacobi Program
A modified version of the Basic 2D Jacobi program can be found here (Basic2DJacobi_LiveViz.tar.gz). In addition to changing which value elements are held constant, several sleep calls have been added to slow the code down so user can both have time to connect the LiveViz client and time to see the image change slowly.
First, as is described above, an entry method that takes a liveVizRequestMsg message must be
created. The prototype for this function should fit the form
void MyChareClass::myLiveVizEntryMethod(liveVizRequestMsg* msg) where
MyChareClass is the name of the chare class and myLiveVizEntryMethod is the name of
the entry method. At some point in this function, a call to the liveVizDeposit function.
The prototype for the liveVizDeposit function is
liveVizDeposit(msg, startX, startY, width, height, imageBuff, this, max_image_data).
The important parameters are as follows: msg is a pointer to the liveVizRequestMsg that
was passed to the entry method, startX and startY are the X and Y coordinates of the upper
left corner of the sub-image contributed by this chare object, width and height are the
width and height of the sub-image contributed by this chare object, imageBuff is a pointer to
a data buffer containing the image data for the sub-image (the format of which depends on the type of
image being produced), and this is the special C++ this pointer. The final parameter,
in this case max_image_data, is used to control how image data is combined when multiple chare
objects product data to overlapping areas of the image (that is, when one or more sub-images created by
chare objects overlap with one another).
In the case of the Basic 2D Jacobi program, each of the Jacobi chare objects in the 2D chare array have an independent, non-overlapping portion of the overall value matrix (their local sub-matrix). Because of this, none of the sub-images create by the chare objects will overlap with one another. To keep the code simple, the resulting image will have a single pixel per element in the value matrix. The width and height of the client's drawing area will be ignored to keep the code simple and straight forward. In the example code, the name of the entry method is Jacobi::liveVizFunc() and the code for it can be found in jacobi.C.
Second, a liveVizConfig object containing configuration data for LiveViz must be created. For this example, a color image is created and will be continuously updated.
Third, LiveViz is initiallized with the chare array and configuration object pair. The code for doing both the second and third steps can be found in Main::Main() in main.C.
Running the Basic 2D Jacobi Program
When the Charm++ program is started, it must
specify that it will act as a CCS server. To do this add the following options to the
command line used to launch the Charm++ program:
++server ++server-port xxxx where
xxxx is the port number where the Charm++ application will listen for CCS messages. LiveViz
uses CCS to communicate with the Charm++ application.
Once the Charm++ program has been started, a LiveViz client program can attach to it. One LiveViz client program can be found at [charmDir]/java/bin/liveViz where [charmDir] is the base directory for the Charm++ distribution. This LiveViz client program expects two command line arguements: (1) host which is the name of the machine on which the charmrun command was executed and (2) port which is the port number the Charm++ application is listening for CCS messsages on (should match the xxxx specified for the ++server-port xxxx command line option given to charmrun).