gcc openblas_test.c -lopenblas
이름 | 뜻 | 목록 |
---|---|---|
CBLAS_ORDER | major가 row 또는 col로 되어있음 | CblasRowMajor , CblasColMajor |
CBLAS_TRANSPOSE | 전치 행렬 | CblasNoTrans , CblasTrans , CblasConjTrans , CblasConjNoTrans |
CBLAS_UPLO | 상/하 삼각행렬 | CblasUpper , CblasLower |
void cblas_sgemm(OPENBLAS_CONST enum CBLAS_ORDER Order, OPENBLAS_CONST enum CBLAS_TRANSPOSE TransA, OPENBLAS_CONST enum CBLAS_TRANSPOSE TransB, OPENBLAS_CONST blasint M, OPENBLAS_CONST blasint N, OPENBLAS_CONST blasint K,
OPENBLAS_CONST float alpha, OPENBLAS_CONST float *A, OPENBLAS_CONST blasint lda, OPENBLAS_CONST float *B, OPENBLAS_CONST blasint ldb, OPENBLAS_CONST float beta, float *C, OPENBLAS_CONST blasint ldc);
gemm
은 GEneral Matrix-Matrix Multiplication 의 약자로
αAB * βC = C
를 구하는 함수이다.
행렬 A를 m × k, 행렬 B를 k × n 라고 할 때, 행렬 AB의 결과인 C는 n × m 이다
Order : rowMajor의 경우 CblasRowMajor
, colMajor의 경우, CblasColMajor
TransA : 전치행렬의 경우, CblasTrans
, 아닐경우 CblasNoTrans
TransB : TransA
와 동일
A, B : 행렬 A, B
C : input과 output으로 받을 행렬 C
(A, B, C 모두 1차원 배열)
M, N, K : 위의 정의와 동일한 값 (즉, 실제 행렬 곱에 사용되는 m, n, k)
alpha : (행렬 A × 행렬 B)
에 곱해질 상수
beta : 행렬 C
에 곱해질 상수
lda, ldb : 행렬 A 또는 B
의 열의 크기
ldc : 행렬 C
의 열의 크기
#include <stdlib.h>
#include <stdio.h>
#include <cblas.h>
void print_matrix(float* A, int m, int k) {
for (int i = 0; i < m; i++) {
for (int j = 0; j < k; j++) {
printf("%f ", A[i * k + j]);
}
printf("\n");
}
printf("\n");
}
int main() {
int a_m = 2;
int a_n = 3;
int b_m = 7;
int b_n = 3;
float* A = (float*)malloc(a_m * a_n * sizeof(float));
float* B = (float*)malloc(b_m * b_n * sizeof(float));
float* C = (float*)malloc(a_m * b_m * sizeof(float));
for (int i = 0; i < a_m * a_n; i++) {
A[i] = i + 1;
}
for (int i = 0; i < b_m * b_n; i++) {
B[i] = i + 1;
}
print_matrix(A, a_m, a_n);
print_matrix(B, b_m, b_n);
cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasTrans, 2, 7, 3, 1.0f, A, 3, B, 3, 0, C, 7);
print_matrix(C, a_m, b_m);
free(A);
free(B);
free(C);
return 0;
}
void cblas_sgemv(const enum CBLAS_ORDER __Order, const enum CBLAS_TRANSPOSE __TransA, const int __M, const int __N,
const float __alpha, const float *__A, const int __lda, const float *__X, const int __incX, const float __beta, float *__Y, const int __incY);
gemv
은 GEneral Matrix-Vector multiplication의 약자로
αAX * βY = Y
를 구하는 함수이다.
Order, TransA : gemm과 동일
A, X : 행렬 A
와벡터 X
Y : input 과 output으로 받을 벡터 Y
M, N : 행렬 A
의 행과 열
alpha : (행렬 A × 벡터 X)
에 곱해질 상수
beta : 벡터 Y
에 곱해질 상수
ida : 행렬 A
의 열의 크기
incX, incY : incX
, incY
값 만큼 점프뛰어 해당 행렬을 계산한다.
#include <stdio.h>
#include <stdlib.h>
#include <cblas.h>
void insert_value(float *matrix, int m, int n) {
for (int i = 0; i < m * n; i++) {
matrix[i] = i + 1;
}
}
void print_value(float* matrix, int m, int n) {
for (int y = 0; y < m; y++) {
for (int x = 0; x < n; x++) {
printf("%f ", matrix[y * n + x]);
}
printf("\n");
}
printf("\n");
}
int main() {
int m = 3;
int n = 2;
float *A = (float*)malloc(sizeof(float) * m * n);
float *X = (float*)malloc(sizeof(float) * n * 1);
float *Y = (float*)malloc(sizeof(float) * m * 1);
insert_value(A, m, n);
insert_value(X, n, 1);
print_value(A, m, n);
print_value(X, n, 1);
cblas_sgemv(CblasRowMajor, CblasNoTrans, m, n, 1, A, n, X, 1, 0, Y, 1);
print_value(Y, m, 1);
return 0;
}
인자 목록에 적었듯이 incX
는 점프해서 계산하기 때문에 위의 행렬과 벡터의 곱
을 incX = 2
로 세팅하여 아래처럼 계산이 가능하도록 구현가능하다.
#include <stdio.h>
#include <stdlib.h>
#include <cblas.h>
void insert_value(float *matrix, int m, int n) {
for (int i = 0; i < m * n; i++) {
matrix[i] = i + 1;
}
}
void print_value(float* matrix, int m, int n) {
for (int y = 0; y < m; y++) {
for (int x = 0; x < n; x++) {
printf("%f ", matrix[y * n + x]);
}
printf("\n");
}
printf("\n");
}
int main() {
// cblas_sgemv(OPENBLAS_CONST enum CBLAS_ORDER order, OPENBLAS_CONST enum CBLAS_TRANSPOSE trans, OPENBLAS_CONST blasint m, OPENBLAS_CONST blasint n,
// OPENBLAS_CONST float alpha, OPENBLAS_CONST float *a, OPENBLAS_CONST blasint lda, OPENBLAS_CONST float *x, OPENBLAS_CONST blasint incx, OPENBLAS_CONST float beta, float *y, OPENBLAS_CONST blasint incy);
// Y = bY + aAX
int m = 3;
int n = 3;
float *A = (float*)malloc(sizeof(float) * m * n);
float *X = (float*)malloc(sizeof(float) * 5 * 1);
float *Y = (float*)malloc(sizeof(float) * m * 1);
insert_value(A, m, n);
insert_value(X, 5, 1);
print_value(A, m, n);
print_value(X, 5, 1);
cblas_sgemv(CblasRowMajor, CblasNoTrans, m, n, 1, A, n, X, 2, 0, Y, 1);
print_value(Y, m, 1);
return 0;
}
float cblas_sdot(const int __N, const float *__X, const int __incX, const float *__Y, const int __incY);
X·Y
즉, 벡터 X
와 벡터 Y
의 내적을 구하는 함수이다.
X, Y : 벡터 X
, 벡터 Y
N : 벡터 X, Y
의 element 개수
incX, incY : incX
, incY
값 만큼 점프뛰어 내적을 계산한다.
#include <stdio.h>
#include <stdlib.h>
#include <cblas.h>
void insert_value(float *matrix, int m, int n) {
for (int i = 0; i < m * n; i++) {
matrix[i] = i + 1;
}
}
void print_value(float* matrix, int m, int n) {
for (int y = 0; y < m; y++) {
for (int x = 0; x < n; x++) {
printf("%f ", matrix[y * n + x]);
}
printf("\n");
}
printf("\n");
}
int main() {
// float cblas_sdot(const int __N, const float *__X, const int __incX, const float *__Y, const int __incY);
// ans = X · Y;
int n = 3;
float *X = (float*)malloc(sizeof(float) * n * 1);
float *Y = (float*)malloc(sizeof(float) * 5 * 1);
insert_value(X, n, 1);
insert_value(Y, 5, 1);
print_value(X, n, 1);
print_value(Y, 5, 1);
float ans = cblas_sdot(n, X, 1, Y, 2);
printf("%f", ans);
return 0;
}
void catlas_caxpby(const int __N, const void *__alpha, const void *__X, const int __incX, const void *__beta, void *__Y, const int __incY);
axpby
는 Alpha, vector X, Plus, Beta, vector Y 의 약자로
αX * βY = Y
를 구하는 함수이다.
X, Y : 벡터 X
, 벡터 Y
N :벡터 X, Y
의 element 개수
alpha, beta = 벡터 X
또는 벡터 Y
에 곱해질 상수
incX, incY : incX
, incY
값 만큼 점프뛰어 계산
#include <stdio.h>
#include <stdlib.h>
#include <cblas.h>
void insert_value(float *matrix, int m, int n) {
for (int i = 0; i < m * n; i++) {
matrix[i] = i + 1;
}
}
void print_value(float* matrix, int m, int n) {
for (int y = 0; y < m; y++) {
for (int x = 0; x < n; x++) {
printf("%f ", matrix[y * n + x]);
}
printf("\n");
}
printf("\n");
}
int main() {
// void catlas_caxpby(const int __N, const void *__alpha, const void *__X, const int __incX, const void *__beta, void *__Y, const int __incY);
// αX * βY = Y
int n = 3;
float *X = (float*)malloc(sizeof(float) * n * 1);
float *Y = (float*)malloc(sizeof(float) * 5 * 1);
insert_value(X, n, 1);
insert_value(Y, 5, 1);
print_value(X, n, 1);
print_value(Y, 5, 1);
cblas_saxpby(n, 2, X, 1, 3, Y, 2);
print_value(Y, 5, 1);
return 0;
}