GPU支持¶
本节介绍构建TomoPy以及对GPU卸载和常规用法的支持。对于实现的迭代算法,根据可用的硬件,每个切片的重建时间可以减少几个数量级。在NERSC的NVIDIA Volta(VX-100)图形处理器上,对于具有1501个投影角和100次迭代的2048P图像,SIRT和MLEM算法的每层重建时间从~6.5小时减少到~40秒。
支持的GPU¶
TomoPy支持在Linux和Windows 10上通过编译的CUDA内核将负载分流到NVIDIA GPU。在MacOS上的NVIDIA GPU未经测试,但可能受支持。
用CUDA构建TomoPy¶
CMake配置为在CMake可以检测到有效的CUDA编译器时自动启用构建GPU支持。TomoPy需要CMake3.9+,它支持将CUDA作为一流语言--这意味着CUDA编译器只需要在 PATH
。在Unix上,可以使用以下命令轻松检查这一点: which nvcc
。如果该命令返回到编译器的路径,则正常构建TomoPy。如果没有,请找到CUDA编译器,并将编译器的路径放在 PATH
,删除构建目录 (rm -r _skbuild
或 python setup.py clean
)和重建。
TomoPy包括 Parallel Tasking Library (PTL) 作为Git子模块来处理辅助线程池的创建,该辅助线程池帮助隐藏CPU和GPU之间的通信延迟。此子模块由CMake构建系统自动签出和编译。
使用GPU卸载进行重建¶
为了在GPU上实现高效的重建,该算法被实现为基于旋转的重建,而不是标准的基于光线的重建。算法改变的主要含义是,当图像的角点处有重要像素时,在重建之前必须填充图像。这是由于以不是90度系数的任意角度旋转的副作用:
obj = tomopy.shepp2d()
obj = tomopy.misc.morph.pad(obj, axis=1, mode='constant')
obj = tomopy.misc.morph.pad(obj, axis=2, mode='constant')
目前支持的GPU减负算法有:
算法 |
---|
SIRT |
MLEM |
当由于缺乏编译器支持或没有可用的CUDA设备而导致GPU支持不可用时,算法将使用与使用OpenCV的GPU版本相同的算法在CPU上执行。当NVIDIA设备成为目标设备时,算法使用NPP(NVIDIA Performance Primitions)库,而不是有限的GPU支持的OpenCV。但是,如果OpenCV配置了GPU支持,则仍有可能发生GPU减负。
增加了 accelerated=True
至 tomopy.recon(...)
是启用上述算法加速版本的唯一要求。但是,还有一项额外定制支持:
|
类型 |
描述 |
选项 |
---|---|---|---|
|
布尔型 |
启用加速算法 |
对,错 |
|
集成 |
辅助线程池的大小 |
|
|
细绳 |
插补方案 |
“NN”、“线性”、“立方” |
|
细绳 |
目标设备 |
“CPU”、“GPU” |
|
不伦不类 |
GPU网格尺寸 |
设置为 |
|
不伦不类 |
GPU块尺寸 |
缺省值为 |
多线程¶
TomoPy支持在Python级通过 ncore
参数。当卸载到GPU时,通常建议设置 ncore
增加到GPU的数量。当在Python级别启动的线程下拉到TomoPy的编译代码时,这些线程递增一个计数器,该计数器将它们的执行分散到所有可用的GPU上
// thread counter for device assignment
static std::atomic<int> ntid;
// increment counter and get a "Python thread-id"
int pythread_num = ntid++;
// set the device to the modulus of number of device available
int device = pythread_num % cuda_device_count();
如前所述,TomoPy在加速算法中创建了一个辅助线程池,帮助隐藏CPU和GPU之间的通信延迟。一旦为线程分配了设备,它就会创建 pool_size
用于此目的的其他线程。当将负载转移到GPU时,标准建议是超额订阅相对于硬件核心数量的线程数量。每个GPU的理想线程数约为12-24个线程。的默认数量 pool_size
线程数是可用硬件线程数除以在Python级启动的线程数的两倍,例如,如果有8个CPU核心和1个在Python级启动的线程,则将在辅助线程池中创建16个线程。