About Hidemi

主にFPGAに関する技術アイデアのための備忘録を展開しています。

Free HTML5 Template

興味のあること

  • 萌系アニメ
  • FPGA
  • 画像処理
  • 通信(Ethenret)
  • 高位合成

Features

画像処理をする高位合成処理系などの統合開発環境を構築を進めています。

高位合成処理

新フェーズを計画中。

統合環境

高位合成からFPGA化、Linuxディストリビューションからクロス開発環境までトータルで使いやすいプラットフォーム環境の開発を進めています。

クラウドFPGA

クラウド経由でFPGAを使用する実験を計画中。JavaScriptでクラウドに配置されているFPGAの書き換えを可能にしてリモートでアクセス可能にする機能を計画中。

Webで開発

Webブラウザ上でブロックモデリング開発を計画中。Webブラウザ→Vivado→FPGAの流れを計画中。

@hidemi_ishihara

Twtitterで呟いています。ブログに書く必要のないネタや速報はTwitterで、サポートもTwitterでご質問くださいませ。
https://twitter.com/hidemi_ishihara

RSS配信

RSS配信を復活しました。最新の5件分を配信中です。こちらのURLをRSSリーダに登録してください。
http://www.sweetcafe.jp/?rss

Blog

入手しました。

こんなの来ましたよ。

なんですの?

これ?

蓋を開けると・・・

何もない?

ごそごそ、探ってみると・・・

こんなの入ってました!

ちゃんと7020って、箱に書いてますね。

さっそく、開けてみましょう。

なんと!

ヒートシンク付き!

あれ?

ファンないよ?

ファンはオプション?

2017年09月20日 21時50分56秒 - Permament Link

メモリリークで思わぬ結果が・・・

CNNの勉強用にフルスクラッチでコードを起こして、SDSoCでZYBOに適用したのだがデータがPLに転送できないメモリアクセスエラーが発生した。

エラー内容からどの配列でエラーが起きているかわからないのでなにが原因か解らなかった。

メモリ領域もsds_allocしたし、AXIバスも正常に生成されている。

ソースコードをよく見なおしてみると、CNNの畳み込みのフィルタ配列が勘違いでメモリリークを起こしていた。

よく見ると、フィルタが半分はガボールフィルタで半分が全結合の中間層の重みが割り当たっていたようだ。

まだ、詳細に確認したわければ無いがガボールフィルタは最初に生成した時点から変更はしない。

全結合の中間層の重みは学習しながらパラメータを修正していように作っていた。

つまり、畳み込みのフィルタの半分が動的に変更される中で全結合の学習を行っていた形になっていた。

検証範囲に限った話だがメモリリークを修正して正常な形で動作確認を行った時よりもメモリリークしてた時のほうが結果が良い方向にでた。

なぜか学習の収束も速く、メモリリークよりも正常時のほうが1.7倍ぐらいかかるようになった。

畳み込みのフィルタを全結合の中間層の重みを使うといいかもしれないという怪我の功名的な発見だった。

こういうのもありなのかもね・・・

2017年09月07日 01時42分05秒 - Permament Link

SDSoCの良いところ悪いところ

SDSoCって、単にFPGA化してソフトウェア側のアプリとFPGA側のbitファイル(boot.bin)を生成する。

とりあえず、ソフトウェア側はソフトウェアとして間違えていなければ実行ファイルを生成する。

今日、遭遇したのは「viratual to phtsical」のエラーだ。

これはsds_allocにしなければいけないところをmallocにしておくと起きやすいエラーだ。

今回はFPGAにつながる配列をmallocしたにも関わらず、実機でこのエラーが解消されなかった。

よくよく、追いかけてみると、転送すべき範囲より小さい領域をsds_allocしてて転送に失敗してたのが原因だった。

このエラー、どの関数やどのアドレスで発生しているというのがないので大きな範囲をFPGA化していると全て追いかけなければいけない状態になる。

さらに、ポインタの変数を構造体や途中で入れ替えたりしているようなソースコードでは追いかけにくい。

今回はポインタを入れ替えながら実行する関数でしかもメモリーリークがあったために転送できないという形でのエラーだった。

