【问题标题】:CUDA fails to run / copy memoryCUDA 无法运行/复制内存
【发布时间】:2016-08-07 20:02:21
【问题描述】:

我正在编写一个程序来并行执行多个集成副本,以加快对 50000 个不同输入的评估。代码通常需要大约 0.0005 秒才能在单个 CPU 内核上的 C++ 及其内部循环中运行我的测试运行了大约 3000 个周期,所以我认为在 gpu 线程上运行可能不会太复杂。另外,我使用 Visual Studio 2013 和 GTX 860m 编写程序,没有编译其他用 CUDA C 编写的程序。

这是我的代码:(你可以从这里获取数据文件ElCentro-import2.txt

#include <stdio.h>
#include<iostream>
#include <math.h>
#include <fstream>
#include <cmath>
#include <cuda_runtime.h>
using namespace std;
__global__ void
vectorAdd(const float *A, const float *p, float *u, float *v, float *a, float *fs, float *rhat, float *phat, int j, int numElements)
{
    int ni = blockDim.x * blockIdx.x + threadIdx.x;
    int ti = 10000 * ni;
    float t = A[ni];
    float m = 1.0f;
    float epsilon = 10.0f;
    float gamma = 0.5f;
    float beta = 1.0f / 4.0f;
    float pi = 3.14159f;
    float ksy = 0.04f;
    float dt = 0.02f;
    float fy = 1000.0f;
    float c = 4.0f * ksy * pi / t;
    float a1 = m / (beta * dt * dt) + gamma * c / (beta * dt);
    float a2 = m / (beta * dt) + c*(gamma / beta - 1.0f);
    float a3 = (1.0f / (2.0f *beta) - 1.0f)* m + dt*(gamma / (2.0f *beta) - 1.0f) *c;
    float k = m * (2.0f*pi / t)*(2.0f*pi / t);
    float fz;
    float ab;

    if (ni < numElements)
    {
    v[10000 * ni] = 0.0f;
    u[10000 * ni] = 0.0f;
    fs[10000 * ni] = 0.0f;
    a[10000 * ni] = 0.0f;

        for (size_t i = 0 + 10000 * ni; i < j-1 + 10000 * ni; i++)
        {
            u[i + 1] = u[i];
            fs[i + 1] = fs[i];
            phat[i + 1] = p[i + 1] + a1 * u[i] + a2*v[i] + a3*a[i];
            rhat[i + 1] = phat[i + 1] - fs[i + 1] - a1 * u[i + 1];
            ab = std::fabsf(rhat[i + 1]);
            while (ab >= epsilon)
            {
                u[i + 1] = u[i + 1] + rhat[i + 1] / (k + a1);
                fz = fs[i] + k*(u[i + 1] - u[i]);
                if (fz > 0.0)
                {
                    fs[i + 1] = fminf(fz, fy);
                }
                else
                {
                    fs[i + 1] = fmaxf(fz, -fy);

                }
                rhat[i + 1] = phat[i + 1] - fs[i + 1] - a1 * u[i + 1];
                ab = std::fabsf(rhat[i + 1]);
            }
            v[i + 1] = gamma*(u[i + 1] - u[i]) / beta / dt + (1.0f - gamma / beta)*v[i] + dt*(1.0f - gamma / 2.0f / beta)*a[i];
            a[i + 1] = (u[i + 1] - u[i]) / beta / dt / dt - (1.0f / beta / dt)*v[i] + (1.0f - 1.0f / 2.0f / beta)*a[i];
        }
    }
}
int
main(void)
{

    int numElements = 16;
    int kore;
    FILE* myfile;
    size_t size = numElements * sizeof(float);
    printf("[Vector addition of %d elements]\n", numElements);
    float *h_data = (float *)malloc(10000);
    float *h_datat = (float *)malloc(10000);
    myfile = fopen("ElCentro-import2.txt", "r");
    std::cout << "file is opened\n";
    kore = 0;
    while (EOF != fscanf(myfile, "%f %f \n", &h_datat[kore], &h_data[kore])) 
    {
        kore++;
    }
    std::cout << kore << "file is read\n";
    kore--;
    size_t nsize = 10000 * numElements * sizeof(float);
    float *h_A = (float *)malloc(size);
    float *h_u = (float *)malloc(nsize);
    float *h_v = (float *)malloc(nsize);
    float *h_a = (float *)malloc(nsize);
    float *h_p = (float *)malloc(nsize);

    for (int i = 0; i < kore; ++i)
    {
        h_p[i] = -10000 * h_data[i];
    }
    for (int i = 0; i < numElements; ++i)
    {
        h_A[i] = 1.0f;
    }
    float *d_A = NULL;
    err = cudaMalloc((void **)&d_A, size);
    float *d_p = NULL;
    err = cudaMalloc((void **)&d_p, nsize);
    float *d_u = NULL;
    err = cudaMalloc((void **)&d_u, nsize);
    float *d_v = NULL;
    err = cudaMalloc((void **)&d_v, nsize);
    float *d_a = NULL;
    err = cudaMalloc((void **)&d_a, nsize);
    float *d_fs = NULL;
    err = cudaMalloc((void **)&d_fs, nsize);
    float *d_rhat = NULL;
    err = cudaMalloc((void **)&d_rhat, nsize);
    float *d_phat = NULL;
    err = cudaMalloc((void **)&d_phat, nsize);
    printf("Copy input data from the host memory to the CUDA device\n");
    err = cudaMemcpy(d_A, h_A, size, cudaMemcpyHostToDevice);
    err = cudaMemcpy(d_p, h_p, nsize, cudaMemcpyHostToDevice);
    int threadsPerBlock = 1;
    int blocksPerGrid = (numElements + threadsPerBlock - 1) / threadsPerBlock;
    printf("CUDA kernel launch with %d blocks of %d threads\n", blocksPerGrid, threadsPerBlock);

    vectorAdd <<<blocksPerGrid, threadsPerBlock >>>(d_A, d_p, d_u, d_v, d_a, d_fs, d_rhat, d_phat, kore-1, numElements);
    err = cudaGetLastError();
    cudaDeviceSynchronize();

    printf("Copy output data from the CUDA device to the host memory\n");
    err = cudaMemcpy(h_u, d_u, nsize, cudaMemcpyDeviceToHost);
    }
    for (int i = 0; i < numElements; ++i)
    {
        std::cout << h_u[1000+kore * i] << "\n";;
    }


    printf("Test PASSED\n");
    err = cudaFree(d_A);
    err = cudaFree(d_p);
    err = cudaFree(d_u);
    err = cudaFree(d_v);
    err = cudaFree(d_a);
    err = cudaFree(d_fs);
    err = cudaFree(d_rhat);
    err = cudaFree(d_phat);
    free(h_A);
    free(h_p);
    free(h_u);
    free(h_v);
    free(h_a);
    free(h_data);
    free(h_datat);
    err = cudaDeviceReset();
    printf("Done\n");
    return 0;
}

