1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Polyphony にまつわる 25 の話題Advent Calendar 2017

Day 14

[新機能]: for 文の unroll

Last updated at Posted at 2017-12-13

Python はコンパイラ側から見て非常によくできた言語だと思う。不必要に機能を入れ込んでいない点が何より素晴らしい。コンパイラを作るという視点から見ると普通の機能も別の意味があることに気が付く。

Python だけではないが、foreach のような構文を書ける言語はいくつもある。記述に便利なだけでなく、書き方によってはシリアライズが確定するのでコンパイラのオプティマイゼーションが効きやすくなるだろう。
どういうことか?簡単なリストの for 文を考える。

a_lst = [1, 2, 3, 4, 5]
for e in a_lst:
    print(e)

a_lst は必ず最初から順番にアクセスされる。一方、C で各 for 文では次のようになるだろう。

int a[] = {1, 2, 3, 4, 5};
for (int i = 0 ;i < sizeof(a)/sizeof(int); i++ ) {
    printf("%d\n", a[i]);
}

配列 a は何かに index される(この場合は変数 i)。配列 a がランダムアクセスされないことは、for の中を解析しないとわからない。配列をポインタに変えても本質は変わらない。

表記だけでそのアクセス方法がわかることはコンパイラにとって都合がよい。とりわけ HLS では最適化の可能性が広がる。

unroll の実際

前置きが長くなったが for 文の unroll を使った例を示そう。unroll は for 文の中身をマクロのように展開する。

unroll01.py
from polyphony import testbench
from polyphony import unroll, rule


def unroll01(xs, ys):
    s = 0
    with rule(unroll='full'):
        for i in range(8):
            x = xs[i] + 1
            if x < 0:
                s = s + x
            else:
                s = s - x
            ys[i] = x
            #print(x)
    return s


@testbench
def test():
    data = [1, 2, 3, 4, 5, 6, 7, 8]
    out_data = [0] * 8
    s = unroll01(data, out_data)
    print(s)
    assert -44 == s
    assert 2 == out_data[0]
    assert 3 == out_data[1]
    assert 4 == out_data[2]
    assert 5 == out_data[3]
    assert 6 == out_data[4]
    assert 7 == out_data[5]
    assert 8 == out_data[6]
    assert 9 == out_data[7]


test()

実際に unroll をした場合と、しない場合でのシミュレーション上の結果は 38 clock と 52 clock となった。

unroll の回数が決定できない場合は数字を指定することができる。回数は丁度良い必要はない。この例では 8 のループに対し 3 ずつの展開をする。あまりの 2 は逐次的に実行される。

    with rule(unroll='3'):
        for i in range(8):
            x = xs[i] + 1
            ...後略...

将来的には書き方が変わるかもしれない。最新のバージョンでは次の書き方もサポートされている。with 文を省きインデントの混乱が少なく書けるように設計されている。

def unroll04_a(xs:list):
    sum = 0
    for x in unroll(xs, 4):
        sum += x
    return sum
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?