Задача программирования CUDA 3 - PullRequest
0 голосов
/ 30 мая 2011

У меня есть два одномерных массива.Теперь я должен выполнить 'anding' этих двух массивов, если элементы массивов равны, то я должен поместить элемент в 2d массив.

Я написал следующий код, но мой код не работает.Кто-нибудь может сказать мне, что я делаю неправильно?

#include<stdio.h>
#include<stdio.h>
#include<cuda.h>
#define height 3
#define width 2

__global__ void fun(unsigned char *c ,unsigned short *s,unsigned char *u,size_t pitch)
{ 

    int tid =blockIdx.x * blockDim.x + threadIdx.x ;
    //int tidy=blockIdx.y * blockDim.y + threadIdx.y ;

    if(tid<6)
    {

        for (int r = 0; r < height; ++r)
        {        //float* row = (float*)((char*)u + r*pitch);

                for (int d = 0; d< width; ++d) 
                {
                    u[r*width+d] = c[tid] & s[tid];
                }
        }
    } 
}


int main()
{
    int i,j;
    unsigned char man[6]="manis",*dev_c,jan[3][2],*dev_r;

    unsigned short a[6]={32,33,43,35,36,37},*dev_s;

    size_t pitch;

    cudaMalloc((void**)&dev_c,sizeof( unsigned char)*6);       // memory allocation on device

    cudaMalloc((void**)&dev_s,sizeof(unsigned short)*6);

    cudaMallocPitch((void**)&dev_r, &pitch, width*sizeof(unsigned char),height);

    cudaMemcpy(dev_c,man, 6*sizeof(unsigned char),cudaMemcpyHostToDevice);

    cudaMemcpy(dev_s,a, 6*sizeof(short int),cudaMemcpyHostToDevice);

    fun<<<5,2>>>(dev_c,dev_s,dev_r,pitch);

    cudaMemcpy2D(jan,3*sizeof(unsigned char),dev_r,pitch,sizeof( unsigned char),2,cudaMemcpyDeviceToHost);

    printf("\nThe call is completd");

    for ( i=0; i < width; i++)
    {
        for (j=0; j < height; j++)
        {
            printf("%d ",jan[j+i*width]);
        }

Кто-нибудь может сказать мне, что я делаю неправильно?Я использовал cudamallocpitch для выделения 2d на устройстве, затем я использую cudamemcpy , чтобы скопировать массив обратно на хост, но код не работает должным образом при каждом запуске, он показывает все новые значения.

Может ли какой-либо орган объяснить мне, как достичь моей цели, которая заключается в том, чтобы "объединить элементы 2 одномерного массива и поместить результат в 2d".

Пожалуйста, не обращайте внимания на мой английский и помогите мне.

1 Ответ

1 голос
/ 30 мая 2011

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

  1. У вас есть несколько переполнений буфера в памяти устройства, в основном из-за использования 25 потоков для записи в массивы с выделением 4 или 5 слов
  2. Ваше ядро ​​содержит ужасную гонку памяти. Потоки будут перезаписывать чужие выходные данные, которые дают неопределенное поведение в CUDA.
  3. Цикл while в вашем ядре производить бесконечное циклическое поведение и ядро ​​может никогда не прекратить в результате.
  4. Вы продолжаете спрашивать о 2D-массивах, но нигде в вашем коде нет двумерного массива. Все линейно 1D памяти от что я вижу.

Это должно занять тебя некоторое время.


РЕДАКТИРОВАТЬ: другой день, еще одна совершенно другая версия кода, так что еще несколько комментариев:

  1. Ваше ядро ​​теперь полностью последовательное. Первые 6 потоков будут пытаться перезаписать выходной массив с другими результатами. Это гонка памяти.
  2. Вы смешиваете char и unsigned short типы данных внутри ядра. Это, вероятно, означает, что вы выполняете операцию и между 8 и 16-битными значениями, а затем сохраняете результат в 8-битном типе. Даже без гонки памяти, я вполне уверен, что это не то, что вы хотите.
  3. Примерно в десятый раз я повторюсь - cudaMallocPitch выделяет линейную память с отступами, чтобы сделать ее подходящим размером для контроллера памяти GPU и текстурных блоков. Это не размещение 2D массивов. Поэтому, если вы хотите получить доступ к этой линейной памяти, вам нужно использовать высоту, возвращаемую вызовом cudaMallocPitch. Формула для доступа к памяти есть в документации , но я повторю ее здесь:

    T* pElement = (T*)((char*)BaseAddress + Row * pitch) + Column;

  4. Каждый вызов API в вашей программе возвращает код ошибки. Вы должны проверить каждый из них, чтобы увидеть, обнаруживаются ли какие-либо ошибки во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...