BNN-PYNQ の走り書き

アドレスはハードコーディング

library/driver/platform-xlnk.cpp:               platform = new XlnkDriver(0x43c00000, 64 * 1024);

FoldedMVInit でメモリアロケーションしている。accelBufIn と AccelBufOut は thePlatform->allocAccelBuffer で取得している。これは最終的に sds_mmap を呼ぶ。sds つかってなくてもね。sds_mmap は UIO の一部を使っているか使ってないかを無視してマップするので危険。使っているか使っていないかはドライバやアプリしだいなので、つかってくれるな~~とお願いしながら使うことになる(と思う。改善されてるかもしれない。)

で IP にこの物理アドレスを教えてあげる。

    thePlatform->write64BitJamRegAddr(0x10, (AccelDblReg) accelBufIn);
    thePlatform->write64BitJamRegAddr(0x1c, (AccelDblReg) accelBufOut);
    thePlatform->writeJamRegAddr(0x28, 0);

0x28 へのアクセスは // disable weight loading mode ということみたい。

writeJamRegAddr は最初の 32 個のシステム用のアドレスをスキップして(つまり 32xsizeof(uint32_t) = 0x80) てアクセスする。この場合 0x43c00000 + 0x80 + 0x28 だね。64bit の場合はリトルエンディアンで 2回 writeJamRegAddr を呼ぶ。

testPrebinarized_nolabel で実際の処理。1つのワードが 64bit ( 8x8 )で、これに切り上げられる。例えば、この場合 28x28 = 784 だけど、832 ビットになる。この LFC ネットワークの MNIST はグレースケールを二値化(0 と 0xff) になっていることを前提としていて、それをされに 0 と 1 に落とし込む。ので 832ビット。

参考までに書くとゼロから作る DL の本では 784 バイトでグレースケールを考慮している。 隠れが1層で 784(バイト) => (50x100) => 10だった?BNN-PYNQ は 832bit => 1000x1000x1000 => 10 。方や float で方や二値。たぶん、精度はゼロから作るの方がいいのか微妙。BNN-PYNQ で私の手書きの9は7になってしまった。

さて、ドライバに戻る。

立ち上げた瞬間はまだネットワークのウェイトが設定されていない。load_parameter で設定する。

extern "C" void load_parameters(const char* path)
{
#include "config.h"
FoldedMVInit("lfc-pynq");
network<mse, adagrad> nn;
makeNetwork(nn);
        cout << "Setting network weights and thresholds in accelerator..." << endl;
        FoldedMVLoadLayerMem(path, 0, L0_PE, L0_WMEM, L0_TMEM);
        FoldedMVLoadLayerMem(path, 1, L1_PE, L1_WMEM, L1_TMEM);
        FoldedMVLoadLayerMem(path, 2, L2_PE, L2_WMEM, L2_TMEM);
        FoldedMVLoadLayerMem(path, 3, L3_PE, L3_WMEM, L3_TMEM);
}

L0_PE = 32, L0_WMEM=416, L0_TMEM=32 う~ん。PE(Processor Entity?)とかSIMD とかよくわからんが、、、各レイヤーのパラメタを設定する。
L0_WMEM が 416 で L0_SIMD が 64 なので 416 x (64 / 32) = 832 bit が入力。
L0_TMEM が 32 で LO_PE が 32 なので 1024 bit が出力。
L1 は 入力 L1_SIMD / 32 * L1_WMEM => 32 / 32 * 512 => 512(あれ?)出力は 64 * 16 = 1024。てな具合にやっていくのでしょう。なんか計算が合わないけど。
HLS 側のソース見ると

static ap_uint<L0_SIMD> weightMem0[L0_PE][L0_WMEM];
static ap_fixed<24, 16> thresMem0[L0_PE][L0_TMEM];
static ap_uint<L1_SIMD> weightMem1[L1_PE][L1_WMEM];
static ap_uint<16> thresMem1[L1_PE][L1_TMEM];
static ap_uint<L2_SIMD> weightMem2[L2_PE][L2_WMEM];
static ap_uint<16> thresMem2[L2_PE][L2_TMEM];
static ap_uint<L3_SIMD> weightMem3[L3_PE][L3_WMEM];
static ap_uint<16> thresMem3[L3_PE][L3_TMEM];
static ap_uint<L4_SIMD> weightMem4[L4_PE][L4_WMEM];
static ap_uint<16> thresMem4[L4_PE][L4_TMEM];
static ap_uint<L5_SIMD> weightMem5[L5_PE][L5_WMEM];
static ap_uint<16> thresMem5[L5_PE][L5_TMEM];
static ap_uint<L6_SIMD> weightMem6[L6_PE][L6_WMEM];
static ap_uint<16> thresMem6[L6_PE][L6_TMEM];
static ap_uint<L7_SIMD> weightMem7[L7_PE][L7_WMEM];
static ap_uint<16> thresMem7[L7_PE][L7_TMEM];
static ap_uint<L8_SIMD> weightMem8[L8_PE][L8_WMEM];

