rakeとかでwarning: already initialized constant Rake::VERSIONみたいなエラーが出た

世界の総水産量は年間約9000万トン(養殖含め)だそうですが、世界の鯨が1年に食べる魚類の量は2.8億トンから5億トンになると試算されており(1)、人間の数倍もの水産物が鯨によって消費されているそうです。ヒトの生物量でもせいぜい3億トンかそこら(50kg*70億人=3.5億トン)ですから、すごい量です。とはいえオキアミや微生物など水産物として競合しないものもあるので単純な比較はできませんが。

さて、rails開発していて、見たことのないこんなエラーに遭遇しました。

% rake -T
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:2: warning: already initialized constant Rake::VERSION
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:2: warning: previous definition of VERSION was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: already initialized constant Rake::Version::MAJOR
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: previous definition of MAJOR was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: already initialized constant Rake::Version::MINOR
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: previous definition of MINOR was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: already initialized constant Rake::Version::BUILD
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: previous definition of BUILD was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: already initialized constant Rake::Version::OTHER
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:5: warning: previous definition of OTHER was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:7: warning: already initialized constant Rake::Version::NUMBERS
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/version.rb:7: warning: previous definition of NUMBERS was here
WARNING: Possible conflict with Rake extension: String#ext already exists
WARNING: Possible conflict with Rake extension: String#pathmap already exists

...(つらつら続きます)...

/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/task_arguments.rb:107: warning: already initialized constant Rake::EMPTY_TASK_ARGS
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/task_arguments.rb:107: warning: previous definition of EMPTY_TASK_ARGS was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/invocation_chain.rb:54: warning: already initialized constant Rake::InvocationChain::EMPTY
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/invocation_chain.rb:54: warning: previous definition of EMPTY was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/early_time.rb:20: warning: already initialized constant Rake::EARLY
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/early_time.rb:20: warning: previous definition of EARLY was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/late_time.rb:16: warning: already initialized constant Rake::LATE
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/late_time.rb:16: warning: previous definition of LATE was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:3: warning: already initialized constant Rake::Backtrace::SYS_KEYS
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:3: warning: previous definition of SYS_KEYS was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:4: warning: already initialized constant Rake::Backtrace::SYS_PATHS
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:4: warning: previous definition of SYS_PATHS was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:7: warning: already initialized constant Rake::Backtrace::SUPPRESSED_PATHS
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:7: warning: previous definition of SUPPRESSED_PATHS was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:11: warning: already initialized constant Rake::Backtrace::SUPPRESSED_PATHS_RE
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:11: warning: previous definition of SUPPRESSED_PATHS_RE was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:15: warning: already initialized constant Rake::Backtrace::SUPPRESS_PATTERN
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake/backtrace.rb:15: warning: previous definition of SUPPRESS_PATTERN was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake.rb:69: warning: already initialized constant FileList
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake.rb:69: warning: previous definition of FileList was here
/Users/foo/bar/hoge/vendor/bundle/ruby/2.4.0/gems/rake-12.0.0/lib/rake.rb:70: warning: already initialized constant RakeFileUtils
/Users/foo/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/rake-12.0.0/lib/rake.rb:70: warning: previous definition of RakeFileUtils was here

自分の場合はrbenvを使っていたので、rubyの処理系を一旦消した上でもっかい入れ直し、さらにvendor/bundleを消したらなおりました。

% rbenv uninstall 2.4.1
% rbenv install 2.4.1
% rbenv rehash
% rm -rf vendor/bundle
% gem install bundler
% bundle install
% rake -T
rake about                              # List versions of all Rails frameworks and the environment
rake app:template                       # Applies the template supplied by LOCATION=(/path/to/template) or URL
rake app:update                         # Update configs and some other initially generated files (or use just update:configs or update:bin)
rake assets:clean[keep]                 # Remove old compiled assets
rake assets:clobber                     # Remove compiled assets
...

原因は、rails newしたあと一回普通にbundle installしたのですが、その後でbundle install –path=vendor/bundleをしてしまったため、rbenvの下のrubyの中にgemがどばどば入ったのと、railsアプリ内のvendor/bundleの下に入ったgemが一緒にロードされてしまったためです。

上の対処法では両方消した形になりますが、本当は片方だけで良いはず。
自分はついでに.bundle/configの中からBUNDLE_PATHを除去し、vendor/bundleではなくruby処理系の中に入れることにしました(自分のruby使用頻度だとそれであんま困らないので)

