Windows(MSVC)でmrubyからGPU対応のTensorflowを動かせた
こんにちは、長男が高熱をだし、時期が時期なので、インフルエンザを疑ったのですが、陰性で、その後もしばらく高熱がつづいたのですが、今では熱が下がり、大好きなYouTubeを見てます。@kjunichiです。
やったこと
タイトルの通りですが、以前このブログでも話題にしたmrubyかJuliaを呼び出せるmruby-juliaをWindowsのMSVC環境で動かせるようにして、 そこからJuliaからPythonを呼び出せるPyCallを経由して、すでにセットアップ済みのGPU対応のTensorflowを動かせました
mruby-juliaをwindows(MSVC)に対応することに成功したので、#mruby からGPUありの#tensorflow が動かせた! https://t.co/LCUGa1P9Ee pic.twitter.com/KrcAqh7VDB
— kjunichi (@kjunichi) 2017年1月27日
JuliaをMSVC環境で動かそうとして分かったこと
.libファイルが必要
JuliaのWindows版はMinGWでビルドされているので、MSVCで動かすには.libファイルを作る必要がりました。
MSVCではCではJuliaを組み込めない
さらに、CからJuliaを呼び出すことは出来ず、C++からでないと、ダメでした。 そのため、mruby-juliaは元々Cオンリーであったのを、JuliaのAPIを叩く箇所をC++化して対応しました。 (mrubyでC++を使ったmrbgemを使うとちょっと問題があるのですが、これは別の記事で書く予定)
mrubyからTensorflowを呼び出す
事前準備
Juliaであらかじめ環境変数PYTHONをGPUが有効なTensorflowが使えるPythonに設定した状態で、
Pkb.add("PyCall")
もしくは、
Pkb.build("PyCall")
しておく。
サンプルコード
j=Julia.new j.eval("using PyCall") j.eval("string(@pyimport tensorflow as tf)") j.eval('sess = tf.Session()') j.eval('a = tf.constant(10)') j.eval('b = tf.constant(32)') j.eval('sess[:run](pyeval("a + b", a=a, b=b))') p j.eval('string(sess[:run](pyeval("a + b", a=a, b=b)))')
成果物
関連記事
- mruby-juliaでPythonもmrubyから呼び出せるようになった - non vorrei lavorare
- Tensoflowのclassify_image.pyにElectronでGUIを被せてみた
- Raspberry Pi3でTensorflowをビルドして動かした
12年前の記事
11年前の記事
- vlcがインストールできない
- SETI@home について
- 最大表示解像度
- Starting tomcat5: /usr/bin/rebuild-jar-repository: error: could not find jta Java extension for this JVM
2年前の記事
1年前の記事
Windowsでmruby-http2を動かした
こんにちは、kindle fireでYouTubeで車モノ(knight riderやワイルドスピード)の映像を中毒患者の様に見まくる長男からタブレットを修理に出したといって、隔離してしばらくたち、今のところ、長男は隙を見て奥さんがおもに使っているChromebookでYouTubeを見ています。@kjunichiです。
mruby-http2 for win32
Xeonで昨年末久々にPC組んだ流れで、Windowsでの開発環境をあれこれ試している。 そんな中、今回はmrubyでhttp2をしゃべることが可能になるmrbgemのmruby-http2をWindowsで動かしてみた。
事前に必要なモノ
- openssl
- libevent
- nghttp2
- zlib
zlib以外は、
- Windows 10でMSVCでnghttp2のサンプルを動かす
の記事に少し書いてます。
ヘッダ無い問題
以下に挙げるヘッダがWindowsでは用意されていない模様。
- pwd.h
- unistd.h
- sys/socket.h
- sys/wait.h
- sys/resource.h
- sys/queue.h
- netdb.h
- netinet/in.h
- netinet/tcp.h
- poll.h
- signal.h
- pthread.h
- err.h
定数無い問題
mruby-http2をWindowsでビルドする際、以下の定数が未定義でエラーとなった。
- F_GETFL
- O_NONBLOCK
- SHUT_WR
型や構造体無い問題
mruby-http2をWindowsでビルドする際、以下の型が未定義でエラーとなった。
- ssize_t
- uid_t
- nfds_t
- struct pollfd
関数無い問題
mruby-http2をWindowsでビルドする際、以下の関数が未定義でエラーとなった。
- pipe
- fcntl
- alloca
- gmtime_r
- fork
- TAILQ_FOREACH
- kill
- daemon
pipe
_pipeなる関数が用意されており、これを用いることで対応出来た。 ただし、引数がUNIXのpipeと異なり3つ必要。
#ifndef _WIN32 rv = pipe(pipefd); #else rv = _pipe(pipefd, 65535, _O_BINARY); #endif
作成するパイプのバッファサイズの指定は決め打ちで暫定的に対処した。
fcntl
mruby-http2ではfcntlでソケットをノンブロッキング指定にする為に用いられていた。 Windowsではこのような用途にはioctlsocketを用いることで対応出来た。
#ifndef _WIN32 while ((flags = fcntl(fd, F_GETFL, 0)) == -1 && errno == EINTR) ; if (flags == -1) { mrb_raisef(mrb, E_RUNTIME_ERROR, "fcntl: %S", mrb_str_new_cstr(mrb, strerror(errno))); } while ((rv = fcntl(fd, F_SETFL, flags | O_NONBLOCK)) == -1 && errno == EINTR) ; if (rv == -1) { mrb_raisef(mrb, E_RUNTIME_ERROR, "fcntl: %S", mrb_str_new_cstr(mrb, strerror(errno))); } #else flags = 1; rv = ioctlsocket(fd, FIONBIO, &flags); if (rv != NO_ERROR) { mrb_raisef(mrb, E_RUNTIME_ERROR, "ioctlsocket: %S", mrb_str_new_cstr(mrb, "error")); // TODO } #endif
シグナルがWindowsでないと勘違いしてた問題
シグナル周りは一旦全部コメントアウトして無視することにして対応した。
- struct sigaction
- sigaction
関数自体を無効にしたものたち
単純にWindowsで動かすにには不要な機能はスパッと諦めて作業した。 その結果、以下の関数は、戻るだけだったり、固定値を返すだけにしたり、関数そのものをコメントアウトした。
- mrb_http2_get_uid
- mrb_http2_config_get_worker
- tune_rlimit
成果物
mrubyのbuild_config.rbに以下を記述することでwindowsでビルド可能なmruby-http2が利用できるハズ。
conf.gem :github => 'kjunichi/mruby-http2', :branch => 'support-for-win32'
まとめ
クライアントは、これらの問題を解決することで、動かせた。 サーバー側は、さらに対応が必要だった。これはまた、別の記事にするつもり。
ちなみに、mruby-cliでバイナリを作る場合は、今回のMSVCの対応とは別にmingw-w64での対応が必要となる。 もし、dockerを使わず直接Windows上でmruby-cliでワンバイナリをMSVCで作製すれば、今回のmrbgemが使えるかもしれません。
関連記事
- http2 ハッカソン #5に行ってきた
- libtrusterdでHTTP/2でphpを動かして分かったことのその後 #知見
- Windows 10でMSVCでnghttp2のサンプルを動かす
- Windows(MSVC)でmrubyからGPU対応のTensorflowを動かせた
- WindowsでDLLを作ろうとしてmrb_context_runの歴史を調べた
11年前の記事
10年前の記事
9年前の記事
8年前の記事
7年前の記事
6年前の記事
5年前の記事
Rust入門者向けハンズオン #2 に行ってきた
#
VS CodeだからRustどうだろと思ったが、ちゃんとVS Code向けにCargoと連携できることを知った。
— kjunichi (@kjunichi) 2017年1月15日
今日は面接じゃないから落とされる心配なしw (@ 渋谷ヒカリエ in 渋谷区, 東京都) https://t.co/moykmzhSxD
— kjunichi (@kjunichi) 2017年1月15日
#Rust_jp ヒカリエ17Fやっぱり11Fの受付で待つこに、無事、会場に上がれた。
— kjunichi (@kjunichi) 2017年1月15日
CSSのレンダリングもRustでの実装に置き換えようとしてるとのこと #rust_jp
— kjunichi (@kjunichi) 2017年1月15日
Typeに近いんじゃにかと < cat #rust_jp
— kjunichi (@kjunichi) 2017年1月15日
#Rust_jp Rustなら、ディレクトリも作らなくて、Hello Worldできるのか! https://t.co/Gs9eBWjaNe pic.twitter.com/jsqn6Fp9bf
— kjunichi (@kjunichi) 2017年1月15日
動いた! https://t.co/uSDAIwuPGL pic.twitter.com/KRT5X6plkY
— kjunichi (@kjunichi) 2017年1月15日
OCamlのletどうだっけかなぁとふと思った。 #Rust_jp
— kjunichi (@kjunichi) 2017年1月15日
「;」つけない関数末尾はreturn 文なのかなぁ #rust_jp
— kjunichi (@kjunichi) 2017年1月15日
再帰呼び出しっていうと、末尾再帰が気にあるが、できるらしいが、何か制約があるような #Rust_jp
— kjunichi (@kjunichi) 2017年1月15日
行単位で文字列を取ってくることに苦戦中 #rust_jp
— kjunichi (@kjunichi) 2017年1月15日
なんとかlinesで取得したイテレータを回せたが、今度は行番号が全部1で出力された #rust_jp
— kjunichi (@kjunichi) 2017年1月15日
let num = num + 1;
では、numが加算されなかった。
OpenCVでカメラの画像を表示するやつが以前Rustで作っていたが、これ今のRustでも動いた もくもくタイムに少し進められると良いが、catコマンドでも力尽きそうw #rust_jp
— kjunichi (@kjunichi) 2017年1月15日
linesで行単位で文字列を取り出せることがわかったが、スタックオーバーフローのコードのSomeがまさかRustの命令?とはおもわず、これでてこずった #rust_jp
— kjunichi (@kjunichi) 2017年1月15日
関連記事
- RustでFaceTime HDカメラやWebカメラを使う
- RustでOpenGLやGLSLやる準備
- macOS Sierraにしたらrustが暴走して、黒い画面には入れなくなった #解決済み
- Rustで多次元配列を扱うには
- libtrusterdをRustで動かした
- RustでWebカメラの映像をコマンドプロンプトに出すコマンドを作った
- 2018年版、Rustで多次元配列を使うには