Матрицы на CUDA

Tagged:  

Немогу перенести двумерный массив на Cuda,да и в инете все работают в одномерными.Т.е. чтобы задавали матрицу на хосте,а потом переносили на девайс и там с ней уже работали.Пару примеров было но нерабочие,непонятно зачем выкладывали,т.е. там даже на с++ошибки в коде неговоря про CUDA

Comments

а как вы пытаетесь это сделать?
про функцию cudaMallocPitch знаете?

Нет,только начел изучать Cuda,но типерь посмотрю о ней:)
Кстати может еще подскажете ,что может быть за проблема,на гпу делаю вычисления между двумя векторами,но с последним элементом никак не хочет работать,т.е. все вычисляет правильно,а за последний не берется.Создал вектор на хосте,записал в него значения,потом на гпу сделал вычисления и получившиеся значения записал в этот вектор, все элементы назначаются правильно, а последний остается как был.

возможно размер грида не покрывает последний элемент вектора, соответственно до него дело не доходит.

беру небольшие вектора рабмерностью 3-4 элемента ,размер грида задаю вручную
kernel<<<16,16>>>(da,db,dc);
кстат с выделением места под матрицу ошибка вылазиет,хотя судя по интеренет источникам выделенно все верно:

int n,i,j;
scanf("%d",&n);
int m=n+1;
size_t nsz=n*sizeof(float);
float* Ptr;
int pitch;
cudaMallocPitch((void**)&Ptr,&pitch,nsz,m);

error: no instance of overloaded function "cudaMallocPitch" matches the argument list

NVIDIA_CUDA_Programming_Guide_2.3.pdf
// Host code
float* devPtr;
int pitch;
cudaMallocPitch((void**)&devPtr, &pitch,width * sizeof(float), height);
myKernel<<<100, 512>>>(devPtr, pitch);
// Device code
__global__ void myKernel(float* devPtr, int pitch)
{
for (int r = 0; r < height; ++r) {
float* row = (float*)((char*)devPtr + r * pitch);
for (int c = 0; c < width; ++c) {
float element = row[c];
}}}
Из примера вышеуказанного пдф.height и width не передаются ядру с хоста,откуда они должны определится непонятно,Кстати обратите внимания как в примере задется pitch.

ну это ж просто пример. конечно width и height надо передать в ядро.

а доступ к элементам массива внутри кернела как происходит?
должно быть что-то вроде:
float* pElement = (float*)((char*)devPtr + row * pitch) + column;
(кстати, вы в курсе что cudaMallocPitch используется для выделения памяти под 2D массивы, а то вы тут что-то про вектора нам рассказываете)

>error: no instance of overloaded function "cudaMallocPitch" matches the argument list
сигнатура функции:
cudaError_t cudaMallocPitch (void ** devPtr, size_t * pitch, size_t width, size_t height)
видимо ругается на то что не может откастить int* к типу size_t*.
измените тип pitch на size_t.

float* pElement = (float*)((char*)devPtr + row * pitch) + column;
А причем тут (char*)?массив состоит из вещественных цисел.row как я понимаю кол-во строк и надо тоже перидавать ядру с хоста?и что под column идет?

тут row/column это не кол-во строк/колонок, а номер строки/колонки, из которой происходит выбор элемента массива.

Насчет векторов, не обращайте внимания это отдельная програма,просто решил заодно спросить:)
pitch та изменю на size_t* но как сказанно в мануале
CudaMallocPitch(void** devPtr,
size_t* pitch,
size_t widthInBytes,
size_t height);
т.е.я кол-во строк должен тоже задавать size_t ?(как я понел height считается высотой матрицы)если так то как его задавать?размерность матрицы я задаю с клавиатуры целым числом.

что вы понимаете под размерностью матрицы?
(у меня такое чувство что вы путаете размер и размерность)

Возможно не так выразился,я задаю кол-во строк с клавиатуры,кол-во столбцов на 1 больше чем строк.

тогда примерно так:

  1. float* devPtr;
  2. size_t width, height, widthInBytes;
  3. // спросить у пользователя width и height матрицы
  4. widthInBytes = width*sizeof(float);
  5. cudaMallocPitch((void**)&devPtr, &pitch,widthInBytes, height);

Copyright © 2008-2011 Alex Tutubalin