|
About this site
Entries @ recently
June 07, 2026numru/fftw3とnumo/fftwをGithub actionsで使う
[Computer]
頭の体操を兼ねて、FFT(Fast Fourier Transform)の代表的なアルゴリズムであるCooley-Tukey(素因数分解して高速化)とBluestein(2のべき乗になるようゼロ埋め)をRubyのgemであるgps_pvtのFFT.hとして実装してみました。正しく実装が行われているか比較するためにFFTライブラリとして著名なFFTWとの比較をしようと思い、Rubyのnumru/fftw3(パッケージ名はruby-fftw3)、およびその近代化版であるnumo/fftw(同numo-fftw)と比較をしてみることにしました。Rspec上にてfft_spec.rbでFFT結果の比較をしてみています。 対応するGithub Actions用のCIスクリプトも作りました。テストをパスさせるうえでいくつか嵌った点があるので、ここに書き残しておこうと思います。 まずGithub Actions上でnumru/fftw3とnumo/fftwを標準的なRubyインストールアクションであるruby/setup-ruby@v1にてbundle installさせるために、少々ビルドを外から助けてあげる必要がありました。CIスクリプト上でBUNDLE_BUILD_XXXという環境変数を設定することで、共有ライブラリのパスやファイル名(-l:narray.soとすると標準(=libnarray.so)でないファイル名のライブラリにリンクできる、ldのmanの-lオプションに記載)、コンパイルオプション(narrayは古いのでgcc-15以降でもビルドするには-std=c17が必要)を教えてあげるようにしています。この環境変数はbundle config setでのビルド設定と同様の効果をもたらします。またこの環境変数の命名規則ですが、_(アンダースコア)が2個で.(ドット)に、_が3個で-(ハイフン)になるという仕様があり、ドキュメントに書いてある(Credentials For Gem Sourcesの最後のほう)ものの、気が付くのに時間がかかりました。 次の嵌りポイントはWindows環境におけるFFTWライブラリの調達です。pacmanを使っても良いのですが、最新版を追えてなさそうなのでvcpkgでセルフビルドするようにしました。ビルドを毎回しなくてよいよう、TAServers/vcpkg-cache@v3にてキャッシュも効かせてあります。 最後にWindowsでの嵌りポイントです。numru/fftw3はnarrayパッケージのnarray.soを、numo/fftwはnumo/narrayのnarray.soを参照します。同時に使おうとすると、共有ライブラリ(.so)の内部が違うにもかかわらず、同じ名前(Windowsではパス全体ではなくファイル名しか見てくれない)によりシンボル解決ができず、死にます。gdbで動きをおってみた(こちらのリンクにあるsls(Show Loader Snaps)のビットを立てると十分なログが取れる)ところ、下記のようなエラーがでていました。 warning: 144f4:b6b8 @ -1382925171 - LdrpNameToOrdinal - WARNING: Procedure "na_data_type" could not be located in DLL at base 0x00007FFFD1280000.
warning: 144f4:b6b8 @ -1382925156 - LdrpReportError - ERROR: Locating export "na_data_type" for DLL "C:\Tools\Ruby\Ruby34-x64\lib\ruby\gems\3.4.0\bundler\gems\numo-fftw-d89821146b5c\lib\numo\fftw.so" failed with status: 0xc0000139. 仕方がないので、ライブラリごとにプロセスを分けて比較をします。といってもWindows環境にはforkがないので、別プロセスをopen3(内部的にはspawn)で立ち上げて、drbで通信をしてFFTの結果だけ取り出すことにしました。 技術的に色々細かいこと(特にWindowsの共有ライブラリまわり)を知れたのが良かったです。 00:05 fenrir が投稿 : 固定リンク
|
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/965 August 11, 2025Ruby 3.5のRactorでyield/takeを復活させる
[Computer]
Ruby 3.5(現時点では3.5-dev)で並列実行機構であるRactorの仕様が大きく変わりました。Ractor::Portという通信経路が定義され、別実行されるRactorの外から中への内向き通信経路がRactor#default_portでとりだせるRactor::Portで管理されるようになりました。従来からあるpush型の通信関数であるRactor#sendとRactor.receiveもdefault_portと紐づけられています。 一方、pull型通信であるRactor.yieldとRactor#take(3.4のドキュメントへのリンク)がなくなってしまいました。いちおうtakeは3.5でも残されているのですが、2025/8に除去します、と警告が表示され、また対になるyieldがないので並列実行途中(終了時ではなく)に出したメッセージを取得してくれません。 調べてみたところ、Ractor::Portの提案には3.5でも動くとされる代替策(Ractor.yield and Ractor#take with channel ractor)が記述されているのですが、これが実装ミスでうまく動きません。主な原因として、Ractorのインスタンス生成がinitializeを呼び出さずnewだけで定義されていることによるものと思われます。 そこでRactor.yieldとRactor#takeを3.5でも動くようにしてみました。newされるときに外向きの通信経路をRactor::Portで新たに追加してあげています。またRactor#monitorで終了を監視するようにしました。 上記で手元ではRuby 3.4までのコードをそのまま使うことができています。 08:56 fenrir が投稿 : 固定リンク
|
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/964 July 14, 2025RubyでRactor::Selectorを使う(C APIをRubyから呼び出す)
[Computer]
Rubyで並列処理をするにあたってRuby3から導入されたRactor(日本語のドキュメントが見つからなかったので英語版で…)を使ってみています。まだ試験的導入(Ractor入りのスクリプトを実行すると warning: Ractor is experimental, and the behavior may change in future versions of Ruby! Also there are many implementation issues.とでる)であるため、日々改良が重ねられているようですが、つーすを読んでみると隠し機能があることがわかりました。 Ractor間の通信があったことを補足するRactor::select(*ractors)という関数があるのですが、複数のRactorのメッセージを全て完了するのに、一つずつ減らしながらselectを何度も呼び出すのはオーバーヘッドが大きそうだということに気が付きました。内部的にはRuby 3.3, 3.4ではRactor::Selectorというクラスのインスタンスを生成して、そこにractorsを登録するような仕組みになっていますので、selectを呼ぶためにRactor::Selectorを作ります。もしRactor::Selectorが再利用できれば、オーバーヘッドを少しでも減らせそうです。 しかし残念ながらRactor::Selectorを直接RubyからいじるにはRubyをビルドする時にUSE_RACTOR_SELECTORをdefineする必要がありました。一方よく見てみると、rb_init_ractor_selector()というRactor::SelectorをRubyから見えるようにする関数も公開されていることがわかりました(Ruby 3.4では2567行目付近、3.3も同様の定義です)。 Rubyをビルドしなおすのも少々面倒なので、ここからはサブタイトルになっているRubyのC API(今回でいうとrb_init_ractor_selector)を呼び出すことを考えます。C関数を呼び出せるFFIまたはFiddleを使うことにしました。下記のコードで達成できます。Using Ruby's C API inside Rubyが参考になりました。 最後にもともとのRactor::selectの効率化ですがRactor::Selector#wait, #removeなどが定義されていますので、これを使って実現しました。 00:33 fenrir が投稿 : 固定リンク
|
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/963 July 24, 2024HDL-AAX2 シャットダウンスクリプト
[Computer]
自宅NASのIO-DATA HDL-AAX2ですが、リモートでシャットダウンする必要があり、方法を検討しました。少し古い機種のHDL2-Aのシャットダウンスクリプトが見つかったのですが、それをそのまま適用することはできなかったので、少し改造して使うことにしました。 出来上がったのが以下のRubyスクリプトです。 mechanizeというwebの自動巡回を可能とするgem(クローラ)を使うことで実現しています。少し古いRuby(< 2.6.0)でも簡潔に書けるよう、Kernel#thenがない場合に備えて自己定義しています(古いRubyに最新の機能を入れ込むbackports gemのKernel#yield_selfのコードを参考にしました)。 00:12 fenrir が投稿 : 固定リンク
|
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/962 July 04, 2024曜日を求める(8bit範囲で)マイコンを使って年月日から曜日を求めたいケースがありました。普通の環境ならC言語を前提とすれば<time.h>にあるmktime関数とlocaltime関数を使うことで実現できます。
11:40 fenrir が投稿 : 固定リンク
|
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/961 April 02, 2024Assisted GPS (A-GPS)クライアントの実装GPS関係の処理をRubyから使えるようにしたgps_pvt gemは色々なストリームやファイル、シリアルポート(GPSデバイス直結)から情報を読み込めるようにしてあります。このたびv0.10で初期測位を早めるためのAssisted GPS (A-GPS)に対応しました。単独測位をするのであればgemをインストール後に以下のコマンドで例えばAndroidなどて使われているGoogleのサーバから情報を取得してA-GPSを利用できます。 $ gps_pvt supl://supl.google.com/ (Ntrip等のリアルタイムストリームを指定)
生データに近い物が見たければ、以下のコマンドでJSON形式でエフェメリス等が得られます。 $ gps_get supl://supl.google.com/
エフェメリス(軌道情報)を読み込む程度なので実装は簡単かなと思って始めたのですが、結果的に色々調べる必要がありました。羅列ですが、調べたものを残しておこうと思います。
最後におまけとなりますが、SUPLサーバに対しては携帯のようにIMEIを渡すわけではなく、問い合わせホストのGlobal IPを渡すようにしてみています。 22:39 fenrir が投稿 : 固定リンク
|
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/960 March 17, 2024HDL-AAX2の修理
[Computer]
自宅NASのIO-DATA HDL-AAX2から少し異音がしていたので確認してみたところ、ファンから異音が出ていました。そこで修理をしてみることにしました。 元々ついていたファンはSunonのHA40101V4-1Q01C-F99というファンでした。残念ながら全く同じ型番のファンを見つけることができませんでしたが、DC12Vで40mm角の10mm厚、回転パルス出力付きのものであれば交換可能だろうということで、違うものに変えてみました。選んだのはAINEX CFY-40SAです。 ぴったりはまりました。コネクタだけは加工する必要があって、秋月電子や千石電商などで買えるJST XHシリーズの3ピンコネクタ(ハウジング:XHP-3, コンタクト:SXH-001T-P0.6)に付け替えています。 23:36 fenrir が投稿 : 固定リンク
|
このエントリーのトラックバックURL: https://fenrir.naruoka.org/mt/mt-tb.cgi/959 |
最近のはてブられ
かてごり~別
Aero & Astro (100)
Computer (192) Embedded System (308) Info (14) Mountain (43) Movable Type (28) Movie & Animation (20) Music (9) Photo (47) Site Management (46) Timely (135) Tips (68) ついったー
|