无法在我自己的代码中使用CHOLMOD和CUDA加速

无法在我自己的代码中使用CHOLMOD和CUDA加速,c,cuda,suitesparse,C,Cuda,Suitesparse,我正在尝试将CHOLMOD与CUDA一起使用SuiteSparse 4.4.4中的加速度。我根据用户指南编译了它,我可以在Demo文件夹下成功运行gpu.sh,这表明gpu正在做部分工作。然而,当我尝试使用CHOLMOD运行自己的代码时,我发现GPU调用的次数始终为0。我确实将Common->useGPU设置为1,环境变量CHOLMOD\u USE\u GPU也设置为1。我的Makefile如下所示。库路径是正确的。有什么建议吗 实际上,我应该提到,我只是在运行一个最简单的测试用例来解决一个线性

我正在尝试将
CHOLMOD
CUDA
一起使用
SuiteSparse 4.4.4
中的加速度。我根据用户指南编译了它,我可以在
Demo
文件夹下成功运行
gpu.sh
,这表明gpu正在做部分工作。然而,当我尝试使用
CHOLMOD
运行自己的代码时,我发现GPU调用的次数始终为0。我确实将
Common->useGPU
设置为1,环境变量
CHOLMOD\u USE\u GPU
也设置为1。我的Makefile如下所示。库路径是正确的。有什么建议吗

实际上,我应该提到,我只是在运行一个最简单的测试用例来解决一个线性系统

我尝试了UF稀疏矩阵集合中的几个矩阵,但
nvprof
显示没有分析
CUDA
应用程序

我尝试过的一些矩阵:

bmw7st_1:

nd6k:

nd24k:

代码:

#包括
#包括
#包括
#包括
#包括
#包括“cholmod.h”
内部主(空)
{
结构时间值t1,t2;
双延时;
const char*matFile=“../bmw7st_1.mtx”;
文件*fp=fopen(matFile,“r”);
断言(fp!=NULL);
cholmod_稀疏*A;
cholmod_稠密*x,*b;
cholmodu因子*L;
cholmod_common*c=(cholmod_common*)malloc(sizeof(cholmod_common));
cholmod_start(c);/*启动cholmod*/
c->useGPU=1;
c->超节点=CHOLMOD_超节点;
A=cholmod_read_sparse(fp,c);/*在矩阵中读取*/
cholmod_print_sparse(A,“A”,c);/*打印矩阵*/
fclose(fp);
如果(A==NULL | | A->stype==0)/*A必须是对称的*/
{
cholmod_free_sparse(&A,c);
cholmod_饰面(c);
返回(0);
}
b=cholmod_one(A->nrow,1,A->xtype,c);/*b=one(n,1)*/
gettimeofday(&t1,NULL);
L=cholmod_analyze(A,c);/*analyze*/
cholmod_分解(A,L,c);/*分解*/
x=cholmod_solve(cholmod_A,L,b,c);/*solve Ax=b*/
gettimeofday(&t2,NULL);
elapsedTime=(t2.tv_秒-t1.tv_秒)*1000.0;
elapsedTime+=(t2.tv_usec-t1.tv_usec)/1000.0;
printf(“时间:%.4f毫秒\n”,elapsedTime);
cholmod_free_因子(&L,c);/*自由矩阵*/
cholmod_free_sparse(&A,c);
cholmod_free_density(&x,c);
cholmod_free_density(&b,c);
cholmod_饰面(c);/*饰面cholmod*/
返回(0);
}
生成文件:

CC = gcc

CFLAGS = -g -Wall -O2 \
-lrt -lgfortran \
-gdwarf-2

LIBS = $(CHOLMOD)/Lib/libcholmod.a \
$(AMD)/Lib/libamd.a \
$(COLAMD)/Lib/libcolamd.a \
$(LAPACK)/liblapack.a \
$(OPENBLAS)/lib/libopenblas.so \
$(XERBLA)/libcerbla.a \
$(METIS)/libmetis.a \
$(CAMD)/Lib/libcamd.a \
$(CCOLAMD)/Lib/libccolamd.a \
$(SUITESPARSE)/SuiteSparse_config/libsuitesparseconfig.a \
$(CUDART_LIB) \
$(CUBLAS_LIB)

