Getting Started | Documentation | Glish | Learn More | Programming | Contact Us |
Version 1.9 Build 1556 |
|
The AIPS++ group is attempting to use Glish as an end-user command line interpreter (CLI). Since Glish was originally designed for a very different purpose (instrument control) some work and experimentation will be required for Glish to be truly suitable. Much of the work will be ``environmental'': command line editing9.32, on-line help, and the like. Some of this work can, however, can be done by establishing programming conventions within Glish so the end user sees a consistent and convenient way of interacting with Glish values and functions.
Neither of the obvious alternatives:
Instead, polymorphic methods seemed to solve the problem readily. Additionally, the OO convention diminishes the ``impedance mismatch'' between the C++ libraries and the CLI user, allowing the proxy objects to more closely follow the C++ versions.
Obviously an idea solution would be for Glish to provide built-in support, , i.e. evolve towards S+ from S. We shall investigate the costs and benefits of doing so.
Glish has excellent facilities for asynchronous programming. The full set of facilities -- whenever statements, subsequences, etc., -- is far richer than the typical user will to want to deal with.
We can instead establish a convention where the user specifies during the function invocation whether or not the execution takes place asynchronously. In the latter case, the user also needs to know where to find the result, and to know when the computation has finished.
x := fft(y)*z; # fft defaults to synchronous; just use it as any # other function. fft(y, async=T); # Run fft asynchronously. Eventually the ... other work ... # user gets notified that it has finished. x := results.fft*z; # Get the result and compute with it
While in the above example ``results.fft'' is an array, it could clearly just as easily be a Glish record for computations which produce multiple output values.
A flaw in the previous example is that since there is only one place to look for the result, only one asynchronous ``fft'' may take place at a time, since there's only one place to look for it. This may not only be inconvenient, it would disallow the user to take advantage of coarse parallelism by spreading computations out over multiple cpu's of a single machine, or multiple hosts on a network.
For example suppose the user is on a four processor machine and wants to fft a cube a plane at a time, spread over all four processors.
nplanes := cube::shape[3]; for (i in 1:nplanes) { request[i] := fft(cube[,,i], async=T, client_number=i%4+1); } wait_for(requests); for (i in 1:nplanes) { cube[,,i] := result[request[i]]; }
A slightly more complicated example would have the client adaptively fill up the fastest CPU's in case some are faster than others (e.g., sharing with another user). Note that this example assumes that the underlying client (i.e., compiled binary) is single threaded; that is, we need one client per CPU. If this wasn't the case, we could just leave out the client number.
A similar example would allow the computation to be spread over a network of machines by specifying host = hostname.
Here we have made the user remember a request number, where before they only had to remember ``result.fft.'' The increase in generality appears to me to be worth the price.
The asynchronous idiom presented here has not been implemented, although it should be straightforward