新千葉 ガーベージ・コレクション

FPGA マガジンやインターフェースで書けなかったこと等をちょぼちょぼ書いてます。@ryos36

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

サブタイトル:そら飛ぶ バイナリアン

このブログは 2011 年に新人教育をしたメールの断片から書きこおこしている。もう6年も前の話であることに注意。新人君(高橋くん - 仮名 - )は理工学系大卒のピカピカの新人。数学は得意で球の体積を積分で簡単に出せる。結構優秀。そして、学部では FORTRAN を学んでプログラミングもしたことがあるので、結構、できると信じて疑っていない。

そこで、GNU Development Tools という某所の自費出版本をよませて(それ以外の仕事はなし。勉強が仕事)自習させてみた。その記録である。

よくわからないけど、サブタイトルもつけてみた。どっかの出版社の人、本にしてください。:-)

新人くん日報:6/15 17:52

今日行ったこと
 移行作業を終了させる。
 GNU Development Tools第7章動的リンクを読み終える。
 内容については完全に把握していないので読み直しが必要。
今後やるべきこと
 GNU Development Tools を読み終える。
 FreeBSDを導入する。

コメント(現在の私の)

Ubuntu を導入した翌週に無謀にも FreeBSD をインストールさせている。これじゃ、なんの学習効果もないんじゃないかな。と今頃反省。

実務経験7~8年の人の日報

  • 画像認識

- 顔認識のサンプルプログラムの、API レベルでやってることを把握
OpenCV は haar 分類器というものを持っており、
xml で与えられるパターン情報を元に、画像のパターン認識を行うことが出来る
パターンにヒットした箇所は座標で得られ、
テストでは座標をもとに赤い丸を書いている
テストに用いた顔の認識パターンは、正面を向いたもの、である

