使用 CUDA 并行实现多个 SVD

2023-12-29

我是使用 GPU 并行编程的新手,因此如果问题广泛或模糊,我深表歉意。我知道 CULA 库中有一些并行 SVD 函数,但是如果我有大量相对较小的矩阵需要分解,应该采取什么策略?例如我有n有维数的矩阵d, n很大并且d是小。如何并行化这个过程?有人能给我提示吗?


我之前的答案现在已经过时了。截至 2015 年 2 月,CUDA 7(当前为候选版本)在其 cuSOLVER 库中提供了完整的 SVD 功能。下面,我提供了一个使用 CUDA cuSOLVER 生成奇异值分解的示例。

关于您提出的具体问题(计算几个小尺寸矩阵的 SVD),您应该使用流来调整我在下面提供的示例。要将流与每个任务关联,您可以使用

cudaStreamCreate()

and

cusolverDnSetStream()

内核.cu

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

#include<iostream>
#include<iomanip>
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#include<math.h>

#include <cusolverDn.h>
#include <cuda_runtime_api.h>

#include "Utilities.cuh"

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

    // --- gesvd only supports Nrows >= Ncols
    // --- column major memory ordering

    const int Nrows = 7;
    const int Ncols = 5;

    // --- cuSOLVE input/output parameters/arrays
    int work_size = 0;
    int *devInfo;           gpuErrchk(cudaMalloc(&devInfo,          sizeof(int)));

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

    // --- Setting the host, Nrows x Ncols matrix
    double *h_A = (double *)malloc(Nrows * Ncols * sizeof(double));
    for(int j = 0; j < Nrows; j++)
        for(int i = 0; i < Ncols; i++)
            h_A[j + i*Nrows] = (i + j*j) * sqrt((double)(i + j));

    // --- Setting the device matrix and moving the host matrix to the device
    double *d_A;            gpuErrchk(cudaMalloc(&d_A,      Nrows * Ncols * sizeof(double)));
    gpuErrchk(cudaMemcpy(d_A, h_A, Nrows * Ncols * sizeof(double), cudaMemcpyHostToDevice));

    // --- host side SVD results space
    double *h_U = (double *)malloc(Nrows * Nrows     * sizeof(double));
    double *h_V = (double *)malloc(Ncols * Ncols     * sizeof(double));
    double *h_S = (double *)malloc(min(Nrows, Ncols) * sizeof(double));

    // --- device side SVD workspace and matrices
    double *d_U;            gpuErrchk(cudaMalloc(&d_U,  Nrows * Nrows     * sizeof(double)));
    double *d_V;            gpuErrchk(cudaMalloc(&d_V,  Ncols * Ncols     * sizeof(double)));
    double *d_S;            gpuErrchk(cudaMalloc(&d_S,  min(Nrows, Ncols) * sizeof(double)));

    // --- CUDA SVD initialization
    cusolveSafeCall(cusolverDnDgesvd_bufferSize(solver_handle, Nrows, Ncols, &work_size));
    double *work;   gpuErrchk(cudaMalloc(&work, work_size * sizeof(double)));

    // --- CUDA SVD execution
    cusolveSafeCall(cusolverDnDgesvd(solver_handle, 'A', 'A', Nrows, Ncols, d_A, Nrows, d_S, d_U, Nrows, d_V, Ncols, work, work_size, NULL, devInfo));
    int devInfo_h = 0;  gpuErrchk(cudaMemcpy(&devInfo_h, devInfo, sizeof(int), cudaMemcpyDeviceToHost));
    if (devInfo_h != 0) std::cout   << "Unsuccessful SVD execution\n\n";

    // --- Moving the results from device to host
    gpuErrchk(cudaMemcpy(h_S, d_S, min(Nrows, Ncols) * sizeof(double), cudaMemcpyDeviceToHost));
    gpuErrchk(cudaMemcpy(h_U, d_U, Nrows * Nrows     * sizeof(double), cudaMemcpyDeviceToHost));
    gpuErrchk(cudaMemcpy(h_V, d_V, Ncols * Ncols     * sizeof(double), cudaMemcpyDeviceToHost));

    std::cout << "Singular values\n";
    for(int i = 0; i < min(Nrows, Ncols); i++) 
        std::cout << "d_S["<<i<<"] = " << std::setprecision(15) << h_S[i] << std::endl;

    std::cout << "\nLeft singular vectors - For y = A * x, the columns of U span the space of y\n";
    for(int j = 0; j < Nrows; j++) {
        printf("\n");
        for(int i = 0; i < Nrows; i++)
            printf("U[%i,%i]=%f\n",i,j,h_U[j*Nrows + i]);
    }

    std::cout << "\nRight singular vectors - For y = A * x, the columns of V span the space of x\n";
    for(int i = 0; i < Ncols; i++) {
        printf("\n");
        for(int j = 0; j < Ncols; j++)
            printf("V[%i,%i]=%f\n",i,j,h_V[j*Ncols + i]);
    }

    cusolverDnDestroy(solver_handle);

    return 0;

}

