Prism 6.0 User's Guide

Chapter 5 Visualizing Data

This chapter describes how to examine the values of variables and expressions in your program. This is referred to as visualizing data. In addition, it describes how to find out the type of a variable and change its values.

See the following sections:

Overview of Data Visualization

You can visualize either variables (including arrays, structures, pointers, etc.) or expressions; see " Writing Expressions in Prism" for information about writing expressions in Prism. In addition, you can provide a context, so that Prism handles the values of data elements differently, depending on whether they meet the condition you specify.

Printing and Displaying

Prism provides two general methods for visualizing data: printing and displaying.

Printing or displaying to the history region of the command window prints out the numeric or character values of the data in standard fashion.

Printing or displaying to a graphical window creates a visualizer, which provides you with various options as to how to represent the data.

Visualization Methods

Prism provides these methods for choosing what to print or display:

In all cases, choosing Display adds an event to the event list, since displaying data requires an action to update the values each time the program is stopped. Note that, since Display updates automatically, the only way to keep an unwanted display window from reappearing is to delete the corresponding display event.

You create print events only via the Event Table and the Events menu.

Changing the Default Radix

By default, Prism prints and displays values as decimal numbers. You can change this default by issuing the set $radix command, specifying as a setting 2 (binary), 8 (octal), or 16 (hexadecimal). For example,

set $radix = 16

changes the default representation to hexadecimal. To reset the default to decimal, issue the command

set $radix = 10

You can override the default for an individual print or display operation. See " Printing and Displaying From the Command Window" and " Using the Options Menu".

The default setting also affects the display of argument values in procedures in the call stack; see " Displaying the Call Stack".

Data Visualization Limits

Note these points in visualizing data:

Choosing the Data to Visualize

This section describes the methods Prism provides for printing and displaying data.

Printing and Displaying From the Debug Menu

To print a variable or expression at the current program location, choose Print from the Debug menu. It is also by default in the tear-off region.

To display a variable or expression every time execution stops, starting at the current program location, choose Display from the Debug menu.

When you choose Print or Display, a dialog box appears; Figure 5-1 shows an example of the Print dialog box.

Figure 5-1 Print Dialog Box

Graphic

In the Expression box, enter the variable or expression whose value(s) you want printed. Text selected in the source window appears as the default; you can edit this text.

The dialog boxes also offer choices as to the window in which the values are to appear:

Click on Print or Display to print the values of the specified expression at the current program location.

Click on Cancel or press the Esc key to close the window without printing or displaying.

Printing and Displaying From the Source Window

To print and display from the source window:

  1. Select the variable or expression by dragging over it with the mouse or double-clicking on it.

  2. Right-click the mouse to display a pop-up menu.

  3. Click on Print in this menu to display a snapshot visualizer containing the value(s) of the selected variable or expression at that point in the program's execution.

    Click on Display to display a visualizer that is automatically updated whenever execution stops.

    To print without bothering to display the menu, press the Shift key while selecting the variable or expression.


    Note -

    Prism prints the correct variable when you choose it in this way, even if the scope pointer sets a scope that contains another variable of the same name.


Printing and Displaying From the Events Menu

You can use the Events menu to define a print or display event that is to take place at a specified location in the program.

The Print dialog box (see Figure 5-2) prompts for the variable or expression whose value(s) are to be printed, the program location at which the printing is to take place, and the name of the window in which the value(s) are to be displayed.

Figure 5-2 Print Dialog Box

Graphic

Window names are dedicated, snapshot, and command; you can also make up your own name. The default is dedicated. See " Redirecting Output" for a discussion of these names.

When you have filled in the fields, click on OK; the event is added to the Event Table. When the location is reached in the program, the value(s) of the expression or variable are printed.

The Display dialog box is similar, but it does not prompt for a location; the display visualizer will update every time the program stops execution.

Printing and Displaying From the Event Table

You can use the Event Table to define a print or display event that is to take place at a specified location in the program.

Click on Print or Display in the Common Events buttons to create an event that will print or display data.

If you click on Print, the Location and Action fields are highlighted. Put a program location in the Location field. Complete the print event in the Actions field, specifying the variable or expression, and the window in which it is to be printed. For example,

print d2 on dedicated

If you click on Display, the Location field displays stopped, and the Actions field displays print on dedicated. Complete the description of the print event, as described above. The variable or expression you specify is then displayed whenever the program stops execution.

Printing and Displaying From the Command Window

Use the print command to print the value(s) of a variable or expression from the command window. Use the display command to display the value(s). The display command prints the value(s) of the variable or expression immediately, and creates a display event so that the values are updated automatically whenever the program stops.

The commands have this format:

[where (expression)] command variable[, variable ...] 

The optional where (expression) syntax sets the context for printing the variable or expression; see below.

In the syntax, command is either print or display, and variable is the variable or expression to be displayed or printed.

Redirection of output to a window via the on window syntax works slightly differently for display and print from the way it works for other commands; see " Redirecting Output" for a discussion of redirection. Separate windows are created for each variable or expression that you print or display. Thus, the commands

display x on dedicated

display y/4 on dedicated

display [0:128:2]z on dedicated

create three windows, each of which is updated separately.

To print or display the contents of a register, precede the register's name with a dollar sign. For example,

print $pc

prints the program counter register. See " Displaying the Contents of Registers" for a list of register names supported by Prism.

