デバッグ その1〜エラーが出る場合〜
デバッグとは、間違いを直すことです。まずは、コンパイル時にエラーが出る場合のデバッグについて説明します。この場合のデバッグは簡単です。とは言え、エラーメッセージは何言ってるか分からない人が多いかと思います。全部読めるに越したことはないですが、全部読めなくても大丈夫です。エラーメッセージには何行目が間違っているという情報が含まれています。それだけ分かれば、その間違ってる行に行って、間違いを直せば良いです。
(私が)よくやる間違いとしては、括弧やdoやifなどの閉じ忘れ、関数を設定してないなどでしょうか。
デバッグ その2〜エラーはないけど計算が止まる場合〜
コンパイル出来て、さぁ実行!と実行してみたら、途中で止まった。ソースにはエラーないのに何で?何で??という事よくあります。しかも今度は何行目で問題が起こったのか分かりません。これは、プログラム自体には問題がないけど、実際に数値を入れたら起こる問題です。これを探すのは大変です。よくある例で見てみましょう。
run-time error M6103: MATH
- floating point error: devided by zero
こんなエラーメッセージが出て止まる事があります。1行目は何かよく分かりませんが、2行目は「0で割られた」とあるので、可能性があるのは、割り算の分母に変数が入っている所という事が推測出来ます。でも、1000行2000行あるプログラムで割り算もかなりの数が出てきてるような場合、そんなの一個一個調べてられませんよね。それに、devided
by zeroじゃないよく分からないエラーの場合、調べようがありません。でも、これを結構簡単に調べる事が出来ます。今回使用しますのは、「write文」です。俗に言う「楔を打つ」ってヤツです。
で、やり方ですが、プログラムの区切りの良い所に、write文を入れて画面に適当な文字を表示させます。例えば、プログラムを5つくらいに分け、画面に順に1、2、3、4とか表示させます。

[ 図T-1 ]
プログラムをコンパイルして実行すると図T-1の様に、DOSの画面に12341234...とダ〜っと出てきます。で、エラーが出て止まる。

[ 図T-2 ]
例えば、図T-2の様に2のところで止まったとします。ということは、2までは行ったけど、3には行かなかった。つまり、2と3の間でエラーが発生してプログラムが止まったということです。そうしたら今度は2と3の間(図T-1の(3)の部分)でエラーが出る場所を探せば良いということになります。そこで、2と3の間(図T-1の(3)の部分)をまた適当に分けて同じ事をする。これを繰り返せば、エラーの発生する個所をどんどん絞り込むことが出来ます。不要になったwrite文はいちいち出てくると鬱陶しいので、コメントアウトするなり削除するなりしましょう。
ネットワークで計算しよう。
PCのスペックがしょぼい人も、コンパイラが高くて買えない人も落胆することはない。 自分のPCに鞭打って計算させることも、ソフトやハードに投資する必要もない。計算なんて他人のPCで回せば良いんです。別に「ハッキングしろ」なんて言ってませんよ。例えば大学の講座なんかだと、ワークステーションがあったりしますよね。自分のPCで作ったプログラムをワークステーションで回すのに、TELNET使って...とやりますよね。そういうことです。要するに、自分の使っているPCは端末なんだということです。端末は頑張る必要も意味もありません。ネットワークはインターネットするためだけにあるんじゃない。もっと活用しないとね。
でも、研究室にあるワークステーションは、所詮、研究室レベルのワークステーションです。もっと強力なパソコンはないでしょうか?大学とかには、大型計算機があったりします。(必ずあるとは言ってないです。)北大には、HITACHIのスパコンがあります。存在を知ってる人は、結構いますが、実際に使ってるという人はあまり聞きません。ざっとシステムを紹介すると...
HITACHI SR8000(メモリ:320GB、32ノード)分散メモリ型システムにUNIX型OSのHI-UX/MPP for
SR8000を採用し、約1.1TBのディスクアレイ装置をはじめとする各種装置で構成。システム全体で256GFLOPSの理論ピーク性能を発揮。ベクトル型/並列型の両方の特性を有した、高速演算環境。周期性を持たない物理乱数発生機構を搭載...
はい、もう何言ってんのか分かりませんね。私も分かりません。でも、まぁ研究室のワークステーションよりはずっと賢そうです。コンパイラもFortranを始め、C、C++等など色々入ってるみたいです。ただし、スパコンにつなぐのは有料らしく、CPUの使用時間によっていくらとか決まってるみたいで、結構なお値段になってしまうらしいです。「それじゃあ、ダメじゃん」ってことになりますが、思い出してみてください。大学の授業で「数値計算法演習」みたいなのありませんでしたか?あれはスパコンにつないでやってる訳じゃないですが、個人や講座単位で所有出来るパソコンよりはずっと強力なパソコンにつないでやってます。
という訳でまとめると、スパコンは高くて使えないけど、やや大型な計算機ならタダだ!学生は学校の設備を有効に活用しましょう。ということでした。
UNIXマシンで計算したバイナリデータ。
ワークステーションで1週間くらいかけて、やっとこさ計算できた結果を自分のパソコンに持ってきたけど、なんか読み込めない。ぅおぉぉおぉ〜いっ!まぢ本気?!ってことありませんか?
これは出力形式がバイナリー形式になってる時に起こります。フォートランでバイナリーデータを出力するには、一般にopen文で form='unformatted'
とします。この時、コンパイラによっては数値データ以外のコードをはさむことがあるそうです。そこらへんはコンパイラの説明書で調べてください。で、UNIX(64bit?)マシーンとWindows(32bit?)マシーンでは、バイナリー形式が異なってくることがあります。また、GlobeとかClefを使う時にもこのバイナリー形式が問題になります。
アスキー形式だと結果のファイルが重すぎて使えないし、自分のパソコンで計算回す気にはなれない。じゃあどうしろって言うのさっ!ってことになります。「時代を先取りし過ぎたか..一般家庭にCPUがテラバイトレベルのパソコンが浸透するまで気長に待つか。フッ..」ということにはならず、きちんと解決方法があります。その方法は次の通りです。
- open文でformの指定をunformattedではなく、binaryとする。
- 各データ出力(読込)行の前後にその行におけるデータの出力バイト数(データ数×4バイト)を整数値で出力(読込)する。
こんなこと言ってもよく分からないと思うので、例を見てみましょう。
まず、UNIXでWindowsでも使える形式で書き出す場合。
| open(n,file='out.d',status='unknown',form='binary') |
| … |
| write(n) |
i1,a,b,i1 |
| write(n) |
i2,nt,time,f(1),f(2),・・・,f(5),i2 |
| write(n) |
i3,((x(i,j),i=1,ni),j=1,nj),i3 |
ここで、i1=2×4バイト、i2=7×4バイト、i3=ni×nj×4バイトです。こんな感じで出力すれば、ファイルをWindowsにコピーしてきて、open(form='unformatted')で普通に使えます。
UNIXでunformattedとして出した結果をWindowsで読み込む場合も一緒です。
| open(n,file='out.d',status='old',form='binary') |
| … |
| read(n) |
i1,a,b,i1 |
| read(n) |
i2,nt,time,f(1),f(2),・・・,f(5),i2 |
| read(n) |
i3,((x(i,j),i=1,ni),j=1,nj),i3 |
i1,i2,i3は上の例と一緒です。これでオッケーです。
ちなみに、本気のプログラムをいきなりやる前に、簡単なプログラムでテストしてからやることをお勧めします。 |