원문: 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는 함수를 정의하고 수학 연산을 수행하고 결과를 출력하는 텐서 기반의 언어입니다.
예시를 통해 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 언어는 다음과 같은 옵션을 가지고 있습니다.
이러한 옵션들을 고려하며 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);
}
위 코드에 대한 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로 변환하는 방법을 살펴보겠습니다.