From 6217aa333146b7cece71ce260d26c5bda90fb97d Mon Sep 17 00:00:00 2001 From: BLMartin99 Date: Wed, 5 Jul 2023 14:48:02 -0700 Subject: [PATCH 1/3] Beginning thresholded relu example, it works with the self-checking testbench --- example-prjs/thresholded_relu/catapult.py | 43 ++++++ example-prjs/thresholded_relu/config.yml | 15 ++ example-prjs/thresholded_relu/run_catapult.sh | 44 ++++++ .../thresholded_relu/tb_input_features.dat | 3 + .../tb_output_predictions.dat | 3 + .../thresholded_relu/thresholded_relu.h5 | Bin 0 -> 8416 bytes .../thresholded_relu/thresholded_relu.json | 1 + .../thresholded_relu/thresholded_relu.py | 62 ++++++++ .../thresholded_relu_test.cpp | 133 ++++++++++++++++++ .../thresholded_relu_weights.h5 | Bin 0 -> 7120 bytes 10 files changed, 304 insertions(+) create mode 100644 example-prjs/thresholded_relu/catapult.py create mode 100644 example-prjs/thresholded_relu/config.yml create mode 100755 example-prjs/thresholded_relu/run_catapult.sh create mode 100644 example-prjs/thresholded_relu/tb_input_features.dat create mode 100644 example-prjs/thresholded_relu/tb_output_predictions.dat create mode 100644 example-prjs/thresholded_relu/thresholded_relu.h5 create mode 100644 example-prjs/thresholded_relu/thresholded_relu.json create mode 100644 example-prjs/thresholded_relu/thresholded_relu.py create mode 100644 example-prjs/thresholded_relu/thresholded_relu_test.cpp create mode 100644 example-prjs/thresholded_relu/thresholded_relu_weights.h5 diff --git a/example-prjs/thresholded_relu/catapult.py b/example-prjs/thresholded_relu/catapult.py new file mode 100644 index 0000000000..79db00adbf --- /dev/null +++ b/example-prjs/thresholded_relu/catapult.py @@ -0,0 +1,43 @@ + +import hls4ml +# import pprint +import yaml +import numpy as np + +print(hls4ml.__version__) + +with open('config.yml', 'r') as ymlfile: + config = yaml.safe_load(ymlfile) + +# try tweaking the reuse_factor on one layer to get different pipelining +# config['HLSConfig']['LayerName']['fc1']['ReuseFactor'] = 4 + +print('NETWORK') +print(config) + +config['OutputDir'] = 'my-Catapult-test' +config['Backend'] = 'Catapult' +config['IOType'] = 'io_stream' + +config['HLSConfig']['Model']['Strategy'] = 'Latency' +#config['HLSConfig']['Model']['Strategy'] = 'Resource' + +# default threshold is infinity +config['HLSConfig']['Model']['BramFactor'] = np.inf +# set to zero to force all weights onto (external function) interface +config['HLSConfig']['Model']['BramFactor'] = 0 + +print('CURRENT CONFIGURATION') +print('Backend='+config['Backend']) +print('IOType='+config['IOType']) +print('BramFactor={bf}'.format(bf=config['HLSConfig']['Model']['BramFactor'])) + +# pprint.pprint(config) + +#Convert it to a hls project +hls_model = hls4ml.converters.keras_to_hls(config) + +hls_model.build(vsynth=False) + +# URL for this info: https://fastmachinelearning.org/hls4ml/setup/QUICKSTART.html + diff --git a/example-prjs/thresholded_relu/config.yml b/example-prjs/thresholded_relu/config.yml new file mode 100644 index 0000000000..835d71f257 --- /dev/null +++ b/example-prjs/thresholded_relu/config.yml @@ -0,0 +1,15 @@ +Backend: Catapult +KerasJson: thresholded_relu.json +KerasH5: thresholded_relu_weights.h5 +OutputDir: my-Catapult-test +ProjectName: thresholded_relu +XilinxPart: xcku115-flvb2104-2-i +Part: xcku115-flvb2104-2-i +ClockPeriod: 5 + +IOType : io_parallel +HLSConfig: + Model: + Precision: ap_fixed<16, 6> + ReuseFactor: 1 + Strategy: Latency diff --git a/example-prjs/thresholded_relu/run_catapult.sh b/example-prjs/thresholded_relu/run_catapult.sh new file mode 100755 index 0000000000..80d74f6f2c --- /dev/null +++ b/example-prjs/thresholded_relu/run_catapult.sh @@ -0,0 +1,44 @@ +#! /bin/bash + +# This script runs the Catapult flows to generate the HLS. + +VENV=/wv/scratch-baimar9c/venv + +MGC_HOME=/wv/hlsb/CATAPULT/TOT/CURRENT/aol/Mgc_home +export MGC_HOME + +export PATH=/wv/hlstools/python/python37/bin:$PATH:$XILINX_VIVADO/bin:$MGC_HOME/bin +export LD_LIBRARY_PATH=/wv/hlstools/python/python37/lib:$XILINX_VIVADO/lib/lnx64.o:$MGC_HOME/lib +export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python + +# needed for pytest +export OSTYPE=linux-gnu + +echo "Activating Virtual Environment..." +# bash +source $VENV/bin/activate + +rm -rf ./my-Catapult-test* + +# to run catapult+vivado_rtl +sed -e 's/Vivado/Catapult/g' vivado.py >catapult.py +# to only run catapult +# sed -e 's/Vivado/Catapult/g' vivado.py | sed -e 's/vsynth=True/vsynth=False/g' >catapult.py + +# actually run HLS4ML + Catapult (+ optional vivado RTL) +python3 catapult.py + +# run just the C++ execution +echo "" +echo "=====================================================" +echo "=====================================================" +echo "C++ EXECUTION" +pushd my-Catapult-test; rm -f a.out; $MGC_HOME/bin/g++ -std=c++17 -I. -DWEIGHTS_DIR=\"firmware/weights\" -Ifirmware -I$MGC_HOME/shared/include firmware/thresholded_relu.cpp thresholded_relu_test.cpp; a.out; popd + +# Using VSCode setup generated by Catapult +echo "" +echo "=====================================================" +echo "=====================================================" +echo "To launch VSCode on the C++ generated by hls4ml:" +echo "setenv LD_LIBRARY_PATH $MGC_HOME/lib:$MGC_HOME/shared/lib" +echo "pushd my-Catapult-test; /wv/hlstools/vscode/LATEST/code Catapult.code-workspace" diff --git a/example-prjs/thresholded_relu/tb_input_features.dat b/example-prjs/thresholded_relu/tb_input_features.dat new file mode 100644 index 0000000000..967ced0937 --- /dev/null +++ b/example-prjs/thresholded_relu/tb_input_features.dat @@ -0,0 +1,3 @@ +1 -2 3 -4 5 -5 1 -2 3 -4 4 -5 1 -2 3 -3 4 -5 1 -2 2 -3 4 -5 1 +-1 2 -3 4 -5 -6 7 -8 9 -10 -11 12 -13 14 -15 -16 17 -18 19 -20 -21 22 -23 24 -25 +1.123 -2.456 3.789 -4.123 5.456 -5.789 1.123 -2.456 3.789 -4.123 4.456 -5.789 1.123 -2.456 3.789 -3.123 4.456 -5.789 1.123 -2.456 2.789 -3.123 4.456 -5.789 1.123 diff --git a/example-prjs/thresholded_relu/tb_output_predictions.dat b/example-prjs/thresholded_relu/tb_output_predictions.dat new file mode 100644 index 0000000000..e6627769af --- /dev/null +++ b/example-prjs/thresholded_relu/tb_output_predictions.dat @@ -0,0 +1,3 @@ +0 -0 3 -0 5 -0 0 -0 3 -0 4 -0 0 -0 3 -0 4 -0 0 -0 0 -0 4 -0 0 +-0 0 -0 4 -0 -0 7 -0 9 -0 -0 12 -0 14 -0 -0 17 -0 19 -0 -0 22 -0 24 -0 +0 -0 3.789 -0 5.456 -0 0 -0 3.789 -0 4.456 -0 0 -0 3.789 -0 4.456 -0 0 -0 2.789 -0 4.456 -0 0 diff --git a/example-prjs/thresholded_relu/thresholded_relu.h5 b/example-prjs/thresholded_relu/thresholded_relu.h5 new file mode 100644 index 0000000000000000000000000000000000000000..0767a9f09aa6917cd1f4f2abaf560389c3161f1b GIT binary patch literal 8416 zcmeHM%}(4f5O(;fR&=RA;sE`TqMQ+eEtRTXN>ymL5-JF&R0*Nf?3&GrkZfZw6rsJ- zTOXsx9{UJ=j6L=(sK=gx-9SLCKq|sM#Ljs9dHiK&vOD=&U3@b-@^FMfE0x#~8#6c>HdaRXZw$Mfa!*Bj5n2B!+hdcUGPb2(mbp2<;daNoXO zSvF^YgrFOphjc45b8|DZj8U4kKNJ{KB9Upf6Q>7u9lg#?{?MYMpcZo}4Wq#eKUf!^ z+agg-9tYEYVDpid9|b@;D9Anq^EjlIZ{~sCC9SqvhNqPS+UBYjg-w_aWyD*6x|y`& zc-pT#+tQoX)u9mv+G?(zR$#qs@l1l|4v(eKf{ZsBqTVAQ`z-KW(CJKTtNRbPaptsZ zV);YPFhV%z+MuU0-c0y*3^u5&4JKS. +// +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "firmware/thresholded_relu.h" +#include "firmware/nnet_utils/nnet_helpers.h" +// #include "firmware/parameters.h" + +#include + +//hls-fpga-machine-learning insert bram + +//hls-fpga-machine-learning insert declare weights + +namespace nnet { + bool trace_enabled = true; + std::map *trace_outputs = NULL; + size_t trace_type_size = sizeof(double); +} + +CCS_MAIN(int argc, char *argv[]) +{ + //load input data from text file + std::ifstream fin("tb_data/tb_input_features.dat"); + //load predictions from text file + std::ifstream fpr("tb_data/tb_output_predictions.dat"); + +#ifdef RTL_SIM + std::string RESULTS_LOG = "tb_data/rtl_cosim_results.log"; +#else + std::string RESULTS_LOG = "tb_data/csim_results.log"; +#endif + std::ofstream fout(RESULTS_LOG); + +#ifndef __SYNTHESIS__ + static bool loaded_weights = false; + if (!loaded_weights) { + //hls-fpga-machine-learning insert load weights + loaded_weights = true; + } +#endif + std::string iline; + std::string pline; + + if (fin.is_open() && fpr.is_open()) { + while ( std::getline(fin,iline) && std::getline (fpr,pline) ) { + char* cstr=const_cast(iline.c_str()); + char* current; + std::vector in; + current=strtok(cstr," "); + while(current!=NULL) { + in.push_back(atof(current)); + current=strtok(NULL," "); + } + cstr=const_cast(pline.c_str()); + std::vector pr; + current=strtok(cstr," "); + while(current!=NULL) { + pr.push_back(atof(current)); + current=strtok(NULL," "); + } +// std::cout << " Input feature map size = " << in.size() << " Output predictions size = " << pr.size() << std::endl; + + //hls-fpga-machine-learning insert data + ac_channel input_1/*("input_1")*/; + nnet::copy_data(in, input_1); + ac_channel layer2_out/*("layer2_out")*/; + + //hls-fpga-machine-learning insert top-level-function + thresholded_relu(input_1,layer2_out); + + for(int i = 0; i < N_INPUT_1_1; i++) + { + if(fabs(pr[i] - layer2_out[0][i].to_double()) > 0.001) + { + std::cout << "FAILURE" << std::endl; + std::cout << "Expected: " << pr[i] << " Actual: " << layer2_out[0][i].to_double() << std::endl; + return 1; + } + } + + //hls-fpga-machine-learning insert tb-output + nnet::print_result(layer2_out, fout); + } + fin.close(); + fpr.close(); + } else { + std::cout << "INFO: Unable to open input/predictions file, using default input." << std::endl; + + //hls-fpga-machine-learning insert zero + ac_channel input_1/*("input_1")*/; + nnet::fill_zero(input_1); + ac_channel layer2_out/*("layer2_out")*/; + + //hls-fpga-machine-learning insert top-level-function + thresholded_relu(input_1,layer2_out); + + //hls-fpga-machine-learning insert output + + //hls-fpga-machine-learning insert tb-output + nnet::print_result(layer2_out, fout); + + } + + fout.close(); + std::cout << "INFO: Saved inference results to file: " << RESULTS_LOG << std::endl; + + return 0; +} diff --git a/example-prjs/thresholded_relu/thresholded_relu_weights.h5 b/example-prjs/thresholded_relu/thresholded_relu_weights.h5 new file mode 100644 index 0000000000000000000000000000000000000000..b4feeba6ab165bae686d089f051d626d32c5d436 GIT binary patch literal 7120 zcmeHL%}&BV5T1%ZL_s0(;LoK`K)`VDCPq;XMvQvkR?)7OP^f7U^yX1-9zA;WQ9Sx6 zz5(vfjKn652Q?vKHtEjp?DXsMb-pc`$J*{*c7AOhR73L4OYM?UZrk@W#{QY87N8;giMNz5whm2M;ERfm(I@Nd4Xh{^(7# zZ{{|O&!L{RyzVMw+;L3g=T322#(z&TZY>bPWJmzaWuQRw4 z3o@`Qv)gapiO}gbJ0j8$t1_>ZlGJ5VJgxnfWoD+QHGsTYH6c1a0~Hf5oy+n%Z(g)T z*M&q}9Sxv`j5vy#4Ac;3QRB2l*o>UM2%}cel`B8t&8oW*Pf6B-l-^%l&mTGvz*F(E z89hU?o=q6{6Usnb&zNHHjCn+~kWRGt$@vRQdTvY`kXwA-NGDmXXLCM`1f93HPzDt! zFF<*S-!Ia0d`n3>@$frJI!WT;W$ruTU-Lld`#bdmjjawU+2}d?Jd*RI^OTNV^T$EP ziEb2xmwqtNF!Gczjb7(Qp;Rgq(J9T-(rC;hW`G%B2ABb6fEi#0m;q*h8DIvO0cL<1 z_+JK24(q!XOi_ssidYw+IzYTmV&iriSf8M{+NxQ&kJT;yclYCi&h^gmc^Bij6RJDL Jb@JDB$4}zbmwf;L literal 0 HcmV?d00001 From 5ee8036304422480c70c74eb58689a5758e23d35 Mon Sep 17 00:00:00 2001 From: BLMartin99 Date: Wed, 5 Jul 2023 14:56:27 -0700 Subject: [PATCH 2/3] Included vivado files --- example-prjs/thresholded_relu/run_vivado.sh | 39 +++++++++++++++++++ example-prjs/thresholded_relu/vivado.py | 43 +++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100755 example-prjs/thresholded_relu/run_vivado.sh create mode 100644 example-prjs/thresholded_relu/vivado.py diff --git a/example-prjs/thresholded_relu/run_vivado.sh b/example-prjs/thresholded_relu/run_vivado.sh new file mode 100755 index 0000000000..f630a803da --- /dev/null +++ b/example-prjs/thresholded_relu/run_vivado.sh @@ -0,0 +1,39 @@ +#! /bin/bash + +# This script runs the Vivado flows to generate the HLS. + +VENV=$HOME/venv + +MGC_HOME=/wv/hlsb/CATAPULT/TOT/CURRENT/aol/Mgc_home +export MGC_HOME + +export PATH=/wv/hlstools/python/python37/bin:$PATH:$XILINX_VIVADO/bin:$MGC_HOME/bin +export LD_LIBRARY_PATH=/wv/hlstools/python/python37/lib:$XILINX_VIVADO/lib/lnx64.o:$MGC_HOME/lib +export PROTOCOL_BUFFERS_PYTHON_IMPLEMENTATION=python + +# needed for pytest +export OSTYPE=linux-gnu + +echo "Activating Virtual Environment..." +# bash +source $VENV/bin/activate + +rm -rf ./my-Vivado-test* + +mkdir -p tb_data + +# to run catapult+vivado_rtl +sed -e 's/Vivado/Catapult/g' vivado.py >catapult.py +# to only run catapult +# sed -e 's/Vivado/Catapult/g' vivado.py | sed -e 's/vsynth=True/vsynth=False/g' >catapult.py + +# actually run HLS4ML + Vivado HLS +python3 vivado.py + +# run just the C++ execution +echo "" +echo "=====================================================" +echo "=====================================================" +echo "C++ EXECUTION" +pushd my-Vivado-test; rm -f a.out; $MGC_HOME/bin/g++ -g -std=c++11 -I. -DWEIGHTS_DIR=\"firmware/weights\" -Ifirmware -Ifirmware/ap_types -I$MGC_HOME/shared/include firmware/thresholded_relu.cpp thresholded_relu_test.cpp; a.out; popd + diff --git a/example-prjs/thresholded_relu/vivado.py b/example-prjs/thresholded_relu/vivado.py new file mode 100644 index 0000000000..2665211b27 --- /dev/null +++ b/example-prjs/thresholded_relu/vivado.py @@ -0,0 +1,43 @@ + +import hls4ml +# import pprint +import yaml +import numpy as np + +print(hls4ml.__version__) + +with open('config.yml', 'r') as ymlfile: + config = yaml.safe_load(ymlfile) + +# try tweaking the reuse_factor on one layer to get different pipelining +# config['HLSConfig']['LayerName']['fc1']['ReuseFactor'] = 4 + +print('NETWORK') +print(config) + +config['OutputDir'] = 'my-Vivado-test' +config['Backend'] = 'Vivado' +config['IOType'] = 'io_stream' + +config['HLSConfig']['Model']['Strategy'] = 'Latency' +#config['HLSConfig']['Model']['Strategy'] = 'Resource' + +# default threshold is infinity +config['HLSConfig']['Model']['BramFactor'] = np.inf +# set to zero to force all weights onto (external function) interface +config['HLSConfig']['Model']['BramFactor'] = 0 + +print('CURRENT CONFIGURATION') +print('Backend='+config['Backend']) +print('IOType='+config['IOType']) +print('BramFactor={bf}'.format(bf=config['HLSConfig']['Model']['BramFactor'])) + +# pprint.pprint(config) + +#Convert it to a hls project +hls_model = hls4ml.converters.keras_to_hls(config) + +hls_model.build(vsynth=False) + +# URL for this info: https://fastmachinelearning.org/hls4ml/setup/QUICKSTART.html + From be140aa79b4ff0eb9bca3eb6fb585d6afaadd77f Mon Sep 17 00:00:00 2001 From: BLMartin99 Date: Wed, 5 Jul 2023 15:04:53 -0700 Subject: [PATCH 3/3] Created read me document for thresholded relu example --- example-prjs/thresholded_relu/README.md | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 example-prjs/thresholded_relu/README.md diff --git a/example-prjs/thresholded_relu/README.md b/example-prjs/thresholded_relu/README.md new file mode 100644 index 0000000000..3feb0eac44 --- /dev/null +++ b/example-prjs/thresholded_relu/README.md @@ -0,0 +1,6 @@ +This is small thresholded relu 1 layer example. To run it: +1. Run the run_catapult.sh script. +2. Replace the thresholded_relu_test.cpp in the my-Catapult-test with the thresholded_relu_test.cpp a level up (if you would like the testbench to be self-checking). +3. Move tb_input_features.dat and tb_output_predictions.dat to my-Catapult-test/tb_data (if you want two pre-computed examples). + +Note: You can create your own array and get the predictions by editing then running thresholded_relu.py.