最終的にはメモリーリークが見つかったんだけど、そこにたどり着くまでに時間がかかってしまった。

エラー時に何らかの情報を出してくれれば、もう少し追いやすいんだけど・・・

それか、コンパイルの時点でワーニングでも吐いてくれれば・・・

実機に持っていくと物理的に悪いかどうかがCPUより厳密になるので良いのかもしれない。

FPGA化によって、ソフトウェアの性能向上を目指すという側面と、ソフトウェアの物理的不具合の確認用とした使い方もできるのかもしれない。

2017年09月06日 00時23分24秒 - Permament Link

【SDSoC】 pragma実験(メモリ編)・その2

まずは、SDSoCのpragmaでメモリ(主に配列)がどのように展開されるかを実験してみた。

 ソースコード

実験は次のソースコードを対象とする。

#include <stdio.h>
#include <stdlib.h>

#define SIZE (256)

int MemTest(
  char MemInA[SIZE],
  char MemInB[SIZE],
  char MemOut[SIZE]
)
{
  int i;
  for(i = 0; i < SIZE; i++){
    MemOut[i] = MemInA[i] * MemInB[i];
  }

  return 0;
}

int main(){
  int i;
  char MemInA[SIZE], MemInB[SIZE], MemOut[SIZE];

  FILE *fp = fopen("test.dat", "r");
  fread(MemInA, sizeof(char) * SIZE, 1, fp);
  fread(MemInB, sizeof(char) * SIZE, 1, fp);
  fclose(fp);

  MemTest(
    MemInA,
    MemInB,
    MemOut
  );

  for(i = 0; i< SIZE; ++i){
    printf("%d: %d\n", i, MemOut[i]);
  }

  return 0;
}

mem_attribute(PHYSICAL_CONTIGUOUS)

実験対象のソースコードにPHYSICAL_CONTIGUOUSを適用した。

#pragma SDS data mem_attribute(MemInA:PHYSICAL_CONTIGUOUS)
#pragma SDS data mem_attribute(MemInB:PHYSICAL_CONTIGUOUS)
#pragma SDS data mem_attribute(MemOut:PHYSICAL_CONTIGUOUS)

まず、これを基準に比較してみよう。

+-----------------+---------+-------+-------+-------+
|       Name      | BRAM_18K| DSP48E|   FF  |  LUT  |
+-----------------+---------+-------+-------+-------+
|DSP              |        -|      -|      -|      -|
|Expression       |        -|      0|      0|     70|
|FIFO             |        -|      -|      -|      -|
|Instance         |        -|      -|      -|      -|
|Memory           |        -|      -|      -|      -|
|Multiplexer      |        -|      -|      -|     36|
|Register         |        -|      -|     39|      -|
+-----------------+---------+-------+-------+-------+
|Total            |        0|      0|     39|    106|
+-----------------+---------+-------+-------+-------+
|Available        |      120|     80|  35200|  17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%)  |        0|      0|   ~0  |   ~0  |
+-----------------+---------+-------+-------+-------+

sizeof(char) * 256wordなので256Byte = 2,048bit

どこに2,048bitが隠れた?

メモリサイズを512wordに変更

#define SIZE (512)
+-----------------+---------+-------+-------+-------+
|       Name      | BRAM_18K| DSP48E|   FF  |  LUT  |
+-----------------+---------+-------+-------+-------+
|DSP              |        -|      -|      -|      -|
|Expression       |        -|      0|      0|     71|
|FIFO             |        -|      -|      -|      -|
|Instance         |        -|      -|      -|      -|
|Memory           |        -|      -|      -|      -|
|Multiplexer      |        -|      -|      -|     36|
|Register         |        -|      -|     42|      -|
+-----------------+---------+-------+-------+-------+
|Total            |        0|      0|     42|    107|
+-----------------+---------+-------+-------+-------+
|Available        |      120|     80|  35200|  17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%)  |        0|      0|   ~0  |   ~0  |
+-----------------+---------+-------+-------+-------+

256Byteと比較するとFFとLUTが若干増えたけど、256Byte同じく、4,096bitはどこに隠れた?

メモリサイズを1,024wordに変更

