[Swift-user] Questions on use of iterate statement

Michael Wilde wilde at mcs.anl.gov
Fri Feb 20 07:07:31 CST 2009

Im trying to use iterate to test successive sets of parallel simulations 
for a termination condition, and can't find a way to do this.

Ive distilled, I think, the problem down to the following.

One can say this:

iterate i {
   int j = i * i;
} until (i>3);

but not this:

iterate i {
   int j = i * i;
} until (j>15);

because the value j, computed by the "simulation" i*i is not in scope in 
the termination condition.

In my case, the simulation is a protein fold in a parallel foreach. Each 
simulation computes a set of files. After each set of parallel 
simulations completes, I need to check the set of result files to see if 
   they have achieved a termination condition (either reached a 
threshold or a limit on the number of attempts).

I may be stumbling on some strange array closing problems in the real 
case, so Ive tried to distill the problem into a simpler test case.

The current "real" code is pasted at the end of this message (lines are 
wrapped; file is http://www.ci.uchicago.edu/~wilde/oops8.swift).

An east-to-run test case which I think shows a similar problem is this:

string protein[] = ["prot1","prot2"];
int iter[] = [0,1,2];

(boolean rc) done (int i[]) // fake termination test
   if (i[0] == 3) {
     rc = true;
   else {
     rc = false;

foreach p in protein {
   iterate i {  // do sets of parallel simulations
                // until convergence achieved or limit reached
     int result[]; // Holds results of 1 set of parallel simulations
     foreach j in iter { // do a set of "iter" simulations in parallel
       string out=@strcat("output/r",i,"/","prot1",".",j);
       trace (out);
       result[j] = i;
   } until (i==3);
//} until (done(result));

This works, and produces the expected series of output trace lines.

But when i try to use the alternative termination test "done(result)" I get:

Could not start execution.

Compile error in foreach statement at line 15: Compile error in 
procedure invocation at line 25: Variable result is undefined.

because, as in the trivial initial example, the array results is out of 
scope at that point. I cant figure out how to write a termination 
expression that can access the values from within the iterate{} body.

So how do I pass the results of the set of simulation to a function like 
"done()" to check a termination condition?

My real code (below) hangs after the first set of simulations, which 
makes me think that it is (perhaps, in addition to the problem above) 
stumbling into an array closing issue. But I think that a solution to 
the mock simulation example above may help me solve the actual problem.



The current "real" code is below (lines are wrapped; file is 

type Fasta;
type SecSeq;
type PDB;
type RetValFile;

type OOPSSecStr;
type OOPSLog;
type OOPSEnergy;
type OOPSpdt;
type OOPSrmsd;
type OOPSLibrary;

app (OOPSpdt pdt, OOPSEnergy e, OOPSLibrary lib, OOPSSecStr secstr, 
OOPSrmsd rmsd, OOPSLog log)
     runoops (Fasta fasta, SecSeq secseq, PDB pdb, int jobnum, string 
{ simoops @fasta @secseq @pdb @pdt @rmsd jobnum cfgParams stdout=@log; }

app (RetValFile rv) roundDoneTest ( OOPSpdt pdts[] )
{ testifdone @filename(pdts[0]) @rv; }

(int rc) roundDone (OOPSpdt pdts[] ) { RetValFile rv = 
roundDoneTest(pdts); rc = readData(@rv); }

string config [] = readData(@arg("params"));

int iter[]=[ 0 : @toint(@arg("niter","1")) - 1 ];
string protein[] = readData(@arg("plist"));

foreach p in protein {
     iterate i {
         OOPSpdt result[];
         foreach j in iter {

             // map inputs

             Fasta fasta 
             SecSeq secseq 
             PDB native 

             // map outputs

             string out=@strcat("output/r",i,"/",p,".",j);

             OOPSpdt pdt <single_file_mapper;file=@strcat(out,".pdt")>;
             OOPSEnergy e <single_file_mapper;file=@strcat(out,".Energy")>;
             OOPSLibrary lib 
             OOPSSecStr secstr 
             OOPSrmsd rmsd <single_file_mapper;file=@strcat(out,".rmsd")>;
             OOPSLog log <single_file_mapper;file=@strcat(out,".log")>;

             // run oops

             ( pdt, e, lib, secstr, rmsd, log) = runoops( fasta, secseq, 
native, j, config );
             result[j] = pdt;
     } until (roundDone(result) == 1);

More information about the Swift-user mailing list