仅使用 CUDA 进行奇异值计算

2024-04-24

我正在尝试使用新的cusolverDnSgesvdCUDA 7.0 用于计算奇异值的例程。完整代码如下:

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>

#include<iostream>
#include<stdlib.h>
#include<stdio.h>
#include <cusolverDn.h>
#include <cuda_runtime_api.h>

/***********************/
/* CUDA ERROR CHECKING */
/***********************/
void gpuAssert(cudaError_t code, char *file, int line, bool abort=true)
{
   if (code != cudaSuccess)
   {
      fprintf(stderr,"GPUassert: %s %s %d\n", cudaGetErrorString(code), file, line);
      if (abort) { exit(code); }
   }
}
void gpuErrchk(cudaError_t ans) { gpuAssert((ans), __FILE__, __LINE__); }

/********/
/* MAIN */
/********/
int main(){

    int M = 10;
    int N = 10;

    // --- Setting the host matrix
    float *h_A = (float *)malloc(M * N * sizeof(float));
    for(unsigned int i = 0; i < M; i++){
        for(unsigned int j = 0; j < N; j++){
            h_A[j*M + i] = (i + j) * (i + j);
        }
    }

    // --- Setting the device matrix and moving the host matrix to the device
    float *d_A;         gpuErrchk(cudaMalloc(&d_A,      M * N * sizeof(float)));
    gpuErrchk(cudaMemcpy(d_A, h_A, M * N * sizeof(float), cudaMemcpyHostToDevice));

    // --- host side SVD results space
    float *h_U = (float *)malloc(M * M * sizeof(float));
    float *h_V = (float *)malloc(N * N * sizeof(float));
    float *h_S = (float *)malloc(N *     sizeof(float));

    // --- device side SVD workspace and matrices
    int work_size = 0;

    int *devInfo;       gpuErrchk(cudaMalloc(&devInfo,          sizeof(int)));
    float *d_U;         gpuErrchk(cudaMalloc(&d_U,      M * M * sizeof(float)));
    float *d_V;         gpuErrchk(cudaMalloc(&d_V,      N * N * sizeof(float)));
    float *d_S;         gpuErrchk(cudaMalloc(&d_S,      N *     sizeof(float)));

    cusolverStatus_t stat;

    // --- CUDA solver initialization
    cusolverDnHandle_t solver_handle;
    cusolverDnCreate(&solver_handle);

    stat = cusolverDnSgesvd_bufferSize(solver_handle, M, N, &work_size);
    if(stat != CUSOLVER_STATUS_SUCCESS ) std::cout << "Initialization of cuSolver failed. \N";

    float *work;    gpuErrchk(cudaMalloc(&work, work_size * sizeof(float)));
    //float *rwork; gpuErrchk(cudaMalloc(&rwork, work_size * sizeof(float)));

    // --- CUDA SVD execution
    //stat = cusolverDnSgesvd(solver_handle, 'A', 'A', M, N, d_A, M, d_S, d_U, M, d_V, N, work, work_size, NULL, devInfo);
    stat = cusolverDnSgesvd(solver_handle, 'N', 'N', M, N, d_A, M, d_S, d_U, M, d_V, N, work, work_size, NULL, devInfo);
    cudaDeviceSynchronize();

    int devInfo_h = 0;
    gpuErrchk(cudaMemcpy(&devInfo_h, devInfo, sizeof(int), cudaMemcpyDeviceToHost));
    std::cout << "devInfo = " << devInfo_h << "\n";

    switch(stat){
        case CUSOLVER_STATUS_SUCCESS:           std::cout << "SVD computation success\n";                       break;
        case CUSOLVER_STATUS_NOT_INITIALIZED:   std::cout << "Library cuSolver not initialized correctly\n";    break;
        case CUSOLVER_STATUS_INVALID_VALUE:     std::cout << "Invalid parameters passed\n";                     break;
        case CUSOLVER_STATUS_INTERNAL_ERROR:    std::cout << "Internal operation failed\n";                     break;
    }

    if (devInfo_h == 0 && stat == CUSOLVER_STATUS_SUCCESS) std::cout    << "SVD successful\n\n";

    // --- Moving the results from device to host
    gpuErrchk(cudaMemcpy(h_S, d_S, N * sizeof(float), cudaMemcpyDeviceToHost));

    for(int i = 0; i < N; i++) std::cout << "d_S["<<i<<"] = " << h_S[i] << std::endl;

    cusolverDnDestroy(solver_handle);

    return 0;

}

