Chapter 1: Toy Language and AST

moze·2024년 12월 31일

원문: https://mlir.llvm.org/docs/Tutorials/Toy/Ch-1/

본 게시글에서는 MLIR의 Toy Tutorial - Chapter 1: Toy Language and AST 내용을 다루고 있습니다. 단순 해석글로, 이해를 쉽게 하기 위해 필자가 이해한 내용을 조금 덧붙이고 있습니다.


Toy Tutorial - Chapter 1: Toy Language and AST 에서는 임의적으로 정의한 Toy라는 언어를 설명합니다. Toy 언어의 활용과 AST로의 변환을 직접 보여줍니다.

앞으로 만들어갈 Toy는 함수를 정의하고 수학 연산을 수행하고 결과를 출력하는 텐서 기반의 언어입니다.

The Language

예시를 통해 Toy 언어를 살펴보겠습니다.

def main() {
  # <2, 3> 형태의 변수 'a' 정의
  var a = [[1, 2, 3], [4, 5, 6]];

  # 변수 'b'는 'a'와 동일
  # ㄴ 암묵적으로 재구조화 되기 때문임
  var b<2, 3> = [1, 2, 3, 4, 5, 6];

  # transpose()와 print()는 빌트인 함수로 제공
  # 'a'와 'b'를 전치한 뒤 요소별 곱셈을 수행한 결과를 출력
  print(transpose(a) * transpose(b));
}

Toy 언어는 다음과 같은 옵션을 가지고 있습니다.

  • 텐서 연산 지원
  • 변수는 불변
  • 데이터 타입은 64비트 부동 소수점 타입 (= C에서의 double)
  • 타입 추론을 통해서 변수나 함수의 타입이 자동으로 결정
  • 필요한 때에 따라 텐서의 형태 명시
  • 함수의 매개변수는 텐서임은 아나 차원을 모르는 식으로 정의. 호출될 때마다 해당 텐서의 차원에 맞게 특수화된 형태로 처리

이러한 옵션들을 고려하며 Toy Language를 활용해 사용자 정의 함수를 추가해 보겠습니다.

# 차원을 모르는 매개변수에 대해 작동하는 사용자 정의 제네릭 함수
def multiply_transpose(a, b) {
  return transpose(a) * transpose(b);
}

def main() {
  var a = [[1, 2, 3], [4, 5, 6]];
  var b<2, 3> = [1, 2, 3, 4, 5, 6];

  # multiply_transpose(a, b)의 a, b를 <2, 3> 형태로 특수화
  # 반환 타입을 <3, 2>로 유추해서 변수 'c' 초기화
  var c = multiply_transpose(a, b);

  # 동일하게 <2, 3> 형태로 매개변수 호출
  # 반환 타입은 <3, 2>
  var d = multiply_transpose(b, a);

  # <3, 2> 형태의 매개변수 호출 (앞선 코드와는 다른 특수화 유발)
  var e = multiply_transpose(c, d);

  # <2,3> 형태인 'a'와 <3, 2> 형태인 'c'는 서로 형태가 맞지 않으므로 형태 추론 오류가 발생
  var f = multiply_transpose(a, c);
}

The AST

위 코드에 대한 AST는 아래와 같이 간단하게 나타낼 수 있습니다.

Module:

# 사용자 정의 함수인 multiply_transpose() 함수
  Function 
    Proto 'multiply_transpose' @test/Examples/Toy/Ch1/ast.toy:4:1
    Params: [a, b] # 매개 변수
    Block {
      Return
        BinOp: * @test/Examples/Toy/Ch1/ast.toy:5:25
          Call 'transpose' [ @test/Examples/Toy/Ch1/ast.toy:5:10
            var: a @test/Examples/Toy/Ch1/ast.toy:5:20
          ]
          Call 'transpose' [ @test/Examples/Toy/Ch1/ast.toy:5:25
            var: b @test/Examples/Toy/Ch1/ast.toy:5:35
          ]
    } // Block
    
    # main() 함수
  Function 
    Proto 'main' @test/Examples/Toy/Ch1/ast.toy:8:1
    Params: []
    Block {
      
      # 변수 'a' 선언
      VarDecl a<> @test/Examples/Toy/Ch1/ast.toy:11:3
        Literal: <2, 3>[ <3>[ 1.000000e+00, 2.000000e+00, 3.000000e+00], <3>[ 4.000000e+00, 5.000000e+00, 6.000000e+00]] @test/Examples/Toy/Ch1/ast.toy:11:11
      
      # 변수 'b' 선언
      VarDecl b<2, 3> @test/Examples/Toy/Ch1/ast.toy:15:3
        Literal: <6>[ 1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00] @test/Examples/Toy/Ch1/ast.toy:15:17
      
      # multiply_transpose()를 활용하여 선언한 변수 'c'에 대한 내용
      VarDecl c<> @test/Examples/Toy/Ch1/ast.toy:19:3
        Call 'multiply_transpose' [ @test/Examples/Toy/Ch1/ast.toy:19:11
          var: a @test/Examples/Toy/Ch1/ast.toy:19:30
          var: b @test/Examples/Toy/Ch1/ast.toy:19:33
        ]
        
      # multiply_transpose()를 활용하여 선언한 변수 'd'에 대한 내용  
      VarDecl d<> @test/Examples/Toy/Ch1/ast.toy:22:3
        Call 'multiply_transpose' [ @test/Examples/Toy/Ch1/ast.toy:22:11
          var: b @test/Examples/Toy/Ch1/ast.toy:22:30
          var: a @test/Examples/Toy/Ch1/ast.toy:22:33
        ]
      
      # multiply_transpose()를 활용하여 선언한 변수 'e'에 대한 내용.
      VarDecl e<> @test/Examples/Toy/Ch1/ast.toy:25:3
        Call 'multiply_transpose' [ @test/Examples/Toy/Ch1/ast.toy:25:11
          var: c @test/Examples/Toy/Ch1/ast.toy:25:30
          var: d @test/Examples/Toy/Ch1/ast.toy:25:33
        ]
      
      # multiply_transpose()를 활용하여 선언한 변수 'f'에 대한 내용. 오류가 나는 부분.
      VarDecl f<> @test/Examples/Toy/Ch1/ast.toy:28:3
        Call 'multiply_transpose' [ @test/Examples/Toy/Ch1/ast.toy:28:11
          var: a @test/Examples/Toy/Ch1/ast.toy:28:30
          var: c @test/Examples/Toy/Ch1/ast.toy:28:33
        ]
    } // Block

다음 장에서 위 AST를 MLIR로 변환하는 방법을 살펴보겠습니다.

0개의 댓글