Ошибка сегментации с cudaMemcpy2D - PullRequest
1 голос
/ 28 октября 2011

У меня есть двумерный массив dev_histogram, сохраненный в графическом процессоре, и двумерный массив гистограммы, сохраненный в CPU.Я хочу скопировать содержимое dev_histogram в гистограмму.Ниже приведены соответствующие фрагменты моей программы.Я также могу опубликовать полный код.

int *dev_histogram; // Array for histogram, GPU
int histogram[SIZE_THETA][SIZE_RHO]; // Array for histogram, CPU

size_t pitch;
histogramSize = sizeof(int) * SIZE_THETA * SIZE_RHO;
cudaMallocPitch((void**)&dev_histogram, &pitch, SIZE_THETA * sizeof(int), SIZE_RHO)

houghTransformation << <width, height >> >(dev_edges, dev_histogram, pitch, n_pixels, width, height);

// Here I get a Segmentation fault:
cudaMemcpy2D(histogram, pitch, dev_histogram, SIZE_THETA * sizeof(int), SIZE_THETA * sizeof(int), SIZE_RHO * sizeof(int), cudaMemcpyDeviceToHost)

Не могли бы вы помочь мне понять, как копировать мою матрицу обратно?В основном меня смущает то, что нужно указывать в качестве источника моего источника.

Ответы [ 3 ]

1 голос
/ 29 октября 2011

В справочном руководстве по инструментарию CUDA вы можете видеть, что шаг в cudaMallocPitch - это выделенная ширина в байтах для 2D-массива, который вы копируете.Ваша dev_histogram будет иметь фактическую ширину, равную высоте и высоте, равную указанной вами высоте.Каждая строка вашего двумерного массива имеет выделенные байты основного тона, но только ширина * sizeof (int) байтов действительных данных.

В том же документе прототип для cudaMemcpy2D равен

cudaError_t cudaMemcpy2D (void ∗ dst, size_t dpitch, const void ∗ src, size_t spitch, size_t width, size_t height, enum cudaMemcpyKind kind)

здесьваш массив на хосте, dpitch - это ширина в байтах целевого массива (гистограмма), а spitch - это ширина в байтах исходного массива (dev_histogram).ширина и высота - это размеры вашего 2D массива.Тогда вы должны назвать это так:

cudaMemcpy2D(histogram, SIZE_THETA*sizeof(int), dev_histogram, pitch, SIZE_THETA * sizeof(int), SIZE_RHO, cudaMemcpyDeviceToHost);

Редактировать: после ArchaeaSoftware я заметил, что действительно высота - это количество строк, высота в количестве байтов не имеет смысла.Обновленный ответ, потому что вам все еще нужно изменить высоту звука.

1 голос
/ 29 октября 2011

Укажите SIZE_RHO в качестве высоты, а не SIZE_RHO * sizeof (int):

<cudaMemcpy2D(histogram, pitch, dev_histogram, SIZE_THETA * sizeof(int), SIZE_THETA * sizeof(int), SIZE_RHO * sizeof(int), cudaMemcpyDeviceToHost);
>cudaMemcpy2D(histogram, pitch, dev_histogram, SIZE_THETA * sizeof(int), SIZE_THETA * sizeof(int), SIZE_RHO, cudaMemcpyDeviceToHost);
0 голосов
/ 29 октября 2011

Часто при хранении данных в непрерывной памяти вы хотите, чтобы раздел памяти имел размерность, кратную единице хранения, чтобы данные могли быть эффективно прочитаны. Например, вместо чтения 4 отдельных байтов подряд вы можете прочитать одно 32-битное слово. Вы делаете это для эффективности. Посмотрите выравнивание памяти.

По той же причине вы хотите, чтобы определенные массивы имели размер шага * высоту, где шаг - это ширина, округленная до ближайшего кратного любой используемой вами единицы хранения. Если ваш массив 31 * 5, то вы используете шаг 32, но ширину 31. Ожидается, что четыре 32-битных чтения будут быстрее, чем тридцать одно 1-байтовое чтение. Вы отбрасываете дополнительный байт заполнения.

Вы, вероятно, хотите установить шаг = ширина. Причина вашей ошибки сегмента в том, что вы ее не инициализировали. Убедитесь, что ширина и высота соответствуют спецификациям вашего графического процессора для размера блока резьбы.

...