view 2017/2017_08_08/slide.md @ 27:d005b4f353d3

Update slide
author Tatsuki IHA <innparusu@cr.ie.u-ryukyu.ac.jp>
date Tue, 26 Sep 2017 19:06:19 +0900
parents
children
line wrap: on
line source

title: Gears OS
author: Tatsuki IHA
profile:
lang: Japanese
code-engine: coderay

## 研究目的
- 当研究室では  処理の単位を Code Gear、 データの単位を Data Gear を用いて 信頼性が高い並列処理を行う Gears OS を開発している
- Gears OS では Task を Code Gear と実行するときに必要な Input Data Gear と出力するための Output Data Gear の組で表現される。 Input Data Gear/Output Data Gear によって依存関係が決定し、それにそって並列実行を行う.
- 信頼性の確保はモデルチェック、検証等を使用して行う。この信頼性のための計算は通常の計算とは別の階層のメタ計算として記述する。
- また、 メタ計算は信頼性の他に CPU, GPU などの実行環境の切り替え, データ拡張等の柔軟性を提供する。
- 本研究では、 Gears OS の並列処理機構の実装を行う。また、並列処理の検証をメタ計算として記述することで、 並列処理の信頼性を保証する。

## 今週
- par goto の変換script


## par goto

``` c
__code code2(...) {
...
    par goto mult(integer1, integer2, integer3, __exit);
    goto createTask1();
}
```

- 実行するtaskは↓のような感じ
``` c
__code mult(struct Integer* input1, struct Integer* input2, __code next(struct Integer* output, ...)) {
  ...
}
```

- ↓ に変換できれば良い

``` c
__code code2(...) {
...
    struct Context** tasks = (struct Context**)ALLOC_ARRAY(context, Context, 1);
    int taskCount = 0;

    struct Context* task = NEW(struct Context);
    initContext(task);
    task->next = C_mult;
    task->idgCount = 2;
    task->idg = task->dataNum;
    task->data[task->idg] = (union Data*)integer1;
    task->data[task->idg+1] = (union Data*)integer2;
    task->maxIdg = task->idg + 2;
    task->odg = task->maxIdg;
    task->data[task->odg] = (union Data*)integer3;
    task->maxOdg = task->odg + 1;
    tasks[taskCount] = task;
    taskCount++;

    taskManager->contexts = tasks;
    // goto crateTask1();
    taskManager->next1 = C_createTask1;
    goto meta(context, taskManager->taskManager->TaskManager.spawnTasks);
}
```

## par goto
- 中途半端な感じですがこんな変換はできた

``` c
__code code2(...) {
...
    par goto mult(integer1, integer2, integer3, __exit);
}
```

``` c
__code code2(...) {
...
    struct Context** tasks = (struct Context**)ALLOC_ARRAY(context, Context, ?); // ? の部分は一つのcode gear block の par goto の数が入る
    int taskCount = 0;

    struct Context* task = NEW(struct Context);
    initContext(task);
    task->next = C_mult;
    task->idgCount = 2;
    task->idg = task->dataNum;
    task->data[task->idg] = (union Data*)integer1;
    task->data[task->idg+1] = (union Data*)integer2;
    task->maxIdg = task->idg + 2;
    task->odg = task->maxIdg;
    task->data[task->odg] = (union Data*)integer3;
    task->maxOdg = task->odg + 1;
    tasks[taskCount] = task;
    taskCount++;
    // まだ par goto が残ってる
    par goto mult(integer1, integer2, integer3, __exit);
    
    // まだ, TaskManager の spawn に飛ばす変換をしていない
    goto crateTask1();
}
```

## par goto script
- generate\_stub を編集した形
- par goto を見つけると, その cs名.cbcを見に行く

``` perl
sub getDataGear {
    my ($filename) = @_;
    my ($codeGearName, $name, $inTypedef);
    open my $fd,"<",$filename or die("can't open $filename $!");
    while (<$fd>) {
            if (/^typedef struct (\w+)\s*<(.*)>/) {
            ....
            } elsif(/^(.*)par goto (\w+)\((.*)\)/) {
                my $codeGearName = $2;
                if ( -f "$codeGearName.cbc") {
                    &getCodeGear("$codeGearName.cbc");
                }
            }
```

## par goto script
- input と output の数を取りに行く
``` perl
sub getCodeGear {
    my ($filename) = @_;
    open my $fd,"<",$filename or die("can't open $filename $!");
    my ($name,$impln);
    while (<$fd>) {
        if (/^(\w+)(\*)+ create(\w+)\(/) {
            ....
        }
        if (defined $name) {
            ....
        } elsif (/^\_\_code (\w+)\((.*)\)(.*)/) {
            my $codeGearName = $1;
            my $args = $2;
            my $inputCount = 0;
            my $outputCount = 0;
            my $inputIncFlag = 1;
            while($args) {
                if ($args =~ s/(^\s*,\s*)//) {
                }
                if ($args =~ s/^(\s)*\_\_code\s+(\w+)\(//) {
                    $inputIncFlag = 0;
                } elsif ($args =~ s/^(struct|union) (\w+)(\*)+\s(\w+)//) {
                    if($inputIncFlag) {
                        $inputCount++;
                    }
                    else {
                        $outputCount++;
                    }
                } elsif ($args =~ s/(.*,)//) {
                } else {
                    last;
                }
            }
            // ここで code gear 毎のinput, output の数を持っておく
            $codeGear{$codeGearName}->{"input"} = $inputCount;
            $codeGear{$codeGearName}->{"output"} = $outputCount;
        }
    }
}

```

## par goto script
- par gotoの変換

```perl
sub generateDataGear {
    ...
    while(<$fd>) {
            if (...) {
            } elsif(/^(.*)par goto (\w+)\((.*)\)/) {
                # handling par goto statement
                # convert it to the parallel 
                my $prev = $1;
                my $codeGearName = $2;
                my @dataGears = split(/,\s*/, $3);
                my $nextCodeGear = pop(@dataGears);
                my $inputCount = $codeGear{$codeGearName}->{'input'};
                my $outputCount = $codeGear{$codeGearName}->{'output'};
                if (! $inParGoto) {
                    $inParGoto = 1;
                    my $initTasks = << "EOFEOF";
${prev}struct Context** tasks = (struct Context**)ALLOC_ARRAY(context, Context, ?);
${prev}int taskCount = 0;
EOFEOF
                    print $fd $initTasks;
                }

                my $initTask = << "EOFEOF";
${prev}struct Context* task = NEW(struct Context);
${prev}initContext(task);
${prev}task->next = C_$codeGearName;
${prev}task->idgCount = $inputCount;
${prev}task->idg = task->dataNum;
${prev}task->maxIdg = task->idg + $inputCount;
${prev}task->odg = task->maxIdg;
${prev}task->maxOdg = task->odg + $outputCount;
EOFEOF
                print $fd $initTask;
                for my $i (0..$inputCount-1) {
                    print $fd "${prev}task->data[task->idg+$i] = (union Data*)@dataGears[$i];\n";
                }

                for my $i (0..$outputCount-1) {
                    print $fd "${prev}task->data[task->odg+$i] = (union Data*)@dataGears[$inputCount+$i];\n";
                }

                print $fd "${prev}tasks[taskCount] = task;\n";
                print $fd "${prev}taskCount++;\n";
            }
```

## 残っていること
- par goto で実行される cs の stub 生成