2016-01-29 4 views
0

У меня проблема с использованием функции sgemm cblas.Cblas_sgemm производит неправильные результаты

Вот код:

#include <math.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <cblas.h> 

#define MATRIX_DIM 5 

int main(){ 

    float *a_mat = calloc(MATRIX_DIM*MATRIX_DIM, sizeof(float)); 
    float *b_mat = calloc(MATRIX_DIM, sizeof(float)); 
    float *c_mat = calloc(MATRIX_DIM, sizeof(float)); 
    int i,j; 

    for(i=0; i<MATRIX_DIM*MATRIX_DIM; i++) { 
     a_mat[i] = 1.0f; 
     b_mat[i] = 1.0f; 
     c_mat[i] = 0.0f; 
    } 

    cblas_sgemm(CblasRowMajor, CblasNoTrans, 
       CblasNoTrans, MATRIX_DIM, MATRIX_DIM, 
       MATRIX_DIM, 1.0, a_mat, 
       MATRIX_DIM, b_mat, MATRIX_DIM, 
       1.0, c_mat, MATRIX_DIM); 

    //RESULT PRINTING 
    printf("Printing A MATRIX: \n"); 
    for(i=0; i<MATRIX_DIM; i++) { 
     for(j=0; j<MATRIX_DIM; j++){ 
       printf("%0.1f ", a_mat[i*MATRIX_DIM+j]); 
     } 
     printf("\n"); 
    } 
    printf("Printing B MATRIX: \n"); 
    for(i=0; i<MATRIX_DIM; i++) { 
      for(j=0; j<MATRIX_DIM; j++){ 
       printf("%0.1f ", b_mat[i*MATRIX_DIM+j]); 
     } 
     printf("\n"); 
    } 

    printf("\nPrinting the Results: \n"); 
    for(i=0; i<MATRIX_DIM;i++){ 
     for(j=0; j<MATRIX_DIM; j++){ 
       printf("%0.1f ", c_mat[i*MATRIX_DIM+j]); 
     } 
     printf("\n"); 
    } 

    free(a_mat); 
    free(b_mat); 
    free(c_mat); 

    return 0; 
} 

Я довольно некоторые из аргументов, я ставлю в ошибаемся, но я действительно не знаю. Результаты должны быть матрицей 5x5, заполненной 5.0. Вместо этого программа отвечает следующим образом:

6.0 6.0 6.0 16.0 86.0 
6.0 6.0 6.0 16.0 86.0 
16.0 36.0 6.0 46.0 86.0 
16.0 36.0 5.0 45.0 85.0 
20.0 80.0 5.0 45.0 85.0 

Я знаю rowmajor порядка или аргументы транспонирования могут быть ошибочными, и я понять те позже, но в данном конкретном умножении ответ должен быть 5,0 или иначе.

+0

Хм ... Разве вы не должны 'calloc' для' sizeof (float) '? Как 'sizeof (* a_mat)' даже действителен? И не должен ли ваш результат быть * вектором * длины 5, все элементы равны 5? И не должен ли этот результат записываться в * вектор * 'c_mat'? Как вы не получаете никаких segfaults? –

+0

@AndrasDeak Ну, возможно, вы правы в части 'sizeof (float)', но по какой-то причине она работает именно так. Тем не менее я изменю его. Так как это Матрица-Матричное умножение, результатом должна быть матрица из MxN (M - строки первой матрицы, а N - столбцы второй матрицы), которая в этом случае была бы матрицей 5x5. Я думаю, вы имеете в виду Matrix-Vector Multiplication. – kmentis

+0

Где я могу видеть, что вторая матрица имеет 5 столбцов? 'float * b_mat = calloc (MATRIX_DIM, sizeof (* b_mat));' является только столбцом выделенных значений. Отсюда мое удивление, что вы не получите segfault чуть позже. Одна из возможностей заключается в том, что 'sizeof (* a_mat)' (что бы то ни было) имеет больше места, чем 'float'. И ваша проблема в том, что она * не * работает нормально :) –

ответ

0

Благодаря @AndrasDeak в комментариях все, что мне было нужно, это выделить больше пространства на две матрицы, которые я ранее забыл.

Так в основном меняется:

float *b_mat = calloc(MATRIX_DIM, sizeof(float)); 
float *c_mat = calloc(MATRIX_DIM, sizeof(float)); 

To:

float *b_mat = calloc(MATRIX_DIM*MATRIX_DIM, sizeof(float)); 
float *c_mat = calloc(MATRIX_DIM*MATRIX_DIM, sizeof(float)); 

С тех должны быть 2-мерные матрицы, а не векторы.

+0

Я бы поменял эти 'sizeof()' ы на float :) И поскольку это по сути опечатка в коде, вы должны подумать о том, что будущие пользователи могут найти это Q & A полезным. Если вы не думаете об этом, то, возможно, стоит удалить вопрос. Если вы решите сохранить вопросы и ответы, тогда примите свой ответ через некоторое время, когда сможете (24 или 48 часов, я думаю) –

+0

Я изменил 'calloc' на float, как вы сказали, следует ли изменить' * MATRIX_DIM', чтобы он полностью функционировал? Я новичок в stackoverflow, поэтому я не знаком с этой процедурой. – kmentis

+0

Ooooh no no no, извините, вы неправильно поняли :) Я имел в виду просто изменить ваш фактический код, но не ваш вопрос выше (в вашем ответе было неясно, изменили ли вы также sizeof), поэтому я заметил, что тоже в мой комментарий). Процедура «оставить вопрос« как есть », если не добавить пояснения», и любые исправления должны быть включены в ответы. Затем все присутствует ровно один раз: один ясный вопрос и один (или более) четкий ответ. –