我有一个稀疏矩阵结构,我将它与CUBLAS结合使用来实现一个线性求解器类。我预计我要求解的稀疏矩阵的维数会相当大(大约是10^7乘10^7)。我还预计求解器将需要多次使用,并且此矩阵的一部分也将需要多次更新(在计算解决方案之间)。
将整个矩阵结构从系统存储器复制到设备存储器可能成为相当大的性能瓶颈,因为在给定时间只需要改变矩阵条目的一小部分。
我希望能够做的是有一种方法来仅更新特定的子集/子矩阵,而不是在每次需要更改矩阵时将整个矩阵结构从系统内存重新复制到设备内存。
矩阵数据结构将以数组的形式驻留在CUDA设备上: d_col、d_row和d_val
在系统端,我将有相应的数组I、J和val。
因此,理想情况下,我只想更改与系统数组val中的值相对应的d_val的子集。
请注意,我预计不会向矩阵中添加或从矩阵中删除任何条目,只会更改现有条目的值。
我天真地认为,为了实现这一点,我应该在主机端有一个整数数组或向量,例如updateInds,它将跟踪val中已更改的条目的索引,但我不确定如何有效地告诉CUDA设备更新d_val的相应值。
本质上:如何将CUDA设备端数组( d_val )中索引updateInds1,updateInds2,...,updateIndsn处的条目更改为一组新的值val[updatInds1],val[updateInds2],...,val[updateInds3],而无需将整个val数组从系统内存重新复制到CUDA设备内存数组d_val中?
发布于 2015-06-23 06:17:45
只要您只想更改与CSR (或CSC或COO)稀疏矩阵表示相关联的值数组的数值,该过程就不复杂。
假设我有这样的代码(摘自CUDA共轭梯度sample):
checkCudaErrors(cudaMalloc((void **)&d_val, nz*sizeof(float)));
...
cudaMemcpy(d_val, val, nz*sizeof(float), cudaMemcpyHostToDevice);现在,在代码中的这一点之后,假设我需要更改d_val数组中的一些值,以对应于我在val中所做的更改
for (int i = 10; i < 25; i++)
val[i] = 4.0f;移动这些特定更改的过程在概念上与使用memcpy更新阵列的过程相同,但我们将使用cudaMemcpy更新设备上的d_val阵列:
cudaMemcpy(d_val+10, val+10, 15*sizeof(float), cudaMempcyHostToDevice);因为这些值都是连续的,所以我可以使用单个cudaMemcpy调用来实现传输。
如果我有几个类似于上面的不相交的区域,它将需要多次调用cudaMemcpy,每个区域一个。如果碰巧两个区域的间距相等且长度相等:
for (int i = 10; i < 5; i++)
val[i] = 1.0f;
for (int i = 20; i < 5; i++)
val[i] = 2.0f;
for (int i = 30; i < 5; i++)
val[i] = 4.0f;然后,也可以使用对cudaMemcpy2D的单个调用来执行此传输。该方法被概述为here。
备注:
与对相同数量的元素执行cudaMemcpy操作相比,
cudaMemcpy2D的速度比您预期的要慢。d_val cudaMemcpy方法。在这种情况下,我无法提供如何通过外科手术更新设备上的CSR稀疏矩阵的一般答案。而且,某些相对简单的更改可能需要更新大多数数组数据(3个向量)。https://stackoverflow.com/questions/30988492
复制相似问题