トップ(最新)

nDiki : XS

スポンサード リンク

Related term

2004年2月19日 (木)

[ Perl ] PDL::PP で C extension を書く このエントリーを含むはてなブックマーク

スポンサード リンク

PDLを使ったPerl数値処理プログラムによりインタラクティブ性が求められるようになってきたので、一部をCで書いて高速化する事を検討。 問題は Linux でも Windows + ActivePerl でもすんなり動くかどうか。

@ .pd ファイルを書く

とりあず PDL::PP のサンプルから sumit 関数あたりを MathEx.pd に書いておく。

@ Makefile.PLを修正する

Foo::Bar パッケージの中の Foo::Bar::Math の一部を Foo::Bar::MathEx に移して、C extension 化したい。 ということで lib/Foo/Bar/MathEx.pd として、Makefile.PL の各種設定をしてみる。

がどうもうまくいかない。 PDL::PPMakefile.PLサポートは、Makefile.PL と同じ位置に .pd がある事を想定しているようなので、いろいろと小細工をしなければならない。 一方 PerlXS は Foo::Bar のベース名から Bar.so を作る前提になっているようで、これまたパッケージの中の一部のモジュールをどうもXS化しにくい。

@ 子Makefile.PLを作る

Perl の ext/SDBM_File を真似て、子 Makefile.PL を使ってみることにした。

 Foo-Bar-x.xx
   |
   +- Makefile.PL
   |
   +- lib
   |    |
   |    +- Foo
   |         |
   |         +- Bar.pm
   |         |
   |         +- Bar
   |              |
   |              +- Math.pm
   |              |
   |              +- MathNoEx.pm
   |              |
   |              ...
   |
   |
   +- blib/...
   |
   +- MathEx
   |    |
   |    +- Makefile.PL
   |    |
   |    +- MathEx.pd
   ...

パッケージディレクトリの下に MathEx ディレクトリを作り、そこに Makefile.PL と MathEx.pd を置く。 Makefile.PL は MathEx.pd 専用になるので、PDL::PP の標準的なものでOKになる。

全体のパッケージング・PPM化・インストール等が面倒にならないかと心配したが、Foo-Bar パッケージ化で perl Makefile.PL、make xxx を実行すれば子Makefile.PLまできちんと面倒をみてくれる。 MathEx 以下でビルドしたものもパッケージの blib に一緒に入れてくれるし(=一緒にインストールできる・PPM化できる)。 逆に make dist の際には子Makefileの方は余計なとりまとめはしないで、親Makefileが一括して tar.gz に入れてくれる。 これはよい。 MathEx.pd もきちんと Foo/Bar/MathEx.so になった。

@ XSが使えない環境との両対応

XSが使えない環境のために、PerlとPPの両方で関数を書いておく。 XSが使えれば MathEx を、使えなければ MathNoEx.pm を使うように。 表向きのAPIは Foo::Bar::Math とし、ここで AUTOLOAD を使ってどちらか一方を呼び出すようにする。 間接呼び出しにして遅くなるのはいやなので、シンボルテーブルを直接設定する。

 use vars qw($IMPLEMENT_CLASS $AUTOLOAD);
 BEGIN {
   $IMPLEMENT_CLASS = 'Foo::Bar::MathEx';

   eval "use $IMPLEMENT_CLASS";
   if ($@) {
     warn "Can't load $IMPLEMENT_CLASS: $@";
     $IMPLEMENT_CLASS = 'Foo::Bar::MathNoEx';
     eval "use $IMPLEMENT_CLASS";
     die $@ if $@;
   }
 }

 sub AUTOLOAD {
   my $name = $AUTOLOAD;
   $name =~ s/.*://;
   my $implement = $IMPLEMENT_CLASS . '::' .$name;
   no strict "refs";
   *{$name} = \&{$implement}; # ここでシンボルテーブル設定
   return &{$implement}(@_);
 }

最初は、AUTOLOAD の最後の行で die したら、trap してエラーメッセージ中のパッケージ名(Foo::Bar::MathEx や Foo::Bar::MathNoEx)を呼び出された Foo::Bar::Math に置換して die し直すようにしようかと思ったが面倒なのでやめ。

@ ActivePerl 5.6 + Visual C++ 6

使っているWindows BOX には Visual C++ 6 が入っているので、XSも問題なくビルドでき PDL extension もうまく動いた。

 PPM化までここで済ませば、他のPCにも持っていけるはず。

@ さて

これでバシバシPPで書けるわけだが、PPがこれまた難解で最初は苦労しそう。

■ Twitter やってます。この記事が気にいったらぜひ twitter.com/Naney の follower になってください。

Google Buzz はよろしければ Naney の Google プロフィールからどうぞ。


