next up previous contents index
Next: Schedules Up: A Distributed Array Communication Previous: Irregular collective communications   Contents   Index


I/O

Support for I/O in the current HPJava version of Adlib is rudimentary. In general any communications needed to input and output parallel data structures are left as the reponsibility of the HPJava programmer--such operations may, for example, be built up from standard Java I/O features, together with the broadcast and remap functions of Adlib. But to help you get started we provide a couple of ``convenience methods''. The most interesting is aprintf(). This is modelled on the C printf() function. Its arguments are a control string and a list of distributed arrays. The effective prototypes are

\begin{displaymath}
\begin{minipage}[t]{\linewidth}\small\begin{tabbing}
\verb$ ...
...e1,$ \\
\>$T_2$\verb$  ...

For now a maximum of three input arrays is allowed (but this is just an interface issue). If more than one array is specified, all should have the same shape. But they can have any, unrelated distribution format.

The control string (like all arguments of Adlib methods) should be a ``coherent'' expression: it takes the same value for all processes in the active group. It has basically the same role and the same format as the control string of the printf() function in the C standard library. But the aprintf() operation performs its output ``elementally''. If there is a single array argument it is as if a printf() function was called repeatedly, once for each element of the array. For example

\begin{displaymath}
\begin{minipage}[t]{\linewidth}\small\begin{verbatim}floa...
...dlib.aprintf(''a[i] = %f\n'', a) ;
\end{verbatim}\end{minipage}\end{displaymath}

would print out something like:

\begin{displaymath}
\begin{minipage}[t]{\linewidth}\small\begin{verbatim}a [i...
....0
a [i] = 30.0
a [i] = 40.0
...\end{verbatim}\end{minipage}\end{displaymath}

If there are two array elements, it is as if a printf() function was called once for each matching pair of array elements, passing two scalar arguments to the printf(). So

\begin{displaymath}
\begin{minipage}[t]{\linewidth}\small\begin{verbatim}int ...
...aprintf(''a[%d] = %f\n'', ix, a) ;
\end{verbatim}\end{minipage}\end{displaymath}

would print out something like:

\begin{displaymath}
\begin{minipage}[t]{\linewidth}\small\begin{verbatim}a [0...
....0
a [3] = 30.0
a [4] = 40.0
...\end{verbatim}\end{minipage}\end{displaymath}

Because it is quite common to want to print the current index value there is a special format sequence allowed in the control string to do just this: the

\begin{displaymath}
\begin{minipage}[t]{\linewidth}\small\begin{verbatim}Adlib.aprintf(''a[%R0] = %f\n'', a) ;
\end{verbatim}\end{minipage}\end{displaymath}

produces the same output as the version above. The format %R0 interpolates the index value into the string without the need to initialize an extra array of integers.

All this works for multidimensional arrays as well. In a pseudocode notation, the general behaviour of aprintf() is like

\begin{displaymath}
\begin{minipage}[t]{\linewidth}\small\begin{tabbing}
\verb$f...
...1}$\verb$],$ \\
\>\verb$...)$ \\
\end{tabbing}\end{minipage}\end{displaymath}

where $(N_0, \ldots, N_{R-1})$ is the shape the arrays. The integer value $i_0$ is interpolated into the output wherever there is a %R0 in the control string; the value $i_1$ is interpolated wherever there is a %R1; and so on (a field width modifier is also allowed with %R$D$ format, just as with %d format). The imaginary elemental printf operation outputs to System.out on the root process of the active process group.

This code, for example:

\begin{displaymath}
\begin{minipage}[t]{\linewidth}\small\begin{verbatim}floa...
...rintf(''a[%R0, %R1] = %f\n'', a) ;
\end{verbatim}\end{minipage}\end{displaymath}

might print out something like:

\begin{displaymath}
\begin{minipage}[t]{\linewidth}\small\begin{verbatim}a [0...
...0
a [1, 1] = 11.0
a [1, 2] = 12.0\end{verbatim}\end{minipage}\end{displaymath}

where we assumed, for the sake of illustration, an unusually small 2 by 3 distributed array.

For large, possibly multidimensional, arrays one would probably prefer a more tabular layout. The aprintf() method provides one special format to support more creative line breaking. The aprintf() format %N by itself behaves exactly like the \n escape sequence--it inserts a newline into the output. But %N allows an integer modifier. This looks like a printf() field width modifier, but it is interpretted differently--it defines the frequency with which the newline is printed: if the value of the modifier is $w$, the newline is only printed in every $w$th elemental print operation. So if we replace the aprintf() call in the previous example with:

\begin{displaymath}
\begin{minipage}[t]{\linewidth}\small\begin{verbatim}Adli...
...ntf(''a[%R0, %R1] = %f %3N'', a) ;
\end{verbatim}\end{minipage}\end{displaymath}

we get output something like

\begin{displaymath}
\begin{minipage}[t]{\linewidth}\small\begin{verbatim}a [0...
...0.0 a [1, 1] = 11.0 a [1, 2] = 12.0\end{verbatim}\end{minipage}\end{displaymath}

By specifying normal C-like field width modifiers on the %f format one could line up columns more beautifully, if so desired.

As a final trick, we can build the control string at run-time, allowing the number of columns to reflect the actual shape of the array:

\begin{displaymath}
\begin{minipage}[t]{\linewidth}\small\begin{verbatim}Adli...
...'' + a.rng(1).size() + ''N'', a) ;
\end{verbatim}\end{minipage}\end{displaymath}

Now if the range $y$ has size 8, say, the control string evaluates to "%f %8N", and a newline is printed after every 8 elemental outputs, i.e. we get a newline at the end of every row of the array, whatever the actual shape of the array. With a second modified %N format in the control string, one might use similar tricks to insert a blank line to delimit the end of each ``plane'' of a three dimensional array. And so on.

The aprintf() method is useful for testing and demonstrating programs. It is less obvious that it is useful for production codes. We expect distributed arrays to be large, and in general it probably it doesn't make much sense to print thousands or millions of elements to standard output. With this in mind the current implementation has not been carefully optimized--it is quite slow.

For convenience there are also two much simpler methods in Adlib for printing a ``global'' String value. These are called gprint() and gprintln(). They have interfaces:

\begin{displaymath}
\begin{minipage}[t]{\linewidth}\small\begin{verbatim}gpri...
...ng string)
gprintln(String string)\end{verbatim}\end{minipage}\end{displaymath}

All they do is output string to System.out on the root process of the active process group.


next up previous contents index
Next: Schedules Up: A Distributed Array Communication Previous: Irregular collective communications   Contents   Index
Bryan Carpenter 2003-04-15