Setting the Context

You can precede the print or display command with a where statement that can make elements of a variable or array inactive. Inactive elements are not printed in the command window; " Overview of Data Visualization" describes how they are treated in visualizers. Making elements inactive is referred to as setting the context.

To set the context, follow the where keyword with an expression in parentheses. The expression must evaluate to true or false for every element of the variable or array being printed.

For example,

where (i .gt. 0) print i

prints (in the command window) only the values of i that are greater than 0.

You can use certain Fortran intrinsics in the where statement. For example,

where (a .eq. maxval(a)) print a

prints the element of a that has the largest value. (This is equivalent to the MAXLOC intrinsic function.) See " Writing Expressions in Prism" for more information on writing expressions in Prism.

Note that setting the context affects only the printing or displaying of the variable. It does not affect the actual context of the program as it executes.

Specifying the Radix

You can specify the radix to be used in printing or displaying values by adding a suffix of the form /radix to the print or display command. radix can be b (binary), d (decimal), x (hexadecimal), or o (octal). For example,

print/b pvar1

prints the binary representation of pvar1 in the command window.

display/x pvar2 on dedicated

displays the hexadecimal values of pvar2 in a dedicated window.

The default radix is decimal, unless you have used the set $radix command to change it; see " Changing the Default Radix".

Working With Visualizers

The window that contains the data being printed or displayed is called a visualizer. Figure 5-3 shows a visualizer for a 3-dimensional array.

Figure 5-3 Visualizer for a 3-Dimensional Array

Graphic

The visualizer consists of two parts: the data navigator and the display window. There are also File and Options pulldown menus.

The data navigator shows which portion of the data is being displayed, and provides a quick method for moving through the data. The appearance of the data navigator depends on the number of dimensions in the data. It is described in more detail in " Using the Display Window in a Visualizer".

The display window is the main part of the visualizer. It shows the data, using a representation that you can choose from the Options menu. The default is text: that is, the data is displayed as numbers or characters. Figure 5-3 is a text visualizer. The display window is described in more detail in " Using the Options Menu".

The File menu lets you save, update, or cancel the visualizer; see " Using the File Menu" for more information. The Options menu, among other things, lets you change the way values are represented; see Section " Using the Options Menu".

Using the Data Navigator in a Visualizer

The data navigator helps you move through the data being visualized. It has different appearances, depending on the number of dimensions in your data. If your data is a single scalar value, there is no data navigator.

For 1-dimensional arrays and parallel variables, the data navigator is the scroll bar to the right of the data. The number to the right of the buttons for the File and Options menus indicates the coordinate of the first element that is displayed. The elevator in the scroll bar indicates the position of the displayed data relative to the entire data set.

For 2-dimensional data, the data navigator is a rectangle in the shape of the data, with the axes numbered. The white box inside the rectangle indicates the position of the displayed data relative to the entire data set. You can either drag the box or click at a spot in the rectangle. The box moves to that spot, and the data displayed in the display window changes.

For 3-dimensional data, the data navigator consists of a rectangle and a slider, each of which you can operate independently. The value to the right of the slider indicates the coordinate of the third dimension. Changing the position of the bar along the slider changes which 2-dimensional plane is displayed out of the 3-dimensional data.

For data with more than three dimensions, the data navigator adds a slider for each additional dimension.

Changing the Axes

You can change the way the visualizer lays out your data by changing the numbers that label the axes. Click in the box surrounding the number; it is highlighted, and an I-beam appears. You can then type in the new number of the axis; you don't have to delete the old number. The other axis number automatically changes; for example, if you change axis 1 to 2, axis 2 automatically changes to become axis 1.

Using the Display Window in a Visualizer

The display window shows the data being visualized.

In addition to using the data navigator to move through the data, you can drag the data itself relative to the display window by holding down the left mouse button; this provides finer control over the display of the data.

To find out the coordinates and value of a specific data element, click on it while pressing the Shift key. Its coordinates are displayed in parentheses, and its value is displayed beneath them. If you have set a context for the visualizer, you also see whether the element is active or inactive (see " Using the Options Menu"). Drag the mouse with the Shift key pressed, and you see the coordinates, value, and context of each data element over which the mouse pointer passes.

You can resize the visualizer to display more (or less) data either horizontally or vertically.

Using the File Menu

Click on File to pull down the File menu.

Choose Update from this menu to update the display window for this variable, using the value(s) at the current program location. See " Updating and Closing the Visualizer" for more information on updating a visualizer.

Choose Save or Save As to save the visualizer's values to a file. See " Saving the Values of a Variable" for more information.

Choose Diff or Diff With to compare the visualizer's values with values stored in a file. See " Comparing the Data" for more information.

Choose Snapshot to create a copy of the visualizer, which you can use to compare with later updates.

Choose Close to cancel the visualizer.

Using the Options Menu

Click on Options to pull down the Options menu. See Figure 5-4.

Figure 5-4 Options Menu in a Visualizer

Graphic

Choosing the Representation

Choose Representation from the Options menu to display another menu that gives the choices for how the values are represented in the display window. The choices are described below. You can control aspects of the way these visualizers appear by changing their parameters, as described later in this section.

Figure 5-5 Histogram Visualizer

Graphic

For complex numbers, Prism uses the modulus.

Figure 5-6 Dither Visualizer