#define SIZE (1024)
+-----------------+---------+-------+-------+-------+
|       Name      | BRAM_18K| DSP48E|   FF  |  LUT  |
+-----------------+---------+-------+-------+-------+
|DSP              |        -|      -|      -|      -|
|Expression       |        -|      0|      0|     72|
|FIFO             |        -|      -|      -|      -|
|Instance         |        -|      -|      -|      -|
|Memory           |        -|      -|      -|      -|
|Multiplexer      |        -|      -|      -|     36|
|Register         |        -|      -|     45|      -|
+-----------------+---------+-------+-------+-------+
|Total            |        0|      0|     45|    108|
+-----------------+---------+-------+-------+-------+
|Available        |      120|     80|  35200|  17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%)  |        0|      0|   ~0  |   ~0  |
+-----------------+---------+-------+-------+-------+

4kbit増えてるんだけど、本当にこれでいいの?

メモリサイズを2,048wordに変更

#define SIZE (2048)
+-----------------+---------+-------+-------+-------+
|       Name      | BRAM_18K| DSP48E|   FF  |  LUT  |
+-----------------+---------+-------+-------+-------+
|DSP              |        -|      -|      -|      -|
|Expression       |        -|      0|      0|     73|
|FIFO             |        -|      -|      -|      -|
|Instance         |        -|      -|      -|      -|
|Memory           |        -|      -|      -|      -|
|Multiplexer      |        -|      -|      -|     36|
|Register         |        -|      -|     48|      -|
+-----------------+---------+-------+-------+-------+
|Total            |        0|      0|     48|    109|
+-----------------+---------+-------+-------+-------+
|Available        |      120|     80|  35200|  17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%)  |        0|      0|   ~0  |   ~0  |
+-----------------+---------+-------+-------+-------+

ホント、bitはどこに消えたの?

メモリサイズを4,096wordに変更

#define SIZE (4096)
+-----------------+---------+-------+-------+-------+
|       Name      | BRAM_18K| DSP48E|   FF  |  LUT  |
+-----------------+---------+-------+-------+-------+
|DSP              |        -|      -|      -|      -|
|Expression       |        -|      0|      0|     74|
|FIFO             |        -|      -|      -|      -|
|Instance         |        -|      -|      -|      -|
|Memory           |        -|      -|      -|      -|
|Multiplexer      |        -|      -|      -|     36|
|Register         |        -|      -|     51|      -|
+-----------------+---------+-------+-------+-------+
|Total            |        0|      0|     51|    110|
+-----------------+---------+-------+-------+-------+
|Available        |      120|     80|  35200|  17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%)  |        0|      0|   ~0  |   ~0  |
+-----------------+---------+-------+-------+-------+

やべ、なんかもう信用できないサイズになってきた。

メモリサイズを16,384wordに変更

#define SIZE (16384)
+-----------------+---------+-------+-------+-------+
|       Name      | BRAM_18K| DSP48E|   FF  |  LUT  |
+-----------------+---------+-------+-------+-------+
|DSP              |        -|      -|      -|      -|
|Expression       |        -|      0|      0|     76|
|FIFO             |        -|      -|      -|      -|
|Instance         |        -|      -|      -|      -|
|Memory           |        -|      -|      -|      -|
|Multiplexer      |        -|      -|      -|     36|
|Register         |        -|      -|     57|      -|
+-----------------+---------+-------+-------+-------+
|Total            |        0|      0|     57|    112|
+-----------------+---------+-------+-------+-------+
|Available        |      120|     80|  35200|  17600|
+-----------------+---------+-------+-------+-------+
|Utilization (%)  |        0|      0|   ~0  |   ~0  |
+-----------------+---------+-------+-------+-------+

マジでどこに消えたの?

メモリサイズを16,385wordに変更

#define SIZE (16385)

これはエラーになった。

