Dynabookのタッチパッドの設定

TOSHIBA Dynabookで、タッチパッドを端からドラッグするとスタートメニューが出たり、画面が切り替わったりして鬱陶しい。特にパワポでプレゼン中に暴発すると最悪。その設定変更方法を見つけた。

「コントロールパネル」→「マウス」→「デバイス設定」→「設定」→「ポインティング」→「エッジスワイプを使用する」のチェックボックスを外す

マウスの設定から、さらにデバイス設定に行かないといけないので気づかなかった。他にもこれに悩んでいる人がいるかもしれないのでここにメモっておく。

stdio.hとmpi.hの順番によるエラー

mpiccとかmpiiccとかで以下のようなプログラムをコンパイルする時、stdio.hとmpi.hの順番を変えろ、というエラーが出る事がある。

#include <stdio.h>
#include <mpi.h>
int
main(void){
  printf("Hello\n");
}
$ mpiicc test.cc
/opt/intel/impi/4.1.0.030/intel64/include/mpicxx.h(95): catastrophic error: #error directive: "SEEK_SET is #defined but must not be for the C++ binding of MPI. Include mpi.h before stdio.h"
  #error "SEEK_SET is #defined but must not be for the C++ binding of MPI. Include mpi.h before stdio.h"
   ^

compilation aborted for test.cc (code 4)

指示通り、mpi.hとstdio.hを入換えても良いのだが、大きなコードでそれをやるのは面倒。-DMPICH_IGNORE_CXX_SEEKオプションをつけてコンパイルすると、このエラーは出ない。

$ mpiicc -DMPICH_IGNORE_CXX_SEEK test.cc

コンストラクタを持つクラスの配列

コンストラクタに引数が必要なクラスを配列で宣言する時、どうやってその引数を渡すのかわからなかったんだけど、こうすればできた。

class Test{
  public:
   const int value;
   Test (int i) : value(i) {};
};
int
main(void){
  Test c[3] = {1,2,3};
  printf("%d %d %d\n",c[0].value, c[1].value, c[2].value);
}
$ c++ test.cc
$ ./a.out
1 2 3

RubyからMac OS Xのスクリーンショットを撮る

RubyからCocoaを叩いてMac OS Xスクリーンショットを撮るサンプル。

osx/cocoaがなければ、

$ sudo port install rb-cocoa

を実行すること。

なぜか「全体のスクリーンのRect」を意味するOSX::CGRectInfinite定数が見つからなかったので、 OSX::NSScreen.screensで、スクリーンリストを取得、その0番目が全体スクリーンなので、そのframeを手に入れ、 そのwidthとheightからOSX::CGRectを作成、そいつをCGWindowListCreateImageの引数に入れて呼んでいる。

require 'osx/cocoa'

f = OSX::NSScreen.screens[0].frame
cr = OSX::CGRectMake(0,0,f.width,f.height)
screenshot = OSX::CGWindowListCreateImage(cr, OSX::KCGWindowListOptionOnScreenOnly, OSX::KCGNullWindowID, OSX::KCGWindowImageDefault)

c = OSX::CIImage.imageWithCGImage(screenshot)
bitmaprep = OSX::NSBitmapImageRep.alloc.initWithCIImage(c)
blob = bitmaprep.representationUsingType_properties(OSX::NSJPEGFileType,nil)
blob.writeToFile_atomically("test.jpg",false)

スクリーンショットはNSObject。これをCIImageを経由してNSBitmapImageRepにして、ファイルタイプにJPGを指定してからファイル名を指定して保存する。

RubyでいんちきHexdump

Rubyでバイナリファイルを1バイトずつ読み込んで整数値でダンプするサンプル。

filename = ARGV[0]
open(filename,"rb"){|f|
  while c = f.read(1)
    puts c.unpack("C")
  end
}

1.9系だとbinreadとか使えるらしいが、これは1.8系でも動作するスクリプト

Lion + OpenMPのバグ?

Mac OS X 10.7.4 (Lion) + gcc 4.2.1 で、OpenMPがたまにバグる。

エラーメッセージは以下のような感じ。

=====================================================================================
=   BAD TERMINATION OF ONE OF YOUR APPLICATION PROCESSES
=   EXIT CODE: 6
=   CLEANING UP REMAINING PROCESSES
=   YOU CAN IGNORE THE BELOW CLEANUP MESSAGES
=====================================================================================
APPLICATION TERMINATED WITH THE EXIT STRING: Abort trap: 6 (signal 6)

gdbで見たらこんな感じ。

Program received signal SIGABRT, Aborted.
0x00007fff88389bf2 in __psynch_mutexwait ()
(gdb) up
#1  0x00007fff867281a1 in pthread_mutex_lock ()
(gdb) up
#2  0x00000001000022c4 in gomp_barrier_destroy ()
(gdb) up
#3  0x0000000100001f5b in gomp_team_end ()

まだよくわからないが、Snow Leopardでは問題が生じないのでOS 依存の可能性あり。ちなみにgccのバージョンは4.2.1。

$ mpic++ --version
i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00)
Copyright (C) 2007 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

'Hoge::v' is not a variable in clause 'shared'

C++でOpemMP並列をする際、

error: 'Hoge::v' is not a variable in clause 'shared'

というエラーが出る事がある。これは、クラスのメンバ変数をshared指定しようとした時のエラー。例えば以下がサンプル。

#include <iostream>
#include <omp.h>
#include <vector>
class Hoge{
  private:
    std::vector<int> v;
  public:
    void func(void){
      int tid;
#pragma omp parallel shared(v) private(tid)
      {
        tid = omp_get_thread_num();
#pragma omp critical
        v.push_back(tid);
      }
      for(int i=0;i<v.size();i++){
        std::cout << v[i] << std::endl;
      }
    };
};
int
main(void){
  Hoge h;
  h.func();
}

これをコンパイルすると、

test.cc: In member function 'void Hoge::func()':
test.cc:10: error: 'Hoge::v' is not a variable in clause 'shared'

こんなエラーがでる。調べてみたが、どうもクラスのメンバ変数をshared指定できないようなので、一度別のテンポラリ変数を使って後でコピーするしかないらしい。こんな感じ。

#include <iostream>
#include <omp.h>
#include <vector>
class Hoge{
  private:
    std::vector<int> v;
  public:
    void func(void){
      int tid;
      std::vector<int> vtmp;
#pragma omp parallel shared(vtmp) private(tid)
      {
        tid = omp_get_thread_num();
#pragma omp critical
        vtmp.push_back(tid);
      }
      for(int i=0;i<vtmp.size();i++){
        v.push_back(vtmp[i]);
      }
      for(int i=0;i<v.size();i++){
        std::cout << v[i] << std::endl;
      }
    };
};
int
main(void){
  Hoge h;
  h.func();
}

実行結果。

$ g++ -fopenmp test.cc
$ export OMP_NUM_THREADS=4;./a.out
2
1
0
3