INTC NUMWORKERS: NUMWORKERS := 2 VAL POPSIZE IS 2200: VAL PROBLEMSIZE IS 200: VAL WORK.LENGTH IS 4: VAL REQ.LENGTH IS 4: VAL WORKTIME IS 100: VAL FINISHED IS PROBLEMSIZE+1: VAL COLLENGTH IS POPSIZE*4: VAL NOWORKER IS NUMWORKERS+1: [10]CHAN OF ANY ch.farmer.in, ch.farmer.out: [10][10]CHAN OF ANY ch.network: [10]CHAN OF ANY ch.buffer.in: [10]CHAN OF ANY ch.buffer.out: [10]CHAN OF ANY ch.buffer.req: PLACED PAR INT which.worker, prev.worker: SEQ | farmer SEQ i=1 FOR PROBLEMSIZE+NUMWORKERS SEQ ALT ch.farmer.in[0] ? which.worker SKIP ch.farmer.in[1] ? which.worker SKIP ch.farmer.in[2] ? which.worker SKIP ch.farmer.in[3] ? which.worker SKIP ch.farmer.in[4] ? which.worker SKIP ch.farmer.in[5] ? which.worker SKIP ch.farmer.in[6] ? which.worker SKIP ch.farmer.in[7] ? which.worker SKIP ch.farmer.in[8] ? which.worker SKIP ch.farmer.in[9] ? which.worker SKIP ch.farmer.out[which.worker] ! i | WORK.LENGTH IF i=1 prev.worker := NOWORKER i > FINISHED ch.farmer.out[prev.worker] ! NOWORKER | WORK.LENGTH TRUE ch.farmer.out[prev.worker] ! which.worker | WORK.LENGTH IF i > FINISHED ch.farmer.out[which.worker] ! NOWORKER | WORK.LENGTH TRUE ch.farmer.out[which.worker] ! prev.worker | WORK.LENGTH prev.worker := which.worker ch.farmer.out[which.worker] ! NOWORKER | WORK.LENGTH -- next is not valid PLACED PAR i=0 FOR NUMWORKERS INT prev,next,workno,dummy,lastwork: SEQ | generator workno := 0 WHILE workno < FINISHED SEQ ch.buffer.req[i] ! i | WORK.LENGTH ch.buffer.out[i] ? prev PAR SEQ | recvprev IF prev <> NOWORKER SEQ ch.network[i][prev] ! workno | WORK.LENGTH ch.network[prev][i] ? dummy TRUE SKIP SEQ | recvmodel ch.buffer.req[i] ! i | WORK.LENGTH ch.buffer.out[i] ? workno ch.buffer.req[i] ! i | WORK.LENGTH ch.buffer.out[i] ? next OUTSTRM ! i,workno,prev,next NOTE(gen.start) IF workno < FINISHED SERV(10) -- generation of one column is almost constant for fixed populaton size TRUE SKIP NOTE(gen.end) IF next <> NOWORKER SEQ ch.network[next][i] ? lastwork -- the next worker has already genes 0..lastwork, do not send it ch.network[i][next] ! dummy | (workno-lastwork) * (COLLENGTH/100) -- ECS is 100x slower TRUE SKIP PLACED PAR i=0 FOR NUMWORKERS INT workno,geneno,prev,next,pprev,pnext,tmp: SEQ | worker ch.farmer.in[i] ! i | REQ.LENGTH ch.farmer.out[i] ? workno ch.farmer.out[i] ? pprev ch.farmer.out[i] ? pnext WHILE workno < FINISHED SEQ prev := pprev next := pnext geneno := workno PRI PAR SEQ | getwork ch.farmer.in[i] ! i | REQ.LENGTH ch.farmer.out[i] ? workno ch.farmer.out[i] ? pprev ch.farmer.out[i] ? pnext SEQ | builder ch.buffer.in[i] ! prev | WORK.LENGTH NOTE(build.start) OUTSTRM ! i,geneno,geneno*75/10 SERV(geneno*75/10) -- builging of geneno-th tree is proportional to geneno, pop. size is assumed to be fixed NOTE(build.end) ch.buffer.in[i] ! geneno | WORK.LENGTH ch.buffer.in[i] ! next | WORK.LENGTH ch.buffer.in[i] ! pprev | WORK.LENGTH ch.buffer.in[i] ! workno | WORK.LENGTH ch.buffer.in[i] ! pnext | WORK.LENGTH PLACED PAR i=0 FOR NUMWORKERS [1000]INT buffer: INT bufstart, bufend, dummy: SEQ | bufproc bufstart := 1 bufend := 1 WHILE TRUE ALT ch.buffer.in[i] ? buffer[bufend] bufend := bufend + 1 ch.buffer.req[i] ? dummy SEQ IF bufstart = bufend ch.buffer.in[i] ? buffer[bufstart-1] TRUE bufstart := bufstart + 1 ch.buffer.out[i] ! buffer[bufstart-1] | WORK.LENGTH -- ....................................................................... NODE i=0 FOR NUMWORKERS+1 NODE nn : ICD = 0.0, ICS = 10000, ECD = 500, ECS = 0.1, SPD = 0.001 MAP nn[0]: farmer MAP i=0 FOR NUMWORKERS MAP nn[i+1]: generator[i], worker[i], bufproc[i] -- .......................................................................