Проблема в функции ядра OpenCL

Я новичок в Open-cl и пытаюсь написать код ядра для следующей операции матрицы:

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

пример

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

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

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];"+

            "}";

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) это позволяет достичь чего угодно, но если вы вычисляете большие матрицы, это может немного ускорить процесс. Тем не менее, это короткий пример и не оптимизирован. Он имеет некоторые ограничения:

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

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

Другие вопросы по тегам