FC2カウンター FPGAの部屋 DNN
FC2ブログ

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

hls4mlをやってみた7(自分で学習したネットワークをhls4mlでハードウェア化2)

hls4mlをやってみた6(自分で学習したネットワークをhls4mlでハードウェア化1)”の続き。

前回は、白線追従ロボットカーの学習データ keras_curve_cnn2_line を hls4ml でVivado HLS 2019.1 のプロジェクトにしようということで、白線追従ロボットカーの学習データのネットワーク構造と重みのファイルを出力した。今回は、それをhls4ml でVivado HLS のプロジェクトにしてみよう。

keras_curve_cnn2_line.json と keras_curve_cnn2_line_weights.h5 をhls4ml/keras-to-hls/example-keras-model-files/ ディレクトリにコピーした。
hls4ml_28_190704.png

hls4ml/keras-to-hls/ ディレクトリに keras_curve_cnn2_line.yml を作成した。
hls4ml_29_190704.png

keras_curve_cnn2_line.yml の内容を示す。
hls4ml_30_190704.png

KerasJson: example-keras-model-files/keras_curve_cnn2_line.json
KerasH5:   example-keras-model-files/keras_curve_cnn2_line_weights.h5
OutputDir: keras_curve_cnn2_line
ProjectName: keras_curve_cnn2_line
XilinxPart: xcku5p-sfvb784-1-e
ClockPeriod: 5

IOType: io_parallel # options: io_serial/io_parallel
HLSConfig:
  Model:
    Precision: ap_fixed<16,6>
    ReuseFactor: 1



hls4ml でVivado HLS の tcl ファイルを作成する。
python keras-to-hls.py -c keras_curve_cnn2_line.yml
hls4ml_31_190704.png

hls4ml/keras-to-hls/keras_curve_cnn2_line/ ディレクトリができて、その下に build_prj.tcl が生成されている。
hls4ml_32_190704.png

Vivado HLS で build_prj.tcl を実行したところエラーが出てしまった。
cd keras_curve_cnn2_line
vivado_hls -f build_prj.tcl

hls4ml_33_190704.png

ERROR: [XFORM 203-504] Stop unrolling loop 'Product1' (/home/masaaki/DNN/hls4ml/nnet_utils/nnet_dense.h:97) in function 'nnet::dense, ap_fixed<16, 6, (ap_q_mode)5, (ap_o_mode)3, 0>, config6>' because it may cause large runtime and excessive memory usage due to increase in code size. Please avoid unrolling the loop or form sub-functions for code in the loop body.
ERROR: [HLS 200-70] Pre-synthesis failed.
command 'ap_source' returned error code
while executing
"source build_prj.tcl"
("uplevel" body line 1)
invoked from within
"uplevel \#0 [list source $arg] "


large runtime and excessive memory usage エラーだった。このエラー、何とかならないものだろうか?何時間、何日かかっても良いので、続けて欲しい。Xilinx さん、よろしくお願いします。

一応、Vivado HLS 2019.1を立ち上げて、もう一度、C コードの合成をやってみたが結果は同じだった。
hls4ml_34_190705.png

hls4ml は小さいネットワークの時のみ、使えるみたいだ。
  1. 2019年07月06日 04:34 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

hls4mlをやってみた6(自分で学習したネットワークをhls4mlでハードウェア化1)

hls4mlをやってみた5(KERAS_conv1d_small_nfilt5その2)”の続き。

前回は、KERAS_conv1d_small_nfilt5 のネットワーク構造を調べた。今回は、白線追従ロボットカーの学習データ keras_curve_cnn2_line を hls4ml でVivado HLS 2019.1 のプロジェクトにしてみよう。

hls4ml にかけるには、モデルの構造を記述したJSON ファイルと、モデルの重みの h5 ファイルが必要なので、keras_curve_cnn2_line のJupyter notebook を立ち上げて、出力してみよう。
最初に学習済みモデルを読み込む。

