Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ CUDA-CUBLAS:解决多(3x3)稠密线性系统的问题_C++_C_Cuda_Cublas_Cusolver - Fatal编程技术网

C++ CUDA-CUBLAS:解决多(3x3)稠密线性系统的问题

C++ CUDA-CUBLAS:解决多(3x3)稠密线性系统的问题,c++,c,cuda,cublas,cusolver,C++,C,Cuda,Cublas,Cusolver,我试图用CUDA 10.1解决大约1200000个线性系统3x3,Ax=B,特别是使用CUBLAS库。我从一个统一的内存版本中得到了提示,并重新编写了建议的代码。该算法首先使用cublasgetrfBatched执行LU分解,然后两次连续调用cublastrsm求解上下三角线性系统。代码附在下面。它可以在大约10000个矩阵中正常工作,在这种情况下,在NVIDIA GeForce 930MX上执行LU分解需要约570 ms,而求解系统则需要约311 ms 我的问题是: 过载问题:为超过10k的矩

我试图用CUDA 10.1解决大约1200000个线性系统3x3,Ax=B,特别是使用CUBLAS库。我从一个统一的内存版本中得到了提示,并重新编写了建议的代码。该算法首先使用cublasgetrfBatched执行LU分解,然后两次连续调用cublastrsm求解上下三角线性系统。代码附在下面。它可以在大约10000个矩阵中正常工作,在这种情况下,在NVIDIA GeForce 930MX上执行LU分解需要约570 ms,而求解系统则需要约311 ms

我的问题是:

过载问题:为超过10k的矩阵分配内存时崩溃。为什么?如何改进代码以解决整个120万个矩阵

时间问题:我的目标是在不到1秒的时间内解决所有这些系统。我目前是否遵循正确的方法?还有其他建议吗

是否可能和/或有用,如果是,如何使用10k矩阵批次的“流”

代码:

过载问题:为超过10k的矩阵分配内存时崩溃。为什么?如何改进代码以解决整个120万个矩阵

在我看来,代码中最大的问题是,在这些密钥分配循环中,托管内存的使用效率极低:

  //ALLOCATE MEMORY - using unified memory
  double** h_A;
  cudaMallocManaged(&h_A, sizeof(double*) * numMatrices);
  for (int nm = 0; nm < numMatrices; nm++) {
    cudaMallocManaged(&(h_A[nm]), sizeof(double) * N * N);
  }

  double** h_b;
  cudaMallocManaged(&h_b, sizeof(double*) * numMatrices);
  for (int nm = 0; nm < numMatrices; nm++) {
    cudaMallocManaged(&(h_b[nm]), sizeof(double) * N );
  }
这样做的另一个好处是分配过程运行得更快

时间问题:我的目标是在不到1秒的时间内解决所有这些系统。我目前是否遵循正确的方法?还有其他建议吗

通过对代码的更改,我能够在1GB GPU GeForce GT640上成功运行,并且:

const int numMatrices = 1200000;
输出如下:

  //ALLOCATE MEMORY - using unified memory
  double** h_A;
  cudaMallocManaged(&h_A, sizeof(double*) * numMatrices);
  cudaMallocManaged(&(h_A[0]), sizeof(double)*numMatrices*N*N);
  for (int nm = 1; nm < numMatrices; nm++) {
    h_A[nm] = h_A[nm-1]+ N * N;
  }

  double** h_b;
  cudaMallocManaged(&h_b, sizeof(double*) * numMatrices);
  cudaMallocManaged(&(h_b[0]), sizeof(double) * numMatrices * N);
  for (int nm = 1; nm < numMatrices; nm++) {
    h_b[nm] = h_b[nm-1] + N;
  }
$ ./t81
 memory allocated
 Matrix filled
 Coeff. vector filled

It took 70.3032 milliseconds.
rearrangement took 60.02 milliseconds.
second step took 156.067 milliseconds.
你的GPU可能有点慢,但我认为总的时间应该很容易在不到1秒

是否可能和/或有用,如果是,如何使用10k矩阵批次的“流”

有了以上的改变,我想你不必担心这个。流在这里对计算操作的重叠没有帮助。它们可以帮助复制/计算重叠,虽然在GPU上可能不多,但在具有托管内存的windows上很难构建。对于windows的使用,我可能会建议切换到普通的CUDA主机和设备内存分离,如果你想探索的话