我的问题是,当我尝试将结果从设备复制到主机时(比如将 d_u 复制到 h_u),它会生成我的错误检查短语:

Failed to copy vector u from device to host (error code uspecified launch failure)

此外,如果我将内核同步代码 (cudaDeviceSynchronize()) 移到内核调用之后,它还会生成有关内核启动的错误报告。我对 C++ 和 CUDA 编程很陌生,这个问题让我困惑了好几天。

这部分应该多次打印相同的值(~21.8)(对于numElements&gt;1

for (int i = 0; i < numElements; ++i)
{
    std::cout << h_u[1000+kore * i] << "\n";;
}

更新 如果我将numElements 的值设置为1,则代码运行良好,但这不是并行计算的重点。我还检查了 GPU-Z 中的 GPU 统计数据,内存利用率小于 1 MB,最大 GPU 负载小于 1%。 (发布构建)

【问题讨论】:

  • 请编辑您的问题并重新格式化您的代码。从字面上看,您发布的内容中有一半是无意义的 cmets 或空行。如果你希望别人看你的一百行代码,至少让他们的工作不那么艰巨。
  • 为什么在内核代码中使用std::fabsf?您是在 Visual Studio 中构建调试项目还是发布项目?你在什么GPU上运行这个?您是否为该 GPU 正确设置了编译目标?
  • @RobertCrovella 我猜这是一个坏习惯(std::)。不过非常感谢您指出可能的设置!

标签: c++ visual-c++ parallel-processing cuda


【解决方案1】:

我已将构建从 Debug 更改为 Release 并且程序运行良好!此外,通过增加窗口注册表 (WDDM) 中的 GPU 超时设置,此问题几乎已消除。

【讨论】:

  • 所以您遇到了 WDDM 超时。发布代码内核比调试代码内核运行得更快。调试代码内核花费了足够长的时间来触发 WDDM 超时。如果您进一步修改代码(处理更多数据),您可能会再次遇到这种情况,即使在发布模式下也是如此。
猜你喜欢
  • 2022-01-14
  • 1970-01-01
  • 1970-01-01
  • 2012-06-15
  • 1970-01-01
  • 2012-01-04
  • 2021-11-29
  • 1970-01-01
相关资源
最近更新 更多