Ошибка компиляции проекта cuda

У меня возникли проблемы с компиляцией проекта cuda с помощью C Cuda и библиотек lodepng.

Мой makefile выглядит так.

gpu:    super-resolution.cu
    gcc -g -O -c lodepng.c
    nvcc -c super-resolution.cu
    nvcc -o super-resolution-cuda super-resolution.o 
    rm -rf super-resolution.o
    rm -rf lodepng.o

Может ли кто-нибудь сказать мне, что я делаю неправильно, потому что он жалуется на

nvcc warning : The 'compute_10' and 'sm_10' architectures are deprecated, and may be removed in a future release.
super-resolution.o: In function `main':
parallel-algorithm/super-resolution.cu:238: undefined reference to `lodepng_decode32_file(unsigned char**, unsigned int*, unsigned int*, char const*)'
parallel-algorithm/super-resolution.cu:259: undefined reference to `lodepng_encode32_file(char const*, unsigned char const*, unsigned int, unsigned int)'
parallel-algorithm/super-resolution.cu:269: undefined reference to `lodepng_encode32_file(char const*, unsigned char const*, unsigned int, unsigned int)'
parallel-algorithm/super-resolution.cu:282: undefined reference to `lodepng_encode32_file(char const*, unsigned char const*, unsigned int, unsigned int)'
parallel-algorithm/super-resolution.cu:292: undefined reference to `lodepng_encode32_file(char const*, unsigned char const*, unsigned int, unsigned int)'
parallel-algorithm/super-resolution.cu:301: undefined reference to `lodepng_encode32_file(char const*, unsigned char const*, unsigned int, unsigned int)'
...

Мне просто нужен способ скомпилировать мой файл .cu и добавить в него файл C .o во время процесса компиляции с использованием nvcc.

РЕДАКТИРОВАТЬ: попробовал предложение. нет успеха.

gcc -g -O -c lodepng.c
nvcc -c super-resolution.cu
nvcc warning : The 'compute_10' and 'sm_10' architectures are deprecated, and may be removed in a future release.
super-resolution.cu:1:2: warning: #import is a deprecated GCC extension [-Wdeprecated]
 #import "cuda.h"
  ^
super-resolution.cu(106): warning: expression has no effect

super-resolution.cu(116): warning: expression has no effect

super-resolution.cu(141): warning: variable "y" was declared but never referenced

super-resolution.cu:1:2: warning: #import is a deprecated GCC extension [-Wdeprecated]
 #import "cuda.h"
  ^
super-resolution.cu(106): warning: expression has no effect

super-resolution.cu(116): warning: expression has no effect

super-resolution.cu(141): warning: variable "y" was declared but never referenced

ptxas /tmp/tmpxft_00000851_00000000-5_super-resolution.ptx, line 197; warning : Double is not supported. Demoting to float
nvcc -o super-resolution-cuda super-resolution.o lodepng.o

nvcc warning : The 'compute_10' and 'sm_10' architectures are deprecated, and may be removed in a future release.
super-resolution.o: In function `main':
tmpxft_00000851_00000000-3_super-resolution.cudafe1.cpp:(.text+0x5d): undefined reference to `lodepng_decode32_file(unsigned char**, unsigned int*, unsigned int*, char const*)'

Он по-прежнему не может найти ссылку на объектный файл. Редактировать: вот наш файл .cu.

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

extern "C" unsigned lodepng_encode32_file(const char* ,const unsigned char* , unsigned , unsigned h);
extern "C" unsigned lodepng_decode32_file(unsigned char** , unsigned* , unsigned* ,const char* );

person user2467731    schedule 24.04.2014    source источник
comment
Вы связываетесь с nvcc, но не включаете объект, который вы создали с помощью gcc (lodepng.o). попробуйте nvcc -o super-resolution-cuda super-resolution.o lodepng.o вместо существующего шага ссылки nvcc -o super-resolution-cuda super-resolution.o.   -  person Robert Crovella    schedule 24.04.2014
comment
так что ссылка lodepng_encode32_file разобралась, а ссылка lodepng_decode32_file нет? Вероятно, потребуется увидеть точный код, чтобы понять, почему и правильно ли вы выполняете компоновку C/C++ (например, extern C и т. д.). Вы уверены, что и lodepng_encode32_file, и lodepng_decode32_file экспортируются и используются одинаково?   -  person Robert Crovella    schedule 25.04.2014
comment
Шутки в сторону? Вы публикуете эти обновления в комментариях? Как насчет соответствующих функций в lodepng? Совпадают ли их прототипы? Я не уверен, что на этот вопрос можно ответить небольшими фрагментами. Создайте полный, короткий, компилируемый случай в вопросе, который демонстрирует проблему. Да, вам нужно будет существенно отредактировать ваши файлы, это потребует усилий с вашей стороны. Но не должно быть сложно отредактировать 2 файла до критических фрагментов, демонстрирующих проблему.   -  person Robert Crovella    schedule 25.04.2014


Ответы (2)


  1. не #import. Если вы хотите включить cuda.h (в этом нет необходимости), используйте #include. Вместо этого я бы просто удалил эту строку из вашего файла super-resolution.cu.
  2. Что вы раньше не показывали, но теперь очевидно, так это то, что в super-resolution.cu вы включаете lodepng.h и также позднее указываете C-связь для двух функций: lodepng_decode32_file и lodepng_encode32_file. Когда я попытался скомпилировать ваш super-resolution.cu, компилятор выдал мне такие ошибки (не знаю, почему вы их не видите):

    super-resolution.cu(8): error: linkage specification is incompatible with previous "lodepng_encode32_file"
    lodepng.h(184): here
    
    super-resolution.cu(9): error: linkage specification is incompatible with previous "lodepng_decode32_file"
    lodepng.h(134): here
    

    Так что в основном вы спотыкаетесь о связи C и C++.

  3. Я считаю, что самое простое решение - использовать lodepng.cpp (вместо lodepng.c), удалить следующие строки из вашего super-resolution.cu:

    extern "C" unsigned lodepng_encode32_file(const char* ,const unsigned char* , unsigned , unsigned h);
    extern "C" unsigned lodepng_decode32_file(unsigned char** , unsigned* , unsigned* ,const char* );
    

    И просто скомпилируйте все и слинкуйте все в стиле С++:

    $ g++ -c lodepng.cpp
    $ nvcc -c super-resolution.cu
    nvcc warning : The 'compute_10' and 'sm_10' architectures are deprecated, and may be removed in a future release.
    $ nvcc -o super-resolution super-resolution.o lodepng.o
    nvcc warning : The 'compute_10' and 'sm_10' architectures are deprecated, and may be removed in a future release.
    $
    
  4. Если вы действительно хотите связать lodepng.o c-стиль вместо стиля c++, вам нужно будет изменить lodepng.h с соответствующими оболочками extern "C", где вызываются необходимые функции. На мой взгляд, это становится грязным.

  5. Если вы хотите избавиться от предупреждений о sm_10, добавьте переключатель nvcc для компиляции для другой архитектуры, например:

    nvcc -arch=sm_20 ...
    

    но убедитесь, что все, что вы выберете, совместимо с вашим графическим процессором.

person Robert Crovella    schedule 24.04.2014
comment
Вам не нужно переходить на lodepng.cpp, если код был C, вам следует использовать компилятор C. Просто нужно исправить спецификацию связи. - person M.M; 25.04.2014

Вот простой фрагмент кода.

Библиотеку lodepng можно получить отсюда (http://lodev.org/lodepng/).

Если переименовать его в C, его можно будет использовать на C.

Даже на этом уровне возникают проблемы с компиляцией

"undefined reference to `lodepng_decode32_file'"
"undefined reference to `lodepng_encode32_file'"