实用程序.cuh

#ifndef UTILITIES_CUH
#define UTILITIES_CUH

extern "C" int iDivUp(int, int);
extern "C" void gpuErrchk(cudaError_t);
extern "C" void cusolveSafeCall(cusolverStatus_t);

#endif

实用程序.cu

#include <stdio.h>
#include <assert.h>

#include "cuda_runtime.h"
#include <cuda.h>

#include <cusolverDn.h>

/*******************/
/* iDivUp FUNCTION */
/*******************/
extern "C" int iDivUp(int a, int b){ return ((a % b) != 0) ? (a / b + 1) : (a / b); }

/********************/
/* CUDA ERROR CHECK */
/********************/
// --- Credit to http://stackoverflow.com/questions/14038589/what-is-the-canonical-way-to-check-for-errors-using-the-cuda-runtime-api
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); }
   }
}

extern "C" void gpuErrchk(cudaError_t ans) { gpuAssert((ans), __FILE__, __LINE__); }

/**************************/
/* CUSOLVE ERROR CHECKING */
/**************************/
static const char *_cudaGetErrorEnum(cusolverStatus_t error)
{
    switch (error)
    {
        case CUSOLVER_STATUS_SUCCESS:
            return "CUSOLVER_SUCCESS";

        case CUSOLVER_STATUS_NOT_INITIALIZED:
            return "CUSOLVER_STATUS_NOT_INITIALIZED";

        case CUSOLVER_STATUS_ALLOC_FAILED:
            return "CUSOLVER_STATUS_ALLOC_FAILED";

        case CUSOLVER_STATUS_INVALID_VALUE:
            return "CUSOLVER_STATUS_INVALID_VALUE";

        case CUSOLVER_STATUS_ARCH_MISMATCH:
            return "CUSOLVER_STATUS_ARCH_MISMATCH";

        case CUSOLVER_STATUS_EXECUTION_FAILED:
            return "CUSOLVER_STATUS_EXECUTION_FAILED";

        case CUSOLVER_STATUS_INTERNAL_ERROR:
            return "CUSOLVER_STATUS_INTERNAL_ERROR";

        case CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED:
            return "CUSOLVER_STATUS_MATRIX_TYPE_NOT_SUPPORTED";

    }

    return "<unknown>";
}

inline void __cusolveSafeCall(cusolverStatus_t err, const char *file, const int line)
{
    if(CUSOLVER_STATUS_SUCCESS != err) {
        fprintf(stderr, "CUSOLVE error in file '%s', line %d\n %s\nerror %d: %s\nterminating!\n",__FILE__, __LINE__,err, \
                                _cudaGetErrorEnum(err)); \
        cudaDeviceReset(); assert(0); \
    }
}

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

