GeMM

GeMM(General Matrix Multiply) 메서드는 두 행렬의 일반적인 곱셈을 구현합니다. 연산은 C ← α AB + β C 로 정의되며 여기서 A 및 B 행렬은 선택적으로 전치될 수 있습니다. 행렬 AB (MatMul), 알파 스칼라는 1과 같다고 가정하고베타는 0과 같습니다.

효율성 측면에서 GeMM과 MatMul의 주요 차이점은 MatMul은 항상 새로운 행렬/벡터 객체를 생성하는 반면 GeMM은 기존 행렬 객체와 함께 작동하며 행렬을 다시 생성하지 않는다는 것입니다. 따라서 GeMM을 사용하고 해당 행렬에 대해 메모리를 사전 할당하면 동일한 행렬 크기로 작업하는 동안 메모리를 재할당하지 않습니다. 이는 예를 들어 전략 테스터에서 최적화를 실행하거나 신경망을 교육할 때 대량 컴퓨팅을 위한 GeMM의 중요한 이점이 될 수 있습니다.

MatMul과 유사하게 GeMM에도 4개의 과부하가 있습니다. 그러나 수직 벡터와 a 및 수평 벡터의 곱셈을 가능하게 하기 위해 네 번째 오버로드의 의미 체계가 수정되었습니다.

기존 행렬/벡터 개체에서는 메모리를 미리 할당할 필요가 없습니다. 메모리는 첫 번째 GeMM 호출에서 할당되고 0으로 채워집니다.

Multiplying a matrix by a matrix:   matrix C[M][N] = α * ( matrix A[M][K] * matrix B[K][N]) + β * matrix C[M][N]

bool  matrix::GeMM(
  const matrix &A,    // 첫번째 행렬
  const matrix &B,    // 두번째 행렬
  double alpha,       // 행렬곱에 대한 알파 승수
  double beta,        //  행렬 C에 대한 베타 승수
  uint   flags        // 행렬 A, B 및 C의 전치 여부를 결정하는 ENUM_GEMM 열거형 값
   );

Multiplying a vector by a matrix: vector C[N] = α * ( vector A[K] * matrix B[K][N]) + β * vector C[N]

bool  matrix::GeMM(
  const vector &A,    // 수평 벡터
  const matrix &B,    // 행렬
  double alpha,       // 행렬곱에 대한 알파 승수
  double beta,        // 벡터 C에 대한 베타 승수
  uint   flags        //  A, B, C의 전치 여부를 결정하는 ENUM_GEMM 열거형 값
   );

Multiplying a matrix by a vector: vector C[M] = α * ( matrix A[M][K] * vector B[K] * ) + β * vector C[M]

bool  matrix::GeMM(
  const matrix &A,    // 행렬
  const vector &B,    // 수직 벡터
  double alpha,       // 행렬곱에 대한 알파 승수
  double beta,        // 벡터 C에 대한 베타 승수
  uint   flags        //  A, B, C의 전치 여부를 결정하는 ENUM_GEMM 열거형 값
   );

Multiplying a vector by a vector: matrix C[M][N] = α * ( vector A[M] * vector B[N] * ) + β * matrix C[M][N]. 이 오버로드는 스칼라를 반환하는 MatMul과 달리 행렬을 반환합니다.

bool  matrix::GeMM(
  const vector &A,    // 첫번째 벡터
  const vector &B,    // 두번째 벡터
  double alpha,       // 행렬곱에 대한 알파 승수
  double beta,        // matrix C에 대한 벡터
  uint   flags        //  A, B, C의 전치 여부를 결정하는 ENUM_GEMM 열거형 값
   );

매개 변수

A

[in]  헹렬 혹은 벡터.

B

[in]  헹렬 혹은 벡터.

alpha

[in]  행렬 곱셉 AB에 대한 알파 승수.

beta

[in]  행렬 C에 대한 베타 승수.

flags

【in】 행렬 A, B 및 C가 전치되는지 여부를 결정하는 ENUM_GEMM 열거형 값입니다.

반환값

성공하면 true를  그렇지 않으면 false를 반환.

ENUM_GEMM

GeMM 메서드에 대한 플래그의 열거.

ID

설명

TRANSP_A

전치 행렬 A 사용

TRANSP_B

전치 행렬 B 사용

TRANSP_C

전치 행렬 C 사용

참조

float, double 및 complex 유형의 행렬 및 벡터를 매개변수 A 및 B로 사용할 수 있습니다. GeMM 메서드의 템플릿 변형은 다음과 같습니다.

bool matrix<T>::GeMM(const matrix<T> &A,const matrix<T> &B,T alpha,T beta,ulong flags);
bool matrix<T>::GeMM(const vector<T> &A,const vector<T> &B,T alpha,T beta,ulong flags);
 
bool vector<T>::GeMM(const vector<T> &A,const matrix<T> &B,T alpha,T beta,ulong flags);
bool vector<T>::GeMM(const matrix<T> &A,const vector<T> &B,T alpha,T beta,ulong flags);

기본적으로 일반적인 행렬 곱셈 함수는 다음과 같이 설명됩니다:

C[m,n] = α *Sum(A[m,k]*B[k,n]) + β*C[m,n]

크기는 다음과 같습니다. 행렬 A는 M x K, 행렬 B는 K x N, 행렬 C는 M x N입니다.

따라서 행렬은 곱셈과 호환되어야 합니다. 즉 첫 번째 행렬의 열 수가 두 번째 행렬의 행 수와 같아야 합니다. 행렬 곱셈은 비가환적입니다. 일반적인 경우 첫 번째 행렬에 두 번째 행렬을 곱한 결과는 두 번째 행렬에 첫 번째 행렬을 곱한 결과와 같지 않습니다.

 

예:

void OnStart()
  {
   vector vector_a= {12345};
   vector vector_b= {4321};
   matrix matrix_c;
//--- 두 벡터에 대한 GeMM 계산
   matrix_c.GeMM(vector_avector_b10);
   Print("matrix_c:\n "matrix_c"\n");
   /*
   matrix_c:
    [[4,3,2,1]
    [8,6,4,2]
    [12,9,6,3]
    [16,12,8,4]
    [20,15,10,5]]
   */
//--- 행렬을 벡터로 생성
   matrix matrix_a(51);
   matrix matrix_b(14);
   matrix_a.Col(vector_a0);
   matrix_b.Row(vector_b0);
   Print("matrix_a:\n "matrix_a);
   Print("matrix_b:\n "matrix_b);
   /*
   matrix_a:
   [[1]
   [2]
   [3]
   [4]
   [5]]
   matrix_b:
   [[4,3,2,1]]
   */
//-- 두 행렬에 대해 GeMM을 계산하고 동일한 결과를 얻습니다.
   matrix_c.GeMM(matrix_amatrix_b10);
   Print("matrix_c:\n "matrix_c);
   /*
   matrix_c:
    [[4,3,2,1]
    [8,6,4,2]
    [12,9,6,3]
    [16,12,8,4]
    [20,15,10,5]]
   */
  }

 

또다른 참조

MatMul