#include "iwsim.hh" //#define IWAVE_VERBOSE //#define IWAVE_APPLY_VERBOSE namespace TSOpt { // helper function - not accessible outside this file! void synch(IWAVE * pstate, bool fwd, int it, int iv, IWaveInfo const & ic, FILE * stream) { // no-op unless MPI is defined #ifdef IWAVE_USE_MPI int err = 0; // step info for the state to be updated int iopp; /* opposite neighbor index */ IPNT offs; /* neighbor offset */ MPI_Status status; int tmpsend, tmprecv; MPI_Datatype tmpsend_dt, tmprecv_dt; int tmpsend_val, tmprecv_val; void *tmpsend_buf, *tmprecv_buf; // double time; // time = 0.0; /* To avoid "unitialized variable" warning */ // fprintf(stream,"IWAVE::synch: printact = %d\n",pstate->printact); /* we use the time step internal index for the perturbed field because this is the field being updated - on call should be same as index for unperturbed field, but don't use this */ if ( (pstate->printact > 1) ) { if (fwd) { fprintf(stream,"\n\n**************************\n"); fprintf(stream, "****** SYNCH: FWD ********\n"); fprintf(stream, "**************************\n\n"); } else { fprintf(stream,"\n\n**************************\n"); fprintf(stream, "****** SYNCH: BWD ********\n"); fprintf(stream, "**************************\n\n"); } } if ( (pstate->printact > 6) ) { fprintf(stream,"\n------ synch: before exchange, step %d substep %d\n",it,iv); for (int ia=0;iamodel).ld_a), ia, stream); } } fflush(stream); } for (int ia=0;iamodel,ic); if (pstate->printact>5) { fprintf(stream,"synch: array loop, test ia=%d iv=%d upd=%d isa=%d\n", ia,iv,upd,isa); fflush(stream); } // if (fd_update(ia,iv,ic) && fd_isarr(ia,pstate->model,ic)) { if (upd && isa) { if ( (pstate->printact > 1) ) { fprintf(stream,"\n------ synch fwd=%d array=%d -------------\n",fwd,ia); fflush(stream); } IPNT gs; IPNT ge; RARR sendsave; ra_setnull(&sendsave); for ( int i = 0; i < (pstate->model).nnei; ++i ) { if ( (pstate->printact > 1) ) { fprintf(stream,"array=%d neighbor=%d\n",ia,i); } // initialize all tmps to null values tmpsend = MPI_PROC_NULL; tmpsend_buf = &tmpsend_val; tmpsend_dt = MPI_INT; tmprecv = MPI_PROC_NULL; tmprecv_buf = &tmprecv_val; tmprecv_dt = MPI_INT; if ( (pstate->pinfo).seinfo[ia][i].type != MPI_DATATYPE_NULL ) { tmpsend = (pstate->pinfo).sranks[i]; tmpsend_buf = (pstate->pinfo).seinfo[ia][i].buf; tmpsend_dt = (pstate->pinfo).seinfo[ia][i].type; if ( (pstate->printact > 1) ) { fprintf(stream," sranks=%d\n",(pstate->pinfo).sranks[i]); fflush(stream); } // adjoint case - save a copy of send RARR, which becomes recv buffer // for adjoint if (!fwd) { rd_gse(&(((pstate->model).ld_s)[i]),ia,gs,ge); // cleanup - why is this necessary for (int k=(pstate->model).g.dim; kprintact > 1) ) { fprintf(stream,"\n bwd - copy send array with\n"); fprintf(stream," gs[0]=%d gs[1]=%d gs[2]=%d\n",gs[0],gs[1],gs[2]); fprintf(stream," ge[0]=%d ge[1]=%d ge[2]=%d\n",ge[0],ge[1],ge[2]); fflush(stream); } if ((err=ra_create(&sendsave,gs,ge))) { fprintf(stream,"\nError: synch from ra_create err=%d\n",err); RVLException e; e<<"\nError: IwaveSynch from ra_create err="<model).ld_s)[i])._s)[ia])))) { fprintf(stream,"\nError: synch from ra_copy err=%d\n",err); RVLException e; e<<"\nError: IWaveSynch from ra_copy err="<printact > 1) ) { fprintf(stream,"\n no send buffer\n"); } } // having found send index, find recv index if ((err=gen_i2pnt((pstate->model).g.dim,i,offs))) { fprintf(stream,"\nError: synch from gen_i2pnt\n"); fprintf(stream," dim=%d i=%d\n",(pstate->model).g.dim, i); RVLException e; e<<"\nError: IWaveSynch from gen_i2pnt\n"; throw e; } for (int k=0;k<(pstate->model).g.dim;k++) offs[k]*=(-1); if ((err=gen_pnt2i((pstate->model).g.dim,offs,&iopp))) { fprintf(stream,"\nError: synch from gen_pnt2i\n"); RVLException e; e<<"\nError: IWaveSynch from gen_i2pnt\n"; throw e; } if ( (pstate->pinfo).reinfo[ia][iopp].type != MPI_DATATYPE_NULL ) { tmprecv = (pstate->pinfo).rranks[iopp]; tmprecv_buf = (pstate->pinfo).reinfo[ia][iopp].buf; tmprecv_dt = (pstate->pinfo).reinfo[ia][iopp].type; if ( (pstate->printact > 1) ) { fprintf(stream," receive from %d rranks=%d\n",iopp,(pstate->pinfo).rranks[iopp]); fflush(stream); } } else { if ( (pstate->printact > 1) ) { fprintf(stream,"\n no recv buffer\n"); } } /* else { RVLException e; e<<"Error: IWaveSynch rk="<printact > 1)) { if ((tmpsend != MPI_PROC_NULL ) || (tmprecv != MPI_PROC_NULL)) fprintf(stream,"exchange with relative position %d: ",i); if (tmpsend != MPI_PROC_NULL) { fprintf(stream,"send to rk %d from virtual array\n",tmpsend); if (fwd) rd_dump(&(((pstate->model).ld_s)[i]), ia, stream); else ra_dump(&sendsave, stream); } if (tmprecv != MPI_PROC_NULL) { fprintf(stream,"recv fr rk %d into virtual array\n",tmprecv); rd_dump(&(((pstate->model).ld_r)[iopp]), ia, stream); } if ((tmpsend != MPI_PROC_NULL ) || (tmprecv != MPI_PROC_NULL)) fprintf(stream,"\n"); fflush(stream); } if ((tmpsend != MPI_PROC_NULL) && (pstate->printact > 5)) { fprintf(stream,"\n------ synch: send buffer before exchange\n"); fprintf(stream," step %d substep %d field %d rel pos %d\n", it,iv,ia,i); if (fwd) rd_print(&(((pstate->model).ld_s)[i]), ia, stream); else ra_print(&sendsave, stream); fflush(stream); } if ((tmprecv != MPI_PROC_NULL) && (pstate->printact > 5)) { fprintf(stream,"\n------ synch: receive buffer before exchange\n"); fprintf(stream," step %d substep %d field %d rel pos %d\n", it,iv,ia,i); rd_print(&(((pstate->model).ld_r)[iopp]), ia, stream); fflush(stream); } /* "send" is send buffer "recv" is receive buffer if fwd: SEND data in tmpsend_buf to rk=tmpsend RECEIVE data in tmprecv_buf from rk=tmprecv else: SEND data in tmprecv_buf to rk=tmprecv RECEIVE data in tmpsend_buf from rk=tmpsend */ // if ((tmpsend != MPI_PROC_NULL) && (tmprecv != MPI_PROC_NULL)) { if ((tmpsend != MPI_PROC_NULL) || (tmprecv != MPI_PROC_NULL)) { if (fwd) { if (pstate->printact > 1) { fprintf(stream,"\n------- send/recv: recv=%d send=%d substep=%d\n", tmprecv, tmpsend, iv); } err = MPI_Sendrecv(tmpsend_buf, 1, tmpsend_dt, tmpsend, iv, tmprecv_buf, 1, tmprecv_dt, tmprecv, iv, (pstate->pinfo).ccomm, &status); if ( err != MPI_SUCCESS ) { fprintf(stream, "ERROR. Internal: MPI_Sendrecv error #%d, nei=%d, iv=%d, arr=%d. ABORT.\n", err, i, iv, ia); RVLException e; e<<" ERROR. Internal: MPI_Sendrecv error #"<pinfo).ccomm, &status); if ( err != MPI_SUCCESS ) { fprintf(stream, "ERROR. Internal: MPI_Sendrecv error #%d, nei=%d, iv=%d, arr=%d. ABORT.\n", err, i, iv, ia); RVLException e; e<<" ERROR. Internal: MPI_Sendrecv error #"<pinfo).seinfo[ia][i].type != MPI_DATATYPE_NULL ) ) { if (!(sendsave._s0)) { fprintf(stream,"\nError: synch before axpy: sendsave not initialized\n"); RVLException e; e<<"\nError: IWaveSynch before axpy: sendsave not initialized\n"; throw e; } if ((pstate->printact) > 5) { fprintf(stream,"\n------ synch: delta send buffer after exchange \n"); fprintf(stream," step %d substep %d field %d rel pos %d\n", it,iv,ia,i); rd_dump(&(((pstate->model).ld_s)[i]), ia, stream); rd_print(&(((pstate->model).ld_s)[i]), ia, stream); } fflush(stream); if ((err=ra_axpy(&(((((pstate->model).ld_s)[i])._s)[ia]),&sendsave,REAL_ONE))) { fprintf(stream,"\nError: synch from ra_axpy err=%d\n",err); ra_dump(&(((((pstate->model).ld_s)[i])._s)[ia]),stream); ra_dump(&sendsave,stream); ra_destroy(&sendsave); RVLException e; e<<"Error: IWaveSynch from ra_axpy err="<pinfo).ccomm, &status); if ( err != MPI_SUCCESS ) { fprintf(stream, "ERROR. Internal: MPI_Sendrecv error #%d, nei=%d, iv=%d, arr=%d. ABORT.\n", err, i, iv, ia); RVLException e; e<<" ERROR. Internal: MPI_Sendrecv error #"<pinfo).reinfo[ia][iopp].type != MPI_DATATYPE_NULL ) ) { ra_zero(&(((((pstate->model).ld_r)[iopp])._s)[ia])); } } } } if ((tmpsend != MPI_PROC_NULL) && (pstate->printact > 5)) { fprintf(stream,"\n------ synch: send buffer after exchange\n"); fprintf(stream," step %d substep %d field %d rel pos %d\n", it,iv,ia,i); rd_print(&(((pstate->model).ld_s)[i]),ia, stream); fflush(stream); } if ((tmprecv != MPI_PROC_NULL) && (pstate->printact > 5)) { fprintf(stream,"\n------ synch: receive buffer after exchange\n"); fprintf(stream," step %d substep %d field %d rel pos %d\n", it,iv,ia,i); rd_print(&(((pstate->model).ld_r)[iopp]), ia, stream); fflush(stream); } } } } if ( (pstate->printact > 6) ) { fprintf(stream,"\n------ synch: after exchange, step %d substep %d\n",it,iv); for (int ia=0;iamodel).ld_a), ia, stream); } } fflush(stream); } #endif } IWaveSim::IWaveSim(int _order, bool _fwd, PARARRAY & pars, FILE * _stream, IWaveInfo const & _ic, int _printact, bool _dryrun, ostream & _drystr, ostream & _announce) : ic(_ic), fwd(_fwd), stream(_stream), printact(_printact), order(_order), cps(NULL), narr(0), dryrun(_dryrun), drystr(_drystr), announce(_announce) { try { // cerr<<"iwavesim constr\n"; // cerr<<"step 1: create list of i/o tasks\n"; IOTask(t,order,fwd,ic); #ifdef IWAVE_VERBOSE cerr<<"IWaveSim constructor: fwd="<getStateArray())[0])->model).g.dim; int check = 0; for (int i=0;igetStateArray())[0])->model).g.axes[i].id; if ( (id> -1) && (id < dim) ) { copy_axis(&(g.axes[id]),&((((w->getStateArray())[0])->model).g.axes[i])); check++; } } if (check != dim) { RVLException e; e<<"Error: IWaveSim constructor\n"; e<<" grid in model indices funged up\n"; throw e; } // trash all axes above spatial dimn for (int i=dim;i(pars,"nsnaps",0); if (!fwd && ((snaps<=0) && (order>0))) { RVLException e; e<<"Error: IWaveSim constructor\n"; e<<" adjoint mode (fwd=false):"<<"\n"; e<<" must provide positive number of \n"; e<<" storage units for checkpoints (argument \"snaps\")\n"; e<<" however snaps = "<0 if (!fwd && order>0) { typedef RARR* RP; typedef RARR** RPP; narr = snaps*pow2(order-1)*ndyn; RARR * cpstmp = new RARR[narr]; RARR ** cpstmp2 = new RP[snaps*pow2(order-1)]; for (size_t i=0;igetRefStateArray())[0]->model.ld_a.narr;k++) { if (fd_isarr(k,(w->getRefStateArray())[0]->model,ic) && fd_isdyn(k,ic)) { // pull out gs, ge for kth rarr in w->getRefStateArray[0] IPNT gs; IPNT ge; ra_a_gse(&((w->getRefStateArray())[0]->model.ld_a._s[k]),gs,ge); // int ndim = (w->getRefStateArray())[0]->model.ld_a._s[k].ndim; for (int i=0;indyn-1) { RVLException e; e<<"Error: IWaveSim: construct checkpoint array\n"; e<<" bad news - index into rarray "<keyword<<"\n"; #endif tmp = new IWaveSampler(w->getStateArray()[0], t[i]->keyword, pars, stream); // mod of 07.12.13: if current job does not provide source/sink for // this i/o task, then sampler returns no axes. in that case, set // this pointer in s to NULL if (tmp->getNumAxes() == 0) { #ifdef IWAVE_VERBOSE cerr<<"sampler "<keyword<<" is null\n"; #endif delete tmp; tmp = NULL; } else { /////// loop through sampler axes, add each to grid, then on /////// success add sampler address to sim list // cerr<<"sampler "<keyword<<" is live\n"; // note these are internal simulation axes, not archival, // which will require some re-arranging in traceio // grid_union(grid *, std::vector) // cerr<<"in sampler loop: sampler index = "<getNumAxes(); k++) // fprint_axis(stderr,tmp->getAxis(k)); // fprintf(stderr," add to grid:\n"); // fprint_grid(stderr,g); // IMPORTANT MOD 11.12.14: since physical domain is spec'd by FIELD ID 0, // only add spatial axes for FIELD ID 0. These axes were already fixed in // step 1, by initial construction of grid. So skip all subsequent axes // with id < dim for (int j=0; jgetNumAxes();j++) { // IMPORTANT CHANGE 07.12.13: the time axis is special, because // the internal step is already fixed by the IWAVE constructor. // therefore, change this axis to have the simulation time step // before registering it via grid_union. // Change 08.12.13: copy axis to workspace - only const access // now allowed axis * a = new axis; init_default_axis(a); copy_axis(a, &(tmp->getAxis(j))); float tntmp = 0.0f; if (a->id == g.dim) { // signals time axis!! if (ProtectedDivision((a->n * a->d), (w->getStateArray()[0]->model.tsind.dt), tntmp)) { RVLException e; e<<"Error: IWaveSim constructor\n"; e<<" zerodivide by dt stored in IWaveTree model struct\n"; e<<" dt = "<getStateArray()[0]->model.tsind.dt<<"\n"; throw e; } // adjust number, spacing a->n = iwave_max(1, (int)(tntmp+0.1f)); a->d = w->getStateArray()[0]->model.tsind.dt; // adjust origin so that in all cases 0 is a (virtual) grid point // this assures that all time axes are compatible. Adjust o and n // so that new grid interval contains old. float tmpo = a->o; a->o = // ((int)(((a->o)/(a->d))-0.1)) ((int)((a->o)/(a->d))) *(a->d); if (tmpoo) { a->o -= a->d; a->n ++; } // notice that now simulation time axis has been DETERMINED, so // must be used in trace sampler!!!! } if ((a->id > g.dim-1) && (!grid_union(&g,a))) { // cerr<<"Error: IWaveSim constructor from grid_union\n"; RVLException e; e<<"Error: IWaveSim constructor from grid_union\n"; fprintf(stream,"Error: IWaveSim constructor from grid_union\n"); fprintf(stream," failed to add these axes:\n"); for (int k=0;kgetNumAxes(); k++) fprint_axis(stream,tmp->getAxis(k)); fprintf(stream," to grid:\n"); fprint_grid(stream,g); throw e; } // having added to grid, or not, trash it delete a; } // fprintf(stderr," result grid:\n"); // fprint_grid(stderr,g); } s.push_back(tmp); } // 08.01.14: panelindex construction makes this unnecessary // fprint_grid(stderr,g); // step 4: modify grid if necessary // no-op if no mpi //#ifdef IWAVE_USE_MPI // mpi_update_grid(&g); //#endif // cerr<<"exit iwavesim constructor\n"; } catch (RVLException & e) { e<<"\ncalled from IWaveSim constructor\n"; throw e; } } IWaveSim::~IWaveSim() { // cerr<<"destructor\n"; for (size_t i=0; igetStateArray()[0]->model.specs); } // time axis - index=dim: last data point if fwd = false (reverse) // step 5: initial sample - includes any post-contruction // initialization // step 6: sim loop - includes time, record,... // time step function knows what to do based // merely on size. use next_step to increment // extended axes - time step loop is explicit // here more = more records for (panelindex=first; panelindex<=last; panelindex++) { /* for (int i=0;igetStateArray().size();i++) { if (int err=rd_a_zero(&((w->getStateArray()[i]->model).ld_a))) { RVLException e; e<<"Error: IWaveTree main constructor, IWAVE["<getStateArray().size();i++) { iwave_dynamic_init(w->getStateArray()[i],start[g.dim],ic); } for (int it=start[g.dim]; it sampler["<sample(g,step,ic.get_iwave_fields()[t[i]->rarrindex].gtype,fwd, t[i]->input,w->getStateArray()[t[i]->iwaveindex], t[i]->rarrindex,t[i]->iwaveindex,stream, dryrun,drystr); #ifdef IWAVE_VERBOSE cerr<<"IWaveSim::run - rk="<keyword,"active") == ACTIVE_LINEAR)) { ic.get_loopdef()(s[i]->get_gmin(),s[i]->get_gmax(),tmax,t[i]->input,stream,fdm); } } */ } // first time through, call check #ifdef IWAVE_VERBOSE cerr<<"IWaveSim::run - call check\n"; #endif if (!dryrun) { if (it==start[g.dim]) { ic.get_check()(w->getRDOMArray()[0],fdm,stream); } } if (dryrun) { drystr<<"\nIWaveSim::run fwd step "< "<5) { fprintf(stream,"iwsim::run timestep it=%d iv=%d\n", it,iv); fflush(stream); } ic.get_timestep()(w->getRDOMArray(),fwd,iv,fdm); if (printact>5) { fprintf(stream,"iwsim::run return from timestep\n"); fflush(stream); } // in fwd loop, synch ALL dynamic arrays #ifdef IWAVE_USE_MPI MPI_Barrier(retrieveComm()); #endif for (size_t k=0; kgetStateArray().size(); k++) { if (w->getStateArray()[k]->printact > 5) { fprintf(stream,"iwsim::run: before synch k=%d it=%d iv=%d\n" ,k,it,iv); fflush(stream); } #ifdef IWAVE_VERBOSE cerr<<"IWaveSim::run -synch substep="<getStateArray()[k],fwd,it,iv,ic,stream); if (printact>5) { fprintf(stream,"iwsim::run: after synch k=%d it=%d iv=%d\n", k,it,iv); fflush(stream); } } } } } if (dryrun) drystr<<"\n"; step[g.dim]=stop[g.dim]; for (size_t i=0; isample(g,step,ic.get_iwave_fields()[t[i]->rarrindex].gtype,fwd,t[i]->input, w->getStateArray()[t[i]->iwaveindex], t[i]->rarrindex,t[i]->iwaveindex,stream, dryrun,drystr); } } } /******* ADJOINT LOOP, ORDER=0 - SOURCE CASE *********/ else if ((fwd==0) && (order==0)) { // cerr<<"\nIWaveSim::run - BACKWARD WET RUN\n\n"; if (dryrun) { drystr<<"\nIWaveSim::run - BACKWARD DRY RUN\n\n"; } #ifdef IWAVE_VERBOSE cerr<<"IWaveSim::run - dynamic init\n"; #endif for (size_t i=0;igetStateArray().size();i++) { iwave_dynamic_init(w->getStateArray()[i],start[g.dim],ic); } for (int it=stop[g.dim]; it>=start[g.dim]; it--) { float dt = g.axes[g.dim].d; float ot = g.axes[g.dim].o; #ifdef IWAVE_VERBOSE cerr<<"IWaveSim::run - it="<sample(g,step,ic.get_iwave_fields()[t[i]->rarrindex].gtype,fwd, t[i]->input,w->getStateArray()[t[i]->iwaveindex], t[i]->rarrindex,t[i]->iwaveindex,stream, dryrun,drystr); } } // first time through, call check #ifdef IWAVE_VERBOSE cerr<<"IWaveSim::run - call check\n"; #endif if (!dryrun) { if (it==start[g.dim]) ic.get_check()(w->getRDOMArray()[0],fdm,stream); } if (dryrun) { drystr<<"\nIWaveSim::run fwd step "< "<-1;iv--) { for (int iv=0; ivgetRDOMArray(),fwd,iv,fdm); // in fwd loop, synch ALL dynamic arrays for (size_t k=0; kgetStateArray().size(); k++) { // if (w->getStateArray()[k]->printact > 5) // fprintf(stream,"\n*** SYNCH: iwdx = %d\n\n",k); #ifdef IWAVE_VERBOSE cerr<<"IWaveSim::run -synch substep="<getStateArray()[k],fwd,it,iv,ic,stream); // cerr<<" k="<sample(g,step,ic.get_iwave_fields()[t[i]->rarrindex].gtype,fwd, t[i]->input,w->getStateArray()[t[i]->iwaveindex], t[i]->rarrindex,t[i]->iwaveindex,stream, dryrun,drystr); } } } /******** ONE STEP CASE OF ADJOINT *******/ else if (stop[g.dim]-start[g.dim]==1) { for (size_t i=0;igetStateArray().size();i++) { iwave_dynamic_init(w->getStateArray()[i],start[g.dim],ic); } int it = start[g.dim]; // ref state index int at = stop[g.dim]; // pert state index if (dryrun) { drystr<<"\nIWaveSim::run - ADJOINT DRY RUN\n"; drystr<<" SINGLE STEP CASE\n\n"; } #ifdef IWAVE_VERBOSE cerr<<"\nIWaveSim::run - ADJOINT DRY RUN\n"; cerr<<" SINGLE STEP CASE\n\n"; #endif // load reference data step[g.dim]=it; bool reffwd = true; for (size_t i=0; iiwaveindex < (int)pow2(order-1) && s[i]) { s[i]->sample(g,step,ic.get_iwave_fields()[t[i]->rarrindex].gtype,reffwd, t[i]->input,w->getStateArray()[t[i]->iwaveindex], t[i]->rarrindex,t[i]->iwaveindex,stream, dryrun,drystr); } } // check if (!dryrun) { ic.get_check()(w->getRDOMArray()[0],fdm,stream); } // load adjoint data step[g.dim]=at; for (size_t i=0; iiwaveindex >= (int)pow2(order-1) && s[i]) { s[i]->sample(g,step,ic.get_iwave_fields()[t[i]->rarrindex].gtype,fwd, t[i]->input,w->getStateArray()[t[i]->iwaveindex], t[i]->rarrindex,t[i]->iwaveindex,stream, dryrun,drystr); } } if (!dryrun) { // backwards step - only need to synch top-order pert arrays for (int iv=fd_numsubsteps(ic)-1; iv>-1; iv--) { ic.get_timestep()(w->getRDOMArray(),fwd,iv,fdm); for (size_t k=pow2(order-1); kgetStateArray()[k]->printact > 5) // fprintf(stream,"\n*** SYNCH: iwdx = %d\n\n",k); synch(w->getStateArray()[k],fwd,at,iv,ic,stream); } } } else { drystr<<"IWaveSim::run adj - first adjoint step: at="<"< cplist(snaps); int it = start[g.dim]; // ref state index int at = stop[g.dim]; // pert state index #ifdef IWAVE_VERBOSE cerr<<"\nIWaveSim::run adj - load initial data time step "<getStateArray().size();i++) { iwave_dynamic_init(w->getStateArray()[i],start[g.dim],ic); } for (size_t i=0; iiwaveindex < (int)pow2(order-1) && s[i]) { s[i]->sample(g,step,ic.get_iwave_fields()[t[i]->rarrindex].gtype,reffwd, t[i]->input,w->getStateArray()[t[i]->iwaveindex], t[i]->rarrindex,t[i]->iwaveindex,stream, dryrun,drystr); } } // check if it=start if (!dryrun) { if (it==start[g.dim]) ic.get_check()(w->getRDOMArray()[0],fdm,stream); } ACTION::action whatodo; if (dryrun) { drystr<<"\nIWaveSim::run - ADJOINT DRY RUN\n"; drystr<<" FORWARD TIME LOOP\n\n"; } do { whatodo = r.revolve(); if (whatodo == ACTION::takeshot) { int cp = r.getcheck(); for (int j=0;j<(int)pow2(order-1);j++) { int l = 0; for (int k=0;kgetStateArray()[0]->model,ic) && fd_isdyn(k,ic)) { if (ra_a_copy(&(cps[cp][j][l]),&(((w->getRefRDOMArray())[j])->_s[k]))) { RVLException e; e<<"Error: IWaveSim::run\n"; e<<"attempt to store checkpoint "<getRefRDOMArray(),reffwd,iv,fdm); for (size_t k=0; kgetStateArray()[k]->printact > 5) // fprintf(stream,"\n*** SYNCH: iwdx = %d\n\n",k); synch(w->getRefStateArray()[k],reffwd,it,iv,ic,stream); } } #ifdef IWAVE_VERBOSE cerr<<"IWaveSim::run adj - fwd step "<"<"<iwaveindex < (int)pow2(order-1) && s[i]) { s[i]->sample(g,step,ic.get_iwave_fields()[t[i]->rarrindex].gtype,reffwd, t[i]->input,w->getStateArray()[t[i]->iwaveindex], t[i]->rarrindex,t[i]->iwaveindex,stream, dryrun,drystr); } } } } if (whatodo == ACTION::firsturn) { #ifdef IWAVE_VERBOSE cerr<<"\nIWaveSim::run - ADJOINT WET RUN\n"; cerr<<" REVERSE TIME LOOP\n\n"; #endif if (dryrun) { drystr<<"\nIWaveSim::run - ADJOINT DRY RUN\n"; drystr<<" REVERSE TIME LOOP\n\n"; } step[g.dim]=at; for (size_t i=0; iiwaveindex >= (int)pow2(order-1)) { // iwave_dynamic_init(w->getStateArray()[t[i]->iwaveindex],at,ic); // if (!(t[i]->input) ) // ra_a_zero(&(w->getStateArray()[t[i]->iwaveindex]->model.ld_a._s[t[i]->rarrindex])); } // pert sample if (t[i]->iwaveindex >= (int)pow2(order-1) && s[i]) { s[i]->sample(g,step,ic.get_iwave_fields()[t[i]->rarrindex].gtype,fwd, t[i]->input,w->getStateArray()[t[i]->iwaveindex], t[i]->rarrindex,t[i]->iwaveindex,stream, dryrun,drystr); } } if (!dryrun) { for (int iv=fd_numsubsteps(ic)-1; iv>-1; iv--) { ic.get_timestep()(w->getRDOMArray(),fwd,iv,fdm); for (size_t k=pow2(order-1); kgetStateArray()[k]->printact > 5) // fprintf(stream,"\n*** SYNCH: iwdx = %d\n\n",k); synch(w->getStateArray()[k],fwd,at,iv,ic,stream); } } #ifdef IWAVE_VERBOSE cerr<<"IWaveSim::run adj - first adjoint step: at="<"<"<iwaveindex >= (int)pow2(order-1) && s[i]) { s[i]->sample(g,step,ic.get_iwave_fields()[t[i]->rarrindex].gtype,fwd, t[i]->input,w->getStateArray()[t[i]->iwaveindex], t[i]->rarrindex,t[i]->iwaveindex,stream, dryrun,drystr); } } #ifdef IWAVE_VERBOSE cerr<<"backwards step"<-1; iv--) { ic.get_timestep()(w->getRDOMArray(),fwd,iv,fdm); for (size_t k=pow2(order-1); kgetStateArray()[k]->printact > 5) // fprintf(stream,"\n*** SYNCH: iwdx = %d\n\n",k); synch(w->getStateArray()[k],fwd,at,iv,ic,stream); } } #ifdef IWAVE_VERBOSE cerr<<"backwards step"<"<"<iwaveindex >= (int)pow2(order-1) && s[i]) { s[i]->sample(g,step,ic.get_iwave_fields()[t[i]->rarrindex].gtype,fwd, t[i]->input,w->getStateArray()[t[i]->iwaveindex], t[i]->rarrindex,t[i]->iwaveindex,stream, dryrun,drystr); } } // for dry run, dump revolve output to // dry run file. Else to sim output. if (dryrun) drystr<<"\nRevolve report:\n"< i are NOT full for (int i=g.dim-1;i>g.dim;i--) { if (step[i] IWaveEnvironment\n"; #endif IWaveEnvironment(argc, argv, 0, &par, &stream); #ifdef IWAVE_USE_MPI if (retrieveGroupID() == MPI_UNDEFINED) { #ifdef IWAVE_APPLY_VERBOSE fprintf(stderr,"NOTE: idle rank=%d, finalize MPI, cleanup, exit\n",retrieveGlobalRank()); #endif fprintf(stream,"NOTE: finalize MPI, cleanup, exit\n"); fflush(stream); } else { #endif #ifdef IWAVE_APPLY_VERBOSE fprintf(stderr,"NOTE: working rank=%d proceed with sim\n",retrieveGlobalRank()); #endif int dryrun = 0; parse(*par,"dryrun",dryrun); ofstream * drystr = NULL; if (dryrun) { stringstream dryfile; dryfile <<"dryrun"; dryfile <0) { RVLException e; e<<"Error: IWaveApply: failed to read parameter adj\n"; e<<" required for application of derivative of any positive order\n"; e<<" (int) = [0 = apply derivative, 1 = apply adjoint derivative]\n"; e<<" check parameter file\n"; throw e; } if (adj == 0) fwd = true; else fwd = false; #ifdef IWAVE_APPLY_VERBOSE cerr<<"IWaveApply: fwd = "<(*par,"printact",0); #ifdef IWAVE_APPLY_VERBOSE cerr<<"IWaveApply: printact = "< IWaveSim constructor\n"; cerr<<"IWaveApply: fwd="< IWaveSim::run\n"; #endif sim.run(); } else { IWaveSim sim(deriv,fwd,*par,stream,ic,printact,dryrun,cerr); #ifdef IWAVE_APPLY_VERBOSE cerr<<"IWaveApply -> IWaveSim::run\n"; #endif sim.run(); } #ifdef IWAVE_APPLY_VERBOSE cerr<<"IWaveApply -> exit\n"; #endif if (drystr) { drystr->close(); delete drystr; } #ifdef IWAVE_USE_MPI /* end nontriv comm branch */ } MPI_Barrier(MPI_COMM_WORLD); #endif ps_delete(&par); fclose(stream); } catch (RVLException & e) { e<<"\ncalled from IWaveApply\n"; throw e; } } } // end namespace TSOpt