如果我要求计算完整的 SVD(注释行为jobu = 'A' and jobvt = 'A')一切正常。如果我只要求计算奇异值(与jobu = 'N' and jobvt = 'N'), cusolverDnSgesvd回报

CUSOLVER_STATUS_INVALID_VALUE

请注意,在这种情况下devInfo = 0,所以我无法发现无效参数。

另请注意,文档 PDF 缺少有关rwork参数,以便我将其作为虚拟参数处理。


此时cuSolvergesvd功能仅支持jobu = 'A' and jobvt = 'A'

因此,当您指定其他组合时出现错误是预料之中的。来自文档 http://docs.nvidia.com/cuda/cusolver/index.html#cuds-lt-t-gt-gesvd:

备注2:gesvd仅支持jobu='A'和jobvt='A'并返回矩阵U和VH

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

仅使用 CUDA 进行奇异值计算 的相关文章

  • Nvcc 的版本与 CUDA 不同

    我安装了 cuda 7 但是当我点击 nvcc version 时 它打印出 6 5 我想在 GTX 960 卡上安装 Theano 库 但它需要 nvcc 7 0 我尝试重新安装cuda 但它没有更新nvcc 当我运行 apt get i
  • 无法在 CUDA 中执行设备内核

    我正在尝试在全局内核中调用设备内核 我的全局内核是矩阵乘法 我的设备内核正在查找乘积矩阵每列中的最大值和索引 以下是代码 device void MaxFunction float Pd float max int x threadIdx
  • CUDA 常量内存是否应该被均匀地访问?

    我的 CUDA 应用程序的恒定内存小于 8KB 既然它都会被缓存 我是否需要担心每个线程访问相同的地址以进行优化 如果是 如何确保所有线程同时访问同一地址 既然它都会被缓存 我是否需要担心每个线程访问相同的地址以进行优化 是的 这缓存本身每
  • cuda中有模板化的数学函数吗? [复制]

    这个问题在这里已经有答案了 我一直在寻找 cuda 中的模板化数学函数 但似乎找不到 在普通的 C 中 如果我调用std sqrt它是模板化的 并且将根据参数是浮点数还是双精度数执行不同的版本 我想要这样的 CUDA 设备代码 我的内核将真
  • 使用 CUDA 进行逐元素向量乘法

    我已经在 CUDA 中构建了一个基本内核来执行逐元素两个复向量的向量 向量乘法 内核代码插入如下 multiplyElementwise 它工作正常 但由于我注意到其他看似简单的操作 如缩放向量 在 CUBLAS 或 CULA 等库中进行了
  • 在 cudaFree() 之前需要 cudaDeviceSynchronize() 吗?

    CUDA 版本 10 1 帕斯卡 GPU 所有命令都发送到默认流 void ptr cudaMalloc ptr launch kernel lt lt lt gt gt gt ptr cudaDeviceSynchronize Is th
  • cuda中内核的并行执行

    可以说我有三个全局数组 它们已使用 cudaMemcpy 复制到 GPU 中 但 c 中的这些全局数组尚未使用 cudaHostAlloc 分配 以便分配页面锁定的内存 而不是简单的全局分配 int a 100 b 100 c 100 cu
  • cudaMemcpy() 与 cudaMemcpyFromSymbol()

    我试图找出原因cudaMemcpyFromSymbol 存在 似乎 symbol func 可以做的所有事情 nonSymbol cmd 也可以做 symbol func 似乎可以轻松移动数组或索引的一部分 但这也可以使用 nonSymbo
  • 将 nvidia 运行时添加到 docker 运行时

    我正在运行虚拟机GCP配备特斯拉 GPU 并尝试部署一个PyTorch基于应用程序使用 GPU 加速 我想让 docker 使用这个 GPU 可以从容器访问它 我设法在主机上安装了所有驱动程序 并且该应用程序在那里运行良好 但是当我尝试在
  • CUDA 中指令重放的其他原因

    这是我从 nvprof CUDA 5 5 获得的输出 Invocations Metric Name Metric Description Min Max Avg Device Tesla K40c 0 Kernel MyKernel do
  • 具有 Cuda Thrust 的多个 GPU?

    如何将 Thrust 与多个 GPU 一起使用 这只是使用 cudaSetDevice deviceId 的问题吗 然后运行相关的 Thrust 代码 使用 CUDA 4 0 或更高版本 cudaSetDevice deviceId 接下来
  • CUDA:获取数组中的最大值及其索引

    我有几个块 每个块在整数数组的单独部分上执行 举个例子 块一从 array 0 到 array 9 块二从 array 10 到 array 20 我可以获得每个块的数组最大值的索引的最佳方法是什么 示例块一 a 0 到 a 10 具有以下
  • cudaDeviceScheduleBlockingSync 和 cudaDeviceScheduleYield 之间有什么区别?

    正如这里所说 如何减少 CUDA 同步延迟 延迟 https stackoverflow com questions 11953722 how to reduce cuda synchronize latency delay 等待设备结果有
  • CUDA Thrust 库中counting_iterators 的用途和用法

    我很难理解counting iterator在 CUDA 的推力库中 它的目的是什么以及如何使用 它在其他编程语言 例如 C 中也可用吗 计数迭代器只是一个迭代器 它从每次迭代器递增时前进的序列中返回下一个值 最简单的例子是这样的 incl
  • 使用 cudamalloc()。为什么是双指针?

    我目前正在浏览有关的教程示例http code google com p stanford cs193g sp2010 http code google com p stanford cs193g sp2010 学习CUDA 演示的代码 g
  • 使用推力来处理 CUDA 类中的向量?

    我对 C 类的推力的适用性有疑问 我正在尝试实现一个类对象 该对象接收顶点的 x y z 坐标作为 ver1 ver2 和 ver3 然后 分配给一个三角形并计算面积和法向量 然而 我不太明白如何创建一类推力向量 这是我从文件中读取的顶点坐
  • 如何在没有 nvcc 的情况下在编译时获取 CUDA 工具包版本?

    我在 cpp 文件中对 cuSPARSE 库进行了一些调用 这些调用在旧工具包中不可用 为了支持使用旧工具包的系统 我想使用编译器指令编译不同的代码部分 特别是 我想使用旧工具包的 CSR 格式矩阵和新工具包的 BSR 格式矩阵来求解稀疏三
  • 完全禁用 NVCC 优化

    我正在尝试测量 GPU 上的峰值单精度触发器 为此我正在修改 PTX 文件以在寄存器上执行连续的 MAD 指令 不幸的是 编译器正在删除所有代码 因为它实际上没有做任何有用的事情 因为我没有执行任何数据的加载 存储 是否有编译器标志或编译指
  • 了解流式多处理器 (SM) 和流式处理器 (SP)

    我正在尝试了解 GPU 的基本架构 我已经阅读了很多材料 包括这个非常好的答案 https stackoverflow com a 2213744 2386113 但我仍然很困惑 无法得到一个好的图片 我的理解 GPU 包含两个或多个流式多
  • 如何转储所有 NVCC 预处理器定义?

    我想达到同样的效果 gcc dM E lt dev null 如所描述的here https stackoverflow com q 2224334 1593077 但对于 nvcc 也就是说 我想转储所有 nvcc 的预处理器定义 唉 n

随机推荐