Глобальная функция CUDA, неправильно добавляющая значения массива для некоторых индексов - PullRequest
0 голосов
/ 13 октября 2019

Я работаю с этим видеоуроком CUDA на Youtube. Код предоставлен во второй половине видео. Это простая программа CUDA для добавления элементов двух массивов. Поэтому, если бы у нас был первый массив с именем a и второй с именем b, конечное значение a[i] было бы:

a[i] += b[i];

Проблема в том, что бы я ни делал. Первые четыре элемента окончательного вывода всегда причудливые числа. Программа создает случайные входные данные для массивов от 0 до 1000. Это означает, что конечное выходное значение для каждого индекса должно быть в диапазоне от нуля до 2000. Однако, независимо от случайного начального числа, программа всегда выводит комбинацию абсурдно больших (издиапазон) числа или нули для первых четырех результатов.

Для индексов, превышающих 3, выходные данные, похоже, найдены. Вот мой код:

#include <iostream>
#include <cuda.h>
#include <stdlib.h>
#include <ctime>

using namespace std;

__global__ void AddInts( int *a, int *b, int count){
  int id = blockIdx.x * blockDim.x +threadIdx.x;
  if (id < count){
    a[id] += b[id];
  }
}

int main(){
  srand(time(NULL));
  int count = 100;
  int *h_a = new int[count];
  int *h_b = new int[count];

  for (int i = 0; i < count; i++){ // Populating array with 100 random values
    h_a[i] = rand() % 1000; // elements in range 0 to 1000
    h_b[i] = rand() % 1000;
  }

  cout << "Prior to addition:" << endl;
  for (int i =0; i < 10; i++){ // Print out the first five of each
    cout << h_a[i] << " " << h_b[i] << endl;
  }

  int *d_a, *d_b; //device copies of those arrays

  if(cudaMalloc(&d_a, sizeof(int) * count) != cudaSuccess) // malloc for cudaMemcpyDeviceToHost
  {
    cout<<"Nope!";
    return -1;
  }
  if(cudaMalloc(&d_b, sizeof(int) * count) != cudaSuccess)
  {
    cout<<"Nope!";
    cudaFree(d_a);
    return -2;
  }

  if(cudaMemcpy(d_a, h_a, sizeof(int) * count, cudaMemcpyHostToDevice) != cudaSuccess)
  {
    cout << "Could not copy!" << endl;
    cudaFree(d_a);
    cudaFree(d_b);
    return -3;
  }
  if(cudaMemcpy(d_b, h_b, sizeof(int) * count, cudaMemcpyHostToDevice) != cudaSuccess)
  {
    cout << "Could not copy!" << endl;
    cudaFree(d_b);
    cudaFree(d_a);
    return -4;
  }

  AddInts<<<count / 256 +1, 256>>>(d_a, d_b, count);

  if(cudaMemcpy(h_a, d_a, sizeof(int) * count, cudaMemcpyDeviceToHost)!= cudaSuccess)   //magic of int division
  { // copy from device back to host
    delete[]h_a;
    delete[]h_b;
    cudaFree(d_a);
    cudaFree(d_b);
    cout << "Error: Copy data back to host failed" << endl;
    return -5;
  }
  delete[]h_a;
  delete[]h_b;
  cudaFree(d_a);
  cudaFree(d_b);

  for(int i = 0; i < 10; i++){
    cout<< "It's " << h_a[i] << endl;
  }

  return 0;
}

Я скомпилировал с:

nvcc threads_blocks_grids.cu -o threads

Результат nvcc -version:

nvcc: NVIDIA (R) Cuda compiler driver
Copyright (c) 2005-2015 NVIDIA Corporation
Built on Tue_Aug_11_14:27:32_CDT_2015
Cuda compilation tools, release 7.5, V7.5.17

И вот мой вывод:

Prior to addition:
771 177
312 257
303 5
291 819
735 359
538 404
718 300
540 943
598 456
619 180
It's 42984048
It's 0
It's 42992112
It's 0
It's 1094
It's 942
It's 1018
It's 1483
It's 1054
It's 799

1 Ответ

1 голос
/ 13 октября 2019

Вы удалили массивы хостов перед печатью. Это имеет неопределенное поведение , если вы используете <= C ++ 11, и поведение, определенное реализацией для> C ++ 11.

Если вы перемещаете часть печати вверх, это должно быть решено.

...