- エッジ検出のテストの修正
エッジ検出のテストでは、matrix を使って rotate していたが、必要無いことが分かった。`
利用するカメラの性質により、画像の左上を座標の起点とするか、左下を起点とするか分かれる
どちらを起点にするかは、取得した画像データ IplImage の持つ origin メンバにより取得出来るで、
もし origin が IPL_ORIGIN_BL ( 左下起点 ) の場合、cvFlip() という API
上下の反転が可能であることがわかったため、テストを修正した

- OpenCV 2.2 と OpenCV 1.0 の違いをより明確に調査(特に、H/W アクセラレーションについて)
H/W アクセラレーション、正確には GPU の利用機能は、2.2 から導入された
対応する GPU は NDIVIA 製のもののみで、cuda ライブラリが必要となる
GPU を使うライブラリは、既存のソフトウェアで計算する API と別モノになっている
( DirectFB のように、API は一つで、API の中でソフトウェアを使うかハードウェアを使うか
処理が分岐するような設計にはなっていない)
GPU を使った HogDescriptor という画像検出器が、CPU による検出に比べ桁違いに高速らしい
リファレンスマニュアル:
http://opencv.jp/opencv-2svn/cpp/index.html
http://opencv.jp/opencv-2svn/cpp/gpu._gpu-based_functionality.html

ChangeLog:
http://opencv.jp/opencv2-x-tips/changelog_from_21

- IplImage 構造体の中身の調査
image_data, image_size をもとに、raw データをファイルに保存するテストを作った

コメント

さすがに実務経験のある人の日報はちゃんとしている。このあと、彼はちゃんと arm 上に OpenCV のクロスコンパイルを達成する。このころは、日報を書かせてたんだな。いまは週報になっている。グレードダウンだ。

社長から高橋君への指示 6/15(Wed) 22:50

次の事を達成してください。

72x34 の白黒画像イメージに四角を書く
PNG でセーブ

  • OpenCV で次のプログラムを作る

72x34 の白黒画像イメージに書いた四角を書く
45度傾ける
PNG でセーブ

  • OpenCV で次のプログラムを作る

72x34 の白黒画像イメージに書いた四角を書く
45度傾ける
白黒のraw データでセーブ(すでに実現しているのでそれをそのまま流用)

  • 普通のプログラムで

白黒の raw データを読み込む
白の数と黒の数を数えて表示する。

  • 普通のプログラムで

72x34 の白黒画像イメージに書いた四角を書く
raw データで書き出す

  • 普通のプログラムで

72x34 の白黒画像イメージに書いた四角を書く
45度傾ける
raw データで書き出す

今月中にすべてこれができたら大したもの。

コメント

かなり無茶ぶり。高橋くんピ~ンチ。ちゃんと OpenCV つくれるのか?FORTRAN しかしらないんだぞ。社長かなり無理なことを言っています。これに高橋君どうこたえる?しかも、OpenCV の次の作業が不明瞭だ。

新人:高橋くん日報:6/16(Thu) 18:16

今日行ったこと
 GNU Development Tools を読み終わる。
 ただし、理解がまだまだ浅いと思われるのでこのまま2周目に移行。
 VMware上でFreeBSDを導入した。
 ただし設定が終わり切っていないため明日以降も行う予定。
これから行うべきこと
 GNU Development Tools を読みつづける。
 FreeBSDの設定。
 OpenCVのインストール及びプログラム作成。

コメント

この日だけ 18:16 の報告になっている。実は 18:00 に帰るためには 17:30 には仕事を終了して、日報をかいて 17:50 に日報をメールして帰るように指示していた。ブラックでない会社。まぁ小さい会社、いいことばかりじゃないけどね。ここは私の方針で継続して働ける環境を作っている。(もちろんデスマーチもありました。それで会社がピンチになったことも)。この日はきっと本を読み切るためにちょっと遅くなったんだね。

GNU Development Tools 読み終わった!!1週間ちょっと?おー誰かが指示したのかな?このままで終わらせずに2周目に突入。まだ、よんだだけだからね。でも、新人だけに、出来る気になっている。

実務経験7~8年の人の日報

- 移植用 todo の更新
- qemu for ARM の環境をサーバ に作る
- arm 向け OpenCV 1.0.0 の build
- arm 向けに、グレースケール変換のテストをコンパイル
- qemu-arm 上でグレースケール変換のテスト
-> ok
- arm 向け OpenCV 2.2.0 の build
-> ok. 手順書を書いた
- arm 向けに、グレースケール変換のテストをコンパイル( 2.2.0 )
- qemu-arm 上でグレースケール変換のテスト( 2.2.0 )
-> ok
- qemu-arm 上でエッジ検出変換のテスト( 2.2.0 )
-> ok
- ARM のボードに、OpenCV 2.2.0 のライブラリをコピー
- ARM のボード上でエッジ検出変換のテスト
-> ok

高橋くんへ

マトリックスを使った回転をしているプログラムを添付します。

コメント

指示した OpenCV の構築が出来ている。さすが、実務経験7~8年。そして、その結果が高橋君にわたされる。どうする、いきなり OpenCV のソースを渡された新人。どーなるんだ。(おぼえてない)

新人:高橋くん日報:6/17(Fri) 18:12

今日行ったこと
 C言語プログラミングを3章 スタイルまで読み終える。
 opencvのインストールを済ませ、使える状態にした。 

 opencvについて
  72×34の画像出力には成功、この後は四角形領域の作成に入る。
これから行うべきこと
 opencvのプログラムを作成する。
 C言語プログラミング、linuxの使い方などに目を通しておく。

コメント

あれ?今日も 18:12 報告。ブラック企業になり始めている(苦笑)。C言語プログラミングを読ませている。今考えると順番が逆だ。なんで、先にGNU Development Tools 読ませているんだろう?わかるわけないじゃん。FORTRAN しかやったことないのに。スパルタ教育だな。

おーそれでも OpenCV でなんかプログラミングしている。ここまではお遊戯な感じだけど、新卒ならこんなもんじゃないのかな。上出来上出来。とこれが2周目。まだまだ続くよ。メールの残骸が残っている限り。
このペースだといつまでたってもブログが終わらない気がするけど。

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

以前新人教育をしたメールの文章をブログに書き起こす。

登場人物は 高橋(仮名)くん。まずやったこと。

例の自費出版本の GNU Development Tools を読ませた。

6/8 17:59 日報

GNU Development Tools 第4章コンパイルについて読み終わる。
同じくGNU Develpoment Tools 第5章 アセンブルについて実行コードの逆アセンブルまで読み終わる。
4章、5章ともに今現在読み取ることができない点はなし。

コメント

そんなことはないだろう。この時点で、新人くん大きく勘違い。がんばれ。でも、まだスキルが足りなくて4章、5章なんて理解できないぞ。理解できないことを理解できないのが新人たるゆえんか。

6/9 17:52 日報

GNU Development Tools 第5章アセンブルを読み終わる。
同じくGNU Development Tools 第6章静的リンクを_startシンボルによる致命的エラーま
で読み終わる。
アセンブラについては若干解析が不十分だと思われる。
また、静的リンクについてはリンクが異常終了するため少々難航するかと思われる。

コメント

その後何が起こるか正確には思い出せないけど、まぁしかたがない。というか、その技量を上の人が見極めるのはどれだけ大変かが後でわかった。ついつい期待しちゃうんだよね。だって本人の報告から「アセンブラについては若干解析が不十分」ってあるから、裏を返せば、ちょっとがんばって解析すると、アセンブラとかできちゃう?とおもっちゃう。

私の回答

エラー内容を精査してXXXさんと一緒に解決してください。

社長通信

社長技術通信 6/13

みんながリーナス・トラバースさんになろう。
=> そのためには、A面B面を作らない
=> 具体的には、自分探しをしない(夢や憧れを追わない)

GLSL について調査した。
http://http.developer.nvidia.com/Cg/arbvp1.html
vp1 => vertex 用の Low Level Shader 言語(アセンブラ?)
文法通り作ればよさそう。
あとはスタックを作るのと、テンポラリレジスタのセーブ・ロード
Sparc のように in register をtemp register 8をout register 8とすればよさそ
う?
Result 用のレジスタも必要かも。

コメント

当時、社長通信とか言ってみんなに発信していた。いまも技術通信に変わってやり続けている。この何とか通信10年以上、社員に向けて毎週発信しているんだよね。継続は力なり。

6/13 17:55

GNU Development Tools 第6章静的リンクまで読み終わる。
完全に理解したわけではないので今後読み直しが必要。
今後の予定としてはGNU Development Tools を読み進めつつ、Ubuntsuの導入などを行う
予定。

コメント

これだけ読むとすごい進捗。2~3年かかることを3日で達成している。新人すごい。

6/14 17:57

今日行ったこと
実機にUbuntuのインストールを行う。
それに伴い環境設定及び移行作業を始める。
今後行うべきこと
移行作業を終了させ、GNU Development Toolsを読み進める。

コメント

おーついに Ubuntu 導入。がんばれ新人。きっと実践は本とは違うぞ。

おまけ

画像認識の作業、 todo を細かくしました:

  • 画像認識

- OpenCV の調査
ビデオ入力してエッジ検出するテストがどう動くかは、API のレベルで把握した
- 顔認識のサンプルプログラムの、API レベルでやってることを把握
- ( 道路標識などの)パターン認識のテストを書く。API レベルで、やってることを把握。
- 2.2 と 1.0 の違いをより明確に調査(特に、H/W アクセラレーションについ

コメント

当時実作業に充てていた人間が OpenCV の作業をしてくれていた。画像認識を ARM でできるようにしていたんだね。

risc-v を試してみる(途中)

まずは toolchain のインストール
github.com


git submodule update --init --recursive

llvm でえらく時間がかかっているんですけど。
あとは


export RISCV=/path/to/install/riscv/toolchain
$ ./build.sh

でできるらしい。
その後、

github.com

ここのを使えばバーチャルな環境ができる、、、はず。
よくみると toolchain のなかに tests は含まれていた。なので、toolchain だけでいいはず。
llvm の clone がおそい。

PYNQ の Binary NN やってみたよ

とりあえず
qiita.com
のとおりやってみる。sudo -H でやった方がいいことに後で気づく。
update は結構時間かかった。

Cifar10.ipynb
当たり前だけど、うまくいくね。

それじゃ、ガゼルはどうよ?
f:id:ryos36:20170413012950p:plain
馬と判断されました。鹿じゃないんだね。

Python をさわってみて

Python 実によくできた言語だと思います。C や Perl でどんな風に書いたら可読性が”落ちるのか”を研究していて、そういう書き方が”できない”ようにしているようです。(あくまで個人的な感想)

インデントで整形というのがその典型です。これは構文解析が楽になるという効果もあるようです。

代入したらローカル変数、参照”だけ”はグローバル

面白いと思ったのはこのスコープの扱い。フリー変数の扱いと言い換えてもいいかもしれません。

def func(a):
    b = 3
    return a + b

この b のように”代入したら”ローカル変数です。

def func(a):
    return a + b

ここの b は、参照”だけ”しているのでグローバル変数。この時点で、かの有名な方の持論である PythonLisp の亜種説は崩れます。スコープが特殊なんです。これ、Lisp とは大きく方向性が違う。いいか悪いかはともかくとして、おそらく、このようなスコープは Python 独特で、なかのコンパイラインタプリタの構造を大きく変える(はずです)。事実 HyLang は let を捨てたようです。

じゃ、こんなのはどう?

def func(a):
     c = b
     b = b + 3
     return c + b + a

"UnboundLocalError: local variable 'b' referenced before assignment" と実行時にエラーになります。

if の中で現れたものは?

>>> def iffunc(a):
...     if a :
...         b = 3
...     else :
...         print(a)
...     print(b)
...
>>> iffunc(3==3)
3
>>> iffunc(3!=3)
False
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 6, in iffunc
UnboundLocalError: local variable 'b' referenced before assignment

実行時にかなり頑張っています。

++ とかはない

>>> a++
  File "<stdin>", line 1
    a++
      ^
SyntaxError: invalid syntax

こういう構文シュガーがありません。どっかの言語みたいに構文シュガーの塊のようなことはないんです。載せればいいわけじゃない。

単項演算子の ++ とか -- とかあったほうが便利そうじゃないですか。でも入れると全体のバランスが崩れるんです。折角、参照はグローバルと規定したのに、++ を入れることで、参照だが代入だかわからなくなる。そういう事態を避けるようになっています。この規則のおかげでグローバル変数はたいていの場合"read onlyなデータ"です。関数の中からは書き換えることが出来ません。

こういった、コンパイラの中身や(インタプリタか、、、)書き方の細部にわたって、設計思想がかなりはっきりした言語であり、私にとっては知れば知るほど好感が持てる言語として評価が上がっています。コンパイラインタプリタを作る人はその思想はどうあるべきかを考えるうえで研究対象の筆頭に上がってよい言語だと思います。

Polyphony で 64bit Fibonacci (本編スピンアウト 64bit Fibonacci the movie)

あらすじ ~ TV とは違う Movie ならではの展開 ~

32bit で気を良くした Polyphony サポートチームは 64bit の Fibonacci にチャレンジした。64bit は 32 を2つにしたというだけではない。次から次へと襲う難題。チームは問題を解決できるのか?本編からスピンアウトした 64bit 対応。最後に笑うのは誰だ?そして翔太は?

まずは Polyphony 0.3.0 の 64bit 化

env.py にある default_int_width=32 を 64 に変更。なお、64bit 対応は 0.3.0 から。master の 0.2.2 は未対応。

 default_int_width = 64

test bench を 64bit 化

from polyphony import testbench

def fib(n):
    if n <= 0: return 0
    if n == 1: return 1
    r0 = 0
    r1 = 1
    for i in range(n-1):
        prev_r1 = r1
        r1 = r0 + r1
        r0 = prev_r1
    return r1

@testbench
def test():
    expect = [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610]
    for i in range(len(expect)):
        result = fib(i)
        assert expect[i] == result
        print(i, "=>", result)

    expect2 = [ 0, 55, 6765, 832040, 102334155, 12586269025, 1548008755920, 190392490709135, 23416728348467685, 2880067194370816120, 354224848179261915075, 573147844013817084101, 927372692193078999176, 1500520536206896083277, 2427893228399975082453 ]
    j = 0
    for i in range(105):
        if i % 10 != 0 and i < 100 :
            continue
        result = fib(i)
        #print("{i} => {result}({rhex}) vs {expect2}({ehex})".format(i = i, result = result, rhex = hex(result), expect2 = expect2[j], ehex = hex(expect2[j])))
        print(i, "=>", result, "(", expect2[j], ")")
        #print(i, "=>", hex(result), "(", expect2[j], ")")
        assert expect2[j] == result
        j += 1

test()

そして、Python3 で動くことを確かめる。

> python3 fib.py
0 => 0
ざっくり中略
90 => 2880067194370816120 ( 2880067194370816120 )
100 => 354224848179261915075 ( 354224848179261915075 )
101 => 573147844013817084101 ( 573147844013817084101 )
102 => 927372692193078999176 ( 927372692193078999176 )
103 => 1500520536206896083277 ( 1500520536206896083277 )
104 => 2427893228399975082453 ( 2427893228399975082453 )

64bit の int では 93 まで。(uint なら 94)。上の結果はなぜか 104 まで

msgpack-rpc vhdl を 64bit 化

たぶん create_project で generate する際のパラメタを渡せると思うだが、力及ばず、/src/test/vhdl/test_bench.vhd を直接編集。

> git diff ../../../src/test/vhdl/test_bench.vhd
diff --git a/examples/fibonacci/src/test/vhdl/test_bench.vhd b/examples/fibonacci/src/test/vhdl/test_bench.vhd
index 11f6861..7eabfbf 100644
--- a/examples/fibonacci/src/test/vhdl/test_bench.vhd
+++ b/examples/fibonacci/src/test/vhdl/test_bench.vhd
@@ -66,13 +66,13 @@ architecture MODEL of TEST_BENCH is
     constant CLOCK_PERIOD    : time    := 10 ns;
     constant DELAY           : time    :=  1 ns;
     constant MATCH_PHASE     : integer :=  8;
-    constant I_BYTES         : integer :=  4;
+    constant I_BYTES         : integer :=  8;
     constant I_WIDTH         : AXI4_STREAM_SIGNAL_WIDTH_TYPE := (
                                  ID    => 4,
                                  USER  => 4,
                                  DEST  => 4,
                                  DATA  => 8*I_BYTES);
-    constant O_BYTES         : integer :=  4;
+    constant O_BYTES         : integer :=  8;
     constant O_WIDTH         : AXI4_STREAM_SIGNAL_WIDTH_TYPE := (
                                  ID    => 4,
                                  USER  => 4,

これは polyphony では入力も 64 ビットになるから。Synthesijer では入力 32ビット、出力 64bit みたいなことができる。
あとcreate_project.tcl 内のシナリオも test_42.snr から test_92.snr に変えておく

Vivado でシミュレーション

f:id:ryos36:20170322184239p:plain
結果は 7540113804746346429 でウェブで検索したらあたったので、OK とします。

そのころ翔太は

Ikalog をとることに没頭していた。

PYNQ で fibonacci (完結編)

前回までのあらすじ

Polyphony で高位合成をして fib.py を verilog に落とし、ついでにインタフェース情報も JSON で吐き出したものを yml に(python で)書き直し、それを手で書き直したものをつかい vivado のシミュレーションに成功。さらに IPXACT 化して、PYNQ の FPGA のビットストリームを作ることに成功した。このバイナリは本当に動くのか?チームの命運は如何に?そして、翔太の恋愛のゆくえは?

PYNQ の環境を git clone する (lfs に注意!!)

https://github.com/ikwzm/PYNQ-Festival から clone する。ReadMe に書いてある通りにやればいいので、この ReadMe を最初によく読む(べきだった、、、)
特にここに含まれる大きめのファイルは git lfs をつかっているので、clone しただけだとただの ascii file です。

  • boot/boot.bin
  • boot/design_1_wrapper.bit
  • boot/u-boot.img
  • boot/uImage-4.8.17-armv7-fpga
  • debian8-rootfs-4.8.17.tgz

私の環境では git lfs が使えなかったので、githubgui からこつこつクリックしてとってきました。あとパーティションを切るようになっているので、SD カードの 2nd Partition を適切に設定し、debian8-rootfs-4.8.17.tgz を展開しました。これも ReadMe の通り

うまくたちあがると login を見ることが出来るので fpga/fpga でログイン。examples/fibonacci に移動して fibonacci_server_install.sh をroot 権限で実行。これで準備は整いました。

jupyter からつかう

折角 PYNQ なので、web browser から使います。samba も動いているので pynq という hostname で繋がります。うまく、動きました。
f:id:ryos36:20170320164153p:plain

jupyter 便利ですね。これの便利さは結局 history の永続性と視覚化の2点ですね。

ISSUE: time out

なんか時々動きが、、、そういう細かいところにこだわっていてはお重荷になれないので、大物になれないので、ざっくりとオミット。
はいいろぞうさん、いるといいなぁ~

追記

「timeout は、socat を起動するときに "socat -d -d tcp-listen:54321,fork /dev/zptty0,raw,nonblock,echo=0 &" のように echo=0 をつけると出なくなりました。」

とのこと。試してみよう。

そのころ翔太は、、、

ひとり家の中でスプラトゥーンに興じていた。