Пример #1
0
/**
   Update various quantities upon updating dmreal.
*/
void update_dm(SIM_T *simu){
    const PARMS_T *parms=simu->parms;
    if(!parms->fit.square && simu->dmrealsq){
	/* Embed DM commands to a square array for fast ray tracing */
	for(int idm=0; idm<parms->ndm; idm++){
	    loc_embed(simu->dmrealsq->p[idm], simu->recon->aloc->p[idm], simu->dmreal->p[idm]->p);
	}
    }
#if USE_CUDA
    if(parms->gpu.wfs || parms->gpu.evl){
	gpu_dmreal2gpu(simu->dmrealsq);
    }
#endif
    calc_cachedm(simu);
}
Пример #2
0
void maos_isim(int isim){
    const PARMS_T *parms=global->parms;
    RECON_T *recon=global->recon;
    SIM_T   *simu =global->simu;
    int iseed=global->iseed;
    int simstart=parms->sim.start;
    int simend=parms->sim.end;
    if(isim==simstart+1){//skip slow first step.
	tk_atm=myclockd();
    }
    if(isim+2+parms->sim.dtrat_hi>=simend){
	draw_single=0;
    }
    double ck_0=myclockd();
    simu->isim=isim;
    simu->status->isim=isim;
    sim_update_etf(simu);
    if(parms->atm.frozenflow){
#if USE_CUDA
	if(parms->gpu.evl || parms->gpu.wfs){
	    /*may need to copy another part */
	    gpu_atm2gpu(simu->atm, simu->atmscale, parms, iseed, isim);
	}
#endif
    }else{
	//Do not put this one inside parallel 
	genatm(simu);
	/*re-seed the atmosphere in case atm is loaded from shm/file */
	seed_rand(simu->atm_rand, lrand(simu->init_rand));
    }
    OMPTASK_SINGLE{
	if(parms->sim.dmproj){
	    /* teporarily disable FR.M so that Mfun is used.*/
	    cell *FRM=recon->FR.M; recon->FR.M=NULL; 
	    muv_solve(&simu->dmproj, &recon->FL, &recon->FR, NULL);
	    recon->FR.M=FRM;/*set FR.M back*/
	    if(parms->save.dm){
		zfarr_dcell(simu->save->dmproj, simu->isim, simu->dmproj);
	    }
	    if(!parms->fit.square){
		/* Embed DM commands to a square array for fast ray tracing */
		for(int idm=0; idm<parms->ndm; idm++){
		    loc_embed(simu->dmprojsq->p[idm], recon->aloc->p[idm], simu->dmproj->p[idm]->p);
		}
	    }
#if USE_CUDA
	    if(parms->gpu.evl || parms->gpu.wfs){
		gpu_dmproj2gpu(simu->dmprojsq);
	    }
#endif
	}
	save_dmreal(simu);
	extern int NO_RECON, NO_WFS, NO_EVL;
	if(PARALLEL){
	    /*
	      We do the big loop in parallel to make better use the
	      CPUs. Notice that the reconstructor is working on grad from
	      last time step so that there is no confliction in data access.
	    */
	    /*when we want to apply idealngs correction, wfsgrad need to wait for perfevl. */
	    long group=0;
	    if(parms->gpu.evl && !NO_EVL){
		//Queue tasks on GPU, no stream sync is done
		QUEUE_THREAD(group, simu->perf_evl_pre, 0);
	    }
	    if(!parms->tomo.ahst_idealngs && parms->gpu.wfs && !NO_WFS){
		//task for each wfs
		QUEUE_THREAD(group, simu->wfs_grad_pre, 0);
	    }
	    if(!NO_RECON){
		//don't put this first. It has cpu overhead in computing gradol
		QUEUE(group, reconstruct, simu, 1, 0);
	    }
	    if(!NO_EVL){
		if(parms->gpu.evl){
		    //wait for GPU tasks to be queued before calling sync
		    WAIT(group);
		}
		QUEUE(group, perfevl, simu, 1, 0);
	    }
	    if(!NO_WFS){
		if(parms->tomo.ahst_idealngs || (parms->gpu.wfs && !parms->gpu.evl)){
		    //in ahst_idealngs mode, weight for perfevl to finish.
		    //otherwise, wait for GPU tasks to be queued before calling sync
		    WAIT(group);
		}
		QUEUE(group, wfsgrad, simu, 1, 0);
	    }
	    if(!NO_RECON){
		//wait for all tasks to finish before modifying dmreal
		WAIT(group);
		shift_grad(simu);/*before filter() */
		filter_dm(simu);/*updates dmreal, so has to be after prefevl/wfsgrad is done. */
	    }
	    WAIT(group);
	}else{/*do the big loop in serial mode. */
	    if(parms->sim.closeloop){
		if(!NO_EVL) perfevl(simu);/*before wfsgrad so we can apply ideal NGS modes */
		if(!NO_WFS) wfsgrad(simu);/*output grads to gradcl, gradol */
		if(!NO_RECON) {
		    reconstruct(simu);/*uses grads from gradlast cl, gradlast ol. */
		    shift_grad(simu);
		    filter_dm(simu);
		}
	    }else{/*in OL mode,  */
		if(!NO_WFS) wfsgrad(simu);
		if(!NO_RECON) {
		    shift_grad(simu);
		    reconstruct(simu);
		    filter_dm(simu);
		}
		if(!NO_EVL) perfevl(simu);
	    }
	}
    }
    double ck_end=myclockd();
    long steps_done=iseed*(simend-simstart)+(isim+1-simstart);
    long steps_rest=parms->sim.nseed*(simend-simstart)-steps_done;
    if(isim!=simstart){
	simu->status->rest=(long)((ck_end-tk_0-(tk_atm-tk_1)*(iseed+1))/steps_done*steps_rest
				  +(tk_atm-tk_1)*(parms->sim.nseed-iseed-1));
	simu->status->mean=(ck_end-tk_atm)/(double)(isim-simstart);
    }
    simu->status->laps=(long)(ck_end-tk_0);
    simu->status->tot  =ck_end-ck_0;
    simu->status->wfs  =simu->tk_wfs;
    simu->status->recon=simu->tk_recon;
    simu->status->other=simu->tk_cache;
    simu->status->eval =simu->tk_eval;
    simu->status->scale=1;
    if(simu->timing){
	simu->timing->p[isim*simu->timing->nx]=get_job_mem();
	simu->timing->p[isim*simu->timing->nx+1]=simu->status->tot;
	simu->timing->p[isim*simu->timing->nx+2]=simu->status->wfs;
	simu->timing->p[isim*simu->timing->nx+3]=simu->status->recon;
	simu->timing->p[isim*simu->timing->nx+4]=simu->status->eval;
    }
    double this_time=myclockd();
    if(this_time>simu->last_report_time+1 || isim+1==simend || parms->sim.pause){
	/*we don't print out or report too frequently. */
	simu->last_report_time=this_time;
#if defined(__linux__) || defined(__APPLE__)
	scheduler_report(simu->status);
#endif
	print_progress(simu);
    }
}
Пример #3
0
static void test_accuracy(int argc, char **argv){
    double displacex=0.01;
    double displacey=0.05;
    double scale=1.01;/*.414065; */
    int wrap=0;  

    double D=30;
    double D2=32;
    int save=1;
    if(argc>1){
	scale=strtod(argv[1], 0);
    }
    if(argc>2){
	displacex=strtod(argv[2], 0);
    }
    if(argc>3){
	displacey=strtod(argv[3], 0);
    }
    if(argc>4){
	wrap=strtol(argv[4], 0, 10);
    }
    if(argc>5){
	D=strtod(argv[5], 0);
    }
    if(argc>6){
	D2=strtod(argv[6], 0);
    }
    if(argc>7){
	save=strtol(argv[7], 0, 10);
    }

    double dx=1/64.; 
    double dsa=0.5;
    map_t *screen=mapnew(D2/dx, D2/dx, dx, dx, 0);
    dset((dmat*)screen, 1);
    for(long iy=0; iy<screen->ny; iy++){
	for(long ix=0; ix<screen->nx; ix++){
	    screen->p[ix+iy*screen->nx]=sin((double)ix/screen->nx*2*M_PI)*sin((double)iy/screen->ny*2*M_PI);
	}
    }

    /*loc for the map */
    loc_t *locin=mksqloc(screen->nx,screen->ny,dx,dx,screen->ox,screen->oy);
    
    //pts_t *pts=realloc(mkannloc(D, 0, 1./2.,0), sizeof(pts_t));
    pts_t *pts=realloc(mksqloc_auto(D/dsa, D/dsa, dsa, dsa), sizeof(pts_t));
    pts->dx=dx;
    pts->dy=dx;
    pts->nx=dsa/dx;
    pts->ny=pts->nx;
    loc_t *loc=pts2loc(pts);

    loc_create_map(locin);
    loc_create_stat(loc);
    loc_create_map(loc);
    locstat_t *locstat=loc->stat;
  
    map_t *screen2=mapnew2(locin->map);
    dset((dmat*)screen2, NAN);
    loc_embed(screen2, locin, screen->p);


    double *phi_pts, *phi_loc, *phi_stat;
    double *phi_loc2loc, *phi_h, *phi_cub, *phi_cub2, *phi_cubh;

    double cubic=0.3;
    int ii;
	    
    info("displacex=%g, displacey=%g, scale=%g, wrap=%d\n",
	 displacex, displacey,scale,wrap);
	
    double diff1, diff2,diff3,diff14,diff15;
    diff1=0;
    diff2=0;
    diff3=0;
    diff14=0;
    diff15=0;
	
    phi_pts=calloc(loc->nloc, sizeof(double));
    phi_loc=calloc(loc->nloc, sizeof(double));
    phi_stat=calloc(loc->nloc, sizeof(double));
    phi_loc2loc=calloc(loc->nloc, sizeof(double));

    map_t *map1=mapnew2(loc->map);
    prop_grid_map(screen, map1, -2, displacex, displacey, scale, wrap, 0,0);
    tic;
    prop_grid_map(screen, map1, 1, displacex, displacey, scale, wrap, 0,0);
    toc("map\t\t");

    prop_grid_pts(screen, pts, phi_pts, -2, displacex, displacey, scale, wrap, 0,0);
    tic;
    prop_grid_pts(screen, pts, phi_pts,  1, displacex, displacey, scale, wrap, 0,0);
    toc("pts\t\t");

    prop_grid_stat(screen, locstat, phi_stat, -2,displacex, displacey, scale, wrap, 0,0);
    tic;
    prop_grid_stat(screen, locstat, phi_stat , 1, displacex, displacey, scale, wrap, 0,0);
    toc("stat\t");tic;

    prop_grid(screen, loc, phi_loc, -2,displacex, displacey, scale, wrap, 0,0);
    tic;
    prop_grid(screen, loc, phi_loc,  1,displacex, displacey, scale, wrap, 0,0);
    toc("loc\t\t");


    prop_nongrid(locin, screen->p,loc, phi_loc2loc, -2,displacex, displacey, scale,0,0);
    toc("nongrid\t"); tic;
    prop_nongrid(locin, screen->p,loc, phi_loc2loc, 1,displacex, displacey, scale,0,0);
    toc("nongrid\t");
	
    phi_h=calloc(loc->nloc,sizeof(double));
 
    tic;
    dsp *hfor=mkh(locin, loc, displacex, displacey, scale);
    toc("mkh\t\t\t");
    dspmulvec(phi_h,hfor, screen->p, 'n', -2);
    tic;
    dspmulvec(phi_h,hfor, screen->p, 'n', 1);
    toc("mul h\t\t");


    phi_cub=calloc(loc->nloc,sizeof(double));
    phi_cub2=calloc(loc->nloc,sizeof(double));
    double *phi_cub3=calloc(loc->nloc,sizeof(double));
    double *phi_cub4=calloc(loc->nloc,sizeof(double));
    phi_cubh=calloc(loc->nloc, sizeof(double));

    prop_nongrid_cubic(locin,screen->p,loc,phi_cub,-2, displacex, displacey, scale, cubic,0,0);
    tic;
    prop_nongrid_cubic(locin,screen->p,loc,phi_cub,1, displacex, displacey, scale, cubic,0,0);
    toc("nongrid, cubic\t");
    prop_grid_cubic(screen, loc, phi_cub2, -2,displacex, displacey, scale,  cubic, 0,0);
    tic;
    prop_grid_cubic(screen, loc, phi_cub2, 1,displacex, displacey, scale,  cubic, 0,0);
    toc("grid,  cubic\t");
    prop_grid_cubic(screen2, loc,phi_cub3, -2,displacex, displacey, scale,  cubic, 0,0);
    tic;
    prop_grid_cubic(screen2, loc,phi_cub3, 1,displacex, displacey, scale,  cubic, 0,0);
    toc("grid2, cubic\t");
    prop_grid_stat_cubic(screen, locstat,phi_cub4, -2,displacex, displacey, scale,  cubic, 0,0);
    tic;
    prop_grid_stat_cubic(screen, locstat,phi_cub4, 1,displacex, displacey, scale,  cubic, 0,0);
    toc("grid  2stat, cubic\t");
    dsp *hforcubic;
    tic;
    hforcubic=mkh_cubic(locin, loc, displacex, displacey, scale, cubic);
    toc("mkh cubic \t\t");
    dspmulvec(phi_cubh, hforcubic,screen->p,'n',-2);
    tic;
    dspmulvec(phi_cubh, hforcubic,screen->p,'n',1);
    toc("cubic mul h\t\t");
    double diffc12=0,diff45=0,diff46=0,diff47=0;
    for(ii=0; ii<loc->nloc; ii++){
	diff1+=fabs(phi_loc[ii]-phi_pts[ii]);
	diff2+=fabs(phi_stat[ii]-phi_loc[ii]);
	diff3+=fabs(phi_stat[ii]-phi_pts[ii]);
	diff14+=fabs(phi_loc2loc[ii]-phi_pts[ii]);
	diff15+=fabs(phi_h[ii]-phi_pts[ii]);
	diff45+=fabs(phi_loc2loc[ii]-phi_h[ii]);
	diffc12+=fabs(phi_cub[ii]-phi_cubh[ii]);
	diff46+=fabs(phi_cub[ii]-phi_cub2[ii]);
	diff47+=fabs(phi_cub[ii]-phi_cub3[ii]);
    }
    info2("(pts-loc)=\t%g\n(loc-stat)=\t%g\n(stat-pts)=\t%g\n"
	  "(loc2loc-pts)=\t%g\n(h-pts)=\t%g\n"
	  "(loc2loc-h)=\t%g\n"
	  "(cub:h-loc2loc)=\t%g\n"
	  "(cub:map2loc-loc2loc)=\t%g\n"
	  "(cub:locmap2loc-loc2loc=\t%g\n"
	  ,diff1, diff2,diff3,diff14,diff15,diff45,diffc12, 
	  diff46, diff47);

//    exit(0);
    if(!save) return;
    mapwrite(screen2,"accphi_screen2");
    mapwrite(screen,"accphi_screen");
    locwrite((loc_t*)pts,"accphi_pts");
    locwrite(loc,"accphi_loc");
    locwrite(locin, "accphi_locin");
    loc_create_map_npad(locin, 0, 0, 0);
    mapwrite(locin->map, "accphi_locin_map");
    mapwrite(loc->map, "accphi_loc_map");
    mapwrite(map1, "accphi_map2map.bin");
    writedbl(phi_pts,loc->nloc,1,"accphi_pts1.bin");
    writedbl(phi_loc,loc->nloc,1,"accphi_loc0.bin");
    writedbl(phi_stat,loc->nloc,1,"accphi_stat.bin");
    writedbl(phi_loc2loc,loc->nloc,1,"accphi_loc2loc.bin");
    writedbl(phi_h,loc->nloc,1,"accphi_loc2h.bin");
    writedbl(phi_cub,loc->nloc,1,"accphi_cub_loc2loc.bin");
    writedbl(phi_cub2,loc->nloc,1,"accphi_cub_map2loc.bin");
    writedbl(phi_cub3,loc->nloc,1,"accphi_cub_locmap2loc.bin");
    writedbl(phi_cub4,loc->nloc,1,"accphi_cub_locmap2stat.bin");
    writedbl(phi_cubh,loc->nloc,1,"accphi_cub_loc2h.bin");
    info("saved\n");

    writedbl(phi_pts,loc->nloc,1,"accphi_pts.bin");
    writedbl(phi_cub,loc->nloc,1,"accphi_cub.bin");

    writebin(hfor, "accphi_hfor");
    writebin(hforcubic, "accphi_cub_hfor");
    dspfree(hfor);
    dspfree(hforcubic);
    free(phi_loc); free(phi_stat);
    free(phi_loc2loc);

    free(phi_pts);
    free(phi_h); 
    free(phi_cub); 
    free(phi_cubh);
	
    cellfree(screen);
    locfree(locin);
}
Пример #4
0
static inline void clipdm(SIM_T *simu, dcell *dmcmd){
    const PARMS_T *parms=simu->parms;
    if(!dmcmd) return;
    /*
      clip integrator. This both limits the output and
      feeds back the clip since we are acting on the integrator directly.
    */
    if(parms->sim.dmclip){
	for(int idm=0; idm<parms->ndm; idm++){
	    const int nact=dmcmd->p[idm]->nx;
	    if(parms->dm[idm].stroke->nx==1){
		if(parms->dm[idm].stroke->ny!=1){
		    error("dm.stroke is in wrong format\n");
		}
		int nclip=dclip(dmcmd->p[idm], 
				-parms->dm[idm].stroke->p[0],
				parms->dm[idm].stroke->p[0]);
		if(nclip>0){
		    info2("step %d DM %d: %d actuators clipped\n", simu->isim, idm, nclip);
		}
	    }else if(parms->dm[idm].stroke->nx==nact){
		if(parms->dm[idm].stroke->ny!=2){
		    error("dm.stroke is in wrong format\n");
		}
		
		double *pcmd=dmcmd->p[idm]->p;
		double *plow=parms->dm[idm].stroke->p;
		double *phigh=parms->dm[idm].stroke->p+nact;
		for(int iact=0; iact<nact; iact++){
		    if(pcmd[iact]<plow[iact]){
			pcmd[iact]=plow[iact];
		    }else if(pcmd[iact]>phigh[iact]){
			pcmd[iact]=phigh[iact];
		    }
		}		    
	    }else{
		error("Invalid format\n");
	    }
	}
    }
    if(parms->sim.dmclipia){
	/*Clip interactuator stroke*/
	for(int idm=0; idm<parms->ndm; idm++){
	    /* Embed DM commands to a square array (borrow dmrealsq) */
	    double iastroke;
	    int nx=simu->recon->anx->p[idm];
	    double (*dmr)[nx];
	    dmat *dm;
	    if(parms->dm[idm].iastrokescale){ //convert dm to voltage
		dm=dinterp1(parms->dm[idm].iastrokescale->p[0], 0, dmcmd->p[idm], NAN);
		iastroke=parms->dm[idm].iastroke;//voltage.
	    }else{
		dm=dmcmd->p[idm];
		iastroke=parms->dm[idm].iastroke*2;//surface to opd
	    }
	    if(!parms->fit.square){
		loc_embed(simu->dmrealsq->p[idm], simu->recon->aloc->p[idm], dm->p);
		dmr=(double(*)[nx])simu->dmrealsq->p[idm]->p;
	    }else{
		dmr=(double(*)[nx])dm->p;
	    }
	    lcell *actstuck=simu->recon->actstuck;
	    long *stuck=actstuck?(actstuck->p[idm]?actstuck->p[idm]->p:0):0;
	    int count=0,trials=0;
	    do{
		count=0;
		PDMAT(simu->recon->amap->p[idm],map);
		for(int iy=0; iy<simu->recon->any->p[idm]-1; iy++){
		    for(int ix=0; ix<nx; ix++){
			int iact1=map[iy][ix];
			int iact2=map[iy+1][ix];
			if(iact1>0 && iact2>0){
			    count+=limit_diff(&dmr[iy][ix], &dmr[iy+1][ix], iastroke, 
					      stuck?stuck[iact1-1]:0, stuck?stuck[iact2-1]:0);
			}
		    } 
		}
		for(int iy=0; iy<simu->recon->any->p[idm]; iy++){
		    for(int ix=0; ix<nx-1; ix++){
			int iact1=map[iy][ix];
			int iact2=map[iy][ix+1];
			if(iact1>0 && iact2>0){
			    count+=limit_diff(&dmr[iy][ix], &dmr[iy][ix+1], iastroke, 
					      stuck?stuck[iact1-1]:0, stuck?stuck[iact2-1]:0);
			}
		    }
		}
		trials++;
		if(trials==1 && count>0) {
		    info2("Step %d, DM %d: %d actuators over ia limit. ", simu->isim, idm, count);
		}
	    }while(count>0 && trials<100);
	    if(trials>1){
		info2("trials=%d: %s\n", trials, count?"failed.":"success.");
	    }
	    if(!parms->fit.square){//copy data back
		loc_extract(simu->dmreal->p[idm], simu->recon->aloc->p[idm], simu->dmrealsq->p[idm]);
	    }
	    if(parms->dm[idm].iastrokescale){//convert back to opd
		dmat *dm2=dinterp1(parms->dm[idm].iastrokescale->p[1], 0, dm, NAN);
		dcp(&dmcmd->p[idm], dm2);
		dfree(dm); dfree(dm2);
	    }
	}
    }
}