2015/06/28(日)octave+openblas+intlabで丸め変更を検証

INTLAB version 9をubuntu上のoctaveで使うの続きです。このopenblasはパッケージで入れたものなので、丸めの向きの変更が正しく効くかどうか分かりません。そこで、行列積について、丸めの向きの変更が効いているかどうかテストしてみました。前の記事で入れたubuntuと、ついでにwindowsでも試してみました。

行列積はn3回の乗算とn2(n-1)回の加算を含んでいますが、これらの全ての演算について、上向き丸めと下向き丸めで結果が異なる筈であるような入力値を与え、計算結果が同一になる(すなわち丸め変更が効いていない)ことが発生することがないかどうか試すプログラムを作ってみました。matlabのプログラムは書いたことがないのでこれが普通の書き方かどうかはよく分かりません。
function testmm(n)
	disp('testing multiplication...')
	flag = 1;
	for k=1:n
		a=zeros(n);
		a(:,k)=ones(n,1)*1/3;
		b=zeros(n);
		b(k,:)=ones(1,n)*1/3;
		c = (rad(intval(a) * b) ~= 0) + 0.0;
		if prod(prod(c)) == 0
			disp('multiplication error!')
			flag = 0;
			break
		end
	end
	if flag == 1
		disp('multiplication OK!')
	end

	disp('testing addition...')
	flag = 1;
	for k=2:n
		a=zeros(n);
		a(:,1)=ones(n,1);
		a(:,k)=ones(n,1)*2^(-27);
		b=zeros(n);
		b(1,:)=ones(1,n);
		b(k,:)=ones(1,n)*2^(-27);
		c = (rad(intval(a) * b) ~= 0) + 0.0;
		if prod(prod(c)) == 0
			disp('addition error!')
			flag = 0;
			break
		end
	end
	if flag == 1
		disp('addition OK!')
	end
end
これをtestmm.mという名前で作成し、testmm(100)などとintlab上で実行してみました。なお、数値は行列サイズで、このプログラムはn4に比例した時間がかかるのであまり大きな行列ではテストできません。実行結果は、次のようになりました。
ubuntu 14.04windows + octave 3.8.2windows + octave 4.0.0
シングルコアOKOKOK
マルチコアNGOKNG
実行環境は次の通り。
ubuntu 14.04前記事で書いたubuntu 14.04 + パッケージで入れたoctave, openblas
windows + octave 3.8.2windows7 + INTLAB公式のoctaveページからダウンロードしたoctave 3.8.2
windows + octave 4.0.0windows7 + Octave公式ページからダウンロードしたoctave 4.0.0
さて、この結果はある程度予想できるものでした。これら3つの環境では全て内部でopenblasが用いられています。openblasのソースファイルのMakefile.ruleというファイルの中に、
# CONSISTENT_FPCSR = 1
という行があります。これは、マルチスレッド環境において浮動小数点数のControl/Statusレジスタをコピーするか否かを決めていて、ここをuncommentするとopenblasが起動されたときの丸めの向きの状態がマルチスレッド時の全てのスレッドに伝わるようになります。この結果から、ubuntuのパッケージとoctave公式のopenblasはここがコメントのままmakeされていて、INTLABページのものはここのコメントが外されてmakeされていると推定できます。

ここからは、ubuntu 14.04の場合について、openblasのパッケージを作りなおしてマルチコア環境でも丸めの向きの変更が全てのスレッドに伝わるようにします。野良ビルドでも良いのですが、ubuntuのパッケージシステムとなるべく合わせた形で作ってみました。
  • sudo apt-get install devscripts
  • 適当な作業directoryを作ってそこに移動
  • sudo apt-get source openblas でソースコードを取得。
  • sudo apt-get build-dep openblas でmakeするのに必要なものをインストール。
  • cd openblas-0.2.8/ でソースdirectoryに入る。
  • Makefile.ruleを編集し、コメントアウトされている
    CONSISTENT_FPCSR = 1
    
    を有効化する。
  • dch -i で、version番号を例えば0.2.8-6ubuntu2のように進め、changelogを適当に書く。
  • dpkg-buildpackage -b -uc -us でmake。
  • これで必要なdebファイルが生成されたので、cd .. で一つ上に上がり、
  • sudo dpkg -i libopenblas-base_0.2.8-6ubuntu2_amd64.deb
  • sudo dpkg -i libopenblas-dev_0.2.8-6ubuntu2_amd64.deb
別のマシンで入れ替え作業を行う場合は、最後に使った2つのdebファイルだけあればOKです。一応作成したdebファイルを上げておきますが、自分で作成することをお勧めします。
ところで、INTLAB公式のoctaveページからダウンロードしたoctave-3.8.2-installer.exe、Aviraさんが

octave-virus.jpg


みたいに反応するんだが、大丈夫だろうか (自分は仮想環境で実行してすぐに消しました)。Aviraさんはときどき過剰に反応するからそのせいだと信じよう。
OK キャンセル 確認 その他