2016-07-01 98 views
0

对于10^6遗传因子及其GeneXGene相互作用(〜5x10^11)的分析,我有许多独立的线性回归问题,这些问题可能适用于GPU分析。使用CUDA实现大型线性回归模型

目标是使用包含交互项的线性回归在调节结果变量(脑表型)中详尽搜索GeneXGene相互作用效应。

据我所知,Householder QR因子分解可能是拟合回归模型的解决方案,但是,考虑到这个特定工作中的每个回归矩阵都可以很容易地接近〜10'000x10的大小,即使是每个回归矩阵似乎不适合GPU片上存储器(共享,寄存器等)。

我是否应该接受这个问题,它本质上是带宽限制的,并且在回归分析期间将矩阵保留在GPU全局内存中,或者是否有其他策略可行?

EDIT 下面是有关该问题的更多细节:

将有大约10'000受试者,每个〜1M遗传参数(遗传矩阵:10'000x10^6)。每次迭代的算法应该选择这个遗传矩阵的两列(10'000x2),还有其他6个与遗传数据无关的其他变量(年龄,性别等),所以最终的回归模型将处理一个矩阵,如大小为10 '000x [2(遗传因子)+6(协变量)+2(截距&相互作用项)]和结果变量向量(10'000x1)。对于给定的一对遗传因子,每次重复这一过程~5e11次。那些通过预定义统计阈值的模型应该保存为输出。

具体的问题是,虽然有〜5e11单独的回归模型,即使单个回归模型似乎不适合片上存储器。

我也猜测,坚持使用CUDA库可能不是这里的解决方案,因为这要求大部分数据操作发生在CPU端,并且只发送每个QR分解到GPU?

+1

先走高层。尽量减少你的问题到常见的线性代数例程,并使用[CUDA库](https://developer.nvidia.com/gpu-accelerated-libraries)(其中有很多:例如cuBLAS和cuSolver可能已经有你需要的)。推迟发明你自己的东西,并担心带宽,直到你真的需要这个。 – Drop

+0

为什么问题的大小从10^12突然变为10000 * 10? – kangshiyin

+0

@Drop谢谢。但考虑到将会有10^12个独立的回归模型,这是否有效? – Sourena

回答

1

整个数据矩阵(1e4 x 1e6)可能太大而不适合全局内存,而每个最小二乘求解(1e4 x 10)可能太小而不能充分利用GPU。


对于每个最小二乘问题,您可以使用cuSolver进行QR分解和三角求解。

http://docs.nvidia.com/cuda/cusolver/index.html#cuds-lt-t-gt-geqrf

如果问题规模太小,无法充分利用GPU,您可以使用并发内核执行,同时解决多个方程。

https://devblogs.nvidia.com/parallelforall/gpu-pro-tip-cuda-7-streams-simplify-concurrency/


对于整个数据矩阵,若不能融入全局内存,你可以在每次的只是其中的一部分工作。例如,您可以将矩阵分成十个(1e4 x 1e5)块,每次通过PCIe加载两个块时,分别从两个块中选择所有可能的两列组合,求解方程,然后加载另外两个块。最大化块大小将有助于最大限度地减少PCIe数据传输。通过适当的设计,我确信PCIe数据传输的时间将比求解1e12方程小得多。此外,您可以将数据传输与求解器内核执行重叠。

https://devblogs.nvidia.com/parallelforall/how-overlap-data-transfers-cuda-cc/

+0

对不起,如果这个问题听起来很平凡,但是从我的理解,这意味着我应该将两个大型遗传矩阵块转移到GPU,然后使用来自主机端的循环枚举blockXblock交互,并在每个循环中迭代将从输入矩阵中选择的两列的“设备指针偏移量”发送到cuSolver,每次使用由cudaStreamCreate()创建的新流?你能否给我一个提示,如何在主机代码循环中实现最佳抵消? – Sourena

+0

@sourena你关于流的话是正确的。您需要复制块中的两列来构建矩阵A,而不仅仅是两个指针。您可以先忘记流和重叠的数据传输。 – kangshiyin

+0

我只是没有在你的答案中得到这句话“每次你通过PCIe加载两个块”:现在我想大矩阵的两个片段在GPU全局mem中。然后您评论说:“您需要复制块中的两列来构建矩阵A”。要么我应该在主机端创建A列的十列,然后将其传输到GPU以供cuSolver分析,或者我宁愿将主要大型矩阵的块传输到GPU,然后在设备端构建十列A,然后继续cuSolver? – Sourena

相关问题