From f2d3bc49b62740f822bebd0f345b29c5681b0e57 Mon Sep 17 00:00:00 2001 From: Qianqian Fang Date: Fri, 8 Nov 2024 00:56:17 -0500 Subject: [PATCH] [feat] support 1x1x1 volume, add onecube/twocube benchmarks, det not working --- src/mcx_bench.c | 110 +++++++++++++++++++++++++++++++++++++++++++++++- src/mcx_bench.h | 2 +- src/mcx_core.cu | 15 +++++-- src/mcx_utils.h | 2 +- src/mcxlab.cpp | 9 +++- 5 files changed, 130 insertions(+), 8 deletions(-) diff --git a/src/mcx_bench.c b/src/mcx_bench.c index ff2cf587..9969389b 100644 --- a/src/mcx_bench.c +++ b/src/mcx_bench.c @@ -36,7 +36,7 @@ #define MSTR(...) #__VA_ARGS__ -const char *benchname[MAX_MCX_BENCH]={"cube60","cube60b","cube60planar","cubesph60b","skinvessel","sphshells","spherebox", +const char *benchname[MAX_MCX_BENCH]={"cube60","cube60b","cube60planar","cubesph60b","onecube","twocube","skinvessel","sphshells","spherebox", #ifndef _MSC_VER "colin27",""}; #else @@ -266,6 +266,114 @@ MSTR( }), +MSTR( +{ + "Session":{ + "ID":"onecube", + "DoSaveVolume":0, + "DoAutoThread":1, + "SaveDataMask":"xv", + "Photons":1000000 + }, + "Forward":{ + "T0":0, + "T1":5e-09, + "Dt":5e-09 + }, + "Optode":{ + "Source":{ + "Pos":[0.5,0.5,0], + "Dir":[0,0,1] + }, + "Detector":[ + { + "Pos":[0.5,0.45,1], + "R":0.016667 + } + ] + }, + "Domain":{ + "OriginType":1, + "LengthUnit":60, + "Media":[ + { + "mua":0, + "mus":0, + "g":1, + "n":1 + }, + { + "mua":0.005, + "mus":1, + "g":0, + "n":1.37 + } + ], + "MediaFormat":"byte", + "Dim":[1,1,1] + }, + "Shapes": { + "_ArraySize_": [1,1,1], + "_ArrayType_": "uint8", + "_ArrayData_": [1] + } +}), + + +MSTR( +{ + "Session":{ + "ID":"twocube", + "DoSaveVolume":0, + "DoAutoThread":1, + "SaveDataMask":"xv", + "Photons":1000000 + }, + "Forward":{ + "T0":0, + "T1":5e-09, + "Dt":5e-09 + }, + "Optode":{ + "Source":{ + "Pos":[1,1,0], + "Dir":[0,0,1] + }, + "Detector":[ + { + "Pos":[1,0.9,1], + "R":0.0333333 + } + ] + }, + "Domain":{ + "OriginType":1, + "LengthUnit":30, + "Media":[ + { + "mua":0, + "mus":0, + "g":1, + "n":1 + }, + { + "mua":0.005, + "mus":1, + "g":0, + "n":1.37 + } + ], + "MediaFormat":"byte", + "Dim":[2,2,2] + }, + "Shapes": { + "_ArraySize_": [2,2,2], + "_ArrayType_": "uint8", + "_ArrayData_": [1,1,1,1,1,1,1,1] + } +}), + + MSTR( { "Session": { diff --git a/src/mcx_bench.h b/src/mcx_bench.h index 04397afc..88c8714b 100644 --- a/src/mcx_bench.h +++ b/src/mcx_bench.h @@ -35,7 +35,7 @@ #ifndef _MCEXTREME_BENCHMARK_H #define _MCEXTREME_BENCHMARK_H -#define MAX_MCX_BENCH 9 /**< Total number of built-in benchmarks */ +#define MAX_MCX_BENCH 11 /**< Total number of built-in benchmarks */ extern const char* benchname[MAX_MCX_BENCH]; /**< String list defining the names of each built-in benchmark */ extern const char* benchjson[MAX_MCX_BENCH]; /**< JSON-formatted input configuration for each built-in benchmark */ diff --git a/src/mcx_core.cu b/src/mcx_core.cu index bab29f98..1e126276 100644 --- a/src/mcx_core.cu +++ b/src/mcx_core.cu @@ -2678,7 +2678,8 @@ void mcx_run_simulation(Config* cfg, GPUInfo* gpu) { float4 s0 = (float4)cfg->srciquv; float3 maxidx = float3(cfg->dim.x, cfg->dim.y, cfg->dim.z); - int timegate = 0, totalgates, gpuid, threadid = 0; + uint timegate = 0, totalgates, threadid = 0; + int gpuid; /** \c gpuphoton - number of photons to be simulated per thread, determined by total workload and thread number */ size_t gpuphoton = 0; @@ -2792,6 +2793,14 @@ void mcx_run_simulation(Config* cfg, GPUInfo* gpu) { param.skipradius2 = 0.f; } + if (is2d) { + /** + * is2d is only turn 1 if only 1 of the 3 dimension has a length of 1; if 2x or 3x of the dimension have a length of 1, use 3D mode + */ + is2d = is2d * ((cfg->dim.x > 1) + (cfg->dim.y > 1) + (cfg->dim.z > 1) == 2); + param.is2d = is2d; + } + /** Start multiple CPU threads using OpenMP, one thread for each GPU device to run simultaneously, \c threadid returns the current thread ID */ #ifdef _OPENMP threadid = omp_get_thread_num(); @@ -2944,7 +2953,7 @@ void mcx_run_simulation(Config* cfg, GPUInfo* gpu) { /** Here we determine if the GPU memory of the current device can store all time gates, if not, disabling normalization */ if (totalgates > gpu[gpuid].maxgate && cfg->isnormalized) { - MCX_FPRINTF(cfg->flog, S_RED "WARNING: GPU memory can not hold all time gates, disabling normalization to allow multiple runs\n" S_RESET); + MCX_FPRINTF(cfg->flog, S_RED "WARNING: %d %d %d [%d %d %d] GPU memory can not hold all time gates, disabling normalization to allow multiple runs\n" S_RESET, totalgates, gpu[gpuid].maxgate, cfg->isnormalized, cfg->dim.x, cfg->dim.y, cfg->dim.z); cfg->isnormalized = 0; } @@ -3706,7 +3715,7 @@ is more than what your have specified (%d), please use the -H option to specify } else { int j; - for (iter = 0; iter < gpu[gpuid].maxgate; iter++) + for (iter = 0; iter < (int)gpu[gpuid].maxgate; iter++) for (j = 0; j < (int)dimlen.z; j++) { mcx_kahanSum(&energyabs[i], &kahanc, cfg->exportfield[iter * dimxyz + (j * cfg->srcnum + i)]*mcx_updatemua((uint)cfg->vol[j], cfg)); } diff --git a/src/mcx_utils.h b/src/mcx_utils.h index b4950e25..3411a6dd 100644 --- a/src/mcx_utils.h +++ b/src/mcx_utils.h @@ -160,7 +160,7 @@ typedef struct MCXGPUInfo { int core; /**< number of stream processors */ int autoblock; /**< optimized number of blocks to launch */ int autothread; /**< optimized number of threads to launch */ - int maxgate; /**< max number of time gates that can be saved in one call */ + unsigned int maxgate; /**< max number of time gates that can be saved in one call */ int maxmpthread; /**< maximum thread number per multi-processor */ } GPUInfo; diff --git a/src/mcxlab.cpp b/src/mcxlab.cpp index 24297b27..316b41bf 100644 --- a/src/mcxlab.cpp +++ b/src/mcxlab.cpp @@ -737,7 +737,7 @@ void mcx_set_field(const mxArray* root, const mxArray* item, int idx, Config* cf cfg->mediabyte = 0; arraydim = mxGetDimensions(item); - if (mxGetNumberOfDimensions(item) == 3) { + if (mxGetNumberOfDimensions(item) <= 3) { if (mxIsUint8(item) || mxIsInt8(item)) { // input is a 3D byte array cfg->mediabyte = 1; } else if (mxIsUint16(item) || mxIsInt16(item)) { // input is a 3D short array @@ -750,9 +750,14 @@ void mcx_set_field(const mxArray* root, const mxArray* item, int idx, Config* cf cfg->mediabyte = 14; } - for (i = 0; i < 3; i++) { + for (i = 0; i < mxGetNumberOfDimensions(item); i++) { ((unsigned int*)(&cfg->dim))[i] = arraydim[i]; } + + if (i < 3) { + cfg->dim.z = 1; + } + } else if (mxGetNumberOfDimensions(item) == 4) { // if dimension is 4D, 1st dim is the property records: mua/mus/g/n if ((mxIsUint8(item) || mxIsInt8(item)) && arraydim[0] == 4) { // if 4D byte array has a 1st dim of 4 cfg->mediabyte = MEDIA_ASGN_BYTE;