HEADER_DIR = $(CHOLMOD)/Include
CONFIG_HEADER_DIR = $(SUITESPARSE)/SuiteSparse_config

OBJ_DIR = .

BIN_DIR = .

INCLUDES = -I$(HEADER_DIR) \
-I$(CONFIG_HEADER_DIR)

SRCS = $(shell ls *.c)

OBJS = $(SRCS:.c=.o)

OBJS_BUILD = $(shell ls $(OBJ_DIR)/*.o)

APP = prog

RM = rm -f

all: $(APP)

$(APP): $(OBJS)
        $(CC) $(CFLAGS) -o $(BIN_DIR)/$(APP) $(OBJS_BUILD) $(LIBS)

%.o: %.c $(HEADER_DIR)/*.h $(CONFIG_HEADER_DIR)/*.h
        $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $(OBJ_DIR)/$@

clean:
        $(RM) $(OBJS_BUILD) $(APP)
CC=gcc
CFLAGS=-g-壁-O2\
-lrt-lgfortran\
-gdwarf-2
LIBS=$(CHOLMOD)/Lib/libcholmod.a\
$(AMD)/Lib/libamd.a\
$(COLAMD)/Lib/libcolamd.a\
$(LAPACK)/liblapack.a\
$(OPENBLAS)/lib/libopenblas.so\
$(XERBLA)/libcerbla.a\
美元(货币兑换率)/libmetis.a\
$(CAMD)/Lib/libcamd.a\
$(cCLAMD)/Lib/libcCLAMD.a\
$(SUITESPARSE)/SUITESPARSE\u config/libsuitesparseconfig.a\
$(CUDART_LIB)\
$(库布拉斯库)
标题_DIR=$(CHOLMOD)/包括
CONFIG_HEADER_DIR=$(SUITESPARSE)/SUITESPARSE_CONFIG
OBJ_DIR=。
BIN_DIR=。
INCLUDES=-I$(头目录)\
-I$(配置头目录)
SRCS=$(shell ls*.c)
OBJS=$(SRCS:.c=.o)
OBJS_BUILD=$(shell ls$(OBJ_DIR)/*.o)
APP=prog
RM=RM-f
全部:$(应用程序)
$(应用程序):$(OBJS)
$(CC)$(CFLAGS)-o$(BIN_DIR)/$(APP)$(OBJS_BUILD)$(LIBS)
%.o:%.c$(头目录)/*.h$(配置头目录)/*.h
$(CC)$(CFLAGS)$(包括)-c$<-o$(OBJ_DIR)/$@
清洁:
$(RM)$(OBJS_构建)$(应用程序)

参考SuiteSparse 4.4.4附带的CHOLMOD UserGuide.pdf第7节第34页:

只有长整数版本的CHOLMOD可以利用GPU加速

长整数版本的区别在于api调用,如
cholmod\u l\u start
,而不是
cholmod\u start

对您的程序进行以下修改:

#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <assert.h>
#include <sys/time.h>
#include "cholmod.h"

int main (void)
{
    struct timeval t1, t2;
    double elapsedTime;

    const char* matFile = "../Matrix/nd6k/nd6k.mtx";
    FILE* fp = fopen(matFile, "r");
    assert(fp != NULL);

    cholmod_sparse *A ;
    cholmod_dense *x, *b;
    cholmod_factor *L ;

    cholmod_common* c = (cholmod_common*)malloc(sizeof(cholmod_common));
    cholmod_l_start (c) ; /* start CHOLMOD */
    c->useGPU = 1;
    c->supernodal = CHOLMOD_SUPERNODAL;

    A = cholmod_l_read_sparse (fp, c) ; /* read in a matrix */
    cholmod_l_print_sparse (A, "A", c) ; /* print the matrix */
    fclose(fp);

    if (A == NULL || A->stype == 0) /* A must be symmetric */
    {
        cholmod_l_free_sparse (&A, c) ;
        cholmod_l_finish (c) ;
        return (0) ;
    }

    b = cholmod_l_ones (A->nrow, 1, A->xtype, c) ; /* b = ones(n,1) */

    gettimeofday(&t1, NULL);
    L = cholmod_l_analyze (A, c) ; /* analyze */
    cholmod_l_factorize (A, L, c) ; /* factorize */
    x = cholmod_l_solve (CHOLMOD_A, L, b, c) ; /* solve Ax=b */
    gettimeofday(&t2, NULL);
    elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0;
    elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0;
    printf("Time: %.4f ms\n", elapsedTime);
    cholmod_l_gpu_stats(c);
    cholmod_l_free_factor (&L, c) ; /* free matrices */
    cholmod_l_free_sparse (&A, c) ;
    cholmod_l_free_dense (&x, c) ;
    cholmod_l_free_dense (&b, c) ;
    cholmod_l_finish (c) ; /* finish CHOLMOD */
    return (0) ;
}

