Package: elasticai.creator
ElasticAI.creatorDesign, train and compile neural networks optimized specifically for FPGAs.
Obtaining a final model is typically a three stage process.design and train it using the layers provided in theelasticai.creator.nnpackage.translate the model to a target representation, e.g. VHDLcompile the intermediate representation with a third party tool, e.g. Xilinx Vivado (TM)This version currently only supports parts of VHDL as target representations.The project is part of the elastic ai ecosystem developed by the Embedded Systems Department of the University Duisburg-Essen. For more details checkout the slides atresearchgate.Table of contentsUsers GuideInstallMinimal ExampleGeneral LimitationsStructure of the ProjectDevelopers GuideInstall Dev DependenciesConventional Commit RulesAdding new translation targetsSyntax CheckingTestsTest Style GuidelinesFile IODirectory structure and file namesUnit testsIntegration testsSystem testsAdding new functionalities and tests requiredUpdating testsUsers GuideInstallYou can install the ElasticAI.creator as a dependency using pip:python3-mpipinstallelasticai-creatorMinimal ExampleThe following example shows how to use the ElasticAI.creator to define and translate a machine learning model to VHDL. It will save the generated VHDL code to a directory calledbuild_dir.fromelasticai.creator.nnimportSequentialfromelasticai.creator.nn.fixed_pointimportLinear,HardSigmoidfromelasticai.creator.file_generation.on_disk_pathimportOnDiskPathdefmain()->None:# Define a modelmodel=Sequential(Linear(in_features=10,out_features=2,bias=True,total_bits=16,frac_bits=8),HardSigmoid(total_bits=16,frac_bits=8),)# Train the modelrun_training(model)# Save the VHDL code of the trained modeldestination=OnDiskPath("build_dir")design=model.create_design("my_model")design.save_to(destination)if__name__=="__main__":main()General LimitationsBy now we only support Sequential models for our translations.Structure of the ProjectThe structure of the project is as follows.
Thecreatorfolder includes all main concepts of our project, especially the qtorch implementation which is our implementation of quantized PyTorch layer.
It also includes the supported target representations, like the subfoldernnis for the translation to vhdl.
Additionally, we have unit and integration tests in thetestsfolder.Developers GuideInstall Dev Dependenciespoetryrecommended:pre-commitcommitlintto help following ourconventional commitguidelines
poetry can be installed in the following way:pipinstallpoetry
poetryinstall
poetryshell
pre-commitinstall
npminstall--save-dev@commitlint/{config-conventional,cli}# Optional:sudoaptinstallghdlProject StructureAll packages and modules fall into one of five main categories and can thus be found in the corresponding packagenn: trainable modules that can be translated to vhdl to build a hardware acceleratorbase_modules: (non-public) shared functionality and data structures, that we use to create our neural network software modulesvhdl: (non-public) shared code that we use to represent and generate vhdl codefile_generation: provide a very restricted api to generate files or file subtrees under a given root node and defines a basic template api and datastructure, compatible withfile_generationGlossaryfxp/Fxp: prefix for fixed pointflp/Flp: prefix for floating pointx: parameter input tensor for layer with single input tensory: output value/tensor for layer with single output_bits: suffix to denote the number of bits, e.g.total_bits,frac_bits, in python context_width: suffix to denote the number of bits used for a data bus in vhdl, e.g.total_width,frac_widthMathOperations/operations: definition of how to perform mathematical operations (quantization, addition, matrix multiplication, ...)Conventional Commit RulesWe use conventional commits (seehere). The following commit types are allowed. The message scope is optional.Commit TypesfeatfixdocsstylerefactorrevertchorewipperfTestsOur implementation is tested with unit and integration.
You can run one explicit test with the following statement:python3-mpytest./tests/path/to/specific/test.pyIf you want to run all tests, give the path to the tests:python3-mpytest./testsIf you want to add more tests please refer to the Test Guidelines in the following.Test Style GuidelinesFile IOIn general try to avoid interaction with the filesystem. In most cases instead of writing to or reading from a file you can use a StringIO object or a StringReader.
If you absolutely have to create files, be sure to use pythonstempfilemodule and cleanup after the tests.
In most cases you can use theInMemoryPathclass to write files to the RAM instead of writing them to the hard disc (especially for testing the generated VHDL files of a certain layer).Directory structure and file namesFiles containing tests for a python module should be located in a test directory for the sake of separation of concerns.
Each file in the test directory should contain tests for one and only one class/function defined in the module.
Files containing tests should be named according to the rubrictest_<class_name>.py.
Next, if needed for more specific tests define a class. Then subclass it.
It avoids introducing the category of bugs associated with copying and pasting code for reuse.
This class should be named similarly to the file name.
There's a category of bugs that appear if  the initialization parameters defined at the top of the test file are directly used: some tests require the initialization parameters to be changed slightly.
Its possible to define a parameter and have it change in memory as a result of a test.
Subsequent tests will therefore throw errors.
Each class contains methods that implement a test.
These methods are named according to the rubrictest_<name>_<condition>Unit testsIn those tests each functionality of each function in the module is tested, it is the entry point  when adding new functions.
It assures that the function behaves correctly independently of others.
Each test has to be fast, so use of heavier libraries is discouraged.
The input used is the minimal one needed to obtain a reproducible output.
Dependencies should be replaced with mocks as needed.Integration TestsHere the functions' behaviour with other modules is tested.
In this repository each integration function is in the correspondent folder.
Then the integration with a single class of the target, or the minimum amount of classes for a functionality, is tested in each separated file.System testsThose tests will use every component of the system, comprising multiple classes.
Those tests include expected use cases and unexpected or stress tests.Adding new functionalities and tests requiredWhen adding new functions to an existing module, add unit tests in the correspondent file in the same order of the module, if a new module is created a new file should be created.
When a bug is solved created the respective regression test to ensure that it will not return.
Proceed similarly with integration tests.
Creating a new file if a functionality completely different from the others is created e.g. support for a new layer.
System tests are added if support for a new library is added.Updating testsIf new functionalities are changed or removed the tests are expected to reflect that, generally the ordering is unit tests -> integration tests-> system tests.
Also, unit tests that change the dependencies should be checked, since this system is fairly small the internal dependencies are not always mocked.references:https://jrsmith3.github.io/python-testing-style-guidelines.html