使用 CUDA 并行实现多个 SVD 的相关文章

  • 使用 tfprof 分析 TensorFlow

    我正在尝试分析 TensorFlow 的计算 内存使用情况 发现tfprof https github com tensorflow tensorflow tree master tensorflow tools tfprof是实现我的目的
  • C# 并行与并行线程代码性能

    我一直在测试 System Threading Parallel 与线程的性能 我很惊讶地发现并行比线程花费更长的时间来完成任务 我确信这是由于我对并行的了解有限 我刚刚开始阅读 我想我会分享一些片段 如果有人可以向我指出并行代码比线程代码
  • “程序顺序”实际上是什么意思?

    据我所知 莱斯利 兰波特 Leslie Lamport 声明如下 任何执行的结果都相同 就好像所有处理器的操作都按某种顺序执行 并且每个单独处理器的操作都按此顺序出现在由其程序指定的顺序 取自 Leslie Lamport 如何制作正确执行
  • 摆脱异步 cuda 流执行期间的忙等待

    我正在寻找一种方法 如何摆脱以下代码中主机线程中的忙等待 不要复制该代码 它仅显示我的问题的想法 它有许多基本错误 cudaStream t steams S N for int i 0 i lt S N i cudaStreamCreat
  • PHP 中的并行处理 - 你是如何做到的?

    我目前正在尝试在 php 中实现一个作业队列 然后 队列将作为批处理作业进行处理 并且应该能够并行处理一些作业 我已经做了一些研究并找到了几种实现它的方法 但我并不太了解它们的优点和缺点 例如 通过多次调用脚本来进行并行处理fsockope
  • Cuda:最小二乘求解,速度较差

    最近 我使用Cuda编写了一个名为 正交匹配追踪 的算法 在我丑陋的 Cuda 代码中 整个迭代需要 60 秒 而 Eigen lib 只需 3 秒 在我的代码中 矩阵 A 是 640 1024 y 是 640 1 在每一步中 我从 A 中
  • 使用 numpy eig 和 svd 计算的特征向量不匹配

    考虑奇异值分解 M USV 然后M M的特征值分解得到M M V S S V VS U USV 我希望通过显示返回的特征向量来验证与 numpy 的相等性eigh函数与返回的函数相同svd功能 import numpy as np np r
  • Erlang 进程如何(如果有的话)映射到内核线程?

    Erlang 因能够支持许多轻量级进程而闻名 它之所以能做到这一点 是因为它们不是传统意义上的进程 甚至不是 P 线程中的线程 而是完全在用户空间中的线程 这很好 实际上很棒 那么 Erlang 线程如何在多核 多处理器环境中并行执行呢 当
  • Rmpi:mclapply:在 selectChildren(ac, 1) 中:选择中出现“系统调用中断”错误

    以下最小示例 require Rmpi set seed 1 foo lt parallel mclapply seq len 10 function l lapply 1 10 function x mean rnorm 10000 me
  • 我们如何在每次运行时使用不同的种子在 CUDA C 中生成随机数?

    我正在研究一个随机过程 我想在每次运行程序时在 CUDA 内核中生成不同的系列随机数 这类似于我们在 C 中声明 种子 时间 空 接下来是 srand 种子 和兰特 我可以通过内核将种子从主机传递到设备 但是 这样做的问题是我必须将整个种子
  • Windows Azure 虚拟机配备什么类型的显卡?

    我正在考虑在 Windows Azure 虚拟机上运行一些图形密集型程序 但不确定它们有什么样的硬件 所有虚拟机都具有相同的 GPU 吗 您对此有何体验 Azure 虚拟机中的 GPU 可能非常基本 并且很可能不具备执行密集图形操作所需的处
  • 如何安装libcusolver.so.11

    我正在尝试安装 Tensorflow 但它要求 libcusolver so 11 而我只有 libcusolver so 10 有人可以告诉我我做错了什么吗 这是我的 Ubuntu nvidia 和 CUDA 版本 uname a Lin
  • Flink Kafka - 如何使应用程序并行运行?

    我正在 Flink 中创建一个应用程序 读取某个主题的消息 对其进行一些简单的处理 将结果写入不同的主题 我的代码确实有效 然而它不并行运行我怎么做 看来我的代码只在一个线程 块上运行 在 Flink Web 仪表板上 应用程序进入运行状态
  • 编写openCL代码时,在没有GPU的单核机器上表现如何?

    大家好 我目前正在将光线追踪器从 FORTRAN 77 移植到 C 语言以进行研究项目 移植了要点之后 问题是我们如何进行并行化 在实验室中 我可以使用几台不同的 Opteron 机器 具有 2 到 8 个内核 但没有 GPU 目前 我们正
  • 避免 Python 3 的多处理队列中的竞争条件

    我正在尝试找到大约 61 亿 自定义 物品的最大重量 并且我想通过并行处理来完成此操作 对于我的特定应用程序 有更好的算法不需要我迭代超过 61 亿个项目 但解释它们的教科书超出了我的能力范围 我的老板希望在 4 天内完成此任务 我认为我公
  • 如何强制tensorflow使用所有可用的GPU?

    我有一个 8 GPU 集群 当我运行Kaggle 的一段 Tensorflow 代码 https www kaggle com keegil keras u net starter lb 0 277 scriptVersionId 2164
  • OpenMP 与浮点范围并行

    我有以下程序 int main double sum 0 pragma omp parallel for reduction sum for double x 0 x lt 10 x 0 1 sum x x 当我编译它时 我收到错误inva
  • Java 8 Stream - 并行执行 - 不同的结果 - 为什么?

    假设我有一个List
  • SLURM 节点、任务、核心和 CPU

    有人能够澄清这些东西到底是什么吗 据我所知 节点是集群内的计算点 本质上是一台计算机 任务是可以在单个节点或多个节点上执行的进程 核心基本上是指您希望在单个节点上分配多少 CPU 来执行分配给该 CPU 的任务 它是否正确 我混淆了什么吗
  • 将 cuda 数组传递给 Thrust::inclusive_scan

    我可以对 cpu 上的数组使用包容性扫描 但是否可以对 gpu 上的数组执行此操作 注释是我知道有效但我不需要的方式 或者 是否有其他简单的方法可以对设备内存中的数组执行包含扫描 Code include

