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 の並列処理機構の実装を行う。また、並列処理の検証をメタ計算として記述することで、 並列処理の信頼性を保証する。 ## 今週 - 前回の Executor interface の呼び出し側 - primitive な型 を union Data に入れられるようにする ## Executor interface の呼び出し - 例: twice_stub - buffer に gpu に送りたい Data を指定 ``` c __code twice_stub(struct Context* context) { #ifdef USE_CUDAWorker if (context->gpu) { Array* inputArray = &context->data[context->idg]->Array; Array* outputArray = &context->data[context->odg]->Array; outputArray->array = inputArray->array; // setting buffer CUDABuffer* buffer = &ALLOCATE(context, CUDABuffer)->CUDABuffer; buffer->inputData = (union Data**)ALLOCATE_PTR_ARRAY(context, Array, 2); buffer->inputData[0] = (union Data*)inputArray->array; buffer->inputData[1] = (union Data*)inputArray; buffer->outputData = NULL; buffer->inputLen = 2; buffer->outputLen = 0; Executor* executor = context->worker->worker->CUDAWorker.executor; executor->executor->CUDAExecutor.buffer = buffer; cudaLoadFunction(context, "c/examples/twice/CUDAtwice.ptx", "twice"); Gearef(context, Executor)->executor = (union Data*)executor; Gearef(context, Executor)->task = context; Gearef(context, Executor)->next = context->next; goto meta(context, executor->read); } #endif ``` ## Cuda Executor の実装 - いまは read->exec->write の順番で continuation する(パイプラインを実装するともちろん変わる) ``` __code readCUDAExecutor(struct CUDAExecutor* executor, struct Context* task, __code next(...)) { struct CUDABuffer* buffer = executor->buffer; ... // TODO: Implements pipeline // goto next(...); goto meta(context, C_execCUDAExecutor); } __code execCUDAExecutor(struct CUDAExecutor* executor, struct Context* task, __code next(...)) { // Asynchronous launch kernel task->num_exec = 1; ...... // TODO: Implements pipeline // goto next(...); goto meta(context, C_writeCUDAExecutor); } __code writeCUDAExecutor(struct CUDAExecutor* executor, struct Context* task, __code next(...)) { struct CUDABuffer* buffer = executor->buffer; ... goto next(...); } ``` ## primitive な型 を union Data のメンバーにする - 今までは union Data の中には struct のみしか書けなかった - なのでint 等をを使うときはわざわざ struct を定義してその中に int を メンバーを定義していた - ちょっと不便なので, union Data の中に定義出来るようにしてみました - int int だと error 吐くので, 一度 typedef を挟む必要がある - perl script も変更 - struct 前提だったので,,,, ``` c typedef int Int; union Data { struct Meta { enum DataType type; long size; long len; struct Queue* wait; // tasks waiting this dataGear } Meta; ... Int Int; }; // union Data end this is necessary for context generator ```