備忘録でした。

tqdmをムリヤリprocess safeっぽくするdirty hack

生物界で最大の目(光を検知する器官)を持っているのはダイオウイカおよびダイオウホウズキイカと言われ、その大きさは30〜35cmほどにもなるのだそうです。

さて、世界70億人のPythonプログラマが手放せないのが、tqdmというプログレスバーを簡単に表示できるようにしてくれるライブラリです。
しかしながらtqdmは(当然と言えば当然ですが)複数のプロセスから1つのプログレスバーを管理することができるような設計にはなっていません。
たとえば高速化のためにmultiprocessingを用いて並列処理をしながらプログレスバーを出したいとき、tqdmはそのままでは使えないことになります。

例えば、下記のようなコードで単にtqdmのインスタンスを子プロセスに渡して中でupdateをすると…

import tqdm
import multiprocessing

def worker(pbar):
    pbar.update()

ar = [i for i in range(100)]
with tqdm.tqdm(ar) as pbar:
    jobs = []
    for t in ar:
        job = multiprocessing.Process(target=worker, args=(pbar,))
        job.start()
        jobs.append(job)
    for job in jobs:
        job.join()

実行結果はこんな感じ。

% python usage.py
  1%|▉                                                                                                 | 1/100 [00:00<00:25,  3.89it/s]

こんなふうに、100%まで行ってくれません。
端的に説明すると、100個forkされた内部カウント0の状態をそれぞれ+1するのが100回走るだけ、だからです。

じゃあ内部カウントが常によろしく増えるために、内部カウントを無視して共有メモリで常に正しくカウントしてればいいよね、っていう単純な発想による汚いハックをしてみました。

Continue reading

OpenCVの二値画像からの画素値の取得でハマった

OpenCVの画像形式cv::Matはいろんな格納方式ができて,二値画像ももちろんいけるんですが,画素値を個別にアクセスするときのやり方でうっかりしたミスでハマってしまいました.

ということで自虐を兼ねてメモ.(逆では

//画像を読み込む
cv::Mat img = cv::imread("fugafuga.png", CV_LOAD_IMAGE_GRAYSCALE);

//大津の方法で二値化.こうすると二値画像のフォーマットでMatに格納してくれます
//srcとdstが一緒ですが一応問題ないです
cv::threshold(img, img, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);

//全画素をPGMフォーマットで出してみる
std::cout << "P1" << std::endl;
std::cout << img.cols << " " << img.rows << std::endl;
for(int y = 0; y < img.rows; y++)
{
    for(int x = 0; x < img.cols; x++)
    {
        //std::cout << img.at<int>(y, x) << " ";    //まちがい!!
        std::cout << static_cast<int>(img.at<unsigned char>(y, x)) << " ";
    }
    std::cout << std::endl;
}

at<int>()はカラー画像のBGRAをごそっと取り出すとき用だったりするので,二値画像の画素値を出すときはat<unsigned char>()を使いましょうというお話でした.static_castはべつにせんでもええです.
ちなみにat<int>()でやると事実上のゴミが出てきます.
何をいまさらこんなところでつまづいてるのか小一時間問い詰めたい.

研究の全てをgitで管理してたら( ・∀・)イイ!!

ここ1ヶ月半くらいかな,研究データの全てをgitで管理してみるようにしました.

画像系の研究なので,テスト画像だったり,テスト画像毎の処理結果だったり,実験を走らせるためのスクリプトだったり,プログラムだったり.
今まではreadme的なテキストファイルに「これはいついつこういう目的でやった実験だよ!(>ヮ<*)」と書いてるだけだったんですが,時間軸方向の管理能力には限界があったのです.

全てをひとつのリポジトリにぶっ込むとリポジトリが肥大化しすぎて(それこそ画像数万枚の実験を何百回となく行うので,バイト数でいうとLinuxカーネルどころじゃない),速度的にさすがに問題が出てくるので,ひとまとまりの実験をひとつのリポジトリにして,全体はsubmoduleとして管理します.
特定の実験のためのアドホックなプログラムはさらにそいつのsubmoduleで,みたいな.

まだ日は浅く管理してる要素の数もそれほどですが,
ドジっ子おさかなさんはしょっちゅう実験ミスするので,こういう形であらゆる実験結果を検証できるようにしておくと非常によいです.

みなさんもいかがでしょうか?