# 学習済みモデルの読み込み

from keras.models import load_model

model = load_model('keras_curve_cnn2_line.h5')


hls4ml_25_190704.png

モデルを json に書き出す。

# save as JSON
json_string = model.to_json()


モデルを json ファイルに書き出して、重みも h5 ファイルに書き出す。

json_name='keras_curve_cnn2_line.json'

with open(json_name, mode='w') as f:
    f.write(json_string)

model.save_weights('keras_curve_cnn2_line_weights.h5')


hls4ml_26_190704.png

keras_curve_cnn2_line.json と keras_curve_cnn2_line_weights.h5 を出力することができた。
hls4ml_27_190704.png

なお keras のコードは、Keras Documentation の”モデルについて”を参考にさせていただいた。
  1. 2019年07月05日 05:00 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

hls4mlをやってみた5(KERAS_conv1d_small_nfilt5その2)

hls4mlをやってみた4(KERAS_conv1d_small_nfilt5その1)”の続き。

前回は、KERAS_conv1d_small_nfilt5 ネットワークをビルドして、C コードの合成結果を観察した。今回は、KERAS_conv1d_small_nfilt5 のネットワーク構造を調べていこう。

KERAS_conv1d_small_nfilt5.cpp を引用する。

//
//    rfnoc-hls-neuralnet: Vivado HLS code for neural-net building blocks
//
//    Copyright (C) 2017 EJ Kreinar
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
#include <iostream>

#include "KERAS_conv1d_small_nfilt5.h"

//hls-fpga-machine-learning insert weights
#include "weights/w2.h"
#include "weights/b2.h"
#include "weights/w4.h"
#include "weights/b4.h"
#include "weights/w6.h"
#include "weights/b6.h"
#include "weights/w8.h"
#include "weights/b8.h"
#include "weights/w10.h"
#include "weights/b10.h"

void KERAS_conv1d_small_nfilt5(
    input_t input_1[N_INPUT_1_1*N_INPUT_2_1],
    result_t layer11_out[N_LAYER_10],
    unsigned short &const_size_in_1,
    unsigned short &const_size_out_1
) {

    //hls-fpga-machine-learning insert IO
    #pragma HLS ARRAY_RESHAPE variable=input_1 complete dim=0 
    #pragma HLS ARRAY_RESHAPE variable=layer11_out complete dim=0 
    #pragma HLS INTERFACE ap_vld port=input_1,layer11_out 
    #pragma HLS PIPELINE 

    const_size_in_1 = N_INPUT_1_1*N_INPUT_2_1;
    const_size_out_1 = N_LAYER_10;

    // ****************************************
    // NETWORK INSTANTIATION
    // ****************************************

    //hls-fpga-machine-learning insert layers

    layer2_t layer2_out[Y_OUTPUTS_2*N_FILT_2];
    #pragma HLS ARRAY_PARTITION variable=layer2_out complete dim=0
    nnet::conv_1d<input_t, layer2_t, config2>(input_1, layer2_out, w2, b2);

    layer3_t layer3_out[Y_OUTPUTS_2*N_FILT_2];
    #pragma HLS ARRAY_PARTITION variable=layer3_out complete dim=0
    nnet::relu<layer2_t, layer3_t, relu_config3>(layer2_out, layer3_out);

    layer4_t layer4_out[Y_OUTPUTS_4*N_FILT_4];
    #pragma HLS ARRAY_PARTITION variable=layer4_out complete dim=0
    nnet::conv_1d<layer3_t, layer4_t, config4>(layer3_out, layer4_out, w4, b4);

    layer5_t layer5_out[Y_OUTPUTS_4*N_FILT_4];
    #pragma HLS ARRAY_PARTITION variable=layer5_out complete dim=0
    nnet::relu<layer4_t, layer5_t, relu_config5>(layer4_out, layer5_out);

    layer6_t layer6_out[Y_OUTPUTS_6*N_FILT_6];
    #pragma HLS ARRAY_PARTITION variable=layer6_out complete dim=0
    nnet::conv_1d<layer5_t, layer6_t, config6>(layer5_out, layer6_out, w6, b6);

    layer7_t layer7_out[Y_OUTPUTS_6*N_FILT_6];
    #pragma HLS ARRAY_PARTITION variable=layer7_out complete dim=0
    nnet::relu<layer6_t, layer7_t, relu_config7>(layer6_out, layer7_out);

    layer8_t layer8_out[N_LAYER_8];
    #pragma HLS ARRAY_PARTITION variable=layer8_out complete dim=0
    nnet::dense<layer7_t, layer8_t, config8>(layer7_out, layer8_out, w8, b8);

    layer9_t layer9_out[N_LAYER_8];
    #pragma HLS ARRAY_PARTITION variable=layer9_out complete dim=0
    nnet::relu<layer8_t, layer9_t, relu_config9>(layer8_out, layer9_out);

    layer10_t layer10_out[N_LAYER_10];
    #pragma HLS ARRAY_PARTITION variable=layer10_out complete dim=0
    nnet::dense<layer9_t, layer10_t, config10>(layer9_out, layer10_out, w10, b10);

    nnet::softmax<layer10_t, result_t, softmax_config11>(layer10_out, layer11_out);


}


