/** The main(). It parses the command line, setup the parms, ask the scheduler for signal to proceed, and then starts skysim to do sky coverage. */ int main(int argc, const char *argv[]){ dirstart=mygetcwd(); char *scmd=argv2str(argc, argv, " "); ARG_S* arg=parse_args(argc,argv); /*In detach mode send to background and disable drawing*/ if(arg->detach){ daemonize(); }else{ redirect(); } info2("%s\n", scmd); info2("Output folder is '%s'. %d threads\n",arg->dirout, arg->nthread); skyc_version(); /*register signal handler */ register_signal_handler(skyc_signal_handler); /* Ask job scheduler for permission to proceed. If no CPUs are available, will block until ones are available. if arg->force==1, will run immediately. */ scheduler_start(scmd,arg->nthread,0,!arg->force); /*setting up parameters before asking scheduler to check for any errors. */ dirsetup=stradd("setup",NULL); PARMS_S * parms=setup_parms(arg); if(parms->skyc.dbg){ mymkdir("%s",dirsetup); } if(!arg->force){ info2("Waiting start signal from the scheduler ...\n"); /*Failed to wait. fall back to own checking.*/ int count=0; while(scheduler_wait()&& count<60){ warning_time("failed to get reply from scheduler. retry\n"); sleep(10); count++; scheduler_start(scmd,arg->nthread,0,!arg->force); } if(count>=60){ warning_time("fall back to own checker\n"); wait_cpu(arg->nthread); } } info2("Simulation started at %s in %s.\n",myasctime(),myhostname()); free(scmd); free(arg->dirout); free(arg); THREAD_POOL_INIT(parms->skyc.nthread); /*Loads the main software*/ OMPTASK_SINGLE skysim(parms); free_parms(parms); free(dirsetup); free(dirstart); rename_file(0); scheduler_finish(0); info2("End:\t%.2f MiB\n",get_job_mem()/1024.); info2("Simulation finished at %s in %s.\n",myasctime(),myhostname()); return 0; }
//respond to scheduler static int respond(int sock){ int cmd[3]; //read fixed length header info. if(streadintarr(sock, cmd, 3)){ return -1;//failed } int ihost=host_from_sock(sock); if(ihost>=0){ htime[ihost]=myclockd(); } int pid=cmd[2]; switch(cmd[0]){ case -1:{//server request shutdown info("disconnect from %s\n", hosts[ihost]); return -1; } break; case MON_VERSION: break; case MON_STATUS: { if(ihost<0){ warning("Host not found\n"); return -1; } PROC_T *p=proc_get(ihost,pid); if(!p){ p=proc_add(ihost,pid); } if(stread(sock, &p->status, sizeof(STATUS_T))){ return -1; } if(p->status.info==S_REMOVE){ proc_remove(ihost, pid); }else{ if(cmd[1]!=ihost && cmd[1]!=cmd[2]){ /*A new mean to replace the ID of a job.*/ p->pid=cmd[1]; } gdk_threads_add_idle((GSourceFunc)refresh, p); } } break; case MON_PATH: { if(ihost<0){ warning("Host not found\n"); return -1; } PROC_T *p=proc_get(ihost,pid); if(!p){ p=proc_add(ihost,pid); } if(streadstr(sock, &p->path)){ return -1; } char *tmp=NULL; while((tmp=strchr(p->path, '\n'))){ tmp[0]=' '; } } break; case MON_LOAD: { if(ihost<0){ warning("Host not found\n"); return -1; } usage_cpu[ihost]=(double)((pid>>16) & 0xFFFF)/100.; usage_mem[ihost]=(double)(pid & 0xFFFF)/100.; usage_cpu[ihost]=MAX(MIN(1,usage_cpu[ihost]),0); usage_mem[ihost]=MAX(MIN(1,usage_mem[ihost]),0); gdk_threads_add_idle((GSourceFunc)update_progress, GINT_TO_POINTER(ihost)); } break; case MON_ADDHOST: if(cmd[1]>-1 && cmd[1]<nhost){ pthread_t tmp; pthread_create(&tmp, NULL, (void*(*)(void*))add_host, GINT_TO_POINTER(cmd[1])); }else if(cmd[1]==-2){ return -2; } break; default: warning_time("Invalid cmd %d\n",cmd[0]); return -1; } return 0; }
/** This is the standard entrance routine to the program. It first calls setup_parms() to setup the simulation parameters and check for possible errors. It then waits for starting signal from the scheduler if in batch mode. Finally it hands the control to maos() to start the actual simulation. Call maos with overriding *.conf files or embed the overriding parameters in the command line to override the default parameters, e.g. <p><code>maos base.conf save.setup=1 'powfs.phystep=[0 100 100]'</code><p> Any duplicate parameters will override the pervious specified value. The configure file nfiraos.conf will be loaded as the master .conf unless a -c switch is used with another .conf file. For scao simulations, call maos with -c switch and the right base .conf file. <p><code>maos -c scao_ngs.conf override.conf</code><p> for scao NGS simulations <p><code>maos -c scao_lgs.conf override.conf</code><p> for scao LGS simulations. With -c switch, nfiraos.conf will not be read, instead scao_ngs.conf or scao_lgs.conf are read as the master config file. Do not specify any parameter that are not understood by the code, otherwise maos will complain and exit to prevent accidental mistakes. Generally you link the maos executable into a folder that is in your PATH evironment or into the folder where you run simulations. Other optional parameters: \verbatim -d do detach from console and not exit when logged out -s 2 -s 4 set seeds to [2 4] -n 4 launch 4 threads. -f To disable job scheduler and force proceed \endverbatim In detached mode, drawing is automatically disabled. \callgraph */ int main(int argc, const char *argv[]){ char *scmd=argv2str(argc,argv," "); ARG_T* arg=parse_args(argc,argv);/*does chdir */ if(arg->detach){ daemonize(); }else{ redirect(); } /*Launch the scheduler if it is not running and report about our process */ int ngpu; #if USE_CUDA ngpu=arg->ngpu; if(!ngpu) ngpu=0xFFFFFF; #else ngpu=0; #endif scheduler_start(scmd,NTHREAD,ngpu,!arg->force); info2("%s\n", scmd); info2("Output folder is '%s'. %d threads\n",arg->dirout, NTHREAD); maos_version(); /*setting up parameters before asking scheduler to check for any errors. */ PARMS_T *parms=setup_parms(arg->conf, arg->confcmd, arg->override); free(arg->conf); arg->conf=0; if(arg->confcmd){ remove(arg->confcmd); free(arg->confcmd); arg->confcmd=0; } info2("After setup_parms:\t %.2f MiB\n",get_job_mem()/1024.); /*register signal handler */ register_signal_handler(maos_signal_handler); if(!arg->force){ /* Ask job scheduler for permission to proceed. If no CPUs are available, will block until ones are available. if arg->force==1, will run immediately. */ info2("Waiting start signal from the scheduler ...\n"); int count=0; while(scheduler_wait()&& count<60){ /*Failed to wait. fall back to own checking.*/ warning_time("failed to get reply from scheduler. retry\n"); sleep(10); count++; scheduler_start(scmd,NTHREAD,ngpu,!arg->force); } if(count>=60){ warning_time("fall back to own checker\n"); wait_cpu(NTHREAD); } } thread_new((thread_fun)scheduler_listen, maos_daemon); setup_parms_gpu(parms, arg->gpus, arg->ngpu); if(arg->server){ while(maos_server_fd<0){ warning("Waiting for fd\n"); sleep(1); } maos_server(parms); EXIT; } free(scmd); free(arg->dirout); free(arg->gpus); free(arg); /*do not use prallel single in maos(). It causes blas to run single threaded * during preparation. Selective enable parallel for certain setup functions * that doesn't use blas*/ maos(parms); rename_file(0); scheduler_finish(0); return 0; }