2017-01-15 7 views
0

Я относительно новичок в программировании CUDA, поэтому есть некоторые нерешенные проблемы, для которых я надеюсь, что смогу получить некоторые подсказки в правильном направлении.Матрица Умножение матрицы и ее транспонирование в Cuda

Так дело в том, что я хочу, чтобы умножить 2D массив с транспонированной и быть точным, я хочу, чтобы выполнить операцию A T A.

Я уже использовал cublas Dgemm функцию и теперь я Я пытаюсь выполнить ту же операцию с использованием алгоритма с черепицей, который очень похож на тот, который содержится в руководстве CUDA.

Дело в том, что, хотя исходный алгоритм работает правильно, я хочу рассчитать только верхнюю треугольную матрицу продукта, надеясь, что я смогу достичь лучшего времени для операции, и я не уверен, как извлечь плитки/блоки, которые будут иметь соответствующие элементы.

Итак, если бы вы могли просветить меня по этому поводу или дать какой-либо намек, я был бы благодарен, потому что я застрял на нем какое-то время.

Это код ядра

__shared__ double Ads1[TILE_WIDTH][TILE_WIDTH]; 
__shared__ double Ads2[TILE_WIDTH][TILE_WIDTH]; 

//block row and column 
//we save in registers for faster access 
int by = blockIdx.y; 
int bx = blockIdx.x; 

int ty = threadIdx.y; 
int tx = threadIdx.x; 

int row = by * TILE_WIDTH + ty; 
int col = bx * TILE_WIDTH + tx; 

double Rvalue = 0; 

if(row >= width || col >= width) return; 
//Each thread block computes one sub-matrix Rsub of result R 

for (int i=0; i<(int) ceil(((double) height/TILE_WIDTH)); ++i) 
{ 
    Ads1[tx][ty] = Ad[(i * TILE_WIDTH + ty)*width + col]; 
    Ads2[tx][ty] = Ad[(i * TILE_WIDTH + tx)*width + row]; 
    __syncthreads(); 

    for (int j = 0; j < TILE_WIDTH; ++j) 
    { 
     if ((i*TILE_WIDTH + j) > height) break; //in order not to exceed the matrix's height 

     Rvalue+=Ads1[j][tx]*Ads2[ty][j]; 
    } 
    __syncthreads(); 
} 
Rd [row * width + col] = Rvalue; 
+4

Если у вас есть A (T) * A, работающий правильно, и вы хотите извлечь верхнюю треугольную матрицу, почему бы вам не показать код, который вы уже выполнили для умножения A (T) * A? –

+3

этот вопрос не лучше, чем в последний раз, когда вы его задали – talonmies

+0

Ну, это первый раз, когда я задаю вопрос о стеке, поэтому я не совсем уверен, что вы говорите о – CloudTemper

ответ

1

Вы можете использовать функцию пакетного DGEMM API, описанной here recursely разделив выходную матрицу с блоком диагонали и углу. Вы также хотите сбалансировать минимальный размер блока или накладные расходы при вычислении, чтобы избежать небольших вызовов. Наконец, обратите внимание, что матрица multiply превращает память на какой-то стадии, что может быть на современном графическом процессоре несколько большим.