为什么在 Cusolver 中每隔一个函数调用才计算特征向量?

问题描述

我正在编写一个程序来比较 JBlas 和 JCublas 的速度。当我第一次调用下面的函数时,一切正常,并且 v 包含正确的特征向量。当我第二次调用它时,它的计算时间要少得多,但只返回输入的对称矩阵 a,就好像 d_A 的值从未改变过一样。

函数似乎只能在奇数调用上按预期工作。我有一种预感,这个错误是由于 GPU 内存中的某些东西没有被正确清除,但我找不到它。

public static void getSymEigenGPU(cusolverDnHandle handle,DoubleMatrix a) {
        int n2 = a.length;
        int n = a.rows;
        double[] a1d = to1d(a);
        double[] v = new double[n2];
        double[] w = new double[n];

        Pointer h_A = Pointer.to(a1d);
        Pointer h_V = Pointer.to(v);
        Pointer h_W = Pointer.to(w);
        Pointer d_A = new Pointer();
        Pointer d_V = new Pointer();
        Pointer d_W = new Pointer();

        Pointer d_work = new Pointer();

        JCuda.cudamalloc(d_A,(long) n2 * Sizeof.DOUBLE);
        JCuda.cudamalloc(d_V,(long) n2 * Sizeof.DOUBLE);
        JCuda.cudamalloc(d_W,n * Sizeof.DOUBLE);

        int jobz = CUSOLVER_EIG_MODE_VECTOR;
        int uplo = CUBLAS_FILL_MODE_UPPER;

        JCuda.cudamemcpy(d_A,h_A,(long) n2 * Sizeof.DOUBLE,cudamemcpyHostToDevice);

        int[] lworkl = new int[1];
        JCusolverDn.cusolverDnDsyevd_bufferSize(handle,jobz,uplo,n,d_A,d_W,lworkl);
        int lwork = lworkl[0];
        JCuda.cudamalloc(d_work,(long) lwork * Sizeof.DOUBLE);

        NanoStopWatch sw = NanoStopWatch.sw();
        JCusolverDn.cusolverDnDsyevd(handle,d_work,n2,new Pointer());
        System.out.println("sw.stop() = " + sw.stop());

        JCuda.cudamemcpy(h_W,Sizeof.DOUBLE * n,cudamemcpyDevicetoHost);
        JCuda.cudamemcpy(h_V,(long) Sizeof.DOUBLE * n2,cudamemcpyDevicetoHost);

        pp(from1d(v));

        JCuda.cudaFree(d_A);
        JCuda.cudaFree(d_V);
        JCuda.cudaFree(d_W);
        JCuda.cudaFree(d_work);
    }

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)