[ 2月19日全て ]

2004年7月20日 (火)

PARActivePerl 5.6.1 build 638 に このエントリーを含むはてなブックマーク

昨日 Linux 上で実験してみた PARWindows にも入れてみる。 PDLを使っている関係で ActivePerl は 5.6.1。

@ インストール

ppm install で入るパッケージは古いので、最新のものを入れておく。 ちょっと手間。

ワンライナーを pp できるところまで動作確認。

@ モジュール + スクリプトを実行可能形式に

ExtUtils::Makemakerを使ってパッケージ化している開発中のモジュール(スクリプトあり、XS あり)を実行可能形式化してみる。

 perl Makefile.PL
 nmake
 nmake test
 cd blib
 set PERL5LIB=lib;arch (pp の -I オプションが効かなかったので)
 pp -o foo.exe -a lib -a arch -M ... -c  script/foo

Log::Log4perl::Appender::Screen、Jcode::Unicode::NoXS、Unicode::StringGD については依存関係を自動検出できなかったので、それぞれ -M で指定。

できた。動いた。素晴しい。 PDLGD を使っていたのでちょっと不安だったのだがうまく動いて感激。 これでCD-ROMとか USB メモリに入れておいて一発実行とかできる。


[ 7月20日全て ]

2006年12月12日 (火)

PAR::Repositoryビルド済み Perl モジュールをネットワーク配信 このエントリーを含むはてなブックマーク

@ 実行可能ファイル作成としての PAR

PAR といえば Perl スクリプトを実行可能ファイル(Windows なら EXE 形式ファイル)に変換するモジュールとして有名である。

ちなみに実行可能ファイルを作成する部分はは PAR 0.97 より PAR-Packer パッケージに分けられ、PAR 自体はインストールしやすい pure Perl なパッケージになっている。

@ PAR モジュールアーカイブからのローダとしての PAR

PAR が提供するもう一つの(こちらが本来はメイン?)機能は、プログラムの実行時に必要な Perl モジュールPAR ファイルと呼ばれる Perl モジュールアーカイブファイルからロードする機能である。 XS モジュールなどもコンパイルすることができるどこかの環境で1度ビルドして PAR ファイルにしておけば、同じアーキテクチャのホスト上でそのまま利用することができる。

@ PAR リポジトリ

ロードしたい PAR ファイルはファイルパスだけではなく URL でも指定することができ、必要な時にオンデマンドでフェッチさせることができる。 これを使えば Perl プログラムの集中管理可能だ。

PAR 0.951 からは PAR リポジトリというコンセプトが追加され、パッケージ毎に作った PAR ファイルをサーバ上(あるいはローカル)のリポジトリに蓄積してオンデマンドでロードできるようになった。

個別に PAR ファイルを指定する従来の方式に比べてかなり便利そうである。 ということで試用してみた。

まずは

あたりをインストールし準備 OK。

@ 1. PAR リポジトリを作成する

最初に PAR-Repository に含まれている parrepo で。

 parrepo create -r /tmp/PAR

PAR リポジトリファイルの中にはデータベースファイルが作成されるが、これは DBM::Deep というアーキテクチャ非依存のものを使っているので、Linux でも Windows でもどちらからでもアクセス可能である (つまり Linux 上でリポジトリをメンテできるということだ)。

@ 2. Perl パッケージを PAR ファイル化する

次に必要な PAR ファイルを作成する。 作成したいパッケージを展開してビルドし、blib ができている状態で PAR::Dist を使ってパッケージ化する。

 perl Makefile.PL
 make
 make test
 perl -MPAR::Dist -e blib_to_par

例えば ActivePerl*1 上で WWW-Mechanize-1.20 を PAR ファイル化すると

 WWW-Mechanize-1.20-MSWin32-x86-multi-thread-5.8.8.par

というファイルが作成される。

普段から ActivePerl で必要なライブラリは基本的に自前で PPM パッケージ化して、動作確認した上で PPM リポジトリに蓄積するようにしているので、合わせて次の手順でパッケージを作ることになる。

 perl Makefile.PL
 nmake
 nmake test
 perl -MPAR::Dist -e blib_to_par
 make_ppm

*1ここでは Windows 上の

@ 3. PAR リポジトリPAR ファイルを登録する

PAR ファイルができたら parrepo でリポジトリに登録する。

 parrepo inject -r /tmp/PAR -f xxx.par

@ 4. PAR リポジトリ上のライブラリを使用してみる

例えば先ほどの WWW::Mechanize がリポジトリに登録されている状態で

 #!/usr/bin/perl
 use PAR { repository => 'file:///tmp/PAR/' };
 use WWW::Mechanize;
 my $mech = WWW::Mechanize->new;
 $mech->get('http://www.example.com');
 print $mech->content;

