- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我是使用 GPU 进行并行编程的新手,所以如果问题很宽泛或模糊,我深表歉意。我知道 CULA 库中有一些并行的 SVD 函数,但是如果我有大量相对较小的矩阵要分解,应该采用什么策略?例如我有 n
具有维度的矩阵 d
, n
大和d
是小。如何并行化这个过程?谁能给我一个提示?
最佳答案
我之前的回答现在已经过时了。截至 2015 年 2 月,CUDA 7(目前为候选版本)在其 cuSOLVER 库中提供完整的 SVD 功能。下面,我提供了一个使用 CUDA cuSOLVER 生成奇异值分解的示例。
关于您提出的具体问题(计算几个小矩阵的 SVD),您应该使用流来调整我在下面提供的示例。要将流与您可以使用的每个任务相关联
cudaStreamCreate()
cusolverDnSetStream()
#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;
}
#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
#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__); }
关于cuda - 使用 CUDA 并行实现多个 SVD,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17401765/
SciPy 和 Numpy 都内置了奇异值分解 (SVD) 函数。命令基本上是 scipy.linalg.svd 和 numpy.linalg.svd。这两者有什么区别?它们中的任何一个都比另一个更好
numpy.linalg.svd 函数给出输入矩阵的完整 svd。但是我只想要第一个奇异向量。 我想知道在 numpy 中是否有任何函数用于那个或 python 中的任何其他库? 最佳答案 一种可能是
代码: import numpy from matplotlib.mlab import PCA file_name = "store1_pca_matrix.txt" ori_data = nump
我在学习SVD通过关注这个 MIT course . 矩阵构造为 C = np.matrix([[5,5],[-1,7]]) C matrix([[ 5, 5], [-1, 7]]
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 9
我想计算 SVD ,但我没有找到合适的 java 库。现在,我在 hashmap 中存储了数据,因为矩阵不适合内存,因为大小约为 400 000 X 10 000 并且大多数为 0。我尝试了 MTJ、
运行以下代码: from sklearn.decomposition import TruncatedSVD import numpy as np X = np.matrix('1 2 3 4 5;
给定一个实数矩阵 A 使得: A 是对称的 所有非对角线项都是已知且正的 所有对角线项都缺失 排名k 我想找到 A 的最佳可能完成,称为 Ac,这样(大约)rank(Ac)=k。 矩阵 A 可能很大(
我正在寻找一个执行维基百科中描述的奇异值分解的 Java 库:从矩阵 A (m X n) 得到 A = U*S*V' 其中 U 是 m x m,S 是 m x n,V 是n x n. 谁能帮帮我? 请
我正在尝试学习用于图像处理的 SVD...例如压缩。 我的方法:使用 ImageIO 获取图像作为 BufferedImage...获取 RGB 值并使用它们获取等效的灰度值(在 0-255 范围内)
我必须在 Matlab 中使用 SVD 来获得数据的简化版本。我读到函数 svds(X,k) 执行 SVD 并返回前 k 个特征值和特征向量。如果必须规范化数据,文档中没有提及。对于归一化,我指的是减
我已经使用 SVD 找到了两组点之间的旋转矩阵。我知道 R = Transpose(U) * V 但我不明白 U 和 V 代表什么以及为什么这种乘法会产生旋转矩阵。 最佳答案 由于您的问题是理论性的并
我正在尝试在名为“LSA 简介”的论文中复制一个示例: An introduction to LSA 在示例中,它们具有以下术语-文档矩阵: 然后他们应用 SVD 并得到以下结果: 试图复制这一点,我
我正在使用带有 R 的 SVD 包,我能够通过将最低奇异值替换为 0 来降低矩阵的维数。但是当我重新组合矩阵时,我仍然拥有相同数量的特征,我找不到如何有效地删除源矩阵中最无用的特征,以减少其列数。 例
我想编写一个函数,它使用 SVD 分解来求解方程组 ax=b,其中 a 是一个方阵,b 是一个值向量。 scipy 函数 scipy.linalg.svd() 应该将 a 转换为矩阵 U W V。对于
我在 R 中有一个稀疏矩阵,它显然太大了,无法在其上运行 as.matrix()(尽管它也不是 super 大)。有问题的 as.matrix() 调用位于 svd() 函数内部,所以我想知道是否有人
我正在尝试使用 bcv 包中的 SVD 插补,但所有插补值都是相同的(按列)。 这是缺少数据的数据集 http://pastebin.com/YS9qaUPs #load data dataMiss
我有这个数组 double a[][] = {{1,1,1}, {0,1,1} , { 1,0,0} ,{0,1,0},{1,0,0},{1,0,1},{1,1,1},{1,1,1},
我们现在知道A_(m x n) = U_(m x k) * S_(k x k) * V_(k x n)^T = u_(1) * s_1 * v_(1) + u_(2) * s_2 * v_(2) +
我必须对矩阵进行 SVD,但它有一些错误,在下面的示例中 U[1][1]、U[2][1] 和 U[2][0] 应为 0。 问题是,上面的例子只是一个测试,我必须使用条件不太好的大型矩阵,我该怎么做才能
我是一名优秀的程序员,十分优秀!