KERAS_conv1d_small_nfilt5.cpp と parameters.h から推定した層構成を示す。ただしすべての層の変数の型は ap_fixed<16,6> となっている。

入力層 40 入力
conv_1d 入力数 40 出力数 30
relu 入力数 30 出力数 30
conv_1d 入力数 30 出力数 20
relu 入力数 20 出力数 20
conv_1d 入力数 20 出力数 10
relu 入力数 10 出力数 10
dense 入力数 10 出力数 5
relu 入力数 5 出力数 5
dense 入力数 5 出力数 5
softmax 入力数 5 出力数 5


IP の入力と出力のフォーマットだが、 KERAS_conv1d_small_nfilt5.cpp で dim=0 で ARRAY_RESHAPE ディレクティブが書かれている。
よって、入力の input_1 が ap_fixed<16,6> が 40 個なので、640 ビット幅となり、
出力の layer9_out が ap_fixed<16,6> が 5 個なので、 80 ビット幅となっている。
KERAS_conv1d_small_nfilt5.vhd の entity 部分を引用する。

entity KERAS_conv1d_small_nfilt5 is
port (
    ap_clk : IN STD_LOGIC;
    ap_rst : IN STD_LOGIC;
    ap_start : IN STD_LOGIC;
    ap_done : OUT STD_LOGIC;
    ap_idle : OUT STD_LOGIC;
    ap_ready : OUT STD_LOGIC;
    input_1_V_ap_vld : IN STD_LOGIC;
    input_1_V : IN STD_LOGIC_VECTOR (639 downto 0);
    layer11_out_V : OUT STD_LOGIC_VECTOR (79 downto 0);
    layer11_out_V_ap_vld : OUT STD_LOGIC;
    const_size_in_1 : OUT STD_LOGIC_VECTOR (15 downto 0);
    const_size_in_1_ap_vld : OUT STD_LOGIC;
    const_size_out_1 : OUT STD_LOGIC_VECTOR (15 downto 0);
    const_size_out_1_ap_vld : OUT STD_LOGIC );
end;


2つの hls4ml のexample ネットワークを見てきたが、小さいネットワークだった。自分で構築したニューラルネットワークを次にはやってみたい。
  1. 2019年07月04日 04:56 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

hls4mlをやってみた4(KERAS_conv1d_small_nfilt5その1)

hls4mlをやってみた3(シミュレーション)”の続き。

前回は、ivado HLS プロジェクトの myproject_prj の C シミュレーションとC/RTL 協調シミュレーションの結果を見た。今回は、異なるネットワークを自分で yml ファイルを作成してやってみよう。

