входные матрицы целых чисел в cblas_sgemm возвращают все 0

Я пытаюсь использовать cblas_sgemm для быстрого умножения матриц на две матрицы целых чисел.

Сейчас он возвращает все нули.

Я выполнил быстрое наивное умножение матрицы, чтобы дважды проверить ожидаемые выходные данные, и они не должны быть нулями.

Работающий наивный подход:

typedef int    mm_data_t;

void func1( mm_data_t *in1, mm_data_t *in2,  mm_data_t *out, int N ){
    int i, j, k;

    for(i=0; i<N; i++){
        for(k=0; k<N; k++){
            int temp = in1[i*N+k];
            for(j=0; j<N; j++){
                out[i*N+j] += temp * in2[k*N+j];
            }
        }
    }
}

И используя cblas_sgemm:

void func2( mm_data_t *in1, mm_data_t *in2,  mm_data_t *out, int N ){

    cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, N,  N,  N, 1.0, (float*)in1, N, (float*)in2, N, 0.0, (float*)out, N);

}

Я использую одномерные массивы для оптимизации.

Входные данные помещены в черный ящик, но они постоянны.


person samuelsaumanchan    schedule 29.11.2012    source источник


Ответы (1)


cblas_sgemm() предназначен для умножения матриц значений с плавающей запятой одинарной точности, а не целых чисел.

Таким образом, ваши целые числа интерпретируются как значения с плавающей запятой. Маленькие положительные целые числа, скорее всего, будут рассматриваться как субнормальные числа. Умножение любой пары из них даст нулевой результат. Поэтому, если все ваши входные данные представляют собой небольшие неотрицательные целые числа, все выходные данные будут равны нулю.

И если ваши входные данные содержат небольшие отрицательные целые числа, ваши выходные данные, вероятно, будут содержать много NaN, которые будут выглядеть как очень большие целые числа (которые могут быть положительными или отрицательными).

Если вам действительно нужно умножать целые числа, вам нужно будет преобразовать их в & из чисел с плавающей запятой или использовать библиотеку, которая может умножать матрицы целых чисел (BLAS не может).

person finnw    schedule 01.12.2012