使用nvcc -c mag_cuda.cu编译以下代码时:
//Standard Libraries
#include <iostream>
#include <math.h>
#include <vector>
//Project Specific Header
#include "mag.hpp"
__global__
void indv_B_components(int *self_coords, int pole_coords[][3], double *indv_B[][3], int No_poles, int counter_1)
{
some code......
}
//----------------------------------------------------------
//------- Function to Calculate B Field at Each Pole -------
//----------------------------------------------------------
void calc_indv_B()
{
//declare namepspace for internal variables
using namespace mag::internal;
int *ppole_coords = &pole_coords[0][0];
double *pindv_B;
int self_coords[3];
int num_threads_in_block = 256;
int num_blocks = 32*2;
cudaMallocManaged(&pindv_B, No_poles*3*sizeof(int));
//first loop to go over all poles …Run Code Online (Sandbox Code Playgroud) 我正在尝试用 Julia 编写有关 GPU 计算的教程。在演示简单的矩阵运算时,一切都很顺利,GPU 击败了单线程和多线程的等效项。
\n现在我试图提出一个更复杂的例子,涉及模拟数据的生成X和一些估计的计算\xce\xb2,而这就是事情变得奇怪的时候。无论我做什么,GPU (Nvidia RTX 2070) 模拟的性能都比其多线程 (20) 模拟性能差约 20 倍。
以下是 MRE 的一些代码:
\n# Meta-simulation constants =================================\nreplications = 10\nn = 100\np = 2\n\xce\xbc = rand(replications)\n\n# Multi-threaded simulations =================================\n\xce\xb2_par = fill(0., (p, replications))\nfunction parsim()\n Threads.@threads for r in 1:replications\n X = rand(Float16, (n, p)) .* \xce\xbc[r]; # Sample data\n \xce\xb2 = sum(X .^ 2, dims = 1); # Estimate parameters\n \xce\xb2_par[:, r] = \xce\xb2\n end\nend\n\n# GPU simulations =================================\nusing …Run Code Online (Sandbox Code Playgroud) 这是我的内核调用代码
inline void find_min_max(thrust::device_vector<Npp8u> dev_vec, Npp8u *min, Npp8u *max){
thrust::pair<thrust::device_vector<Npp8u>::iterator,thrust::device_vector<Npp8u>::iterator> tuple;
tuple = thrust::minmax_element(dev_vec.begin(),dev_vec.end());
*min = *(tuple.first);
*max = *tuple.second;
}
Run Code Online (Sandbox Code Playgroud)
我还使用map-reduce范例和简单的CPU代码,用我的原始CUDA内核实现相同的算法.作为测量的结果,我看到推力是最慢的.
为简洁起见,我使用事件来测量原始CUDA和推力代码.如果事件适用于推力基准测试,我很确定我能正确测量执行时间.
这是测量部分;
....
cudaEvent_t start, stop;
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start, 0);
thrust::device_vector<Npp8u> image_dev(imageHost, imageHost+N);
// Device vector allocation
find_min_max(image_dev,&min,&max);
cudaEventRecord(stop, 0);
cudaEventSynchronize(stop);
float elapsedTime1;
cudaEventElapsedTime(&elapsedTime1, start, stop);
cudaEventDestroy(start);
cudaEventDestroy(stop);
totalTime1 = elapsedTime1/1000
....
Run Code Online (Sandbox Code Playgroud)
我真正的问题是,除了推力中的简单minmax_element函数之外,是否还有可能采用更好的方法?
我的机器规格:这是华硕k55v笔记本电脑与GeForce 635M和i7处理器.
我想用推力计算均值和标准,我发现了这段代码.我试图使用复杂的值,我遇到了一些问题.
这是代码:
#include <thrust/device_vector.h>
#include <thrust/host_vector.h>
#include <thrust/transform_reduce.h>
#include <thrust/functional.h>
#include <thrust/extrema.h>
#include <cmath>
#include <float.h>
typedef struct
{
float re,im;
} mycomplex;
// structure used to accumulate the moments and other
// statistical properties encountered so far.
template <typename T>
struct summary_stats_data
{
T n;
T min;
T max;
T mean;
T M2;
// initialize to the identity element
void initialize()
{
n.re = mean.re = M2.re = 0;
n.im = mean.im = M2.im = 0;
min …Run Code Online (Sandbox Code Playgroud) 我需要将矩阵与其转置相乘,但我的 GPU 内存不足并出现错误消息numba.cuda.cudadrv.driver.CudaAPIError: [2] Call to cuMemAlloc results in CUDA_ERROR_OUT_OF_MEMORY
我预计矩阵的大小约为 10k 行和 100k 列,因此将其与其 trnspose 相乘将得到 10k 行和 10k 列的方阵的结果。矩阵只包含0和1。
这是我正在运行的脚本。
from numba import cuda, uint16
import numba
import numpy
import math
import time
TPB = 16
@cuda.jit()
def matmul_shared_mem(A, B, C):
sA = cuda.shared.array((TPB, TPB), dtype=uint16)
sB = cuda.shared.array((TPB, TPB), dtype=uint16)
x, y = cuda.grid(2)
tx = cuda.threadIdx.x
ty = cuda.threadIdx.y
if x >= C.shape[0] and y >= C.shape[1]:
return
tmp = 0.
for i in range(int(A.shape[1] …Run Code Online (Sandbox Code Playgroud) 我编写了两个程序来使用高斯消元计算矩阵的逆,第一个程序是在 C# 中,第二个是在 CUDA C++ 中。这两个程序遵循完全相同的程序并给出相同的最终结果。但是,当我检查中间步骤中的值时,我发现值略有不同,小于 1e-5 的相对误差。
这是两个程序的每个代码的一部分。
C#
int i, j, i1, n, y, z;
double[,] M = new double[n, n];
double[,] inv = new double[n, n];
for (i = 0; i < n; i++)
inv[i, i] = 1;
for (i = 0; i < n; i++)
{
for (j = i + 1; j < n; j++)
M[i, j] /= M[i, i];
for (j = 0; j < n; j++)
inv[i, j] /= M[i, i]; …Run Code Online (Sandbox Code Playgroud) 我尝试学习CUDA。它与 C 非常相似。我尝试在我的 GPU 中运行一些代码。但我认为它并不快,我认为这与我的代码有关。我想只有我 __global__ void func(ull* num1, ull* num2, ull* sum)在 GPU 上工作。这就是我要的。但它并不快。我该怎么办。
typedef uint64_t ull;
#define E1 1
#define E2 5000000000000000
__global__ void func(ull* num1, ull* num2, ull* sum)
{
for (ull i = *num1; i <= *num2; i++)
{
sum[0] += i;
}
}
int main()
{
ull n1 = E1;
ull n2 = E2;
ull sum = 0;
ull* d_n1;
ull* d_n2;
ull* d_sum;
cudaMalloc(&d_n1, sizeof(ull));
cudaMalloc(&d_n2, sizeof(ull));
cudaMalloc(&d_sum, sizeof(ull));
cudaMemcpy(d_n1, &n1, sizeof(ull), cudaMemcpyHostToDevice); …Run Code Online (Sandbox Code Playgroud) 使用驱动程序api可以排除在同一个应用程序中使用运行时api([1]).不幸的是,cublas,cufft等都基于运行时api.如果想要同时在cuModuleLoad和cublas中进行动态内核定义,有哪些选项?我记得这些,但也许还有更多:
A.等待计算能力3.5,传闻支持在同一个应用程序中驱动程序和运行时api的和平共存.
B.将内核编译为.so文件并将其删除.他们在dlcose上卸载了吗?
C.尝试从驱动程序api使用cuModuleLoad,但运行时api中的所有其他内容.不知道这是否有任何希望.
我没有屏住呼吸,因为jcuda或pycuda几乎是相同的绑定,他们可能已经想到了它.
电子信息处理技术
按照罗伯特的建议更改代码,但推力仍然慢得多。
我使用的数据基于两个.dat 文件,因此我在代码中省略了它。
原来的问题
我有两个复数向量已放在 GPU Tesla M6 上。我想计算两个向量的逐元素乘积,即 [x1*y1,...,xN*yN]。两个向量的长度均为 N = 720,896。
代码片段(已修改)
我用两种方法解决这个问题。一种是使用带有类型转换和特定结构的推力:
#include <cstdio>
#include <cstdlib>
#include <sys/time.h>
#include "cuda_runtime.h"
#include "cuComplex.h"
#include <thrust/host_vector.h>
#include <thrust/device_vector.h>
#include <thrust/execution_policy.h>
#include <thrust/complex.h>
#include <thrust/transform.h>
#include <thrust/functional.h>
using namespace std;
typedef thrust::complex<float> comThr;
// ---- struct for thrust ----//
struct Complex_Mul_Complex :public thrust::binary_function<comThr, comThr, comThr>
{
__host__ __device__
comThr operator() (comThr a, comThr b) const{
return a*b;
}
};
// ---- my kernel function ---- //
__global__ void HardamarProductOnDeviceCC(cuComplex …Run Code Online (Sandbox Code Playgroud) 我是nvcc的新手,我见过一个库,用g ++和nvcc选项-O3进行编译.
CC=g++
CFLAGS=--std=c++11 -O3
NVCC=nvcc
NVCCFLAGS=--std=c++11 -arch sm_20 -O3
Run Code Online (Sandbox Code Playgroud)
什么是-O3在做什么?