ん?なんで L8 まであるんだ?

    switch (targetLayer) {
    case 0:
        weightMem0[targetMem][targetInd] = val;
        break;

いずれにせよこんな感じで入れている。だから、targetLayerと targetMem と targetInd を設定して val をいれればよい。
バイナリデータがあるので64bit ずつ、

  FoldedMVMemSet(layerNo*2, pe, line, e);

てなかんじ。ファイル名は layerno + pe + "-weights.bin" or "-thres.bin" だ。そうか、sigmoid つかうかわりにスレッショルド使っているのか(予測)。

  // enable weight loading mode
  thePlatform->writeJamRegAddr(0x28, 1);
  // set up init data
  thePlatform->writeJamRegAddr(0x30, targetLayer);
  thePlatform->writeJamRegAddr(0x38, targetMem);
  thePlatform->writeJamRegAddr(0x40, targetInd);
  thePlatform->write64BitJamRegAddr(0x48, (AccelDblReg) val);
  // do write
  ExecAccel();
  // disable weight loading mode
  thePlatform->writeJamRegAddr(0x28, 0);

これで値設定。設定するたびに待っているぞ。

void ExecAccel() {
  // invoke accelerator and wait for result
  thePlatform->writeJamRegAddr(0x00, 1);
  while((thePlatform->readJamRegAddr(0x00) & 0x2) == 0) usleep(1);
}

あとは 28x28 をビットに整形して(binarizeAndPack)、IP がアクセスできる連続領域にさらにコピーして(copyBufferHostToAccel)、実行

   FoldedMVOffloadBinarized(binImages, outLabel, count*psi, count*psl, count);

....
void FoldedMVOffloadBinarized(....

  thePlatform->writeJamRegAddr(0x54, numImages);

  // launch
  ExecAccel();

結果を accelBufOut からもってくる。

FTDI と Vivado の Jtag

Vivado で JTAG 認識しなくなった時のリカバリー方法。hw_manager まではつながるけど、その先。陥った©状態は、USB-UART は動くのに JTAG を認識してくれない。

PYNQ や ARTY-Z7 では USB-UART に FTDI の 2232HQ というのをつかっている。Zybo も同じ。このチップ、USB のインタフェースとして2つもっているみたいだ。UltraZed は 232HQ で微妙に違う。

ここの blog だと
http://www.hmwr-lsi.co.jp/fpga/fpga_1.htm
FT2232D(微妙に違うな)、片方をJTAG、片方を UART にできそうな感じ。

Windows で PYNQ を USB に接続して見るとデバイスマネージャだと USB-UART が動いているので、安心してしまう。でもこれは実はインタフェース1のほうなのだ。JTAG として動くのはインタフェース0 。なので、USB-UART は動くけど、JTAG が動かないという状況があり得る。

おそらく、ちょっと前に FreeScale(じゃなくなったんだっけ) の i.MX6 をデバッグするときに、OpenOCDをつかっていた。 zadig-2.3.exe というツールをつかってドライバを入れ替えたのが今回のトラブルの元の気がする。zadig はよくできていて、インストーラもない(だからダウンロードしたらウィルスチェックすること)。

もどしかたはデバイスドライバを元に戻せばいいのだけど、どういうわけか、JTAG のドライバはデバイスマネージャで見えない。あるかもしれないけど、すぐに探せない。ここはもう Windows 10 の使い方の問題。デバイスとプリンタになぜか現れる。Digilent Adept USB Device。

f:id:ryos36:20171007140326p:plain

うまくうごいている状態の記録しかのこっていないのがお粗末だが、上の絵になれば OK。ここに winusb とかが見えているとだめ。winusb 自身は MS だからちょっと安心したりするけど、JTAG 的にはだめ。ダブルクリックして、プロパティを見るとドライバの状態を見ることが出来る。この時点では”見る”だけなので(管理者権限で動いていない)、設定の変更を更にクリックする。あとはドライバの更新で FTDI の USB Serial Conveter にすればよい。私の場合、バージョンは 2.12.24.0 (現時点の最新は 2.12.28 かな?)

f:id:ryos36:20171007140719p:plain

そうこうしていると USB-UART が動かなくなることがあるので、USB Serial Converter B をダブルクリックして詳細設定の TAG を開くと VCP をロードするがあるので、これをロードすると USB-UART が使える。

f:id:ryos36:20171007140854p:plain

これでひとまず終了なのだが、PC の再起動とかなんとかしていると、また、元に戻ったり、あるいはデバイスドライバに不具合があります。とか出てきて、問題を修正すると、元に戻ってしまったりとすることがある。これは、おそらく inf ファイルが残っているから。

そこでコマンドプロンプトからどんな inf があるかチェックする。pnputil.exe というこまんどがそれ。MS 製でもとからついてきている。-e オプションで表示。-d で削除ができる。libusb に関連する inf を削れば(おそらく)元に戻ったりすることはなくなる(と思う)。

c:\Temp>pnputil -e > inf6.txt

c:\Temp>explorer .

c:\Temp>explorer -d oem55.inf

c:\Temp>pnputil -d oem55.inf
Microsoft PnP ユーティリティ

ドライバー パッケージが正常に削除されました。

c:\Temp>pnputil -d oem141.inf
Microsoft PnP ユーティリティ

ドライバー パッケージが正常に削除されました。

c:\Temp>pnputil -e > inf7.txt

alliance

今やるべき事かどうかわからないが、alliance インストールしている。え!!X window が必要なの?

configure: error: requires the X window system to compile and run.
                  Please do not use the configure option '--without-x'.

つかえねーじゃん。

ubuntu があったので、ここでコンパイルすることに X のライブラリが必要みたい。

 X11/X.h: No such file or directory

sudo apt-get install xorg-dev" 

げー今度は Motif かよ。20年前かよ。

 sudo apt-get install libmotif-dev 

これでどうよ。configure は通ったよ。yacc がねー。bison いれればいいみたい。

sudo apt-get install bison

一瞬 bison++ を入れるという誘惑にかられたけど、安全のために bison にした。

  • lMut がないといわれた。LD_LIBRARY_PATH にまちがいがあったらしく。make install とか設定しなおしていいるうちにコンパイルできるようになった。なんかいろいろ途中でエラーになる。make でなくて

make install とすることが判明。あーぜんぶ install しながらつくるのね。

https://soc-extras.lip6.fr/en/alliance-abstract-en/

まぁこの通りにやればいいということ。またエラー

/.libs/libVrd.so: undefined reference to `vrd_y_in'

bison じゃだめなのか、、、無念コンパイルできず。

あーflex インストールしてなかった。インストールして再挑戦中。あーflex missing 。configure からやりなおし。
なんでこんなことしているかというと ocp がないから。man ocp はできるのに、、、

~/Polyphony/examples/alliance-examples/adder4$ make
MBK_WORK_LIB=.; export MBK_WORK_LIB; MBK_IN_LO=vst; export MBK_IN_LO; MBK_OUT_LO=vst; export MBK_OUT_LO; MBK_CATA_LIB=/usr/share/alliance/cells/sxlib; export MBK_CATA_LIB; MBK_IN_PH=ap; export MBK_IN_PH; MBK_OUT_PH=ap; export MBK_OUT_PH; MBK_CATAL_NAME=CATAL; export MBK_CATAL_NAME; /usr/bin/ocp -v -gnuplot -ioc adder4  adder4 adder4_p
/bin/sh: 1: /usr/bin/ocp: not found
Makefile:212: recipe for target 'adder4_p.ap' failed
make: *** [adder4_p.ap] Error 127

BNN-PYNQ をリビルドする

Linux では簡単

tkat0.hateblo.jp
方法はこちらが詳しい。

Windows ではコンパイル時にエラー

これはどうも clang の 4.5.2(?) のバグらしい。(clang のバージョンなのか g++ のバージョンなのか不明)

c++ - Clang on Cygwin with C++11 - Stack Overflow

これによると、4.7.2 をつかえとなっている。どうやら clang はヘッダーなどを g++ から拝借してきているようだ。g++ の構文では通るが clang では通らないという記述があるらしい。でも、ちゃんと type_info という定義はある。
で、4.7.2 を見てみると、、、どちらでも通る記述に変更されている。

diff exception_ptr.h*
132c132
<       const class type_info*
---
>       const type_info*

これ単純に class ってつけ足せばいいのでは、、、、ビンゴ!!コンパイルが通るようになる。そしてまたエラー。

throw_with_nested という関数が2度定義されていて、どちらにも = 0 で初期値をいれている。これ、2回目の定義の時は初期値を入れてはだめなのでは?

> diff nested_exception.h*
122c122
<     __throw_with_nested(_Ex&& __ex, const nested_exception*)
---
>     __throw_with_nested(_Ex&& __ex, const nested_exception* = 0)

ビンゴ!!エラーがなくなる。これでとりあえずこの問題解決。Vivado HLS の最近のバージョンでも同じ問題が残っているので、いちいちぜんぶに変更しないといけない(もちろん自己責任で)

c:/Xilinx/Vivado_HLS/2016.2/win64/tools/clang/include/c++/4.5.2

とにかくこうすると、うまくいく。

シェルプロで作られているよ

なんだかしらんが、シェルプロで作るようになっている。なので、非常にめんどくさい。なんで tcl で共通化しないんだよ。Linux 文化オンリー?
しかたがないのでシェルプロを見ながらつくりなおし。っていうか Vivado HLS はさっきの修正でうまくいく。問題は Vivado の方。
Vivado HLS でつくった BlackBox Jam なる IP を Vivado にいれこむ。これ、単純にいれて自動配線に任せてよさそう。で、どういうわけか、合成と実装のオプションを変えている。タイミングがメットしなかったんだねきっと。

set_property strategy Flow_PerfOptimized_high [get_runs synth_1]

set_property STEPS.SYNTH_DESIGN.ARGS.DIRECTIVE AlternateRoutability [get_runs synth_1]
set_property STEPS.SYNTH_DESIGN.ARGS.RETIMING true [get_runs synth_1]

set_property strategy Performance_ExtraTimingOpt [get_runs impl_1]
set_property STEPS.OPT_DESIGN.ARGS.DIRECTIVE Explore [get_runs impl_1]
set_property STEPS.POST_ROUTE_PHYS_OPT_DESIGN.ARGS.DIRECTIVE AggressiveExplore [get_runs impl_1]
set_property STEPS.PHYS_OPT_DESIGN.ARGS.DIRECTIVE AggressiveExplore [get_runs impl_1]
set_property STEPS.POST_ROUTE_PHYS_OPT_DESIGN.IS_ENABLED true [get_runs impl_1]

よくこんな設定見つけたな、、、、とおもいつつ、、、GUI からその通りに修正。(しゅうせいしなくてもいけるのか?誰か人柱)

とりあえず、合成もできたし、自分のデザインに入れ込むこともできた。

f:id:ryos36:20170909232858p:plain

ただし、これ、使い方がよくわからない。

BNN-PYNQ をリビルドする

type_info の unknown type name

error: unknown type name 'type_info'
const type_info*

https://forums.xilinx.com/t5/High-Level-Synthesis-HLS/Building-Xilinx-Binary-Neural-Network-in-HLS-Error-on-Windows/td-p/757041
https://github.com/jingpu/Halide-HLS/issues/5

https://stackoverflow.com/questions/12938663/clang-on-cygwin-with-c11

diff exception_ptr.h*
132c132
<       const class type_info*
---
>       const type_info*
diff nested_exception.h*
122c122
<     __throw_with_nested(_Ex&& __ex, const nested_exception*)
---
>     __throw_with_nested(_Ex&& __ex, const nested_exception* = 0)


qiita.com

github.com

tkat0.hateblo.jp

とりあえず Ubuntu をアップグレード

手元の VMWare 上の Ubuntu が 14.04 だったので、16.04 にしてみた。が、upgrade しようとすると、

The required dependency 'apt (>= 1.0.1ubuntu2.13)' is not installed.

だと。apt が古いのか?

14.04 --> 16.04 failed; apt (>= 1.0.1ubuntu2.13)' is not installed - Ask Ubuntu

をみると

sudo apt update
sudo apt dist-upgrade

したあとに、

sudo do-release-upgrade

すればいいみたい。このあと、SDSoC 2016.4 を入れる予定。やれやれ。

新人をバイナリアンに育てる ~ その10 ~

やはりこういう地味なものは、地味にしか展開しない。新人、高橋君8月に突入。C言語は初めてで、ポインタの前の配列で苦戦。

新人高橋君 日報 8/1(月) 18:21

作業報告します

今日行ったこと
 -"C言語入門書の次に読む本"を409ページ中122-137まで読み進める
 -"明解C言語"を325ページ中118-132まで読み進める

 -複数行読んで、1文字目に応じて異なる関数を読んで異なる表示をするプログラムの作成
 -複数行読んで、各コマンドを実行するプログラムの作成

今後のtodo
 -"C言語入門書の次に読む本"を読み進める
 -"明解C言語"を読み進める


 -入力に応じて三角形、四角形、円を複数個描画その後にrawデータで保存するプログラムの作成
  -複数行読んで、最初の計画通り各コマンドを実行するプログラム

 -行を読むプログラムをバイナリフォーマットで行うようにする
 -文字列を10進数の数に変換するプログラムの作成する
 -文字列を16進数の数に変換するプログラムの作成

社長コメント

もうちょい詳しく書きましょう。
>   -複数行読んで、最初の計画通り各コマンドを実行するプログラム
s(小文字)
とかいてあったら表示をする
S(大文字) ファイル名
と書いてあったらセーブする
L(大文字) ファイル名
と書いてあったらロードする

ファイル名の処理(とくに一貫性のある処理=美しいプログラム)が難しいかもしれない。

>  -文字列を10進数の数に変換するプログラムの作成する
-> my_atoi ね
>  -文字列を16進数の数に変換するプログラムの作成
-> my_atoi16 ね


コメント

「1文字目に応じて異なる関数を読んで異なる表示をするプログラムの作成」でなかなか先に進まず。
switch/case でも苦戦中。教える方とも我慢比べ。報告を見てもやっぱりわからないので、指導が入ります。

週刊社長通信 8/1

■ What's New
本日、XXXにいってきました。
案件として成立しそうです。
なんかぼちぼち日本語で書いた資料が効いてきている。YYY のウェブとか。
もうちょい日本語のWebを増やすか、、、

先週の金曜日は SSS という会社に行ってきました。
サッカースタジアムを上から俯瞰したいらしい。
これも WEB 経由。

営業いらないじゃん。ウェブを充実させていこう、、、

ZZZの案件=> 「同プロジェクトの経験のない会社への発注はリスクが高い」
だって。そんじゃ最初からコンペするな、、、といいたい。

■ 読書
ゲーテル・エッシャー・バッハ」再帰が難しいまま、160ページくらい=>(再開)
いそがしくて読書してないのか、、、
今日は「生命とは何か」をもって電車に乗りました。

科学の”正しい”知識を増やしていくことは我々の業種にとって重要です。
文学やイデオロギーよりも重要です。
なぜなら、こーしょな文学論やくだらないイデオロギー談義は宇宙の果てでは意味がありませんが、
正しい科学の知識は宇宙の果てでも意味があるから。

■みんながリーナス・トラバースさんになろう。
 =>どうすればなれるか?
 =>3つの柱がある

1. コンピュータプログラミング技術
-> ポインタと再帰がわかること
2. コンピュータ設計技術
3. コミュニケーション能力

とくに最終的に重要になってくるのが設計能力。
これは囲碁が上達する人の原理と同じ。

ものの本によると、囲碁が上達する人は初心者の時からわかるらしい。
なぜその手を打ったか論理的に説明できることが重要らしい。
論理の正誤はこの際問題にならない。

最終的には設計書を書けるようになりましょう!!!
設計書が書ければ一人前です。

どうも、Yさんとかは頭の中に設計書があるみたいね。

                                                                                            • -

スタックマシンをつくりたいのだが、その前に scheme を復活させることにした。
DirectFB でそれなり数のテストを作らなきゃならなくなって、
C のソースをたくさん書くのは嫌なので、scheme にしようと。
まぁみんなを Lisp に巻き込むという事だね。

で今ソースを見たら boost を使っている、、、
だめじゃん。Linux ならいいけど、、、組み込みシステムに使えない。

                                                                                            • -

ということで、プログラマが知らなければならない言語
1. C
2. forth
3. lisp
4. VHDL
5. アセンブラ
6. C++
7. sed
8. awk

というのが私のおすすめ順。Forth がわかれば組み込みシステム技術者になれるでしょう。Lisp を知っていればコンパイラ技術者になれるでしょう。VHDL を知っていればハードウェア関連に強くなれるでしょう。LispVHDL は出会わなくても組み込みシステム技術者になれます。Forth も出会わなくても大丈夫な言語ですが、、、知っているのと知らないのでは大違い。組み込み技術者にとって必須の技術が詰まっている。Lisp も出会わなくても大丈夫と言えば体上部ですが、、、これは知っているのと知らないので大きく人生を変える言語でしょう。Emacsmule を使っている人は普段からlisp を使って自分の環境を拡張してください。

Java を知っていても Python を知っていても Ruby を知っていても、それだけではコンピュータのエキスパートにはなれないでしょう。sedawk は知っていると便利かな。特にawk はちょっとしたコンパイラだからね。

あと、Object 指向は必要な概念ではないね。C++ は便利で好きな言語だけど。Lisp でプログラムを書いていて思ったけど、一切、オブジェクト指向の必要がなくかける。

しかも破綻せずに。C は規模が大きくなると破綻する(ので C++ が必要になる)けど lisp は破綻しない。ただし、だからといって、必要なのは関数型言語でもない。マクロでもない。(マクロは便利だけど)

必要なのはクロージャーとデリゲート。いずれもインタフェースを提供する機構だ。C++ は class でクロージャーを、テンプレートでデリゲートを手に入れた。Lisp は最初から両方持っている。

巷の流行に惑わされないようにしましょう。
惑わされそうなキーワード:オブジェクト指向、関数型、マクロ、Railsクロージャー、デリゲート
(ん?今必要って言ったばかりジャン、、、、)

■追伸
dc というプログラムをインストールして使えるようにしておいてください。dc は一種の電卓です。

http://www.gnu.org/s/bc/
bc の中に dc があるらしい。
ソースをダウンロードしてコンパイルしてインストールしてください。
出来るかな?

コメント

いまにして思えば、やはり文学的な心は必要。重要。いろんなことへの感受性の解像度が低いと結局、正しい知識を得ても運用できない。

偉そうに Forth っていっているけど、Forth 今でもかけないし、、、

なぜか dc をコンパイルせよと言っている。謎。

新人高橋君 日報 8/2(火) 18:18

作業報告します

今日行ったこと
 -"C言語入門書の次に読む本"を409ページ中138-154まで読み進める
 -"明解C言語"を325ページ中133-148まで読み進める

 -複数行読んで、各コマンドを実行するプログラムの作成
  -表示、セーブ、ロードそれぞれを動作させるところまで

今後のtodo
 -"C言語入門書の次に読む本"を読み進める
 -"明解C言語"を読み進める


 -入力に応じて三角形、四角形、円を複数個描画その後にrawデータで保存するプログラムの作成
  -複数行読んで、最初の計画通り各コマンドを実行するプログラムの手直し

 -行を読むプログラムをバイナリフォーマットで行うようにする

 -文字列を10進数の数に変換するプログラムmy_atoiの作成
 -文字列を16進数の数に変換するプログラムmy_atoi16の作成

コメント

ちゃくちゃくとバイナリアンへの道を進んでいます。s(表示) と S(セーブ) と L(ロード) がコマンド。「行を読むプログラムをバイナリフォーマットで行うようにする」は何を意味しているのか今となってはわからない。

社長の指示

>  -文字列を10進数の数に変換するプログラムmy_atoiの作成
>  -文字列を16進数の数に変換するプログラムmy_atoi16の作成
1st version はただの16進数のみを解読
例: 123
ABC
abc
AbC
xyz -> error

2nd version はただの16進数と 0x をつけた 16進数を解読する
例: 0x123
0xABC
DEF
Def
def
0xDEF
XYZ -> error

>  -行を読むプログラムをバイナリフォーマットで行うようにする
バイナリになると
一行ではなく一文字ずつあるいはまとまって読むようになる。
まずは
P ... (10, 10) に点を打つ
L ... (15, 15, 20, 20) に線を書く
s ... show する
この3つをサポートする。

任意の場所に点を打てるようにするにはどうしたらよいか?

* ヒント
関数の戻り値をうまく使う

determine -> dispatch_xxxxxx
xxxxxx は graphic とか file とか show とか

doit = dispatch_graphic(....);
で、もし実行したら 1 が返る、実行していないなら 0 とすると
if ( doit == 1 ) {
continue; // <- continue は何かを調べておいてください。
}
とすればよい。その後
doit = dispatch_xxxxxx
if ( doit == 1 ) {
....
...
...

とすればスマートになる。

コメント

何事も step by step。一文字読むプログラムでも難しい。そして、continue が何かを教えている。社著の私は最終的にはバイナリを読むということをさせたいらしい。

新人高橋君 日報 8/3(水) 18:12

作業報告します

今日行ったこと
 -"C言語入門書の次に読む本"を409ページ中155-164まで読み進める
 -"明解C言語"を325ページ中149-162まで読み進める

 -DCのインストー
  -挑戦中、コンパイルがうまくいかない

 -複数行読んで、各コマンドを実行するプログラムの改良

 -文字列を10進数の数に変換するプログラム my_atoi の作成
 -文字列を16進数の数に変換するプログラム my_atoi16 の作成
  -ただの16進数を解読するところまで

今後のtodo
 -"C言語入門書の次に読む本"を読み進める
 -"明解C言語"を読み進める


 -入力に応じて三角形、四角形、円を複数個描画その後にrawデータで保存するプログラムの作成
  -複数行読んで、最初の計画通り各コマンドを実行するプログラムの手直し

 -文字列を16進数の数に変換するプログラムmy_atoi16の作成
  -ただの16進数と0xをつけた16進数を解読するようにする

 -行を読むプログラムをバイナリフォーマットで行うようにする

社長コメント

報告をもう少し細かくしてください。(読む側にわかるように)

>  -複数行読んで、各コマンドを実行するプログラムの改良
どんな改良をしたのかをわかるようにしましょう。

コメント

dc のコンパイルはオーバワークだったらしい。ちょっと先を急ぎ過ぎた。my_atoi16 はある程度できたみたい。だんだんと社長の私も要求が増え始めた。まぁ読む側にわかるように、、、という意識は難しいよね。

新人高橋君 日報 8/4(木) 18:14

作業報告します

今日行ったこと
 -"C言語入門書の次に読む本"を409ページ中165-174まで読み進める
 -"明解C言語"を325ページ中163-179まで読み進める

 -文字列を16進数の数に変換するプログラムmy_atoi16の作成
  -0xが先頭についていた場合のことも含めて作成
  -テストプログラムの作成

今後のtodo
 -"C言語入門書の次に読む本"を読み進める
 -"明解C言語"を読み進める


 -入力に応じて三角形、四角形、円を複数個描画その後にrawデータで保存するプログラムの作成
  -複数行読んで、最初の計画通り各コマンドを実行するプログラムの手直し

 -行を読むプログラムをバイナリフォーマットで行うようにする
  -バイナリファイルを読み込み、
   Pを読み込むと(10, 10)に点を打ち、Lを読み込むと(15, 15, 20, 20)に線を描き
   sを読み込むと表示させるプログラムの作成

コメント

だんだんとバイナリを扱う感じになってきた。my_atoi16 で 0x がついたものに対応した。よしよしって感じかね。一歩一歩進んでいるという感じ。

新人高橋君 日報 8/5(金) 18:28

作業報告します

今日行ったこと
 -"C言語入門書の次に読む本"を409ページ中165-174まで読み進める
 -"明解C言語"を325ページ中163-179まで読み進める

 -バイナリファイルを読み込みコマンドに応じた図形を描画するプログラムの作成
  -Pを読み込むと(10, 10)に点を打ち、Lを読み込むと(15, 15, 20, 20)に線を描き
   sを読み込むと表示させるところまで

今後のtodo
 -"C言語入門書の次に読む本"を読み進める
 -"明解C言語"を読み進める

 -バイナリファイルを読み込みコマンドに応じた図形を描画するプログラムの作成
  -バイナリファイルの作成
  -コマンドに応じた図形を描画するプログラムの作成

コメント

ん?ついにちょっと作業がアクセラレートされた?来週に期待しちゃうね。(10, 10) への点うちと(15, 15) - (20, 20) への線はできたらしい。いままで三角形とか書いてたからそこは難しくないでしょう。