hls4ml/keras-to-hls/example-keras-model-files/ ディレクトリのKERAS_conv1d_small_nfilt5.json , KERAS_conv1d_small_nfilt5_weights.h5 の組のネットワークをVivado HLS で実装してみることにする。
hls4ml_17_190703.png

hls4ml/keras-to-hls/ ディレクトリに KERAS_conv1d_small_nfilt5.yml を作成した。
hls4ml_18_190703.png

KERAS_conv1d_small_nfilt5.yml の内容を示す。
hls4ml_19_190703.png

KerasJson: example-keras-model-files/KERAS_conv1d_small_nfilt5.json
KerasH5: example-keras-model-files/KERAS_conv1d_small_nfilt5_weights.h5
OutputDir: KERAS_conv1d_small_nfilt5
ProjectName: KERAS_conv1d_small_nfilt5
XilinxPart: xcku5p-sfvb784-1-e
ClockPeriod: 5

IOType: io_parallel # options: io_serial/io_parallel
HLSConfig:
Model:
Precision: ap_fixed<16,6>
ReuseFactor: 1


hls4ml でKERAS_conv1d_small_nfilt5 のネットワークを Vivaod HLS のプロジェクトへ変換した。
python keras-to-hls.py -c KERAS_conv1d_small_nfilt5.yml
hls4ml_20_190703.png

KERAS_conv1d_small_nfilt5 ディレクトリに行って、build_prj.tcl を実行する。
cd KERAS_conv1d_small_nfilt5
vivado_hls -f build_prj.tcl

hls4ml_21_190703.png

tcl スクリプトの実行が終了した。
hls4ml_22_190703.png

Vivado HLS 2019.1 を立ち上げて、C コードの合成の結果を確認した。
hls4ml_23_190703.png
hls4ml_24_190703.png

Latency は 15 クロックで、Interval は 1 クロックだった。
リソースも今度はFPGA に収まっている。
  1. 2019年07月03日 05:10 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

hls4mlをやってみた3(シミュレーション)

hls4mlをやってみた2(KERAS_3layer ネットワークの構成)”の続き。

前回は、Vivado HLS を使用して機械学習をハードウェア化するフレームワークのhls4ml を使用してVivado HLS のIP として生成した KERAS_3layer ネットワークがどのようななネットワークか知らないので調査した。今回は、そのVivado HLS プロジェクトの myproject_prj の C シミュレーションとC/RTL 協調シミュレーションの結果を見ていこう。

最初にテストベンチの myproject_test.cpp を引用する。

//
//    rfnoc-hls-neuralnet: Vivado HLS code for neural-net building blocks
//
//    Copyright (C) 2017 EJ Kreinar
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "firmware/parameters.h"
#include "firmware/myproject.h"
#include "nnet_helpers.h"


int main(int argc, char **argv)
{
  //hls-fpga-machine-learning insert data
  input_t input_1[N_INPUT_1_1] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  result_t layer9_out[N_LAYER_8] = {0,0,0,0,0};

  //hls-fpga-machine-learning insert top-level-function
  unsigned short size_in1,size_out1;
  myproject(input_1,layer9_out,size_in1,size_out1);

  //hls-fpga-machine-learning insert output
  for(int i = 0; i < N_LAYER_8; i++) {
    std::cout << layer9_out[i] << " ";
  }
  std::cout << std::endl;

  return 0;
}


入力配列(input_1)に値を代入して、1度だけ myproject() を読んでいる。
このテストベンチでのシミュレーション結果を示す。

INFO: [SIM 2] *************** CSIM start ***************
INFO: [SIM 4] CSIM will launch GCC as the compiler.
   Compiling ../../../../myproject_test.cpp in debug mode
   Compiling ../../../../firmware/myproject.cpp in debug mode
   Generating csim.exe