Graphic

For complex numbers, Prism uses the modulus.

Figure 5-7 Threshold Visualizer

Graphic

For complex numbers, Prism uses the modulus.

Figure 5-8 1-Dimensional Graph Visualizer

Graphic

Figure 5-9 Surface Visualizer

Graphic


Note -

If there are large values in the top rows of the data, they may be drawn off the top of the screen. To see these values, flip the axes as described earlier in this section, so that the top row appears in the left column.


Figure 5-10 Vector Visualizer

Graphic

Setting Parameters

Choose Parameters from the Options menu to display a dialog box in which you can change various defaults that Prism uses in setting up the display window; see Figure 5-11. If a parameter is grayed out or missing, it does not apply to the current representation.

Figure 5-11 Visualization Parameters Dialog Box

Graphic

The parameters (for all representations except the histogram representation) are:

For the text representation, the field width specifies the number of characters in each column. If a number is too large for the field width you specify, dots are printed instead of the number.

For dither, threshold, colormap, and vector representations, the field width specifies how wide (in pixels) the representation of each data element is to be. By default, dither, threshold, and colormap visualizers are scaled to fit the display window. Note, however, that for dither visualizers, the gray shading may be more noticeable with a smaller field width.

For the graph representation, the field width specifies the horizontal spacing between elements.

For the surface representation, it specifies the spacing of elements along both directions of the plane.

set $d_precision = 11

sets the default precision for doubles to 11 significant digits.

For graph, surface, and vector representations, these parameters represent the bottom and top of the range that is to be represented. Values below the minimum are shown as the minimum; values above the maximum are shown as the maximum.

By default Prism uses the entire range of values for all these representations.

The parameters for the histogram representation are:

If you specify a different minimum or maximum, values below the minimum or above the maximum are not displayed in the histogram, but are counted as outliers instead; the number of outliers is displayed above the histogram.

Displaying a Ruler

Choose Ruler from the Options menu to toggle the display of a ruler around the data in the display window. The ruler is helpful in showing which elements are being displayed. Figure 5-12 shows a 3-dimensional threshold visualizer with the ruler displayed.

In the surface representation, the ruler cannot indicate the coordinates of elements in the vertical axis, since they change depending on the height of each element. However, you can press the Shift key and left-click to display the coordinates and value of an element.

Figure 5-12 Threshold Visualizer With a Ruler

Graphic

Displaying Statistics

Choose Statistics from the Options menu to display a window containing statistics and other information about the variable being visualized. The window contains:

Figure 5-13 gives an example of the Statistics window.

Figure 5-13 Statistics for a Visualizer

Graphic

For complex numbers, Prism uses the modulus.

Using the Set Context Dialog Box

Choose Set Context from the Options menu to display a dialog box in which you can specify which elements of the variable are to be considered active and which are to be considered inactive. Active and inactive elements are treated differently in visualizers:

Figure 5-14 shows the Set Context dialog box.

Figure 5-14 Set Context Dialog Box

Graphic

By default, all elements of the variable are active; this is the meaning of the everywhere keyword in the text-entry box. To change this default, you can either edit the text in the text-entry box directly or click on the Where button to display a menu. The choices in the menu are everywhere and other:

In the text-entry box, you can enter any valid expression that will evaluate to true or false for each element of the variable.

The context you specify for printing does not affect the program's context; it just affects the way the elements of the variable are displayed in the visualizer.

See "Setting the Context" above for more information on context. See " Writing Expressions in Prism" for more information on writing expressions in Prism.

Click on Apply to set the context you specified. Click on Cancel or press the Esc key to close the dialog box without setting the context.

Changing the Radix

Choose Radix from the Options menu to change the radix used in the text representation of a value.

Choosing Radix pulls down a submenu with four selections: Decimal, Hex, Octal, and Binary. Choosing one of these changes the value to the specified radix. Prism continues to use this radix if the visualizer is updated.

By default, Prism displays values in decimal. You can change this default via the set $radix command; see " Changing the Default Radix". You can also override it for a specific print or display command; see " Printing and Displaying From the Command Window".

Updating and Closing the Visualizer

If you created a visualizer by issuing a display command, it automatically updates every time the program stops execution.

If you created the visualizer by issuing a print command, its display window is grayed out when the program resumes execution and the values in the window are outdated. To update the values, choose Update from the visualizer's File menu.

To close the visualizer, choose Close from the File menu, or press the Esc key.

Saving, Restoring, and Comparing Visualizers

You can save the values of a variable or expression to a file. You can subsequently visualize these values and compare them with the values in another visualizer--for example, the same variable later in the run, or during a totally separate execution of the program. This provides a convenient way of spotting changes in the values of a variable.

Saving the Values of a Variable

You can save the values of a variable or expression to a file for later use.

From the Command Line

Use the command varsave to save the values of a variable or expression to a file. Its syntax is

varsave "filename" expression

where filename is the name of the file to which the data is to be saved, and expression is the variable or expression whose values are to be saved. For example,

varsave "alpha.data" alpha

saves the values of the variable alpha in the file alpha.data (in your current working directory within Prism).

varsave "/u/kathy/alpha2.data" alpha*2

saves the results of the expression alpha*2 in the file with the path name /u/kathy/alpha2.data.

From a Visualizer

