# HG changeset patch # User Tatsuki IHA # Date 1509441376 -32400 # Node ID 382cd93f2a60f03165b4106b2f588eaf494b36ca # Parent d005b4f353d307cacc431de3ee1bf1d02a8da33b Update slide diff -r d005b4f353d3 -r 382cd93f2a60 2017/2017_10_10/slide.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/2017/2017_10_10/slide.md Tue Oct 31 18:16:16 2017 +0900 @@ -0,0 +1,68 @@ +title: Akatsuki の Rails 5.1 へのUpdate +author: いんぱるす@きりん +profile: +lang: Japanese +code-engine: coderay + +## 目的 +現状のAkatsukiはRails 4.2.6 で運用されている。 +しかし、今年の4月にRails 5.1がリリースされ、Rails 4系は重要なセキュリティfix 以外はサポートされなくなった。 +そのため、現状の最新版5.1.4 にUpdateすることを目的とする(ついでに秋のLT大会があったので発表する) + +## 今週 +- Rails 4.2.6 -> 5.1.4 +- Rails 5.1 がリリースされたときに, Rails 4 はほぼサポートされなくなってしまった +- 内定式の動画づくり、編集 (次話し振られて,強制されたらこの会社辞めますって人事に言いました) + +## 基本的には +- 4.2.6 -> 5.0.6 -> 5.1.4 +- ``$ ./bin/rails app:update`` でいい感じに merge してあげる +- あとは, [Railsアップグレードガイド](http://guides.rubyonrails.org/upgrading_ruby_on_rails.html) に従う + +## ハマったとこ +- rspec でテストを一気に走らせると事故るケースがある +- 失敗した所に binding.pry をかけると, ActiveLdap(学科アカウントとの連携で使われるもの) で association先がうまく取れない場合がある + +``` ruby +class LDAP::User < ActiveLdap::Base + .... + #ここがうまく取れない場合がある + belongs_to :groups, class_name: 'LDAP::Group', many: :memberUid +... +end +``` + +## 原因 +- LDAP::User が取れるはずの場所で LDAP::User を継承した class が 取れるときがあった +- 継承先ではassociationの記述がないため, association 先のclassが取れないのが原因っぽいのがわかった + - 新しい ActiveLdap の version では ActiveRecord の STI(single table inheritance) っぽいことをサポートしていた +- Akatsuki では継承先で取れても問題はなかったので, 継承先に association を書くことで対応 + +``` ruby +pry(main)> (LDAP::User.find ("akatsuki")).class +=> API::LDAP::Felica(objectClass:gpu) { + struct Array* array = &context->data[context->idg]->Array; + struct CudaBuffer* buffer = &ALLOCATE(context, CudaBuffer)->CudaBuffer; + buffer->inputData = (union Data**)ALLOCATE_PTR_ARRAY(context, Array, 2); + buffer->inputData[0] = (union Data*)array->array; + buffer->inputData[1] = (union Data*)array; + buffer->outputData = NULL; + buffer->inputLen = 2; + buffer->outputLen = 0; + cudaExec(context, buffer, "c/examples/twice/CUDAtwice.ptx", "twice"); + //continuationにそってGPUworkerに戻る + goto meta(context, context->next); + } +#endif + goto twice(context, + &context->data[context->idg]->Array, + &context->data[context->idg+1]->MultiDim, + context->next, + Gearef(context, LoopCounter)); +} +``` + +## cudaRead +- buffer に入れた DataGear を cuda に allocate, 送信 + +``` c +void cudaRead(struct CudaBuffer* buffer) { + buffer->kernelParams = (void **)calloc(buffer->inputLen + buffer->outputLen, sizeof(void *)); + int paramCount = 0; + for (int i = 0; i < buffer->inputLen; i++) { + CUdeviceptr* deviceptr = (CUdeviceptr *)calloc(1, sizeof(CUdeviceptr)); + // memory allocate + checkCudaErrors(cuMemAlloc(deviceptr, GET_SIZE(buffer->inputData[i]))); + // Synchronous data transfer(host to device) + checkCudaErrors(cuMemcpyHtoD(*deviceptr, buffer->inputData[i], GET_SIZE(buffer->inputData[i]))); + buffer->kernelParams[paramCount++] = deviceptr; + } + + for (int i = 0; i < buffer->outputLen; i++) { + CUdeviceptr* deviceptr = (CUdeviceptr *)calloc(1, sizeof(CUdeviceptr)); + // memory allocate + checkCudaErrors(cuMemAlloc(deviceptr, GET_SIZE(buffer->outputData[i]))); + // Synchronous data transfer(host to device) + checkCudaErrors(cuMemcpyHtoD(*deviceptr, buffer->outputData[i], GET_SIZE(buffer->outputData[i]))); + buffer->kernelParams[paramCount++] = deviceptr; + } +} +``` + +## cudaExec2 +- *cudaLaunch* とか *cudaLaunchKernel* にしたかった. すでにcuda側で使われているらしい(この辺の名前は後で要修正) +- cudaRead で設定した kernelParams(CUdeviceptr) を launchKernel に引き渡す + +``` c +void cudaExec2(struct Context* context, struct CudaBuffer* buffer) { + // Asynchronous launch kernel + context->num_exec = 1; + if (context->iterate) { + struct MultiDimIterator* iterator = &context->iterator->iterator->MultiDimIterator; + checkCudaErrors(cuLaunchKernel(context->function, + iterator->x, iterator->y, iterator->z, + 1, 1, 1, + 0, NULL, buffer->kernelParams, NULL)); + + } else { + checkCudaErrors(cuLaunchKernel(context->function, + 1, 1, 1, + 1, 1, 1, + 0, NULL, buffer->kernelParams, NULL)); + } +} +``` + +## cudaWrite +- 実行した結果を指定した DataGear に書き出す + - input にそのまま結果を書き出す場合もある. flip 的なものも実装しないと +- 後使用した領域の free + +``` c +void cudaWrite(struct CudaBuffer* buffer) { + //結果を取ってくるコマンドを入力する + //コマンドの終了待ちを行う + int paramCount = 0; + for (int i = 0; i < buffer->inputLen; i++) { + CUdeviceptr* deviceptr = buffer->kernelParams[paramCount++]; + checkCudaErrors(cuMemcpyDtoH(buffer->inputData[i], *deviceptr, GET_SIZE(buffer->inputData[i]))); + cuMemFree(*deviceptr); + free(deviceptr); + } + + for (int i = 0; i < buffer->outputLen; i++) { + CUdeviceptr* deviceptr = buffer->kernelParams[paramCount++]; + checkCudaErrors(cuMemcpyDtoH(buffer->outputData[i], *deviceptr, GET_SIZE(buffer->outputData[i]))); + cuMemFree(*deviceptr); + free(deviceptr); + } + free(buffer->kernelParams); + // wait for stream + checkCudaErrors(cuCtxSynchronize()); +} +``` + +## 次は +- RBTree の deletion +- Perl script をどうにかする +- 並列処理の検証をどうするか diff -r d005b4f353d3 -r 382cd93f2a60 2017/2017_10_24/slide.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/2017/2017_10_24/slide.md Tue Oct 31 18:16:16 2017 +0900 @@ -0,0 +1,70 @@ +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 の並列処理機構の実装を行う。また、並列処理の検証をメタ計算として記述することで、 並列処理の信頼性を保証する。 + +## 今週 +- Raspberry Pi で arm な xv6 の起動 +- Raspberry Pi 3 で cbclang の build + +## Raspberry Pi zero で arm な xv6 の起動 +- 最初は ソースコード読み会で用意したもの(https://github.com/david50407/xv6-rpi)を arm-none-eabi-gcc を使ってbuild +- しかし, README にも Raspberry pi での install 方法が書かれてない(Qemu での Debug のみ、、、) +- ググると別の実装で install 方法が書かれてたのでそいつを使う方針に(https://github.com/zhiyihuang/xv6_rpi_port) + - Architecture の設定も zero と同じで march=armv6 mcpu=arm1176jzf-s だったので +- このProject を make すると img が生成された + +## Raspberry Pi zero で arm な xv6 の起動 +- できたimg を boot SDカードに任意な名前で配置 +- boot/config.txtに以下を追記 + +``` +kernel=kernel-xv6.img +``` + +- これで起動はできました(shell は起動できてるっぽいが, キーボード入力は受け付けず) + +## Raspberry Pi 3 で cbclang の build +- xv6起動したついでに cbclang もbuildしてみることに + - 流石に zero じゃ無理だろうと判断し, Raspberry Pi 3 で(Raspbian) + - https://llvm.org/docs/HowToBuildOnARM.html を参考に + - ninja も使ってみた + +``` +$ mkdir CbC_build; cd $_ +$ cmake -G Ninja -D CMAKE_BUILD_TYPE=Release LLVM_TARGETS_TO_BUILD="ARM;X86;AArch64" CMAKE_INSTALL_PREFIX:PATH=pwd /path/to/cbc +$ ninja +``` + +## Raspberry Pi 3 で cbclang の build +- しかし, めちゃくちゃ遅い(4時間くらい放置してもninjaのシーケンスは 1800個中10個も進まない) +- ninja を使わず, cmake -> make -j2 でやることに + +``` +$ cmake -D CMAKE_BUILD_TYPE=Release LLVM_TARGETS_TO_BUILD="ARM;X86;AArch64" CMAKE_INSTALL_PREFIX:PATH=pwd /path/to/cbc +$ make -j2 +``` + +- その後睡眠 +- 起きると通ってた + +## Gears の make +- 試しに Gears の twice を make -> 通る +- しかし実行するとセグフォ +- 怪しい所として, まず context を生成する際に取る領域が多い?(context1つデータ領域2.7Gくらい取ってるらしい) +- 2桁くらい減らすと実行できた + +## CbClang をつかって xv6 を make してみる +- クロスコンパイラで成功したxv6 で make +- できた img を Raspberry Pi zero で起動 + - 起動失敗(kernel読み込みにはいってるっぽい?) +- 試しに Raspbian の gcc で make + - 起動成功 diff -r d005b4f353d3 -r 382cd93f2a60 2017/2017_10_31/slide.md --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/2017/2017_10_31/slide.md Tue Oct 31 18:16:16 2017 +0900 @@ -0,0 +1,64 @@ +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 の並列処理機構の実装を行う。また、並列処理の検証をメタ計算として記述することで、 並列処理の信頼性を保証する。 + +## 今週 +- cuda 関連のものを Interface にする(まだ途中) +- Jenkins の update + +## Executor interface +- 今は実装としてはCuda のみ, OpenCL とかも実装する +- 将来的にはパイプラインで乗っけられるようにするために methodは + - read + - exec + - write +- task, buffer は引数として取る + +``` +typedef struct Executor{ + union Data* Executor; + struct Context* task; + struct Buffer* buffer; + __code read(Impl* executor, struct Context* task, struct Buffer* buffer, __code next(...)); + __code exec(Impl* executor, struct Context* task, struct Buffer* buffer, __code next(...)); + __code write(Impl* executor, struct Context* task, struct Buffer* buffer, __code next(...)); +} +``` + +``` +struct CudaExecutor { + void** kernelParams; +} CudaExecutor; +``` + + +## CudaExecutor +- create は他のinterface の実装と基本同じ +- read, write, exec 辺りは前回の発表のコードを CG に書き換え + - 前回注意された for の中で calloc 等は修正 + - 最終的には CuDevicePtr とかも ALLOCATE(context, CuDevicePtr) みたいに取れるようにしたい + +``` +Executor* createCudaExecutor(struct Context* context) { + struct Executor* executor = new Executor(); + struct CudaExecutor* cudaExecutor = new CudaExecutor(); + executor->executor = (union Data*)cudaExecutor; + executor->read = C_readCudaExecutor; + executor->exec = C_execCudaExecutor; + executor->write = C_writeCudaExecutor; + return executor; +} +``` + +## まだできてない +- このinterface を呼び出す部分(基本的には関数呼び出しの場所をgoto にしてきちんと継続すればいいはず) +- このinteface のメソッド呼び出しは stub でやるべき?