0.0292969 0.761719 0.0566406 0.142578 0.0361328 
INFO: [SIM 1] CSim done with 0 errors.
INFO: [SIM 3] *************** CSIM finish ***************


layer9_out[] に値が出力されいてる。

次に、C/RTL 協調シミュレーションの結果を示す。
hls4ml_14_190701.png

Latency は 15 クロックだが、Interval が NA になってしまっている。これは、myproject() のコールが 1 回のためだと思う。
それでは、テストベンチの myproject_test.cpp を myproject() を 2 回呼ぶように書き換えた。新しい myproject_test.cpp を示す。

//
//    rfnoc-hls-neuralnet: Vivado HLS code for neural-net building blocks
//
//    Copyright (C) 2017 EJ Kreinar
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
#include <fstream>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#include "firmware/parameters.h"
#include "firmware/myproject.h"
#include "nnet_helpers.h"


int main(int argc, char **argv)
{
  //hls-fpga-machine-learning insert data
  input_t input_1[N_INPUT_1_1] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  input_t input_2[N_INPUT_1_1] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16};
  result_t layer9_out[N_LAYER_8] = {0,0,0,0,0};
  result_t layer9_out2[N_LAYER_8] = {0,0,0,0,0};

  //hls-fpga-machine-learning insert top-level-function
  unsigned short size_in1,size_out1;
  myproject(input_1,layer9_out,size_in1,size_out1);
  myproject(input_2,layer9_out2,size_in1,size_out1);

  //hls-fpga-machine-learning insert output
  for(int i = 0; i < N_LAYER_8; i++) {
    std::cout << layer9_out[i] << " ";
  }
  std::cout << std::endl;

  for(int i = 0; i < N_LAYER_8; i++) {
    std::cout << layer9_out2[i] << " ";
  }
  std::cout << std::endl;

  return 0;
}


このテストベンチで C シミュレーションを行った。結果を示す。

INFO: [SIM 2] *************** CSIM start ***************
INFO: [SIM 4] CSIM will launch GCC as the compiler.
   Compiling ../../../../myproject_test.cpp in debug mode
   Generating csim.exe
0.0292969 0.761719 0.0566406 0.142578 0.0361328 
0 0.399414 0.0439453 0.571289 0.015625 
INFO: [SIM 1] CSim done with 0 errors.
INFO: [SIM 3] *************** CSIM finish ***************


結果が 2 つになった。

C/RTL 協調シミュレーションの結果を示す。
hls4ml_15_190701.png

Interval が 1 になった。
C/RTL 協調シミュレーションの波形を確認しよう。
hls4ml_16_190701.png

波形を少し拡大してみよう。
hls4ml_17_190701.png

input_1_V_ap_vld が 1 になったクロックから layer9_out_V_ap_vld が 1 になるまでは、 75 ns で クロックが 5 ns なので、15 クロックかかっている。そして、次の結果が 1 クロック後に出いているので、Latency は 15 クロック、Interval が 1 クロックということがC/RTL 協調シミュレーションの波形からも確認することができた。
  1. 2019年07月02日 04:58 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

hls4mlをやってみた2(KERAS_3layer ネットワークの構成)

hls4mlをやってみた1”の続き。

前回は、Vivado HLS を使用して機械学習をハードウェア化するフレームワークのhls4ml をインストールし、KERAS_3layer ネットワークをVivado HLS のプロジェクトとして生成し、C シミュレーション、C コードの合成、C/RTL 協調シミュレーション、Export RTL をTCL スクリプトで行った。今回は、Vivado HLS のIP として生成した KERAS_3layer ネットワークがどのようななネットワークか知らないので、調べていこう。

まずは myproject.cpp を貼っておく。