Use the Save or Save As selection from a visualizer's File menu to save the visualizer's values to a file.

If you choose Save As, a dialog box appears in which you can specify the name of the file to which the values are to be saved; see Figure 5-15.

Figure 5-15 Saving a Visualizer's Data to a File

Graphic

The highlighted directory is the current working directory. If you want to put the file there, simply type its name in the Save As box and click on OK.

If you want to put the file in another directory, click on the directory. (The parent directories of the current working directory are shown above it in the Directories list; its subdirectories are listed beneath it.) This will display the subdirectories of the directory you clicked on. You can traverse the directory structure in this manner until you find the directory in which you want to put the file, or, you can simply type the entire path name in the Save As box.

Choose the Save selection to save the values in the file you most recently specified. If you haven't specified a file, the values are saved in a file called noname.var in your current working directory in Prism.

Restoring the Data

Use the intrinsic varfile to bring values you have saved to a file back into Prism. Its syntax is:

varfile("filename")

where filename is the name of the file that contains the values you want to restore.


Note -

The varfile intrinsic is not available in MP Prism.


You can use the varfile intrinsic anywhere you could have used the original variable or expression that you saved to a file. For example, if you saved x:

varsave "x.var" x

then the command

print varfile("x.var")

is equivalent to

print x

Note that this allows you to save a variable's values, then print them during a later Prism session, without having a program loaded or running.

Comparing the Data

You can compare a variable or expression whose values have been saved in a file with another version of the variable or expression. This comparison could take place later in the same run of the program, during a subsequent run, or even during a second, simultaneous Prism session.

