Skip to content

New backend development framework #395

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 129 commits into from
Feb 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
129 commits
Select commit Hold shift + click to select a range
673f6f8
Backend Update
hamzajaved780 Jul 8, 2020
2738587
Backend Update
hamzajaved780 Jul 8, 2020
2e605b9
bug fixes in Quartus writer
hamzajaved780 Jul 10, 2020
f722f50
bug fixes in Quartus writer
hamzajaved780 Jul 10, 2020
d6e96f2
Update to precision declaration within config file
hamzajaved780 Jul 11, 2020
4ac1e43
Updated example configs, thanks to Andres.
hamzajaved780 Jul 11, 2020
e2f27ab
Updated hls4ml report
hamzajaved780 Jul 14, 2020
96d31ef
Added quartus synth to build
hamzajaved780 Jul 14, 2020
66dd843
Fixed dir change in build
hamzajaved780 Jul 14, 2020
ed2c040
Added report parsing capabilities to hls_model
hamzajaved780 Jul 15, 2020
ed8137e
Fixes to Quartus build #2
hamzajaved780 Jul 15, 2020
19acc66
Fixes to report output
hamzajaved780 Jul 16, 2020
ca3f45c
Fixes to report output #2
hamzajaved780 Jul 16, 2020
1c64872
Fixed activation data rounding for higher precisions
hamzajaved780 Jul 21, 2020
573e320
Added Compressed Implementation
hamzajaved780 Aug 6, 2020
0278627
Added Compressed Implementation
hamzajaved780 Aug 6, 2020
493245f
csim dll fix
hamzajaved780 Aug 14, 2020
e894df2
csim dll fix
hamzajaved780 Aug 14, 2020
bda2287
Cleanup
hamzajaved780 Dec 3, 2020
2ab877c
Update front end build and report function calling
jmitrevs Dec 17, 2020
9fc1497
change from slimit to calmjs.parse to remove warnings
jmitrevs Dec 18, 2020
59526d8
improve the JS parsing
jmitrevs Dec 19, 2020
378bea4
Merge pull request #3 from jmitrevs/quartus
hamzajaved780 Dec 31, 2020
d5003ba
Merge remote-tracking branch 'hamza/master' into quartus_new
vloncar Feb 28, 2021
3b00af6
Add Hamza's Quartus templates and writer
vloncar Mar 1, 2021
c5c0826
Enable Quartus backend (not ready yet)
vloncar Mar 2, 2021
34baf55
Move shared backend functions to a common class
vloncar Mar 13, 2021
a5fdfce
Update Quartus writer to support new backend design
vloncar Mar 13, 2021
8387480
Merge branch 'master' into quartus_new
vloncar Mar 16, 2021
2d3f545
Move compile and build to backend
vloncar Mar 18, 2021
75e91f1
Separate ap wrappers from ac types
vloncar Mar 19, 2021
a2e2a9e
Rename XilinxPart config to Device
vloncar Mar 19, 2021
3fba955
Move reports to separate file
vloncar Mar 21, 2021
0c27679
Add backend to config and utils
vloncar Mar 25, 2021
c92795f
Merge branch 'master' into quartus_new
vloncar Apr 3, 2021
7ccbd4c
Move backends to dedicated module
vloncar Apr 8, 2021
daad20c
Split optimizers into general and backend-specific
vloncar Apr 13, 2021
0356d5e
Don't check for resource strategy in BN fuse
vloncar Apr 13, 2021
d028f05
Move backend-specific stuff from the layers into the backend
vloncar Apr 14, 2021
0da1c2a
Quartus optimizer fixes
vloncar Apr 15, 2021
b48daf0
Move initial config creation to backends
vloncar Apr 15, 2021
dc2c6f8
Read backend-specific reports in hls4ml command
vloncar Apr 16, 2021
ef4cb15
Write YAML file in Quartus projects
vloncar Apr 16, 2021
f4e3ba4
Support building Quartus projects from hls4ml cmd
vloncar Apr 16, 2021
a3c8612
Quartus new (#37)
jmitrevs Apr 22, 2021
3934658
Move IOType to backend optimizers
vloncar May 1, 2021
4578dd5
Split types to a separate module
vloncar May 2, 2021
9ec1fd4
Create a prent PrecisionType
vloncar May 10, 2021
f8ade58
Introduce layer attributes for model validation
vloncar May 14, 2021
00140a6
Support attributes in activations
vloncar May 19, 2021
60932b3
Extra attribute in activation layer
vloncar May 19, 2021
dd6554d
Support attributes in Quartus backend
vloncar May 19, 2021
59c09a8
Some more attributes
vloncar May 24, 2021
03c1b59
Take bride from quartus, not vivado templates when using quartus back…
jmitrevs May 25, 2021
a029788
Bakcend-specific attributes and use of isinstance instead of __class_…
vloncar Jun 8, 2021
56ae82a
Split template registration from backend init
vloncar Jun 8, 2021
e68fe5d
Fix include of quant BN
vloncar Jun 8, 2021
460ec36
Allow class or str in make_node
vloncar Jun 8, 2021
0fdd7dd
Proper name of init_templates() function
vloncar Jun 8, 2021
53bd01f
Handle reuse_factor as an attribute
vloncar Jun 8, 2021
bcd599e
Move reuse factor to backend initializer
vloncar Jun 9, 2021
8cfcb6a
Use class_name property instead of __class__.__name__
vloncar Jun 10, 2021
cd4d468
New optimization pass class for layer optimizers
vloncar Jun 15, 2021
08b84e5
Initial support for flows (ordered opt passes)
vloncar Jun 21, 2021
1333a4d
Ensure backend optimizers have unique names
vloncar Jun 21, 2021
6944f8a
Move ap_types cpp gen to optimizer (for Vivado)
vloncar Jun 23, 2021
31eeee2
Fix setting closest reuse factor
vloncar Jun 23, 2021
09c93c5
Use enums for rounding and saturation modes
vloncar Jun 23, 2021
211494d
Use ac types for quartus backend
vloncar Jun 23, 2021
1e88c44
Remove ap_types wrapper from Quartus backend
vloncar Jun 23, 2021
1093764
Templates as optimizers (keep originals for now)
vloncar Aug 1, 2021
758d25f
Templates as optimizers for Quartus
vloncar Aug 1, 2021
f26ae9b
Support using structs as inputs/outputs in Quartus
vloncar Aug 3, 2021
004b715
Defend against applying variable changes multiple times
vloncar Aug 10, 2021
54171eb
Fix imports in a few optimizers
vloncar Aug 10, 2021
f447244
Consolidate optimizer and flow handling
vloncar Aug 24, 2021
8ab5a93
Keep track of applied flows and optimizers
vloncar Aug 24, 2021
6c15c51
Get rid of custom initializers
vloncar Aug 24, 2021
49c025e
Split optimizers into more granular flows
vloncar Aug 30, 2021
8a870d9
Move include lists into function templates
vloncar Aug 31, 2021
537c38d
Move resource strategy transposes to optimizer
vloncar Sep 1, 2021
54b84e0
Introduce backend-specific types and variables
vloncar Sep 4, 2021
0b551bd
Consolidate transformation optimizers
vloncar Sep 4, 2021
f2e72c7
Move variable C++ generation to classes
vloncar Sep 4, 2021
d97af0f
Merge branch 'master' into quartus_new
vloncar Sep 7, 2021
abfe1ce
Fixes after merging the accelerator backend
vloncar Sep 10, 2021
436bf1d
Follow up with XilinxPart -> Part changes
vloncar Sep 10, 2021
6e45ec8
Big cleanup of old unused functionality
vloncar Sep 10, 2021
fa0700a
swap round and saturation in precision, make precision methods static
jmitrevs Sep 13, 2021
b5bfe43
change from staticmethod to classmethod
jmitrevs Oct 6, 2021
3ea0d48
propagate reuse factor for Quartus, allow rf=1 for Resouce in all cases
jmitrevs Oct 5, 2021
51a1a8b
Add Quartus package dependancies to setup.py
vloncar Oct 8, 2021
749ee9e
Fix ParametrizedActivation function call template
vloncar Oct 13, 2021
b26dd74
Prevent clash between layer's output name and attributes
vloncar Oct 13, 2021
a55b947
Merge branch 'master' into quartus_new
vloncar Oct 18, 2021
8bb5e06
Fix GlobalPooling1D after incorrect merge
vloncar Oct 19, 2021
30fe63e
Properly convert all variable and precision types
vloncar Oct 19, 2021
35bf771
QKeras fixes
vloncar Oct 19, 2021
7c5b9c6
Test changes:
vloncar Oct 19, 2021
dcfd97b
Cleanup Backend class functions
vloncar Oct 26, 2021
d6350a2
Move writer to backend and write model as an opt pass
vloncar Oct 26, 2021
8bddce0
Improve type conversion consistency
vloncar Oct 28, 2021
24c3c80
Handle weights in BRAM via optimizer pass
vloncar Oct 29, 2021
730a0c6
Fix precision handling routines
vloncar Nov 4, 2021
ea7e1d0
Switch GarNet to new API
vloncar Nov 4, 2021
d2ea734
Merge branch 'master' into quartus_new
vloncar Nov 4, 2021
c91bca4
Remove extra backend argument from hls4ml script
vloncar Nov 4, 2021
37c989b
Fix config creation in the tests
vloncar Nov 5, 2021
70d35b0
Merge branch 'master' into quartus_new
vloncar Nov 5, 2021
2456330
Make sure example models are loaded in the CI
vloncar Nov 22, 2021
258c0a0
Don't transpose weights in QKeras optimizer
vloncar Nov 22, 2021
0de5ad4
Use mixins to override types and C++ definitions
vloncar Nov 22, 2021
3be6542
Merge branch 'master' into quartus_new
vloncar Nov 22, 2021
9d18b60
Register remove_final_reshape optimizer
vloncar Nov 22, 2021
c19cb2e
Don't use class name to match
vloncar Nov 22, 2021
86324bc
Prevent running into an endless loop in pointwise
vloncar Nov 22, 2021
82a720c
Use new style of output directories in tests
vloncar Nov 22, 2021
6896a9c
Handle conversion of InplaceVariable
vloncar Nov 23, 2021
b3819ef
Fix GarNet converter
vloncar Nov 23, 2021
f663263
Make sure the accum type is set to a named type
vloncar Nov 23, 2021
23920c3
Register writer_flow in VivadoAccelerator backend
vloncar Nov 23, 2021
7d03025
Don't let InplaceVariable override type definition
vloncar Nov 25, 2021
3934cf7
allocate entry in array before use
jmitrevs Dec 7, 2021
3e5a9e7
Merge branch 'master' into quartus_new
vloncar Jan 12, 2022
1844b9a
Check QKeras availability before registering flows
vloncar Jan 12, 2022
4c5aa3c
Fix parametrized activations in Quartus backend
vloncar Jan 27, 2022
05140ce
Add Quartus tests
vloncar Jan 27, 2022
7644b8c
Remove unused Quartus backend functions/templates
vloncar Jan 27, 2022
61708fa
Drop the use of "HLS" in class and file names
vloncar Jan 27, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,5 @@ vivado_prj
my-hls-test
*.tar.gz
docs/_build
docs/autodoc/*
docs/autodoc/*
hls4mlprj_*
4 changes: 2 additions & 2 deletions docs/api/configuration.rst
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ It looks like this:
OutputPredictions: keras/KERAS_3layer_predictions.dat
OutputDir: my-hls-test
ProjectName: myproject
XilinxPart: xcku115-flvb2104-2-i
Device: xcku115-flvb2104-2-i
ClockPeriod: 5

IOType: io_parallel # options: io_serial/io_parallel
Expand All @@ -88,7 +88,7 @@ There are a number of configuration options that you have. Let's go through the
* **InputData/OutputPredictions**\ : path to your input/predictions of the model. If none is supplied, then hls4ml will create aritificial data for simulation. The data used above in the example can be found `here <https://cernbox.cern.ch/index.php/s/2LTJVVwCYFfkg59>`__. We also support ``npy`` data files. We welcome suggestions on more input data types to support.
* **OutputDir**\ : the output directory where you want your HLS project to appear
* **ProjectName**\ : the name of the HLS project IP that is produced
* **XilinxPart**\ : the particular FPGA part number that you are considering, here it's a Xilinx Virtex-7 FPGA
* **Device**\ : the particular FPGA part number that you are considering, here it's a Xilinx Virtex-7 FPGA
* **ClockPeriod**\ : the clock period, in ns, at which your algorithm runs
Then you have some optimization parameters for how your algorithm runs:
* **IOType**\ : your options are ``io_parallel`` or ``io_serial`` where this really defines if you are pipelining your algorithm or not
Expand Down
6 changes: 3 additions & 3 deletions docs/api/profiling.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ Using a low precision can help reduce the FPGA resource usage of a model, but ma

Profiling uses some extra dependencies, to install these, run ``pip install hls4ml[profiling]``. The profiling tools are provided as a ``Python`` module which you can use.

Three types of objects can be provided: **a Keras model object**\ , **test data**\ , and an **HLSModel object**.
Three types of objects can be provided: **a Keras model object**\ , **test data**\ , and an **ModelGraph object**.
You will need to initialise these objects by using a trained model, loading a model from a file, and loading your data. The Keras model and data each need to be in the format that would normally allow you to run, e.g. ``model.predict(X)``.

.. code-block:: python
Expand Down Expand Up @@ -47,11 +47,11 @@ When different combinations of the input objects are given, different plots will

1) Only Keras model: only the weights profile plot will be produced, the activation profile will be ``None``. No grey boxes representing the data types will be shown.

2) Only HLSModel (or HLSModel and Keras model): only the weights profile plot will be produced, with grey boxes indicating the data types from the HLSModel.
2) Only ModelGraph (or ModelGraph and Keras model): only the weights profile plot will be produced, with grey boxes indicating the data types from the ModelGraph.

3) Keras model and data (\ ``X``\ ): both the weights profile and activation profile will be produced. No grey boxes representing the data types will be shown.

4) Keras model, HLSModel, and data: both weights and activation profiles are produced, with grey boxes indicating the data types from the HLSModel.
4) Keras model, ModelGraph, and data: both weights and activation profiles are produced, with grey boxes indicating the data types from the ModelGraph.

Each box shows the median and quartiles of the distribution. The grey shaded boxes show the range which can be represented with the ``hls4ml`` config file used.

Expand Down
12 changes: 12 additions & 0 deletions hls4ml/backends/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from __future__ import absolute_import

from hls4ml.backends.backend import Backend, register_backend, get_backend, get_available_backends
from hls4ml.backends.fpga.fpga_backend import FPGABackend
from hls4ml.backends.vivado.vivado_backend import VivadoBackend
from hls4ml.backends.vivado_accelerator.vivado_accelerator_backend import VivadoAcceleratorBackend
from hls4ml.backends.vivado_accelerator.vivado_accelerator_config import VivadoAcceleratorConfig
from hls4ml.backends.quartus.quartus_backend import QuartusBackend

register_backend('Vivado', VivadoBackend)
register_backend('VivadoAccelerator', VivadoAcceleratorBackend)
register_backend('Quartus', QuartusBackend)
78 changes: 78 additions & 0 deletions hls4ml/backends/backend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import inspect
import os

from hls4ml.backends.template import Template
from hls4ml.model.flow import get_backend_flows
from hls4ml.model.optimizer import LayerOptimizerPass, register_pass, extract_optimizers_from_path, extract_optimizers_from_object, get_backend_passes, get_optimizer


class Backend(object):
def __init__(self, name):
self.name = name
self._init_optimizers()

def _init_optimizers(self):
optimizers = {}
optimizers.update(self._init_class_optimizers())
optimizers.update(self._init_file_optimizers())
for opt_name, opt in optimizers.items():
self.register_pass(opt_name, opt)

def _init_class_optimizers(self):
class_optimizers = extract_optimizers_from_object(self)
return class_optimizers

def _init_file_optimizers(self):
opt_path = os.path.dirname(inspect.getfile(self.__class__)) + '/passes'
module_path = self.__module__[:self.__module__.rfind('.')] + '.passes'
file_optimizers = extract_optimizers_from_path(opt_path, module_path, self)
return file_optimizers

def _get_layer_initializers(self):
all_initializers = { name:get_optimizer(name) for name in get_backend_passes(self.name) if isinstance(get_optimizer(name), LayerOptimizerPass) }

# Sort through the initializers based on the base class (e.g., to apply 'Layer' optimizers before 'Dense')
sorted_initializers = sorted(all_initializers.items(), key=lambda x: len(x[1].layer_class.mro()))

# Return only the names of the initializers
return [opt[0] for opt in sorted_initializers]

def _get_layer_templates(self):
return [name for name in get_backend_passes(self.name) if isinstance(get_optimizer(name), Template)]

def create_initial_config(self, **kwargs):
raise NotImplementedError

def create_layer_class(self, layer_class):
raise NotImplementedError

def get_available_flows(self):
return get_backend_flows(self.name)

def get_default_flow(self):
raise NotImplementedError

def register_source(self, file_name, source, destination_dir='nnet_utils'):
raise NotImplementedError

def register_pass(self, name, opt_cls):
register_pass(name, opt_cls, backend=self.name)

def register_template(self, template_cls):
template = template_cls()
register_pass(template.get_name(), template, backend=self.name)


backend_map = {}

def register_backend(name, backend_cls):
if name.lower() in backend_map:
raise Exception('Backend {} already registered'.format(name))

backend_map[name.lower()] = backend_cls()

def get_backend(name):
return backend_map[name.lower()]

def get_available_backends():
return list(backend_map.keys())
Empty file.
Loading