//
//    rfnoc-hls-neuralnet: Vivado HLS code for neural-net building blocks
//
//    Copyright (C) 2017 EJ Kreinar
//
//    This program is free software: you can redistribute it and/or modify
//    it under the terms of the GNU General Public License as published by
//    the Free Software Foundation, either version 3 of the License, or
//    (at your option) any later version.
//
//    This program is distributed in the hope that it will be useful,
//    but WITHOUT ANY WARRANTY; without even the implied warranty of
//    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//    GNU General Public License for more details.
//
//    You should have received a copy of the GNU General Public License
//    along with this program.  If not, see <http://www.gnu.org/licenses/>.
//
#include <iostream>

#include "myproject.h"

//hls-fpga-machine-learning insert weights
#include "weights/w2.h"
#include "weights/b2.h"
#include "weights/w4.h"
#include "weights/b4.h"
#include "weights/w6.h"
#include "weights/b6.h"
#include "weights/w8.h"
#include "weights/b8.h"

void myproject(
    input_t input_1[N_INPUT_1_1],
    result_t layer9_out[N_LAYER_8],
    unsigned short &const_size_in_1,
    unsigned short &const_size_out_1
) {

    //hls-fpga-machine-learning insert IO
    #pragma HLS ARRAY_RESHAPE variable=input_1 complete dim=0 
    #pragma HLS ARRAY_RESHAPE variable=layer9_out complete dim=0 
    #pragma HLS INTERFACE ap_vld port=input_1,layer9_out 
    #pragma HLS PIPELINE 

    const_size_in_1 = N_INPUT_1_1;
    const_size_out_1 = N_LAYER_8;

    // ****************************************
    // NETWORK INSTANTIATION
    // ****************************************

    //hls-fpga-machine-learning insert layers

    layer2_t layer2_out[N_LAYER_2];
    #pragma HLS ARRAY_PARTITION variable=layer2_out complete dim=0
    nnet::dense<input_t, layer2_t, config2>(input_1, layer2_out, w2, b2);

    layer3_t layer3_out[N_LAYER_2];
    #pragma HLS ARRAY_PARTITION variable=layer3_out complete dim=0
    nnet::relu<layer2_t, layer3_t, relu_config3>(layer2_out, layer3_out);

    layer4_t layer4_out[N_LAYER_4];
    #pragma HLS ARRAY_PARTITION variable=layer4_out complete dim=0
    nnet::dense<layer3_t, layer4_t, config4>(layer3_out, layer4_out, w4, b4);

    layer5_t layer5_out[N_LAYER_4];
    #pragma HLS ARRAY_PARTITION variable=layer5_out complete dim=0
    nnet::relu<layer4_t, layer5_t, relu_config5>(layer4_out, layer5_out);

    layer6_t layer6_out[N_LAYER_6];
    #pragma HLS ARRAY_PARTITION variable=layer6_out complete dim=0
    nnet::dense<layer5_t, layer6_t, config6>(layer5_out, layer6_out, w6, b6);

    layer7_t layer7_out[N_LAYER_6];
    #pragma HLS ARRAY_PARTITION variable=layer7_out complete dim=0
    nnet::relu<layer6_t, layer7_t, relu_config7>(layer6_out, layer7_out);

    layer8_t layer8_out[N_LAYER_8];
    #pragma HLS ARRAY_PARTITION variable=layer8_out complete dim=0
    nnet::dense<layer7_t, layer8_t, config8>(layer7_out, layer8_out, w8, b8);

    nnet::softmax<layer8_t, result_t, softmax_config9>(layer8_out, layer9_out);


}


myproject .cpp と parameters.h から推定した層構成を示す。

入力層 16 入力
dense 16 入力 64 出力
relu
dense 64 入力 32 出力
relu
dense 32 入力 32 出力
relu
dense 32 入力 5 出力
softmax 5 出力


入力、出力のデータ型は、ap_fixed<16,6> だった。

IP の入力と出力のフォーマットだが、 myproject.cpp で dim=0 で ARRAY_RESHAPE ディレクティブが書かれている。
よって、入力の input_1 が ap_fixed<16,6> が 16 個なので、256 ビット幅となり、
出力の layer9_out が ap_fixed<16,6> が 5 個なので、 80 ビット幅となっている。
myproject.vhd の entity 部分を引用する。