You can also compare the values with those of another variable, as long as both variables have the same base type (that is, you can't compare integers with floating-point numbers).

From the Command Line

You can use the print or display command with the difference operator and the varfile intrinsic to perform a comparison between two versions of a variable or expression.

For example, if you saved x in the file x.var:

varsave "x.var" x

then the command

print x - varfile("x.var")

prints the difference between the current and saved values of x.

If an element is printed as 0, it is the same in both versions. If it is nonzero, its value is different in the two versions.

From a Visualizer

Use the Diff or Diff With selection from a visualizer's File menu to compare the visualizer's values with values stored in a file.

Choose Diff With to choose the file containing the values. It displays a dialog box like the one shown below.

Figure 5-16 Diff With Dialog Box

Graphic

The dialog box has the same format as the Save As dialog box described in " Saving the Values of a Variable". It lists the files found in your current working directory in Prism. Click on a file name, then click on OK to choose the file. Or type a file name in the Diff With text-entry box and click on OK.

Choose Diff to compare the visualizers values to those in the most recently specified file; if no file has been specified, values are compared to those in the file noname.var in your current working directory in Prism.

Once you have specified a file via Diff or Diff With, Prism creates a new visualizer that displays the difference in values between the visualizer and the file. If an element's value in the new visualizer is 0, the value is the same in both versions. If it is nonzero, it is different in the two versions.

You can work with this visualizer as you would any visualizer. For example, you can change the representation and display summary statistics.

Visualizing Layouts of Parallel Objects

Prism provides a layout intrinsic that returns the numbers of the nodes on which the data elements of a parallel object are located. Its syntax is

layout(pvar)

where pvar is a parallel object. You can use the Fortran 90 array-section syntax described in " Using Array-Section Syntax in C arrays " to specify a range of elements within a parallel object.

You can print or display the results of applying the layout intrinsic to a parallel object. For example,

print layout(p1) on dedicated

creates a visualizer that is the same size and shape as the parallel object p1. The visualizer displays the rank of the process that is holding each value.

Note that you can use other visualizer representations--for example, dither or colormap--to display the layout graphically.

Visualizing Structures

If you print a pointer or a structure (or a structure-valued expression) in a window, a structure visualizer appears.

Figure 5-17 shows an example of a structure visualizer.

Figure 5-17 Structure Visualizer

Graphic

The structure you specified appears inside a box; this is referred to as a node. The node shows the fields in the structure and their values. If the structure contains pointers, small boxes appear next to them; they are referred to as buttons. Left-click on a node to select it. Use the up and down arrow keys to move between buttons of a selected node.

You can perform various actions within a structure visualizer, as described below.

Expanding Pointers

You can expand scalar pointers in a structure to generate new nodes. (You cannot expand a pointer to a parallel variable.)

To expand a single pointer:

Figure 5-18 Structure Visualizer, With One Pointer Expanded

Graphic

To expand all pointers in a node:

To recursively expand all pointers from the selected node on down:

Panning and Zooming

You can left-click and drag through the data navigator or the display window to pan through the data, just as you can with visualizers; see " Using the Data Navigator in a Visualizer" and " Using the Display Window in a Visualizer".

You can also "zoom" in and out on the data by left-clicking on the Zoom arrows. Click on the down arrow to zoom out and see a bird's-eye view of the structure; click on the up arrow to get a closeup. Figure 5-19 shows part of a complicated structure visualizer after zooming out.

Left-click on a node in a zoomed-out structure visualizer to pop up a window showing the full contents of the node.

Figure 5-19 Zooming Out in a Structure Visualizer

Graphic

The selected node is centered in the display window whenever you zoom in or out.

Deleting Nodes

To delete a node (except the root node):

Deleting a node also deletes its children (if any).

More About Pointers in Structures

Note the following about pointers in structure visualizers:

Augmenting the Displayed Information

You may provide a special function for each of your data types that makes additional information available to Prism. This enables Prism to more accurately display the contents of structures with that data type.

For C or C++ union types, you may identify which member of the union is valid. For a pointer within a structure, you may specify that the pointer's target is an array of elements, rather than a single element, and you may further specify the length of the array.

You must embed these specifications within a special function that is compiled and linked with your program being debugged. The function has the following form:

void prism_define_typename (typename *ptr);

where typename is the tag name of one of your structure data types. Thus, you can define one such function for each of your data types. When Prism displays a variable of this type, it checks whether an augmentation function is defined in the program. If so, Prism calls the function, passing a pointer to the instance of the structure being displayed. Your function may then look at the instance to choose valid union members and to size dynamic arrays.

You communicate this information back to Prism by calling the following, defined in prism.h:

void prism_add_array(char *member_name, int len);

This call specifies that the pointer named member_name points to an array of length len. The pointer's name, member_name, is the name of one of the members of the structure, as found in the structure's C (or C++) declaration. The results are undefined if member_name is not a pointer.

void prism_add_union(char *name, char
*valid_member);

This call specifies that the member named name is of type union, and of all the members of this union, only valid_member is to be displayed. Both name and valid_member are names as found in the C or C++ declarations of structs or unions.

Assume that data in the declaration below is a dynamic array:

 struct Vector {
      int len;
      int *data;
   };

The function you write looks like this:

#include "prism.h"
     void prism_define_Vector(struct
Vector *v)
   {
     prism_add_array("data",
v->len);
   }

Assume that the member type discriminates the union value in this example:

 enum Type {INT, DOUBLE};
     struct Value {
      enum Type type;
       union
{
        int
i;
        double
d;
      } value;
    };

The function you write would look like this:

#include "prism.h"
    void prism_define_Value(struct Value
*val)
     {
        if
(val->type == INT)
            prism_add_union("value",
"i");
        else
        prism_add_union("value",
"d");
     }

There are no restrictions on the number or order of calls to prism_add_union and prism_add_array.

Updating and Closing a Structure Visualizer

Left-click on Update in the File menu to update a structure visualizer. When you do this, the root node is re-read; Prism attempts to expand the same nodes that are currently expanded. (The same thing happens if you re-print an existing structure visualizer.)

Left-click on Close in the File menu to close the structure visualizer.

Printing the Type of a Variable

Prism provides several methods for finding out the type of a variable.

From the menu bar - Choose the Whatis selection from the Debug menu. The Whatis dialog box appears; it prompts for the name of a variable. Click on Whatis to display the information about the variable in the command window.

From the source window - Select a variable by double-clicking on it or by dragging over it while pressing the left mouse button. Then hold down the right mouse button; a pop-up menu appears. Choose Whatis from this menu. Information about the variable appears in the command window.

From the command window - Issue the whatis command from the command line, specifying the name of the variable as its argument.

What Is Displayed

Prism displays the information about the variable in the command window. For example,

whatis primes
logical primes(1:999)

Modifying Data

You can use the assign command to assign new values to a variable or an array. For example,

assign x = 0

assigns the value 0 to the variable x. You can put anything on the left-hand side of the statement that can go on the left-hand side in the language you are using-- for example, a variable or a Fortran array section.

If the right-hand side does not have the same type as the left-hand side, Prism performs the proper type coercion.

Changing the Radix of Data

Use the command value = base to change the radix of a value in Prism. The value can be a decimal, hexadecimal, or octal number. Precede hexadecimal numbers with 0x; precede octal numbers with 0 (zero). The base can be D (decimal), X (hexadecimal), or O (octal). Prism prints the converted value in the command window.

For example, to convert 100 (hex) to decimal, issue this command:

0x100=D

Prism responds:

256

Printing the Names and Values of Local Variables

Use the dump command, followed by the name of a function or procedure, to print the names and values of all local variables in that function or procedure. If you omit the function name, dump uses the current function. If you specify a period, dump prints the names and values of all local variables in the functions in the stack.

Printing Pointers as Array Sections

Prism allows you to print simple arrays by section. For example, assuming the following declarations and code,


double da[]={0.1,1.1,2.1,3.1,4.1,5.1,6.1,7.1,8.1,9.1,10.1};
double *pd=da;
int a[]={0,1,2,3,4,5,6,7,8,9,10};
int *pa=a;
int *par[10];
int **ppi=par;
void *ptr=(void*)da;
...
for(i=0;i<10;i++)
   par[i]=&a[9-i];
<------ assume that the program is stopped here ------
...

you can print array a by section:

print a[1:5:2]
a[1:5:2] = 
(1:3) 1 3 5

Prism allows you to view a pointer as a one-dimensional array, by specifying a section when printing the pointer. For example:

print pa[1:5:2]
pa[1:5:2] = 
(1:3) 1 3 5

Prism allows you to dereference an array of pointers if you specify the elements to be dereferenced by using sections. If the array element is a pointer, then Prism allows you to the dereference the section:

*par[1:5:2] =
(1:3) 8 6 4

Prism allows you to cast pointers:

print ((double*)ptr)[1:4:2]
((double*)ptr)[1:4:2] = 
(1:2) 1.100000000000000      3.100000000000000

Currently, Prism supports only one level of dereferencing. Assuming this declaration:

int **appi[2]; 

Prism does not support:

print **(appi[0:1])

Although Prism allows one level of dereference for sections, Prism does not support indexing. Thus, Prism allows:

print *par[1:5:2]

but Prism does not allow:

print par[1:5:2][0]

Visualizing Multiple Processes in MP Prism

When you print or display an object in MP Prism, the data is shown for all processes in the pset you specify (in the current pset, if you do not include a pset qualifier). Choosing the Print or Display selection from the Debug menu prints or displays data for processes in the current pset.

If there is only one process in the pset, the visualizer that is displayed is no different from the visualizer you would see in scalar Prism.

If there is more than one process in the pset, Prism adds a dimension to the visualizer. The extra dimension represents the processes in the set. For example, if the variable is scalar, Prism displays a 1-dimensional array that represents the value of the variable in each process. If you are printing a 1-dimensional array, Prism uses a 2-dimensional visualizer.

For C programs, axis 0 represents the processes. For Fortran 77 programs, the highest-numbered axis represents the processes.

Prism can aggregate data from multiple processes only if the expression has the same size and number of dimensions in each process; if it doesn't, Prism prints an error message.

In the example shown in Figure 5-20, the variable board is an 8x8 array (representing a chess board); the current pset contains four processes. Therefore, MP Prism displays a 3-dimensional visualizer. Axis 0 represents the processes. The figure shows the values of board in the first process in the set. You would drag the white bar in the slider portion of the data navigator to display the values in the other processes in the set. (Note that, for a 2-dimensional Fortran array, where axis 3 would represent the processes, you might want to rearrange the display axes so that axis 3 is on the slider. You can do this by clicking in the box to the left of the slider and changing the number to a 3.)

Figure 5-20 Visualizer in MP Prism (Threshold Representation)

Graphic

To find out the value and process number for an element, shift-click on the element.

Printing to the history region, or in commands-only Prism, works the same way. Axis 0 represents the processes. Here is some of the history-region output for the data shown below:


(prism all) print board
 board = 
 process 0
  (0,0,0:4)   4   1     0    3     0 
  (0,0,5:7)   -1  0     -4
  (0,1,0:4)   2   1     0    0     0 
  (0,1,5:7)   0   -1    0
  (0,2,0:4)   3   1     0    0     0 
  (0,2,5:7)   2   -1    -3
  (0,3,0:4)   5   0     0    0     -1 
  (0,3,5:7)   0   0     -5
  (0,4,0:4)   4   0     0    -2    0 
  (0,4,5:7)   0   0     -6
  (0,5,0:4)   0   1     0    0     0 
  (0,5,5:7)   0   -1    0
  (0,6,0:4)   0   1     0    0     0 
  (0,6,5:7)   0   -1    0
  (0,7,0:4)   6   -1    0    0     0 
  (0,7,5:7)   0   -1    -4
 process 1
  (1,0,0:4)   4   1     0    3     0 
  (1,0,5:7)   -1  0     -4
  (1,1,0:4)   2   1     0    1     0    ... 

The elements of axis 0 do not necessarily correspond to the numbers of the processes they represent. For example, if you were visualizing a variable in pset (1, 3, 5, 7), element 0 of axis 0 would represent process 1, element 1 would represent process 3, and so forth.

MP Prism provides a Cycle visualizer window you can use to display the values of a variable in the cycle pset; see " The cycle Pset". If you issue the command

print x on cycle

Prism displays a window containing the value of x in the current process of the current pset. If you then issue the cycle command or otherwise cycle through the members of the cycle pset, this window automatically updates to display the value of x in the next member of the set. This provides a convenient way of examining a variable in a series of processes.

Visualizing MPI Message Queues

Use the Prism MPI queue visualizer to examine the message queues created by your Sun MPI program. The visualizer shows you the status of messages generated by nonblocking send and receive routines that have not been reaped by a call to MPI_Test or MPI_Wait.

By showing you the state of the queue, detailing the messages that have not completed, Prism gives you clues regarding where your program's logic can be tuned.

The Prism queue visualizer also shows you unexpected receive routines, indicating performance or correctness problems:

In addition to viewing the status of messages, you can also view the contents of the messages themselves to ensure that the correct data was transmitted.


Note -

Prism does not display blocking sends and receives on message queues. If a blocking routine such as an MPI_Send hangs your program, you can use Prism to display a stack backtrace to find the problem, showing the MPI_Send present on the stack. Prism also does not display MPI generalized requests.


Launching the MPI Queue Visualizer

To launch the MPI queue visualizer, choose the MPI Msgs selection under the Prism Debug menu. This selection is available only when a program linked to the Sun MPI library has been loaded into Prism. See Figure 5-23 for an example.

Using the MPI Queue Visualizer

Each row of messages displayed in the message queue window corresponds to a process rank, numbered from zero. The following sections describe how each part of the MPI queue visualizer window affects the display of messages.

Selecting the Queue to Visualize

Use the View menu to select the queues to visualize. You can view three classes of MPI queues for each rank:

You can view queues only when a rank has stopped. Otherwise, the visualizer displays the label running for that rank. Prism re-evaluates the queue every time the rank stops.

Zooming Through Levels of Message Detail

The MPI queue visualizer opens, by default at zoom level three. Using the Zoom buttons, you can zoom through four levels of message detail. The levels are:

Examples of the zoom levels are:

  1. Figure 5-21 shows a single pixel per message. This zoom level is useful when examining very large MPI jobs.

Figure 5-21 Queue Visualizer at Zoom Level One

Graphic

  1. Figure 5-22 shows a simple box per message (the size of the box increases with the size of the message).

Figure 5-22 Queue Visualizer at Zoom Level Two

Graphic

  1. Figure 5-23 shows a single label on message. Clicking the buttons on the Show menu toggles the labels. Label choices are Source/Destination and Tag.

Figure 5-23 Queue Visualizer at Zoom Level Three

Graphic

  1. Figure 5-24 shows the entire message.

Figure 5-24 Queue Visualizer at Zoom Level Four

Graphic

Controlling the Values of Message Labels

Use the toggle buttons under Show on the MPI queue visualizer to control the value of the message labels. Select Source/Dest to show the source or destination rank for the message; select Tag to show the MPI tag of the message. The Show toggle affects the display of messages at zoom level three only.

Sorting Messages

You can sort messages by row or by column according to several criteria, by choosing selections from the Sort Rows By and Sort Columns By option menus.

Table 5-1 Column Sort Criteria

Sort Criteria  

Description 

Order posted 

Sort messages by the order in which messages are posted by the MPI program, with the earliest posted on the left. This is the default. The implementation of MPI Sends of large messages may queue and dequeue the message several times once the rendezvous begins, at which point the posted order seen in the visualizer no longer matches the programmatic order. At present there is no way to distinguish such messages.  

Source/Destination 

Sort by the source rank for receives and the destination rank for sends. 

Tag 

Sort by the messages' tag values. 

Size 

Sort by size in bytes, from small to large. 

Communicator 

Sort by communicator address. 

Protocol 

Group together messages sent with the same transport protocol. Protocols are loopback, shared memory, RSM, and TCP. 

Table 5-2 Row Sort Criteria

Sort Criteria 

Description 

Rank 

Sort rows from the smallest to the largest process rank (the default). 

Message Count 

Sort by the number of messages posted. 

Message Volume 

Sort by the sum of the sizes, in bytes, of all messages for each rank. 

Since the graphical size of a message is not linearly proportional to the message length in bytes, a number of small messages may occasionally extend further to the right in the visualizer than a single large message of greater total size.

Displaying Message Fields

Click individual messages to open the Message dialog box, shown in Figure 5-25.

Figure 5-25 Message Dialog Box

Graphic

The fields in the Message dialog box are described in Table 5-3.

Table 5-3 Message Dialog Box Fields

Label 

Description 

Buffer 

The address of the message. 

Size 

The length (in bytes) of the message. 

Tag 

The MPI tag argument passed in the call to post the message. 

Comm 

The name of the MPI communicator in which the message belongs, or the communicator's address if it is unnamed. Click on the Communicator View button to display the Communicator dialog box. 

To 

The rank of the destination of the message. Prism displays this field only for posted sends. 

From 

The rank of the sender of the message. Prism displays this field only for posted receives or unexpected receives. 

Protocol 

The implementation method by which the message has been sent. Possible values are: loopback, shared memory, RSM, and TCP. 

Data Type 

The MPI data type of the message, with the size of a single data type element in bytes. Click on the Data Type View button to display the Data Type dialog box. See "Data Types" for more information about the Data Type dialog box.The View button is available only for user-defined data types.

Contents 

The contents of the message. Click on the triangular button to open or close the contents area. Click on More repeatedly to scroll through more of the message, until the whole message has been displayed. 

When the Message dialog box displays a posted receive, it displays the value of the buffer address as null (indicating that no buffer has been allocated), and disables the Contents button.

When the Message dialog box displays an unexpected receive, it shows the delivered message with no data type. This characteristic is due to MPI design, since a posted receive declares the data type. Here too, the Contents button is disabled, and the visualizer displays the value of the buffer address as null.

Displaying Communicator Data

Prism displays MPI Communicators in the Communicators region of the MPI queue visualizer window. The visualizer does not display all the communicators that have been created in an MPI program; rather, it displays only communicators referenced by currently posted messages. Thus, if no messages are visible, then the visualizer displays no communicators.

Prism displays as many as three distinct communicators. Each communicator is color coded, and messages are drawn using the color of their communicator. If more than three communicators are present, then the excess are grouped together under a single color labeled Others.

You can change colors for the communicators by setting the following X resources in the Prism application defaults file:

For information about modifying values in the Prism applications defaults file, see " Changing Prism Defaults".

Figure 5-26 shows the Communicator dialog box. Press any of the communicator buttons to reveal the Communicator dialog box, displaying the following information:

Figure 5-26 Communicator Dialog Box

Graphic

Data Types

Figure 5-27 shows the Data Type dialog box. Display the Data Type dialog box by clicking on the Data Type View button in a Message dialog box. The fields of this dialog box are:

Figure 5-27 Data Type Dialog Box

Graphic

Displaying and Visualizing Sun S3L Arrays

In a multiprocess Sun MPI program, a parallel array is an array whose elements may be distributed among the processes of the program (every process holds only part of the global array). Prism can extract the global dimensionality and distribution information from these arrays and manipulate them as single entities. For the purpose of this discussion, arrays that are not distributed (arrays that belong in their entirety to a single process) are referred to as regular arrays.

Sun S3L's parallel array syntax is based on array handles, which define the properties of the parallel array. Using Prism's type command to identify a Sun S3L array handle and specify its basic data type, you can use Prism to display and visualize the Sun S3L parallel array.

Basic data types are int, float, double, complex8, and complex16. Before using the type command, Prism recognizes the array handle as a simple variable. In Fortran 77 and Fortran 90, the array handle is a variable of type integer*8. In C, the array handle is type S3L_array_t.

Table 5-4 S3L Array Demonstration Program

c Copyright (c) 1998, by Sun Microsystems, Inc. 

c All rights reserved 

program test_prism_s3l 

include 's3l/s3l-f.h' 

c In f77 programs, s3l arrays are integer*8  

integer*8 a 

integer*4 ext(2),local(2),ier 

c Initialize the S3L library and the prism/s3l interface. 

call s3l_init(ier) 

 

c Declare a parallel S3L array of size 2 x 3,  

c with the second dimension distributed. 

ext(1) = 2 

ext(2) = 3 

 

local(1) = 1 

local(2) = 0 

 

call s3l_declare(a,2,ext,S3L_float,local, 

.S3L_USE_MALLOC,ier) 

 

c Initialize the array randomly by using S3L_rand_lcg 

 

call s3l_rand_lcg(a,123456,ier) 

w = 1.0 

c free the resources associated with the parallel S3L array 

 

call s3l_free(a,ier) 

 

c finalize the S3L library. 

 

call s3l_exit(ier) 

c  

stop  

end 

For example, before using the type command, the whatis command reports that the Sun S3L array handle, a, has been declared an integer*8 in the Fortran program in Table 5-4.

Before applying the Prism type command, Prism identifies the array handle, a, as a variable of type integer*8:

(prism all) whatis a
integer*8 a

Issue the type command, associating the Sun S3L handle, a, with the basic data type float, the same type used to declare the element type of the Sun S3L array in your program:

(prism all) type float a
"a" defined as "float a"

Now Prism recognizes a as a Sun S3L handle and can call the appropriate Sun S3L routines to get the array's data and extents.

(prism all) type float a
"a" defined as "float a"

Prism now recognizes a as a Sun S3L array. You can now use Prism to display the values of a using the print command:

(prism all) print a
a = 
(0:1,0) 0.000000      1.000000 
(0:1,1) 0.1000000     1.100000 
(0:1,2) 0.2000000     1.200000

In all respects, you can use a as you would use any array in Prism. For example:

(prism all) assign a=9
(prism all) print a
a = 
(0:1,0) 9.000000      9.000000 
(0:1,1) 9.000000      9.000000 
(0:1,2) 9.000000      9.000000 
(prism all) print layout a
layout (a) =
a = 
(0:1,0) 0 0
(0:1,1) 0 0
(0:1,2) 1 1
  (prism all) print layout(a) on dedicated

Sun S3L arrays are distributed across multiple processes. Since each process has an identical view of a, Prism prints the values of the array only once.

However, when Prism prints a regular array, larr,Prism prints the values of larr separately for each process. For regular arrays such as larr, the values of the array can be different on different processes, since every process has its own copy. For example:

(prism all) print larr
larr = 
Pset 0
(1:2,1,1) 0.000000      1.000000 
(1:2,2,1) 0.1000000     1.100000 
(1:2,3,1) 0.2000000     1.200000 
Pset 1
(1:2,1,2) 0.000000      1.000000 
(1:2,2,2) 0.1000000     1.100000 
(1:2,3,2) 0.2000000     1.200000 
(prism all) assign larr=larr*5 pset 0
(prism all) print larr
larr = 
Pset 0
(1:2,1,1) 0.000000      5.000000 
(1:2,2,1) 0.5000000     5.500000 
(1:2,3,1) 1.000000      6.000000 
Pset 1
(1:2,1,2) 0.000000      1.000000 
(1:2,2,2) 0.1000000     1.100000 
(1:2,3,2) 0.2000000     1.200000

Expressions involving Sun S3L arrays (after having issued the type command), unless they include a variable in the user program, are printed only once. Their values are the same for all processes:

(prism all) print 10* a - 1
10* a - 1 = 
(0:1,0) -1.000000000000000     9.000000000000000 
(0:1,1) 0.00000000000000000   10.00000023841858 
(0:1,2) 1.000000029802322      11.00000047683716 
(prism all) print a
a = 
(0:1,0) 0.000000      1.000000 
(0:1,1) 0.1000000     1.100000 
(0:1,2) 0.2000000     1.200000 

However, if you use a Sun S3L array in an expression that includes a variable, then Prism replicates the array on each process and then evaluates the array separately on each process. This example adds a variable, w, to a. Prism prints the results for both processes.

(prism all) print w
w = 
(1:2) 0           0 
(prism all) print a+w
a+w = 
Pset 0
(0:1,0,1) 0.000000000000000      1.000000000000000 
(0:1,1,1) 0.1000000014901161     1.100000023841858 
(0:1,2,1) 0.2000000029802322     1.200000047683716 
Pset 1
(0:1,0,2) 0.000000000000000      1.000000000000000 
(0:1,1,2) 0.1000000014901161     1.100000023841858 
(0:1,2,2) 0.2000000029802322     1.200000047683716