Как продолжение предыдущего вопроса Вот, Я пытаюсь реализовать следующий цикл, который представляет собой умножение матрицы на вектор, где вектор представляет собой столбец из матрицы Q на основе итератора цикла:
РЕДАКТИРОВАТЬ: Q не может быть заполнен до руки, но заполняется с помощью итератора K.
for (unsigned K=0;K<N;K++){ // Number of iterations loop
//... do some stuff
for (unsigned i=0; i<N; i++){
float sum = 0;
for (unsigned j=0; j<N; j++){
sum += A[j][i]*Q[j][K];
}
v[i] = sum;
}
//... do some stuff
// populate next column of Q
}
Где размеры массивов:
A [N x N]
Q [Н х (0,5Н + 1)]
Эти массивы были сплющены, чтобы использовать их с cublasSgemv (). Мой вопрос заключается в том, можно ли использовать cublasSgemv (), указав ему, с чего начать доступ к d_Q, и каков приращение элементов (поскольку это C ++ для мажорной строки):
РЕДАКТИРОВАТЬ: умноженный прирост доступа к памятке с sizeof (float). Все еще не работает, насколько я могу судить.
Niter = 0.5*N + 1;
for (unsigned K=0;K<N;K++){
cublasSgemv(handle, CUBLAS_OP_T, N, N, &alpha, d_A, N, (d_Q + sizeof(float)*K*(Niter)), (Niter), &beta, d_v , 1);
}
Я не думаю, что возможно индексировать d_Q, так как я не получаю никаких результатов
РЕШЕНО: решение от @RobertCrovella — это то, что я искал. Благодарю.
Можно индексировать через ваш плоский Q
матрица так, как вы предлагаете. Ваш звонок в Sgemv должно быть следующим:
cublasSgemv(handle, CUBLAS_OP_T, N, N, &alpha, d_A, N, (d_Q + K), (Niter), &beta, (d_v+(K*Niter)) , 1);
Указатель на Q
должен указывать на первый элемент рассматриваемого столбца, и поскольку ваша матрица является мажорной строкой, это просто d_Q + K
(используя арифметику указателей, а не байтовую арифметику). Niter
шаг (в элементах, а не в байтах) между последовательными элементами рассматриваемого столбца. Обратите внимание, что ваш код в том виде, в котором он написан, перезапишет результаты одного матричного вектора, умноженного на следующий, так как вы не индексируете через d_v
выходной вектор. Поэтому я добавил индексирование d_v
,
Как указывает @JackOLantern, это также должно быть возможно сделать за один шаг без вашего цикла, вызвав Sgemm:
cublasSgemm(handle, CUBLAS_OP_T, CUBLAS_OP_T N, Niter, N, &alpha, d_A, N, d_Q, (Niter), &beta, d_v, N);
Если ваш код работает не так, как вы ожидаете, предоставьте полный, скомпилированный пример.
Других решений пока нет …