随机推荐

  • 如何为Notepad++编写宏?

    我想为 Notepad 编写一个宏 它应该分别用 char4 char5 char6 替换 char1 char2 char3 Notepad 中的宏只是一堆编码操作 您开始录制 对缓冲区进行操作 也许激活菜单 停止录制然后播放宏 经过调查
  • java中如何将日期时间转换为时间戳

    论坛会员 我在 java 中遇到一个日期时间问题 实际上我正在收到开始日期格式为 2012 02 27T01 10 10我想将收到的日期插入到具有日期时间数据类型的数据库中 实际上我尝试通过下面的代码将收到的开始日期转换为日期时间 Stri
  • Android Eclipse Lint API 检查

    谢谢 P T 看起来像是问题的正确答案在 Eclipse 中构建多 SDK Android 应用程序而不会丢失编译时检查 https stackoverflow com questions 7642249 但是 当我尝试按照建议使用 Tar
  • 读取 spacy 中的文本文件语料库

    我看到的使用 spacy 的所有示例都只是在单个文本文件 尺寸很小 中读取 如何将文本文件语料库加载到 spacy 中 我可以通过腌制语料库中的所有文本来使用 textacy 来做到这一点 docs textacy io spacy rea
  • Azure Blob、文件和磁盘存储

    快问 我已经阅读了大量有关 azure blob 文件 磁盘存储选项的信息 并且我有一个如此简单的存储要求 以至于我对最佳选择感到困惑 我正在阅读的大部分信息都完全超出了我的理解范围 我希望有人能够将视野缩小到更合理的优点 缺点 我的情况如
  • 快速排序与堆排序

    快速排序和堆排序都进行就地排序 哪个更好 首选哪种应用和案例 堆排序是 O N log N 保证的 这比快速排序中最坏的情况要好得多 堆排序不需要更多内存来让另一个数组像合并排序那样放置有序数据 那么为什么商业应用程序坚持使用快速排序呢 与
  • update_or_create 与 ManyToManyField

    我有 2 个模型 如下所示 class Subs models Model tag models CharField max length 100 class Users models Model name models CharField
  • ReactforwardRef 含义

    我不明白这有什么意义 const FancyButton React forwardRef props ref gt
  • 如何使用 ffmpeg 批量/顺序下载 m3u8 文件?

    我目前在 Mac 上使用以下命令单独下载 m38u 播放列表 ffmpeg i lt URL with m3u8 gt codec copy output ts 如果我想处理多个文件 我目前可以通过单独的终端窗口进行操作 我想做的是 在一个
  • Python 使用正则表达式替换

    例如 有谁知道如何将所有出现的 lt 20 应该转化为 r n lt 20 but gt HELLO lt asassdsa 应该保持不变 gt gt gt import re gt gt gt str lt 20 gt gt gt out
  • Angular Elements 和 Stencil 的技术概念

    技术概念是角元素 and Stencil相似的 角元素将是 Angular 6 中的一个新功能 您基本上可以将编写的 Angular 组件包装为 Web 组件 根据我的理解 生成的自定义元素只是通往 Angular 的桥梁 因此我们仍然必须
  • Maven 使用 git 发布插件,如果在处理过程中推送提交,则会出现错误

    我们使用 git 存储库和 Maven 发布插件 在第一个构建步骤中 我们将所有更改提取到本地存储库 然后在下一个构建步骤中运行mvn release prepare release perform release prepare更新工作区
  • 如何以编程方式修改 Open/Libreoffice odt 文档?

    我想在我的应用程序中使用 OO LO PDF 生成功能 为此 我需要能够从代码中修改之前生成的 odt 模板 修改只是简单的文本替换 甚至不需要正则表达式 OO 开发者指南 https wiki openoffice org wiki Do
  • TypeError:“Tensor”对象不支持 TensorFlow 中的项目分配

    我尝试运行这段代码 outputs states rnn rnn lstm cell x initial state initial state sequence length real length tensor shape output
  • 在 ORMLite 中为一个类创建多个表

    我在 Android 上使用 ORMLite 并有以下问题 是否可以基于单个 Java 类创建多个表 这些表应该仅在名称上有所不同 并且应该通过名称访问它们 例如 如果我有一堂课 public class Order DatabaseFie
  • 标签和文本块之间的区别

    根据训练套件 两者有什么区别Label控制和TextBlock控制 因为两者都是内容控件并且只显示文本 TextBlock 不是控件 虽然TextBlock位于 System Windows Controls 命名空间中 它不是一个控件 它
  • scipy.io:无法写入 wavfile

    我在将 2d numpy 数组写入波形文件 音频 时遇到问题 根据文档我应该写一个 2d int16 numpy 数组 https docs scipy org doc scipy 0 18 1 reference generated sc
  • 使用 PHP 进行树形图可视化?

    除了 PHP 之外 几乎所有语言似乎都有 TreeMap 的示例 有人有一些基本代码的链接吗 http www neurofuzzy net 2006 04 28 treemap php source code http www neuro
  • 向 DOM Element 对象添加属性有什么问题?

    我一直在寻找一个直接的答案 我可以想到很多可能性 但我想知道真正的原因 jQuery 提供了 data 方法来将数据与 DOM Element 对象关联起来 是什么使得这有必要 直接向 DOM 元素对象添加属性 或方法 是否存在问题 它是什
  • 使用 CUDA 并行实现多个 SVD

    我是使用 GPU 并行编程的新手 因此如果问题广泛或模糊 我深表歉意 我知道 CULA 库中有一些并行 SVD 函数 但是如果我有大量相对较小的矩阵需要分解 应该采取什么策略 例如我有n有维数的矩阵d n很大并且d是小 如何并行化这个过程