Файл: Makefile

all:    gpu
    gcc -g -O -c lodepng.c
    nvcc -c super-resolution.cu
    nvcc -o super-resolution-cuda super-resolution.o lodepng.o
    rm -rf super-resolution.o
    rm -rf lodepng.o

Файл: super-resolution.cu

#import "cuda.h"
#include "lodepng.h"

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

extern "C" unsigned lodepng_encode32_file(const char* ,const unsigned char* , unsigned , unsigned h);
extern "C" unsigned lodepng_decode32_file(unsigned char** , unsigned* , unsigned* ,const char* );

//GPU 3x3 Blur.
__global__ void gpuBlur(unsigned char* image, unsigned char* buffer, int width, int height)
{
    int i = threadIdx.x%width;
    int j = threadIdx.x/width;
    if (i == 0 || j == 0 || i == width - 1 || j == height - 1)
        return;

    int k;
    for (k = 0; k <= 4; k++)
    {
        buffer[4*width*j + 4*i + k] =           (image[4*width*(j-1) + 4*(i-1) + k] +
                                image[4*width*(j-1) + 4*i + k] +
                                image[4*width*(j-1) + 4*(i+1) + k] +
                                image[4*width*j + 4*(i-1) + k] +
                                image[4*width*j + 4*i + k] +
                                image[4*width*j + 4*(i+1) + k] +
                                image[4*width*(j+1) + 4*(i-1) + k] +
                                image[4*width*(j+1) + 4*i + k] +
                                image[4*width*(j+1) + 4*(i+1) + k])/9;
    }
}

int main(int argc, char *argv[])
{
    //Items for image processing;
    //int threshold = 100;
    unsigned int error;
    unsigned char* image;
    unsigned int width, height;

    //Load the image;
    if (argc > 1)
    {
        error = lodepng_decode32_file(&image, &width, &height, argv[1]);
        printf("Loaded file: %s[%d]\n", argv[1], error);
    }
    else
    {

        return 0;
    }

    unsigned char* buffer =(unsigned char*)malloc(sizeof(char) * 4*width*height);

    //GPU Blur Section.
    unsigned char* image_gpu;
    unsigned char* blur_gpu;
    cudaMalloc( (void**) &image_gpu, sizeof(char) * 4*width*height);
    cudaMalloc( (void**) &blur_gpu, sizeof(char) * 4*width*height);
    cudaMemcpy(image_gpu,image, sizeof(char) * 4*width*height, cudaMemcpyHostToDevice);
    cudaMemcpy(blur_gpu,image, sizeof(char) * 4*width*height, cudaMemcpyHostToDevice);
    gpuBlur<<< 1, height*width >>> (image_gpu, blur_gpu, width, height);
    cudaMemcpy(buffer, blur_gpu, sizeof(char) * 4*width*height, cudaMemcpyDeviceToHost);
    //Spit out buffer as an image.
    error = lodepng_encode32_file("GPU_OUTPUT1_Blur.png", buffer, width, height);
    cudaFree(image_gpu);
    cudaFree(blur_gpu);

    free(buffer);
    free(image);

}
person user2467731    schedule 24.04.2014
comment
Лучше отредактировать этот тип материала в своем вопросе. Не публикуйте ответ на SO, если вы действительно не отвечаете на вопрос (даже если это ваш собственный вопрос). - person Robert Crovella; 25.04.2014