というスクリプトを書いて実行すると、PAR リポジトリから WWW::Mechanize がロードされて正しく実行される。

ここでリポジトリを Web サーバアップロードして、repository のところに URL を指定するようにすることもできる。 例えばリポジトリを http://www.example.com/PAR/ に配置したとすると

 #!/usr/bin/perl
 use PAR { repository => 'http://www.example.com/PAR/' };
 use WWW::Mechanize;
 my $mech = WWW::Mechanize->new;
 $mech->get('http://www.example.com');
 print $mech->content;

と書き換えることで、インストールしていない WWW::Mechanize を使用できるようになる。

@ Perl プログラムを実行形式化する

先ほどの Perl スクリプトを get_top_page.pl という名前で保存して pp で実行可能ファイル化する。

 pp -o get_top_page.exe -M PAR::Repository::Client get_top_page.pl

とすれば get_top_page.exe という実行可能ファイルが作成される。 WWW::Mechanize はオンデマンドで http://www.example.com/PAR/ からフェッチされるので、アップデートが必要な場合は新しい PAR ファイルを作成してリポジトリを更新するだけでよい。 EXE ファイルを作成しなおして利用者に配付しなすといった作業も不要だ。

@ スクリプトもリポジトリにおく

さらには実行するスクリプトをも PAR リポジトリに置いておくことが可能だ。

例えば WWW-Mechanize に含まれている mech-dump をオンデマンドにフェッチして実行する実行形式ファイルは以下のコマンドで作成できる。

 pp -o mech-dump.exe -M PAR::Repository::Client \
   -e "use PAR { repository => 'http://www.example.com/PAR/', \
                 run => 'mech-dump' }"

@ まとめ

ActivePerl では PPM があるとはいえ、普通のユーザにちょっとしたプログラムを使ってもらうのに「ActivePerlインストールして、PPM パッケージインストールして、……」というのは手間すぎる。

pp で プログラムに必要なものを全てバンドルした実行形式化ファイルにするという方法ももちろんあるのだが、頻繁にアップデートするようなスクリプトの場合には、起動のための部分だけ pp で作成しておいてあとは PAR リポジトリで集中管理するというのもちょっと魅力的である。


[ 12月12日全て ]

2007年4月7日 (土)

携帯電話(iモード)から Twitter を更新する このエントリーを含むはてなブックマーク

Twitter をいろいろ遊んでみて「やはり携帯電話から更新できないと」と思えてきた。

携帯電話からメールを送る事で Twitterアップデートをかけてくれるゲートウェイを設置できれば一番いいのだけれど、そのようなメールアドレスを作る場所が今はない(さすがに会社のサーバはまずい)。

ということでiモードから更新をかけられるように短い CGI プログラムを書くことにした。 CPAN には Net::Twitter という Perl モジュールがあるのだが、JSON::Any (と JSON::XS / JSON / JSON::DWIW / JSON::Syck のどれか)が必要で、ちょっと大げさなので今回は使用は見送り。 普通に CGI.pm と LWP::UserAgent で書いた。

 #!/usr/bin/perl -w

 use 5.005_03;
 use strict;
 use CGI qw(-no_xhtml);
 use Jcode;
 use LWP::UserAgent;

 my $query     = CGI->new;
 my $user_name = $query->param('u');
 my $password  = $query->param('p');
 my $status    = $query->param('s');

 $user_name = '' unless defined $user_name;
 $password  = '' unless defined $password;
 $status    = '' unless defined $status;

 my $message = '';

 if ($user_name ne '' && $password ne '' && $status ne '') {
   my $ua = LWP::UserAgent->new;
   Jcode::convert(\$status, 'utf8', 'sjis');
   $ua->credentials('twitter.com:80', 'Twitter API', $user_name, $password);
   my $request = $ua->post('http://twitter.com/statuses/update.json',
                           {status => $status . ' '});
   if ($request->is_success) {
     $message = '<p>OK</p>';
   }
 }

 print $query->header(-type => 'text/html', -charset => '');
 print '<html><head><title>Twitter update</title></title><body>';
 print '<form method="post" action="twitter">';
 print 'ユーザ名:',   $query->textfield('u'),      '<br>';
 print 'パスワード:', $query->password_field('p'), '<br>';
 print 'ステータス:', $query->textfield('s'),      '<br>';
 print '<input type="submit">';
 print '</form>';
 print $message;
 print '</body></html>';

とりあえずこれで、iモードから送信できることを確認。 パスワードの入力が面倒だけれども、サーバ側に書いておくのも嫌なので毎回送ることにした。FOMA 端末側には定型文として保存しておく以外にいい手はないのかな。

