0

我在 CUDA 机器上使用 CUSP 库进行稀疏矩阵乘法。我目前的代码是

#include <cusp/coo_matrix.h>
#include <cusp/multiply.h>
#include <cusp/print.h>
#include <cusp/transpose.h>
#include<stdio.h>
#define CATAGORY_PER_SCAN 1000
#define TOTAL_CATAGORY 100000
#define MAX_SIZE 1000000
#define ELEMENTS_PER_CATAGORY 10000 
#define ELEMENTS_PER_TEST_CATAGORY 1000
#define INPUT_VECTOR 1000
#define TOTAL_ELEMENTS ELEMENTS_PER_CATAGORY * CATAGORY_PER_SCAN
#define TOTAL_TEST_ELEMENTS ELEMENTS_PER_TEST_CATAGORY * INPUT_VECTOR
int main(void)
{
    cudaEvent_t start, stop;
    cudaEventCreate(&start);
    cudaEventCreate(&stop);
    cudaEventRecord(start, 0);
    cusp::coo_matrix<long long int, double, cusp::host_memory> A(CATAGORY_PER_SCAN,MAX_SIZE,TOTAL_ELEMENTS);
    cusp::coo_matrix<long long int, double, cusp::host_memory> B(MAX_SIZE,INPUT_VECTOR,TOTAL_TEST_ELEMENTS);

    for(int i=0; i< ELEMENTS_PER_TEST_CATAGORY;i++){    
        for(int j = 0;j< INPUT_VECTOR ; j++){
            int index = i * INPUT_VECTOR + j ;
            B.row_indices[index] = i; B.column_indices[ index ] = j; B.values[index ] = i;
        }    
    }
    for(int i = 0;i < CATAGORY_PER_SCAN;  i++){
        for(int j=0; j< ELEMENTS_PER_CATAGORY;j++){     
            int index = i * ELEMENTS_PER_CATAGORY + j ;
            A.row_indices[index] = i; A.column_indices[ index ] = j; A.values[index ] = i;
        }    
    }
    /*cusp::print(A);
    cusp::print(B); */
    //test vector
    cusp::coo_matrix<long int, double, cusp::device_memory> A_d = A;
    cusp::coo_matrix<long int, double, cusp::device_memory> B_d = B;

        // allocate output vector
    cusp::coo_matrix<int, double, cusp::device_memory>  y_d(CATAGORY_PER_SCAN, INPUT_VECTOR ,CATAGORY_PER_SCAN * INPUT_VECTOR);
    cusp::multiply(A_d, B_d, y_d);
    cusp::coo_matrix<int, double, cusp::host_memory> y=y_d;
    cudaEventRecord(stop, 0);
    cudaEventSynchronize(stop);
    float elapsedTime;
    cudaEventElapsedTime(&elapsedTime, start, stop); // that's our time!
    printf("time elaplsed %f ms\n",elapsedTime);
    return 0;
}

cusp::multiply 函数仅使用 1 个 GPU(据我了解)。

  1. 如何使用 setDevice() 在两个 GPU 上运行相同的程序(每个 GPU 一个 cusp::multiply)。
  2. 准确测量总时间。
  3. 我如何在这个库中使用零拷贝固定内存,因为我自己可以使用 malloc。
4

1 回答 1

1

1 如何使用 setDevice() 在两个 GPU 上运行相同的程序

如果您的意思是“我如何cusp::multiply使用两个 GPU 执行单个操作”,答案是您不能。


编辑:

如果您想在不同的 GPU 上运行两个单独的 CUSP 稀疏矩阵 - 矩阵产品,可以简单地将操作包装在一个循环中并cudaSetDevice在传输和调用之前cusp::multiply调用。您可能不会,但是这样做可以加快速度。我认为我说内存传输和cusp::multiply操作都是阻塞调用是正确的,因此主机 CPU 将停止直到它们完成。因此,不同 GPU 的调用不能重叠,并且不会比在单个 GPU 上执行两次相同的操作更快。如果您愿意使用多线程应用程序并拥有一个具有多个内核的主机 CPU,您可能仍然可以并行运行它们,但它不会像您希望的那样简单直接的主机代码。

2 准确测量总时间

您现在使用的cuda_event方法是测量单个内核执行时间的最准确方法。如果您有一个假设的多 GPU 方案,那么来自每个 GPU 上下文的事件的总和将是内核的总执行时间。如果总时间是指完成操作的“挂钟”时间,那么您需要在代码的整个 multigpu 段周围使用主机计时器。我隐约记得,在某些情况下,在最新版本的 CUDA 中,可能会在来自不同上下文的流中的事件之间进行同步,因此在这种情况下,基于 CUDA 事件的计时器可能仍然可用。

3 我如何在这个库中使用零拷贝固定内存,因为我自己可以使用 malloc。

据我所知,这是不可能的。CUSP 使用的底层推力库可以支持使用零拷贝内存的容器,但 CUSP 没有在标准矩阵构造函数中公开必要的机制,以便能够在零拷贝内存中分配 CUSP 稀疏矩阵。

于 2012-09-19T15:44:18.293 回答