int SeisPipe2D(DsuTask *zz) { int nt,nx,nz,nw,ntpad,ntfft; int it,ix,iz,izz,iw,iw0,iw1,iw2,iw3,iwmin,iwmax; int nfreqs,verbose; float dt,dx,dy,dz,dw; float freqs[4],fw,w,scale,fftscl; float *p, **v, *wdxov,*sx; complex *cpx; float **qx; void *TabInfo; eTable *et; char msg[80]; int info, ToTid, MasterTid; int sz, pz, pei; int SeisIntPars[20]; float SeisFloPars[20]; /* Receive process control information */ MsgLog(zz, "Receiving Control info ... " ); MasterTid = RecvInt(SeisIntPars, 2, -1, MsgCntl); pei = SeisIntPars[0]; ToTid = SeisIntPars[1]; MsgLog(zz, " Ready \n"); /* Receive: efile and other pars ... */ MsgLog(zz, "Receiving parameters ..." ); TabInfo = RecvBytes(-1, MsgTable); RecvFI(SeisFloPars, 10, SeisIntPars, 10, -1, -1); MsgLog(zz, " Ready \n" ); /* get integer parameters */ nt = SeisIntPars[0]; nx = SeisIntPars[1]; nz = SeisIntPars[2]; ntpad = SeisIntPars[3]; verbose = SeisIntPars[4]; sz = SeisIntPars[5]; pz = SeisIntPars[6]; /* get Floating point parameters */ dt = SeisFloPars[0]; dx = SeisFloPars[1]; dz = SeisFloPars[2]; freqs[0] = SeisFloPars[3]; freqs[1] = SeisFloPars[4]; freqs[2] = SeisFloPars[5]; freqs[3] = SeisFloPars[6]; sz = nz / pz; if (pei == (pz - 1)) sz += nz % pz; sprintf(msg, "Receiving Velocity info (pei = %d, sz = %d) ... ", pei, sz); MsgLog(zz,msg); v = alloc2float(nx, sz); for (iz=0; iz<sz; ++iz) RecvFloat(v[iz], nx, -1, MsgVel); MsgLog(zz, " Ready \n" ); /* determine frequency w sampling */ ntfft = npfar(nt+ntpad); nw = ntfft/2+1; dw = 2.0*PI/(ntfft*dt); iwmin = MAX(0,MIN(nw-1,NINT(2.0*PI*freqs[0]/dw))); iwmax = MAX(0,MIN(nw-1,NINT(2.0*PI*freqs[3]/dw))); /* read extrapolator table */ et = ezread(TabInfo); /* pret(zz -> fp_log, et); */ /* allocate workspace */ MsgLog(zz, "Allocating space ... "); qx = alloc2float(nx,sz); sx = alloc1float(nx); wdxov = alloc1float(nx); cpx = alloc1complex(nx); MsgLog(zz, " Ready \n"); sprintf(msg, "Process (%d) starting loop on depth steps(%d,%d)\n", pei, pei*(nz/pz), pei*(nz/pz) + sz); MsgLog(zz, msg); /* Cleanup qx */ for (iz=0; iz<sz; ++iz) for (ix=0; ix<nx; ++ix) qx[iz][ix] = 0.0; /* loop over frequencies w */ for (iw=iwmin,w=iwmin*dw; iw<iwmax; ++iw,w+=dw) { if (verbose && !(iw%1)) { sprintf(msg, "\t%d/%d\n",iw,iwmax); MsgLog(zz, msg); } /* load wavefield */ RecvCplx(cpx, nx, -1, MsgSlice); /* loop over depth steps nz */ for (iz=0; iz<sz; ++iz) { /* compute 2.0*dx/v(x) and zero migrated data */ for (ix=0; ix<nx; ix++) sx[ix] = 2.0*dx/v[iz][ix]; /* make w*dx/v(x) */ for (ix=0; ix<nx; ++ix) wdxov[ix] = w*sx[ix]; /* extrapolate wavefield */ etextrap(et,nx,wdxov,cpx); /* accumulate migrated data */ for (ix=0; ix<nx; ++ix) qx[iz][ix] += cpx[ix].r; } /* Send down the wavefield */ if ( pei != (pz -1)) SendCplx(cpx, nx, ToTid, MsgSlice); } /* End of loop for iw */ for (iz=0; iz<sz; iz++) { izz = pei*(nz/pz) + iz; if (verbose) { sprintf(msg, "Sending values for iz = %d\n",izz); MsgLog(zz, msg); } SendFI(qx[iz], nx, &izz, 1, MasterTid, MsgDepth); } sprintf(msg, "End of processing for (%d)\n",pei); MsgLog(zz, msg); /* free workspace */ free1float(sx); free1float(wdxov); free2float(v); free2float(qx); free1complex(cpx); pvm_exit(); return(0); }
void gradient(float *grad) { /* declaration of variables */ int i, iF, iR, iProc, iDer, iL, iU, offset; /* counters */ int FReceived; /* number of frequencies processed */ int die; /* die processor flag */ int apl_pid; /* PVM process id control */ int pid; /* process id */ int masterId; /* master id */ int processControl; /* monitoring PVM start */ int FInfo[2]; /* frequency delimiters */ float wallcpu; /* wall clock time */ float *gradPart; /* partition of gradients */ complex **resCDPart; /* partition of resCD */ /* Clean up log files */ CleanLog(); /* Reseting synchronization flags */ for (i = 0; i < nFreqPart; i++) { statusFreq[i][2] = 0; } /* allocating some memory */ gradPart = alloc1float(numberPar * limRange); for (i = 0; i < numberPar * limRange; i++) { grad[i] = 0; } fprintf(stderr, "Starting communication with PVM for derivatives\n"); /* starting communication with PVM */ if ((apl_pid = pvm_mytid()) < 0) { pvm_perror("Error enrolling master process"); exit(-1); } processControl = CreateSlaves(processes, PROCESS_FRECHET, nProc); if (processControl != nProc) { fprintf(stderr,"Problem starting PVM daemons\n"); exit(-1); } /* converting to velocities */ if (IMPEDANCE) { for (i = 0; i < info->nL + 1; i++) { alpha[i] /= rho[i]; beta[i] /= rho[i]; } } /* Broadcasting all processes common information */ BroadINFO(info, 1, processes, nProc, GENERAL_INFORMATION); /* sending all profiles */ BroadFloat(thick, info->nL + 1, processes, nProc, THICKNESS); BroadFloat(rho, info->nL + 1, processes, nProc, DENSITY); BroadFloat(alpha, info->nL + 1, processes, nProc, ALPHAS); BroadFloat(qP, info->nL + 1, processes, nProc, QALPHA); BroadFloat(beta, info->nL + 1, processes, nProc, BETAS); BroadFloat(qS, info->nL + 1, processes, nProc, QBETA); /* sending frequency partitions for each process */ for (iProc = 0; iProc < nProc; iProc++) { FInfo[0] = statusFreq[iProc][0]; FInfo[1] = statusFreq[iProc][1]; if (info->verbose) fprintf(stderr, "Master sending frequencies [%d, %d] out of %d to slave Frechet %d [id:%d]\n", FInfo[0], FInfo[1], info->nF, iProc, processes[iProc]); procInfo[iProc][0] = FInfo[0]; procInfo[iProc][1] = FInfo[1]; SendInt(FInfo, 2, processes[iProc], FREQUENCY_LIMITS); statusFreq[iProc][2] = 1; /* and sending the appropriate correlation chunk */ /* allocating some memory */ resCDPart = alloc2complex(FInfo[1] - FInfo[0] + 1, info->nR); for (iR = 0; iR < info->nR; iR++) { for (i = 0, iF = FInfo[0]; iF <= FInfo[1]; iF++, i++) { resCDPart[iR][i] = resCD[iR][iF - initF]; /* fprintf(stderr, "iR %d iF %d [%f %f]\n", iR, iF, resCDPart[iR][i].r, resCDPart[iR][i].i);*/ } } /* sending frequency partition to the slave process */ SendCplx(resCDPart[0], (FInfo[1] - FInfo[0] + 1) * info->nR, processes[iProc], COVARIANCE_PARTITION); free2complex(resCDPart); } /* waiting modelled frequencies */ /* master process will send more frequencies if there's more work to do */ /* measuring elapsed time */ wallcpu = walltime(); /* reseting frequency counter */ FReceived = 0; while (FOREVER) { pid = RecvFloat(gradPart, info->numberPar * info->limRange, -1, PARTIAL_GRADIENT); /* finding the frequency limits of this process */ /* DD fprintf(stderr, "Master finding the frequency limits of this process\n"); */ iProc = 0; while (pid != processes[iProc]) iProc++; /* stacking gradient */ for (i = 0; i < info->numberPar * info->limRange; i++) { grad[i] += gradPart[i]; /* DD fprintf(stderr, "i %d grad %f gradPart %f\n", i, grad[i], gradPart[i]);*/ } /* summing frequencies that are done */ FReceived += procInfo[iProc][1] - procInfo[iProc][0] + 1; if (info->verbose) fprintf(stderr, "Master received %d frequencies, remaining %d\n", FReceived, info->nF - FReceived); /* defining new frequency limits */ i = 0; while (i < nFreqPart && statusFreq[i][2]) i++; /* DD fprintf(stderr, "i %d nFreqPart %d\n", i, nFreqPart);*/ if (i < nFreqPart) { /* there is still more work to be done */ /* tell this process to not die */ die = 0; SendInt(&die, 1, processes[iProc], DIE); FInfo[0] = statusFreq[i][0]; FInfo[1] = statusFreq[i][1]; if (info->verbose) fprintf(stderr, "Master sending frequencies [%d, %d] to slave %d\n", FInfo[0], FInfo[1], processes[iProc]); procInfo[iProc][0] = FInfo[0]; procInfo[iProc][1] = FInfo[1]; SendInt(FInfo, 2, processes[iProc], FREQUENCY_LIMITS); statusFreq[i][2] = 1; /* sending covariance partition */ /* allocating some memory */ resCDPart = alloc2complex(FInfo[1] - FInfo[0] + 1, info->nR); for (iR = 0; iR < info->nR; iR++) { for (i = 0, iF = FInfo[0]; iF <= FInfo[1]; iF++, i++) { resCDPart[iR][i] = resCD[iR][iF - initF]; } } /* sending frequency partition to the slave process */ SendCplx(resCDPart[0], (FInfo[1] - FInfo[0] + 1) * info->nR, processes[iProc], COVARIANCE_PARTITION); free2complex(resCDPart); } else { /* tell this process to die since there is no more work to do */ if (info->verbose) fprintf(stderr, "Master ''killing'' slave %d\n", processes[iProc]); die = 1; SendInt(&die, 1, processes[iProc], DIE); } /* a check to get out the loop */ if (FReceived >= info->nF) break; } /* getting elapsed time */ wallcpu = walltime() - wallcpu; fprintf(stderr, "Frechet derivative wall clock time = %f seconds\n\n", wallcpu); /* back to impedances*/ if (IMPEDANCE) { for (i = 0; i < info->nL + 1; i++) { alpha[i] *= rho[i]; beta[i] *= rho[i]; } } /* finally the gradient, the 2 is due Parseval */ for (iDer = 0; iDer < numberPar * limRange; iDer++) { grad[iDer] *= 2 / (float) (nTotalSamples * oFNorm); } /* getting gradient in impedance domain */ if (IMPEDANCE) { offset = 0; for (i = lim[0], iL = 0; iL < limRange; iL++, i++) { if (vpFrechet) { grad[iL] /= rho[i]; offset = limRange; } if (vsFrechet) { grad[iL + offset] /= rho[i]; offset += limRange; } if (rhoFrechet) { grad[iL + offset] = - alpha[i] * grad[iL] - beta[i] * grad[iL + limRange] + grad[iL + 2 * limRange]; } } } if (PRIOR) { auxm1 = 1. / (float) (numberPar * limRange); /* normalization */ /* considering the regularization or model covariance term */ for (i = 0; i < limRange; i++) { for (offset = i, iL = 0; iL < limRange; iL++) { iU = 0; if (vpFrechet) { grad[iL] += (alpha[i + lim[0]] - alphaMean[i + lim[0]]) * CMvP[offset] * auxm1; iU = limRange; /* used as offset in gradient vector */ } if (vsFrechet) { grad[iL + iU] += (beta[i + lim[0]] - betaMean[i + lim[0]]) * CMvS[offset] * auxm1; iU += limRange; } if (rhoFrechet) { grad[iL + iU] += (rho[i + lim[0]] - rhoMean[i + lim[0]]) * CMrho[offset] * auxm1; } offset += MAX(SGN0(i - iL) * (limRange - 1 - iL), 1); } } } /* normalizing gradient normalize(grad, numberPar * limRange);*/ /* freeing memory */ free1float(gradPart); }