另一方面,您可以通过使用直接反转获得一组cublas调用,这些调用将更快地完成工作。CUBLAS采用批量直接反演方法。对于线性方程组的求解,我通常不建议这样做,但是对于一组3x3或4x4反演,它可能是要考虑的问题,在这里你可以用行列式方法很容易地检查奇点。这就是一个例子

过载问题:为超过10k的矩阵分配内存时崩溃。为什么?如何改进代码以解决整个120万个矩阵

在我看来,代码中最大的问题是,在这些密钥分配循环中,托管内存的使用效率极低:

  //ALLOCATE MEMORY - using unified memory
  double** h_A;
  cudaMallocManaged(&h_A, sizeof(double*) * numMatrices);
  for (int nm = 0; nm < numMatrices; nm++) {
    cudaMallocManaged(&(h_A[nm]), sizeof(double) * N * N);
  }

  double** h_b;
  cudaMallocManaged(&h_b, sizeof(double*) * numMatrices);
  for (int nm = 0; nm < numMatrices; nm++) {
    cudaMallocManaged(&(h_b[nm]), sizeof(double) * N );
  }
这样做的另一个好处是分配过程运行得更快

时间问题:我的目标是在不到1秒的时间内解决所有这些系统。我目前是否遵循正确的方法?还有其他建议吗

通过对代码的更改,我能够在1GB GPU GeForce GT640上成功运行,并且:

const int numMatrices = 1200000;
输出如下:

  //ALLOCATE MEMORY - using unified memory
  double** h_A;
  cudaMallocManaged(&h_A, sizeof(double*) * numMatrices);
  cudaMallocManaged(&(h_A[0]), sizeof(double)*numMatrices*N*N);
  for (int nm = 1; nm < numMatrices; nm++) {
    h_A[nm] = h_A[nm-1]+ N * N;
  }

  double** h_b;
  cudaMallocManaged(&h_b, sizeof(double*) * numMatrices);
  cudaMallocManaged(&(h_b[0]), sizeof(double) * numMatrices * N);
  for (int nm = 1; nm < numMatrices; nm++) {
    h_b[nm] = h_b[nm-1] + N;
  }
$ ./t81
 memory allocated
 Matrix filled
 Coeff. vector filled

It took 70.3032 milliseconds.
rearrangement took 60.02 milliseconds.
second step took 156.067 milliseconds.
你的GPU可能有点慢,但我认为总的时间应该很容易在不到1秒

是否可能和/或有用,如果是,如何使用10k矩阵批次的“流”

有了以上的改变,我想你不必担心这个。流在这里对计算操作的重叠没有帮助。它们可以帮助复制/计算重叠,虽然在GPU上可能不多,但在具有托管内存的windows上很难构建。对于windows的使用,我可能会建议切换到普通的CUDA主机和设备内存分离,如果你想探索的话


另一方面,您可以通过使用直接反转获得一组cublas调用,这些调用将更快地完成工作。CUBLAS采用批量直接反演方法。对于线性方程组的求解,我通常不建议这样做,但是对于一组3x3或4x4反演,它可能是要考虑的问题,在这里你可以用行列式方法很容易地检查奇点。是一个例子。

与您的内存问题无关,但请注意,对于如此小的矩阵,直接方法可能比LU分解更有效。您可能有兴趣了解一下:与内存问题无关,但请注意,对于如此小的矩阵,直接方法可能比LU分解更有效。你可以看一看,也许会感兴趣:谢谢
! 我用这些更正测试了代码,整个过程第一步+重排+第二步大约需要600毫秒,这对我来说非常好。然而,为了检查结果的一致性,我还用3个矩阵测试了代码,这并没有为系统提供正确的解决方案。我想知道在填充矩阵时是否应该更改/更正任何索引?我无法告诉您没有显示的代码有什么问题。据我所知,分配方案的这一变化不应该影响算法的后续使用或算法的行为。谢谢!我用这些更正测试了代码,整个过程第一步+重排+第二步大约需要600毫秒,这对我来说非常好。然而,为了检查结果的一致性,我还用3个矩阵测试了代码,这并没有为系统提供正确的解决方案。我想知道在填充矩阵时是否应该更改/更正任何索引?我无法告诉您没有显示的代码有什么问题。据我所知,分配方案的这种变化不应该影响算法中的后续使用或算法的行为。