ERROR: [CF2XD 83-2235] Invalid array size (16385) for bram port 'MemInA_PORTA' on component 'MemTest_1'
ERROR: [CF2XD 83-2239] failed to create xd_adapter for accelerator comp MemTest_1
ERROR: [CF2XD 83-2110] An error has occurred reading the system description file apsys_0.xml.  If targeting a custom platform or hardware library, ensure that hardware function mappings accurately map software function prototypes to IP port interfaces and register offsets.  Please consult the log files in _sds/reports for additional ERROR messages. You may find it helpful to run sdscc with the '-verbose' option.
ERROR: [SystemLinker 83-4806] Exiting system_linker: Error when calling '/opt/Xilinx/SDx/2017.1/bin/cf2xd -i apsys_0.xml -o top.xml -r /home/hidemi/workspace/sdsocCNN/MemTest0_6/Debug/_sds/.cdb/xd_ip_db.xml -trace-buffer 1024 -mc '
ERROR: [SdsCompiler 83-5019] Exiting sds++ : Error when calling '/opt/Xilinx/SDx/2017.1/bin/system_linker -cf-input /home/hidemi/workspace/sdsocCNN/MemTest0_6/Debug/_sds/.llvm/apsys_0.xml -cf-output-dir _sds/p0 -ip-db /home/hidemi/workspace/sdsocCNN/MemTest0_6/Debug/_sds/.cdb/xd_ip_db.xml -ip-repo /home/hidemi/workspace/sdsocCNN/MemTest0_6/Debug/_sds/iprepo/repo -sds-pf /opt/Xilinx/SDx/2017.1/platforms/zybo:linux  -sds-sys-config linux -sds-proc a9_0 -software-only   -target-os linux -trace-buffer 1024 -sdsoc '
sds++ log file saved as /home/hidemi/workspace/sdsocCNN/MemTest0_6/Debug/_sds/reports/sds.log
ERROR: [SdsCompiler 83-5004] Build failed
make: *** [MemTest0_6.elf] Error 1

makefile:45: recipe for target 'MemTest0_6.elf' failed

ちょっと待て!

16,384wordまでBRAMを使用しなかったくせに、16,385wordになったらBRAMを使うの?

急に?

BRAM使ってないんだからエラーにすんなよ。

マニュアルにもBRAMの深さは16,384が最大で・・・と、書いてのと、16,384までBRAMに割り振られなかったのでFFで対応しているのかと思ってたんだけど・・・

もしかして、配列の深さが16,384を超えるとエラーなだけ?

2017年09月04日 23時14分21秒 - Permament Link

【SDSoC】pragma実験(メモリ編)・その1

とりあえず、SDSoCのpragmaを整理していこう。

pragmaめんどくせぇ〜。

まずは、性能に重要なメモリ周辺から整理してみる。

Cソースでメモリというと、大分類で変数と配列に別れる。

ここでは構造体やmallocは配列の一部とする。

変数はスカラーで要素が1つかないメモリ領域である。

SDSoCではPLにある変数はAXI_LITEでアクセスする。

配列AXI_DMA_SG、AXI_DMA_SIMLE、AXI_DMA_2D、AXI_FIFO、AXI_M、AXI_LITEのいずれかでPLとデータのアクセスをする。

大きく分ければ、DMAかDMAではないかの2つ。

これを表にしてみよう。

たぶん、こうだろう。

アクセス方法 DMA or noDMA 特徴
AXI_DMA_SG DMA スキャッターギャザーDMAを使用した転送。mallocに対応する。
AXI_DMA_SIMLE DMA 連続した領域でのDMA。CMA領域を使用したDMAになる。sds_mallocに対応する。
AXI_DMA_2D DMA
AXI_FIFO DMA
AXI_M noDMA もしかして、DMAじゃない?
AXI_LITE noDMA AXI_GPを使用したアクセス

SDSoCには次の仕様がある。

  • mallocの場合、通常はAXI_DMA_SGを使用する
  • 300Byte未満はAXI_FIFOを使用する
  • AXI_FIFOの方がAXI_DMA_SGよりデータ転送時間が短く、PLの専有リソースも少ない。
  • 構造体、クラスはフラット化する

なんで300Byte未満?

変数はAXI_LITEから変えられないので、たくさんの変数を設定する場合は配列や構造体にしてDMAにするのが良さげかな?

と、いうことで実験開始!

実験内容

SDSoCのpragmaでメモリに関するものは次のものである。

これを1つずつ試してみようではないか!

結果は次から・・・

2017年09月04日 00時30分55秒 - Permament Link