CUDA: Не понимаю, почему эта тестовая программа, похоже, ничего не делает

#cuda

Вопрос:

У меня есть тестовая программа CUDA, которая должна инвертировать значения RGB изображения. По крайней мере, в моей системе это создает выходное изображение, но оно полностью прозрачно.

Вот CudaLodepng.cu

 #include <stdio.h>
#include <stdlib.h>

#include "lodepng.h"


__global__
void NegativeFilter(unsigned char *inputImage, unsigned char *outputImage)
{

    int r;
    int g;
    int b;
    int t;

    int threadIndex = blockDim.x * blockIdx.x   threadIdx.x;

    int pixel = threadIndex * 4;

    printf("uid = %dn", pixel);

    r = inputImage[pixel];
    g = inputImage[pixel 1];
    b = inputImage[pixel 2];
    t = inputImage[pixel 3];

    outputImage[pixel] = 255-r;
    outputImage[pixel 1] = 255-g;
    outputImage[pixel 2] = 255-b;
    outputImage[pixel 3] = t;

}


int main(int argc, char ** argv){

  unsigned int errorDecode;
  unsigned char* cpuImage;
  unsigned int width, height;
  
  char *filename = argv[1];
  char *newFilename = argv[2];

  errorDecode = lodepng_decode32_file(amp;cpuImage, amp;width, amp;height, filename);
  if(errorDecode){
    printf("error %u: %sn", errorDecode, lodepng_error_text(errorDecode));
  }
  
  int arraySize = width*height*4;
  int memorySize = arraySize * sizeof(unsigned char);
  
  unsigned char *cpuOutImage = (unsigned char*)malloc(memorySize);
  
  unsigned char* gpuInput;
  unsigned char* gpuOutput;
  
  cudaMalloc((void**)amp;gpuInput, memorySize);
  cudaMalloc((void**)amp;gpuOutput, memorySize);
  
  cudaMemcpy(gpuInput, cpuImage, memorySize, cudaMemcpyHostToDevice);
  
  NegativeFilter<<<1, width * height>>>(gpuInput, gpuOutput);
  cudaDeviceSynchronize();

  cudaMemcpy(cpuOutImage, gpuOutput, memorySize, cudaMemcpyDeviceToHost);
  
  unsigned int errorEncode = lodepng_encode32_file(newFilename, cpuOutImage, width, height);
  if(errorEncode) {
  printf("error %u: %sn", errorEncode, lodepng_error_text(errorEncode));
  }

  cudaFree(gpuInput);
  cudaFree(gpuOutput);

  free(cpuImage);
  free(cpuOutImage);

}
 

Для этого требуется несколько других файлов для компиляции: lodepng.h и lodepng.cpp .

Вы можете получить их здесь: https://github.com/lvandeve/lodepng

Наконец, для компиляции и запуска:

 nvcc CudaLodepng.cu lodepng.cpp
./a.out image.png imageout.png
 

Если вы не хотите утруждать себя загрузкой loadpng и запуском этого кода в файле, вы можете обнаружить проблему в самом коде. Я искал около часа или около того и не могу этого понять.

Я не новичок в CUDA, но прошло около 5 лет с тех пор, как я что-либо делал, так что это несколько застало меня врасплох, когда оказалось, что он ничего не делает.

(Кстати, он компилируется и работает нормально, но на выходе получается просто прозрачное изображение в моей системе. Я тестировал его с помощью тестового изображения 4×4, содержащего 4 цветных квадрата. Вы могли бы проделать то же самое с gimp. Я прикреплю тестовое изображение ниже, но я понятия не имею, будут ли данные передаваться правильно. Это 32-битный png, предположительно формат rgba.)

Посмотрите на действительно крошечное изображение здесь

ВВВВВВ

тестовое изображение

^^^^^^

Комментарии:

1. запустите свой код cuda-memcheck примерно так: cuda-memcheck ./a.out image.png imageout.png и если он сообщает о каких-либо ошибках , отредактируйте эти выходные данные в своем вопросе.

2. Никаких ошибок при проверке памяти, я понял, что не так. См.Ответ. (Это не связано с кодом.)

Ответ №1:

Совершенно не связано с приведенным выше кодом: Проблема в том, что я нахожусь на ноутбуке Linux с дискретным и встроенным графическим процессором.

 optirun ./a.out
 

требуется для выполнения кода CUDA на графическом процессоре Nvidia.

Я бы удалил этот вопрос, однако в системе Linux может быть кто-то другой с аналогичной конфигурацией, и чтение этого ответа может помешать им потратить несколько часов на то, чтобы вернуться и попытаться найти решение проблемы, которой не существует. (он же в коде)