最初うまく送れなくてなんだろうと思ったが、あきやん氏の「Twitterで日本語を入力する方法 (akiyan.com)」の記事にある

  • 全て全角文字で入力して、最後に半角スペースをいれる
  • 半角全角を混在させるときは、半角文字と全角文字の間にスペースをいれる

といった日本語を入力する際の注意点がらみだったようである。 とりあえず CGI プログラムの方で最後に必ずいわゆる半角空白を追加するようにしておいた。

文字数チェックとか Twitter API の返り値チェックとか、改善すべきところはいろいろあるけれど、自分用にはまずこれでいいかな。

気が向いた時に外出先から更新かけます。


[ 4月7日全て ]

2009年8月19日 (水)

今日のさえずり - 選挙カー vs 廃品回収車 このエントリーを含むはてなブックマーク

@ 2009年08月17日

  • 12:10 限界がきて穴の開いたパンツ靴下は洗濯してからじゃないと処分できない派なんだけれど、みんな使用済みの状態で処分したりしているの? *P3
  • 12:50 今のところ洗濯派2、そのまま捨てる派2。 RT @Naney: 限界がきて穴の開いたパンツ靴下は洗濯してからじゃないと処分できない派なんだけれど、みんな使用済みの状態で処分したりしているの? *P3 *P3
  • 14:07 zakwa がいなくなって以来、久しぶりの社内コーヒーサービス(賞味期限今日まで)。 *P3
  • 14:29 Text::CSV_XS::Encoded 一所懸命探してた。 Text::CSV::Encoded だった。 *P3
  • 16:53 今のところ洗濯派4、そのまま捨てる派4。拮抗している。 RT @Naney: 限界がきて穴の開いたパンツ靴下は洗濯してからじゃないと処分できない派なんだけれど、みんな使用済みの状態で処分したりしているの? *P3 *P3
  • 17:08 歯医者につき退社。 [mb]
  • 17:10 後ろの人に「今帰ったら日焼けするよ」と脅された。 [mb]
  • 18:19 歯医者へ GO。 [mb]
  • 19:07 今日の歯医者終了。インレー詰めて痛む奥歯でしばらく強く噛み続けるプレイを味わった。 [mb]

@ 2009年08月18日

  • 09:09 昨日の朝から背中が痒い。原因不明なのでムヒ塗っておく、ムヒ。 [mb]
  • 09:35 東京国際フォーラムのシャッターの向こうにワサワサ人がいた。あれなんだろ。 [mb]
  • 09:45 調査員がホームレスにインタビューしてる。 #Akihabara L:秋葉原駅 [mb]
  • 12:19 会社の女の子がお台場ガンダムについて熱く語っている。 *P3
  • 12:41 2009年8月17日の歩行: 7037歩、5.42km、61分、5.30km/h、消費 269.0kcal、脂肪燃焼 38.4g、3.9エクササイズ。 *P3
  • 12:49 滞在時間何時間? RT @naofumiyoshida: Naha, Okinawa. / 日帰り出張で那覇到着。 *P3
  • 12:54布団って結局どちらを上にして寝れば良いのだろう。房のある方が上? 下? *P3
  • 12:59 選挙カー vs 廃品回収車。 *P3
  • 20:06 @naofumiyoshida 沖縄滞在8時間半ですか。結構居られるんですね。日帰りなんて芸能人みたい。 [mb]

@ 2009年08月19日

  • 12:28 2009年8月17日の歩行: 7037歩、5.42km、61分、5.30km/h、消費 269.0kcal、脂肪燃焼 38.4g、3.9エクササイズ。 *P3
  • 12:29 2009年8月18日の歩行: 4798歩、3.68km、41分、5.30km/h、消費 184.5kcal、脂肪燃焼 26.4g、2.7エクササイズ。 *P3
  • 12:32 今日から花輪ばやしhttp://tinyurl.com/lcr4el *P3
  • 12:36 最近のカメラ屋は。 RT @fujiyacamera: フジヤカメラ店 )))))))♡ 愛と勇気をただいまお届け致しました *P3
  • 14:26 ThinkPad X31 が Caps Lock ランプ点滅させてハングったので再起動したところ (Debian GNU/Linux sid)。 *P3
  • 16:45 「ほぼ日乗組員が紹介する、ほぼ日手帳2010」観た(音無し)。酔う映像でちょっとつらかった。 *P3
  • 20:16 久しぶりに京浜東北線内でコーディング。 [mb]

[ 8月19日全て ]

この日記のはてなブックマーク数 Add to Google RSS

Process Time: 0.077689s / load averages: 0.14, 0.12, 0.09
nDiki by WATANABE Yoshimasa (profile)
Powered by DiKicker
Base theme by Nana (for tDiary)