- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用 CUDA 10.1 解决大约 1200000 个线性系统(3x3,Ax=B),特别是使用 CUBLAS 库。我从 this (useful!) post 那里得到了提示并在统一内存版本中重新编写了建议的代码。该算法首先使用 cublasgetrfBatched() 执行 LU 分解,然后连续两次调用 cublastrsm() 求解上三角线性系统或下三角线性系统。代码附在下面。它最多可以正确处理大约 10000 个矩阵,在这种情况下,执行 LU 分解需要约 570 毫秒(在 NVIDIA GeForce 930MX 上),求解系统需要约 311 毫秒。
我的问题/问题是:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <vector>
#include <ctime>
#include <ratio>
#include <chrono>
#include <random>
#include <time.h>
#include <math.h>
// CUDA
#include <cuda.h>
#include <cuda_runtime.h>
#include "device_launch_parameters.h"
#include <cusolverDn.h>
//#include "Utilities.cuh"
using namespace std;
using namespace std::chrono;
/************************************/
/* COEFFICIENT REARRANGING FUNCTION */
/************************************/
void rearrange(double** vec, int* pivotArray, int N, int numMatrices) {
for (int nm = 0; nm < numMatrices; nm++) {
for (int i = 0; i < N; i++) {
double temp = vec[nm][i];
vec[nm][i] = vec[nm][pivotArray[N*i + nm] - 1];
vec[nm][pivotArray[N * i + nm] - 1] = temp;
}
}
}
/************************************/
/* MAIN */
/************************************/
int main() {
const int N = 3;
const int numMatrices = 10000; // I want 1200000
// random generator to fill matrices and coefficients
random_device device;
mt19937 generator(device());
uniform_real_distribution<double> distribution(1., 5.);
//ALLOCATE MEMORY - using unified memory
double** h_A;
cudaMallocManaged(&h_A, sizeof(double*) * numMatrices);
for (int nm = 0; nm < numMatrices; nm++) {
cudaMallocManaged(&(h_A[nm]), sizeof(double) * N * N);
}
double** h_b;
cudaMallocManaged(&h_b, sizeof(double*) * numMatrices);
for (int nm = 0; nm < numMatrices; nm++) {
cudaMallocManaged(&(h_b[nm]), sizeof(double) * N );
}
cout << " memory allocated" << endl;
// FILL MATRICES
for (int nm = 0; nm < numMatrices; nm++) {
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
h_A[nm][j * N + i] = distribution(generator);
}
}
}
cout << " Matrix filled " << endl;
// FILL COEFFICIENTS
for (int nm = 0; nm < numMatrices; nm++) {
for (int i = 0; i < N; i++) {
h_b[nm][i] = distribution(generator);
}
}
cout << " Coeff. vector filled " << endl;
cout << endl;
// --- CUDA solver initialization
cublasHandle_t cublas_handle;
cublasCreate_v2(&cublas_handle);
int* PivotArray;
cudaMallocManaged(&PivotArray, N * numMatrices * sizeof(int));
int* infoArray;
cudaMallocManaged(&infoArray, numMatrices * sizeof(int));
//CUBLAS LU SOLVER
high_resolution_clock::time_point t1 = high_resolution_clock::now();
cublasDgetrfBatched(cublas_handle, N, h_A, N, PivotArray, infoArray, numMatrices);
cudaDeviceSynchronize();
high_resolution_clock::time_point t2 = high_resolution_clock::now();
duration<double> time_span = duration_cast<duration<double>>(t2 - t1);
cout << "It took " << time_span.count() * 1000. << " milliseconds." << endl;
for (int i = 0; i < numMatrices; i++)
if (infoArray[i] != 0) {
fprintf(stderr, "Factorization of matrix %d Failed: Matrix may be singular\n", i);
}
// rearrange coefficient
// (temporarily on CPU, this step will be on a GPU Kernel as well)
high_resolution_clock::time_point tA = high_resolution_clock::now();
rearrange(h_b, PivotArray, N, numMatrices);
high_resolution_clock::time_point tB = high_resolution_clock::now();
duration<double> time_spanA = duration_cast<duration<double>>(tB - tA);
cout << "rearrangement took " << time_spanA.count() * 1000. << " milliseconds." << endl;
//INVERT UPPER AND LOWER TRIANGULAR MATRICES
// --- Function solves the triangular linear system with multiple right-hand sides
// --- Function overrides b as a result
const double alpha = 1.f;
high_resolution_clock::time_point t3 = high_resolution_clock::now();
cublasDtrsmBatched(cublas_handle, CUBLAS_SIDE_LEFT, CUBLAS_FILL_MODE_LOWER, CUBLAS_OP_N, CUBLAS_DIAG_UNIT, N, 1, &alpha, h_A, N, h_b, N, numMatrices);
cublasDtrsmBatched(cublas_handle, CUBLAS_SIDE_LEFT, CUBLAS_FILL_MODE_UPPER, CUBLAS_OP_N, CUBLAS_DIAG_NON_UNIT, N, 1, &alpha, h_A, N, h_b, N, numMatrices);
cudaDeviceSynchronize();
high_resolution_clock::time_point t4 = high_resolution_clock::now();
duration<double> time_span2 = duration_cast<duration<double>>(t4 - t3);
cout << "second step took " << time_span2.count() * 1000. << " milliseconds." << endl;
// --- Free resources
if (h_A) cudaFree(h_A);
if (h_b) cudaFree(h_b);
cudaDeviceReset();
return 0;
}
最佳答案
Overload issue: it crashes allocating memory for more than 10k matrices. Why? How can I improve my code in order to solve the whole batch of 1.2 million matrices?
//ALLOCATE MEMORY - using unified memory
double** h_A;
cudaMallocManaged(&h_A, sizeof(double*) * numMatrices);
for (int nm = 0; nm < numMatrices; nm++) {
cudaMallocManaged(&(h_A[nm]), sizeof(double) * N * N);
}
double** h_b;
cudaMallocManaged(&h_b, sizeof(double*) * numMatrices);
for (int nm = 0; nm < numMatrices; nm++) {
cudaMallocManaged(&(h_b[nm]), sizeof(double) * N );
}
问题是每次调用
cudaMallocManaged
具有最小粒度。这意味着如果你请求分配 1 个字节,它实际上会占用大约 4kbyte 的内存(我相信这是 linux 分配粒度。看起来你在 windows 上,我相信 windows 分配粒度可能更大) .此外,当您启动内核时,这会在托管内存子系统上造成巨大的低效数据传输负载(内核将在您的
cublas
调用中启动)。
//ALLOCATE MEMORY - using unified memory
double** h_A;
cudaMallocManaged(&h_A, sizeof(double*) * numMatrices);
cudaMallocManaged(&(h_A[0]), sizeof(double)*numMatrices*N*N);
for (int nm = 1; nm < numMatrices; nm++) {
h_A[nm] = h_A[nm-1]+ N * N;
}
double** h_b;
cudaMallocManaged(&h_b, sizeof(double*) * numMatrices);
cudaMallocManaged(&(h_b[0]), sizeof(double) * numMatrices * N);
for (int nm = 1; nm < numMatrices; nm++) {
h_b[nm] = h_b[nm-1] + N;
}
这样做的另一个好处是分配过程运行得相当快。
Time issue: my goal would be to solve all of these systems in less than 1 second. Am I currently following the correct approach? Any suggestions otherwise?
const int numMatrices = 1200000;
输出如下:
$ ./t81
memory allocated
Matrix filled
Coeff. vector filled
It took 70.3032 milliseconds.
rearrangement took 60.02 milliseconds.
second step took 156.067 milliseconds.
你的 GPU 可能有点慢,但我认为整体时间应该很容易在不到 1 秒的时间内进入。
Would it be possible and/or useful, and if yes how, to use 'streams' of batches of 10k matrices?
关于c++ - CUDA-CUBLAS : issues solving many (3x3) dense linear systems,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64664431/
为什么 get_weights() 返回的权重值与实际权重不同?我认为初始化后这两种方法应该显示相同的权重。 import tensorflow as tf import os sess = tf.S
我正在尝试使用 Keras。 当我尝试以下代码时: from keras.layers import Dense 我收到以下错误: Traceback (most recent call last):
我正在构建一个模型,该模型使用循环层 (GRU) 将一个字符串转换为另一个字符串。我尝试过使用 Dense 层和 TimeDistributed(Dense) 层作为最后一层,但我不明白使用 retu
this question of mine 的答案让我期望 Eigen 中的产品(对于具有 1/4 非消失条目的矩阵)稠密矩阵 * 稠密 vector 应该跑赢稀疏矩阵*密集 vector 。 我不仅
我正在尝试为上下文强盗问题 (https://medium.com/emergent-future/simple-reinforcement-learning-with-tensorflow-part
from keras import layers from keras import models model = models.Sequential() model.add(layers.Conv2
我目前正在学习深度学习和Keras。当我执行此代码时,我收到奇怪的错误:“TypeError:无法使用非浮点dtype构建Dense层”,我无法找出问题所在。我想念什么?如何解决这个奇怪的错误? 错误
我正在处理 pandas 数据框并且有一个像这样的框架: Year Value 2012 10 2013 20 2013 25 2014 30 我想做一个等同于 DENSE_RANK ()
我在 Tensorflow 中有一个网络,我想定义一个函数,通过 tf.layers.dense 层(显然是同一层)传递它的输入。我看到了 reuse 参数,但为了正确使用它,我似乎需要保留一个全局变
在转换自定义 tensorflow 图时,我看到与将密集层从 pb 格式转换为 DLC 格式有关的错误: 2017-11-02 13:43:35,260 - 305 - WARNING - WARNI
我需要在稀疏矩阵上使用线性回归。我的结果一直很差,所以我决定在一个稀疏表示的非稀疏矩阵上测试它。数据取自https://www.analyticsvidhya.com/blog/2021/05/mul
这个问题已经有答案了: How to pivot Spark DataFrame? (10 个回答) 已关闭 6 年前。 我有一个数据框,如下所示: item_id week_id sale am
我正在尝试为序数回归创建一个模型,正如这个 paper 所解释的那样.它的主要部分是在最后一层共享权重,而不是为了获得秩单调性的偏差(基本上确保 P[Y>N] 必须始终大于 P[Y>N-1] 对于任何
我有一个简单的序列模型,使用 TimeDistributed(Dense...) 作为 LSTM 层之后的最后一层。我正在以 20 个时间步长的顺序训练时间序列数据。损失函数是Mean Absolut
我有点误解如何为我的数据创建一个简单的序列。 数据具有以下维度: X_train.shape (2369, 12) y_train.shape (2369,) X_test.shape (592, 1
这个问题在这里已经有了答案: CSS-only masonry layout (4 个答案) 关闭 4 年前。 您可以这样想,因为我们在 Facebook 上上传了多张图片(可能尺寸不同),它们在新
我正在制作一个解决回归问题的 DNN。 首先我加载了一个预训练的 VGG16 网络,然后我制作了几个完全连接的隐藏层。最后一层有一个输出标量的节点。 我认为输出的形状应该类似于 [batch_size
在 tensorflow layers.dense(inputs, units, activation) 中实现了一个具有任意激活函数的多层感知器层。 输出=激活(matmul(输入,权重)+偏差)
如果我只使用这样的单层: layer = tf.layers.dense(tf_x, 1, tf.nn.relu) 这只是具有单个节点的单层吗? 或者它实际上是一组只有一个节点的层(输入层、隐藏层、输
池化层定义在tensorflow/python/layers/pooling.py. 有最大值池化和均值池化。 1、tf.layers.max_pooling2d
我是一名优秀的程序员,十分优秀!