2013-10-12 2 views
2

Я новый Открыть-ХЛ, и я пытаюсь написать код ядра для следующей матричной операции:Проблема в функции OpenCL ядра

A is a 2X2 matrix: 
A = [1 2] ----> row1 
    [3 4] ----->row2 

I need to compute: 
1) s1 = transpose(row1) X row1 
2) s1 = transpose(row2) X row2 
3) Sum = s1+s2 

Example

Я написал код ядра для уровня строки (т.е. Я могу сделать транспонирование (row1) X row1) -this служит только для первой строки

Как использовать параллелизм для вычисления этого для каждой строки и найти окончательную сумму в функции ядра?

private static String programSource1 = 
      "__kernel"+ 
      " void matrixMul(__global float* A, __global float* C, int rowLength)"+ 
      "{"+ 
       "int row = get_global_id(1);"+ 
       "int col = get_global_id(0);"+    
        "C[row*rowLength+col] = A[col] * A[row];"+ 

      "}"; 
+0

Будет ли окончательная реализация работать только на матрице 2x2 матриц или больших матриц? Это полностью меняет, как реализовать код .... – DarkZeros

ответ

1
#define MAX_ROW_LENGTH 2 // or more 
__kernel void matrixMul(__global float* A, __global float* C, 
               int rowLength) 
{ 
    __local float buffer[MAX_ROW_LENGTH * MAX_ROW_LENGTH]; 
    __local float s1[MAX_ROW_LENGTH * MAX_ROW_LENGTH]; 

    int col = get_global_id(0); 
    int row = get_global_id(1); 
    int rows = get_global_size(1); 

    // read the matrix from global to local memory 
    buffer[row * rowLength + col] = A[row * rowLength + col]; 
    s1[row * rowLength + col] = 0.0f; 

    barrier(CLK_LOCAL_MEM_FENCE); 

    for (int i = 0; i < rows; ++i) 
    { 
     s1[row * rowLength + col] += 
       buffer[i * rowLength + col] * buffer[i * rowLength + row]; 
    } 
    C[row * rowLength + col] = s1[row*rowLength+col]; 
} 

Вот код ядра, который делает то, что вы хотите для небольших матриц. Ядро использует локальную память для уменьшения доступа к глобальной памяти. Для таких небольших задач (матрица 2x2) это требует чего-либо, но если вы вычисляете большие матрицы, это может немного ускорить работу. Тем не менее, это короткий пример, а не optimized.Iit поставляется с некоторыми ограничениями:

  • этот код поддерживает только локальную рабочую группу размером равным глобальной размера рабочей группы (без чушек)
  • если ваши матрицы получают в большой общая память будет ограничивать использование вашего GPU и
  • если ваши матрицы получить действительно большие их не будет достаточно разделяемой памяти

Если вы не хотите, локальная удалить память заменить вызовы для буфера в пределах для цикл по A и записать d прямо на C вместо s1.

+0

Большое спасибо, отличное объяснение. Это дало мне четкое представление о написании кода ядра. –

Смежные вопросы