entity myproject is
port (
    ap_clk : IN STD_LOGIC;
    ap_rst : IN STD_LOGIC;
    ap_start : IN STD_LOGIC;
    ap_done : OUT STD_LOGIC;
    ap_idle : OUT STD_LOGIC;
    ap_ready : OUT STD_LOGIC;
    input_1_V_ap_vld : IN STD_LOGIC;
    input_1_V : IN STD_LOGIC_VECTOR (255 downto 0);
    layer9_out_V : OUT STD_LOGIC_VECTOR (79 downto 0);
    layer9_out_V_ap_vld : OUT STD_LOGIC;
    const_size_in_1 : OUT STD_LOGIC_VECTOR (15 downto 0);
    const_size_in_1_ap_vld : OUT STD_LOGIC;
    const_size_out_1 : OUT STD_LOGIC_VECTOR (15 downto 0);
    const_size_out_1_ap_vld : OUT STD_LOGIC );
end;

  1. 2019年06月30日 05:23 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0

hls4mlをやってみた1

hls4ml をやってみた。hls4ml はVivado HLS を使用して機械学習をハードウェア化するフレームワークだ。
なお、OS は Ubuntu 18.04 を使用している。

インストール前の環境のインストールは、Setup -> Dependencies を見れば分かるが、numpy,h5py, pyyaml, PyTorch, scikit-learn だ。だいたいインストールされていると思うので、ここは飛ばす。後で不具合が出たらインストールを確認することにする。

次に、Setup -> Quick Start をやってみよう。
まずは、リポジトリを git clone する。
git clone https://github.com/hls-fpga-machine-learning/hls4ml.git
hls4ml_1_190628.png

hls4ml ディレクトリの内容を示す。
hls4ml_2_190628.png

Quick Start に従ってやっていこう。
cd hls4ml/keras-to-hls/
2to3 -w keras-to-hls.py

hls4ml_3_190628.png

cd ../hls-writer/
2to3 -w hls_writer.py

hls4ml_4_190628.png

Vivado 2019.1 WebPACK なので、指定されたFPGA が無いため、hls4ml/keras-to-hls/keras-config.yml ファイルの XilinxPart を WebPACKでも使えるUltraScale+ (xcku5p-sfvb784-1-e) に変更した。
hls4ml_5_190628.png

cd ../keras-to-hls/
python keras-to-hls.py -c keras-config.yml

hls4ml_6_190628.png

my-hls-test ディレクトリが生成された。Viavdo HLS 2019.1 を設定して、build.tcl をVivado HLS 2019.1 で実行した。
cd my-hls-test/
ls
source /tools/Xilinx/Vivado/2019.1/settings64.sh
vivado_hls -f build_prj.tcl

hls4ml_7_190628.png

終了するまで、時間かかりました。
hls4ml_8_190629.png

Vivado HLS 2019.1 をGUI 付きで立ち上げ、my-hls-test/myproject_prj ディレクトリのVivado HLS プロジェクトをロードした。
vivado_hls &
hls4ml_9_190629.png

C コードの合成済みなので、レポートを見てみよう。
hls4ml_10_190629.png
hls4ml_11_190629.png

凄い。Latency が 15 クロックで、Interval が 1 だった。つまり、15 クロックで出力できて、次のクロックには次のデータ入れられるということね。。。それで 200 MHz 動作か。
でもWebPACK で使えるFPGA だと、DSP48E がオーバーフローしてしまっている。実装のリソースをDSP48E に集めているのかも?

Analysis を見てみよう。
hls4ml_12_190629.png

hls4ml_13_190629.png

softmax にクロック数がかかっている。
  1. 2019年06月29日 04:51 |
  2. DNN
  3. | トラックバック:0
  4. | コメント:0
»