Python并行处理#
Python 中的concurrent包提供了对于并行运行的接口,包括进程级并行和线程级并行。下面是一个例子。
from concurrent.futures import ProcessPoolExecutor, ThreadPoolExecutor
def func(a, b):
return a*b
if __name__ == '__main__':
n_core = 4
nums = 10000
b = 2
res = [0 for _ in range(nums)]
with ProcessPoolExecutor(n_core) as pool:
futures = {pool.submit(func, i, b): i for i in range(1, nums)}
for f in futures:
res[futures[f]] = f.result()
res = [0 for _ in range(nums)]
with ThreadPoolExecutor(n_core) as pool:
futures = {pool.submit(func, i, b): i for i in range(1, nums)}
for f in futures:
res[futures[f]] = f.result()在并行处理时,写明 if __name__ == '__main__' 以声明主进程。
进程级并行时,各个并行进程之间独享计算资源(尤其是内存)。对于这个例子,就是会为每个进程拷贝一个 b 。这样的好处是进程之间基本不会相互影响,对于I/O型任务的效率提升较大;而缺点是会增加内存的消耗。
对于线程级并行,并行线程之间可以共享变量,因此相比起进程级别的并行,消耗的内存会更少。
上面的线程和进程相关的描述是笔者久远的记忆加上自己的理解,可能不准确,但代码可用。
futures[f] 会返回 {pool.submit(func, i, b): i for i in range(1, nums)} 里面的 i。
R并行处理#
R 里面的 snowfall 包提供了并行的接口。
library(snowfall)
parallel <- function(x, y) {
sfCat(print(x))
return(x * y)
}
b <- 2
sfInit(parallel = TRUE, cpus = 4, slaveOutfile = 'demo.log')
sfLibrary(snowfall)
sfExport('b')
res <- sfSapply(1:5, parallel, b)
sfStop()sfInit 用于设置基础环境,其中 slaveOutfile 用来重定向并行中的输出信息,方便检测进度。
sfLibrary 函数导入并行函数需要的包。
sfExport 函数将外部变量和函数导入并行函数。
sfSapply 类似 R 中其他的*apply函数族,返回值类似。
sfCat 函数将并行过程中的信息输出。如果在 slaveOutfile 中设置了,输出信息将保存到相应的文件中。
annot文件#
FreeSurfer 中的函数可以将 .annot 文件转换为 .gii 文件,命令如下。
mris_convert --annot lh.aparc.annot lh.white lh.aparc.giiggplot2中自定义字体#
library(showtext)
font.add('calibri', 'xxx.ttf')
showtext.auto()
ggplot() ...showtext 包可以载入外部字体。利用 font.add 函数,载入字体文件。showtext.auto 函数可以在后面的绘图中自动使用载入的字体。