表示正在使用GPU。

您实际上应该提供一个完整的测试用例,而不仅仅是一个生成文件。@RobertCrovella很抱歉,添加了测试用例。我想没有矩阵文件,没有人可以尝试您的测试用例。你能使用一个标准的矩阵文件吗?矩阵有多大?我很确定CHOLMOD(即SuiteSparse)对是否使用GPU做出了明智的决定。小型测试用例可能不使用GPU。@RobertCrovella,谢谢。事实上,我尝试了UF稀疏矩阵集合中的几个矩阵,但没有一个使用GPU。非常感谢!我是SuiteSparse的新手,我错过了非常重要的信息。它终于起作用了。
#include <stdio.h>
#include <time.h>
#include <unistd.h>
#include <assert.h>
#include <sys/time.h>
#include "cholmod.h"

int main (void)
{
    struct timeval t1, t2;
    double elapsedTime;

    const char* matFile = "../Matrix/nd6k/nd6k.mtx";
    FILE* fp = fopen(matFile, "r");
    assert(fp != NULL);

    cholmod_sparse *A ;
    cholmod_dense *x, *b;
    cholmod_factor *L ;

    cholmod_common* c = (cholmod_common*)malloc(sizeof(cholmod_common));
    cholmod_l_start (c) ; /* start CHOLMOD */
    c->useGPU = 1;
    c->supernodal = CHOLMOD_SUPERNODAL;

    A = cholmod_l_read_sparse (fp, c) ; /* read in a matrix */
    cholmod_l_print_sparse (A, "A", c) ; /* print the matrix */
    fclose(fp);

    if (A == NULL || A->stype == 0) /* A must be symmetric */
    {
        cholmod_l_free_sparse (&A, c) ;
        cholmod_l_finish (c) ;
        return (0) ;
    }

    b = cholmod_l_ones (A->nrow, 1, A->xtype, c) ; /* b = ones(n,1) */

    gettimeofday(&t1, NULL);
    L = cholmod_l_analyze (A, c) ; /* analyze */
    cholmod_l_factorize (A, L, c) ; /* factorize */
    x = cholmod_l_solve (CHOLMOD_A, L, b, c) ; /* solve Ax=b */
    gettimeofday(&t2, NULL);
    elapsedTime = (t2.tv_sec - t1.tv_sec) * 1000.0;
    elapsedTime += (t2.tv_usec - t1.tv_usec) / 1000.0;
    printf("Time: %.4f ms\n", elapsedTime);
    cholmod_l_gpu_stats(c);
    cholmod_l_free_factor (&L, c) ; /* free matrices */
    cholmod_l_free_sparse (&A, c) ;
    cholmod_l_free_dense (&x, c) ;
    cholmod_l_free_dense (&b, c) ;
    cholmod_l_finish (c) ; /* finish CHOLMOD */
    return (0) ;
}
$ ./prog
CHOLMOD sparse:  A:  18000-by-18000, nz 3457658, upper.  OK
Time: 14570.3950 ms

CHOLMOD GPU/CPU statistics:
SYRK  CPU calls          888 time   1.0637e-01
      GPU calls          213 time   8.9194e-02
GEMM  CPU calls          711 time   1.1511e-01
      GPU calls          213 time   1.9351e-03
POTRF CPU calls          217 time   3.2180e-02
      GPU calls            5 time   1.5788e-01
TRSM  CPU calls          217 time   6.0409e-01
      GPU calls            4 time   5.6943e-02
time in the BLAS: CPU   8.5774e-01 GPU   3.0595e-01 total:   1.1637e+00
assembly time   0.0000e+00    0.0000e+00
$