void kill_workers () { printf ("INFO: Killing the workers\n") ; /* kill all the worker */ pvm_initsend(PvmDataDefault) ; pvm_mcast (Worker_tids,NUMBER_OF_WORKERS,KILL) ; /* close the window */ auxCloseWindow() ; /* exit pvm */ pvm_exit() ; /* free the pixel buffer */ free (Pixel_buffer) ; /* free the pixel buffer */ free (Image_buffer) ; /* free the worker tids */ free (Worker_tids) ; /* exit the program */ auxQuit() ; }
void sendEof(FilterPlacement *pFilterP) { pvm_initsend(PvmDataRaw); int tipo_msg = MSGT_EOF; pvm_pkint(&tipo_msg, 1, 1); //sends the EOF message for all instances of the filter pvm_mcast(pFilterP->tids, pFilterP->numInstances, 0); }
void mcast_accept_msg(struct state_info info) { char diag[200]; GQueue *waiting_req_q = (*info.my_lift_number == LIFT_1) ? info.waiting_req_q1 : info.waiting_req_q2; int len = g_queue_get_length(waiting_req_q); // diag_msg(info.mstrtid, info.mytid, "*** 0"); int *tids = malloc(len * sizeof(int)); int i = 0; sprintf(diag, "*** %d processes awaiting accepts", g_queue_get_length(info.waiting_req_q)); diag_msg(info.mstrtid, info.mytid, diag); while (!g_queue_is_empty(waiting_req_q)) { int *tid = g_queue_pop_head(waiting_req_q); int *sender_weight_ptr = g_hash_table_lookup(info.skiers_weights, tid); int *lift_free = (*info.my_lift_number == LIFT_1) ? info.lift1_free : info.lift2_free; *lift_free -= *sender_weight_ptr; tids[i] = *tid; i++; sprintf(diag, "*** mcast MSG_ACCEPT to %d [weight=%d]", *tid, *sender_weight_ptr); diag_msg(info.mstrtid, info.mytid, diag); } *info.local_clock += 1; int tag = MSG_ACCEPT; pvm_initsend(PvmDataDefault); pvm_pkint(&tag, 1, 1); pvm_pkint(&info.mytid, 1, 1); pvm_pkint(info.local_clock, 1, 1); pvm_mcast(tids, len, tag); sprintf(diag, "mcast MSG_ACCEPT to %d waiting processes [timestamp=%d]", len, *info.local_clock); diag_msg(info.mstrtid, info.mytid, diag); }
int msend_msg(int *recipients, int number, int msgtag) { int info; PVM_FUNC(info, pvm_mcast(recipients, number, msgtag)); return(info); }
value Pvm_mcast(value tids, value msgtag) { int *ctids, i, err; int n = Wosize_val(tids); ctids = (int*)malloc(sizeof(int)*(n+1)); for(i = 0; i < n; i++) ctids[i] = Int_val(Field(tids, i)); err = pvm_mcast(ctids, n, Int_val(msgtag)); free(ctids); if (err < 0) TreatError(err); return; }
void BroadStr(char *str, int tids[], int ntids, int MsgType) { int info; info = pvm_initsend(PvmDataDefault); if (info) { pvm_pkstr(str); pvm_mcast(tids,ntids, MsgType); } else { fprintf(stderr, "Problems with BroadStr : Message type %d\n", MsgType); } }
void BroadInt(int IntBuf[], int n, int tid[], int ntid, int MsgType) { int info; info = pvm_initsend(PvmDataDefault); if (info) { pvm_pkint(IntBuf, n, 1); pvm_mcast(tid, ntid, MsgType); } else { fprintf(stderr, "Problems with BroadInt: Message type %d\n", MsgType); } }
void BroadINFO(INFO *data, int n, int tid[], int ntid, int MsgType) { int info; info = pvm_initsend(PvmDataDefault); if (info) { pvm_pkbyte((char *)data, n*sizeof(INFO), 1); pvm_mcast(tid, ntid, MsgType); } else { fprintf(stderr, "Problems with BroadINFO : Message type %d\n", MsgType); } }
void BroadFloat(float *FloatBuf, int n, int tid[], int ntid, int MsgType) { int info; info = pvm_initsend(PvmDataDefault); /*pvm_pkbyte((char *)FloatBuf, n*sizeof(float), 1);*/ if (info) { pvm_pkfloat(FloatBuf, n, 1); /* wences */ pvm_mcast(tid, ntid, MsgType); } else { fprintf(stderr, "Problems with BroadFloat : Message type %d\n", MsgType); } }
void sendEowToAllInputs(FilterSpec * filterSpec) { int i, j; // for each input Port of this filter for(i = 0; i < filterSpec->numInputs; i++) { // i must send 1 Eow for each instace that writes to this filter for(j = 0; j < filterSpec->inputs[i]->fromFilter->filterPlacement.numInstances; j++) { //send our EOW to listeners on the other side int msgType = MSGT_EOW; int taskId = -1; pvm_initsend(PvmDataRaw); pvm_pkint(&msgType, 1, 1); pvm_pkint(&taskId, 1, 1); pvm_mcast(filterSpec->filterPlacement.tids, filterSpec->filterPlacement.numInstances, filterSpec->inputs[i]->tag); } } }
static void find_tree_manager(const int my_tid, int &tm_tid) { struct pvmtaskinfo *taskp = 0; int ntask = 0; pvm_tasks(0, &ntask, &taskp); int * tids = new int[ntask]; int i, k; for (i = 0, k = 0; i < ntask; ++i) { if (taskp[i].ti_ptid != 0) continue; // has a parent, can't be the TM if (taskp[i].ti_tid == my_tid) continue; // self // Otherwise it could be the TM (might be a console...) tids[k++] = taskp[i].ti_tid; } if (tm_tid != 0) { // Check that the given tid is among the candidates for (i = 0; i < k; ++i) if (tids[i] == tm_tid) break; if (i == k) stop("No TM candidate has the given tid... Aborting.\n"); } else { // Broadcast a query to the candidates pvm_initsend(PvmDataRaw); pvm_mcast(tids, k, BCP_ARE_YOU_TREEMANAGER); // Wait for an answer struct timeval tout = {15, 0}; int bufid = pvm_trecv(-1, BCP_I_AM_TREEMANAGER, &tout); if (bufid == 0) stop("No TM candidates replied within 30 seconds... Aborting.\n"); int bytes = 0, msgtag = 0; pvm_bufinfo(bufid, &bytes, &msgtag, &tm_tid); } delete[] tids; }
int main (int argc, char **argv) { int nt; /* number of time samples */ int nz; /* number of migrated depth samples */ int nx,nxshot; /* number of midpoints,shotgathers, the folds in a shot gather */ int flag=1; /*flag to use ft or meter as the unit*/ int dip=65; /*maximum dip angle to migrate*/ int iz,iw,ix,it,oldsx; /* loop counters*/ int ntfft; /* fft size*/ int nw; /* number of wave numbers */ int mytid,tids[NNTASKS],msgtype,rc,i;/*variable for PVM function*/ int nw1,task; int lpad=9999,rpad=9999; /*zero-traces padded on left and right sides*/ float f1,f2,f3,f4; /*frequencies to build the Hamming window*/ int nf1,nf2,nf3,nf4; /*the index for above frequencies*/ int NTASKS=0; /*number of slave tasks to start*/ char cpu_name[NNTASKS][80]; /*strings to store the computers' name*/ int flag_cpu=0; /*flag to control if using NTASKS variable*/ float sx,gxmin,gxmax; /*location of geophone and receivers*/ int isx,nxo,ifx=0; /*index for geophone and receivers*/ int ix1,ix2,ix3,il,ir; /*dummy index*/ float *wl,*wtmp; /*pointers for the souce function*/ float Fmax=25; /*peak frequency to make the Ricker wavelet*/ int ntw,truenw; /*number of frequencies to be migrated*/ float dt=0.004,dz; /*time, depth sampling interval*/ float ft; /*first time sample*/ float dw; /*frequency sampling interval*/ float fw; /*first frequency*/ float dx; /*spatial sampling interval*/ float **p,**cresult,**result_tmp; /* input, output data*/ float **v; /*double pointer direct to velocity structure*/ complex *wlsp,**cp,**cq,**cq1; /*pointers for internal usage*/ char *vfile=""; /* name of file containing velocities */ char *cpufile=""; /* name of file containing CPU name */ FILE *vfp,*cpu_fp; /* hook up getpar to handle the parameters */ initargs(argc,argv); requestdoc(1); /* get optional parameters */ if (!getparfloat("ft",&ft)) ft = 0.0; if (!getparint("nz",&nz)) err("nz must be specified"); if (!getparfloat("dz",&dz)) err("dz must be specified"); if (!getparstring("vfile", &vfile)) err("vfile must be specified"); if (!getparint("nxo",&nxo)) err("nxo must be specified"); if (!getparint("nxshot",&nxshot)) err("nshot must be specified"); if (!getparfloat("Fmax",&Fmax)) err("Fmax must be specified"); if (!getparfloat("f1",&f1)) f1 = 10.0; if (!getparfloat("f2",&f2)) f2 = 20.0; if (!getparfloat("f3",&f3)) f3 = 40.0; if (!getparfloat("f4",&f4)) f4 = 50.0; if (!getparint("lpad",&lpad)) lpad=9999; if (!getparint("rpad",&rpad)) rpad=9999; if (!getparint("flag",&flag)) flag=1; if (!getparint("dip",&dip)) dip=65; if (getparstring("cpufile", &cpufile)){ cpu_fp=fopen(cpufile,"r"); NTASKS=0; while(!feof(cpu_fp)){ fscanf(cpu_fp,"%s",cpu_name[NTASKS]); NTASKS++; } NTASKS-=1; flag_cpu=1; } else /*if cpufile not specified, the use NTASKS*/ if (!getparint("NTASKS",&NTASKS)) err("No CPUfile specified, NTASKS must be specified"); /*allocate space for the velocity profile*/ tshot=nxshot; v=alloc2float(nxo,nz); /*load velicoty file*/ vfp=efopen(vfile,"r"); efread(v[0],FSIZE,nz*nxo,vfp); efclose(vfp); /*PVM communication starts here*/ mytid=pvm_mytid(); /*get my pid*/ task=NTASKS; warn("\n %d",task); rc=0; /*spawn slave processes here*/ if(!flag_cpu){ rc=pvm_spawn(child,NULL,PvmTaskDefault,"",task,tids); } else{ for(i=0;i<NTASKS;i++){ rc+=pvm_spawn(child,NULL,PvmTaskHost,cpu_name[i],1,&tids[i]); } } /*show the pid of slaves if*/ for(i=0;i<NTASKS;i++){ if(tids[i]<0)warn("\n %d",tids[i]); else warn("\nt%x\t",tids[i]); } /*if not all the slaves start, then quit*/ if(rc<NTASKS){ warn("error");pvm_exit();exit(1);} /*broadcast the global parameters nxo,nz,dip to all slaves*/ pvm_initsend(PvmDataDefault); rc=pvm_pkint(&nxo,1,1); rc=pvm_pkint(&nz,1,1); rc=pvm_pkint(&dip,1,1); msgtype=PARA_MSGTYPE; task=NTASKS; rc=pvm_mcast(tids,task,msgtype); /*broadcast the velocity profile to all slaves*/ pvm_initsend(PvmDataDefault); rc=pvm_pkfloat(v[0],nxo*nz,1); msgtype=VEL_MSGTYPE; rc=pvm_mcast(tids,task,msgtype); /*free the space for velocity profile*/ free2float(v); /*loop over shot gathers begin here*/ loop: /* get info from first trace */ if (!gettr(&tr)) err("can't get first trace"); nt = tr.ns; /* let user give dt and/or dx from command line */ if (!getparfloat("dt", &dt)) { if (tr.dt) { /* is dt field set? */ dt = ((double) tr.dt)/1000000.0; } else { /* dt not set, assume 4 ms */ dt = 0.004; warn("tr.dt not set, assuming dt=0.004"); } } if (!getparfloat("dx",&dx)) { if (tr.d2) { /* is d2 field set? */ dx = tr.d2; } else { dx = 1.0; warn("tr.d2 not set, assuming d2=1.0"); } } sx=tr.sx; isx=sx/dx; gxmin=gxmax=tr.gx; oldsx=sx; /* determine frequency sampling interval*/ ntfft = npfar(nt); nw = ntfft/2+1; dw = 2.0*PI/(ntfft*dt); /*compute the index of the frequency to be migrated*/ fw=2.0*PI*f1; nf1=fw/dw+0.5; fw=2.0*PI*f2; nf2=fw/dw+0.5; fw=2.0*PI*f3; nf3=fw/dw+0.5; fw=2.0*PI*f4; nf4=fw/dw+0.5; /*the number of frequency to migrated*/ truenw=nf4-nf1+1; fw=0.0+nf1*dw; warn("nf1=%d nf2=%d nf3=%d nf4=%d nw=%d",nf1,nf2,nf3,nf4,truenw); fw=0.0; /* allocate space */ wl=alloc1float(ntfft); wlsp=alloc1complex(nw); /*generate the Ricker wavelet*/ wtmp=ricker(Fmax,dt,&ntw); for(it=0;it<ntfft;it++) wl[it]=0.0; for(it=0;it<ntw-12;it++) wl[it]=wtmp[it+12]; free1float( wtmp); /*Fourier transform the Ricker wavelet to frequency domain*/ pfarc(-1,ntfft,wl,wlsp); /* allocate space */ p = alloc2float(ntfft,nxo); cp = alloc2complex(nw,nxo); for (ix=0; ix<nxo; ix++) for (it=0; it<ntfft; it++) p[ix][it] = 0.0; /*read in a single shot gather*/ ix=tr.gx/dx; memcpy( (void *) p[ix], (const void *) tr.data,nt*FSIZE); nx = 0; while(gettr(&tr)){ int igx; if(tr.sx!=oldsx){ fseek(stdin,(long)(-240-nt*4),SEEK_CUR); break;} igx=tr.gx/dx; memcpy( (void *) p[igx], (const void *) tr.data,nt*FSIZE); if(gxmin>tr.gx)gxmin=tr.gx; if(gxmax<tr.gx)gxmax=tr.gx; nx++; oldsx=tr.sx; } warn("\nnx= %d",nx); warn("sx %f , gxmin %f gxmax %f",sx,gxmin,gxmax); /*transform the shot gather from time to frequency domain*/ pfa2rc(1,1,ntfft,nxo,p[0],cp[0]); /*compute the most left and right index for the migrated section*/ ix1=sx/dx; ix2=gxmin/dx; ix3=gxmax/dx; if(ix1>=ix3)ix3=ix1; if(ix1<=ix2)ix2=ix1; il=ix2; ir=ix3; ix2-=lpad; ix3+=rpad; if(ix2<0)ix2=0; if(ix3>nxo-1)ix3=nxo-1; /*the total traces to be migrated*/ nx=ix3-ix2+1; /*allocate space*/ cq = alloc2complex(nx,nw); cq1 = alloc2complex(nx,nw); /*transpose the frequency domain data from data[ix][iw] to data[iw][ix] and apply a Hamming at the same time*/ for (ix=0; ix<nx; ix++) for (iw=0; iw<nw; iw++){ float tmpp=0.0,tmppp=0.0; if(iw<nf1||iw>nf4) cq[iw][ix]=cmplx(0.0,0.0); else{ if(iw>=nf1&&iw<=nf2){tmpp=PI/(nf2-nf1);tmppp=tmpp*(iw-nf1)-PI;tmpp=0.54+0.46*cos(tmppp); cq[iw][ix]=crmul(cp[ix+ix2][iw],tmpp);} else{ if(iw>=nf3&&iw<=nf4){tmpp=PI/(nf4-nf3);tmppp=tmpp*(iw-nf3);tmpp=0.54+0.46*cos(tmppp); cq[iw][ix]=crmul(cp[ix+ix2][iw],tmpp);} else {cq[iw][ix]=cp[ix+ix2][iw];} } } cq[iw][ix]=cp[ix+ix2][iw]; cq1[iw][ix]=cmplx(0.0,0.0); } ix=sx/dx-ifx; warn("ix %d",ix); for(iw=0;iw<nw;iw++){ cq1[iw][ix-ix2]=wlsp[iw]; } free2float(p); free2complex(cp); free1float(wl); free1complex(wlsp); /*if the horizontal spacing interval is in feet, convert it to meter*/ if(!flag) dx*=0.3048; /*start of the timing function*/ time(&t1); /* send local parameters to all slaves*/ pvm_initsend(PvmDataDefault); ix=15; rc=pvm_pkint(&ix,1,1); rc=pvm_pkint(&ntfft,1,1); rc=pvm_pkint(&ix2,1,1); rc=pvm_pkint(&ix3,1,1); rc=pvm_pkint(&isx,1,1); rc=pvm_pkint(&il,1,1); rc=pvm_pkint(&ir,1,1); rc=pvm_pkfloat(&dx,1,1); rc=pvm_pkfloat(&dz,1,1); rc=pvm_pkfloat(&dw,1,1); rc=pvm_pkfloat(&dt,1,1); msgtype=PARA_MSGTYPE; task=NTASKS; rc=pvm_mcast(tids,task,msgtype); /* send all the frequency to slaves*/ count=NTASKS*5; /*count is the number of frequency components in a shot gather*/ nw=truenw; nw1=nw/(count); if(nw1==0)nw1=1; total=count=ceil(nw*1.0/nw1); /* if it is the first shot gather, send equal data to all the slaves, then for the following shot gathers, only send data when slave requests*/ if(nxshot==tshot){ for(i=0;i<NTASKS;i++){ float *tmpp; float fw1; int nww,byte,nwww; pvm_initsend(PvmDataDefault); nww=nf1+i*nw1;fw1=fw+nww*dw; nwww=nw1; byte=UnDone; rc=pvm_pkint(&byte,1,1); rc=pvm_pkfloat(&fw1,1,1); rc=pvm_pkint(&nwww,1,1); rc=pvm_pkfloat((float *)cq[nww],nx*nwww*2,1); rc=pvm_pkfloat((float *)cq1[nww],nx*nwww*2,1); msgtype=DATA_MSGTYPE; pvm_send(tids[i],msgtype); } count-=NTASKS; } while(count){ int tid0,bufid; float *tmpp; float fw1; int nww,byte,nwww; int i; i=total-count; msgtype=COM_MSGTYPE; bufid=pvm_recv(-1,msgtype); rc=pvm_upkint(&tid0,1,1); pvm_freebuf(bufid); pvm_initsend(PvmDataDefault); nww=nf1+i*nw1;fw1=fw+nww*dw; if(i==total-1)nwww=nw-nw1*i; else nwww=nw1; byte=UnDone; rc=pvm_pkint(&byte,1,1); rc=pvm_pkfloat(&fw1,1,1); rc=pvm_pkint(&nwww,1,1); rc=pvm_pkfloat((float *)cq[nww],nx*nwww*2,1); rc=pvm_pkfloat((float *)cq1[nww],nx*nwww*2,1); msgtype=DATA_MSGTYPE; pvm_send(tid0,msgtype); count--; } ix=Done; pvm_initsend(PvmDataDefault); rc=pvm_pkint(&ix,1,1); msgtype=DATA_MSGTYPE; pvm_mcast(tids,task,msgtype); free2complex(cq); free2complex(cq1); time(&t2); warn("\n %d shot been finished in %f seconds, Ntask=%d",nxshot,difftime(t2,t1),NTASKS); nxshot--; if(nxshot)goto loop; /*when all the shot gathers done, send signal to all slaves to request the partial imaging*/ ix=FinalDone; pvm_initsend(PvmDataDefault); rc=pvm_pkint(&ix,1,1); msgtype=PARA_MSGTYPE; pvm_mcast(tids,task,msgtype); /*allocate space for the final image*/ cresult = alloc2float(nz,nxo); for(ix=0;ix<nxo;ix++) for(iz=0;iz<nz;iz++) { cresult[ix][iz]=0.0; } result_tmp= alloc2float(nz,nxo); /*receive partial image from all the slaves*/ msgtype=RESULT_MSGTYPE; i=0; while(i<NTASKS){ int bufid; bufid=pvm_recv(-1,msgtype); rc=pvm_upkfloat(result_tmp[0],nxo*nz,1); pvm_freebuf(bufid); for(ix=0;ix<nxo;ix++) for(iz=0;iz<nz;iz++) { cresult[ix][iz]+=result_tmp[ix][iz]; } i=i+1; warn("\n i=%d been received",i); } /*send signal to all slaves to kill themselves*/ pvm_initsend(PvmDataDefault); pvm_mcast(tids,task,COM_MSGTYPE); /*output the final image*/ for(ix=0; ix<nxo; ix++){ tr.ns = nz ; tr.dt = dz*1000000.0 ; tr.d2 = dx; tr.offset = 0; tr.cdp = tr.tracl = ix; memcpy( (void *) tr.data, (const void *) cresult[ix],nz*FSIZE); puttr(&tr); } pvm_exit(); return EXIT_SUCCESS; }
/// user function:add a new query to a pipeline of filters. Called by user manager runs this. /// \param layout System Layout. /// \param work Buffer with a Unit of Work (UoW) /// \param workSize Unit of Work Size (UoW) /// \return Zero on success, -1 on error. int appendWork(Layout *layout, void *work, int workSize) { #ifdef NO_BARRIER // sends work for each filter pvm_initsend(PvmDataRaw); // First tell that is a mensage of WORK int msgType = MSGT_WORK; pvm_pkint(&msgType, 1, 1); //then attach the work to it pvm_pkbyte((char *)work, workSize, 1); // for each filter, send his work for(i = 0; i < layout->numFilters; i++) { FilterPlacement *pFilterP = &(layout->filters[i]->filterPlacement); // sends work to all filters of this set pvm_mcast(pFilterP->tids, pFilterP->numInstances, 0); } #else int i; int totalEows = 0, numEowsReceived; #ifdef ATTACH int totalAttachedFilters = 0; #endif int reconf = 0 /** should we reconfigure? */, remainingReconfs = 0; //how many times should we try? #ifdef VOID_INST #ifdef BMI_FT char instDir[MAX_IDIR_LENGTH]; sprintf(instDir, "%s/", INST_DIR); for (i=0; i < layout->numFilters-1; i++) { if (strlen(instDir) >= (MAX_IDIR_LENGTH - 3)) { //dont want to overflow this array fprintf(stderr, "%s %d: warning, instrumentation directory name too big, truncating to %s\n", __FILE__, __LINE__, instDir); break; } sprintf(instDir, "%s%d-", instDir, layout->filters[i]->filterPlacement.numInstances); } sprintf(instDir, "%s%d", instDir, layout->filters[layout->numFilters-1]->filterPlacement.numInstances); char managerLogFile[MAX_IDIR_LENGTH+20]; sprintf(managerLogFile, "%s/manager.time", instDir); FILE *fp = fopen(managerLogFile, "w"); struct timeval tv; struct timezone tz; //not used //get the time gettimeofday(&tv, &tz); if(fp != NULL) fprintf(fp, "1 %ld %ld\n", tv.tv_sec, tv.tv_usec); #endif #endif //before sending, we check if we received any filter error int bufid = pvm_probe(-1, MSGT_FERROR); if (bufid != 0) { int bytes, tag, tid; char *msg; pvm_bufinfo(bufid, &bytes, &tag, &tid); msg = (char*)malloc(bytes+1); pvm_recv(tid, MSGT_FERROR); pvm_upkbyte(msg, bytes, 1); msg[bytes] = '\0'; fprintf(stderr, "Manager.c: Error, received death notification\n"); fprintf(stderr, "Manager.c: %s\n", msg); free(msg); killAllFilters(layout); exit(-1); } printf("Manager.c: starting work...\n"); // number of EOWs we expect to receive for(i = 0; i < layout->numFilters; i++) { totalEows += layout->filters[i]->filterPlacement.numInstances; #ifdef ATTACH if(layout->filters[i]->attached) { totalAttachedFilters += layout->filters[i]->filterPlacement.numInstances; } // TODO:TOSCO::: if(layout->filters[i]->attach) return 0; #endif } //we stay in this loop while we have to reconfigure //usually, this will be only one time, unless a we get some reconf message do { // sends work for each filter pvm_initsend(PvmDataRaw); int msgType; #ifdef VOID_FT if(!reconf) { #endif // First tell that is a mensage of WORK msgType = MSGT_WORK; #ifdef VOID_FT } else { // one fault has occurred msgType = MSGT_FT; } #endif pvm_pkint(&msgType, 1, 1); //then attach the work to it pvm_pkbyte((char *)work, workSize, 1); reconf = 0; //we are optimistic, always expect to not reconfigure // for each filter, send his work for(i = 0; i < layout->numFilters; i++) { FilterPlacement *pFilterP = &(layout->filters[i]->filterPlacement); // sends work to all filters of this set pvm_mcast(pFilterP->tids, pFilterP->numInstances, 0); } /* TaskIdList *finalTaskIdList = NULL, *currentTaskIdList; int filtersThatUseTasks = 0; // Manager receives filter's terminated tasks list for(i = 0; i < layout->numFilters; i++) { FilterPlacement *pFilterP = &(layout->filters[i]->filterPlacement); #ifdef ATTACH // if this filter is of the attached // type i dont need worry about use Task // if(layout->filters[i]->attached)continue; #endif for(j = 0; j < pFilterP->numInstances; j++) { int instanceUseTasks = -1; // Get is this filter use tasks pvm_recv(pFilterP->tids[j], 0); pvm_upkint(&instanceUseTasks, 1, 1); layout->filters[i]->useTasks = instanceUseTasks; #ifdef VOID_FT if (instanceUseTasks) { currentTaskIdList = (TaskIdList *)unpackTaskIdList(); // Para fazer intersecao, gerente ordenar? as listas de tarefas recebidas e utilizar? a fun??o meet() do CrazyMiner/ID3. qsort(currentTaskIdList->vetor, currentTaskIdList->size, sizeof(int), compareTaskId); if(finalTaskIdList == NULL) { finalTaskIdList = currentTaskIdList; } else { // Manager makes the intersection of all finished tasks lists finalTaskIdList = taskIdListIntersection(finalTaskIdList, currentTaskIdList); taskIdListDestroy(currentTaskIdList); } } #endif } // for if (layout->filters[i]->useTasks) filtersThatUseTasks++; } // Gerente devolve resultado das intersecoes para todas as instancias de todos os filtros. for(i = 0; i < layout->numFilters; i++) { FilterPlacement *pFilterP = &(layout->filters[i]->filterPlacement); #ifdef ATTACH // if this filter is of the attached // type i dont need worry about use Task //TODO if(layout->filters[i]->attached)continue; #endif int needForwardTaskMessages = 1; if (filtersThatUseTasks < 2) needForwardTaskMessages = 0; #ifdef VOID_FT if (layout->filters[i]->useTasks) { // Send if they should forward task messages // and pigback :-) the final task id list pvm_initsend(PvmDataDefault); pvm_pkint(&needForwardTaskMessages, 1, 1); packTaskIdList(finalTaskIdList); pvm_mcast(pFilterP->tids, pFilterP->numInstances, 0); } else { #endif // Only send if they should forward task messages pvm_initsend(PvmDataDefault); pvm_pkint(&needForwardTaskMessages, 1, 1); pvm_mcast(pFilterP->tids, pFilterP->numInstances, 0); #ifdef VOID_FT } #endif } taskIdListDestroy(finalTaskIdList); */ //now we receive the EOWs numEowsReceived = 0; //now we expect to receive EOW or errors while(numEowsReceived < totalEows) { //we are open to receive anything from anyone here //all messages to the manager should be tagged, so we now their type int szMsg = -1; int inst_tid = -1; int msgTag = -1; int bufid = pvm_recv(-1, -1); pvm_bufinfo(bufid, &szMsg, &msgTag, &inst_tid); switch (msgTag) { case (MSGT_EOW): { //received EOW, expect this usually int instance = -1; FilterSpec *pFilter = NULL; getFilterByTid(layout, inst_tid, &pFilter, &instance); if ((pFilter != NULL) && (instance != -1)) { printf("Manager.c: EOW received from %s, instance %d\n", pFilter->name, instance); } else { fprintf(stderr, "Manager.c: unknown EOW received! Shouldnt get here!\n"); } numEowsReceived++; break; } case (MSGT_AEXIT): case (MSGT_FERROR): { //someone called dsExit or system error at the filter side //common cause for this are library not found, wrong initscritpt etc char *message = (char*)malloc(sizeof(char)*szMsg+1); pvm_upkbyte(message, szMsg, 1); message[szMsg] = '\0'; //the filter and the instance FilterSpec *fp = NULL; int instance = -1; getFilterByTid(layout, inst_tid, &fp, &instance); if (msgTag == MSGT_AEXIT) { printf("Manager.c: Filter %s, instance %d(tid %x) called dsExit: %s\n", fp->name, instance, inst_tid, message); } else { printf("Manager.c: Filter %s error, instance %d(tid %x) called exit: %s\n", fp->name, instance, inst_tid, message); } free(message); // kill all instances killAllFilters(layout); exit(-1); break; } //task exited or host crashed case (MSGT_TEXIT): case (MSGT_HDEL): { //we only reconfigure a fixed number of times if (remainingReconfs <= 0) { //max number of reconfigurations reached... aborting fprintf(stderr, "Manager.c: max reconfigurations reached, aborting...\n"); fflush(stderr); fprintf(stdout, "Manager.c: max reconfigurations reached, aborting...\n"); fflush(stdout); reconf = 0; // kill all instances which might be alive killAllFilters(layout); exit(-1);; } #ifdef BMI_FT gettimeofday(&tv, &tz); fprintf(fp, "2 %ld %ld\n", tv.tv_sec, tv.tv_usec); #endif remainingReconfs--; reconf = 1; // In case of pvm notification, inst_tid will be t80000000 int notifiesRecv = 1; // We are receiving the first death notification int deadFilterTid = -1; FilterSpec *pFilter = NULL; int instanceDead = -1; // Get the tid and name of the dead filter int info = pvm_upkint(&deadFilterTid, 1, 1); if (info < 0) pvm_perror("Manager.c: error calling pvm_upkint"); //discover which filter died getFilterByTid(layout, deadFilterTid, &pFilter, &instanceDead); if((pFilter != NULL) && (instanceDead != -1)) { if (msgTag == MSGT_TEXIT) { fprintf(stderr, "Manager.c: filter %s: instance %d (tid t%x) of %d is dead!!!\n", pFilter->name, instanceDead, deadFilterTid, pFilter->filterPlacement.numInstances); } else { fprintf(stderr, "Manager.c: filter %s: instance %d (tid t%x) of %d machine's crashed!!!\n", pFilter->name, instanceDead, deadFilterTid, pFilter->filterPlacement.numInstances); } } printf("Manager.c: starting reconfiguration\n"); // kill all filters in the pipeline killAllFilters(layout); if (msgTag == MSGT_HDEL) { //int his case, host died, so we must change layout replaceCrashedHost(layout, pFilter, instanceDead); } #ifdef ATTACH if (pFilter->attached) { // In this case, all filters that were killed have to notify // their dead. notifiesRecv = 0; } #endif //Flush the streams //receive all messages which are about to arrive till we get the death notification //pvm order should garantee this #ifdef ATTACH while (notifiesRecv < (totalEows - totalAttachedFilters)) { #else while (notifiesRecv < totalEows) { #endif int newMsgTag = -1; bufid = pvm_recv(-1, MSGT_TEXIT); info = pvm_bufinfo(bufid, NULL, &newMsgTag, &inst_tid); info = pvm_upkint(&deadFilterTid, 1, 1); if (info < 0) pvm_perror("Manager.c: error calling pvm_upkint"); fprintf(stderr, "Manager.c: WARNING: received notification (tag %d) about pvm tid t%x death\n", newMsgTag, deadFilterTid); notifiesRecv++; } #ifdef ATTACH if(pFilter->attached) { notifiesRecv = 1; } else { notifiesRecv = 0; } // Receive all EOW messages from the attached filters. while(notifiesRecv < totalAttachedFilters) { int newMsgTag = -1; bufid = pvm_recv(-1, MSGT_EOW); info = pvm_bufinfo(bufid, NULL, &newMsgTag, &inst_tid); if (info < 0) pvm_perror("Manager.c: error calling pvm_upkint"); fprintf(stderr, "Manager.c: WARNING: received EOW (tag %d) from pvm tid t%x\n", newMsgTag, inst_tid); notifiesRecv++; } #endif // probes for remaining machine crash notifications while (pvm_probe(-1, MSGT_HDEL) > 0) { int newMsgTag = -1; bufid = pvm_recv(-1, MSGT_HDEL); info = pvm_bufinfo(bufid, NULL, &newMsgTag, &inst_tid); info = pvm_upkint(&deadFilterTid, 1, 1); if (info < 0) pvm_perror("Manager.c: error calling pvm_upkint"); fprintf(stderr, "Manager.c: WARNING: received notification (tag %d) about pvm tid t%x machine's crash\n", newMsgTag, deadFilterTid); // Replace the died host FilterSpec *pCrashedFilter = NULL; int crashedInstance = -1; getFilterByTid(layout, deadFilterTid, &pCrashedFilter, &crashedInstance); replaceCrashedHost(layout, pCrashedFilter, crashedInstance); } #ifdef BMI_FT updateAllFiltersFaultStatus(layout, FAULT_OTHER_FILTER_INST); pFilter->faultStatus = instanceDead; #endif //spawn all filters again spawnAllFilter(layout); #ifdef ATTACH // Verifies if the dead filter is an attached. If yes, spawn it. if(pFilter->attached == 1) { spawnOneAttachedInstance(layout, pFilter, instanceDead); } #endif resetStreams(layout); //resend the data sendFiltersData(layout); //start all over again numEowsReceived = 0; #ifdef BMI_FT gettimeofday(&tv, &tz); fprintf(fp, "3 %ld %ld\n", tv.tv_sec, tv.tv_usec); #endif break; } #ifdef VOID_TERM // One filter instance detected local termination case (MSGT_LOCALTERM): { int localTermTag; // filter instance local termination tag pvm_upkint(&localTermTag, 1, 1); verifyGlobalTermination(inst_tid, localTermTag); break; } #endif default: { fprintf(stderr, "Manager.c: error receiving EOW, unknown tag!!!\n"); } } //end switch message tag if((msgTag == MSGT_TEXIT) || (msgTag == MSGT_HDEL)) { // work should be sent again break; } } //end receiving eows } while(reconf == 1); //leave this loop if we will not reconfigure #ifdef BMI_FT gettimeofday(&tv, &tz); fprintf(fp, "4 %ld %ld\n", tv.tv_sec, tv.tv_usec); #endif printf("Manager.c: Work ended\n\n"); return 0; #endif } /// Finalize a Void pipeline. Only manager runs this. int finalizeDs(Layout *layout) { #ifdef NO_BARRIER #else int i; // Envia eof para todos os filtros // Primeiro envia se eh work (WORK) ou EOF (END_OF_FILTER) pvm_initsend(PvmDataRaw); int tipo_msg = MSGT_EOF; pvm_pkint(&tipo_msg, 1, 1); //sends the EOF message for all instances of the filter for(i = 0; i < layout->numFilters; i++) { FilterPlacement *pFilterP = &(layout->filters[i]->filterPlacement); #ifdef ATTACH if(layout->filters[i]->attach) continue;// this filter cant not receive a EOF because // it needs still runnig #endif pvm_mcast(pFilterP->tids, pFilterP->numInstances, 0); } destroyLayout(layout); pvm_exit(); return 0; #endif }
/* Function: main_loop_pvm() * Date: SRE, Wed Aug 19 13:59:54 1998 [St. Louis] * * Purpose: Given an HMM and parameters for synthesizing random * sequences; return a histogram of scores. * (PVM version) * * Args: hmm - an HMM to calibrate. * seed - random number seed * nsample - number of seqs to synthesize * lumpsize- # of seqs per slave exchange; controls granularity * lenmean - mean length of random sequence * lensd - std dev of random seq length * fixedlen- if nonzero, override lenmean, always this len * hist - RETURN: the score histogram * ret_max - RETURN: highest score seen in simulation * extrawatch - RETURN: total CPU time spend in slaves. * ret_nslaves- RETURN: number of PVM slaves run. * * Returns: (void) * hist is alloc'ed here, and must be free'd by caller. */ static void main_loop_pvm(struct plan7_s *hmm, int seed, int nsample, int lumpsize, float lenmean, float lensd, int fixedlen, struct histogram_s **ret_hist, float *ret_max, Stopwatch_t *extrawatch, int *ret_nslaves) { struct histogram_s *hist; int master_tid; int *slave_tid; int nslaves; int nsent; /* # of seqs we've asked for so far */ int ndone; /* # of seqs we've got results for so far */ int packet; /* # of seqs to have a slave do */ float max; int slaveidx; /* id of a slave */ float *sc; /* scores returned by a slave */ Stopwatch_t slavewatch; int i; StopwatchZero(extrawatch); hist = AllocHistogram(-200, 200, 100); max = -FLT_MAX; /* Initialize PVM */ if ((master_tid = pvm_mytid()) < 0) Die("pvmd not responding -- do you have PVM running?"); #if DEBUGLEVEL >= 1 pvm_catchout(stderr); /* catch output for debugging */ #endif PVMSpawnSlaves("hmmcalibrate-pvm", &slave_tid, &nslaves); /* Initialize the slaves */ pvm_initsend(PvmDataDefault); pvm_pkfloat(&lenmean, 1, 1); pvm_pkfloat(&lensd, 1, 1); pvm_pkint( &fixedlen, 1, 1); pvm_pkint( &Alphabet_type, 1, 1); pvm_pkint( &seed, 1, 1); if (! PVMPackHMM(hmm)) Die("Failed to pack the HMM"); pvm_mcast(slave_tid, nslaves, HMMPVM_INIT); SQD_DPRINTF1(("Initialized %d slaves\n", nslaves)); /* Confirm slaves' OK status. */ PVMConfirmSlaves(slave_tid, nslaves); SQD_DPRINTF1(("Slaves confirm that they're ok...\n")); /* Load the slaves */ nsent = ndone = 0; for (slaveidx = 0; slaveidx < nslaves; slaveidx++) { packet = (nsample - nsent > lumpsize ? lumpsize : nsample - nsent); pvm_initsend(PvmDataDefault); pvm_pkint(&packet, 1, 1); pvm_pkint(&slaveidx, 1, 1); pvm_send(slave_tid[slaveidx], HMMPVM_WORK); nsent += packet; } SQD_DPRINTF1(("Loaded %d slaves\n", nslaves)); /* Receive/send loop */ sc = MallocOrDie(sizeof(float) * lumpsize); while (nsent < nsample) { /* integrity check of slaves */ PVMCheckSlaves(slave_tid, nslaves); /* receive results */ SQD_DPRINTF2(("Waiting for results...\n")); pvm_recv(-1, HMMPVM_RESULTS); pvm_upkint(&slaveidx, 1, 1); pvm_upkint(&packet, 1, 1); pvm_upkfloat(sc, packet, 1); SQD_DPRINTF2(("Got results.\n")); ndone += packet; /* store results */ for (i = 0; i < packet; i++) { AddToHistogram(hist, sc[i]); if (sc[i] > max) max = sc[i]; } /* send new work */ packet = (nsample - nsent > lumpsize ? lumpsize : nsample - nsent); pvm_initsend(PvmDataDefault); pvm_pkint(&packet, 1, 1); pvm_pkint(&slaveidx, 1, 1); pvm_send(slave_tid[slaveidx], HMMPVM_WORK); SQD_DPRINTF2(("Told slave %d to do %d more seqs.\n", slaveidx, packet)); nsent += packet; } /* Wait for the last output to come in. */ while (ndone < nsample) { /* integrity check of slaves */ PVMCheckSlaves(slave_tid, nslaves); /* receive results */ SQD_DPRINTF1(("Waiting for final results...\n")); pvm_recv(-1, HMMPVM_RESULTS); pvm_upkint(&slaveidx, 1, 1); pvm_upkint(&packet, 1, 1); pvm_upkfloat(sc, packet, 1); SQD_DPRINTF2(("Got some final results.\n")); ndone += packet; /* store results */ for (i = 0; i < packet; i++) { AddToHistogram(hist, sc[i]); if (sc[i] > max) max = sc[i]; } } /* Shut down the slaves: send -1,-1,-1. */ pvm_initsend(PvmDataDefault); packet = -1; pvm_pkint(&packet, 1, 1); pvm_pkint(&packet, 1, 1); pvm_pkint(&packet, 1, 1); pvm_mcast(slave_tid, nslaves, HMMPVM_WORK); /* Collect stopwatch results; quit the VM; return. */ for (i = 0; i < nslaves; i++) { pvm_recv(-1, HMMPVM_RESULTS); pvm_upkint(&slaveidx, 1, 1); StopwatchPVMUnpack(&slavewatch); SQD_DPRINTF1(("Slave %d finished; says it used %.2f cpu, %.2f sys\n", slaveidx, slavewatch.user, slavewatch.sys)); StopwatchInclude(extrawatch, &slavewatch); } free(slave_tid); free(sc); pvm_exit(); *ret_hist = hist; *ret_max = max; *ret_nslaves = nslaves; return; }
void main (int argc, char** argv) { int Message_counter ; /* counter for message packing */ int My_tid ; /* my task id */ /* show start up message */ printf ("\n-=> Fractal Terrain Engine version 2.1 release 2 <=-\n\n") ; /* read the config files */ read_config (argc,argv) ; /* set up the pixel buffer and it's variables */ Pixel_buffer_width=User_view.X_size/Number_of_workers; Pixel_buffer_size= Pixel_buffer_width*User_view.Y_size*3*sizeof(unsigned char) ; Pixel_buffer=(unsigned char *) malloc(Pixel_buffer_size) ; /* set up worker tids array */ Worker_tids=(int *)malloc(Number_of_workers*sizeof(int)) ; /* set up the image buffer */ Image_buffer=(unsigned char *) malloc ((User_view.X_size*User_view.Y_size*3*sizeof(unsigned char))) ; /* start up pvm */ if ((My_tid = pvm_mytid()) < 0) { exit(1); } /* start up the workers */ pvm_spawn(WORKER_NAME,(char**)0,PvmTaskDefault,"", Number_of_workers,Worker_tids) ; printf ("INFO:Spawned %i Workers\n",Number_of_workers) ; /* tell the worker what values to use for the terrain function */ pvm_initsend(PvmDataDefault) ; pvm_pkdouble(&H,1,1) ; pvm_pkdouble(&Lacunarity,1,1); pvm_pkdouble(&Octaves,1,1); pvm_pkdouble(&Offset,1,1) ; pvm_pkfloat(&Ambient_light,1,1) ; pvm_pkfloat(&Fog.Red,1,1) ; pvm_pkfloat(&Fog.Green,1,1); pvm_pkfloat(&Fog.Blue,1,1) ; pvm_pkfloat(&Sky.Red,1,1) ; pvm_pkfloat(&Sky.Green,1,1) ; pvm_pkfloat(&Sky.Blue,1,1) ; pvm_pkfloat(&Horizon.Red,1,1) ; pvm_pkfloat(&Horizon.Green,1,1) ; pvm_pkfloat(&Horizon.Blue,1,1) ; pvm_pkdouble(Colour_boundaries,NUMBER_OF_TERRAIN_COLOURS,1) ; for ( Message_counter = 0 ; Message_counter<NUMBER_OF_TERRAIN_COLOURS ; Message_counter++ ) { pvm_pkfloat(&Terrain_colours[Message_counter].Red,1,1) ; pvm_pkfloat(&Terrain_colours[Message_counter].Green,1,1) ; pvm_pkfloat(&Terrain_colours[Message_counter].Blue,1,1) ; } pvm_pkdouble(&Fog_start,1,1) ; pvm_pkdouble(&Fog_end,1,1) ; /* tell the worker what values to use for the display */ pvm_pkdouble(&Ray_step,1,1) ; pvm_pkdouble(&X_view_angle,1,1) ; pvm_pkdouble(&Y_view_angle,1,1) ; pvm_pkint(&Pixel_buffer_width,1,1) ; pvm_pkint(&User_view.Y_size,1,1) ; pvm_pkdouble(&X_ray_angle,1,1) ; pvm_pkdouble(&Y_ray_angle,1,1) ; /* send the message to all the workers */ pvm_mcast (Worker_tids,Number_of_workers,INFO) ; /* set up light source */ normalize_3d(Light_source) ; /* set the light source */ Light_source[0]=0.1 ; Light_source[1]=0.4 ; Light_source[2]=0.3 ; /* tell the worker what values to use for the light source */ pvm_initsend(PvmDataDefault) ; pvm_pkdouble(Light_source,3,1) ; pvm_mcast (Worker_tids,Number_of_workers,NEW_LIGHT_SOURCE) ; /* set up the users view point */ Height=1.0 ; User.X=0 ; User.Y=0 ; User.Z=Height ; User.X_angle=0.0 ; User.Y_angle=0.0 ; User.Z_angle=0.0 ; /* set up window */ open_window() ; print_keys() ; /* */ /* set up the keyboard,Reshape and display routines */ /* */ auxKeyFunc(AUX_Q,kill_workers) ; auxKeyFunc(AUX_q,kill_workers) ; auxKeyFunc(AUX_ESCAPE,kill_workers) ; auxKeyFunc(AUX_LEFT,left) ; auxKeyFunc(AUX_RIGHT,right) ; auxKeyFunc(AUX_UP,forwards) ; auxKeyFunc(AUX_DOWN,backwards) ; auxKeyFunc(AUX_a,up) ; auxKeyFunc(AUX_A,up) ; auxKeyFunc(AUX_Z,down) ; auxKeyFunc(AUX_z,down) ; auxKeyFunc(AUX_J,save_image) ; auxKeyFunc(AUX_j,save_image) ; auxMainLoop(display_loop) ; }