умножение матриц с использованием cuBLAS на alea gpu

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

Gpu gpu = Gpu.Default;
Blas blas = new Blas(gpu);

int m=2,n=3;    //in dimension and out dimension (output will be mxn matrix)
int k=4;

//column major
float[,] A = new float[4,2] { {100,200},{2,6},{3,7},{4,8} };    //2x4 matrix
float[,] B = new float[3,4] { {1,4,7,10}, {2,5,8,11}, {3,6,9,12} }; //4x3 matrix
float[,] C = new float[3,2] { {-1,-1}, {-1,-1}, {-1,-1}  }; //2x3 matrix

var dA = gpu.AllocateDevice<float>(A);  
var dB = gpu.AllocateDevice<float>(B);  
var dC = gpu.AllocateDevice<float>(C);

blas.Gemm(Operation.N,Operation.N,m,n,k,1f,dA.Ptr,m,dB.Ptr,k,0f,dC.Ptr,m);

var result = Gpu.Copy2DToHost(dC);

Это результат, который я получаю. Он просто копирует некоторое число из матрицы A. Некоторые числа в матрице C не меняются с момента инициализации.

100 -1 -1
200 -1 -1

Что-то не так с кодом? Пожалуйста помоги.

Я использую alea 3.0.3 с набором инструментов cuda 8.0.

ОБНОВЛЕНИЕ 1: я обнаружил, что это дает правильный результат, когда я сглаживаю матрицы A, B, C в одномерные массивы. Однако все же хочется узнать, что не так с 2D-массивами.


person koonyook    schedule 04.09.2017    source источник


Ответы (1)


Я обнаружил, что gpu.AllocateDevice для 2D-массива не выделяет пространство на графическом процессоре, как на процессоре. Расстояние между первыми элементами любых двух последовательных столбцов (шаг) удивительно велико.

Следовательно, необходимо изменить параметр ведущего размера.

blas.Gemm(Operation.N,Operation.N,m,n,k,1f,dA.Ptr,dA.PitchInElements.ToInt32(),dB.Ptr,dB.PitchInElements.ToInt32(),0f,dC.Ptr,dC.PitchInElements.ToInt32());

Теперь я получил правильный результат. Однако есть ли какие-либо документы, показывающие подробности того, как на самом деле работает выделение 2D-массива на GPU в Alea?

Я вижу только http://www.aleagpu.com/release/3_0_3/api/html/6f0dc687-7191-91ba-6c30-bb379dded567.htm, который не имеет объяснения.

person koonyook    schedule 05.09.2017
comment
Скорее всего, он использует cudaMallocPitch. Причиной этого шага является выравнивание строк матрицы с каналами физической памяти для повышения производительности в некоторых ядрах. - person Aleksandr Dubinsky; 10.11.2017