Я не знаю ни одного, и я всегда думал, что было бы полезно иметь.
Для размера задач, с которыми я обычно работаю (небольшие матрицы и тензоры, возникающие в методе конечных элементов), я просто написал шаблоны C ++ для выполнения операций. Шаблонирование функций позволяет компилятору узнавать счетчики отключений во время компиляции, а также может развертывать циклы и сохранять результаты или промежуточные результаты в регистре, что, как правило, очень эффективно для пропускной способности ядра. Таким образом, матрично-матричный продукт объявляется как
template < typename Real, unsigned int l, unsigned int m, unsigned int n >
__device__ __host__
void matmul(const Real *a,
const Real *b,
Real *c)
{
for(int i=0; i<l; i++) {
for(int j=0; j<n; j++) {
Real dotprod = Real(0);
for(int k=0; k<m; k++) {
dotprod += a[idx2c(i,k,l)] * b[idx2c(k,j,m)];
}
c[idx2c(i,j,l)] = dotprod;
}
}
}
Для таких размеров, которые возникают в моих ядрах (2x2, 3x3, 4x4, 8x8, 9x9), выполнение вышеизложенного и возможность компиляции работают так же хорошо, как любой другой подход, который я пробовал. Поскольку на уровне потоков CUDA эффективно скалярен, нет никаких векторных примитивов или чего-то подобного, что можно использовать для ускорения такого рода небольших операций.