Skip to content

如何修改MCX原版code

[time=Sat, Jan 29, 2022 11:11 PM] [name=dicky1031] [TOC]

1. 初始設定

原始程式碼連結 我修改的部分從branch-master clone而來 修改資料夾 MCX/src (原版MCX C code都會在這裏面)

2. 原始code功能說明

判斷哪個detector偵測到: mcx_core.cu : finddetector 使用出光光子與detector XYZ距離的平方合,看是否在detector半徑以內

mcx_core.cu : mcx_main_loop 是MC的主要loop 他真的是在每個while loop裡面一個一個voxel移動

random出一個unitless PL後 走一個voxel花的距離要乘上mus才是他花掉的PL

不過他裡面有計算mua衰減的code mcx_core.cu : line 1255~1259

finddetector會被savedetphoton呼叫到,用來決定要儲存在哪個detector 而savedetphoton會在每次launchnewphoton時被呼叫到,把上一顆光子的資訊存起來 launchnewphoton則會在mcx_main_loop裡面的開始新光子、光子跑出組織外、輪盤玩輸之後被呼叫到 看起來頗合理 因此應該不會有上次懷疑的,detector太大(超出一個voxel)導致收到的光子不對的狀況

mcx_main_loop之中 launchnewphoton在一開始、玩輪盤,或是time window超過、光子從non-zero voxel跑到zero voxel時會被呼叫

launchnewphoton: 結束目前的光子,並且開始新的光子 如果mediaid(the medium index at the voxel at launch)==0且isdet(前一顆光子打到了detector)的話,裡面會呼叫到savedetphoton,才會把偵測到個光子存起來

transmit會在檢查光子是否跑到zero voxel前被呼叫,而transmit會改變方向,所以輸出的光子方向應該是已經跑到外面的方向

3. Make mex

3.1 編譯mex檔案

mex為matlab執行C語法的執行檔案,所以當修改完原始版C語言的程式碼後,需要再將其編譯成matlab可以執行的mex檔案 具體使用方式: 打開終端機(terminal)

cd ~/mcx-master/src
cmake ~/mcx-master/src
make

之後如果都沒報錯,編譯好的mex檔案將會在mcx-master/bin裡面


3.2 如果遇到錯誤的解決方案

3.2.1 GPU環境不相容

nvcc fatal   : Value 'sm_30' is not defined for option 'gpu-architecture'

如果看到此錯誤(注意錯誤可能為sm_為任意數字代表不同版本),代表gpu環境編譯時發生不相容的情況,此時請點此連結查看本機端電腦的gpu規格。


ex:假如GPU為RTX2080,則表示此架構為Turing (CUDA 10 and later)適用sm_75版本。 因此需要將~/mcx-master/src這個路徑下的cmakelist.txt做修改。

# NVCC Options
set(
    CUDA_NVCC_FLAGS
    ${CUDA_NVCC_FLAGS};
    -g -lineinfo -Xcompiler -Wall -Xcompiler -fopenmp -O3 -arch=sm_30
    -DMCX_TARGET_NAME="fermi  MCX" -DUSE_ATOMIC -use_fast_math
    -DSAVE_DETECTORS -Xcompiler -fPIC
    )

將上述程式碼中的 sm_30 修改為 sm_75, -DMCX_TARGET_NAME="fermi MCX" --> -DMCX_TARGET_NAME="Turing MCX"

3.2.2 ZLIB錯誤

Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR)

如果看到上述錯誤則代表需安裝ZLIB,執行以下程式碼即可

sudo apt-get install zlib1g-dev

Config structure 在 mcx_utils.h 259行 mcx_run_simulation 在 mcx_core.cu 2236行 mcxlab.cpp 257行 launchnewphoton 在 mcx_core.cu 1026行

ifndef#define#endif的用法(整理)

https://huenlil.pixnet.net/blog/post/24339151

__device__ inline uint finddetector(MCXpos *p0){
      uint i;
      for(i=gcfg->maxmedia+1;i<gcfg->maxmedia+gcfg->detnum+1;i++){
        if((gproperty[i].x-p0->x)*(gproperty[i].x-p0->x)+
       (gproperty[i].y-p0->y)*(gproperty[i].y-p0->y)+
       (gproperty[i].z-p0->z)*(gproperty[i].z-p0->z) < gproperty[i].w*gproperty[i].w){
            return i-gcfg->maxmedia;
       }
      }
      return 0;
}

在 core.cu 的2764行 /* Copy param to the constant memory variable gcfg / 把 cfg的data複製到 gcfg(在GPU上)

__host__ ​cudaError_t cudaMemcpyToSymbol ( const void* symbol, const void* src, size_t count, size_t offset = 0, cudaMemcpyKind kind = cudaMemcpyHostToDevice )

Copies data to the given symbol on the device.

Parameters
symbol
- Device symbol address
src
- Source memory address
count
- Size in bytes to copy
offset
- Offset from start of symbol in bytes
kind
- Type of transfer

2348行

MCXParam param={cfg->steps,minstep,0,0,cfg->tend,R_C0*cfg->unitinmm,
                     (uint)cfg->issave2pt,(uint)cfg->isreflect,(uint)cfg->isrefint,(uint)cfg->issavedet,1.f/cfg->tstep,
             p0,c0,s0,maxidx,uint4(0,0,0,0),cp0,cp1,uint2(0,0),cfg->minenergy,
                     cfg->sradius*cfg->sradius,minstep*R_C0*cfg->unitinmm,cfg->srctype,
             cfg->srcparam1,cfg->srcparam2,cfg->voidtime,cfg->maxdetphoton,
             cfg->medianum-1,cfg->detnum,cfg->polmedianum,cfg->maxgate,0,0,ABS(cfg->sradius+2.f)<EPS /*isatomic*/,
             (uint)cfg->maxvoidstep,cfg->issaveseed>0,(uint)cfg->issaveref,cfg->isspecular>0,
             cfg->maxdetphoton*hostdetreclen,cfg->seed,(uint)cfg->outputtype,0,0,cfg->faststep,
             cfg->debuglevel,cfg->savedetflag,hostdetreclen,partialdata,w0offset,cfg->mediabyte,
             (uint)cfg->maxjumpdebug,cfg->gscatter,is2d,cfg->replaydet,cfg->srcnum,cfg->nphase,cfg->omega};

param initial時沒有宣告bc 之後才宣告bc如下

2677行

memcpy(&(param.bc),cfg->bc,12);

開始修改 在MCX_utils.h的259行 Config{}增加 float detreflect之屬性;

matlab structure to cJson https://github.com/fangq/mcx/tree/master/src/cjson

mcx_loadjson