Beispiel #1
0
int main (int argc, char *argv[]) {
     /*! structure to store all simulation parameters 
      */
     Config  mcxconfig;            /** mcxconfig: structure to store all simulation parameters */
     GPUInfo *gpuinfo=NULL;        /** gpuinfo: structure to store GPU information */
     unsigned int activedev=0;     /** activedev: count of total active GPUs to be used */

     /** 
        To start an MCX simulation, we first create a simulation configuration and
	set all elements to its default settings.
      */
     mcx_initcfg(&mcxconfig);

     /** 
        Then, we parse the full command line parameters and set user specified settings
      */
     mcx_parsecmd(argc,argv,&mcxconfig);

     /** The next step, we identify gpu number and query all GPU info */
     if(!(activedev=mcx_list_gpu(&mcxconfig,&gpuinfo))){
         mcx_error(-1,"No GPU device found\n",__FILE__,__LINE__);
     }

#ifdef _OPENMP
     /** 
        Now we are ready to launch one thread for each involked GPU to run the simulation 
      */
     omp_set_num_threads(activedev);
     #pragma omp parallel
     {
#endif

     /** 
        This line runs the main MCX simulation for each GPU inside each thread 
      */
     mcx_run_simulation(&mcxconfig,gpuinfo); 

#ifdef _OPENMP
     }
#endif

     /** 
        Once simulation is complete, we clean up the allocated memory in config and gpuinfo, and exit 
      */
     mcx_cleargpuinfo(&gpuinfo);
     mcx_clearcfg(&mcxconfig);
     return 0;
}
Beispiel #2
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
  Config cfg;
  GPUInfo *gpuinfo=NULL;
  mxArray    *tmp;
  int        ifield, jstruct;
  int        ncfg, nfields;
  int        fielddim[4];
  int        activedev=0;
  int        errorflag=0;
  int        threadid=0;
  const char       *outputtag[]={"data"};
  const char       *datastruct[]={"data","stat"};
  const char       *statstruct[]={"runtime","nphoton","energytot","energyabs","normalizer","workload"};
  const char       *gpuinfotag[]={"name","id","devcount","major","minor","globalmem",
                                  "constmem","sharedmem","regcount","clock","sm","core",
                                  "autoblock","autothread","maxgate"};

  if (nrhs==0){
     mcxlab_usage();
     return;
  }
  if(nrhs==1 && mxIsChar(prhs[0])){
        char shortcmd[MAX_SESSION_LENGTH];
        mxGetString(prhs[0], shortcmd, MAX_SESSION_LENGTH);
        shortcmd[MAX_SESSION_LENGTH-1]='\0';
        if(strcmp(shortcmd,"gpuinfo")==0){
            mcx_initcfg(&cfg);
            cfg.isgpuinfo=3;
            if(!(activedev=mcx_list_gpu(&cfg,&gpuinfo))){
                mexWarnMsgTxt("no active GPU device found");
            }
            plhs[0] = mxCreateStructMatrix(gpuinfo[0].devcount,1,15,gpuinfotag);
            for(int i=0;i<gpuinfo[0].devcount;i++){
		mxSetField(plhs[0],i,"name",mxCreateString(gpuinfo[i].name));
		SET_GPU_INFO(plhs[0],i,id);
		SET_GPU_INFO(plhs[0],i,devcount);
		SET_GPU_INFO(plhs[0],i,major);
		SET_GPU_INFO(plhs[0],i,minor);
		SET_GPU_INFO(plhs[0],i,globalmem);
		SET_GPU_INFO(plhs[0],i,constmem);
		SET_GPU_INFO(plhs[0],i,sharedmem);
		SET_GPU_INFO(plhs[0],i,regcount);
		SET_GPU_INFO(plhs[0],i,clock);
		SET_GPU_INFO(plhs[0],i,sm);
		SET_GPU_INFO(plhs[0],i,core);
		SET_GPU_INFO(plhs[0],i,autoblock);
		SET_GPU_INFO(plhs[0],i,autothread);
		SET_GPU_INFO(plhs[0],i,maxgate);
            }
            mcx_cleargpuinfo(&gpuinfo);
            mcx_clearcfg(&cfg);
	}
	return;
  }
  printf("Launching MCXLAB - Monte Carlo eXtreme for MATLAB & GNU Octave ...\n");
  if (!mxIsStruct(prhs[0]))
     mexErrMsgTxt("Input must be a structure.");

  nfields = mxGetNumberOfFields(prhs[0]);
  ncfg = mxGetNumberOfElements(prhs[0]);

  if(nlhs>=1)
      plhs[0] = mxCreateStructMatrix(ncfg,1,2,datastruct);
  if(nlhs>=2)
      plhs[1] = mxCreateStructMatrix(ncfg,1,1,outputtag);
  if(nlhs>=3)
      plhs[2] = mxCreateStructMatrix(ncfg,1,1,outputtag);
  if(nlhs>=4)
      plhs[3] = mxCreateStructMatrix(ncfg,1,1,outputtag);
  if(nlhs>=5)
      plhs[4] = mxCreateStructMatrix(ncfg,1,1,outputtag);

  for (jstruct = 0; jstruct < ncfg; jstruct++) {  /* how many configs */
    try{
	printf("Running simulations for configuration #%d ...\n", jstruct+1);

	mcx_initcfg(&cfg);

	for (ifield = 0; ifield < nfields; ifield++) { /* how many input struct fields */
            tmp = mxGetFieldByNumber(prhs[0], jstruct, ifield);
	    if (tmp == NULL) {
		    continue;
	    }
	    mcx_set_field(prhs[0],tmp,ifield,&cfg);
	}
#ifndef MATLAB_MEX_FILE
        mexEvalString("fflush(stdout);");
#else
	mexEvalString("drawnow;");
#endif
	cfg.issave2pt=(nlhs>=1);
	cfg.issavedet=(nlhs>=2);
	cfg.issaveseed=(nlhs>=4);
#if defined(USE_MT_RAND)
        cfg.issaveseed=0;
#endif
	if(cfg.vol==NULL || cfg.medianum==0){
	    mexErrMsgTxt("You must define 'vol' and 'prop' field.");
	}
	if(!(activedev=mcx_list_gpu(&cfg,&gpuinfo))){
            mexErrMsgTxt("No active GPU device found");
	}
	if(nlhs>=1){
            int fieldlen=cfg.dim.x*cfg.dim.y*cfg.dim.z*(int)((cfg.tend-cfg.tstart)/cfg.tstep+0.5);
	    cfg.exportfield = (float*)calloc(fieldlen,sizeof(float));
	}
	if(nlhs>=2){
	    cfg.exportdetected=(float*)malloc((cfg.medianum+1)*cfg.maxdetphoton*sizeof(float));
        }
        if(nlhs>=4){
	    cfg.seeddata=malloc(cfg.maxdetphoton*sizeof(float)*RAND_BUF_LEN);
	}
        if(nlhs>=5){
	    cfg.exportdebugdata=(float*)malloc(cfg.maxjumpdebug*sizeof(float)*MCX_DEBUG_REC_LEN);
	}
        mcx_validate_config(&cfg);
#ifdef _OPENMP
        omp_set_num_threads(activedev);
#pragma omp parallel shared(errorflag)
{
        threadid=omp_get_thread_num();
#endif
        try{

            mcx_run_simulation(&cfg,gpuinfo);

        }catch(const char *err){
	    mexPrintf("Error from thread (%d): %s\n",threadid,err);
	    errorflag++;
	}catch(const std::exception &err){
	    mexPrintf("C++ Error from thread (%d): %s\n",threadid,err.what());
	    errorflag++;
	}catch(...){
	    mexPrintf("Unknown Exception from thread (%d)",threadid);
	    errorflag++;
	}
#ifdef _OPENMP
}
#endif

        if(errorflag)
            mexErrMsgTxt("MCXLAB Terminated due to an exception!");

        if(nlhs>=5){
            fielddim[0]=MCX_DEBUG_REC_LEN; fielddim[1]=cfg.debugdatalen; // his.savedphoton is for one repetition, should correct
    	    fielddim[2]=0; fielddim[3]=0;
            mxSetFieldByNumber(plhs[4],jstruct,0, mxCreateNumericArray(2,fielddim,mxSINGLE_CLASS,mxREAL));
	    if(cfg.debuglevel & MCX_DEBUG_MOVE)
                memcpy((float*)mxGetPr(mxGetFieldByNumber(plhs[4],jstruct,0)),cfg.exportdebugdata,fielddim[0]*fielddim[1]*sizeof(float));
	    if(cfg.exportdebugdata)
	        free(cfg.exportdebugdata);
            cfg.exportdebugdata=NULL;
	}
        if(nlhs>=4){
            fielddim[0]=(cfg.issaveseed>0)*RAND_BUF_LEN*sizeof(float); fielddim[1]=cfg.detectedcount; // his.savedphoton is for one repetition, should correct
    	    fielddim[2]=0; fielddim[3]=0;
		    mxSetFieldByNumber(plhs[3],jstruct,0, mxCreateNumericArray(2,fielddim,mxUINT8_CLASS,mxREAL));
		    memcpy((unsigned char*)mxGetPr(mxGetFieldByNumber(plhs[3],jstruct,0)),cfg.seeddata,fielddim[0]*fielddim[1]);
	    free(cfg.seeddata);
            cfg.seeddata=NULL;
	}
	if(nlhs>=3){
            fielddim[0]=cfg.dim.x; fielddim[1]=cfg.dim.y;
            fielddim[2]=cfg.dim.z; fielddim[3]=0;
            if(cfg.vol){
                    mxSetFieldByNumber(plhs[2],jstruct,0, mxCreateNumericArray(3,fielddim,mxUINT8_CLASS,mxREAL));
                    memcpy((unsigned char*)mxGetPr(mxGetFieldByNumber(plhs[2],jstruct,0)),cfg.vol,
                	 fielddim[0]*fielddim[1]*fielddim[2]*sizeof(unsigned char));
            }
	}
	if(nlhs>=2){
            fielddim[0]=(cfg.medianum+1); fielddim[1]=cfg.detectedcount; 
            fielddim[2]=0; fielddim[3]=0;
            if(cfg.detectedcount>0){
                    mxSetFieldByNumber(plhs[1],jstruct,0, mxCreateNumericArray(2,fielddim,mxSINGLE_CLASS,mxREAL));
                    memcpy((float*)mxGetPr(mxGetFieldByNumber(plhs[1],jstruct,0)),cfg.exportdetected,
                         fielddim[0]*fielddim[1]*sizeof(float));
            }
            free(cfg.exportdetected);
            cfg.exportdetected=NULL;
	}
        if(nlhs>=1){
            fielddim[0]=cfg.dim.x; fielddim[1]=cfg.dim.y; 
	    fielddim[2]=cfg.dim.z; fielddim[3]=(int)((cfg.tend-cfg.tstart)/cfg.tstep+0.5);
	    mxSetFieldByNumber(plhs[0],jstruct,0, mxCreateNumericArray(4,fielddim,mxSINGLE_CLASS,mxREAL));
            memcpy((float*)mxGetPr(mxGetFieldByNumber(plhs[0],jstruct,0)),cfg.exportfield,
                         fielddim[0]*fielddim[1]*fielddim[2]*fielddim[3]*sizeof(float));
            free(cfg.exportfield);
            cfg.exportfield=NULL;

            mxArray *stat=mxCreateStructMatrix(1,1,6,statstruct);
            mxArray *val = mxCreateDoubleMatrix(1,1,mxREAL);
            *mxGetPr(val) = cfg.runtime;
            mxSetFieldByNumber(stat,0,0, val);

            val = mxCreateDoubleMatrix(1,1,mxREAL);
            *mxGetPr(val) = cfg.nphoton;
            mxSetFieldByNumber(stat,0,1, val);

            val = mxCreateDoubleMatrix(1,1,mxREAL);
            *mxGetPr(val) = cfg.energytot;
            mxSetFieldByNumber(stat,0,2, val);

            val = mxCreateDoubleMatrix(1,1,mxREAL);
            *mxGetPr(val) = cfg.energyabs;
            mxSetFieldByNumber(stat,0,3, val);

            val = mxCreateDoubleMatrix(1,1,mxREAL);
            *mxGetPr(val) = cfg.normalizer;
            mxSetFieldByNumber(stat,0,4, val);

            val = mxCreateDoubleMatrix(1,activedev,mxREAL);
	    for(int i=0;i<activedev;i++)
                *(mxGetPr(val)+i) = cfg.workload[i];
            mxSetFieldByNumber(stat,0,5, val);

	    mxSetFieldByNumber(plhs[0],jstruct,1, stat);
        }
    }catch(const char *err){
      mexPrintf("Error: %s\n",err);
    }catch(const std::exception &err){
      mexPrintf("C++ Error: %s\n",err.what());
    }catch(...){
      mexPrintf("Unknown Exception");
    }

    if(detps)
       free(detps);
    mcx_cleargpuinfo(&gpuinfo);
    mcx_clearcfg(&cfg);
  }
  return;
}