From c5ab726a22ce1f0885a7e1f3e6ebf0500d73d478 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Fri, 21 Aug 2026 15:04:55 -0500 Subject: [PATCH 1/9] Use AI to migrate oneAPI to Altera --- README.md | 2 +- docs/api/configuration.rst | 2 +- docs/backend/{oneapi.rst => altera.rst} | 12 +- docs/backend/quartus.rst | 6 +- docs/index.rst | 2 +- docs/intro/setup.rst | 4 +- docs/intro/status.rst | 6 +- docs/ir/attributes.rst | 204 +++++++++--------- docs/ir/ir.rst | 2 +- hls4ml/backends/__init__.py | 5 +- .../backends/{oneapi => altera}/__init__.py | 0 .../altera_backend.py} | 68 +++--- .../altera_template.py} | 6 +- .../altera_types.py} | 62 +++--- .../{oneapi => altera}/passes/__init__.py | 0 .../{oneapi => altera}/passes/bn_quant.py | 2 +- .../passes/clone_templates.py | 4 +- .../passes/convolution_templates.py | 14 +- .../passes/convolution_winograd.py | 0 .../passes/core_templates.py | 6 +- .../{oneapi => altera}/passes/einsum.py | 2 +- .../{oneapi => altera}/passes/einsum_dense.py | 2 +- .../passes/embedding_templates.py | 4 +- .../passes/feature_check.py | 2 +- .../passes/merge_templates.py | 4 +- .../{oneapi => altera}/passes/pointwise.py | 14 +- .../passes/pooling_templates.py | 6 +- .../passes/quantization_templates.py | 8 +- .../passes/recurrent_templates.py | 6 +- .../passes/reshaping_templates.py | 6 +- .../passes/resource_strategy.py | 2 +- .../passes/transform_types.py | 32 +-- hls4ml/backends/fpga/fpga_types.py | 4 +- .../backends/fpga/passes/hgq_proxy_model.py | 12 +- .../vivado/passes/distributed_arithmetic.py | 2 +- hls4ml/report/__init__.py | 8 +- .../{oneapi_report.py => altera_report.py} | 12 +- .../{oneapi => altera}/CMakeLists.txt | 0 .../{oneapi => altera}/exception_handler.hpp | 0 .../{oneapi => altera}/firmware/defines.h | 0 .../{oneapi => altera}/firmware/myproject.cpp | 0 .../{oneapi => altera}/firmware/myproject.h | 0 .../firmware/nnet_utils/nnet_activation.h | 0 .../nnet_utils/nnet_activation_stream.h | 0 .../firmware/nnet_utils/nnet_batchnorm.h | 0 .../nnet_utils/nnet_batchnorm_stream.h | 0 .../firmware/nnet_utils/nnet_code_gen.h | 0 .../firmware/nnet_utils/nnet_common.h | 0 .../firmware/nnet_utils/nnet_conv1d.h | 0 .../nnet_utils/nnet_conv1d_resource.h | 0 .../firmware/nnet_utils/nnet_conv1d_stream.h | 0 .../firmware/nnet_utils/nnet_conv2d.h | 0 .../nnet_utils/nnet_conv2d_resource.h | 0 .../firmware/nnet_utils/nnet_conv2d_stream.h | 0 .../firmware/nnet_utils/nnet_dense.h | 0 .../firmware/nnet_utils/nnet_dense_stream.h | 0 .../firmware/nnet_utils/nnet_depthconv1d.h | 0 .../nnet_utils/nnet_depthconv1d_resource.h | 0 .../firmware/nnet_utils/nnet_depthconv2d.h | 0 .../nnet_utils/nnet_depthconv2d_resource.h | 0 .../firmware/nnet_utils/nnet_einsum.h | 0 .../firmware/nnet_utils/nnet_einsum_dense.h | 0 .../firmware/nnet_utils/nnet_embed.h | 0 .../firmware/nnet_utils/nnet_embed_stream.h | 0 .../firmware/nnet_utils/nnet_helpers.h | 0 .../firmware/nnet_utils/nnet_merge.h | 0 .../firmware/nnet_utils/nnet_merge_stream.h | 0 .../firmware/nnet_utils/nnet_mult.h | 0 .../firmware/nnet_utils/nnet_padding.h | 0 .../firmware/nnet_utils/nnet_padding_stream.h | 0 .../firmware/nnet_utils/nnet_pooling.h | 0 .../firmware/nnet_utils/nnet_pooling_stream.h | 0 .../firmware/nnet_utils/nnet_printf.h | 0 .../firmware/nnet_utils/nnet_recurrent.h | 0 .../nnet_utils/nnet_recurrent_activation.h | 0 .../nnet_utils/nnet_recurrent_stream.h | 0 .../firmware/nnet_utils/nnet_resize.h | 0 .../firmware/nnet_utils/nnet_resize_stream.h | 0 .../firmware/nnet_utils/nnet_stream.h | 0 .../firmware/nnet_utils/nnet_transpose.h | 0 .../nnet_utils/nnet_transpose_stream.h | 0 .../firmware/nnet_utils/nnet_types.h | 0 .../{oneapi => altera}/firmware/parameters.h | 0 .../{oneapi => altera}/myproject_bridge.cpp | 0 .../{oneapi => altera}/myproject_test.cpp | 0 hls4ml/writer/__init__.py | 4 +- .../{oneapi_writer.py => altera_writer.py} | 24 +-- ...t_activations_io_parallel-Altera-elu.json} | 0 ...ations_io_parallel-Altera-leaky_relu.json} | 0 ...activations_io_parallel-Altera-prelu.json} | 0 ..._activations_io_parallel-Altera-relu.json} | 0 ...tivations_io_parallel-Altera-sigmoid.json} | 0 ...est_activations_io_stream-Altera-elu.json} | 0 ...ivations_io_stream-Altera-leaky_relu.json} | 0 ...t_activations_io_stream-Altera-prelu.json} | 0 ...st_activations_io_stream-Altera-relu.json} | 0 ...activations_io_stream-Altera-sigmoid.json} | 0 ...l-Altera-Resource-same-channels_last.json} | 0 ...as_api_test_dense_io_parallel-Altera.json} | 0 ...eras_api_test_dense_io_stream-Altera.json} | 0 ...-channels_last-same-AveragePooling1D.json} | 0 ...-channels_last-same-AveragePooling2D.json} | 0 ...tera-channels_last-same-MaxPooling1D.json} | 0 ...tera-channels_last-same-MaxPooling2D.json} | 0 ...channels_last-valid-AveragePooling1D.json} | 0 ...channels_last-valid-AveragePooling2D.json} | 0 ...era-channels_last-valid-MaxPooling1D.json} | 0 ...era-channels_last-valid-MaxPooling2D.json} | 0 test/pytest/ci-template.yml | 2 +- test/pytest/conftest.py | 4 +- test/pytest/synthesis_helpers.py | 8 +- test/pytest/test_activations.py | 2 +- test/pytest/test_batchnorm.py | 2 +- test/pytest/test_bit_exact_grouped_conv.py | 14 +- test/pytest/test_bit_exact_zeropadding.py | 8 +- test/pytest/test_conv1d.py | 8 +- test/pytest/test_embed.py | 8 +- test/pytest/test_globalpooling.py | 4 +- test/pytest/test_keras_api.py | 10 +- test/pytest/test_keras_v3_api.py | 12 +- test/pytest/test_merge.py | 10 +- test/pytest/test_multi_dense.py | 2 +- test/pytest/test_multiout_network.py | 2 +- test/pytest/test_pointwiseconv.py | 12 +- test/pytest/test_pooling.py | 8 +- test/pytest/test_pytorch_api.py | 28 +-- test/pytest/test_qeinsum.py | 4 +- test/pytest/test_qkeras.py | 22 +- test/pytest/test_qkerasV3.py | 26 +-- test/pytest/test_qonnx.py | 2 +- test/pytest/test_recurrent_pytorch.py | 14 +- test/pytest/test_repack_stream.py | 6 +- test/pytest/test_report.py | 18 +- .../{oneAPI => Altera}/loop_attr.ndjson | 0 .../{oneAPI => Altera}/quartus.ndjson | 0 .../{oneAPI => Altera}/summary.ndjson | 0 test/pytest/test_reshape.py | 2 +- test/pytest/test_rnn.py | 16 +- test/pytest/test_serialization.py | 6 +- test/pytest/test_stream_clone.py | 4 +- test/pytest/test_transpose_concat.py | 10 +- test/pytest/test_upsampling.py | 2 +- test/pytest/test_zeropadding.py | 2 +- 143 files changed, 420 insertions(+), 419 deletions(-) rename docs/backend/{oneapi.rst => altera.rst} (82%) rename hls4ml/backends/{oneapi => altera}/__init__.py (100%) rename hls4ml/backends/{oneapi/oneapi_backend.py => altera/altera_backend.py} (92%) rename hls4ml/backends/{oneapi/oneapi_template.py => altera/altera_template.py} (89%) rename hls4ml/backends/{oneapi/oneapi_types.py => altera/altera_types.py} (81%) rename hls4ml/backends/{oneapi => altera}/passes/__init__.py (100%) rename hls4ml/backends/{oneapi => altera}/passes/bn_quant.py (99%) rename hls4ml/backends/{oneapi => altera}/passes/clone_templates.py (85%) rename hls4ml/backends/{oneapi => altera}/passes/convolution_templates.py (97%) rename hls4ml/backends/{oneapi => altera}/passes/convolution_winograd.py (100%) rename hls4ml/backends/{oneapi => altera}/passes/core_templates.py (98%) rename hls4ml/backends/{oneapi => altera}/passes/einsum.py (98%) rename hls4ml/backends/{oneapi => altera}/passes/einsum_dense.py (99%) rename hls4ml/backends/{oneapi => altera}/passes/embedding_templates.py (88%) rename hls4ml/backends/{oneapi => altera}/passes/feature_check.py (92%) rename hls4ml/backends/{oneapi => altera}/passes/merge_templates.py (97%) rename hls4ml/backends/{oneapi => altera}/passes/pointwise.py (97%) rename hls4ml/backends/{oneapi => altera}/passes/pooling_templates.py (96%) rename hls4ml/backends/{oneapi => altera}/passes/quantization_templates.py (91%) rename hls4ml/backends/{oneapi => altera}/passes/recurrent_templates.py (99%) rename hls4ml/backends/{oneapi => altera}/passes/reshaping_templates.py (98%) rename hls4ml/backends/{oneapi => altera}/passes/resource_strategy.py (98%) rename hls4ml/backends/{oneapi => altera}/passes/transform_types.py (74%) rename hls4ml/report/{oneapi_report.py => altera_report.py} (97%) rename hls4ml/templates/{oneapi => altera}/CMakeLists.txt (100%) rename hls4ml/templates/{oneapi => altera}/exception_handler.hpp (100%) rename hls4ml/templates/{oneapi => altera}/firmware/defines.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/myproject.cpp (100%) rename hls4ml/templates/{oneapi => altera}/firmware/myproject.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_activation.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_activation_stream.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_batchnorm.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_batchnorm_stream.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_code_gen.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_common.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_conv1d.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_conv1d_resource.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_conv1d_stream.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_conv2d.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_conv2d_resource.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_conv2d_stream.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_dense.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_dense_stream.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_depthconv1d.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_depthconv1d_resource.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_depthconv2d.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_depthconv2d_resource.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_einsum.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_einsum_dense.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_embed.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_embed_stream.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_helpers.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_merge.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_merge_stream.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_mult.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_padding.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_padding_stream.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_pooling.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_pooling_stream.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_printf.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_recurrent.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_recurrent_activation.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_recurrent_stream.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_resize.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_resize_stream.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_stream.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_transpose.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_transpose_stream.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/nnet_utils/nnet_types.h (100%) rename hls4ml/templates/{oneapi => altera}/firmware/parameters.h (100%) rename hls4ml/templates/{oneapi => altera}/myproject_bridge.cpp (100%) rename hls4ml/templates/{oneapi => altera}/myproject_test.cpp (100%) rename hls4ml/writer/{oneapi_writer.py => altera_writer.py} (98%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_activations_io_parallel-oneAPI-elu.json => Altera/2025.0.1/test_keras_api_test_activations_io_parallel-Altera-elu.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_activations_io_parallel-oneAPI-leaky_relu.json => Altera/2025.0.1/test_keras_api_test_activations_io_parallel-Altera-leaky_relu.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_activations_io_parallel-oneAPI-prelu.json => Altera/2025.0.1/test_keras_api_test_activations_io_parallel-Altera-prelu.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_activations_io_parallel-oneAPI-relu.json => Altera/2025.0.1/test_keras_api_test_activations_io_parallel-Altera-relu.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_activations_io_parallel-oneAPI-sigmoid.json => Altera/2025.0.1/test_keras_api_test_activations_io_parallel-Altera-sigmoid.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_activations_io_stream-oneAPI-elu.json => Altera/2025.0.1/test_keras_api_test_activations_io_stream-Altera-elu.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_activations_io_stream-oneAPI-leaky_relu.json => Altera/2025.0.1/test_keras_api_test_activations_io_stream-Altera-leaky_relu.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_activations_io_stream-oneAPI-prelu.json => Altera/2025.0.1/test_keras_api_test_activations_io_stream-Altera-prelu.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_activations_io_stream-oneAPI-relu.json => Altera/2025.0.1/test_keras_api_test_activations_io_stream-Altera-relu.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_activations_io_stream-oneAPI-sigmoid.json => Altera/2025.0.1/test_keras_api_test_activations_io_stream-Altera-sigmoid.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_conv2d_io_parallel-oneAPI-Resource-same-channels_last.json => Altera/2025.0.1/test_keras_api_test_conv2d_io_parallel-Altera-Resource-same-channels_last.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_dense_io_parallel-oneAPI.json => Altera/2025.0.1/test_keras_api_test_dense_io_parallel-Altera.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_dense_io_stream-oneAPI.json => Altera/2025.0.1/test_keras_api_test_dense_io_stream-Altera.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-same-AveragePooling1D.json => Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-same-AveragePooling1D.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-same-AveragePooling2D.json => Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-same-AveragePooling2D.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-same-MaxPooling1D.json => Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-same-MaxPooling1D.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-same-MaxPooling2D.json => Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-same-MaxPooling2D.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-valid-AveragePooling1D.json => Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-valid-AveragePooling1D.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-valid-AveragePooling2D.json => Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-valid-AveragePooling2D.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-valid-MaxPooling1D.json => Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-valid-MaxPooling1D.json} (100%) rename test/pytest/baselines/{oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-valid-MaxPooling2D.json => Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-valid-MaxPooling2D.json} (100%) rename test/pytest/test_report/{oneAPI => Altera}/loop_attr.ndjson (100%) rename test/pytest/test_report/{oneAPI => Altera}/quartus.ndjson (100%) rename test/pytest/test_report/{oneAPI => Altera}/summary.ndjson (100%) diff --git a/README.md b/README.md index fc1da5e51d..dde69c39ba 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ hls4ml.utils.fetch_example_list() ``` ### Building a project. -We will build the project using Xilinx Vivado HLS, which can be downloaded and installed from [here](https://www.xilinx.com/products/design-tools/vivado/integration/esl-design.html). Alongside Vivado HLS, hls4ml also supports Vitis HLS, Intel HLS, Catapult HLS and has some experimental support dor Intel oneAPI. The target back-end can be changed using the argument backend when building the model. +We will build the project using Xilinx Vivado HLS, which can be downloaded and installed from [here](https://www.xilinx.com/products/design-tools/vivado/integration/esl-design.html). Alongside Vivado HLS, hls4ml also supports Vitis HLS, Intel HLS, Catapult HLS and has experimental support for the Altera backend. The target back-end can be changed using the argument backend when building the model. ```Python # Use Vivado HLS to synthesize the model diff --git a/docs/api/configuration.rst b/docs/api/configuration.rst index ccd6cf53cf..85f4f8c2aa 100644 --- a/docs/api/configuration.rst +++ b/docs/api/configuration.rst @@ -54,7 +54,7 @@ for Keras models: model, granularity='name', default_precision='fixed<16,6>', - backend='oneAPI') + backend='Altera') or for PyTorch models: diff --git a/docs/backend/oneapi.rst b/docs/backend/altera.rst similarity index 82% rename from docs/backend/oneapi.rst rename to docs/backend/altera.rst index 585bfc27cb..76f9f6e890 100644 --- a/docs/backend/oneapi.rst +++ b/docs/backend/altera.rst @@ -1,12 +1,12 @@ ====== -oneAPI +Altera ====== -The **oneAPI** backend of hls4ml is designed for deploying NNs on Intel/Altera FPGAs. It will eventually +The **Altera** backend of hls4ml is designed for deploying NNs on Intel/Altera FPGAs. It will eventually replace the **Quartus** backend, which targeted Intel HLS. (Quartus continues to be used with IP produced by the -**oneAPI** backend.) This section discusses details of the **oneAPI** backend. +**Altera** backend.) This section discusses details of the **Altera** backend. -The **oneAPI** code uses SYCL kernels to implement the logic that is deployed on FPGAs. It naturally leads to the +The **Altera** backend uses SYCL kernels to implement the logic that is deployed on FPGAs. It naturally leads to the accelerator style of programming. In the SYCL HLS (IP Component) flow, which is currently the only flow supported, the kernel becomes the IP, and the "host code" becomes the testbench. An accelerator flow, with easier deployment on PCIe accelerator boards, is planned to be added in the future. @@ -18,7 +18,7 @@ produces the library used for calling the ``predict`` function from hls4ml. The in hls4ml interact with the cmake system, so one does not need to manually use the build system, but it there if desired. -The **oneAPI** backend, like the **Quartus** backend, only implements the ``Resource`` strategy for the layers. There +The **Altera** backend, like the **Quartus** backend, only implements the ``Resource`` strategy for the layers. There is no ``Latency`` implementation of any of the layers. Note: currently tracing and external weights (i.e. setting BramFactor) are not supported. @@ -27,7 +27,7 @@ io_parallel and io_stream ========================= As mentioned in the :ref:`I/O Types` section, ``io_parallel`` is for small models, while ``io_stream`` is for -larger models. In ``oneAPI``, there is an additional difference: ``io_stream`` implements each layer on its +larger models. In ``Altera``, there is an additional difference: ``io_stream`` implements each layer on its own ``task_sequence``. Thus, the layers run in parallel, with pipes connecting the inputs and outputs. This is similar in style to the `dataflow` implementation on Vitis HLS, but more explicit. It is also a change relative to the Intel HLS-based ``Quartus`` backend. On the other hand, ``io_parallel`` always uses a single task, diff --git a/docs/backend/quartus.rst b/docs/backend/quartus.rst index 8cde5f97b2..56ea1eb557 100644 --- a/docs/backend/quartus.rst +++ b/docs/backend/quartus.rst @@ -3,10 +3,10 @@ Quartus ======= .. warning:: - The **Quartus** backend is deprecated and will be removed in a future version. Users should migrate to the **oneAPI** backend. + The **Quartus** backend is deprecated and will be removed in a future version. Users should migrate to the **Altera** backend. -The **Quartus** backend of hls4ml is designed for deploying NNs on Intel/Altera FPGAs. It uses the discontinued Intel HLS compiler. The **oneAPI** backend should be preferred for new projects. -The **oneAPI** backend contains the migrated the HLS code from this backend, with significantly better io_stream support, though the **oneAPI** backend does not yet support profiling, tracing, +The **Quartus** backend of hls4ml is designed for deploying NNs on Intel/Altera FPGAs. It uses the discontinued Intel HLS compiler. The **Altera** backend should be preferred for new projects. +The **Altera** backend contains the migrated the HLS code from this backend, with significantly better io_stream support, though the **Altera** backend does not yet support profiling, tracing, or the BramFactor option supported by the **Quartus** backend. Nevertheless, little or no further development is expected for this backend. The **Quartus** backend only implements the ``Resource`` strategy for the layers. There is no ``Latency`` implementation of any of the layers. diff --git a/docs/index.rst b/docs/index.rst index b0d1480bcd..435ed708ae 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -35,7 +35,7 @@ backend/vitis backend/accelerator - backend/oneapi + backend/altera backend/catapult backend/quartus backend/sr diff --git a/docs/intro/setup.rst b/docs/intro/setup.rst index 15d95401bc..8f8dad03bc 100644 --- a/docs/intro/setup.rst +++ b/docs/intro/setup.rst @@ -60,7 +60,7 @@ The following Python packages are all optional and are only required if you inte * `Brevitas `_: Based on PyTorch. See `frontend/pytorch <../frontend/pytorch.html>`_ for more details. * `QONNX `_: Based on ONNX. See `frontend/onnx <../frontend/onnx.html>`_ for more details. -Running C simulation from Python requires a C++11-compatible compiler. On Linux, a GCC C++ compiler ``g++`` is required. Any version from a recent Linux should work. On MacOS, when the *clang*-based ``g++`` finds issues with ``ap_types`` headers, one may still need to install GCC, using ``brew`` for example. For the oneAPI backend, one must have `oneAPI=2025.0` (2025.1 is known **not to work**) installed, along with the FPGA compiler, to run C/SYCL simulations. +Running C simulation from Python requires a C++11-compatible compiler. On Linux, a GCC C++ compiler ``g++`` is required. Any version from a recent Linux should work. On MacOS, when the *clang*-based ``g++`` finds issues with ``ap_types`` headers, one may still need to install GCC, using ``brew`` for example. For the Altera backend, one must have Intel oneAPI 2025.0 (2025.1 is known **not to work**) installed, along with the FPGA compiler, to run C/SYCL simulations. Specific functionalities may need additional Python packages. If any needed is missing, ``hls4ml`` will raise an error and prompt you to install the missing packages. @@ -72,7 +72,7 @@ To run FPGA synthesis, installation of following tools is required: * Intel Quartus 20.1 to 21.4 for the synthesis for Intel/Altera FPGAs using the ``Quartus`` backend. -* oneAPI 2024.1 to 2025.0 with the FPGA compiler and recent Intel/Altera Quartus for Intel/Altera FPGAs using the ``oneAPI`` backend. Newer versions of ``OneAPI`` removed FPGA support and **will to work** with ``hls4ml``. +* Intel oneAPI 2024.1 to 2025.0 with the FPGA compiler and recent Intel/Altera Quartus for Intel/Altera FPGAs using the ``Altera`` backend. Newer versions of oneAPI removed FPGA support and **will not work** with ``hls4ml``. Catapult HLS 2024.1_1 or 2024.2 can be used to synthesize both for ASICs and FPGAs. diff --git a/docs/intro/status.rst b/docs/intro/status.rst index d3942691ca..2f4f87a606 100644 --- a/docs/intro/status.rst +++ b/docs/intro/status.rst @@ -47,7 +47,7 @@ HLS backends: * Intel HLS * Vitis HLS * Catapult HLS -* oneAPI (experimental) +* Altera (experimental) * XLS (experimental) A summary of the on-going status of the ``hls4ml`` tool is in the table below. @@ -81,7 +81,7 @@ A summary of the on-going status of the ``hls4ml`` tool is in the table below. +-----------------------+-----+-----+--------------+--------+--------+-----+ | Catapult HLS | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | +-----------------------+-----+-----+--------------+--------+--------+-----+ -| oneAPI (experimental) | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | +| Altera (experimental) | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | +-----------------------+-----+-----+--------------+--------+--------+-----+ | XLS (experimental) | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | +-----------------------+-----+-----+--------------+--------+--------+-----+ @@ -94,7 +94,7 @@ Other feature notes: - Intel HLS versions 20.1 to 21.4, versions > 21.4 have not been tested. - Vitis HLS versions 2022.2 to 2024.1. Versions > 2024.1 are less tested. - Catapult HLS versions 2024.1_1 to 2024.2 - - oneAPI versions 2024.1 to 2025.0. Any future versions are known to not work. + - The Altera backend uses Intel oneAPI versions 2024.1 to 2025.0. Later versions are known not to work. * ``hls4ml`` supports Linux [*]_ and requires python >=3.10. hls4ml does not require a specific Linux distribution version and we recommend following the requirements of the HLS tool you are using. * Windows and macOS are not supported. Setting up ``hls4ml`` on these platforms, for example using the Windows Subsystem for Linux (WSL), should be possible, but we do not provide support for such use cases. diff --git a/docs/ir/attributes.rst b/docs/ir/attributes.rst index 8fecef73aa..b08c5fb1d8 100644 --- a/docs/ir/attributes.rst +++ b/docs/ir/attributes.rst @@ -87,19 +87,19 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * table_size: int (Default: 1024) * The size of the lookup table used to approximate the function. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * table_t: NamedType (Default: fixed<18,8,TRN,WRAP,0>) * The datatype (precision) used for the values of the lookup table. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS ParametrizedActivation ====================== @@ -143,19 +143,19 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * table_size: int (Default: 1024) * The size of the lookup table used to approximate the function. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * table_t: NamedType (Default: fixed<18,8,TRN,WRAP,0>) * The datatype (precision) used for the values of the lookup table. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS PReLU ===== @@ -203,19 +203,19 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * table_size: int (Default: 1024) * The size of the lookup table used to approximate the function. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * table_t: NamedType (Default: fixed<18,8,TRN,WRAP,0>) * The datatype (precision) used for the values of the lookup table. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS Softmax ======= @@ -251,59 +251,59 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * table_size: int (Default: 1024) * The size of the lookup table used to approximate the function. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * table_t: NamedType (Default: fixed<18,8,TRN,WRAP,0>) * The datatype (precision) used for the values of the lookup table. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * n_outer: int (Default: 1) - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * n_inner: int (Default: 1) - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * implementation: list [latency,stable,argmax,legacy] (Default: stable) * Choice of implementation of softmax function. "latency" provides good latency at the expense of extra resources. performs well on small number of classes. "stable" may require extra clock cycles but has better accuracy. "legacy" is the older implementation which has bad accuracy, but is fast and has low resource use. It is superseded by the "latency" implementation for most applications. "argmax" is a special implementation that can be used if only the output with the highest probability is important. Using this implementation will save resources and clock cycles. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * skip: bool (Default: False) * If enabled, skips the softmax node and returns the raw outputs. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * exp_table_t: NamedType (Default: fixed<18,8,RND,SAT,0>) * The datatype (precision) used for the values of the lookup table. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * inv_table_t: NamedType (Default: fixed<18,8,RND,SAT,0>) * The datatype (precision) used for the values of the lookup table. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * inv_inp_t: NamedType (Default: fixed<18,8,RND,SAT,0>) - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * accum_t: NamedType (Default: fixed<18,8,RND,SAT,0>) - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS TernaryTanh =========== @@ -339,19 +339,19 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * table_size: int (Default: 1024) * The size of the lookup table used to approximate the function. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * table_t: NamedType (Default: fixed<18,8,TRN,WRAP,0>) * The datatype (precision) used for the values of the lookup table. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS HardActivation ============== @@ -399,19 +399,19 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * table_size: int (Default: 1024) * The size of the lookup table used to approximate the function. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * table_t: NamedType (Default: fixed<18,8,TRN,WRAP,0>) * The datatype (precision) used for the values of the lookup table. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS Reshape ======= @@ -487,13 +487,13 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * strategy: list [latency,resource] (Default: latency) @@ -529,13 +529,13 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS Conv1D ====== @@ -597,19 +597,19 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * parallelization_factor: int (Default: 1) * The number of outputs computed in parallel. Essentially the number of multiplications of input window with the convolution kernel occuring in parallel. Higher number results in more parallelism (lower latency and II) at the expense of resources used.Currently only supported in io_parallel. - * Available in: Vivado, VivadoAccelerator, Vitis, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Catapult, Altera * conv_implementation: list [LineBuffer,Encoded] (Default: LineBuffer) @@ -689,19 +689,19 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * parallelization_factor: int (Default: 1) * The number of outputs computed in parallel. Essentially the number of multiplications of input window with the convolution kernel occuring in parallel. Higher number results in more parallelism (lower latency and II) at the expense of resources used.Currently only supported in io_parallel. - * Available in: Vivado, VivadoAccelerator, Vitis, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Catapult, Altera * conv_implementation: list [LineBuffer,Encoded] (Default: LineBuffer) @@ -781,19 +781,19 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * parallelization_factor: int (Default: 1) * The number of outputs computed in parallel. Essentially the number of multiplications of input window with the convolution kernel occuring in parallel. Higher number results in more parallelism (lower latency and II) at the expense of resources used.Currently only supported in io_parallel. - * Available in: Vivado, VivadoAccelerator, Vitis, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Catapult, Altera * conv_implementation: list [LineBuffer,Encoded] (Default: LineBuffer) @@ -867,23 +867,23 @@ Backend-specific attributes --------------------------- * depthwise_accum_t: NamedType - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * pointwise_accum_t: NamedType - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * depthwise_result_t: NamedType - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * depthwise_reuse_factor: int (Default: 1) - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * pointwise_reuse_factor: int (Default: 1) - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * conv_implementation: list [LineBuffer,Encoded] (Default: LineBuffer) @@ -985,19 +985,19 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * parallelization_factor: int (Default: 1) * The number of outputs computed in parallel. Essentially the number of multiplications of input window with the convolution kernel occuring in parallel. Higher number results in more parallelism (lower latency and II) at the expense of resources used.Currently only supported in io_parallel. - * Available in: Vivado, VivadoAccelerator, Vitis, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Catapult, Altera * conv_implementation: list [LineBuffer,Encoded] (Default: LineBuffer) @@ -1083,23 +1083,23 @@ Backend-specific attributes --------------------------- * depthwise_accum_t: NamedType - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * pointwise_accum_t: NamedType - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * depthwise_result_t: NamedType - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * depthwise_reuse_factor: int (Default: 1) - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * pointwise_reuse_factor: int (Default: 1) - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * conv_implementation: list [LineBuffer,Encoded] (Default: LineBuffer) @@ -1225,19 +1225,19 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * parallelization_factor: int (Default: 1) * The number of outputs computed in parallel. Essentially the number of multiplications of input window with the convolution kernel occuring in parallel. Higher number results in more parallelism (lower latency and II) at the expense of resources used.Currently only supported in io_parallel. - * Available in: Vivado, VivadoAccelerator, Vitis, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Catapult, Altera * conv_implementation: list [LineBuffer,Encoded] (Default: LineBuffer) @@ -1297,7 +1297,7 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS Pooling1D ========= @@ -1347,13 +1347,13 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * conv_implementation: list [LineBuffer,Encoded] (Default: LineBuffer) @@ -1421,13 +1421,13 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * conv_implementation: list [LineBuffer,Encoded] (Default: LineBuffer) @@ -1471,13 +1471,13 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS GlobalPooling2D =============== @@ -1517,13 +1517,13 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS ZeroPadding1D ============= @@ -1707,7 +1707,7 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS MatMul ====== @@ -1739,13 +1739,13 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS Dot === @@ -1793,13 +1793,13 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, Vivado, VivadoAccelerator, VivadoAccelerator, Vitis, Vitis, Quartus, Quartus, Catapult, Catapult, SymbolicExpression, SymbolicExpression, oneAPI, oneAPI, Libero, Libero, XLS, XLS + * Available in: Vivado, Vivado, VivadoAccelerator, VivadoAccelerator, Vitis, Vitis, Quartus, Quartus, Catapult, Catapult, SymbolicExpression, SymbolicExpression, Altera, Altera, Libero, Libero, XLS, XLS Concatenate =========== @@ -1847,7 +1847,7 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS Resize ====== @@ -1955,7 +1955,7 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS SimpleRNN ========= @@ -2019,19 +2019,19 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * recurrent_reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, Altera * static: bool (Default: True) @@ -2043,13 +2043,13 @@ Backend-specific attributes * The size of the lookup table used to approximate the function. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, Altera * table_t: NamedType (Default: fixed<18,8,TRN,WRAP,0>) * The datatype (precision) used for the values of the lookup table. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, Altera LSTM ==== @@ -2123,19 +2123,19 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * recurrent_reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, Altera * static: bool (Default: True) @@ -2147,13 +2147,13 @@ Backend-specific attributes * The size of the lookup table used to approximate the function. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, Altera * table_t: NamedType (Default: fixed<18,8,TRN,WRAP,0>) * The datatype (precision) used for the values of the lookup table. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, Altera GRU === @@ -2229,19 +2229,19 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * recurrent_reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, Altera * static: bool (Default: True) @@ -2253,13 +2253,13 @@ Backend-specific attributes * The size of the lookup table used to approximate the function. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, Altera * table_t: NamedType (Default: fixed<18,8,TRN,WRAP,0>) * The datatype (precision) used for the values of the lookup table. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, Altera Bidirectional ============= @@ -2359,13 +2359,13 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * forward_reuse_factor: int (Default: 1) @@ -2477,7 +2477,7 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, Vivado, VivadoAccelerator, VivadoAccelerator, Vitis, Vitis, Quartus, Quartus, Catapult, Catapult, SymbolicExpression, SymbolicExpression, oneAPI, oneAPI, Libero, Libero, XLS, XLS + * Available in: Vivado, Vivado, VivadoAccelerator, VivadoAccelerator, Vitis, Vitis, Quartus, Quartus, Catapult, Catapult, SymbolicExpression, SymbolicExpression, Altera, Altera, Libero, Libero, XLS, XLS GarNetStack =========== @@ -2525,7 +2525,7 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, Vivado, VivadoAccelerator, VivadoAccelerator, Vitis, Vitis, Quartus, Quartus, Catapult, Catapult, SymbolicExpression, SymbolicExpression, oneAPI, oneAPI, Libero, Libero, XLS, XLS + * Available in: Vivado, Vivado, VivadoAccelerator, VivadoAccelerator, Vitis, Vitis, Quartus, Quartus, Catapult, Catapult, SymbolicExpression, SymbolicExpression, Altera, Altera, Libero, Libero, XLS, XLS Quant ===== @@ -2563,7 +2563,7 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS BipolarQuant ============ @@ -2641,7 +2641,7 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS BatchNormOnnx ============= @@ -2673,7 +2673,7 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS LayerGroup ========== @@ -2791,13 +2791,13 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * table_range_power2: int (Default: 0) @@ -2953,7 +2953,7 @@ Backend-specific attributes * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS DACombinational =============== @@ -3145,19 +3145,19 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * parallelization_factor: int (Default: 1) * The number of outputs computed in parallel. Essentially the number of multiplications of input window with the convolution kernel occuring in parallel. Higher number results in more parallelism (lower latency and II) at the expense of resources used.Currently only supported in io_parallel. - * Available in: Vivado, VivadoAccelerator, Vitis, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Catapult, Altera * conv_implementation: list [LineBuffer,Encoded] (Default: LineBuffer) @@ -3237,19 +3237,19 @@ Backend-specific attributes * The datatype (precision) used to store intermediate results of the computation within the layer. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * reuse_factor: int (Default: 1) * The number of times each multiplier is used by controlling the amount of pipelining/unrolling. Lower number results in more parallelism and lower latency at the expense of the resources used.Reuse factor = 1 corresponds to all multiplications executed in parallel, and hence, the lowest possible latency. - * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, oneAPI, Libero, XLS + * Available in: Vivado, VivadoAccelerator, Vitis, Quartus, Catapult, SymbolicExpression, Altera, Libero, XLS * parallelization_factor: int (Default: 1) * The number of outputs computed in parallel. Essentially the number of multiplications of input window with the convolution kernel occuring in parallel. Higher number results in more parallelism (lower latency and II) at the expense of resources used.Currently only supported in io_parallel. - * Available in: Vivado, VivadoAccelerator, Vitis, Catapult, oneAPI + * Available in: Vivado, VivadoAccelerator, Vitis, Catapult, Altera * conv_implementation: list [LineBuffer,Encoded] (Default: LineBuffer) diff --git a/docs/ir/ir.rst b/docs/ir/ir.rst index 18b0a1c679..19748dbda8 100644 --- a/docs/ir/ir.rst +++ b/docs/ir/ir.rst @@ -53,7 +53,7 @@ io_parallel Parallel IO is applicable to small models that require low latency implementation. Larger models face synthesizability limits very quickly. -In Vivado/Vitis backends, parallel convolution relies on the *im2col* transformation of the input, which turns convolution into a matrix-multiplication task. This task is then implemented as a sequence of matrix-vector multiplications using the routine mentioned above. The ``Latency`` and ``Resource`` strategies refer to the function used for matrix-vector multiplication routine, with ``Resource`` allowing for a slightly larger models to be synthesized. Parallelism can be further controlled via the ``ParallelizationFactor``. Catapult backend in turn uses a direct implementation of convolution via nested loops. The ``Quartus``, ``oneAPI``, and ``Catapult`` backends also implement a ``Winograd`` algorithm choosable by setting the ``implementation`` to ``Winograd`` or ``combination``. Winograd implementation is available for only a handful of filter size configurations, and it is less concerned about bit accuracy and overflow. In certain conditions it can be faster. +In Vivado/Vitis backends, parallel convolution relies on the *im2col* transformation of the input, which turns convolution into a matrix-multiplication task. This task is then implemented as a sequence of matrix-vector multiplications using the routine mentioned above. The ``Latency`` and ``Resource`` strategies refer to the function used for matrix-vector multiplication routine, with ``Resource`` allowing for a slightly larger models to be synthesized. Parallelism can be further controlled via the ``ParallelizationFactor``. Catapult backend in turn uses a direct implementation of convolution via nested loops. The ``Quartus``, ``Altera``, and ``Catapult`` backends also implement a ``Winograd`` algorithm choosable by setting the ``implementation`` to ``Winograd`` or ``combination``. Winograd implementation is available for only a handful of filter size configurations, and it is less concerned about bit accuracy and overflow. In certain conditions it can be faster. io_stream ^^^^^^^^^ diff --git a/hls4ml/backends/__init__.py b/hls4ml/backends/__init__.py index 6febdce076..2e830ce889 100644 --- a/hls4ml/backends/__init__.py +++ b/hls4ml/backends/__init__.py @@ -1,7 +1,8 @@ from hls4ml.backends.backend import Backend, get_available_backends, get_backend, register_backend # noqa: F401 from hls4ml.backends.fpga.fpga_backend import FPGABackend # noqa: F401 from hls4ml.backends.libero.libero_backend import LiberoBackend -from hls4ml.backends.oneapi.oneapi_backend import OneAPIBackend + +from hls4ml.backends.altera.altera_backend import AlteraBackend # isort: skip from hls4ml.backends.plugin_loader import load_backend_plugins from hls4ml.backends.quartus.quartus_backend import QuartusBackend from hls4ml.backends.symbolic.symbolic_backend import SymbolicExpressionBackend @@ -23,7 +24,7 @@ def _register_builtin_backends(): register_backend('Quartus', QuartusBackend) register_backend('Catapult', CatapultBackend) register_backend('SymbolicExpression', SymbolicExpressionBackend) - register_backend('oneAPI', OneAPIBackend) + register_backend('Altera', AlteraBackend) register_backend('Coyote', CoyoteBackend) register_backend('Libero', LiberoBackend) register_backend('XLS', XLSBackend) diff --git a/hls4ml/backends/oneapi/__init__.py b/hls4ml/backends/altera/__init__.py similarity index 100% rename from hls4ml/backends/oneapi/__init__.py rename to hls4ml/backends/altera/__init__.py diff --git a/hls4ml/backends/oneapi/oneapi_backend.py b/hls4ml/backends/altera/altera_backend.py similarity index 92% rename from hls4ml/backends/oneapi/oneapi_backend.py rename to hls4ml/backends/altera/altera_backend.py index 0c11c16d09..1c75bd1d34 100644 --- a/hls4ml/backends/oneapi/oneapi_backend.py +++ b/hls4ml/backends/altera/altera_backend.py @@ -23,16 +23,16 @@ ) from hls4ml.model.optimizer import get_backend_passes, layer_optimizer from hls4ml.model.types import FixedPrecisionType, IntegerPrecisionType, NamedType -from hls4ml.report import parse_oneapi_report +from hls4ml.report import parse_altera_report from hls4ml.utils import attribute_descriptions as descriptions from hls4ml.utils.einsum_utils import parse_einsum -# from hls4ml.report import parse_oneapi_report +# from hls4ml.report import parse_altera_report -class OneAPIBackend(FPGABackend): +class AlteraBackend(FPGABackend): def __init__(self): - super().__init__('oneAPI') + super().__init__('Altera') self._register_layer_attributes() self._register_flows() @@ -66,43 +66,43 @@ def _register_flows(self): initializers = self._get_layer_initializers() init_flow = register_flow('init_layers', initializers, requires=['optimize'], backend=self.name) - streaming_passes = ['oneapi:clone_output'] + streaming_passes = ['altera:clone_output'] streaming_flow = register_flow('streaming', streaming_passes, requires=[init_flow], backend=self.name) - oneapi_types = [ - 'oneapi:transform_types', - 'oneapi:register_bram_weights', - 'oneapi:apply_resource_strategy', - 'oneapi:apply_winograd_kernel_transformation', + altera_types = [ + 'altera:transform_types', + 'altera:register_bram_weights', + 'altera:apply_resource_strategy', + 'altera:apply_winograd_kernel_transformation', ] - oneapi_types_flow = register_flow('specific_types', oneapi_types, requires=[init_flow], backend=self.name) + altera_types_flow = register_flow('specific_types', altera_types, requires=[init_flow], backend=self.name) quantization_passes = [ - 'oneapi:merge_batch_norm_quantized_tanh', - 'oneapi:quantize_dense_output', + 'altera:merge_batch_norm_quantized_tanh', + 'altera:quantize_dense_output', 'fuse_consecutive_batch_normalization', - 'oneapi:xnor_pooling', + 'altera:xnor_pooling', ] quantization_flow = register_flow('quantization', quantization_passes, requires=[init_flow], backend=self.name) optimization_passes = [ - 'oneapi:remove_final_reshape', - 'oneapi:optimize_pointwise_conv', - 'oneapi:inplace_parallel_reshape', - 'oneapi:skip_softmax', - 'oneapi:fix_softmax_table_size', + 'altera:remove_final_reshape', + 'altera:optimize_pointwise_conv', + 'altera:inplace_parallel_reshape', + 'altera:skip_softmax', + 'altera:fix_softmax_table_size', 'infer_precision_types', - 'oneapi:process_fixed_point_quantizer_layer', - 'oneapi:validate_ac_types', + 'altera:process_fixed_point_quantizer_layer', + 'altera:validate_ac_types', ] optimization_flow = register_flow('optimize', optimization_passes, requires=[init_flow], backend=self.name) templates = self._get_layer_templates() template_flow = register_flow('apply_templates', self._get_layer_templates, requires=[init_flow], backend=self.name) - writer_passes = ['make_stamp', 'oneapi:write_hls'] + writer_passes = ['make_stamp', 'altera:write_hls'] - self._writer_flow = register_flow('write', writer_passes, requires=['oneapi:ip'], backend=self.name) + self._writer_flow = register_flow('write', writer_passes, requires=['altera:ip'], backend=self.name) all_passes = get_backend_passes(self.name) @@ -113,12 +113,12 @@ def _register_flows(self): if opt_pass not in initializers + streaming_passes - + oneapi_types + + altera_types + quantization_passes + templates + optimization_passes + writer_passes - + ['oneapi:inplace_stream_flatten', 'oneapi:reshape_stream'] # not needed + + ['altera:inplace_stream_flatten', 'altera:reshape_stream'] # not needed ] if len(extras) > 0: @@ -131,7 +131,7 @@ def _register_flows(self): streaming_flow, quantization_flow, optimization_flow, - oneapi_types_flow, + altera_types_flow, template_flow, ] ip_flow_requirements = list(filter(None, ip_flow_requirements)) @@ -147,7 +147,7 @@ def get_writer_flow(self): def create_initial_config( self, part='Agilex7', clock_period=5, hyperopt_handshake=False, io_type='io_parallel', write_tar=False, **_ ): - """Create initial configuration of the oneAPI backend. + """Create initial configuration of the Altera backend. Args: part (str, optional): The FPGA part to be used. Defaults to 'Agilex7'. @@ -194,7 +194,7 @@ def compile(self, model): def build(self, model, build_type='fpga_emu', run=False): """ - Builds the project using Intel DPC++ (oneAPI) compiler. + Builds the project using the Intel oneAPI DPC++ compiler. Args: model (ModelGraph): The model to build @@ -210,7 +210,7 @@ def build(self, model, build_type='fpga_emu', run=False): try: subprocess.run('which icpx', shell=True, cwd=builddir, check=True) except subprocess.CalledProcessError: - raise RuntimeError('Could not find icpx. Please configure oneAPI appropriately') + raise RuntimeError('Could not find icpx. Please configure the Intel oneAPI toolchain appropriately') subprocess.run('cmake ..', shell=True, cwd=builddir, check=True) subprocess.run(f'make {build_type}', shell=True, cwd=builddir, check=True) @@ -220,7 +220,7 @@ def build(self, model, build_type='fpga_emu', run=False): executable = builddir / f'{model.config.get_project_name()}.{build_type}' subprocess.run(f'{str(executable)}', shell=True, cwd=builddir, check=True) - return parse_oneapi_report(model.config.get_output_dir()) + return parse_altera_report(model.config.get_output_dir()) @layer_optimizer(Layer) def init_base_layer(self, layer): @@ -287,7 +287,7 @@ def init_gru(self, layer): ) if 'table_size' not in layer.attributes: layer.set_attr('table_size', 1024) - if True: # layer.model.config.is_resource_strategy(layer): ... oneAPI only supports Dense resource multiplication + if True: # layer.model.config.is_resource_strategy(layer): ... Altera only supports Dense resource multiplication n_in, n_out, n_in_recr, n_out_recr = self.get_layer_mult_size(layer) self.set_closest_reuse_factor(layer, n_in, n_out) self.set_closest_reuse_factor(layer, n_in_recr, n_out_recr, attribute='recurrent_reuse_factor') @@ -323,7 +323,7 @@ def init_conv1d(self, layer): layer.set_attr( 'n_partitions', 1 - ) # TODO Not used yet as there is no codegen implementation of CNNs for oneAPI backend + ) # TODO Not used yet as there is no codegen implementation of CNNs for Altera backend @layer_optimizer(Conv2D) def init_conv2d(self, layer): @@ -354,7 +354,7 @@ def init_conv2d(self, layer): layer.set_attr( 'n_partitions', 1 - ) # TODO Not used yet as there is no codegen implementation of CNNs for oneAPI backend + ) # TODO Not used yet as there is no codegen implementation of CNNs for Altera backend @layer_optimizer(LSTM) def init_lstm(self, layer): @@ -362,7 +362,7 @@ def init_lstm(self, layer): layer.set_attr('recurrent_reuse_factor', reuse_factor) # We don't use RF yet - if True: # layer.model.config.is_resource_strategy(layer): ... oneAPI only supports Dense resource multiplication + if True: # layer.model.config.is_resource_strategy(layer): ... Altera only supports Dense resource multiplication n_in, n_out, n_in_recr, n_out_recr = self.get_layer_mult_size(layer) self.set_closest_reuse_factor(layer, n_in, n_out) self.set_closest_reuse_factor(layer, n_in_recr, n_out_recr, attribute='recurrent_reuse_factor') diff --git a/hls4ml/backends/oneapi/oneapi_template.py b/hls4ml/backends/altera/altera_template.py similarity index 89% rename from hls4ml/backends/oneapi/oneapi_template.py rename to hls4ml/backends/altera/altera_template.py index 469861429a..7d7f2ad849 100644 --- a/hls4ml/backends/oneapi/oneapi_template.py +++ b/hls4ml/backends/altera/altera_template.py @@ -1,12 +1,12 @@ """ -This package includes oneAPI-specific templates +This package includes Altera-specific templates """ from hls4ml.backends.template import Template class StreamFunctionCallTemplate(Template): - """Base class for the streaming function call templates in oneAPI: provides the 'stream_function_cpp' attribute. + """Base class for the streaming function call templates in Altera: provides the 'stream_function_cpp' attribute. This generally provides the async call to the task sequence that executes the streaming function. Note: the include header files are specified in the regular FunctionCallTemplate, not here. @@ -33,7 +33,7 @@ def transform(self, model, node): class TaskSequenceTemplate(Template): - """Base class for the task sequence definition in oneAPI: provides the 'task_sequence_cpp' attribute. + """Base class for the task sequence definition in Altera: provides the 'task_sequence_cpp' attribute. This defines the task sequence that is then called by the StreamFunctionCallTemplate. Args: diff --git a/hls4ml/backends/oneapi/oneapi_types.py b/hls4ml/backends/altera/altera_types.py similarity index 81% rename from hls4ml/backends/oneapi/oneapi_types.py rename to hls4ml/backends/altera/altera_types.py index 0ecff79034..9ce50d0a0e 100644 --- a/hls4ml/backends/oneapi/oneapi_types.py +++ b/hls4ml/backends/altera/altera_types.py @@ -1,5 +1,5 @@ """ -This package includes oneAPI-specific customizations to the variable types +This package includes Altera-specific customizations to the variable types """ import numpy as np @@ -39,7 +39,7 @@ def definition_cpp(self): return typestring -class OneAPIACTypeConverter(FPGAPrecisionConverter): +class AlteraACTypeConverter(FPGAPrecisionConverter): def __init__(self): super().__init__( type_map={ @@ -54,8 +54,8 @@ def __init__(self): ) -class OneAPICompressedTypeConverter(TypeDefinition, TypePrecisionConverter): - """Use a tuple for storing a compressed type for oneAPI since it's better supported. (Currently unused)""" +class AlteraCompressedTypeConverter(TypeDefinition, TypePrecisionConverter): + """Use a tuple for storing a compressed type for Altera since it's better supported. (Currently unused)""" def definition_cpp(self): """tuple format is row_index, col_index, weight""" @@ -67,8 +67,8 @@ def convert_precision(self, precision_converter): self.index_precision = precision_converter.convert(self.index_precision) -class OneAPIExponentTypeConverter(TypeDefinition, TypePrecisionConverter): - """Use a pair for storing a exponent type for oneAPI since it's better supported""" +class AlteraExponentTypeConverter(TypeDefinition, TypePrecisionConverter): + """Use a pair for storing a exponent type for Altera since it's better supported""" def definition_cpp(self): cpp_fmt = 'typedef std::pair<{sign}, {precision}> {name};\n' @@ -79,7 +79,7 @@ def convert_precision(self, precision_converter): self.sign = precision_converter.convert(self.sign) -class OneAPIPackedTypeConverter(TypeDefinition, TypePrecisionConverter): +class AlteraPackedTypeConverter(TypeDefinition, TypePrecisionConverter): def definition_cpp(self): n_elem_expr = '/' if self.unpack else '*' return 'typedef nnet::array<{precision}, {n_elem}> {name};\n'.format( @@ -92,21 +92,21 @@ def convert_precision(self, precision_converter): self.precision = precision_converter.convert(self.precision) -class OneAPIHLSTypeConverter(HLSTypeConverter): +class AlteraHLSTypeConverter(HLSTypeConverter): def __init__(self, precision_converter): self.precision_converter = precision_converter self.type_map = { NamedType: NamedTypeConverter, - CompressedType: OneAPICompressedTypeConverter, - ExponentType: OneAPIExponentTypeConverter, - PackedType: OneAPIPackedTypeConverter, + CompressedType: AlteraCompressedTypeConverter, + ExponentType: AlteraExponentTypeConverter, + PackedType: AlteraPackedTypeConverter, } # region ArrayVarable -class OneAPIArrayVariableDefinition(VariableDefinition): +class AlteraArrayVariableDefinition(VariableDefinition): def definition_cpp(self, name_suffix='', as_reference=False): if self.pragma and not isinstance(self.pragma, tuple): return f'[[{self.pragma}]] {self.type.name} {self.name}{name_suffix}' @@ -114,7 +114,7 @@ def definition_cpp(self, name_suffix='', as_reference=False): return f'{self.type.name} {self.name}{name_suffix}' -class OneAPIInplaceArrayVariableDefinition(VariableDefinition): +class AlteraInplaceArrayVariableDefinition(VariableDefinition): def definition_cpp(self): return f'auto& {self.name} = {self.input_var.name}' @@ -157,14 +157,14 @@ def convert(self, tensor_var, pragma='', depth=0, n_pack=1): return tensor_var -class OneAPIArrayVariableConverter(AggregratedArrayVariableConverter): +class AlteraArrayVariableConverter(AggregratedArrayVariableConverter): def __init__(self, type_converter): - super().__init__(type_converter=type_converter, prefix='OneAPI', definition_cls=OneAPIArrayVariableDefinition) + super().__init__(type_converter=type_converter, prefix='Altera', definition_cls=AlteraArrayVariableDefinition) -class OneAPIInplaceArrayVariableConverter(AggregratedArrayVariableConverter): +class AlteraInplaceArrayVariableConverter(AggregratedArrayVariableConverter): def __init__(self, type_converter): - super().__init__(type_converter=type_converter, prefix='OneAPI', definition_cls=OneAPIInplaceArrayVariableDefinition) + super().__init__(type_converter=type_converter, prefix='Altera', definition_cls=AlteraInplaceArrayVariableDefinition) # endregion @@ -172,7 +172,7 @@ def __init__(self, type_converter): # region InterfaceMemberVariable -class OneAPIInterfaceVariableDefinition(VariableDefinition): +class AlteraInterfaceVariableDefinition(VariableDefinition): def definition_cpp(self, name_suffix='', as_reference=False): if self.pragma and not isinstance(self.pragma, tuple): return f'[[{self.pragma}]] {self.type.name} {self.name}{name_suffix}' @@ -188,16 +188,16 @@ def declare_cpp(self, pipe_min_size=0, indent=''): return lines -class OneAPIInterfaceVariableConverter(AggregratedArrayVariableConverter): +class AlteraInterfaceVariableConverter(AggregratedArrayVariableConverter): def __init__(self, type_converter): - super().__init__(type_converter=type_converter, prefix='OneAPI', definition_cls=OneAPIInterfaceVariableDefinition) + super().__init__(type_converter=type_converter, prefix='Altera', definition_cls=AlteraInterfaceVariableDefinition) # endregion # region StreamVariable -class OneAPIStreamVariableDefinition(VariableDefinition): +class AlteraStreamVariableDefinition(VariableDefinition): def definition_cpp(self, name_suffix='', as_reference=True): return f'{self.name}{name_suffix}' @@ -210,27 +210,27 @@ def declare_cpp(self, indent=''): return lines -class OneAPIInplaceStreamVariableDefinition(VariableDefinition): +class AlteraInplaceStreamVariableDefinition(VariableDefinition): def definition_cpp(self): return f'using {self.name} = {self.input_var.name}' -class OneAPIStreamVariableConverter(AggregratedArrayVariableConverter): +class AlteraStreamVariableConverter(AggregratedArrayVariableConverter): def __init__(self, type_converter): - super().__init__(type_converter=type_converter, prefix='OneAPI', definition_cls=OneAPIStreamVariableDefinition) + super().__init__(type_converter=type_converter, prefix='Altera', definition_cls=AlteraStreamVariableDefinition) -class OneAPIInplaceStreamVariableConverter(AggregratedArrayVariableConverter): +class AlteraInplaceStreamVariableConverter(AggregratedArrayVariableConverter): def __init__(self, type_converter): super().__init__( - type_converter=type_converter, prefix='OneAPI', definition_cls=OneAPIInplaceStreamVariableDefinition + type_converter=type_converter, prefix='Altera', definition_cls=AlteraInplaceStreamVariableDefinition ) # region WeightsVariable -class OneAPIStaticWeightVariableDefinition(VariableDefinition): +class AlteraStaticWeightVariableDefinition(VariableDefinition): def definition_cpp(self, reuse_factor): """Write the appropriate weight definiiton""" # first determine whether to store in register or bram (heuristic) @@ -251,12 +251,12 @@ def definition_cpp(self, reuse_factor): return f'{attribute} {self.type.name} {self.name}' -class OneAPIStaticWeightVariableConverter: +class AlteraStaticWeightVariableConverter: def __init__(self, type_converter): self.type_converter = type_converter def convert(self, weight_var): - if isinstance(weight_var, OneAPIStaticWeightVariableDefinition): # Already converted + if isinstance(weight_var, AlteraStaticWeightVariableDefinition): # Already converted return weight_var weight_var.weight_class = weight_var.__class__.__name__ @@ -267,8 +267,8 @@ def convert(self, weight_var): weight_cls_fqn = weight_var.__class__.__module__ + '.' + weight_var.__class__.__qualname__ weight_var.__class__ = type( - 'OneAPIStaticWeightVariable', - (type(weight_var), OneAPIStaticWeightVariableDefinition), + 'AlteraStaticWeightVariable', + (type(weight_var), AlteraStaticWeightVariableDefinition), {'_wrapped': weight_cls_fqn}, ) return weight_var diff --git a/hls4ml/backends/oneapi/passes/__init__.py b/hls4ml/backends/altera/passes/__init__.py similarity index 100% rename from hls4ml/backends/oneapi/passes/__init__.py rename to hls4ml/backends/altera/passes/__init__.py diff --git a/hls4ml/backends/oneapi/passes/bn_quant.py b/hls4ml/backends/altera/passes/bn_quant.py similarity index 99% rename from hls4ml/backends/oneapi/passes/bn_quant.py rename to hls4ml/backends/altera/passes/bn_quant.py index 7a7055b852..e6eda4c6a2 100644 --- a/hls4ml/backends/oneapi/passes/bn_quant.py +++ b/hls4ml/backends/altera/passes/bn_quant.py @@ -1,7 +1,7 @@ import numpy as np +from hls4ml.backends.altera.altera_template import StreamFunctionCallTemplate, TaskSequenceTemplate from hls4ml.backends.fpga.fpga_layers import BatchNormalizationQuantizedTanh -from hls4ml.backends.oneapi.oneapi_template import StreamFunctionCallTemplate, TaskSequenceTemplate from hls4ml.backends.template import FunctionCallTemplate, LayerConfigTemplate from hls4ml.model.layers import BatchNormalization, register_layer from hls4ml.model.optimizer import OptimizerPass diff --git a/hls4ml/backends/oneapi/passes/clone_templates.py b/hls4ml/backends/altera/passes/clone_templates.py similarity index 85% rename from hls4ml/backends/oneapi/passes/clone_templates.py rename to hls4ml/backends/altera/passes/clone_templates.py index c49fb3e454..27f6e7a8e4 100644 --- a/hls4ml/backends/oneapi/passes/clone_templates.py +++ b/hls4ml/backends/altera/passes/clone_templates.py @@ -1,7 +1,7 @@ -"""The clone templates in the fpga backend are not enough for oneAPI, so this adds the missing parts""" +"""The clone templates in the fpga backend are not enough for Altera, so this adds the missing parts""" +from hls4ml.backends.altera.altera_template import StreamFunctionCallTemplate, TaskSequenceTemplate from hls4ml.backends.fpga.passes.clone import Clone -from hls4ml.backends.oneapi.oneapi_template import StreamFunctionCallTemplate, TaskSequenceTemplate clone_stream_function_template = '{name}.async();' diff --git a/hls4ml/backends/oneapi/passes/convolution_templates.py b/hls4ml/backends/altera/passes/convolution_templates.py similarity index 97% rename from hls4ml/backends/oneapi/passes/convolution_templates.py rename to hls4ml/backends/altera/passes/convolution_templates.py index f1e1abded5..e775343e22 100644 --- a/hls4ml/backends/oneapi/passes/convolution_templates.py +++ b/hls4ml/backends/altera/passes/convolution_templates.py @@ -1,5 +1,5 @@ +from hls4ml.backends.altera.altera_template import StreamFunctionCallTemplate, TaskSequenceTemplate from hls4ml.backends.backend import get_backend -from hls4ml.backends.oneapi.oneapi_template import StreamFunctionCallTemplate, TaskSequenceTemplate from hls4ml.backends.template import FunctionCallTemplate, LayerConfigTemplate from hls4ml.model.layers import Conv1D, Conv2D, Conv2DBatchnorm, DepthwiseConv1D, DepthwiseConv2D @@ -98,7 +98,7 @@ def format(self, node): mult_params = self._default_config_params(node) mult_params['n_in'] = node.get_attr('n_chan') * node.get_attr('filt_width') mult_params['n_out'] = node.get_attr('n_filt') - mult_params['product_type'] = get_backend('oneAPI').product_type( + mult_params['product_type'] = get_backend('Altera').product_type( node.get_input_variable().type.precision, node.get_weights('weight').type.precision ) mult_config = self.mult_template.format(**mult_params) @@ -114,7 +114,7 @@ def __init__(self): def format(self, node): params = self._default_function_params(node) if node.get_attr('data_format') == 'channels_first': - raise RuntimeError('channels_first not supported on oneAPI') + raise RuntimeError('channels_first not supported on Altera') params['data_format'] = 'cl' params['w'] = node.get_weights('weight').name params['b'] = node.get_weights('bias').name @@ -130,7 +130,7 @@ def __init__(self): def format(self, node): params = self._default_function_params(node) if node.get_attr('data_format') == 'channels_first': - raise RuntimeError('channels_first not supported on oneAPI') + raise RuntimeError('channels_first not supported on Altera') params['data_format'] = 'cl' return self.template.format(**params) @@ -215,7 +215,7 @@ def format(self, node): mult_params = self._default_config_params(node) mult_params['n_in'] = node.get_attr('n_chan') * node.get_attr('filt_height') * node.get_attr('filt_width') mult_params['n_out'] = node.get_attr('n_filt') - mult_params['product_type'] = get_backend('oneAPI').product_type( + mult_params['product_type'] = get_backend('Altera').product_type( node.get_input_variable().type.precision, node.get_weights('weight').type.precision ) mult_config = self.mult_template.format(**mult_params) @@ -231,7 +231,7 @@ def __init__(self): def format(self, node): params = self._default_function_params(node) if node.get_attr('data_format') == 'channels_first': - raise RuntimeError('channels_first not supported for oneAPI') + raise RuntimeError('channels_first not supported for Altera') params['data_format'] = 'cl' params['w'] = node.get_weights('weight').name params['b'] = node.get_weights('bias').name @@ -247,7 +247,7 @@ def __init__(self): def format(self, node): params = self._default_function_params(node) if node.get_attr('data_format') == 'channels_first': - raise RuntimeError('channels_first not supported on oneAPI') + raise RuntimeError('channels_first not supported on Altera') params['data_format'] = 'cl' return self.template.format(**params) diff --git a/hls4ml/backends/oneapi/passes/convolution_winograd.py b/hls4ml/backends/altera/passes/convolution_winograd.py similarity index 100% rename from hls4ml/backends/oneapi/passes/convolution_winograd.py rename to hls4ml/backends/altera/passes/convolution_winograd.py diff --git a/hls4ml/backends/oneapi/passes/core_templates.py b/hls4ml/backends/altera/passes/core_templates.py similarity index 98% rename from hls4ml/backends/oneapi/passes/core_templates.py rename to hls4ml/backends/altera/passes/core_templates.py index 9602b2d0fc..6cd0fe23e8 100644 --- a/hls4ml/backends/oneapi/passes/core_templates.py +++ b/hls4ml/backends/altera/passes/core_templates.py @@ -1,5 +1,5 @@ +from hls4ml.backends.altera.altera_template import StreamFunctionCallTemplate, TaskSequenceTemplate from hls4ml.backends.backend import get_backend -from hls4ml.backends.oneapi.oneapi_template import StreamFunctionCallTemplate, TaskSequenceTemplate from hls4ml.backends.template import FunctionCallTemplate, LayerConfigTemplate from hls4ml.model.layers import Activation, BatchNormalization, Dense, HardActivation, ParametrizedActivation, PReLU, Softmax @@ -49,7 +49,7 @@ def format(self, node): params = self._default_config_params(node) params['nzeros'] = node.get_weights('weight').nzeros params['nonzeros'] = node.get_weights('weight').nonzeros - params['product_type'] = get_backend('oneAPI').product_type( + params['product_type'] = get_backend('Altera').product_type( node.get_input_variable().type.precision, node.get_weights('weight').type.precision ) @@ -121,7 +121,7 @@ def __init__(self): def format(self, node): params = self._default_config_params(node) params['n_in'] = node.get_input_variable().size_cpp() - params['product_type'] = get_backend('oneAPI').product_type( + params['product_type'] = get_backend('Altera').product_type( node.get_input_variable().type.precision, node.get_weights('scale').type.precision ) diff --git a/hls4ml/backends/oneapi/passes/einsum.py b/hls4ml/backends/altera/passes/einsum.py similarity index 98% rename from hls4ml/backends/oneapi/passes/einsum.py rename to hls4ml/backends/altera/passes/einsum.py index ed9150486b..293e0b0d1d 100644 --- a/hls4ml/backends/oneapi/passes/einsum.py +++ b/hls4ml/backends/altera/passes/einsum.py @@ -63,7 +63,7 @@ def format(self, node: Einsum): params['n_inplace'] = node.attributes['n_inplace'] inp0_t = node.get_input_variable(node.inputs[0]).type.precision inp1_t = node.get_input_variable(node.inputs[1]).type.precision - params['product_type'] = get_backend('oneapi').product_type(inp0_t, inp1_t) + params['product_type'] = get_backend('altera').product_type(inp0_t, inp1_t) total_mults = params['n_free0'] * params['n_free1'] * params['n_contract'] * params['n_inplace'] params['multiplier_limit'] = ceil(total_mults / params['reuse_factor']) diff --git a/hls4ml/backends/oneapi/passes/einsum_dense.py b/hls4ml/backends/altera/passes/einsum_dense.py similarity index 99% rename from hls4ml/backends/oneapi/passes/einsum_dense.py rename to hls4ml/backends/altera/passes/einsum_dense.py index a6cac36c6f..faad2531c5 100644 --- a/hls4ml/backends/oneapi/passes/einsum_dense.py +++ b/hls4ml/backends/altera/passes/einsum_dense.py @@ -83,7 +83,7 @@ def dense_config(self, node: EinsumDense): dense_params['nzeros'] = '-1; // Not making sense when kernels are switching' dense_params['nonzeros'] = node.get_weights('weight').nonzeros - dense_params['product_type'] = get_backend('oneAPI').product_type( + dense_params['product_type'] = get_backend('Altera').product_type( node.get_input_variable().type.precision, node.get_weights('weight').type.precision, # type: ignore ) diff --git a/hls4ml/backends/oneapi/passes/embedding_templates.py b/hls4ml/backends/altera/passes/embedding_templates.py similarity index 88% rename from hls4ml/backends/oneapi/passes/embedding_templates.py rename to hls4ml/backends/altera/passes/embedding_templates.py index 6fda678f05..3016f2789f 100644 --- a/hls4ml/backends/oneapi/passes/embedding_templates.py +++ b/hls4ml/backends/altera/passes/embedding_templates.py @@ -1,8 +1,8 @@ """ -These are the stream oneAPI templates for embedding layers. The io_parallel ones are in backends/fpga/passes/embedding.py. +These are the stream Altera templates for embedding layers. The io_parallel ones are in backends/fpga/passes/embedding.py. """ -from hls4ml.backends.oneapi.oneapi_template import StreamFunctionCallTemplate, TaskSequenceTemplate +from hls4ml.backends.altera.altera_template import StreamFunctionCallTemplate, TaskSequenceTemplate from hls4ml.model.layers import Embedding embed_task_sequence_template = 'task_sequence> {name};' diff --git a/hls4ml/backends/oneapi/passes/feature_check.py b/hls4ml/backends/altera/passes/feature_check.py similarity index 92% rename from hls4ml/backends/oneapi/passes/feature_check.py rename to hls4ml/backends/altera/passes/feature_check.py index ca7d417900..7a656b292a 100644 --- a/hls4ml/backends/oneapi/passes/feature_check.py +++ b/hls4ml/backends/altera/passes/feature_check.py @@ -10,4 +10,4 @@ def transform(self, model, node): prec_types = [prec_type.precision for prec_type in node.get_layer_precision().values()] prec_types = [prec_type for prec_type in prec_types if isinstance(prec_type, FloatPrecisionType)] if len(prec_types) > 0: - raise Exception(f'Layer "{node.name}" uses ac_float types that are not supported in oneAPI') + raise Exception(f'Layer "{node.name}" uses ac_float types that are not supported in Altera') diff --git a/hls4ml/backends/oneapi/passes/merge_templates.py b/hls4ml/backends/altera/passes/merge_templates.py similarity index 97% rename from hls4ml/backends/oneapi/passes/merge_templates.py rename to hls4ml/backends/altera/passes/merge_templates.py index 9d261e1f74..60e34589b6 100644 --- a/hls4ml/backends/oneapi/passes/merge_templates.py +++ b/hls4ml/backends/altera/passes/merge_templates.py @@ -1,5 +1,5 @@ +from hls4ml.backends.altera.altera_template import StreamFunctionCallTemplate, TaskSequenceTemplate from hls4ml.backends.backend import get_backend -from hls4ml.backends.oneapi.oneapi_template import StreamFunctionCallTemplate, TaskSequenceTemplate from hls4ml.backends.template import FunctionCallTemplate, LayerConfigTemplate from hls4ml.model.layers import Concatenate, Dot, Merge @@ -101,7 +101,7 @@ def format(self, node): params = self._default_config_params(node) params['n_out'] = 1 params['n_in'] = inp1.shape[0] - params['product_type'] = get_backend('oneAPI').product_type(inp1.type.precision, inp2.type.precision) + params['product_type'] = get_backend('Altera').product_type(inp1.type.precision, inp2.type.precision) return self.template.format(**params) diff --git a/hls4ml/backends/oneapi/passes/pointwise.py b/hls4ml/backends/altera/passes/pointwise.py similarity index 97% rename from hls4ml/backends/oneapi/passes/pointwise.py rename to hls4ml/backends/altera/passes/pointwise.py index 0ec51f87b8..b6b965221b 100644 --- a/hls4ml/backends/oneapi/passes/pointwise.py +++ b/hls4ml/backends/altera/passes/pointwise.py @@ -1,12 +1,12 @@ -from hls4ml.backends.fpga.fpga_layers import PointwiseConv1D, PointwiseConv2D -from hls4ml.backends.oneapi.oneapi_template import StreamFunctionCallTemplate, TaskSequenceTemplate -from hls4ml.backends.oneapi.passes.convolution_templates import ( +from hls4ml.backends.altera.altera_template import StreamFunctionCallTemplate, TaskSequenceTemplate +from hls4ml.backends.altera.passes.convolution_templates import ( Conv1DConfigTemplate, Conv2DConfigTemplate, conv1d_config_template, conv2d_config_template, conv_mult_config_template, ) +from hls4ml.backends.fpga.fpga_layers import PointwiseConv1D, PointwiseConv2D from hls4ml.backends.template import FunctionCallTemplate from hls4ml.model.layers import register_layer from hls4ml.model.optimizer import OptimizerPass @@ -52,7 +52,7 @@ def __init__(self): def format(self, node): params = self._default_function_params(node) if node.get_attr('data_format') == 'channels_first': - raise RuntimeError('channels_first not supported on oneAPI') + raise RuntimeError('channels_first not supported on Altera') params['data_format'] = 'cl' params['w'] = node.get_weights('weight').name params['b'] = node.get_weights('bias').name @@ -68,7 +68,7 @@ def __init__(self): def format(self, node): params = self._default_function_params(node) if node.get_attr('data_format') == 'channels_first': - raise RuntimeError('channels_first not supported on oneAPI') + raise RuntimeError('channels_first not supported on Altera') params['data_format'] = 'cl' return self.template.format(**params) @@ -88,7 +88,7 @@ def __init__(self): def format(self, node): params = self._default_function_params(node) if node.get_attr('data_format') == 'channels_first': - raise RuntimeError('channels_first not supported on oneAPI') + raise RuntimeError('channels_first not supported on Altera') params['data_format'] = 'cl' params['w'] = node.get_weights('weight').name params['b'] = node.get_weights('bias').name @@ -104,7 +104,7 @@ def __init__(self): def format(self, node): params = self._default_function_params(node) if node.get_attr('data_format') == 'channels_first': - raise RuntimeError('channels_first not supported on oneAPI') + raise RuntimeError('channels_first not supported on Altera') params['data_format'] = 'cl' return self.template.format(**params) diff --git a/hls4ml/backends/oneapi/passes/pooling_templates.py b/hls4ml/backends/altera/passes/pooling_templates.py similarity index 96% rename from hls4ml/backends/oneapi/passes/pooling_templates.py rename to hls4ml/backends/altera/passes/pooling_templates.py index 97136ed847..bde4fd2455 100644 --- a/hls4ml/backends/oneapi/passes/pooling_templates.py +++ b/hls4ml/backends/altera/passes/pooling_templates.py @@ -1,4 +1,4 @@ -from hls4ml.backends.oneapi.oneapi_template import StreamFunctionCallTemplate, TaskSequenceTemplate +from hls4ml.backends.altera.altera_template import StreamFunctionCallTemplate, TaskSequenceTemplate from hls4ml.backends.template import FunctionCallTemplate, LayerConfigTemplate from hls4ml.model.layers import GlobalPooling1D, GlobalPooling2D, Pooling1D, Pooling2D @@ -120,7 +120,7 @@ def __init__(self): def format(self, node): params = self._default_function_params(node) if node.get_attr('data_format') == 'channels_first': - raise Exception('channels_first not supported for oneAPI') + raise Exception('channels_first not supported for Altera') params['data_format'] = 'cl' return self.templates[node.class_name].format(**params) @@ -138,7 +138,7 @@ def __init__(self): def format(self, node): params = self._default_function_params(node) if node.get_attr('data_format') == 'channels_first': - raise Exception('channels_first not supported for oneAPI') + raise Exception('channels_first not supported for Altera') params['data_format'] = 'cl' return self.templates[node.class_name].format(**params) diff --git a/hls4ml/backends/oneapi/passes/quantization_templates.py b/hls4ml/backends/altera/passes/quantization_templates.py similarity index 91% rename from hls4ml/backends/oneapi/passes/quantization_templates.py rename to hls4ml/backends/altera/passes/quantization_templates.py index c46e174852..857cc6059b 100644 --- a/hls4ml/backends/oneapi/passes/quantization_templates.py +++ b/hls4ml/backends/altera/passes/quantization_templates.py @@ -1,12 +1,12 @@ -from hls4ml.backends.backend import get_backend -from hls4ml.backends.oneapi.oneapi_template import StreamFunctionCallTemplate, TaskSequenceTemplate -from hls4ml.backends.oneapi.passes.core_templates import ( +from hls4ml.backends.altera.altera_template import StreamFunctionCallTemplate, TaskSequenceTemplate +from hls4ml.backends.altera.passes.core_templates import ( batchnorm_config_template, batchnorm_function_template, batchnorm_include_list, batchnorm_stream_function_template, batchnorm_task_sequence_template, ) +from hls4ml.backends.backend import get_backend from hls4ml.backends.template import FunctionCallTemplate, LayerConfigTemplate from hls4ml.model.optimizer.passes.qkeras import ApplyAlpha @@ -19,7 +19,7 @@ def __init__(self): def format(self, node): params = self._default_config_params(node) params['n_in'] = node.get_input_variable().size_cpp() - params['product_type'] = get_backend('oneAPI').product_type( + params['product_type'] = get_backend('Altera').product_type( node.get_input_variable().type.precision, node.get_weights('scale').type.precision ) diff --git a/hls4ml/backends/oneapi/passes/recurrent_templates.py b/hls4ml/backends/altera/passes/recurrent_templates.py similarity index 99% rename from hls4ml/backends/oneapi/passes/recurrent_templates.py rename to hls4ml/backends/altera/passes/recurrent_templates.py index 0799de5b61..b42ac25c5a 100644 --- a/hls4ml/backends/oneapi/passes/recurrent_templates.py +++ b/hls4ml/backends/altera/passes/recurrent_templates.py @@ -1,5 +1,5 @@ +from hls4ml.backends.altera.altera_template import StreamFunctionCallTemplate, TaskSequenceTemplate from hls4ml.backends.backend import get_backend -from hls4ml.backends.oneapi.oneapi_template import StreamFunctionCallTemplate, TaskSequenceTemplate from hls4ml.backends.template import FunctionCallTemplate, LayerConfigTemplate from hls4ml.model.layers import GRU, LSTM, SimpleRNN @@ -145,7 +145,7 @@ def format(self, node): mult_params_x = self._default_config_params(node) mult_params_x['n_in'] = node.get_attr('n_in') mult_params_x['n_out'] = str(node.get_attr('n_out')) + ' * 3' - mult_params_x['product_type'] = get_backend('oneAPI').product_type( + mult_params_x['product_type'] = get_backend('Altera').product_type( node.get_input_variable().type.precision, node.get_weights('weight').type.precision ) mult_params_x['index'] = str(node.index) + '_x' @@ -156,7 +156,7 @@ def format(self, node): mult_params_h['n_in'] = node.get_attr('n_out') mult_params_h['n_out'] = str(node.get_attr('n_out')) + ' * 3' mult_params_h['reuse_factor'] = params['recurrent_reuse_factor'] - mult_params_h['product_type'] = get_backend('oneAPI').product_type( + mult_params_h['product_type'] = get_backend('Altera').product_type( node.get_input_variable().type.precision, node.get_weights('recurrent_weight').type.precision ) mult_params_h['index'] = str(node.index) + '_h' diff --git a/hls4ml/backends/oneapi/passes/reshaping_templates.py b/hls4ml/backends/altera/passes/reshaping_templates.py similarity index 98% rename from hls4ml/backends/oneapi/passes/reshaping_templates.py rename to hls4ml/backends/altera/passes/reshaping_templates.py index 0f07584440..3d8a71b54d 100644 --- a/hls4ml/backends/oneapi/passes/reshaping_templates.py +++ b/hls4ml/backends/altera/passes/reshaping_templates.py @@ -1,6 +1,6 @@ import numpy as np -from hls4ml.backends.oneapi.oneapi_template import StreamFunctionCallTemplate, TaskSequenceTemplate +from hls4ml.backends.altera.altera_template import StreamFunctionCallTemplate, TaskSequenceTemplate from hls4ml.backends.template import FunctionCallTemplate, LayerConfigTemplate from hls4ml.model.layers import Reshape, Resize, Transpose, ZeroPadding1D, ZeroPadding2D from hls4ml.utils.transpose_utils import transpose_config_gen @@ -68,7 +68,7 @@ def __init__(self): def format(self, node): params = self._default_function_params(node) if node.get_attr('data_format') == 'channels_first': - raise Exception('oneAPI only supports channels_last data format') + raise Exception('Altera only supports channels_last data format') params['data_format'] = 'cl' return self.templates[node.class_name].format(**params) @@ -85,7 +85,7 @@ def __init__(self): def format(self, node): params = self._default_function_params(node) if node.get_attr('data_format') == 'channels_first': - raise RuntimeError('channels_first not supported on oneAPI') + raise RuntimeError('channels_first not supported on Altera') params['data_format'] = 'cl' return self.templates[node.class_name].format(**params) diff --git a/hls4ml/backends/oneapi/passes/resource_strategy.py b/hls4ml/backends/altera/passes/resource_strategy.py similarity index 98% rename from hls4ml/backends/oneapi/passes/resource_strategy.py rename to hls4ml/backends/altera/passes/resource_strategy.py index 2d45410706..96c4dd5738 100644 --- a/hls4ml/backends/oneapi/passes/resource_strategy.py +++ b/hls4ml/backends/altera/passes/resource_strategy.py @@ -10,7 +10,7 @@ class ApplyResourceStrategy(OptimizerPass): def match(self, node): node_matches = isinstance(node, (Dense, Conv1D, Conv2D, GRU, LSTM, SimpleRNN)) is_resource_strategy = ( - True # node.get_attr('strategy', '').lower() == 'resource' -> oneAPI only supportr Resource strategy + True # node.get_attr('strategy', '').lower() == 'resource' -> Altera only supportr Resource strategy ) already_transformed = node.get_attr('_weights_transposed', False) is True return node_matches and is_resource_strategy and not already_transformed diff --git a/hls4ml/backends/oneapi/passes/transform_types.py b/hls4ml/backends/altera/passes/transform_types.py similarity index 74% rename from hls4ml/backends/oneapi/passes/transform_types.py rename to hls4ml/backends/altera/passes/transform_types.py index 40e748d276..bb4e05f64a 100644 --- a/hls4ml/backends/oneapi/passes/transform_types.py +++ b/hls4ml/backends/altera/passes/transform_types.py @@ -1,12 +1,12 @@ -from hls4ml.backends.oneapi.oneapi_types import ( - OneAPIACTypeConverter, - OneAPIArrayVariableConverter, - OneAPIHLSTypeConverter, - OneAPIInplaceArrayVariableConverter, - OneAPIInplaceStreamVariableConverter, - OneAPIInterfaceVariableConverter, - OneAPIStaticWeightVariableConverter, - OneAPIStreamVariableConverter, +from hls4ml.backends.altera.altera_types import ( + AlteraACTypeConverter, + AlteraArrayVariableConverter, + AlteraHLSTypeConverter, + AlteraInplaceArrayVariableConverter, + AlteraInplaceStreamVariableConverter, + AlteraInterfaceVariableConverter, + AlteraStaticWeightVariableConverter, + AlteraStreamVariableConverter, ) from hls4ml.model.optimizer import GlobalOptimizerPass from hls4ml.model.types import InplaceTensorVariable @@ -16,13 +16,13 @@ class TransformTypes(GlobalOptimizerPass): def __init__(self): - self.type_converter = OneAPIHLSTypeConverter(precision_converter=OneAPIACTypeConverter()) - self.array_var_converter = OneAPIArrayVariableConverter(type_converter=self.type_converter) - self.inplace_array_var_converter = OneAPIInplaceArrayVariableConverter(type_converter=self.type_converter) - self.interface_var_converter = OneAPIInterfaceVariableConverter(type_converter=self.type_converter) - self.stream_var_converter = OneAPIStreamVariableConverter(type_converter=self.type_converter) - self.inplace_stream_var_converter = OneAPIInplaceStreamVariableConverter(type_converter=self.type_converter) - self.weight_var_converter = OneAPIStaticWeightVariableConverter(type_converter=self.type_converter) + self.type_converter = AlteraHLSTypeConverter(precision_converter=AlteraACTypeConverter()) + self.array_var_converter = AlteraArrayVariableConverter(type_converter=self.type_converter) + self.inplace_array_var_converter = AlteraInplaceArrayVariableConverter(type_converter=self.type_converter) + self.interface_var_converter = AlteraInterfaceVariableConverter(type_converter=self.type_converter) + self.stream_var_converter = AlteraStreamVariableConverter(type_converter=self.type_converter) + self.inplace_stream_var_converter = AlteraInplaceStreamVariableConverter(type_converter=self.type_converter) + self.weight_var_converter = AlteraStaticWeightVariableConverter(type_converter=self.type_converter) def transform(self, model, node): io_type = node.model.config.get_config_value('IOType') diff --git a/hls4ml/backends/fpga/fpga_types.py b/hls4ml/backends/fpga/fpga_types.py index 0523873903..ca24610447 100644 --- a/hls4ml/backends/fpga/fpga_types.py +++ b/hls4ml/backends/fpga/fpga_types.py @@ -97,8 +97,8 @@ def definition_cpp(self): self.saturation_bits, ] if args[0] == 1: - # Currently oneAPI ac_fixed requires at least two bits for both signed and unsigned cases - # Should be fixed in the future once oneAPI supports 1-bit unsigned ac_fixed + # Currently Altera ac_fixed requires at least two bits for both signed and unsigned cases + # Should be fixed in the future once Altera supports 1-bit unsigned ac_fixed args[0] = 2 if args[3] == 'AC_TRN' and args[4] == 'AC_WRAP': # This is the default, so we won't write the full definition for brevity diff --git a/hls4ml/backends/fpga/passes/hgq_proxy_model.py b/hls4ml/backends/fpga/passes/hgq_proxy_model.py index a8135f655a..e37e838d7d 100644 --- a/hls4ml/backends/fpga/passes/hgq_proxy_model.py +++ b/hls4ml/backends/fpga/passes/hgq_proxy_model.py @@ -16,8 +16,8 @@ def to_apfixed(k, b, i, RND, SAT): def to_acfixed(k, b, i, RND, SAT): k = 'false' if k == 0 else 'true' if b == 1: - # Currently oneAPI ac_fixed requires at least two bits for both signed and unsigned cases - # Should be fixed in the future once oneAPI supports 1-bit unsigned ac_fixed + # Currently Altera ac_fixed requires at least two bits for both signed and unsigned cases + # Should be fixed in the future once Altera supports 1-bit unsigned ac_fixed b = 2 return f'ac_fixed<{b},{i},{k},AC_{RND},AC_{SAT}>' @@ -27,12 +27,12 @@ def generate_mask_fn( ) -> str: """Generate heterogenous quantization mask function, ONLY works for IOType=io_parallel""" assert k.shape[0] == b.shape[0] == i.shape[0] == 1 - assert backend.lower() in ('oneapi', 'quartus', 'vivado', 'vitis'), f'Backend {backend} not tested' + assert backend.lower() in ('altera', 'quartus', 'vivado', 'vitis'), f'Backend {backend} not tested' Ks, Bs, Is = k[0], b[0], i[0] Ks, Bs, Is = np.broadcast_to(Ks, shape), np.broadcast_to(Bs, shape), np.broadcast_to(Is, shape) Ks, Bs, Is = Ks.ravel(), Bs.ravel(), Is.ravel() masks = [] - to_fixed = to_acfixed if backend.lower() in ['oneapi', 'quartus'] else to_apfixed + to_fixed = to_acfixed if backend.lower() in ['altera', 'quartus'] else to_apfixed for idx, (k, b, i) in enumerate(zip(Ks, Bs, Is)): if b == 0: fn = f'out[{idx}] = 0;' @@ -41,12 +41,12 @@ def generate_mask_fn( masks.append(f' {fn}') body = '\n'.join(masks) arguments = ( - 'input_t *inp, output_t *out' if backend.lower() not in ['oneapi', 'quartus'] else 'input_t &inp, output_t &out' + 'input_t *inp, output_t *out' if backend.lower() not in ['altera', 'quartus'] else 'input_t &inp, output_t &out' ) mask_fn = f""" template void {name}({arguments}) {{ - {'#pragma HLS INLINE' if backend.lower() not in ['oneapi', 'quartus'] else ''} + {'#pragma HLS INLINE' if backend.lower() not in ['altera', 'quartus'] else ''} {body} }} diff --git a/hls4ml/backends/vivado/passes/distributed_arithmetic.py b/hls4ml/backends/vivado/passes/distributed_arithmetic.py index d8672104de..3d99cd60fc 100644 --- a/hls4ml/backends/vivado/passes/distributed_arithmetic.py +++ b/hls4ml/backends/vivado/passes/distributed_arithmetic.py @@ -438,7 +438,7 @@ def transform(self, model: 'ModelGraph', node: DACombinational): backend = model.config.get_config_value('Backend').lower() if backend in ('vitis', 'vivado'): flavor = 'vitis' - elif backend == 'oneapi': + elif backend == 'altera': flavor = 'oneapi' else: raise ValueError(f'Unsupported backend {backend} for DACombinational layer.') diff --git a/hls4ml/report/__init__.py b/hls4ml/report/__init__.py index 4d3641a5ac..05f3b2d7d6 100644 --- a/hls4ml/report/__init__.py +++ b/hls4ml/report/__init__.py @@ -1,13 +1,13 @@ +from hls4ml.report.altera_report import ( + parse_altera_report, # noqa: F401 + print_altera_report, # noqa: F401 +) from hls4ml.report.catapult_report import ( parse_catapult_report, # noqa: F401 qofr, # noqa: F401 read_catapult_report, # noqa: F401 ) from hls4ml.report.libero_report import parse_libero_report # noqa: F401 -from hls4ml.report.oneapi_report import ( - parse_oneapi_report, # noqa: F401 - print_oneapi_report, # noqa: F401 -) from hls4ml.report.quartus_report import ( parse_quartus_report, # noqa: F401 read_quartus_report, # noqa: F401 diff --git a/hls4ml/report/oneapi_report.py b/hls4ml/report/altera_report.py similarity index 97% rename from hls4ml/report/oneapi_report.py rename to hls4ml/report/altera_report.py index fc62f0f15a..fcfbff6ed4 100644 --- a/hls4ml/report/oneapi_report.py +++ b/hls4ml/report/altera_report.py @@ -4,7 +4,7 @@ import re -def _convert_to_oneapi_naming(s): +def _convert_to_altera_naming(s): s2 = s.lower() # Capitalize the first letter @@ -54,7 +54,7 @@ def _parse_single_report(prjDir): # PathSimDataJson = PathJson + 'simulation_raw.ndjson' targetName, makeType, _ = os.path.basename(prjDir).rsplit('.', 2) - simTask = _convert_to_oneapi_naming(targetName) + simTask = _convert_to_altera_naming(targetName) # if targetName not in report: # report[targetName] = {} @@ -137,9 +137,9 @@ def _parse_single_report(prjDir): return report -def parse_oneapi_report(hls_dir): +def parse_altera_report(hls_dir): """ - Parse a report from a given oneAPI project as a dictionary. + Parse a report from a given Altera project as a dictionary. Args: hls_dir (string): The directory where the project is found @@ -159,9 +159,9 @@ def parse_oneapi_report(hls_dir): return report -def print_oneapi_report(report_dict): +def print_altera_report(report_dict): """ - Prints the oneAPI report dictionary as a table. + Prints the Altera report dictionary as a table. Args: report_dict (dictionary): The report dictionary, containing latency, resource usage etc. diff --git a/hls4ml/templates/oneapi/CMakeLists.txt b/hls4ml/templates/altera/CMakeLists.txt similarity index 100% rename from hls4ml/templates/oneapi/CMakeLists.txt rename to hls4ml/templates/altera/CMakeLists.txt diff --git a/hls4ml/templates/oneapi/exception_handler.hpp b/hls4ml/templates/altera/exception_handler.hpp similarity index 100% rename from hls4ml/templates/oneapi/exception_handler.hpp rename to hls4ml/templates/altera/exception_handler.hpp diff --git a/hls4ml/templates/oneapi/firmware/defines.h b/hls4ml/templates/altera/firmware/defines.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/defines.h rename to hls4ml/templates/altera/firmware/defines.h diff --git a/hls4ml/templates/oneapi/firmware/myproject.cpp b/hls4ml/templates/altera/firmware/myproject.cpp similarity index 100% rename from hls4ml/templates/oneapi/firmware/myproject.cpp rename to hls4ml/templates/altera/firmware/myproject.cpp diff --git a/hls4ml/templates/oneapi/firmware/myproject.h b/hls4ml/templates/altera/firmware/myproject.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/myproject.h rename to hls4ml/templates/altera/firmware/myproject.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_activation.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_activation.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_activation.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_activation.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_activation_stream.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_activation_stream.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_activation_stream.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_activation_stream.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_batchnorm.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_batchnorm.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_batchnorm.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_batchnorm.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_batchnorm_stream.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_batchnorm_stream.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_batchnorm_stream.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_batchnorm_stream.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_code_gen.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_code_gen.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_code_gen.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_code_gen.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_common.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_common.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_conv1d.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_conv1d.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_conv1d.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_conv1d.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_conv1d_resource.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_conv1d_resource.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_conv1d_resource.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_conv1d_resource.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_conv1d_stream.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_conv1d_stream.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_conv1d_stream.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_conv1d_stream.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_conv2d.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_conv2d.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_conv2d.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_conv2d.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_conv2d_resource.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_conv2d_resource.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_conv2d_resource.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_conv2d_resource.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_conv2d_stream.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_conv2d_stream.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_conv2d_stream.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_conv2d_stream.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_dense.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_dense.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_dense.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_dense.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_dense_stream.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_dense_stream.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_dense_stream.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_dense_stream.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_depthconv1d.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_depthconv1d.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_depthconv1d.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_depthconv1d.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_depthconv1d_resource.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_depthconv1d_resource.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_depthconv1d_resource.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_depthconv1d_resource.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_depthconv2d.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_depthconv2d.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_depthconv2d.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_depthconv2d.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_depthconv2d_resource.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_depthconv2d_resource.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_depthconv2d_resource.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_depthconv2d_resource.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_einsum.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_einsum.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_einsum.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_einsum.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_einsum_dense.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_einsum_dense.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_einsum_dense.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_einsum_dense.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_embed.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_embed.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_embed.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_embed.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_embed_stream.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_embed_stream.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_embed_stream.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_embed_stream.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_helpers.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_helpers.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_helpers.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_helpers.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_merge.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_merge.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_merge.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_merge.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_merge_stream.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_merge_stream.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_merge_stream.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_merge_stream.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_mult.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_mult.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_mult.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_mult.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_padding.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_padding.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_padding.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_padding.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_padding_stream.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_padding_stream.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_padding_stream.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_padding_stream.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_pooling.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_pooling.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_pooling.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_pooling.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_pooling_stream.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_pooling_stream.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_pooling_stream.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_pooling_stream.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_printf.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_printf.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_printf.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_printf.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_recurrent.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_recurrent.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_recurrent.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_recurrent.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_recurrent_activation.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_recurrent_activation.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_recurrent_activation.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_recurrent_activation.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_recurrent_stream.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_recurrent_stream.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_recurrent_stream.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_recurrent_stream.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_resize.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_resize.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_resize.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_resize.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_resize_stream.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_resize_stream.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_resize_stream.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_resize_stream.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_stream.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_stream.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_stream.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_stream.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_transpose.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_transpose.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_transpose.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_transpose.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_transpose_stream.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_transpose_stream.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_transpose_stream.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_transpose_stream.h diff --git a/hls4ml/templates/oneapi/firmware/nnet_utils/nnet_types.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_types.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/nnet_utils/nnet_types.h rename to hls4ml/templates/altera/firmware/nnet_utils/nnet_types.h diff --git a/hls4ml/templates/oneapi/firmware/parameters.h b/hls4ml/templates/altera/firmware/parameters.h similarity index 100% rename from hls4ml/templates/oneapi/firmware/parameters.h rename to hls4ml/templates/altera/firmware/parameters.h diff --git a/hls4ml/templates/oneapi/myproject_bridge.cpp b/hls4ml/templates/altera/myproject_bridge.cpp similarity index 100% rename from hls4ml/templates/oneapi/myproject_bridge.cpp rename to hls4ml/templates/altera/myproject_bridge.cpp diff --git a/hls4ml/templates/oneapi/myproject_test.cpp b/hls4ml/templates/altera/myproject_test.cpp similarity index 100% rename from hls4ml/templates/oneapi/myproject_test.cpp rename to hls4ml/templates/altera/myproject_test.cpp diff --git a/hls4ml/writer/__init__.py b/hls4ml/writer/__init__.py index 49a9aceb80..46fbd43e60 100644 --- a/hls4ml/writer/__init__.py +++ b/hls4ml/writer/__init__.py @@ -1,7 +1,7 @@ +from hls4ml.writer.altera_writer import AlteraWriter from hls4ml.writer.catapult_writer import CatapultWriter from hls4ml.writer.coyote_writer import CoyoteWriter from hls4ml.writer.libero_writer import LiberoWriter -from hls4ml.writer.oneapi_writer import OneAPIWriter from hls4ml.writer.quartus_writer import QuartusWriter from hls4ml.writer.symbolic_writer import SymbolicExpressionWriter from hls4ml.writer.vitis_writer import VitisWriter @@ -14,7 +14,7 @@ register_writer('VivadoAccelerator', VivadoAcceleratorWriter) register_writer('Vitis', VitisWriter) register_writer('Quartus', QuartusWriter) -register_writer('oneAPI', OneAPIWriter) +register_writer('Altera', AlteraWriter) register_writer('Catapult', CatapultWriter) register_writer('Libero', LiberoWriter) register_writer('SymbolicExpression', SymbolicExpressionWriter) diff --git a/hls4ml/writer/oneapi_writer.py b/hls4ml/writer/altera_writer.py similarity index 98% rename from hls4ml/writer/oneapi_writer.py rename to hls4ml/writer/altera_writer.py index 3c0a778c50..d923167b14 100644 --- a/hls4ml/writer/oneapi_writer.py +++ b/hls4ml/writer/altera_writer.py @@ -15,7 +15,7 @@ config_filename = 'hls4ml_config.yml' -class OneAPIWriter(Writer): +class AlteraWriter(Writer): def __make_dat_file(self, original_path, project_path): """ Convert other input/output data types into a dat file, which is @@ -102,7 +102,7 @@ def write_project_cpp(self, model): filedir = os.path.dirname(os.path.abspath(__file__)) with ( - open(os.path.join(filedir, '../templates/oneapi/firmware/myproject.cpp')) as f, + open(os.path.join(filedir, '../templates/altera/firmware/myproject.cpp')) as f, open(f'{model.config.get_output_dir()}/src/firmware/{project_name}.cpp', 'w') as fout, ): model_inputs = model.get_input_variables() @@ -122,7 +122,7 @@ def write_project_cpp(self, model): elif 'MyProject' in line: newline = line.replace('MyProject', convert_to_pascal_case(project_name)) - # oneAPI pipes need to be declared and passed as template parameters + # Altera pipes need to be declared and passed as template parameters elif '// hls-fpga-machine-learning insert inter-task pipes' in line: newline = line if io_type == 'io_stream': @@ -208,7 +208,7 @@ def write_project_header(self, model): filedir = os.path.dirname(os.path.abspath(__file__)) with ( - open(os.path.join(filedir, '../templates/oneapi/firmware/myproject.h')) as f, + open(os.path.join(filedir, '../templates/altera/firmware/myproject.h')) as f, open(f'{model.config.get_output_dir()}/src/firmware/{project_name}.h', 'w') as fout, ): model_inputs = model.get_input_variables() @@ -256,7 +256,7 @@ def write_defines(self, model): """ filedir = os.path.dirname(os.path.abspath(__file__)) with ( - open(os.path.join(filedir, '../templates/oneapi/firmware/defines.h')) as f, + open(os.path.join(filedir, '../templates/altera/firmware/defines.h')) as f, open(f'{model.config.get_output_dir()}/src/firmware/defines.h', 'w') as fout, ): for line in f.readlines(): @@ -285,7 +285,7 @@ def write_parameters(self, model): """ filedir = os.path.dirname(os.path.abspath(__file__)) with ( - open(os.path.join(filedir, '../templates/oneapi/firmware/parameters.h')) as f, + open(os.path.join(filedir, '../templates/altera/firmware/parameters.h')) as f, open(f'{model.config.get_output_dir()}/src/firmware/parameters.h', 'w') as fout, ): for line in f.readlines(): @@ -327,7 +327,7 @@ def write_test_bench(self, model): # copy the exception handler filedir = os.path.dirname(os.path.abspath(__file__)) - srcpath = os.path.join(filedir, '../templates/oneapi/exception_handler.hpp') + srcpath = os.path.join(filedir, '../templates/altera/exception_handler.hpp') dstpath = f'{model.config.get_output_dir()}/src/exception_handler.hpp' copyfile(srcpath, dstpath) @@ -364,7 +364,7 @@ def write_test_bench(self, model): ) with ( - open(os.path.join(filedir, '../templates/oneapi/myproject_test.cpp')) as f, + open(os.path.join(filedir, '../templates/altera/myproject_test.cpp')) as f, open(f'{model.config.get_output_dir()}/src/{project_name}_test.cpp', 'w') as fout, ): for line in f.readlines(): @@ -423,7 +423,7 @@ def write_bridge(self, model): filedir = os.path.dirname(os.path.abspath(__file__)) with ( - open(os.path.join(filedir, '../templates/oneapi/myproject_bridge.cpp')) as f, + open(os.path.join(filedir, '../templates/altera/myproject_bridge.cpp')) as f, open(f'{model.config.get_output_dir()}/src/{project_name}_bridge.cpp', 'w') as fout, ): for line in f.readlines(): @@ -503,7 +503,7 @@ def write_build_script(self, model): period = model.config.get_config_value('ClockPeriod') hyper = model.config.get_config_value('HyperoptHandshake') with ( - open(os.path.join(filedir, '../templates/oneapi/CMakeLists.txt')) as f, + open(os.path.join(filedir, '../templates/altera/CMakeLists.txt')) as f, open(f'{model.config.get_output_dir()}/CMakeLists.txt', 'w') as fout, ): for line in f.readlines(): @@ -530,7 +530,7 @@ def write_nnet_utils(self, model): # nnet_utils filedir = os.path.dirname(os.path.abspath(__file__)) - srcpath = os.path.join(filedir, '../templates/oneapi/firmware/nnet_utils/') + srcpath = os.path.join(filedir, '../templates/altera/firmware/nnet_utils/') dstpath = f'{model.config.get_output_dir()}/src/firmware/nnet_utils/' if not os.path.exists(dstpath): @@ -544,7 +544,7 @@ def write_nnet_utils(self, model): # custom source filedir = os.path.dirname(os.path.abspath(__file__)) - custom_source = get_backend('oneAPI').get_custom_source() + custom_source = get_backend('Altera').get_custom_source() for dst, srcpath in custom_source.items(): dstpath = f'{model.config.get_output_dir()}/src/firmware/{dst}' copyfile(srcpath, dstpath) diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_parallel-oneAPI-elu.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_parallel-Altera-elu.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_parallel-oneAPI-elu.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_parallel-Altera-elu.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_parallel-oneAPI-leaky_relu.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_parallel-Altera-leaky_relu.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_parallel-oneAPI-leaky_relu.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_parallel-Altera-leaky_relu.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_parallel-oneAPI-prelu.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_parallel-Altera-prelu.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_parallel-oneAPI-prelu.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_parallel-Altera-prelu.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_parallel-oneAPI-relu.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_parallel-Altera-relu.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_parallel-oneAPI-relu.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_parallel-Altera-relu.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_parallel-oneAPI-sigmoid.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_parallel-Altera-sigmoid.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_parallel-oneAPI-sigmoid.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_parallel-Altera-sigmoid.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_stream-oneAPI-elu.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_stream-Altera-elu.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_stream-oneAPI-elu.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_stream-Altera-elu.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_stream-oneAPI-leaky_relu.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_stream-Altera-leaky_relu.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_stream-oneAPI-leaky_relu.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_stream-Altera-leaky_relu.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_stream-oneAPI-prelu.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_stream-Altera-prelu.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_stream-oneAPI-prelu.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_stream-Altera-prelu.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_stream-oneAPI-relu.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_stream-Altera-relu.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_stream-oneAPI-relu.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_stream-Altera-relu.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_stream-oneAPI-sigmoid.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_stream-Altera-sigmoid.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_activations_io_stream-oneAPI-sigmoid.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_activations_io_stream-Altera-sigmoid.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_conv2d_io_parallel-oneAPI-Resource-same-channels_last.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_conv2d_io_parallel-Altera-Resource-same-channels_last.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_conv2d_io_parallel-oneAPI-Resource-same-channels_last.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_conv2d_io_parallel-Altera-Resource-same-channels_last.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_dense_io_parallel-oneAPI.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_dense_io_parallel-Altera.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_dense_io_parallel-oneAPI.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_dense_io_parallel-Altera.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_dense_io_stream-oneAPI.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_dense_io_stream-Altera.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_dense_io_stream-oneAPI.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_dense_io_stream-Altera.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-same-AveragePooling1D.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-same-AveragePooling1D.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-same-AveragePooling1D.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-same-AveragePooling1D.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-same-AveragePooling2D.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-same-AveragePooling2D.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-same-AveragePooling2D.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-same-AveragePooling2D.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-same-MaxPooling1D.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-same-MaxPooling1D.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-same-MaxPooling1D.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-same-MaxPooling1D.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-same-MaxPooling2D.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-same-MaxPooling2D.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-same-MaxPooling2D.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-same-MaxPooling2D.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-valid-AveragePooling1D.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-valid-AveragePooling1D.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-valid-AveragePooling1D.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-valid-AveragePooling1D.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-valid-AveragePooling2D.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-valid-AveragePooling2D.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-valid-AveragePooling2D.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-valid-AveragePooling2D.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-valid-MaxPooling1D.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-valid-MaxPooling1D.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-valid-MaxPooling1D.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-valid-MaxPooling1D.json diff --git a/test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-valid-MaxPooling2D.json b/test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-valid-MaxPooling2D.json similarity index 100% rename from test/pytest/baselines/oneAPI/2025.0.1/test_keras_api_test_pooling_oneAPI-channels_last-valid-MaxPooling2D.json rename to test/pytest/baselines/Altera/2025.0.1/test_keras_api_test_pooling_Altera-channels_last-valid-MaxPooling2D.json diff --git a/test/pytest/ci-template.yml b/test/pytest/ci-template.yml index 4b58559cd9..570bebb2e4 100644 --- a/test/pytest/ci-template.yml +++ b/test/pytest/ci-template.yml @@ -28,7 +28,7 @@ - chmod +x cmd_vitis_${VITIS_VERSION}/vitis-run - export PATH=$PWD/cmd_vitis_${VITIS_VERSION}:$PATH - # Load Intel oneAPI environment variables + # Load Intel oneAPI environment variables for the Altera backend - source /opt/intel/oneapi/setvars.sh --force script: - cd test/pytest diff --git a/test/pytest/conftest.py b/test/pytest/conftest.py index 7841a1a989..536cc22b23 100644 --- a/test/pytest/conftest.py +++ b/test/pytest/conftest.py @@ -58,12 +58,12 @@ def synthesis_config(): 'Vivado': os.getenv('VIVADO_VERSION', '2020.1'), 'Vitis': os.getenv('VITIS_VERSION', '2024.1'), 'Quartus': os.getenv('QUARTUS_VERSION', 'latest'), - 'oneAPI': os.getenv('ONEAPI_VERSION', '2025.0.1'), + 'Altera': os.getenv('ONEAPI_VERSION', '2025.0.1'), }, 'build_args': { 'Vivado': {'csim': False, 'synth': True, 'export': False}, 'Vitis': {'csim': False, 'synth': True, 'export': False}, 'Quartus': {'synth': True, 'fpgasynth': False}, - 'oneAPI': {'build_type': 'report', 'run': False}, + 'Altera': {'build_type': 'report', 'run': False}, }, } diff --git a/test/pytest/synthesis_helpers.py b/test/pytest/synthesis_helpers.py index 5d3a7989ea..e660974402 100644 --- a/test/pytest/synthesis_helpers.py +++ b/test/pytest/synthesis_helpers.py @@ -92,9 +92,9 @@ def compare_vitis_backend(data, baseline): compare_dicts(data['CSynthesisReport'], baseline['CSynthesisReport'], tolerances) -def compare_oneapi_backend(data, baseline): +def compare_altera_backend(data, baseline): """ - Compare reports from the oneAPI backend. + Compare reports from the Altera backend. Args: data (dict): The current synthesis report. @@ -120,14 +120,14 @@ def compare_oneapi_backend(data, baseline): COMPARE_FUNCS = { 'Vivado': compare_vitis_backend, 'Vitis': compare_vitis_backend, - 'oneAPI': compare_oneapi_backend, + 'Altera': compare_altera_backend, } EXPECTED_REPORT_KEYS = { 'Vivado': {'CSynthesisReport'}, 'Vitis': {'CSynthesisReport'}, - 'oneAPI': {'report'}, + 'Altera': {'report'}, } diff --git a/test/pytest/test_activations.py b/test/pytest/test_activations.py index 7442757ac0..fe66c0dda5 100644 --- a/test/pytest/test_activations.py +++ b/test/pytest/test_activations.py @@ -13,7 +13,7 @@ # Variable 'name' is simply used as an identifier for the activation -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Catapult', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Catapult', 'Quartus', 'Altera', 'XLS']) @pytest.mark.parametrize('shape, io_type', [((8,), 'io_parallel'), ((8,), 'io_stream'), ((8, 8, 3), 'io_stream')]) @pytest.mark.parametrize( 'activation, name', diff --git a/test/pytest/test_batchnorm.py b/test/pytest/test_batchnorm.py index 8b15e48a57..c92fea647e 100644 --- a/test/pytest/test_batchnorm.py +++ b/test/pytest/test_batchnorm.py @@ -29,7 +29,7 @@ def model(request): @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'Altera']) @pytest.mark.parametrize('model', [True, False], indirect=True) def test_batchnorm(test_case_id, model, data, backend, io_type): default_precision = 'fixed<32, 1>' diff --git a/test/pytest/test_bit_exact_grouped_conv.py b/test/pytest/test_bit_exact_grouped_conv.py index e84b4ee6e8..4a069761b7 100644 --- a/test/pytest/test_bit_exact_grouped_conv.py +++ b/test/pytest/test_bit_exact_grouped_conv.py @@ -48,7 +48,7 @@ def _find(hls_model, cls, name): return next(node for node in hls_model.graph.values() if isinstance(node, cls) and node.name == name) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera']) @pytest.mark.parametrize('n_chan, groups', [(16, 16), (16, 4), (16, 1)], ids=['depthwise', 'grouped', 'dense']) def test_bit_exact_grouped_conv1d(test_case_id, backend, n_chan, groups): with QuantizerConfigScope(f0=4, i0=4): @@ -60,7 +60,7 @@ def test_bit_exact_grouped_conv1d(test_case_id, backend, n_chan, groups): data = np.random.default_rng(0).standard_normal((1000, 16, n_chan)).astype(np.float32) r_keras = trace_minmax(model, data, return_results=True) - precision = 'ac_fixed<2,0>' if backend == 'oneAPI' else 'ap_fixed<1,0>' + precision = 'ac_fixed<2,0>' if backend == 'Altera' else 'ap_fixed<1,0>' hls_config = {'Model': {'Precision': precision, 'ReuseFactor': 1, 'Strategy': 'latency'}} output_dir = str(test_root_path / test_case_id) hls_model = convert_from_keras_model( @@ -70,12 +70,12 @@ def test_bit_exact_grouped_conv1d(test_case_id, backend, n_chan, groups): conv = _find(hls_model, Conv1D, 'cg') _assert_exactly_representable(r_keras, *_result_kif(conv)) - # Per-channel check; skipped for oneAPI, which transposes conv weights after the pass. - if backend != 'oneAPI': + # Per-channel check; skipped for Altera, which transposes conv weights after the pass. + if backend != 'Altera': _assert_exactly_representable(r_keras, *produce_kif(conv)) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera']) @pytest.mark.parametrize('n_chan, groups', [(4, 4), (4, 2), (4, 1)], ids=['depthwise', 'grouped', 'dense']) def test_bit_exact_grouped_conv2d(test_case_id, backend, n_chan, groups): with QuantizerConfigScope(f0=4, i0=4): @@ -87,7 +87,7 @@ def test_bit_exact_grouped_conv2d(test_case_id, backend, n_chan, groups): data = np.random.default_rng(1).standard_normal((500, 8, 8, n_chan)).astype(np.float32) r_keras = trace_minmax(model, data, return_results=True) - precision = 'ac_fixed<2,0>' if backend == 'oneAPI' else 'ap_fixed<1,0>' + precision = 'ac_fixed<2,0>' if backend == 'Altera' else 'ap_fixed<1,0>' hls_config = {'Model': {'Precision': precision, 'ReuseFactor': 1, 'Strategy': 'latency'}} output_dir = str(test_root_path / test_case_id) hls_model = convert_from_keras_model( @@ -96,5 +96,5 @@ def test_bit_exact_grouped_conv2d(test_case_id, backend, n_chan, groups): conv = _find(hls_model, Conv2D, 'cg') _assert_exactly_representable(r_keras, *_result_kif(conv)) - if backend != 'oneAPI': + if backend != 'Altera': _assert_exactly_representable(r_keras, *produce_kif(conv)) diff --git a/test/pytest/test_bit_exact_zeropadding.py b/test/pytest/test_bit_exact_zeropadding.py index bd872f399d..8293151ea2 100644 --- a/test/pytest/test_bit_exact_zeropadding.py +++ b/test/pytest/test_bit_exact_zeropadding.py @@ -26,7 +26,7 @@ test_root_path = Path(__file__).parent -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel']) def test_bit_exact_zeropadding1d(test_case_id, backend, io_type): """ZeroPadding1D between two quantized Conv1D layers must convert via the @@ -41,7 +41,7 @@ def test_bit_exact_zeropadding1d(test_case_id, backend, io_type): data = np.random.default_rng(0).standard_normal((1000, 16, 8)).astype(np.float32) r_keras = trace_minmax(model, data, return_results=True) - precision = 'ac_fixed<2,0>' if backend == 'oneAPI' else 'ap_fixed<1,0>' + precision = 'ac_fixed<2,0>' if backend == 'Altera' else 'ap_fixed<1,0>' hls_config = {'Model': {'Precision': precision, 'ReuseFactor': 1, 'Strategy': 'latency'}} output_dir = str(test_root_path / test_case_id) hls_model = convert_from_keras_model( @@ -53,7 +53,7 @@ def test_bit_exact_zeropadding1d(test_case_id, backend, io_type): np.testing.assert_array_equal(r_keras, r_hls) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel']) def test_bit_exact_zeropadding2d(test_case_id, backend, io_type): """ZeroPadding2D between two quantized Conv2D layers must convert via the @@ -68,7 +68,7 @@ def test_bit_exact_zeropadding2d(test_case_id, backend, io_type): data = np.random.default_rng(1).standard_normal((500, 8, 8, 4)).astype(np.float32) r_keras = trace_minmax(model, data, return_results=True) - precision = 'ac_fixed<2,0>' if backend == 'oneAPI' else 'ap_fixed<1,0>' + precision = 'ac_fixed<2,0>' if backend == 'Altera' else 'ap_fixed<1,0>' hls_config = {'Model': {'Precision': precision, 'ReuseFactor': 1, 'Strategy': 'latency'}} output_dir = str(test_root_path / test_case_id) hls_model = convert_from_keras_model( diff --git a/test/pytest/test_conv1d.py b/test/pytest/test_conv1d.py index 899e2e6112..baed79be05 100644 --- a/test/pytest/test_conv1d.py +++ b/test/pytest/test_conv1d.py @@ -68,8 +68,8 @@ def hls_model(keras_model, request, test_case_id): [ ('Quartus', 'io_parallel', 'resource'), ('Quartus', 'io_stream', 'resource'), - ('oneAPI', 'io_parallel', 'resource'), - ('oneAPI', 'io_stream', 'resource'), + ('Altera', 'io_parallel', 'resource'), + ('Altera', 'io_stream', 'resource'), ('Vivado', 'io_parallel', 'resource'), ('Vivado', 'io_parallel', 'latency'), ('Vivado', 'io_stream', 'latency'), @@ -85,8 +85,8 @@ def hls_model(keras_model, request, test_case_id): ids=[ 'Quartus_io_parallel_resource', 'Quartus_io_stream_resource', - 'oneAPI_io_parallel_resource', - 'oneAPI_io_stream_resource', + 'Altera_io_parallel_resource', + 'Altera_io_stream_resource', 'Vivado_io_parallel_resource', 'Vivado_io_parallel_latency', 'Vivado_io_stream_latency', diff --git a/test/pytest/test_embed.py b/test/pytest/test_embed.py index 6f733cc399..4601c9d48b 100644 --- a/test/pytest/test_embed.py +++ b/test/pytest/test_embed.py @@ -47,24 +47,24 @@ def hls_model(keras_model, request, test_case_id): ('Vitis', 'io_parallel'), ('Quartus', 'io_parallel'), ('Catapult', 'io_parallel'), - ('oneAPI', 'io_parallel'), + ('Altera', 'io_parallel'), ('Vivado', 'io_stream'), ('Vitis', 'io_stream'), ('Quartus', 'io_stream'), ('Catapult', 'io_stream'), - ('oneAPI', 'io_stream'), + ('Altera', 'io_stream'), ], ids=[ 'vivado_parallel', 'vitis_parallel', 'quartus_parallel', 'catapult_parallel', - 'oneapi_parallel', + 'altera_parallel', 'vivado_stream', 'vitis_stream', 'quartus_stream', 'catapult_stream', - 'oneapi_stream', + 'altera_stream', ], indirect=True, ) diff --git a/test/pytest/test_globalpooling.py b/test/pytest/test_globalpooling.py index 8abefe7a46..d02e15b3a8 100644 --- a/test/pytest/test_globalpooling.py +++ b/test/pytest/test_globalpooling.py @@ -32,7 +32,7 @@ def keras_model_1d(request): return model, model_type, keepdims -@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'Altera']) @pytest.mark.parametrize( 'keras_model_1d', [ @@ -89,7 +89,7 @@ def keras_model_2d(request): return model, model_type, keepdims -@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'Altera']) @pytest.mark.parametrize( 'keras_model_2d', [ diff --git a/test/pytest/test_keras_api.py b/test/pytest/test_keras_api.py index 6bde581929..f88748fbf3 100644 --- a/test/pytest/test_keras_api.py +++ b/test/pytest/test_keras_api.py @@ -26,7 +26,7 @@ test_root_path = Path(__file__).parent -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_dense(test_case_id, backend, io_type, synthesis_config): if backend == 'XLS' and io_type != 'io_parallel': @@ -97,7 +97,7 @@ def test_dense(test_case_id, backend, io_type, synthesis_config): ids=['relu', 'leaky_relu', 'elu', 'prelu', 'sigmoid'], ) # ThresholdedReLU(theta=1.0)]) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_activations(test_case_id, activation_function, backend, io_type, synthesis_config): if backend == 'XLS' and io_type != 'io_parallel': @@ -140,7 +140,7 @@ def test_activations(test_case_id, activation_function, backend, io_type, synthe ('Vitis', 'Resource'), ('Vitis', 'Latency'), ('Quartus', 'Resource'), - ('oneAPI', 'Resource'), + ('Altera', 'Resource'), ('XLS', 'Latency'), ], ) @@ -236,7 +236,7 @@ def test_conv1d(test_case_id, padds, backend, strategy, io_type, synthesis_confi ('Vitis', 'Resource'), ('Vitis', 'Latency'), ('Quartus', 'Resource'), - ('oneAPI', 'Resource'), + ('Altera', 'Resource'), ('XLS', 'Latency'), ], ) @@ -431,7 +431,7 @@ def test_depthwise1d(test_case_id, backend, io_type, synthesis_config): ) @pytest.mark.parametrize('padds', padds_options) @pytest.mark.parametrize('chans', chans_options) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) def test_pooling(test_case_id, pooling, padds, chans, backend, synthesis_config): assert '1D' in pooling.__name__ or '2D' in pooling.__name__ diff --git a/test/pytest/test_keras_v3_api.py b/test/pytest/test_keras_v3_api.py index f4f661fb56..bcc3816c87 100644 --- a/test/pytest/test_keras_v3_api.py +++ b/test/pytest/test_keras_v3_api.py @@ -29,7 +29,7 @@ test_root_path = Path(__file__).parent -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'Catapult', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'Catapult', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_dense(test_case_id, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -93,7 +93,7 @@ def test_dense(test_case_id, backend, io_type): Activation(activation='sigmoid', name='sigmoid'), ], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_activations(test_case_id, activation_function, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -129,7 +129,7 @@ def test_activations(test_case_id, activation_function, backend, io_type): @pytest.mark.parametrize('padds', padds_options) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'Catapult', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'Catapult', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) @pytest.mark.parametrize('activation', ['elu', 'relu']) def test_conv1d(test_case_id, padds, backend, io_type, activation): @@ -216,7 +216,7 @@ def test_conv1d(test_case_id, padds, backend, io_type, activation): @pytest.mark.parametrize('chans', chans_options) @pytest.mark.parametrize('padds', padds_options) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'Catapult', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'Catapult', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_conv2d(test_case_id, chans, padds, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -383,7 +383,7 @@ def test_depthwise1d(test_case_id, backend, io_type): @pytest.mark.parametrize('pooling', pooling_layers) @pytest.mark.parametrize('padds', padds_options) @pytest.mark.parametrize('chans', chans_options) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'Catapult', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'Catapult', 'XLS']) def test_pooling(test_case_id, pooling, padds, chans, backend): assert '1D' in pooling.__name__ or '2D' in pooling.__name__ @@ -504,7 +504,7 @@ def test_pooling(test_case_id, pooling, padds, chans, backend): # assert hls_pool.attributes['pad_right'] == 0 -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'Altera', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_reused_layer(test_case_id, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': diff --git a/test/pytest/test_merge.py b/test/pytest/test_merge.py index 9b5e1095bc..a96061ef10 100644 --- a/test/pytest/test_merge.py +++ b/test/pytest/test_merge.py @@ -12,7 +12,7 @@ @pytest.mark.parametrize('merge_layer', [Add, Average, Maximum, Minimum, Multiply, Subtract]) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) @pytest.mark.parametrize('swap_inputs', [True, False]) def test_merge(test_case_id, merge_layer, io_type, backend, swap_inputs): if backend == 'XLS' and io_type != 'io_parallel': @@ -50,7 +50,7 @@ def test_merge(test_case_id, merge_layer, io_type, backend, swap_inputs): @pytest.mark.parametrize('axes', [1]) @pytest.mark.parametrize('io_type', ['io_parallel']) # No io_stream implementation yet -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) def test_dot(test_case_id, axes, io_type, backend): if backend == 'XLS' and io_type != 'io_parallel': pytest.skip(f'XLS backend only supports IOType: io_parallel, but got: {io_type}') @@ -82,7 +82,7 @@ def test_dot(test_case_id, axes, io_type, backend): @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) def test_concatenate1d(test_case_id, io_type, backend): if backend == 'XLS' and io_type != 'io_parallel': pytest.skip(f'XLS backend only supports IOType: io_parallel, but got: {io_type}') @@ -115,7 +115,7 @@ def test_concatenate1d(test_case_id, io_type, backend): @pytest.mark.parametrize('axis', [1, 2]) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) def test_concatenate2d(test_case_id, axis, io_type, backend): if backend == 'XLS' and io_type != 'io_parallel': pytest.skip(f'XLS backend only supports IOType: io_parallel, but got: {io_type}') @@ -151,7 +151,7 @@ def test_concatenate2d(test_case_id, axis, io_type, backend): @pytest.mark.parametrize('axis', [1, 2, 3]) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) def test_concatenate3d(test_case_id, axis, io_type, backend): if backend == 'XLS' and io_type != 'io_parallel': pytest.skip(f'XLS backend only supports IOType: io_parallel, but got: {io_type}') diff --git a/test/pytest/test_multi_dense.py b/test/pytest/test_multi_dense.py index bf67dc3448..d712c0f52a 100644 --- a/test/pytest/test_multi_dense.py +++ b/test/pytest/test_multi_dense.py @@ -18,7 +18,7 @@ ('Vitis', 'Latency'), ('Vitis', 'Resource'), ('Quartus', 'Resource'), - ('oneAPI', 'Resource'), + ('Altera', 'Resource'), ('Catapult', 'Latency'), ('Catapult', 'Resource'), ('XLS', 'Latency'), diff --git a/test/pytest/test_multiout_network.py b/test/pytest/test_multiout_network.py index 4d77f637db..f14d8a9d4d 100644 --- a/test/pytest/test_multiout_network.py +++ b/test/pytest/test_multiout_network.py @@ -69,7 +69,7 @@ def test_multi_output_nn(test_case_id, model, data, backend: str, io_type: str): assert np.allclose(r_hls[1], r_keras[1], atol=1e-5, rtol=0) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Vitis', 'Catapult', 'OneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Vitis', 'Catapult', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) @pytest.mark.parametrize('strategy', ['latency', 'resource']) def test_multi_output_nn_corner_cases( diff --git a/test/pytest/test_pointwiseconv.py b/test/pytest/test_pointwiseconv.py index 50a2785905..68cb615e6f 100644 --- a/test/pytest/test_pointwiseconv.py +++ b/test/pytest/test_pointwiseconv.py @@ -23,8 +23,8 @@ [ ('Quartus', 'io_parallel', 'resource', 1), ('Quartus', 'io_stream', 'resource', 1), - ('oneAPI', 'io_parallel', 'resource', 1), - ('oneAPI', 'io_stream', 'resource', 1), + ('Altera', 'io_parallel', 'resource', 1), + ('Altera', 'io_stream', 'resource', 1), ('Vivado', 'io_parallel', 'resource', 1), ('Vitis', 'io_parallel', 'resource', 1), ('Vivado', 'io_parallel', 'latency', 1), @@ -79,7 +79,7 @@ def test_pointwiseconv1d(test_case_id, chans, padds, strides, backend, io_type, hls_model.compile() hls_prediction = hls_model.predict(X_input).reshape(keras_prediction.shape) - if backend != 'XLS' and not (backend in ['Quartus', 'oneAPI'] and io_type == 'io_stream'): + if backend != 'XLS' and not (backend in ['Quartus', 'Altera'] and io_type == 'io_stream'): # Quartus io_stream does not currently have a special pointwise implementation assert 'Pointwise' in list(hls_model.graph.values())[1].class_name np.testing.assert_allclose(hls_prediction, keras_prediction, rtol=0, atol=0.001) @@ -93,8 +93,8 @@ def test_pointwiseconv1d(test_case_id, chans, padds, strides, backend, io_type, [ ('Quartus', 'io_parallel', 'resource'), ('Quartus', 'io_stream', 'resource'), - ('oneAPI', 'io_parallel', 'resource'), - ('oneAPI', 'io_stream', 'resource'), + ('Altera', 'io_parallel', 'resource'), + ('Altera', 'io_stream', 'resource'), ('Vivado', 'io_parallel', 'resource'), ('Vivado', 'io_parallel', 'latency'), ('Vivado', 'io_stream', 'latency'), @@ -144,7 +144,7 @@ def test_pointwiseconv2d(test_case_id, chans, padds, strides, backend, io_type, hls_model.compile() hls_prediction = hls_model.predict(X_input).reshape(keras_prediction.shape) - if backend != 'XLS' and not (backend in ['Quartus', 'oneAPI'] and io_type == 'io_stream'): + if backend != 'XLS' and not (backend in ['Quartus', 'Altera'] and io_type == 'io_stream'): # Quartus io_stream does not currently have a special pointwise implementation assert 'Pointwise' in list(hls_model.graph.values())[1].class_name np.testing.assert_allclose(hls_prediction, keras_prediction, rtol=0, atol=0.001) diff --git a/test/pytest/test_pooling.py b/test/pytest/test_pooling.py index f4822e60ef..dbfc4eb9f4 100644 --- a/test/pytest/test_pooling.py +++ b/test/pytest/test_pooling.py @@ -49,7 +49,7 @@ def keras_model_1d(request, backend): return model, model_type, pads, strides -@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'Altera', 'XLS']) @pytest.mark.parametrize( 'keras_model_1d', [ @@ -92,7 +92,7 @@ def test_pool1d(test_case_id, backend, keras_model_1d, data_1d, io_type): np.testing.assert_allclose(y_keras, y_hls, rtol=0, atol=atol, verbose=True) -@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Altera']) @pytest.mark.parametrize( 'keras_model_1d', [ @@ -149,7 +149,7 @@ def keras_model_2d(request, backend): return model, model_type, pads, strides -@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'Altera', 'XLS']) @pytest.mark.parametrize( 'keras_model_2d', [ @@ -192,7 +192,7 @@ def test_pool2d(test_case_id, backend, keras_model_2d, data_2d, io_type): np.testing.assert_allclose(y_keras, y_hls, rtol=0, atol=atol, verbose=True) -@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Altera']) @pytest.mark.parametrize( 'keras_model_2d', [ diff --git a/test/pytest/test_pytorch_api.py b/test/pytest/test_pytorch_api.py index cfac61fa4b..73a5395b6b 100644 --- a/test/pytest/test_pytorch_api.py +++ b/test/pytest/test_pytorch_api.py @@ -22,7 +22,7 @@ def forward(self, x): return self.linear(x) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_linear(test_case_id, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -76,7 +76,7 @@ def test_linear(test_case_id, backend, io_type): ], ids=['softmax', 'relu', 'tanh', 'leaky_relu', 'elu', 'prelu', 'sigmoid', 'threshold'], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_activations(test_case_id, activation_function, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -191,7 +191,7 @@ def forward(self, x): ], ids=['softmax', 'relu', 'tanh', 'leaky_relu', 'elu', 'sigmoid', 'threshold'], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_activation_functionals(test_case_id, activation_function, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -227,7 +227,7 @@ def test_activation_functionals(test_case_id, activation_function, backend, io_t @pytest.mark.parametrize('padds', padds_options) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_conv1d(test_case_id, padds, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -336,7 +336,7 @@ def test_conv1d(test_case_id, padds, backend, io_type): @pytest.mark.parametrize('padds', padds_options) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_conv2d(test_case_id, padds, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -493,7 +493,7 @@ def test_conv2d(test_case_id, padds, backend, io_type): @pytest.mark.parametrize('pooling', pooling_layers, ids=['MaxPool1d', 'MaxPool2d', 'AvgPool1d', 'AvgPool2d']) @pytest.mark.parametrize('padds', padds_options) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) def test_pooling(test_case_id, pooling, padds, backend): assert '1d' in pooling.__name__ or '2d' in pooling.__name__ @@ -613,7 +613,7 @@ def forward(self, x): return self.bn(x) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_bn(test_case_id, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -657,7 +657,7 @@ def forward(self, x): # TODO: this test fails for XLS due to PyTorch weights shape mismatch. -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_squeeze(test_case_id, backend, io_type): model = SqueezeModel() @@ -679,8 +679,8 @@ def test_squeeze(test_case_id, backend, io_type): np.testing.assert_allclose(hls_prediction, pytorch_prediction, rtol=1e-2, atol=0.01) - # oneAPI doesn't use the Repack class (and for io_stream does not use inplace variables) - if io_type == 'io_parallel' or backend == 'oneAPI': + # Altera doesn't use the Repack class (and for io_stream does not use inplace variables) + if io_type == 'io_parallel' or backend == 'Altera': assert list(hls_model.get_layers())[1].attributes['class_name'] == 'Reshape' assert list(hls_model.get_layers())[1].attributes['target_shape'] == [1, 5] assert list(hls_model.get_layers())[3].attributes['class_name'] == 'Reshape' @@ -692,7 +692,7 @@ def test_squeeze(test_case_id, backend, io_type): assert list(hls_model.get_layers())[3].attributes['target_shape'] == [3] -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) def test_flatten(test_case_id, backend): input = torch.randn(1, 1, 5, 5) model = nn.Sequential(nn.Conv2d(1, 32, 5, 1, 1), nn.Flatten(), nn.ReLU()) @@ -736,7 +736,7 @@ def forward(self, x): return x -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_skipped_layers(test_case_id, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -771,7 +771,7 @@ def test_skipped_layers(test_case_id, backend, io_type): np.testing.assert_allclose(hls_prediction, pytorch_prediction, rtol=0, atol=5e-2) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel']) # Only io_parallel for now @pytest.mark.parametrize('tensor_rank', [2, 3]) def test_remove_transpose(test_case_id, backend, io_type, tensor_rank): @@ -838,7 +838,7 @@ def forward(self, x): np.testing.assert_allclose(hls_prediction, pytorch_prediction, rtol=0, atol=5e-2) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_view(test_case_id, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': diff --git a/test/pytest/test_qeinsum.py b/test/pytest/test_qeinsum.py index b8711be234..9192d1b1da 100644 --- a/test/pytest/test_qeinsum.py +++ b/test/pytest/test_qeinsum.py @@ -19,7 +19,7 @@ @pytest.mark.parametrize('strategy', ['latency']) @pytest.mark.parametrize('io_type', ['io_parallel']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera']) @pytest.mark.parametrize( 'operation', [ @@ -41,7 +41,7 @@ def test_einsum_dense(test_case_id, backend, io_type, strategy, operation): data = np.random.randn(1000, *inp0_shape).astype(np.float32), np.random.randn(1000, *inp1_shape).astype(np.float32) output_dir = str(test_root_path / test_case_id) hls_config = { - 'Model': {'Precision': 'ap_fixed<1,0>' if backend != 'oneAPI' else 'ac_fixed<2,0>', 'ReuseFactor': 1}, + 'Model': {'Precision': 'ap_fixed<1,0>' if backend != 'Altera' else 'ac_fixed<2,0>', 'ReuseFactor': 1}, 'Strategy': strategy, } diff --git a/test/pytest/test_qkeras.py b/test/pytest/test_qkeras.py index 25d33080fa..a750a7f0ea 100644 --- a/test/pytest/test_qkeras.py +++ b/test/pytest/test_qkeras.py @@ -135,7 +135,7 @@ def randX_100_16(): # https://github.com/fastmachinelearning/hls4ml/issues/381 # @pytest.mark.parametrize('bits', [4, 6, 8]) @pytest.mark.parametrize('bits,alpha', [(4, 1), (4, 'auto_po2')]) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_single_dense_activation_exact(test_case_id, randX_100_16, bits, alpha, backend, io_type): """ @@ -200,7 +200,7 @@ def randX_100_10(): @pytest.mark.parametrize( 'quantizer', [(quantized_tanh(8)), (quantized_sigmoid(5)), (quantized_sigmoid(7, use_real_sigmoid=True))] ) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_quantizer_special(test_case_id, randX_1000_1, quantizer, backend, io_type): """ @@ -239,7 +239,7 @@ def test_quantizer_special(test_case_id, randX_1000_1, quantizer, backend, io_ty (7, 10, binary(), quantized_bits(5, 2), binary(), False, True), ], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_btnn(test_case_id, make_btnn, randX_100_10, backend, io_type): model, is_xnor, test_no = make_btnn @@ -282,7 +282,7 @@ def randX_1000_1(): (quantized_relu(10, 5)), ], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_quantizer(test_case_id, randX_1000_1, quantizer, backend, io_type): """ @@ -317,7 +317,7 @@ def test_quantizer(test_case_id, randX_1000_1, quantizer, backend, io_type): (quantized_relu(10, 2, negative_slope=0.25)), ], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_relu_negative_slope(test_case_id, randX_1000_1, quantizer, backend, io_type): """ @@ -398,7 +398,7 @@ def test_qactivation_kwarg(test_case_id, randX_100_10, activation_quantizer, wei assert sum(wrong) / len(wrong) <= 0.005 -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_quantizer_parsing(test_case_id, randX_100_10, backend, io_type): X = randX_100_10 @@ -437,7 +437,7 @@ def randX_100_8_8_1(): return np.random.rand(100, 8, 8, 1) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_qconv2dbn(test_case_id, randX_100_8_8_1, backend, io_type): """ @@ -518,7 +518,7 @@ def test_qdepthwiseconv2d(test_case_id, randX_10_32_32_3, backend, io_type): np.testing.assert_allclose(y_qkeras, y_hls4ml.reshape(y_qkeras.shape), rtol=1e-2, atol=0.01) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) @pytest.mark.parametrize('strategy', ['Latency', 'Resource']) def test_quantised_po2_bit_width(test_case_id, backend, io_type, strategy): @@ -556,7 +556,7 @@ def test_quantised_po2_bit_width(test_case_id, backend, io_type, strategy): np.testing.assert_allclose(y_hls.flatten(), y_keras.flatten(), rtol=2e-2) -@pytest.mark.parametrize('backend', ['Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Quartus', 'Altera']) def test_qsimplernn(test_case_id, backend): """ Test proper handling of QSimpleRNN. @@ -591,7 +591,7 @@ def test_qsimplernn(test_case_id, backend): np.testing.assert_allclose(y_qkeras, y_hls4ml.reshape(y_qkeras.shape), atol=0.1) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera']) def test_qlstm(test_case_id, backend): """ Test proper handling of QLSTM. @@ -627,7 +627,7 @@ def test_qlstm(test_case_id, backend): np.testing.assert_allclose(y_qkeras, y_hls4ml.reshape(y_qkeras.shape), atol=0.1) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera']) def test_qgru(test_case_id, backend): """ Test proper handling of QGRU. diff --git a/test/pytest/test_qkerasV3.py b/test/pytest/test_qkerasV3.py index cd9429108b..7a12c7bfaa 100644 --- a/test/pytest/test_qkerasV3.py +++ b/test/pytest/test_qkerasV3.py @@ -148,7 +148,7 @@ def randX_100_16(): # https://github.com/fastmachinelearning/hls4ml/issues/381 # @pytest.mark.parametrize('bits', [4, 6, 8]) @pytest.mark.parametrize('bits,alpha', [(4, 1), (4, 'auto_po2')]) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_single_dense_activation_exact(test_case_id, randX_100_16, bits, alpha, backend, io_type): """ @@ -211,7 +211,7 @@ def randX_100_10(): @pytest.mark.parametrize( 'quantizer', [(quantized_tanh(8)), (quantized_sigmoid(5)), (quantized_sigmoid(7, use_real_sigmoid=True))] ) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_quantizer_special(test_case_id, randX_1000_1, quantizer, backend, io_type): """ @@ -250,7 +250,7 @@ def test_quantizer_special(test_case_id, randX_1000_1, quantizer, backend, io_ty (7, 10, binary(), quantized_bits(5, 2), binary(), False, True), ], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_btnn(test_case_id, make_btnn, randX_100_10, backend, io_type): model, is_xnor, test_no = make_btnn @@ -293,7 +293,7 @@ def randX_1000_1(): (quantized_relu(10, 5)), ], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_quantizer(test_case_id, randX_1000_1, quantizer, backend, io_type): """ @@ -328,7 +328,7 @@ def test_quantizer(test_case_id, randX_1000_1, quantizer, backend, io_type): (quantized_relu(10, 2, negative_slope=0.25)), ], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_relu_negative_slope(test_case_id, randX_1000_1, quantizer, backend, io_type): """ @@ -400,7 +400,7 @@ def test_qactivation_kwarg(test_case_id, randX_100_10, activation_quantizer, wei assert sum(wrong) / len(wrong) <= 0.005 -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel']) def test_qkeras_einsum_dense(test_case_id, randX_100_10, backend, io_type): """ @@ -440,7 +440,7 @@ def test_qkeras_einsum_dense(test_case_id, randX_100_10, backend, io_type): np.testing.assert_array_equal(y_qkeras, y_hls4ml.reshape(y_qkeras.shape)) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_quantizer_parsing(test_case_id, randX_100_10, backend, io_type): X = randX_100_10 @@ -479,7 +479,7 @@ def randX_100_8_8_1(): return np.random.rand(100, 8, 8, 1) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) @pytest.mark.parametrize( 'qconv_layer,input_shape,input_data_shape,layer_kwargs', @@ -531,7 +531,7 @@ def test_qconv_activation_kwarg(test_case_id, qconv_layer, input_shape, input_da np.testing.assert_array_equal(y_qkeras, y_hls4ml.reshape(y_qkeras.shape)) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_qconv2dbn(test_case_id, randX_100_8_8_1, backend, io_type): """ @@ -621,7 +621,7 @@ def test_qdepthwiseconv2d(test_case_id, randX_10_32_32_3, backend, io_type, quan np.testing.assert_allclose(y_qkeras, y_hls4ml.reshape(y_qkeras.shape), rtol=1e-2, atol=0.01) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) @pytest.mark.parametrize('strategy', ['Latency', 'Resource']) def test_quantised_po2_bit_width(test_case_id, backend, io_type, strategy): @@ -659,7 +659,7 @@ def test_quantised_po2_bit_width(test_case_id, backend, io_type, strategy): np.testing.assert_allclose(y_hls.flatten(), y_keras.flatten(), rtol=2e-2) -@pytest.mark.parametrize('backend', ['Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Quartus', 'Altera']) def test_qsimplernn(test_case_id, backend): """ Test proper handling of QSimpleRNN. @@ -694,7 +694,7 @@ def test_qsimplernn(test_case_id, backend): np.testing.assert_allclose(y_qkeras, y_hls4ml.reshape(y_qkeras.shape), atol=0.1) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera']) def test_qlstm(test_case_id, backend): """ Test proper handling of QLSTM. @@ -730,7 +730,7 @@ def test_qlstm(test_case_id, backend): np.testing.assert_allclose(y_qkeras, y_hls4ml.reshape(y_qkeras.shape), atol=0.1) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera']) def test_qgru(test_case_id, backend): """ Test proper handling of QGRU. diff --git a/test/pytest/test_qonnx.py b/test/pytest/test_qonnx.py index a467dd170d..d84475332c 100644 --- a/test/pytest/test_qonnx.py +++ b/test/pytest/test_qonnx.py @@ -506,7 +506,7 @@ def test_simple_model(test_case_id, request, model_name, io_type, backend): ('Catapult', 'Latency'), ('Vitis', 'Resource'), ('Vitis', 'Latency'), - ('oneAPI', 'Resource'), + ('Altera', 'Resource'), ], ) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) diff --git a/test/pytest/test_recurrent_pytorch.py b/test/pytest/test_recurrent_pytorch.py index b0157d7e99..5ed573b2ec 100644 --- a/test/pytest/test_recurrent_pytorch.py +++ b/test/pytest/test_recurrent_pytorch.py @@ -31,7 +31,7 @@ def forward(self, x): return output -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel']) def test_gru(test_case_id, backend, io_type): model = GRUNet() @@ -62,7 +62,7 @@ def test_gru(test_case_id, backend, io_type): np.testing.assert_allclose(hls_prediction, pytorch_prediction, rtol=0, atol=1e-1) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_stream']) def test_gru_stream(test_case_id, backend, io_type): model = GRUNetStream() @@ -107,7 +107,7 @@ def forward(self, x): return output -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel']) def test_lstm(test_case_id, backend, io_type): model = LSTM() @@ -148,10 +148,10 @@ def test_lstm(test_case_id, backend, io_type): np.testing.assert_allclose(hls_prediction, pytorch_prediction, rtol=0, atol=1e-1) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_stream']) def test_lstm_stream(test_case_id, backend, io_type): - if not (backend in ('Quartus', 'oneAPI') and io_type == 'io_stream'): + if not (backend in ('Quartus', 'Altera') and io_type == 'io_stream'): model = LSTMStream() model.eval() @@ -190,10 +190,10 @@ def forward(self, x, h0): return output -@pytest.mark.parametrize('backend', ['Quartus', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Quartus', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel']) def test_rnn(test_case_id, backend, io_type): - if not (backend in ('Quartus', 'oneAPI') and io_type == 'io_stream'): + if not (backend in ('Quartus', 'Altera') and io_type == 'io_stream'): model = RNN() model.eval() diff --git a/test/pytest/test_repack_stream.py b/test/pytest/test_repack_stream.py index f24906647a..37545a884b 100644 --- a/test/pytest/test_repack_stream.py +++ b/test/pytest/test_repack_stream.py @@ -9,7 +9,7 @@ test_root_path = Path(__file__).parent -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'Altera']) def test_repack_precision(test_case_id, backend: str): inp = keras.Input(shape=(3, 3), name='inp') out = keras.layers.Reshape((3, 3), name='reshape')(inp) @@ -34,7 +34,7 @@ def test_repack_precision(test_case_id, backend: str): ) model_hls.write() # Not needed for this test, but useful for debugging - reshape_name = 'reshape' if backend == 'oneAPI' else 'repack_reshape' + reshape_name = 'reshape' if backend == 'Altera' else 'repack_reshape' assert reshape_name in model_hls.graph, f'{reshape_name} not found in graph' repack_precision = model_hls.graph[reshape_name].attributes['result_t'].precision assert repack_precision.integer == 10, 'Precision mismatch' @@ -47,7 +47,7 @@ def test_repack_precision(test_case_id, backend: str): 'backend, strategy', [ ('Quartus', 'Resource'), - ('oneAPI', 'Resource'), + ('Altera', 'Resource'), ('Vivado', 'Resource'), ('Vitis', 'Resource'), ('Vivado', 'Latency'), diff --git a/test/pytest/test_report.py b/test/pytest/test_report.py index 5424102235..02cce4a6a9 100644 --- a/test/pytest/test_report.py +++ b/test/pytest/test_report.py @@ -26,8 +26,8 @@ def copy_vivado_report(output_dir, test_report_dir): return -def copy_oneapi_report(output_dir, test_report_dir): - # copy pregenerated oneAPI reports +def copy_altera_report(output_dir, test_report_dir): + # copy pregenerated Altera reports json_dir = f'{output_dir}/build/myproject.fpga.prj/reports/resources/json' os.makedirs(json_dir, exist_ok=True) shutil.copy(test_report_dir / 'quartus.ndjson', f'{json_dir}/quartus.ndjson') @@ -74,13 +74,13 @@ def backend_configs(): + ' LUT: 1526\n' + ' URAM: N/A\n\n', }, - 'oneAPI': { - 'backend': 'oneAPI', + 'Altera': { + 'backend': 'Altera', 'part': 'Agilex7', 'build': {'build_type': 'fpga'}, - 'copy_func': copy_oneapi_report, - 'parse_func': hls4ml.report.parse_oneapi_report, - 'print_func': hls4ml.report.print_oneapi_report, + 'copy_func': copy_altera_report, + 'parse_func': hls4ml.report.parse_altera_report, + 'print_func': hls4ml.report.print_altera_report, 'expected_outcome': '\n' + '==================================================\n' + '== FPGA Hardware Synthesis\n' @@ -128,7 +128,7 @@ def hls_model_setup(request, test_case_id, backend_configs, tmp_path): ) hls_model.write() - # to actually generate the reports (using Vivado 2020.1 or oneAPI 2025.0) + # to actually generate the reports (using Vivado 2020.1 or Altera 2025.0) # hls_model.build(**(backend_config['build'])) backend_config['copy_func'](output_dir, test_report_dir) @@ -136,7 +136,7 @@ def hls_model_setup(request, test_case_id, backend_configs, tmp_path): yield output_dir, backend_config -@pytest.mark.parametrize('hls_model_setup', ['Vivado', 'oneAPI'], indirect=True) +@pytest.mark.parametrize('hls_model_setup', ['Vivado', 'Altera'], indirect=True) def test_report(hls_model_setup, capsys): """Tests that the report parsing and printing functions work for different backends.""" output_dir, backend_config = hls_model_setup diff --git a/test/pytest/test_report/oneAPI/loop_attr.ndjson b/test/pytest/test_report/Altera/loop_attr.ndjson similarity index 100% rename from test/pytest/test_report/oneAPI/loop_attr.ndjson rename to test/pytest/test_report/Altera/loop_attr.ndjson diff --git a/test/pytest/test_report/oneAPI/quartus.ndjson b/test/pytest/test_report/Altera/quartus.ndjson similarity index 100% rename from test/pytest/test_report/oneAPI/quartus.ndjson rename to test/pytest/test_report/Altera/quartus.ndjson diff --git a/test/pytest/test_report/oneAPI/summary.ndjson b/test/pytest/test_report/Altera/summary.ndjson similarity index 100% rename from test/pytest/test_report/oneAPI/summary.ndjson rename to test/pytest/test_report/Altera/summary.ndjson diff --git a/test/pytest/test_reshape.py b/test/pytest/test_reshape.py index 25fd6418c9..bc265fe6bc 100755 --- a/test/pytest/test_reshape.py +++ b/test/pytest/test_reshape.py @@ -20,7 +20,7 @@ def randX_20_10(): return randX(20, 10) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Catapult', 'oneAPI', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Catapult', 'Altera', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_reshape_parallel(test_case_id, randX_20_10, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': diff --git a/test/pytest/test_rnn.py b/test/pytest/test_rnn.py index b259888653..eaed92d794 100644 --- a/test/pytest/test_rnn.py +++ b/test/pytest/test_rnn.py @@ -159,13 +159,13 @@ def create_model_accuracy(rnn_layer, return_sequences): 'rnn_layer, backend, io_type, strategy', [ (SimpleRNN, 'Quartus', 'io_parallel', 'resource'), - (SimpleRNN, 'oneAPI', 'io_parallel', 'resource'), + (SimpleRNN, 'Altera', 'io_parallel', 'resource'), (LSTM, 'Vivado', 'io_parallel', 'resource'), (LSTM, 'Vivado', 'io_parallel', 'latency'), (LSTM, 'Vitis', 'io_parallel', 'resource'), (LSTM, 'Vitis', 'io_parallel', 'latency'), (LSTM, 'Quartus', 'io_parallel', 'resource'), - (LSTM, 'oneAPI', 'io_parallel', 'resource'), + (LSTM, 'Altera', 'io_parallel', 'resource'), (LSTM, 'Vivado', 'io_stream', 'resource'), (LSTM, 'Vivado', 'io_stream', 'latency'), (LSTM, 'Vitis', 'io_stream', 'resource'), @@ -175,13 +175,13 @@ def create_model_accuracy(rnn_layer, return_sequences): (GRU, 'Vitis', 'io_parallel', 'resource'), (GRU, 'Vitis', 'io_parallel', 'latency'), (GRU, 'Quartus', 'io_parallel', 'resource'), - (GRU, 'oneAPI', 'io_parallel', 'resource'), + (GRU, 'Altera', 'io_parallel', 'resource'), (GRU, 'Vivado', 'io_stream', 'resource'), (GRU, 'Vivado', 'io_stream', 'latency'), (GRU, 'Vitis', 'io_stream', 'resource'), (GRU, 'Vitis', 'io_stream', 'latency'), (GRU, 'Quartus', 'io_stream', 'resource'), - (GRU, 'oneAPI', 'io_stream', 'resource'), + (GRU, 'Altera', 'io_stream', 'resource'), (Bidirectional, 'Vivado', 'io_parallel', 'resource'), (Bidirectional, 'Vivado', 'io_parallel', 'latency'), (Bidirectional, 'Vitis', 'io_parallel', 'resource'), @@ -189,13 +189,13 @@ def create_model_accuracy(rnn_layer, return_sequences): ], ids=[ 'SimpleRNN-Quartus-io_parallel-resource', - 'SimpleRNN-oneAPI-io_parallel-resource', + 'SimpleRNN-Altera-io_parallel-resource', 'LSTM-Vivado-io_parallel-resource', 'LSTM-Vivado-io_parallel-latency', 'LSTM-Vitis-io_parallel-resource', 'LSTM-Vitis-io_parallel-latency', 'LSTM-Quartus-io_parallel-resource', - 'LSTM-oneAPI-io_parallel-resource', + 'LSTM-Altera-io_parallel-resource', 'LSTM-Vivado-io_stream-resource', 'LSTM-Vivado-io_stream-latency', 'LSTM-Vitis-io_stream-resource', @@ -205,13 +205,13 @@ def create_model_accuracy(rnn_layer, return_sequences): 'GRU-Vitis-io_parallel-resource', 'GRU-Vitis-io_parallel-latency', 'GRU-Quartus-io_parallel-resource', - 'GRU-oneAPI-io_parallel-resource', + 'GRU-Altera-io_parallel-resource', 'GRU-Vivado-io_stream-resource', 'GRU-Vivado-io_stream-latency', 'GRU-Vitis-io_stream-resource', 'GRU-Vitis-io_stream-latency', 'GRU-Quartus-io_stream-resource', - 'GRU-oneAPI-io_stream-resource', + 'GRU-Altera-io_stream-resource', 'Bidirectional-Vivado-io_parallel-resource', 'Bidirectional-Vivado-io_parallel-latency', 'Bidirectional-Vitis-io_parallel-resource', diff --git a/test/pytest/test_serialization.py b/test/pytest/test_serialization.py index eb403d74e3..c993d6be44 100644 --- a/test/pytest/test_serialization.py +++ b/test/pytest/test_serialization.py @@ -32,7 +32,7 @@ def qkeras_model(input_shape): return model -@pytest.mark.parametrize('backend', ['Vitis', 'Catapult', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vitis', 'Catapult', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_save_load__model(test_case_id, io_type, backend): input_shape = (8, 8, 3) @@ -155,7 +155,7 @@ def test_save_load_testbench_data(test_case_id, backend, input_configured, outpu assert hls_model_clone.config.config.get('OutputPredictions') is None -@pytest.mark.parametrize('backend', ['Vitis']) # Disabling OneAPI for now excessive run time +@pytest.mark.parametrize('backend', ['Vitis']) # Disabling Altera for now due to excessive run time def test_save_load_qonnx_model(test_case_id, backend): dl_file = str(example_model_path / 'onnx/branched_model_ch_last.onnx') @@ -194,7 +194,7 @@ def test_save_load_qonnx_model(test_case_id, backend): np.testing.assert_equal(y_original, y_clone) -@pytest.mark.parametrize('backend', ['Vitis', 'Catapult', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vitis', 'Catapult', 'Altera']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_linking_project(test_case_id, io_type, backend): input_shape = (8, 8, 3) diff --git a/test/pytest/test_stream_clone.py b/test/pytest/test_stream_clone.py index 0931770ce5..d86e10acc8 100644 --- a/test/pytest/test_stream_clone.py +++ b/test/pytest/test_stream_clone.py @@ -70,7 +70,7 @@ def data(): return X -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Vitis', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Vitis', 'Altera']) def test_multi_clone(test_case_id, model_multi_clone, data, backend: str): output_dir = str(test_root_path / test_case_id) hls_config = hls4ml.utils.config_from_keras_model( @@ -90,7 +90,7 @@ def test_multi_clone(test_case_id, model_multi_clone, data, backend: str): np.testing.assert_allclose(r_hls, r_keras, atol=1e-4, rtol=0) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Vitis', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Vitis', 'Altera']) def test_clone_precision_inheritance(test_case_id, model_clone_precision_inheritance, data, backend: str): output_dir = str(test_root_path / test_case_id) layer_config = { diff --git a/test/pytest/test_transpose_concat.py b/test/pytest/test_transpose_concat.py index 6b0866e797..b52b68ff75 100644 --- a/test/pytest/test_transpose_concat.py +++ b/test/pytest/test_transpose_concat.py @@ -49,22 +49,22 @@ def hls_model(keras_model, request, test_case_id): ('io_stream', 'Vivado'), ('io_stream', 'Vitis'), ('io_stream', 'Quartus'), - ('io_stream', 'oneAPI'), + ('io_stream', 'Altera'), ('io_parallel', 'Vivado'), ('io_parallel', 'Vitis'), ('io_parallel', 'Quartus'), - ('io_parallel', 'oneAPI'), + ('io_parallel', 'Altera'), ], indirect=True, ids=[ 'vivado_stream', 'vitis_streamq', 'quartus_stream', - 'oneapi_stream', + 'altera_stream', 'vivado_parallel', 'vitis_parallel', 'quartus_parallel', - 'oneapi_parallel', + 'altera_parallel', ], ) def test_accuracy(data, keras_model, hls_model): @@ -93,7 +93,7 @@ def data_highdim(): @pytest.mark.parametrize('io_type', ['io_stream', 'io_parallel']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera']) def test_highdim_permute(test_case_id, data_highdim, keras_model_highdim, io_type, backend): X = data_highdim model = keras_model_highdim diff --git a/test/pytest/test_upsampling.py b/test/pytest/test_upsampling.py index 0252b55708..497b115c6f 100644 --- a/test/pytest/test_upsampling.py +++ b/test/pytest/test_upsampling.py @@ -46,7 +46,7 @@ def keras_model_2d(): @pytest.mark.parametrize('io_type', ['io_stream', 'io_parallel']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'Altera']) @pytest.mark.parametrize('model_type', ['1d', '2d']) def test_upsampling(test_case_id, keras_model_1d, keras_model_2d, data_1d, data_2d, model_type, io_type, backend): if model_type == '1d': diff --git a/test/pytest/test_zeropadding.py b/test/pytest/test_zeropadding.py index 29d366bdb9..63d7cf8bdb 100644 --- a/test/pytest/test_zeropadding.py +++ b/test/pytest/test_zeropadding.py @@ -50,7 +50,7 @@ def keras_model_2d(): @pytest.mark.parametrize('io_type', ['io_stream', 'io_parallel']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'oneAPI']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'Altera']) @pytest.mark.parametrize('model_type', ['1d', '2d']) def test_zeropadding(test_case_id, keras_model_1d, keras_model_2d, data_1d, data_2d, model_type, io_type, backend): if model_type == '1d': From 5f87ca4b60c7f4044361f7865a04bd281bb0969c Mon Sep 17 00:00:00 2001 From: bugracyln Date: Mon, 13 Jul 2026 18:52:08 +0100 Subject: [PATCH 2/9] Altera HLS compatibility --- hls4ml/backends/altera/altera_backend.py | 4 ++-- hls4ml/backends/altera/altera_types.py | 8 ++++++-- hls4ml/templates/altera/CMakeLists.txt | 11 ++++++++++- hls4ml/templates/altera/firmware/defines.h | 6 ++++++ hls4ml/templates/altera/firmware/myproject.cpp | 8 ++++++++ hls4ml/templates/altera/firmware/myproject.h | 18 +++++++++++++++--- .../altera/firmware/nnet_utils/nnet_common.h | 7 +++++++ hls4ml/templates/altera/myproject_bridge.cpp | 8 ++++++++ hls4ml/templates/altera/myproject_test.cpp | 16 +++++++++++++++- 9 files changed, 77 insertions(+), 9 deletions(-) diff --git a/hls4ml/backends/altera/altera_backend.py b/hls4ml/backends/altera/altera_backend.py index 1c75bd1d34..efe04b5e7e 100644 --- a/hls4ml/backends/altera/altera_backend.py +++ b/hls4ml/backends/altera/altera_backend.py @@ -208,9 +208,9 @@ def build(self, model, build_type='fpga_emu', run=False): builddir = outdir / 'build' builddir.mkdir(exist_ok=True) try: - subprocess.run('which icpx', shell=True, cwd=builddir, check=True) + subprocess.run('which ahls', shell=True, cwd=builddir, check=True) except subprocess.CalledProcessError: - raise RuntimeError('Could not find icpx. Please configure the Intel oneAPI toolchain appropriately') + raise RuntimeError('Could not find ahls. Please configure the Altera HLS IP Gen toolchain appropriately') subprocess.run('cmake ..', shell=True, cwd=builddir, check=True) subprocess.run(f'make {build_type}', shell=True, cwd=builddir, check=True) diff --git a/hls4ml/backends/altera/altera_types.py b/hls4ml/backends/altera/altera_types.py index 9ce50d0a0e..c1ddb647da 100644 --- a/hls4ml/backends/altera/altera_types.py +++ b/hls4ml/backends/altera/altera_types.py @@ -2,6 +2,8 @@ This package includes Altera-specific customizations to the variable types """ +import shutil + import numpy as np from hls4ml.backends.fpga.fpga_types import ( @@ -180,9 +182,10 @@ def definition_cpp(self, name_suffix='', as_reference=False): return f'{self.type.name} {self.name}{name_suffix}' def declare_cpp(self, pipe_min_size=0, indent=''): + compiler_name = 'altera' if shutil.which('ahls') else 'intel' lines = indent + f'class {self.pipe_id};\n' lines += indent + ( - f'using {self.pipe_name} = sycl::ext::intel::experimental::pipe<{self.pipe_id}, ' + f'using {self.pipe_name} = sycl::ext::{compiler_name}::experimental::pipe<{self.pipe_id}, ' + f'{self.type.name}, {pipe_min_size}, PipeProps>;\n' ) return lines @@ -202,9 +205,10 @@ def definition_cpp(self, name_suffix='', as_reference=True): return f'{self.name}{name_suffix}' def declare_cpp(self, indent=''): + compiler_name = 'altera' if shutil.which('ahls') else 'intel' lines = indent + f'class {self.pipe_id};\n' lines += indent + ( - f'using {self.pipe_name} = sycl::ext::intel::experimental::pipe<{self.pipe_id}, ' + f'using {self.pipe_name} = sycl::ext::{compiler_name}::experimental::pipe<{self.pipe_id}, ' + f'{self.type.name}, {self.pragma[-1]}>;\n' ) return lines diff --git a/hls4ml/templates/altera/CMakeLists.txt b/hls4ml/templates/altera/CMakeLists.txt index 5bce2aaf84..88b3ee3ca9 100644 --- a/hls4ml/templates/altera/CMakeLists.txt +++ b/hls4ml/templates/altera/CMakeLists.txt @@ -1,7 +1,12 @@ # Direct CMake to use icpx rather than the default C++ compiler/linker on Linux # and icx-cl on Windows if(UNIX) - set(CMAKE_CXX_COMPILER icpx) + find_program(CXX_COMPILER NAMES icpx ahls) + if(NOT CXX_COMPILER) + message(FATAL_ERROR "Neither icpx nor ahls was found in PATH.") + endif() + set(CMAKE_CXX_COMPILER "${CXX_COMPILER}") + message(STATUS "Using C++ compiler: ${CXX_COMPILER}") else() # Windows include (CMakeForceCompiler) CMAKE_FORCE_CXX_COMPILER (icx-cl IntelDPCPP) @@ -12,6 +17,10 @@ cmake_minimum_required (VERSION 3.7.2) project(myproject CXX) +if(CXX_COMPILER MATCHES "ahls$") + add_compile_definitions(AHLS) +endif() + set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/hls4ml/templates/altera/firmware/defines.h b/hls4ml/templates/altera/firmware/defines.h index 05de507dcd..26f408f685 100644 --- a/hls4ml/templates/altera/firmware/defines.h +++ b/hls4ml/templates/altera/firmware/defines.h @@ -1,9 +1,15 @@ #ifndef DEFINES_H_ #define DEFINES_H_ +#ifdef AHLS +#include +#include +#include +#else #include #include #include +#endif #include // Include nnet::array - a custom array-like struct, mainly used with io_stream diff --git a/hls4ml/templates/altera/firmware/myproject.cpp b/hls4ml/templates/altera/firmware/myproject.cpp index 06e7d3fe37..d345484793 100644 --- a/hls4ml/templates/altera/firmware/myproject.cpp +++ b/hls4ml/templates/altera/firmware/myproject.cpp @@ -1,13 +1,21 @@ #include "myproject.h" #include "parameters.h" +#ifdef AHLS +#include +#else #include +#endif // hls-fpga-machine-learning insert weights // The inter-task pipes need to be declared in the global scope // hls-fpga-machine-learning insert inter-task pipes +#ifdef AHLS +using sycl::ext::altera::experimental::task_sequence; +#else using sycl::ext::intel::experimental::task_sequence; +#endif void MyProject::operator()() const { // **************************************** diff --git a/hls4ml/templates/altera/firmware/myproject.h b/hls4ml/templates/altera/firmware/myproject.h index 082ae5dc8c..fc1ae92665 100644 --- a/hls4ml/templates/altera/firmware/myproject.h +++ b/hls4ml/templates/altera/firmware/myproject.h @@ -6,7 +6,14 @@ // This file defines the interface to the kernel // currently this is fixed -using PipeProps = decltype(sycl::ext::oneapi::experimental::properties(sycl::ext::intel::experimental::ready_latency<0>)); + +using PipeProps = decltype(sycl::ext::oneapi::experimental::properties( +#ifdef AHLS + sycl::ext::altera::experimental::ready_latency<0> +#else + sycl::ext::intel::experimental::ready_latency<0> +#endif + )); // Need to declare the input and output pipes @@ -19,8 +26,13 @@ struct MyProject { // kernel property method to config invocation interface auto get(sycl::ext::oneapi::experimental::properties_tag) { - return sycl::ext::oneapi::experimental::properties{sycl::ext::intel::experimental::streaming_interface<>, - sycl::ext::intel::experimental::pipelined<>}; + return sycl::ext::oneapi::experimental::properties{ +#ifdef AHLS + sycl::ext::altera::experimental::streaming_interface<>, sycl::ext::altera::experimental::pipelined<> +#else + sycl::ext::intel::experimental::streaming_interface<>, sycl::ext::intel::experimental::pipelined<> +#endif + }; } SYCL_EXTERNAL void operator()() const; diff --git a/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h index f37a61cb0c..7c6818e5dc 100644 --- a/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h +++ b/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h @@ -2,9 +2,16 @@ #define NNET_COMMON_H_ #include "nnet_helpers.h" + +#ifdef AHLS +#include +#include +#include +#else #include #include #include +#endif typedef ac_fixed<16, 6> table_default_t; diff --git a/hls4ml/templates/altera/myproject_bridge.cpp b/hls4ml/templates/altera/myproject_bridge.cpp index ddad1d054b..01468c64f5 100644 --- a/hls4ml/templates/altera/myproject_bridge.cpp +++ b/hls4ml/templates/altera/myproject_bridge.cpp @@ -56,7 +56,11 @@ void collect_trace_output(struct trace_data *c_trace_outputs) { void myproject_float( // hls-fpga-machine-learning insert header #float ) { +#ifdef AHLS + auto selector = sycl::ext::altera::fpga_emulator_selector_v; +#else auto selector = sycl::ext::intel::fpga_emulator_selector_v; +#endif static sycl::queue q(selector, fpga_tools::exception_handler, sycl::property::queue::enable_profiling{}); // hls-fpga-machine-learning insert wrapper #float @@ -67,7 +71,11 @@ void myproject_float( void myproject_double( // hls-fpga-machine-learning insert header #double ) { +#ifdef AHLS + auto selector = sycl::ext::altera::fpga_emulator_selector_v; +#else auto selector = sycl::ext::intel::fpga_emulator_selector_v; +#endif static sycl::queue q(selector, fpga_tools::exception_handler, sycl::property::queue::enable_profiling{}); // hls-fpga-machine-learning insert wrapper #double diff --git a/hls4ml/templates/altera/myproject_test.cpp b/hls4ml/templates/altera/myproject_test.cpp index 82fb60d2f8..a861e1fc69 100644 --- a/hls4ml/templates/altera/myproject_test.cpp +++ b/hls4ml/templates/altera/myproject_test.cpp @@ -9,9 +9,13 @@ #include "firmware/myproject.h" #include "firmware/parameters.h" +#ifdef AHLS +#include +#else #include +#endif -#if (__INTEL_CLANG_COMPILER < 20250000) +#if (__INTEL_CLANG_COMPILER < 20250000) && !defined(AHLS) #include #endif @@ -22,12 +26,22 @@ int main(int argc, char **argv) { +#ifdef AHLS +#if FPGA_SIMULATOR + auto selector = sycl::ext::altera::fpga_simulator_selector_v; +#elif FPGA_HARDWARE + auto selector = sycl::ext::altera::fpga_selector_v; +#else // #if FPGA_EMULATOR + auto selector = sycl::ext::altera::fpga_emulator_selector_v; +#endif +#else #if FPGA_SIMULATOR auto selector = sycl::ext::intel::fpga_simulator_selector_v; #elif FPGA_HARDWARE auto selector = sycl::ext::intel::fpga_selector_v; #else // #if FPGA_EMULATOR auto selector = sycl::ext::intel::fpga_emulator_selector_v; +#endif #endif sycl::queue q(selector, fpga_tools::exception_handler, sycl::property::queue::enable_profiling{}); From 155e6d9558003c203ecce10036fc6bab1f332b39 Mon Sep 17 00:00:00 2001 From: bugracyln Date: Thu, 20 Aug 2026 04:15:36 +0100 Subject: [PATCH 3/9] minor corrections --- hls4ml/backends/altera/altera_types.py | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) diff --git a/hls4ml/backends/altera/altera_types.py b/hls4ml/backends/altera/altera_types.py index c1ddb647da..5083d2c1aa 100644 --- a/hls4ml/backends/altera/altera_types.py +++ b/hls4ml/backends/altera/altera_types.py @@ -2,8 +2,6 @@ This package includes Altera-specific customizations to the variable types """ -import shutil - import numpy as np from hls4ml.backends.fpga.fpga_types import ( @@ -182,11 +180,16 @@ def definition_cpp(self, name_suffix='', as_reference=False): return f'{self.type.name} {self.name}{name_suffix}' def declare_cpp(self, pipe_min_size=0, indent=''): - compiler_name = 'altera' if shutil.which('ahls') else 'intel' lines = indent + f'class {self.pipe_id};\n' + # This will look very ugly but it is the only way to ensure synch with CMake compiler decision lines += indent + ( - f'using {self.pipe_name} = sycl::ext::{compiler_name}::experimental::pipe<{self.pipe_id}, ' - + f'{self.type.name}, {pipe_min_size}, PipeProps>;\n' + '#ifdef AHLS\n' + f'using {self.pipe_name} = sycl::ext::altera::experimental::pipe<{self.pipe_id}, ' + f'{self.type.name}, {pipe_min_size}, PipeProps>;\n' + '#else\n' + f'using {self.pipe_name} = sycl::ext::intel::experimental::pipe<{self.pipe_id}, ' + f'{self.type.name}, {pipe_min_size}, PipeProps>;\n' + '#endif\n' ) return lines @@ -205,11 +208,15 @@ def definition_cpp(self, name_suffix='', as_reference=True): return f'{self.name}{name_suffix}' def declare_cpp(self, indent=''): - compiler_name = 'altera' if shutil.which('ahls') else 'intel' lines = indent + f'class {self.pipe_id};\n' lines += indent + ( - f'using {self.pipe_name} = sycl::ext::{compiler_name}::experimental::pipe<{self.pipe_id}, ' - + f'{self.type.name}, {self.pragma[-1]}>;\n' + '#ifdef AHLS\n' + f'using {self.pipe_name} = sycl::ext::altera::experimental::pipe<{self.pipe_id}, ' + f'{self.type.name}, {self.pragma[-1]}>;\n' + '#else\n' + f'using {self.pipe_name} = sycl::ext::intel::experimental::pipe<{self.pipe_id}, ' + f'{self.type.name}, {self.pragma[-1]}>;\n' + '#endif\n' ) return lines From 96ca4762da2e3685391a06f15c177d38f546cdc7 Mon Sep 17 00:00:00 2001 From: bugracyln Date: Fri, 21 Aug 2026 03:03:54 +0100 Subject: [PATCH 4/9] doc update --- docs/backend/altera.rst | 19 ++++++++++++------- docs/intro/status.rst | 14 ++++++++++---- hls4ml/templates/altera/CMakeLists.txt | 4 ++-- 3 files changed, 24 insertions(+), 13 deletions(-) diff --git a/docs/backend/altera.rst b/docs/backend/altera.rst index 76f9f6e890..d58e8f62b9 100644 --- a/docs/backend/altera.rst +++ b/docs/backend/altera.rst @@ -1,10 +1,15 @@ -====== -Altera -====== +=============== +Altera / oneAPI +=============== -The **Altera** backend of hls4ml is designed for deploying NNs on Intel/Altera FPGAs. It will eventually -replace the **Quartus** backend, which targeted Intel HLS. (Quartus continues to be used with IP produced by the -**Altera** backend.) This section discusses details of the **Altera** backend. +The **Altera** backend of hls4ml is designed for deploying neural networks on Intel/Altera FPGAs. +It is based on the SYCL FPGA flow that was previously provided through **Intel oneAPI** and is now continued +by the **Altera HLS IP Gen** toolchain. The functionality and terminology used by hls4ml remain largely unchanged. +(The **oneAPI** backend remains available as a slight modification of the **Altera** backend for use with oneAPI 2025.0.) + +The **Altera HLS/oneAPI** backend is intended to supersede the **Quartus** backend, which targets the discontinued +Intel HLS Compiler. Quartus Prime continues to be used to integrate the IP generated by the Altera HLS IP Gen flow +into FPGA designs. The **Altera** backend uses SYCL kernels to implement the logic that is deployed on FPGAs. It naturally leads to the accelerator style of programming. In the SYCL HLS (IP Component) flow, which is currently the only flow supported, the @@ -12,7 +17,7 @@ kernel becomes the IP, and the "host code" becomes the testbench. An accelerator PCIe accelerator boards, is planned to be added in the future. The produced work areas use cmake to build the projects in a style based -`oneAPI-samples `_. +`Altera HLS IP Gen hls-samples `_ (or deprecated `oneAPI-samples `_). The standard ``fpga_emu``, ``report``, ``fpga_sim``, and ``fpga`` make targets are supported. Additionally, ``make lib`` produces the library used for calling the ``predict`` function from hls4ml. The ``compile`` and ``build`` commands in hls4ml interact with the cmake system, so one does not need to manually use the build system, but it there diff --git a/docs/intro/status.rst b/docs/intro/status.rst index 2f4f87a606..921ada2292 100644 --- a/docs/intro/status.rst +++ b/docs/intro/status.rst @@ -44,12 +44,15 @@ Neural network architectures: HLS backends: * Vivado HLS -* Intel HLS +* Intel HLS (deprecated) * Vitis HLS * Catapult HLS -* Altera (experimental) +* Altera +* oneAPI (to be superseded by Altera) * XLS (experimental) +======= end + A summary of the on-going status of the ``hls4ml`` tool is in the table below. .. table:: hls4ml Supported Features @@ -81,7 +84,9 @@ A summary of the on-going status of the ``hls4ml`` tool is in the table below. +-----------------------+-----+-----+--------------+--------+--------+-----+ | Catapult HLS | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | +-----------------------+-----+-----+--------------+--------+--------+-----+ -| Altera (experimental) | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | +| Altera | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ++-----------------------+-----+-----+--------------+--------+--------+-----+ +| oneAPI | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | +-----------------------+-----+-----+--------------+--------+--------+-----+ | XLS (experimental) | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | +-----------------------+-----+-----+--------------+--------+--------+-----+ @@ -94,7 +99,8 @@ Other feature notes: - Intel HLS versions 20.1 to 21.4, versions > 21.4 have not been tested. - Vitis HLS versions 2022.2 to 2024.1. Versions > 2024.1 are less tested. - Catapult HLS versions 2024.1_1 to 2024.2 - - The Altera backend uses Intel oneAPI versions 2024.1 to 2025.0. Later versions are known not to work. + - Altera HLS IP Gen (Beta) 2026.1 + - oneAPI versions 2024.1 to 2025.0. Any future versions are known to not work. * ``hls4ml`` supports Linux [*]_ and requires python >=3.10. hls4ml does not require a specific Linux distribution version and we recommend following the requirements of the HLS tool you are using. * Windows and macOS are not supported. Setting up ``hls4ml`` on these platforms, for example using the Windows Subsystem for Linux (WSL), should be possible, but we do not provide support for such use cases. diff --git a/hls4ml/templates/altera/CMakeLists.txt b/hls4ml/templates/altera/CMakeLists.txt index 88b3ee3ca9..b79790e479 100644 --- a/hls4ml/templates/altera/CMakeLists.txt +++ b/hls4ml/templates/altera/CMakeLists.txt @@ -1,7 +1,7 @@ -# Direct CMake to use icpx rather than the default C++ compiler/linker on Linux +# Direct CMake to use ahls/icpx rather than the default C++ compiler/linker on Linux # and icx-cl on Windows if(UNIX) - find_program(CXX_COMPILER NAMES icpx ahls) + find_program(CXX_COMPILER NAMES ahls icpx) if(NOT CXX_COMPILER) message(FATAL_ERROR "Neither icpx nor ahls was found in PATH.") endif() From 891f757fc940831e6e93884e4b6d42c705d6c50b Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Tue, 25 Aug 2026 16:35:55 -0500 Subject: [PATCH 5/9] Remove oneAPI support from Altera branch --- hls4ml/backends/altera/altera_types.py | 11 ----------- hls4ml/templates/altera/CMakeLists.txt | 18 ++++-------------- hls4ml/templates/altera/firmware/defines.h | 6 ------ hls4ml/templates/altera/firmware/myproject.cpp | 8 -------- hls4ml/templates/altera/firmware/myproject.h | 17 +++-------------- .../altera/firmware/nnet_utils/nnet_common.h | 7 ------- hls4ml/templates/altera/myproject_bridge.cpp | 8 -------- hls4ml/templates/altera/myproject_test.cpp | 18 ------------------ 8 files changed, 7 insertions(+), 86 deletions(-) diff --git a/hls4ml/backends/altera/altera_types.py b/hls4ml/backends/altera/altera_types.py index 5083d2c1aa..7dce069f06 100644 --- a/hls4ml/backends/altera/altera_types.py +++ b/hls4ml/backends/altera/altera_types.py @@ -181,15 +181,9 @@ def definition_cpp(self, name_suffix='', as_reference=False): def declare_cpp(self, pipe_min_size=0, indent=''): lines = indent + f'class {self.pipe_id};\n' - # This will look very ugly but it is the only way to ensure synch with CMake compiler decision lines += indent + ( - '#ifdef AHLS\n' f'using {self.pipe_name} = sycl::ext::altera::experimental::pipe<{self.pipe_id}, ' f'{self.type.name}, {pipe_min_size}, PipeProps>;\n' - '#else\n' - f'using {self.pipe_name} = sycl::ext::intel::experimental::pipe<{self.pipe_id}, ' - f'{self.type.name}, {pipe_min_size}, PipeProps>;\n' - '#endif\n' ) return lines @@ -210,13 +204,8 @@ def definition_cpp(self, name_suffix='', as_reference=True): def declare_cpp(self, indent=''): lines = indent + f'class {self.pipe_id};\n' lines += indent + ( - '#ifdef AHLS\n' f'using {self.pipe_name} = sycl::ext::altera::experimental::pipe<{self.pipe_id}, ' f'{self.type.name}, {self.pragma[-1]}>;\n' - '#else\n' - f'using {self.pipe_name} = sycl::ext::intel::experimental::pipe<{self.pipe_id}, ' - f'{self.type.name}, {self.pragma[-1]}>;\n' - '#endif\n' ) return lines diff --git a/hls4ml/templates/altera/CMakeLists.txt b/hls4ml/templates/altera/CMakeLists.txt index b79790e479..dd4a5847c4 100644 --- a/hls4ml/templates/altera/CMakeLists.txt +++ b/hls4ml/templates/altera/CMakeLists.txt @@ -1,25 +1,15 @@ -# Direct CMake to use ahls/icpx rather than the default C++ compiler/linker on Linux -# and icx-cl on Windows +# Direct CMake to use ahls rather than the default C++ compiler/linker on Linux if(UNIX) - find_program(CXX_COMPILER NAMES ahls icpx) - if(NOT CXX_COMPILER) - message(FATAL_ERROR "Neither icpx nor ahls was found in PATH.") - endif() - set(CMAKE_CXX_COMPILER "${CXX_COMPILER}") - message(STATUS "Using C++ compiler: ${CXX_COMPILER}") + set(CMAKE_CXX_COMPILER ahls) else() # Windows - include (CMakeForceCompiler) - CMAKE_FORCE_CXX_COMPILER (icx-cl IntelDPCPP) - include (Platform/Windows-Clang) + message(FATAL_ERROR "Only Unix/Linux is supported.") endif() cmake_minimum_required (VERSION 3.7.2) project(myproject CXX) -if(CXX_COMPILER MATCHES "ahls$") - add_compile_definitions(AHLS) -endif() +add_compile_definitions(AHLS) set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/hls4ml/templates/altera/firmware/defines.h b/hls4ml/templates/altera/firmware/defines.h index 26f408f685..ec27d1f703 100644 --- a/hls4ml/templates/altera/firmware/defines.h +++ b/hls4ml/templates/altera/firmware/defines.h @@ -1,15 +1,9 @@ #ifndef DEFINES_H_ #define DEFINES_H_ -#ifdef AHLS #include #include #include -#else -#include -#include -#include -#endif #include // Include nnet::array - a custom array-like struct, mainly used with io_stream diff --git a/hls4ml/templates/altera/firmware/myproject.cpp b/hls4ml/templates/altera/firmware/myproject.cpp index d345484793..a0b79f55f8 100644 --- a/hls4ml/templates/altera/firmware/myproject.cpp +++ b/hls4ml/templates/altera/firmware/myproject.cpp @@ -1,21 +1,13 @@ #include "myproject.h" #include "parameters.h" -#ifdef AHLS #include -#else -#include -#endif // hls-fpga-machine-learning insert weights // The inter-task pipes need to be declared in the global scope // hls-fpga-machine-learning insert inter-task pipes -#ifdef AHLS using sycl::ext::altera::experimental::task_sequence; -#else -using sycl::ext::intel::experimental::task_sequence; -#endif void MyProject::operator()() const { // **************************************** diff --git a/hls4ml/templates/altera/firmware/myproject.h b/hls4ml/templates/altera/firmware/myproject.h index fc1ae92665..fcb95676cd 100644 --- a/hls4ml/templates/altera/firmware/myproject.h +++ b/hls4ml/templates/altera/firmware/myproject.h @@ -7,13 +7,7 @@ // currently this is fixed -using PipeProps = decltype(sycl::ext::oneapi::experimental::properties( -#ifdef AHLS - sycl::ext::altera::experimental::ready_latency<0> -#else - sycl::ext::intel::experimental::ready_latency<0> -#endif - )); +using PipeProps = decltype(sycl::ext::oneapi::experimental::properties(sycl::ext::altera::experimental::ready_latency<0>)); // Need to declare the input and output pipes @@ -26,13 +20,8 @@ struct MyProject { // kernel property method to config invocation interface auto get(sycl::ext::oneapi::experimental::properties_tag) { - return sycl::ext::oneapi::experimental::properties{ -#ifdef AHLS - sycl::ext::altera::experimental::streaming_interface<>, sycl::ext::altera::experimental::pipelined<> -#else - sycl::ext::intel::experimental::streaming_interface<>, sycl::ext::intel::experimental::pipelined<> -#endif - }; + return sycl::ext::oneapi::experimental::properties{sycl::ext::altera::experimental::streaming_interface<>, + sycl::ext::altera::experimental::pipelined<>}; } SYCL_EXTERNAL void operator()() const; diff --git a/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h index 7c6818e5dc..90218d934a 100644 --- a/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h +++ b/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h @@ -2,16 +2,9 @@ #define NNET_COMMON_H_ #include "nnet_helpers.h" - -#ifdef AHLS #include #include #include -#else -#include -#include -#include -#endif typedef ac_fixed<16, 6> table_default_t; diff --git a/hls4ml/templates/altera/myproject_bridge.cpp b/hls4ml/templates/altera/myproject_bridge.cpp index 01468c64f5..03b6aa0a7f 100644 --- a/hls4ml/templates/altera/myproject_bridge.cpp +++ b/hls4ml/templates/altera/myproject_bridge.cpp @@ -56,11 +56,7 @@ void collect_trace_output(struct trace_data *c_trace_outputs) { void myproject_float( // hls-fpga-machine-learning insert header #float ) { -#ifdef AHLS auto selector = sycl::ext::altera::fpga_emulator_selector_v; -#else - auto selector = sycl::ext::intel::fpga_emulator_selector_v; -#endif static sycl::queue q(selector, fpga_tools::exception_handler, sycl::property::queue::enable_profiling{}); // hls-fpga-machine-learning insert wrapper #float @@ -71,11 +67,7 @@ void myproject_float( void myproject_double( // hls-fpga-machine-learning insert header #double ) { -#ifdef AHLS auto selector = sycl::ext::altera::fpga_emulator_selector_v; -#else - auto selector = sycl::ext::intel::fpga_emulator_selector_v; -#endif static sycl::queue q(selector, fpga_tools::exception_handler, sycl::property::queue::enable_profiling{}); // hls-fpga-machine-learning insert wrapper #double diff --git a/hls4ml/templates/altera/myproject_test.cpp b/hls4ml/templates/altera/myproject_test.cpp index a861e1fc69..3f0b4bb381 100644 --- a/hls4ml/templates/altera/myproject_test.cpp +++ b/hls4ml/templates/altera/myproject_test.cpp @@ -9,15 +9,7 @@ #include "firmware/myproject.h" #include "firmware/parameters.h" -#ifdef AHLS #include -#else -#include -#endif - -#if (__INTEL_CLANG_COMPILER < 20250000) && !defined(AHLS) -#include -#endif #include "exception_handler.hpp" // hls-fpga-machine-learning insert bram @@ -26,22 +18,12 @@ int main(int argc, char **argv) { -#ifdef AHLS #if FPGA_SIMULATOR auto selector = sycl::ext::altera::fpga_simulator_selector_v; #elif FPGA_HARDWARE auto selector = sycl::ext::altera::fpga_selector_v; #else // #if FPGA_EMULATOR auto selector = sycl::ext::altera::fpga_emulator_selector_v; -#endif -#else -#if FPGA_SIMULATOR - auto selector = sycl::ext::intel::fpga_simulator_selector_v; -#elif FPGA_HARDWARE - auto selector = sycl::ext::intel::fpga_selector_v; -#else // #if FPGA_EMULATOR - auto selector = sycl::ext::intel::fpga_emulator_selector_v; -#endif #endif sycl::queue q(selector, fpga_tools::exception_handler, sycl::property::queue::enable_profiling{}); From a9c3d8602aa20598b1e0f359ab89bd351ccc5d9f Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Tue, 25 Aug 2026 18:34:50 -0500 Subject: [PATCH 6/9] new lightweight oneAPI branch (generated with AI help) --- docs/backend/altera.rst | 1 + docs/intro/setup.rst | 5 +- hls4ml/backends/__init__.py | 2 + hls4ml/backends/altera/altera_backend.py | 66 ++++++++++------ hls4ml/backends/altera/altera_types.py | 4 +- .../backends/fpga/passes/hgq_proxy_model.py | 10 ++- hls4ml/backends/oneapi/__init__.py | 0 hls4ml/backends/oneapi/oneapi_backend.py | 8 ++ .../vivado/passes/distributed_arithmetic.py | 2 +- hls4ml/templates/altera/CMakeLists.txt | 9 +-- hls4ml/templates/altera/firmware/defines.h | 5 +- .../templates/altera/firmware/myproject.cpp | 3 +- hls4ml/templates/altera/firmware/myproject.h | 7 +- .../altera/firmware/nnet_utils/hls4ml_sycl.h | 28 +++++++ .../altera/firmware/nnet_utils/nnet_common.h | 4 +- hls4ml/templates/altera/myproject_bridge.cpp | 4 +- hls4ml/templates/altera/myproject_test.cpp | 8 +- hls4ml/writer/__init__.py | 2 + hls4ml/writer/altera_writer.py | 13 +++- hls4ml/writer/oneapi_writer.py | 6 ++ test/pytest/test_oneapi_backend.py | 75 +++++++++++++++++++ 21 files changed, 202 insertions(+), 60 deletions(-) create mode 100644 hls4ml/backends/oneapi/__init__.py create mode 100644 hls4ml/backends/oneapi/oneapi_backend.py create mode 100644 hls4ml/templates/altera/firmware/nnet_utils/hls4ml_sycl.h create mode 100644 hls4ml/writer/oneapi_writer.py create mode 100644 test/pytest/test_oneapi_backend.py diff --git a/docs/backend/altera.rst b/docs/backend/altera.rst index d58e8f62b9..90ec396684 100644 --- a/docs/backend/altera.rst +++ b/docs/backend/altera.rst @@ -6,6 +6,7 @@ The **Altera** backend of hls4ml is designed for deploying neural networks on In It is based on the SYCL FPGA flow that was previously provided through **Intel oneAPI** and is now continued by the **Altera HLS IP Gen** toolchain. The functionality and terminology used by hls4ml remain largely unchanged. (The **oneAPI** backend remains available as a slight modification of the **Altera** backend for use with oneAPI 2025.0.) +Select ``backend='Altera'`` for Altera HLS IP Gen or ``backend='oneAPI'`` for the legacy Intel oneAPI FPGA compiler. The **Altera HLS/oneAPI** backend is intended to supersede the **Quartus** backend, which targets the discontinued Intel HLS Compiler. Quartus Prime continues to be used to integrate the IP generated by the Altera HLS IP Gen flow diff --git a/docs/intro/setup.rst b/docs/intro/setup.rst index 8f8dad03bc..431f6dcf34 100644 --- a/docs/intro/setup.rst +++ b/docs/intro/setup.rst @@ -60,7 +60,7 @@ The following Python packages are all optional and are only required if you inte * `Brevitas `_: Based on PyTorch. See `frontend/pytorch <../frontend/pytorch.html>`_ for more details. * `QONNX `_: Based on ONNX. See `frontend/onnx <../frontend/onnx.html>`_ for more details. -Running C simulation from Python requires a C++11-compatible compiler. On Linux, a GCC C++ compiler ``g++`` is required. Any version from a recent Linux should work. On MacOS, when the *clang*-based ``g++`` finds issues with ``ap_types`` headers, one may still need to install GCC, using ``brew`` for example. For the Altera backend, one must have Intel oneAPI 2025.0 (2025.1 is known **not to work**) installed, along with the FPGA compiler, to run C/SYCL simulations. +Running C simulation from Python requires a C++11-compatible compiler. On Linux, a GCC C++ compiler ``g++`` is required. Any version from a recent Linux should work. On MacOS, when the *clang*-based ``g++`` finds issues with ``ap_types`` headers, one may still need to install GCC, using ``brew`` for example. The ``Altera`` backend requires Altera HLS IP Gen, while the ``oneAPI`` backend requires Intel oneAPI 2024.1 to 2025.0 with the FPGA compiler. oneAPI 2025.1 is known **not to work**. Specific functionalities may need additional Python packages. If any needed is missing, ``hls4ml`` will raise an error and prompt you to install the missing packages. @@ -72,7 +72,8 @@ To run FPGA synthesis, installation of following tools is required: * Intel Quartus 20.1 to 21.4 for the synthesis for Intel/Altera FPGAs using the ``Quartus`` backend. -* Intel oneAPI 2024.1 to 2025.0 with the FPGA compiler and recent Intel/Altera Quartus for Intel/Altera FPGAs using the ``Altera`` backend. Newer versions of oneAPI removed FPGA support and **will not work** with ``hls4ml``. +* Altera HLS IP Gen and recent Quartus for Intel/Altera FPGAs using the ``Altera`` backend. +* Intel oneAPI 2024.1 to 2025.0 with the FPGA compiler and recent Intel/Altera Quartus using the ``oneAPI`` backend. Newer versions of oneAPI removed FPGA support and **will not work** with ``hls4ml``. Catapult HLS 2024.1_1 or 2024.2 can be used to synthesize both for ASICs and FPGAs. diff --git a/hls4ml/backends/__init__.py b/hls4ml/backends/__init__.py index 2e830ce889..80d78293f1 100644 --- a/hls4ml/backends/__init__.py +++ b/hls4ml/backends/__init__.py @@ -3,6 +3,7 @@ from hls4ml.backends.libero.libero_backend import LiberoBackend from hls4ml.backends.altera.altera_backend import AlteraBackend # isort: skip +from hls4ml.backends.oneapi.oneapi_backend import OneAPIBackend from hls4ml.backends.plugin_loader import load_backend_plugins from hls4ml.backends.quartus.quartus_backend import QuartusBackend from hls4ml.backends.symbolic.symbolic_backend import SymbolicExpressionBackend @@ -25,6 +26,7 @@ def _register_builtin_backends(): register_backend('Catapult', CatapultBackend) register_backend('SymbolicExpression', SymbolicExpressionBackend) register_backend('Altera', AlteraBackend) + register_backend('oneAPI', OneAPIBackend) register_backend('Coyote', CoyoteBackend) register_backend('Libero', LiberoBackend) register_backend('XLS', XLSBackend) diff --git a/hls4ml/backends/altera/altera_backend.py b/hls4ml/backends/altera/altera_backend.py index efe04b5e7e..a099a6fbe9 100644 --- a/hls4ml/backends/altera/altera_backend.py +++ b/hls4ml/backends/altera/altera_backend.py @@ -1,3 +1,5 @@ +import inspect +import os import subprocess from pathlib import Path from warnings import warn @@ -22,6 +24,7 @@ Softmax, ) from hls4ml.model.optimizer import get_backend_passes, layer_optimizer +from hls4ml.model.optimizer.optimizer import extract_optimizers_from_path from hls4ml.model.types import FixedPrecisionType, IntegerPrecisionType, NamedType from hls4ml.report import parse_altera_report from hls4ml.utils import attribute_descriptions as descriptions @@ -31,11 +34,21 @@ class AlteraBackend(FPGABackend): - def __init__(self): - super().__init__('Altera') + compiler_executable = 'ahls' + + def __init__(self, name='Altera'): + super().__init__(name) self._register_layer_attributes() self._register_flows() + def _init_file_optimizers(self): + file_optimizers = {} + for cls in (FPGABackend, AlteraBackend): + opt_path = os.path.dirname(inspect.getfile(cls)) + '/passes' + module_path = cls.__module__[: cls.__module__.rfind('.')] + '.passes' + file_optimizers.update(extract_optimizers_from_path(opt_path, module_path, self)) + return file_optimizers + def _register_layer_attributes(self): # Add RNN-specific recurrent_reuse_factor attribute rnn_layers = [ @@ -63,46 +76,51 @@ def _register_layer_attributes(self): self.attribute_map[layer] = attrs def _register_flows(self): + backend_prefix = self.name.lower() + + def backend_pass(name): + return f'{backend_prefix}:{name}' + initializers = self._get_layer_initializers() init_flow = register_flow('init_layers', initializers, requires=['optimize'], backend=self.name) - streaming_passes = ['altera:clone_output'] + streaming_passes = [backend_pass('clone_output')] streaming_flow = register_flow('streaming', streaming_passes, requires=[init_flow], backend=self.name) altera_types = [ - 'altera:transform_types', - 'altera:register_bram_weights', - 'altera:apply_resource_strategy', - 'altera:apply_winograd_kernel_transformation', + backend_pass('transform_types'), + backend_pass('register_bram_weights'), + backend_pass('apply_resource_strategy'), + backend_pass('apply_winograd_kernel_transformation'), ] altera_types_flow = register_flow('specific_types', altera_types, requires=[init_flow], backend=self.name) quantization_passes = [ - 'altera:merge_batch_norm_quantized_tanh', - 'altera:quantize_dense_output', + backend_pass('merge_batch_norm_quantized_tanh'), + backend_pass('quantize_dense_output'), 'fuse_consecutive_batch_normalization', - 'altera:xnor_pooling', + backend_pass('xnor_pooling'), ] quantization_flow = register_flow('quantization', quantization_passes, requires=[init_flow], backend=self.name) optimization_passes = [ - 'altera:remove_final_reshape', - 'altera:optimize_pointwise_conv', - 'altera:inplace_parallel_reshape', - 'altera:skip_softmax', - 'altera:fix_softmax_table_size', + backend_pass('remove_final_reshape'), + backend_pass('optimize_pointwise_conv'), + backend_pass('inplace_parallel_reshape'), + backend_pass('skip_softmax'), + backend_pass('fix_softmax_table_size'), 'infer_precision_types', - 'altera:process_fixed_point_quantizer_layer', - 'altera:validate_ac_types', + backend_pass('process_fixed_point_quantizer_layer'), + backend_pass('validate_ac_types'), ] optimization_flow = register_flow('optimize', optimization_passes, requires=[init_flow], backend=self.name) templates = self._get_layer_templates() template_flow = register_flow('apply_templates', self._get_layer_templates, requires=[init_flow], backend=self.name) - writer_passes = ['make_stamp', 'altera:write_hls'] + writer_passes = ['make_stamp', backend_pass('write_hls')] - self._writer_flow = register_flow('write', writer_passes, requires=['altera:ip'], backend=self.name) + self._writer_flow = register_flow('write', writer_passes, requires=[backend_pass('ip')], backend=self.name) all_passes = get_backend_passes(self.name) @@ -118,7 +136,7 @@ def _register_flows(self): + templates + optimization_passes + writer_passes - + ['altera:inplace_stream_flatten', 'altera:reshape_stream'] # not needed + + [backend_pass('inplace_stream_flatten'), backend_pass('reshape_stream')] # not needed ] if len(extras) > 0: @@ -194,7 +212,7 @@ def compile(self, model): def build(self, model, build_type='fpga_emu', run=False): """ - Builds the project using the Intel oneAPI DPC++ compiler. + Builds the project using the backend's configured compiler. Args: model (ModelGraph): The model to build @@ -208,9 +226,11 @@ def build(self, model, build_type='fpga_emu', run=False): builddir = outdir / 'build' builddir.mkdir(exist_ok=True) try: - subprocess.run('which ahls', shell=True, cwd=builddir, check=True) + subprocess.run(f'which {self.compiler_executable}', shell=True, cwd=builddir, check=True) except subprocess.CalledProcessError: - raise RuntimeError('Could not find ahls. Please configure the Altera HLS IP Gen toolchain appropriately') + raise RuntimeError( + f'Could not find {self.compiler_executable}. Please configure the {self.name} toolchain appropriately' + ) subprocess.run('cmake ..', shell=True, cwd=builddir, check=True) subprocess.run(f'make {build_type}', shell=True, cwd=builddir, check=True) diff --git a/hls4ml/backends/altera/altera_types.py b/hls4ml/backends/altera/altera_types.py index 7dce069f06..15f9b1799a 100644 --- a/hls4ml/backends/altera/altera_types.py +++ b/hls4ml/backends/altera/altera_types.py @@ -182,7 +182,7 @@ def definition_cpp(self, name_suffix='', as_reference=False): def declare_cpp(self, pipe_min_size=0, indent=''): lines = indent + f'class {self.pipe_id};\n' lines += indent + ( - f'using {self.pipe_name} = sycl::ext::altera::experimental::pipe<{self.pipe_id}, ' + f'using {self.pipe_name} = hls4ml_sycl_ext::experimental::pipe<{self.pipe_id}, ' f'{self.type.name}, {pipe_min_size}, PipeProps>;\n' ) return lines @@ -204,7 +204,7 @@ def definition_cpp(self, name_suffix='', as_reference=True): def declare_cpp(self, indent=''): lines = indent + f'class {self.pipe_id};\n' lines += indent + ( - f'using {self.pipe_name} = sycl::ext::altera::experimental::pipe<{self.pipe_id}, ' + f'using {self.pipe_name} = hls4ml_sycl_ext::experimental::pipe<{self.pipe_id}, ' f'{self.type.name}, {self.pragma[-1]}>;\n' ) return lines diff --git a/hls4ml/backends/fpga/passes/hgq_proxy_model.py b/hls4ml/backends/fpga/passes/hgq_proxy_model.py index e37e838d7d..9e7bf5d692 100644 --- a/hls4ml/backends/fpga/passes/hgq_proxy_model.py +++ b/hls4ml/backends/fpga/passes/hgq_proxy_model.py @@ -27,12 +27,12 @@ def generate_mask_fn( ) -> str: """Generate heterogenous quantization mask function, ONLY works for IOType=io_parallel""" assert k.shape[0] == b.shape[0] == i.shape[0] == 1 - assert backend.lower() in ('altera', 'quartus', 'vivado', 'vitis'), f'Backend {backend} not tested' + assert backend.lower() in ('altera', 'oneapi', 'quartus', 'vivado', 'vitis'), f'Backend {backend} not tested' Ks, Bs, Is = k[0], b[0], i[0] Ks, Bs, Is = np.broadcast_to(Ks, shape), np.broadcast_to(Bs, shape), np.broadcast_to(Is, shape) Ks, Bs, Is = Ks.ravel(), Bs.ravel(), Is.ravel() masks = [] - to_fixed = to_acfixed if backend.lower() in ['altera', 'quartus'] else to_apfixed + to_fixed = to_acfixed if backend.lower() in ['altera', 'oneapi', 'quartus'] else to_apfixed for idx, (k, b, i) in enumerate(zip(Ks, Bs, Is)): if b == 0: fn = f'out[{idx}] = 0;' @@ -41,12 +41,14 @@ def generate_mask_fn( masks.append(f' {fn}') body = '\n'.join(masks) arguments = ( - 'input_t *inp, output_t *out' if backend.lower() not in ['altera', 'quartus'] else 'input_t &inp, output_t &out' + 'input_t *inp, output_t *out' + if backend.lower() not in ['altera', 'oneapi', 'quartus'] + else 'input_t &inp, output_t &out' ) mask_fn = f""" template void {name}({arguments}) {{ - {'#pragma HLS INLINE' if backend.lower() not in ['altera', 'quartus'] else ''} + {'#pragma HLS INLINE' if backend.lower() not in ['altera', 'oneapi', 'quartus'] else ''} {body} }} diff --git a/hls4ml/backends/oneapi/__init__.py b/hls4ml/backends/oneapi/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/hls4ml/backends/oneapi/oneapi_backend.py b/hls4ml/backends/oneapi/oneapi_backend.py new file mode 100644 index 0000000000..dad02e2981 --- /dev/null +++ b/hls4ml/backends/oneapi/oneapi_backend.py @@ -0,0 +1,8 @@ +from hls4ml.backends.altera.altera_backend import AlteraBackend + + +class OneAPIBackend(AlteraBackend): + compiler_executable = 'icpx' + + def __init__(self): + super().__init__('oneAPI') diff --git a/hls4ml/backends/vivado/passes/distributed_arithmetic.py b/hls4ml/backends/vivado/passes/distributed_arithmetic.py index 3d99cd60fc..6a3b02450f 100644 --- a/hls4ml/backends/vivado/passes/distributed_arithmetic.py +++ b/hls4ml/backends/vivado/passes/distributed_arithmetic.py @@ -438,7 +438,7 @@ def transform(self, model: 'ModelGraph', node: DACombinational): backend = model.config.get_config_value('Backend').lower() if backend in ('vitis', 'vivado'): flavor = 'vitis' - elif backend == 'altera': + elif backend in ('altera', 'oneapi'): flavor = 'oneapi' else: raise ValueError(f'Unsupported backend {backend} for DACombinational layer.') diff --git a/hls4ml/templates/altera/CMakeLists.txt b/hls4ml/templates/altera/CMakeLists.txt index dd4a5847c4..9a4576f211 100644 --- a/hls4ml/templates/altera/CMakeLists.txt +++ b/hls4ml/templates/altera/CMakeLists.txt @@ -1,15 +1,10 @@ -# Direct CMake to use ahls rather than the default C++ compiler/linker on Linux -if(UNIX) - set(CMAKE_CXX_COMPILER ahls) -else() # Windows - message(FATAL_ERROR "Only Unix/Linux is supported.") -endif() +# hls-fpga-machine-learning insert compiler cmake_minimum_required (VERSION 3.7.2) project(myproject CXX) -add_compile_definitions(AHLS) +# hls-fpga-machine-learning insert compiler definitions set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) diff --git a/hls4ml/templates/altera/firmware/defines.h b/hls4ml/templates/altera/firmware/defines.h index ec27d1f703..68da9683c9 100644 --- a/hls4ml/templates/altera/firmware/defines.h +++ b/hls4ml/templates/altera/firmware/defines.h @@ -1,10 +1,7 @@ #ifndef DEFINES_H_ #define DEFINES_H_ -#include -#include -#include -#include +#include "nnet_utils/hls4ml_sycl.h" // Include nnet::array - a custom array-like struct, mainly used with io_stream #include "nnet_utils/nnet_types.h" diff --git a/hls4ml/templates/altera/firmware/myproject.cpp b/hls4ml/templates/altera/firmware/myproject.cpp index a0b79f55f8..d8e383db92 100644 --- a/hls4ml/templates/altera/firmware/myproject.cpp +++ b/hls4ml/templates/altera/firmware/myproject.cpp @@ -1,13 +1,12 @@ #include "myproject.h" #include "parameters.h" -#include // hls-fpga-machine-learning insert weights // The inter-task pipes need to be declared in the global scope // hls-fpga-machine-learning insert inter-task pipes -using sycl::ext::altera::experimental::task_sequence; +using hls4ml_sycl_ext::experimental::task_sequence; void MyProject::operator()() const { // **************************************** diff --git a/hls4ml/templates/altera/firmware/myproject.h b/hls4ml/templates/altera/firmware/myproject.h index fcb95676cd..1fd0a8a561 100644 --- a/hls4ml/templates/altera/firmware/myproject.h +++ b/hls4ml/templates/altera/firmware/myproject.h @@ -7,7 +7,8 @@ // currently this is fixed -using PipeProps = decltype(sycl::ext::oneapi::experimental::properties(sycl::ext::altera::experimental::ready_latency<0>)); +using PipeProps = decltype( + sycl::ext::oneapi::experimental::properties(hls4ml_sycl_ext::experimental::ready_latency<0>)); // Need to declare the input and output pipes @@ -20,8 +21,8 @@ struct MyProject { // kernel property method to config invocation interface auto get(sycl::ext::oneapi::experimental::properties_tag) { - return sycl::ext::oneapi::experimental::properties{sycl::ext::altera::experimental::streaming_interface<>, - sycl::ext::altera::experimental::pipelined<>}; + return sycl::ext::oneapi::experimental::properties{ + hls4ml_sycl_ext::experimental::streaming_interface<>, hls4ml_sycl_ext::experimental::pipelined<>}; } SYCL_EXTERNAL void operator()() const; diff --git a/hls4ml/templates/altera/firmware/nnet_utils/hls4ml_sycl.h b/hls4ml/templates/altera/firmware/nnet_utils/hls4ml_sycl.h new file mode 100644 index 0000000000..62fa180dc6 --- /dev/null +++ b/hls4ml/templates/altera/firmware/nnet_utils/hls4ml_sycl.h @@ -0,0 +1,28 @@ +#ifndef HLS4ML_SYCL_H_ +#define HLS4ML_SYCL_H_ + +#include + +#ifdef HLS4ML_ONEAPI +#include +#include +#include +#include +#include + +#if __INTEL_CLANG_COMPILER < 20250000 +#include +#endif + +namespace hls4ml_sycl_ext = sycl::ext::intel; +#else +#include +#include +#include +#include +#include + +namespace hls4ml_sycl_ext = sycl::ext::altera; +#endif + +#endif diff --git a/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h index 90218d934a..05e1b06dcc 100644 --- a/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h +++ b/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h @@ -2,9 +2,7 @@ #define NNET_COMMON_H_ #include "nnet_helpers.h" -#include -#include -#include +#include "hls4ml_sycl.h" typedef ac_fixed<16, 6> table_default_t; diff --git a/hls4ml/templates/altera/myproject_bridge.cpp b/hls4ml/templates/altera/myproject_bridge.cpp index 03b6aa0a7f..5a22748478 100644 --- a/hls4ml/templates/altera/myproject_bridge.cpp +++ b/hls4ml/templates/altera/myproject_bridge.cpp @@ -56,7 +56,7 @@ void collect_trace_output(struct trace_data *c_trace_outputs) { void myproject_float( // hls-fpga-machine-learning insert header #float ) { - auto selector = sycl::ext::altera::fpga_emulator_selector_v; + auto selector = hls4ml_sycl_ext::fpga_emulator_selector_v; static sycl::queue q(selector, fpga_tools::exception_handler, sycl::property::queue::enable_profiling{}); // hls-fpga-machine-learning insert wrapper #float @@ -67,7 +67,7 @@ void myproject_float( void myproject_double( // hls-fpga-machine-learning insert header #double ) { - auto selector = sycl::ext::altera::fpga_emulator_selector_v; + auto selector = hls4ml_sycl_ext::fpga_emulator_selector_v; static sycl::queue q(selector, fpga_tools::exception_handler, sycl::property::queue::enable_profiling{}); // hls-fpga-machine-learning insert wrapper #double diff --git a/hls4ml/templates/altera/myproject_test.cpp b/hls4ml/templates/altera/myproject_test.cpp index 3f0b4bb381..ffdbde3a57 100644 --- a/hls4ml/templates/altera/myproject_test.cpp +++ b/hls4ml/templates/altera/myproject_test.cpp @@ -9,8 +9,6 @@ #include "firmware/myproject.h" #include "firmware/parameters.h" -#include - #include "exception_handler.hpp" // hls-fpga-machine-learning insert bram @@ -19,11 +17,11 @@ int main(int argc, char **argv) { #if FPGA_SIMULATOR - auto selector = sycl::ext::altera::fpga_simulator_selector_v; + auto selector = hls4ml_sycl_ext::fpga_simulator_selector_v; #elif FPGA_HARDWARE - auto selector = sycl::ext::altera::fpga_selector_v; + auto selector = hls4ml_sycl_ext::fpga_selector_v; #else // #if FPGA_EMULATOR - auto selector = sycl::ext::altera::fpga_emulator_selector_v; + auto selector = hls4ml_sycl_ext::fpga_emulator_selector_v; #endif sycl::queue q(selector, fpga_tools::exception_handler, sycl::property::queue::enable_profiling{}); diff --git a/hls4ml/writer/__init__.py b/hls4ml/writer/__init__.py index 46fbd43e60..53470ab51c 100644 --- a/hls4ml/writer/__init__.py +++ b/hls4ml/writer/__init__.py @@ -2,6 +2,7 @@ from hls4ml.writer.catapult_writer import CatapultWriter from hls4ml.writer.coyote_writer import CoyoteWriter from hls4ml.writer.libero_writer import LiberoWriter +from hls4ml.writer.oneapi_writer import OneAPIWriter from hls4ml.writer.quartus_writer import QuartusWriter from hls4ml.writer.symbolic_writer import SymbolicExpressionWriter from hls4ml.writer.vitis_writer import VitisWriter @@ -15,6 +16,7 @@ register_writer('Vitis', VitisWriter) register_writer('Quartus', QuartusWriter) register_writer('Altera', AlteraWriter) +register_writer('oneAPI', OneAPIWriter) register_writer('Catapult', CatapultWriter) register_writer('Libero', LiberoWriter) register_writer('SymbolicExpression', SymbolicExpressionWriter) diff --git a/hls4ml/writer/altera_writer.py b/hls4ml/writer/altera_writer.py index d923167b14..836d02c93c 100644 --- a/hls4ml/writer/altera_writer.py +++ b/hls4ml/writer/altera_writer.py @@ -7,7 +7,6 @@ import numpy as np import yaml -from hls4ml.backends import get_backend from hls4ml.utils.fixed_point_utils import FixedPointEmulator, ceil_log2, uint_to_binary from hls4ml.utils.string_utils import convert_to_pascal_case from hls4ml.writer.writers import Writer @@ -16,6 +15,9 @@ class AlteraWriter(Writer): + compiler_executable = 'ahls' + compiler_definitions = () + def __make_dat_file(self, original_path, project_path): """ Convert other input/output data types into a dat file, which is @@ -510,6 +512,13 @@ def write_build_script(self, model): line = line.replace('myproject', model.config.get_project_name()) line = line.replace('mystamp', model.config.get_config_value('Stamp')) + if 'hls-fpga-machine-learning insert compiler definitions' in line: + for definition in self.compiler_definitions: + line += f'add_compile_definitions({definition})\n' + + elif 'hls-fpga-machine-learning insert compiler' in line: + line += f'set(CMAKE_CXX_COMPILER {self.compiler_executable})\n' + if 'set(FPGA_DEVICE' in line: line = f' set(FPGA_DEVICE "{device}")\n' @@ -544,7 +553,7 @@ def write_nnet_utils(self, model): # custom source filedir = os.path.dirname(os.path.abspath(__file__)) - custom_source = get_backend('Altera').get_custom_source() + custom_source = model.config.backend.get_custom_source() for dst, srcpath in custom_source.items(): dstpath = f'{model.config.get_output_dir()}/src/firmware/{dst}' copyfile(srcpath, dstpath) diff --git a/hls4ml/writer/oneapi_writer.py b/hls4ml/writer/oneapi_writer.py new file mode 100644 index 0000000000..e08cbfd51f --- /dev/null +++ b/hls4ml/writer/oneapi_writer.py @@ -0,0 +1,6 @@ +from hls4ml.writer.altera_writer import AlteraWriter + + +class OneAPIWriter(AlteraWriter): + compiler_executable = 'icpx' + compiler_definitions = ('HLS4ML_ONEAPI',) diff --git a/test/pytest/test_oneapi_backend.py b/test/pytest/test_oneapi_backend.py new file mode 100644 index 0000000000..92af9065fe --- /dev/null +++ b/test/pytest/test_oneapi_backend.py @@ -0,0 +1,75 @@ +from pathlib import Path + +import pytest +import tensorflow as tf + +import hls4ml +from hls4ml.backends.altera.altera_backend import AlteraBackend +from hls4ml.backends.oneapi.oneapi_backend import OneAPIBackend +from hls4ml.model.flow import get_flow +from hls4ml.model.optimizer import get_optimizer +from hls4ml.writer.altera_writer import AlteraWriter +from hls4ml.writer.oneapi_writer import OneAPIWriter + + +def test_oneapi_backend_registration(): + altera = hls4ml.backends.get_backend('Altera') + oneapi = hls4ml.backends.get_backend('oneAPI') + + assert type(altera) is AlteraBackend + assert type(oneapi) is OneAPIBackend + assert isinstance(oneapi, AlteraBackend) + assert type(altera.writer) is AlteraWriter + assert type(oneapi.writer) is OneAPIWriter + + for backend_name in ('altera', 'oneapi'): + assert get_optimizer(f'{backend_name}:transform_types') is not None + assert get_optimizer(f'{backend_name}:write_hls') is not None + assert get_flow(f'{backend_name}:ip') is not None + assert get_flow(f'{backend_name}:write').requires == [f'{backend_name}:ip'] + + +@pytest.mark.parametrize( + 'backend,compiler,definition', + [('Altera', 'ahls', None), ('oneAPI', 'icpx', 'HLS4ML_ONEAPI')], +) +@pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) +def test_altera_family_generated_project(tmp_path, backend, compiler, definition, io_type): + keras_model = tf.keras.Sequential([tf.keras.Input(shape=(4,)), tf.keras.layers.Dense(2)]) + config = hls4ml.utils.config_from_keras_model(keras_model, backend=backend) + output_dir = tmp_path / f'{backend}-{io_type}' + + hls_model = hls4ml.converters.convert_from_keras_model( + keras_model, + hls_config=config, + output_dir=str(output_dir), + backend=backend, + io_type=io_type, + ) + hls_model.write() + + cmake = (output_dir / 'CMakeLists.txt').read_text() + assert f'set(CMAKE_CXX_COMPILER {compiler})' in cmake + if definition is None: + assert 'add_compile_definitions(HLS4ML_ONEAPI)' not in cmake + else: + assert f'add_compile_definitions({definition})' in cmake + + compatibility_header = (output_dir / 'src/firmware/nnet_utils/hls4ml_sycl.h').read_text() + assert '#ifdef HLS4ML_ONEAPI' in compatibility_header + assert 'namespace hls4ml_sycl_ext = sycl::ext::intel;' in compatibility_header + assert 'namespace hls4ml_sycl_ext = sycl::ext::altera;' in compatibility_header + + generated_sources = [ + output_dir / 'src/firmware/myproject.h', + output_dir / 'src/firmware/myproject.cpp', + output_dir / 'src/myproject_test.cpp', + output_dir / 'src/myproject_bridge.cpp', + ] + generated_text = '\n'.join(path.read_text() for path in generated_sources) + assert 'hls4ml_sycl_ext::' in generated_text + assert 'hls4ml_sycl_ext::experimental::pipe<' in generated_text + assert 'sycl::ext::altera::' not in generated_text + assert 'sycl::ext::intel::' not in generated_text + + assert Path(output_dir / 'src/firmware/nnet_utils/nnet_common.h').exists() From 4620783146adb70a973441189b63fbe180f4f388 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Wed, 26 Aug 2026 00:37:03 -0500 Subject: [PATCH 7/9] pre-commit fixes --- hls4ml/templates/altera/firmware/myproject.h | 7 +++---- hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/hls4ml/templates/altera/firmware/myproject.h b/hls4ml/templates/altera/firmware/myproject.h index 1fd0a8a561..e371cf91e0 100644 --- a/hls4ml/templates/altera/firmware/myproject.h +++ b/hls4ml/templates/altera/firmware/myproject.h @@ -7,8 +7,7 @@ // currently this is fixed -using PipeProps = decltype( - sycl::ext::oneapi::experimental::properties(hls4ml_sycl_ext::experimental::ready_latency<0>)); +using PipeProps = decltype(sycl::ext::oneapi::experimental::properties(hls4ml_sycl_ext::experimental::ready_latency<0>)); // Need to declare the input and output pipes @@ -21,8 +20,8 @@ struct MyProject { // kernel property method to config invocation interface auto get(sycl::ext::oneapi::experimental::properties_tag) { - return sycl::ext::oneapi::experimental::properties{ - hls4ml_sycl_ext::experimental::streaming_interface<>, hls4ml_sycl_ext::experimental::pipelined<>}; + return sycl::ext::oneapi::experimental::properties{hls4ml_sycl_ext::experimental::streaming_interface<>, + hls4ml_sycl_ext::experimental::pipelined<>}; } SYCL_EXTERNAL void operator()() const; diff --git a/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h b/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h index 05e1b06dcc..2ab42b557e 100644 --- a/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h +++ b/hls4ml/templates/altera/firmware/nnet_utils/nnet_common.h @@ -1,8 +1,8 @@ #ifndef NNET_COMMON_H_ #define NNET_COMMON_H_ -#include "nnet_helpers.h" #include "hls4ml_sycl.h" +#include "nnet_helpers.h" typedef ac_fixed<16, 6> table_default_t; From 03d78a0d9e3549bdbfb9a1d85110890c00226cb6 Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Wed, 26 Aug 2026 00:50:33 -0500 Subject: [PATCH 8/9] Copilot status.rst formatting issue fix Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> --- docs/intro/status.rst | 2 -- 1 file changed, 2 deletions(-) diff --git a/docs/intro/status.rst b/docs/intro/status.rst index 921ada2292..35dd3f3ab7 100644 --- a/docs/intro/status.rst +++ b/docs/intro/status.rst @@ -51,8 +51,6 @@ HLS backends: * oneAPI (to be superseded by Altera) * XLS (experimental) -======= end - A summary of the on-going status of the ``hls4ml`` tool is in the table below. .. table:: hls4ml Supported Features From 62c8dbd58a0a056ae12f6829897c19ee8874974b Mon Sep 17 00:00:00 2001 From: Jovan Mitrevski Date: Wed, 26 Aug 2026 16:48:37 -0500 Subject: [PATCH 9/9] add back oneAPI tests --- test/pytest/ci-template.yml | 2 +- test/pytest/conftest.py | 4 +++- test/pytest/synthesis_helpers.py | 2 ++ test/pytest/test_activations.py | 2 +- test/pytest/test_batchnorm.py | 2 +- test/pytest/test_bit_exact_grouped_conv.py | 14 +++++------ test/pytest/test_bit_exact_zeropadding.py | 8 +++---- test/pytest/test_conv1d.py | 4 ++++ test/pytest/test_embed.py | 4 ++++ test/pytest/test_globalpooling.py | 4 ++-- test/pytest/test_keras_api.py | 8 ++++--- test/pytest/test_keras_v3_api.py | 12 +++++----- test/pytest/test_merge.py | 10 ++++---- test/pytest/test_multi_dense.py | 1 + test/pytest/test_multiout_network.py | 2 +- test/pytest/test_pointwiseconv.py | 8 +++++-- test/pytest/test_pooling.py | 8 +++---- test/pytest/test_pytorch_api.py | 28 +++++++++++----------- test/pytest/test_qeinsum.py | 7 ++++-- test/pytest/test_qkeras.py | 22 ++++++++--------- test/pytest/test_qkerasV3.py | 26 ++++++++++---------- test/pytest/test_qonnx.py | 1 + test/pytest/test_recurrent_pytorch.py | 14 +++++------ test/pytest/test_repack_stream.py | 5 ++-- test/pytest/test_report.py | 6 +++-- test/pytest/test_reshape.py | 2 +- test/pytest/test_rnn.py | 8 +++++++ test/pytest/test_serialization.py | 4 ++-- test/pytest/test_stream_clone.py | 4 ++-- test/pytest/test_transpose_concat.py | 6 ++++- test/pytest/test_upsampling.py | 2 +- test/pytest/test_zeropadding.py | 2 +- 32 files changed, 135 insertions(+), 97 deletions(-) diff --git a/test/pytest/ci-template.yml b/test/pytest/ci-template.yml index 570bebb2e4..ac68990e03 100644 --- a/test/pytest/ci-template.yml +++ b/test/pytest/ci-template.yml @@ -28,7 +28,7 @@ - chmod +x cmd_vitis_${VITIS_VERSION}/vitis-run - export PATH=$PWD/cmd_vitis_${VITIS_VERSION}:$PATH - # Load Intel oneAPI environment variables for the Altera backend + # Load Intel oneAPI environment variables for the oneAPI backend - source /opt/intel/oneapi/setvars.sh --force script: - cd test/pytest diff --git a/test/pytest/conftest.py b/test/pytest/conftest.py index 536cc22b23..31813239e9 100644 --- a/test/pytest/conftest.py +++ b/test/pytest/conftest.py @@ -58,12 +58,14 @@ def synthesis_config(): 'Vivado': os.getenv('VIVADO_VERSION', '2020.1'), 'Vitis': os.getenv('VITIS_VERSION', '2024.1'), 'Quartus': os.getenv('QUARTUS_VERSION', 'latest'), - 'Altera': os.getenv('ONEAPI_VERSION', '2025.0.1'), + 'Altera': os.getenv('AHLS_VERSION', '2026.1.0'), # this doesn't actually work + 'oneAPI': os.getenv('ONEAPI_VERSION', '2025.0.1'), }, 'build_args': { 'Vivado': {'csim': False, 'synth': True, 'export': False}, 'Vitis': {'csim': False, 'synth': True, 'export': False}, 'Quartus': {'synth': True, 'fpgasynth': False}, 'Altera': {'build_type': 'report', 'run': False}, + 'oneAPI': {'build_type': 'report', 'run': False}, }, } diff --git a/test/pytest/synthesis_helpers.py b/test/pytest/synthesis_helpers.py index e660974402..2b7ef8f97f 100644 --- a/test/pytest/synthesis_helpers.py +++ b/test/pytest/synthesis_helpers.py @@ -121,6 +121,7 @@ def compare_altera_backend(data, baseline): 'Vivado': compare_vitis_backend, 'Vitis': compare_vitis_backend, 'Altera': compare_altera_backend, + 'oneAPI': compare_altera_backend, } @@ -128,6 +129,7 @@ def compare_altera_backend(data, baseline): 'Vivado': {'CSynthesisReport'}, 'Vitis': {'CSynthesisReport'}, 'Altera': {'report'}, + 'oneAPI': {'report'}, } diff --git a/test/pytest/test_activations.py b/test/pytest/test_activations.py index fe66c0dda5..bc55959cb1 100644 --- a/test/pytest/test_activations.py +++ b/test/pytest/test_activations.py @@ -13,7 +13,7 @@ # Variable 'name' is simply used as an identifier for the activation -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Catapult', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Catapult', 'Quartus', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('shape, io_type', [((8,), 'io_parallel'), ((8,), 'io_stream'), ((8, 8, 3), 'io_stream')]) @pytest.mark.parametrize( 'activation, name', diff --git a/test/pytest/test_batchnorm.py b/test/pytest/test_batchnorm.py index c92fea647e..390d89022d 100644 --- a/test/pytest/test_batchnorm.py +++ b/test/pytest/test_batchnorm.py @@ -29,7 +29,7 @@ def model(request): @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'Altera', 'oneAPI']) @pytest.mark.parametrize('model', [True, False], indirect=True) def test_batchnorm(test_case_id, model, data, backend, io_type): default_precision = 'fixed<32, 1>' diff --git a/test/pytest/test_bit_exact_grouped_conv.py b/test/pytest/test_bit_exact_grouped_conv.py index 4a069761b7..bce400453a 100644 --- a/test/pytest/test_bit_exact_grouped_conv.py +++ b/test/pytest/test_bit_exact_grouped_conv.py @@ -48,7 +48,7 @@ def _find(hls_model, cls, name): return next(node for node in hls_model.graph.values() if isinstance(node, cls) and node.name == name) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera', 'oneAPI']) @pytest.mark.parametrize('n_chan, groups', [(16, 16), (16, 4), (16, 1)], ids=['depthwise', 'grouped', 'dense']) def test_bit_exact_grouped_conv1d(test_case_id, backend, n_chan, groups): with QuantizerConfigScope(f0=4, i0=4): @@ -60,7 +60,7 @@ def test_bit_exact_grouped_conv1d(test_case_id, backend, n_chan, groups): data = np.random.default_rng(0).standard_normal((1000, 16, n_chan)).astype(np.float32) r_keras = trace_minmax(model, data, return_results=True) - precision = 'ac_fixed<2,0>' if backend == 'Altera' else 'ap_fixed<1,0>' + precision = 'ac_fixed<2,0>' if backend in ('Altera', 'oneAPI') else 'ap_fixed<1,0>' hls_config = {'Model': {'Precision': precision, 'ReuseFactor': 1, 'Strategy': 'latency'}} output_dir = str(test_root_path / test_case_id) hls_model = convert_from_keras_model( @@ -70,12 +70,12 @@ def test_bit_exact_grouped_conv1d(test_case_id, backend, n_chan, groups): conv = _find(hls_model, Conv1D, 'cg') _assert_exactly_representable(r_keras, *_result_kif(conv)) - # Per-channel check; skipped for Altera, which transposes conv weights after the pass. - if backend != 'Altera': + # Per-channel check; skipped for Altera-family backends, which transpose conv weights after the pass. + if backend not in ('Altera', 'oneAPI'): _assert_exactly_representable(r_keras, *produce_kif(conv)) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera', 'oneAPI']) @pytest.mark.parametrize('n_chan, groups', [(4, 4), (4, 2), (4, 1)], ids=['depthwise', 'grouped', 'dense']) def test_bit_exact_grouped_conv2d(test_case_id, backend, n_chan, groups): with QuantizerConfigScope(f0=4, i0=4): @@ -87,7 +87,7 @@ def test_bit_exact_grouped_conv2d(test_case_id, backend, n_chan, groups): data = np.random.default_rng(1).standard_normal((500, 8, 8, n_chan)).astype(np.float32) r_keras = trace_minmax(model, data, return_results=True) - precision = 'ac_fixed<2,0>' if backend == 'Altera' else 'ap_fixed<1,0>' + precision = 'ac_fixed<2,0>' if backend in ('Altera', 'oneAPI') else 'ap_fixed<1,0>' hls_config = {'Model': {'Precision': precision, 'ReuseFactor': 1, 'Strategy': 'latency'}} output_dir = str(test_root_path / test_case_id) hls_model = convert_from_keras_model( @@ -96,5 +96,5 @@ def test_bit_exact_grouped_conv2d(test_case_id, backend, n_chan, groups): conv = _find(hls_model, Conv2D, 'cg') _assert_exactly_representable(r_keras, *_result_kif(conv)) - if backend != 'Altera': + if backend not in ('Altera', 'oneAPI'): _assert_exactly_representable(r_keras, *produce_kif(conv)) diff --git a/test/pytest/test_bit_exact_zeropadding.py b/test/pytest/test_bit_exact_zeropadding.py index 8293151ea2..99ea81486a 100644 --- a/test/pytest/test_bit_exact_zeropadding.py +++ b/test/pytest/test_bit_exact_zeropadding.py @@ -26,7 +26,7 @@ test_root_path = Path(__file__).parent -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel']) def test_bit_exact_zeropadding1d(test_case_id, backend, io_type): """ZeroPadding1D between two quantized Conv1D layers must convert via the @@ -41,7 +41,7 @@ def test_bit_exact_zeropadding1d(test_case_id, backend, io_type): data = np.random.default_rng(0).standard_normal((1000, 16, 8)).astype(np.float32) r_keras = trace_minmax(model, data, return_results=True) - precision = 'ac_fixed<2,0>' if backend == 'Altera' else 'ap_fixed<1,0>' + precision = 'ac_fixed<2,0>' if backend in ('Altera', 'oneAPI') else 'ap_fixed<1,0>' hls_config = {'Model': {'Precision': precision, 'ReuseFactor': 1, 'Strategy': 'latency'}} output_dir = str(test_root_path / test_case_id) hls_model = convert_from_keras_model( @@ -53,7 +53,7 @@ def test_bit_exact_zeropadding1d(test_case_id, backend, io_type): np.testing.assert_array_equal(r_keras, r_hls) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel']) def test_bit_exact_zeropadding2d(test_case_id, backend, io_type): """ZeroPadding2D between two quantized Conv2D layers must convert via the @@ -68,7 +68,7 @@ def test_bit_exact_zeropadding2d(test_case_id, backend, io_type): data = np.random.default_rng(1).standard_normal((500, 8, 8, 4)).astype(np.float32) r_keras = trace_minmax(model, data, return_results=True) - precision = 'ac_fixed<2,0>' if backend == 'Altera' else 'ap_fixed<1,0>' + precision = 'ac_fixed<2,0>' if backend in ('Altera', 'oneAPI') else 'ap_fixed<1,0>' hls_config = {'Model': {'Precision': precision, 'ReuseFactor': 1, 'Strategy': 'latency'}} output_dir = str(test_root_path / test_case_id) hls_model = convert_from_keras_model( diff --git a/test/pytest/test_conv1d.py b/test/pytest/test_conv1d.py index baed79be05..a65586914f 100644 --- a/test/pytest/test_conv1d.py +++ b/test/pytest/test_conv1d.py @@ -70,6 +70,8 @@ def hls_model(keras_model, request, test_case_id): ('Quartus', 'io_stream', 'resource'), ('Altera', 'io_parallel', 'resource'), ('Altera', 'io_stream', 'resource'), + ('oneAPI', 'io_parallel', 'resource'), + ('oneAPI', 'io_stream', 'resource'), ('Vivado', 'io_parallel', 'resource'), ('Vivado', 'io_parallel', 'latency'), ('Vivado', 'io_stream', 'latency'), @@ -87,6 +89,8 @@ def hls_model(keras_model, request, test_case_id): 'Quartus_io_stream_resource', 'Altera_io_parallel_resource', 'Altera_io_stream_resource', + 'oneAPI_io_parallel_resource', + 'oneAPI_io_stream_resource', 'Vivado_io_parallel_resource', 'Vivado_io_parallel_latency', 'Vivado_io_stream_latency', diff --git a/test/pytest/test_embed.py b/test/pytest/test_embed.py index 4601c9d48b..5e4e685d47 100644 --- a/test/pytest/test_embed.py +++ b/test/pytest/test_embed.py @@ -48,11 +48,13 @@ def hls_model(keras_model, request, test_case_id): ('Quartus', 'io_parallel'), ('Catapult', 'io_parallel'), ('Altera', 'io_parallel'), + ('oneAPI', 'io_parallel'), ('Vivado', 'io_stream'), ('Vitis', 'io_stream'), ('Quartus', 'io_stream'), ('Catapult', 'io_stream'), ('Altera', 'io_stream'), + ('oneAPI', 'io_stream'), ], ids=[ 'vivado_parallel', @@ -60,11 +62,13 @@ def hls_model(keras_model, request, test_case_id): 'quartus_parallel', 'catapult_parallel', 'altera_parallel', + 'oneapi_parallel', 'vivado_stream', 'vitis_stream', 'quartus_stream', 'catapult_stream', 'altera_stream', + 'oneapi_stream', ], indirect=True, ) diff --git a/test/pytest/test_globalpooling.py b/test/pytest/test_globalpooling.py index d02e15b3a8..c9566d6e2c 100644 --- a/test/pytest/test_globalpooling.py +++ b/test/pytest/test_globalpooling.py @@ -32,7 +32,7 @@ def keras_model_1d(request): return model, model_type, keepdims -@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'Altera']) +@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'Altera', 'oneAPI']) @pytest.mark.parametrize( 'keras_model_1d', [ @@ -89,7 +89,7 @@ def keras_model_2d(request): return model, model_type, keepdims -@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'Altera']) +@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'Altera', 'oneAPI']) @pytest.mark.parametrize( 'keras_model_2d', [ diff --git a/test/pytest/test_keras_api.py b/test/pytest/test_keras_api.py index f88748fbf3..96a48b4b9b 100644 --- a/test/pytest/test_keras_api.py +++ b/test/pytest/test_keras_api.py @@ -26,7 +26,7 @@ test_root_path = Path(__file__).parent -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_dense(test_case_id, backend, io_type, synthesis_config): if backend == 'XLS' and io_type != 'io_parallel': @@ -97,7 +97,7 @@ def test_dense(test_case_id, backend, io_type, synthesis_config): ids=['relu', 'leaky_relu', 'elu', 'prelu', 'sigmoid'], ) # ThresholdedReLU(theta=1.0)]) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_activations(test_case_id, activation_function, backend, io_type, synthesis_config): if backend == 'XLS' and io_type != 'io_parallel': @@ -141,6 +141,7 @@ def test_activations(test_case_id, activation_function, backend, io_type, synthe ('Vitis', 'Latency'), ('Quartus', 'Resource'), ('Altera', 'Resource'), + ('oneAPI', 'Resource'), ('XLS', 'Latency'), ], ) @@ -237,6 +238,7 @@ def test_conv1d(test_case_id, padds, backend, strategy, io_type, synthesis_confi ('Vitis', 'Latency'), ('Quartus', 'Resource'), ('Altera', 'Resource'), + ('oneAPI', 'Resource'), ('XLS', 'Latency'), ], ) @@ -431,7 +433,7 @@ def test_depthwise1d(test_case_id, backend, io_type, synthesis_config): ) @pytest.mark.parametrize('padds', padds_options) @pytest.mark.parametrize('chans', chans_options) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) def test_pooling(test_case_id, pooling, padds, chans, backend, synthesis_config): assert '1D' in pooling.__name__ or '2D' in pooling.__name__ diff --git a/test/pytest/test_keras_v3_api.py b/test/pytest/test_keras_v3_api.py index bcc3816c87..d9bc7246c4 100644 --- a/test/pytest/test_keras_v3_api.py +++ b/test/pytest/test_keras_v3_api.py @@ -29,7 +29,7 @@ test_root_path = Path(__file__).parent -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'Catapult', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'Catapult', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_dense(test_case_id, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -93,7 +93,7 @@ def test_dense(test_case_id, backend, io_type): Activation(activation='sigmoid', name='sigmoid'), ], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_activations(test_case_id, activation_function, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -129,7 +129,7 @@ def test_activations(test_case_id, activation_function, backend, io_type): @pytest.mark.parametrize('padds', padds_options) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'Catapult', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'Catapult', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) @pytest.mark.parametrize('activation', ['elu', 'relu']) def test_conv1d(test_case_id, padds, backend, io_type, activation): @@ -216,7 +216,7 @@ def test_conv1d(test_case_id, padds, backend, io_type, activation): @pytest.mark.parametrize('chans', chans_options) @pytest.mark.parametrize('padds', padds_options) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'Catapult', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'Catapult', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_conv2d(test_case_id, chans, padds, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -383,7 +383,7 @@ def test_depthwise1d(test_case_id, backend, io_type): @pytest.mark.parametrize('pooling', pooling_layers) @pytest.mark.parametrize('padds', padds_options) @pytest.mark.parametrize('chans', chans_options) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'Catapult', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'Catapult', 'XLS']) def test_pooling(test_case_id, pooling, padds, chans, backend): assert '1D' in pooling.__name__ or '2D' in pooling.__name__ @@ -504,7 +504,7 @@ def test_pooling(test_case_id, pooling, padds, chans, backend): # assert hls_pool.attributes['pad_right'] == 0 -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_reused_layer(test_case_id, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': diff --git a/test/pytest/test_merge.py b/test/pytest/test_merge.py index a96061ef10..7db031ab01 100644 --- a/test/pytest/test_merge.py +++ b/test/pytest/test_merge.py @@ -12,7 +12,7 @@ @pytest.mark.parametrize('merge_layer', [Add, Average, Maximum, Minimum, Multiply, Subtract]) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('swap_inputs', [True, False]) def test_merge(test_case_id, merge_layer, io_type, backend, swap_inputs): if backend == 'XLS' and io_type != 'io_parallel': @@ -50,7 +50,7 @@ def test_merge(test_case_id, merge_layer, io_type, backend, swap_inputs): @pytest.mark.parametrize('axes', [1]) @pytest.mark.parametrize('io_type', ['io_parallel']) # No io_stream implementation yet -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) def test_dot(test_case_id, axes, io_type, backend): if backend == 'XLS' and io_type != 'io_parallel': pytest.skip(f'XLS backend only supports IOType: io_parallel, but got: {io_type}') @@ -82,7 +82,7 @@ def test_dot(test_case_id, axes, io_type, backend): @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) def test_concatenate1d(test_case_id, io_type, backend): if backend == 'XLS' and io_type != 'io_parallel': pytest.skip(f'XLS backend only supports IOType: io_parallel, but got: {io_type}') @@ -115,7 +115,7 @@ def test_concatenate1d(test_case_id, io_type, backend): @pytest.mark.parametrize('axis', [1, 2]) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) def test_concatenate2d(test_case_id, axis, io_type, backend): if backend == 'XLS' and io_type != 'io_parallel': pytest.skip(f'XLS backend only supports IOType: io_parallel, but got: {io_type}') @@ -151,7 +151,7 @@ def test_concatenate2d(test_case_id, axis, io_type, backend): @pytest.mark.parametrize('axis', [1, 2, 3]) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) def test_concatenate3d(test_case_id, axis, io_type, backend): if backend == 'XLS' and io_type != 'io_parallel': pytest.skip(f'XLS backend only supports IOType: io_parallel, but got: {io_type}') diff --git a/test/pytest/test_multi_dense.py b/test/pytest/test_multi_dense.py index d712c0f52a..d778ca1d64 100644 --- a/test/pytest/test_multi_dense.py +++ b/test/pytest/test_multi_dense.py @@ -19,6 +19,7 @@ ('Vitis', 'Resource'), ('Quartus', 'Resource'), ('Altera', 'Resource'), + ('oneAPI', 'Resource'), ('Catapult', 'Latency'), ('Catapult', 'Resource'), ('XLS', 'Latency'), diff --git a/test/pytest/test_multiout_network.py b/test/pytest/test_multiout_network.py index f14d8a9d4d..778a49583a 100644 --- a/test/pytest/test_multiout_network.py +++ b/test/pytest/test_multiout_network.py @@ -69,7 +69,7 @@ def test_multi_output_nn(test_case_id, model, data, backend: str, io_type: str): assert np.allclose(r_hls[1], r_keras[1], atol=1e-5, rtol=0) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Vitis', 'Catapult', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Vitis', 'Catapult', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) @pytest.mark.parametrize('strategy', ['latency', 'resource']) def test_multi_output_nn_corner_cases( diff --git a/test/pytest/test_pointwiseconv.py b/test/pytest/test_pointwiseconv.py index 68cb615e6f..9fd43ff1b1 100644 --- a/test/pytest/test_pointwiseconv.py +++ b/test/pytest/test_pointwiseconv.py @@ -25,6 +25,8 @@ ('Quartus', 'io_stream', 'resource', 1), ('Altera', 'io_parallel', 'resource', 1), ('Altera', 'io_stream', 'resource', 1), + ('oneAPI', 'io_parallel', 'resource', 1), + ('oneAPI', 'io_stream', 'resource', 1), ('Vivado', 'io_parallel', 'resource', 1), ('Vitis', 'io_parallel', 'resource', 1), ('Vivado', 'io_parallel', 'latency', 1), @@ -79,7 +81,7 @@ def test_pointwiseconv1d(test_case_id, chans, padds, strides, backend, io_type, hls_model.compile() hls_prediction = hls_model.predict(X_input).reshape(keras_prediction.shape) - if backend != 'XLS' and not (backend in ['Quartus', 'Altera'] and io_type == 'io_stream'): + if backend != 'XLS' and not (backend in ['Quartus', 'Altera', 'oneAPI'] and io_type == 'io_stream'): # Quartus io_stream does not currently have a special pointwise implementation assert 'Pointwise' in list(hls_model.graph.values())[1].class_name np.testing.assert_allclose(hls_prediction, keras_prediction, rtol=0, atol=0.001) @@ -95,6 +97,8 @@ def test_pointwiseconv1d(test_case_id, chans, padds, strides, backend, io_type, ('Quartus', 'io_stream', 'resource'), ('Altera', 'io_parallel', 'resource'), ('Altera', 'io_stream', 'resource'), + ('oneAPI', 'io_parallel', 'resource'), + ('oneAPI', 'io_stream', 'resource'), ('Vivado', 'io_parallel', 'resource'), ('Vivado', 'io_parallel', 'latency'), ('Vivado', 'io_stream', 'latency'), @@ -144,7 +148,7 @@ def test_pointwiseconv2d(test_case_id, chans, padds, strides, backend, io_type, hls_model.compile() hls_prediction = hls_model.predict(X_input).reshape(keras_prediction.shape) - if backend != 'XLS' and not (backend in ['Quartus', 'Altera'] and io_type == 'io_stream'): + if backend != 'XLS' and not (backend in ['Quartus', 'Altera', 'oneAPI'] and io_type == 'io_stream'): # Quartus io_stream does not currently have a special pointwise implementation assert 'Pointwise' in list(hls_model.graph.values())[1].class_name np.testing.assert_allclose(hls_prediction, keras_prediction, rtol=0, atol=0.001) diff --git a/test/pytest/test_pooling.py b/test/pytest/test_pooling.py index dbfc4eb9f4..313576969c 100644 --- a/test/pytest/test_pooling.py +++ b/test/pytest/test_pooling.py @@ -49,7 +49,7 @@ def keras_model_1d(request, backend): return model, model_type, pads, strides -@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize( 'keras_model_1d', [ @@ -92,7 +92,7 @@ def test_pool1d(test_case_id, backend, keras_model_1d, data_1d, io_type): np.testing.assert_allclose(y_keras, y_hls, rtol=0, atol=atol, verbose=True) -@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Altera']) +@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Altera', 'oneAPI']) @pytest.mark.parametrize( 'keras_model_1d', [ @@ -149,7 +149,7 @@ def keras_model_2d(request, backend): return model, model_type, pads, strides -@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Catapult', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize( 'keras_model_2d', [ @@ -192,7 +192,7 @@ def test_pool2d(test_case_id, backend, keras_model_2d, data_2d, io_type): np.testing.assert_allclose(y_keras, y_hls, rtol=0, atol=atol, verbose=True) -@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Altera']) +@pytest.mark.parametrize('backend', ['Quartus', 'Vitis', 'Vivado', 'Altera', 'oneAPI']) @pytest.mark.parametrize( 'keras_model_2d', [ diff --git a/test/pytest/test_pytorch_api.py b/test/pytest/test_pytorch_api.py index 73a5395b6b..36bb7c7795 100644 --- a/test/pytest/test_pytorch_api.py +++ b/test/pytest/test_pytorch_api.py @@ -22,7 +22,7 @@ def forward(self, x): return self.linear(x) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_linear(test_case_id, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -76,7 +76,7 @@ def test_linear(test_case_id, backend, io_type): ], ids=['softmax', 'relu', 'tanh', 'leaky_relu', 'elu', 'prelu', 'sigmoid', 'threshold'], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_activations(test_case_id, activation_function, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -191,7 +191,7 @@ def forward(self, x): ], ids=['softmax', 'relu', 'tanh', 'leaky_relu', 'elu', 'sigmoid', 'threshold'], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_activation_functionals(test_case_id, activation_function, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -227,7 +227,7 @@ def test_activation_functionals(test_case_id, activation_function, backend, io_t @pytest.mark.parametrize('padds', padds_options) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_conv1d(test_case_id, padds, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -336,7 +336,7 @@ def test_conv1d(test_case_id, padds, backend, io_type): @pytest.mark.parametrize('padds', padds_options) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_conv2d(test_case_id, padds, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -493,7 +493,7 @@ def test_conv2d(test_case_id, padds, backend, io_type): @pytest.mark.parametrize('pooling', pooling_layers, ids=['MaxPool1d', 'MaxPool2d', 'AvgPool1d', 'AvgPool2d']) @pytest.mark.parametrize('padds', padds_options) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) def test_pooling(test_case_id, pooling, padds, backend): assert '1d' in pooling.__name__ or '2d' in pooling.__name__ @@ -613,7 +613,7 @@ def forward(self, x): return self.bn(x) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_bn(test_case_id, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -657,7 +657,7 @@ def forward(self, x): # TODO: this test fails for XLS due to PyTorch weights shape mismatch. -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_squeeze(test_case_id, backend, io_type): model = SqueezeModel() @@ -679,8 +679,8 @@ def test_squeeze(test_case_id, backend, io_type): np.testing.assert_allclose(hls_prediction, pytorch_prediction, rtol=1e-2, atol=0.01) - # Altera doesn't use the Repack class (and for io_stream does not use inplace variables) - if io_type == 'io_parallel' or backend == 'Altera': + # Altera-family backends don't use the Repack class (and for io_stream do not use inplace variables) + if io_type == 'io_parallel' or backend in ('Altera', 'oneAPI'): assert list(hls_model.get_layers())[1].attributes['class_name'] == 'Reshape' assert list(hls_model.get_layers())[1].attributes['target_shape'] == [1, 5] assert list(hls_model.get_layers())[3].attributes['class_name'] == 'Reshape' @@ -692,7 +692,7 @@ def test_squeeze(test_case_id, backend, io_type): assert list(hls_model.get_layers())[3].attributes['target_shape'] == [3] -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) def test_flatten(test_case_id, backend): input = torch.randn(1, 1, 5, 5) model = nn.Sequential(nn.Conv2d(1, 32, 5, 1, 1), nn.Flatten(), nn.ReLU()) @@ -736,7 +736,7 @@ def forward(self, x): return x -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_skipped_layers(test_case_id, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': @@ -771,7 +771,7 @@ def test_skipped_layers(test_case_id, backend, io_type): np.testing.assert_allclose(hls_prediction, pytorch_prediction, rtol=0, atol=5e-2) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel']) # Only io_parallel for now @pytest.mark.parametrize('tensor_rank', [2, 3]) def test_remove_transpose(test_case_id, backend, io_type, tensor_rank): @@ -838,7 +838,7 @@ def forward(self, x): np.testing.assert_allclose(hls_prediction, pytorch_prediction, rtol=0, atol=5e-2) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_view(test_case_id, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': diff --git a/test/pytest/test_qeinsum.py b/test/pytest/test_qeinsum.py index 9192d1b1da..a63a294555 100644 --- a/test/pytest/test_qeinsum.py +++ b/test/pytest/test_qeinsum.py @@ -19,7 +19,7 @@ @pytest.mark.parametrize('strategy', ['latency']) @pytest.mark.parametrize('io_type', ['io_parallel']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera', 'oneAPI']) @pytest.mark.parametrize( 'operation', [ @@ -41,7 +41,10 @@ def test_einsum_dense(test_case_id, backend, io_type, strategy, operation): data = np.random.randn(1000, *inp0_shape).astype(np.float32), np.random.randn(1000, *inp1_shape).astype(np.float32) output_dir = str(test_root_path / test_case_id) hls_config = { - 'Model': {'Precision': 'ap_fixed<1,0>' if backend != 'Altera' else 'ac_fixed<2,0>', 'ReuseFactor': 1}, + 'Model': { + 'Precision': 'ac_fixed<2,0>' if backend in ('Altera', 'oneAPI') else 'ap_fixed<1,0>', + 'ReuseFactor': 1, + }, 'Strategy': strategy, } diff --git a/test/pytest/test_qkeras.py b/test/pytest/test_qkeras.py index a750a7f0ea..0e33a0311d 100644 --- a/test/pytest/test_qkeras.py +++ b/test/pytest/test_qkeras.py @@ -135,7 +135,7 @@ def randX_100_16(): # https://github.com/fastmachinelearning/hls4ml/issues/381 # @pytest.mark.parametrize('bits', [4, 6, 8]) @pytest.mark.parametrize('bits,alpha', [(4, 1), (4, 'auto_po2')]) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_single_dense_activation_exact(test_case_id, randX_100_16, bits, alpha, backend, io_type): """ @@ -200,7 +200,7 @@ def randX_100_10(): @pytest.mark.parametrize( 'quantizer', [(quantized_tanh(8)), (quantized_sigmoid(5)), (quantized_sigmoid(7, use_real_sigmoid=True))] ) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_quantizer_special(test_case_id, randX_1000_1, quantizer, backend, io_type): """ @@ -239,7 +239,7 @@ def test_quantizer_special(test_case_id, randX_1000_1, quantizer, backend, io_ty (7, 10, binary(), quantized_bits(5, 2), binary(), False, True), ], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_btnn(test_case_id, make_btnn, randX_100_10, backend, io_type): model, is_xnor, test_no = make_btnn @@ -282,7 +282,7 @@ def randX_1000_1(): (quantized_relu(10, 5)), ], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_quantizer(test_case_id, randX_1000_1, quantizer, backend, io_type): """ @@ -317,7 +317,7 @@ def test_quantizer(test_case_id, randX_1000_1, quantizer, backend, io_type): (quantized_relu(10, 2, negative_slope=0.25)), ], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_relu_negative_slope(test_case_id, randX_1000_1, quantizer, backend, io_type): """ @@ -398,7 +398,7 @@ def test_qactivation_kwarg(test_case_id, randX_100_10, activation_quantizer, wei assert sum(wrong) / len(wrong) <= 0.005 -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_quantizer_parsing(test_case_id, randX_100_10, backend, io_type): X = randX_100_10 @@ -437,7 +437,7 @@ def randX_100_8_8_1(): return np.random.rand(100, 8, 8, 1) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_qconv2dbn(test_case_id, randX_100_8_8_1, backend, io_type): """ @@ -518,7 +518,7 @@ def test_qdepthwiseconv2d(test_case_id, randX_10_32_32_3, backend, io_type): np.testing.assert_allclose(y_qkeras, y_hls4ml.reshape(y_qkeras.shape), rtol=1e-2, atol=0.01) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) @pytest.mark.parametrize('strategy', ['Latency', 'Resource']) def test_quantised_po2_bit_width(test_case_id, backend, io_type, strategy): @@ -556,7 +556,7 @@ def test_quantised_po2_bit_width(test_case_id, backend, io_type, strategy): np.testing.assert_allclose(y_hls.flatten(), y_keras.flatten(), rtol=2e-2) -@pytest.mark.parametrize('backend', ['Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Quartus', 'Altera', 'oneAPI']) def test_qsimplernn(test_case_id, backend): """ Test proper handling of QSimpleRNN. @@ -591,7 +591,7 @@ def test_qsimplernn(test_case_id, backend): np.testing.assert_allclose(y_qkeras, y_hls4ml.reshape(y_qkeras.shape), atol=0.1) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera', 'oneAPI']) def test_qlstm(test_case_id, backend): """ Test proper handling of QLSTM. @@ -627,7 +627,7 @@ def test_qlstm(test_case_id, backend): np.testing.assert_allclose(y_qkeras, y_hls4ml.reshape(y_qkeras.shape), atol=0.1) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera', 'oneAPI']) def test_qgru(test_case_id, backend): """ Test proper handling of QGRU. diff --git a/test/pytest/test_qkerasV3.py b/test/pytest/test_qkerasV3.py index 7a12c7bfaa..c48437e2e2 100644 --- a/test/pytest/test_qkerasV3.py +++ b/test/pytest/test_qkerasV3.py @@ -148,7 +148,7 @@ def randX_100_16(): # https://github.com/fastmachinelearning/hls4ml/issues/381 # @pytest.mark.parametrize('bits', [4, 6, 8]) @pytest.mark.parametrize('bits,alpha', [(4, 1), (4, 'auto_po2')]) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_single_dense_activation_exact(test_case_id, randX_100_16, bits, alpha, backend, io_type): """ @@ -211,7 +211,7 @@ def randX_100_10(): @pytest.mark.parametrize( 'quantizer', [(quantized_tanh(8)), (quantized_sigmoid(5)), (quantized_sigmoid(7, use_real_sigmoid=True))] ) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_quantizer_special(test_case_id, randX_1000_1, quantizer, backend, io_type): """ @@ -250,7 +250,7 @@ def test_quantizer_special(test_case_id, randX_1000_1, quantizer, backend, io_ty (7, 10, binary(), quantized_bits(5, 2), binary(), False, True), ], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_btnn(test_case_id, make_btnn, randX_100_10, backend, io_type): model, is_xnor, test_no = make_btnn @@ -293,7 +293,7 @@ def randX_1000_1(): (quantized_relu(10, 5)), ], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_quantizer(test_case_id, randX_1000_1, quantizer, backend, io_type): """ @@ -328,7 +328,7 @@ def test_quantizer(test_case_id, randX_1000_1, quantizer, backend, io_type): (quantized_relu(10, 2, negative_slope=0.25)), ], ) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_relu_negative_slope(test_case_id, randX_1000_1, quantizer, backend, io_type): """ @@ -400,7 +400,7 @@ def test_qactivation_kwarg(test_case_id, randX_100_10, activation_quantizer, wei assert sum(wrong) / len(wrong) <= 0.005 -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel']) def test_qkeras_einsum_dense(test_case_id, randX_100_10, backend, io_type): """ @@ -440,7 +440,7 @@ def test_qkeras_einsum_dense(test_case_id, randX_100_10, backend, io_type): np.testing.assert_array_equal(y_qkeras, y_hls4ml.reshape(y_qkeras.shape)) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_quantizer_parsing(test_case_id, randX_100_10, backend, io_type): X = randX_100_10 @@ -479,7 +479,7 @@ def randX_100_8_8_1(): return np.random.rand(100, 8, 8, 1) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) @pytest.mark.parametrize( 'qconv_layer,input_shape,input_data_shape,layer_kwargs', @@ -531,7 +531,7 @@ def test_qconv_activation_kwarg(test_case_id, qconv_layer, input_shape, input_da np.testing.assert_array_equal(y_qkeras, y_hls4ml.reshape(y_qkeras.shape)) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_qconv2dbn(test_case_id, randX_100_8_8_1, backend, io_type): """ @@ -621,7 +621,7 @@ def test_qdepthwiseconv2d(test_case_id, randX_10_32_32_3, backend, io_type, quan np.testing.assert_allclose(y_qkeras, y_hls4ml.reshape(y_qkeras.shape), rtol=1e-2, atol=0.01) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) @pytest.mark.parametrize('strategy', ['Latency', 'Resource']) def test_quantised_po2_bit_width(test_case_id, backend, io_type, strategy): @@ -659,7 +659,7 @@ def test_quantised_po2_bit_width(test_case_id, backend, io_type, strategy): np.testing.assert_allclose(y_hls.flatten(), y_keras.flatten(), rtol=2e-2) -@pytest.mark.parametrize('backend', ['Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Quartus', 'Altera', 'oneAPI']) def test_qsimplernn(test_case_id, backend): """ Test proper handling of QSimpleRNN. @@ -694,7 +694,7 @@ def test_qsimplernn(test_case_id, backend): np.testing.assert_allclose(y_qkeras, y_hls4ml.reshape(y_qkeras.shape), atol=0.1) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera', 'oneAPI']) def test_qlstm(test_case_id, backend): """ Test proper handling of QLSTM. @@ -730,7 +730,7 @@ def test_qlstm(test_case_id, backend): np.testing.assert_allclose(y_qkeras, y_hls4ml.reshape(y_qkeras.shape), atol=0.1) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Altera', 'oneAPI']) def test_qgru(test_case_id, backend): """ Test proper handling of QGRU. diff --git a/test/pytest/test_qonnx.py b/test/pytest/test_qonnx.py index d84475332c..dfc9042905 100644 --- a/test/pytest/test_qonnx.py +++ b/test/pytest/test_qonnx.py @@ -507,6 +507,7 @@ def test_simple_model(test_case_id, request, model_name, io_type, backend): ('Vitis', 'Resource'), ('Vitis', 'Latency'), ('Altera', 'Resource'), + ('oneAPI', 'Resource'), ], ) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) diff --git a/test/pytest/test_recurrent_pytorch.py b/test/pytest/test_recurrent_pytorch.py index 5ed573b2ec..61c68e878f 100644 --- a/test/pytest/test_recurrent_pytorch.py +++ b/test/pytest/test_recurrent_pytorch.py @@ -31,7 +31,7 @@ def forward(self, x): return output -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel']) def test_gru(test_case_id, backend, io_type): model = GRUNet() @@ -62,7 +62,7 @@ def test_gru(test_case_id, backend, io_type): np.testing.assert_allclose(hls_prediction, pytorch_prediction, rtol=0, atol=1e-1) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_stream']) def test_gru_stream(test_case_id, backend, io_type): model = GRUNetStream() @@ -107,7 +107,7 @@ def forward(self, x): return output -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel']) def test_lstm(test_case_id, backend, io_type): model = LSTM() @@ -148,10 +148,10 @@ def test_lstm(test_case_id, backend, io_type): np.testing.assert_allclose(hls_prediction, pytorch_prediction, rtol=0, atol=1e-1) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_stream']) def test_lstm_stream(test_case_id, backend, io_type): - if not (backend in ('Quartus', 'Altera') and io_type == 'io_stream'): + if not (backend in ('Quartus', 'Altera', 'oneAPI') and io_type == 'io_stream'): model = LSTMStream() model.eval() @@ -190,10 +190,10 @@ def forward(self, x, h0): return output -@pytest.mark.parametrize('backend', ['Quartus', 'Altera']) +@pytest.mark.parametrize('backend', ['Quartus', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel']) def test_rnn(test_case_id, backend, io_type): - if not (backend in ('Quartus', 'Altera') and io_type == 'io_stream'): + if not (backend in ('Quartus', 'Altera', 'oneAPI') and io_type == 'io_stream'): model = RNN() model.eval() diff --git a/test/pytest/test_repack_stream.py b/test/pytest/test_repack_stream.py index 37545a884b..b9e32dfe3e 100644 --- a/test/pytest/test_repack_stream.py +++ b/test/pytest/test_repack_stream.py @@ -9,7 +9,7 @@ test_root_path = Path(__file__).parent -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'Altera', 'oneAPI']) def test_repack_precision(test_case_id, backend: str): inp = keras.Input(shape=(3, 3), name='inp') out = keras.layers.Reshape((3, 3), name='reshape')(inp) @@ -34,7 +34,7 @@ def test_repack_precision(test_case_id, backend: str): ) model_hls.write() # Not needed for this test, but useful for debugging - reshape_name = 'reshape' if backend == 'Altera' else 'repack_reshape' + reshape_name = 'reshape' if backend in ('Altera', 'oneAPI') else 'repack_reshape' assert reshape_name in model_hls.graph, f'{reshape_name} not found in graph' repack_precision = model_hls.graph[reshape_name].attributes['result_t'].precision assert repack_precision.integer == 10, 'Precision mismatch' @@ -48,6 +48,7 @@ def test_repack_precision(test_case_id, backend: str): [ ('Quartus', 'Resource'), ('Altera', 'Resource'), + ('oneAPI', 'Resource'), ('Vivado', 'Resource'), ('Vitis', 'Resource'), ('Vivado', 'Latency'), diff --git a/test/pytest/test_report.py b/test/pytest/test_report.py index 02cce4a6a9..ffa4547eeb 100644 --- a/test/pytest/test_report.py +++ b/test/pytest/test_report.py @@ -100,6 +100,7 @@ def backend_configs(): + ' ALMs: 4520.0 N/A N/A \n\n', }, } + config_dict['oneAPI'] = {**config_dict['Altera'], 'backend': 'oneAPI', 'report_backend': 'Altera'} return config_dict @@ -116,7 +117,8 @@ def hls_model_setup(request, test_case_id, backend_configs, tmp_path): config = hls4ml.utils.config_from_keras_model(model, granularity='model') output_dir = str(tmp_path / test_case_id) - test_report_dir = test_root_path / f'test_report/{backend_config["backend"]}' + report_backend = backend_config.get('report_backend', backend_config['backend']) + test_report_dir = test_root_path / f'test_report/{report_backend}' hls_model = hls4ml.converters.convert_from_keras_model( model, @@ -136,7 +138,7 @@ def hls_model_setup(request, test_case_id, backend_configs, tmp_path): yield output_dir, backend_config -@pytest.mark.parametrize('hls_model_setup', ['Vivado', 'Altera'], indirect=True) +@pytest.mark.parametrize('hls_model_setup', ['Vivado', 'Altera', 'oneAPI'], indirect=True) def test_report(hls_model_setup, capsys): """Tests that the report parsing and printing functions work for different backends.""" output_dir, backend_config = hls_model_setup diff --git a/test/pytest/test_reshape.py b/test/pytest/test_reshape.py index bc265fe6bc..8bb448ab92 100755 --- a/test/pytest/test_reshape.py +++ b/test/pytest/test_reshape.py @@ -20,7 +20,7 @@ def randX_20_10(): return randX(20, 10) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Catapult', 'Altera', 'XLS']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Catapult', 'Altera', 'oneAPI', 'XLS']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_reshape_parallel(test_case_id, randX_20_10, backend, io_type): if backend == 'XLS' and io_type != 'io_parallel': diff --git a/test/pytest/test_rnn.py b/test/pytest/test_rnn.py index eaed92d794..c2092b3d94 100644 --- a/test/pytest/test_rnn.py +++ b/test/pytest/test_rnn.py @@ -160,12 +160,14 @@ def create_model_accuracy(rnn_layer, return_sequences): [ (SimpleRNN, 'Quartus', 'io_parallel', 'resource'), (SimpleRNN, 'Altera', 'io_parallel', 'resource'), + (SimpleRNN, 'oneAPI', 'io_parallel', 'resource'), (LSTM, 'Vivado', 'io_parallel', 'resource'), (LSTM, 'Vivado', 'io_parallel', 'latency'), (LSTM, 'Vitis', 'io_parallel', 'resource'), (LSTM, 'Vitis', 'io_parallel', 'latency'), (LSTM, 'Quartus', 'io_parallel', 'resource'), (LSTM, 'Altera', 'io_parallel', 'resource'), + (LSTM, 'oneAPI', 'io_parallel', 'resource'), (LSTM, 'Vivado', 'io_stream', 'resource'), (LSTM, 'Vivado', 'io_stream', 'latency'), (LSTM, 'Vitis', 'io_stream', 'resource'), @@ -176,12 +178,14 @@ def create_model_accuracy(rnn_layer, return_sequences): (GRU, 'Vitis', 'io_parallel', 'latency'), (GRU, 'Quartus', 'io_parallel', 'resource'), (GRU, 'Altera', 'io_parallel', 'resource'), + (GRU, 'oneAPI', 'io_parallel', 'resource'), (GRU, 'Vivado', 'io_stream', 'resource'), (GRU, 'Vivado', 'io_stream', 'latency'), (GRU, 'Vitis', 'io_stream', 'resource'), (GRU, 'Vitis', 'io_stream', 'latency'), (GRU, 'Quartus', 'io_stream', 'resource'), (GRU, 'Altera', 'io_stream', 'resource'), + (GRU, 'oneAPI', 'io_stream', 'resource'), (Bidirectional, 'Vivado', 'io_parallel', 'resource'), (Bidirectional, 'Vivado', 'io_parallel', 'latency'), (Bidirectional, 'Vitis', 'io_parallel', 'resource'), @@ -190,12 +194,14 @@ def create_model_accuracy(rnn_layer, return_sequences): ids=[ 'SimpleRNN-Quartus-io_parallel-resource', 'SimpleRNN-Altera-io_parallel-resource', + 'SimpleRNN-oneAPI-io_parallel-resource', 'LSTM-Vivado-io_parallel-resource', 'LSTM-Vivado-io_parallel-latency', 'LSTM-Vitis-io_parallel-resource', 'LSTM-Vitis-io_parallel-latency', 'LSTM-Quartus-io_parallel-resource', 'LSTM-Altera-io_parallel-resource', + 'LSTM-oneAPI-io_parallel-resource', 'LSTM-Vivado-io_stream-resource', 'LSTM-Vivado-io_stream-latency', 'LSTM-Vitis-io_stream-resource', @@ -206,12 +212,14 @@ def create_model_accuracy(rnn_layer, return_sequences): 'GRU-Vitis-io_parallel-latency', 'GRU-Quartus-io_parallel-resource', 'GRU-Altera-io_parallel-resource', + 'GRU-oneAPI-io_parallel-resource', 'GRU-Vivado-io_stream-resource', 'GRU-Vivado-io_stream-latency', 'GRU-Vitis-io_stream-resource', 'GRU-Vitis-io_stream-latency', 'GRU-Quartus-io_stream-resource', 'GRU-Altera-io_stream-resource', + 'GRU-oneAPI-io_stream-resource', 'Bidirectional-Vivado-io_parallel-resource', 'Bidirectional-Vivado-io_parallel-latency', 'Bidirectional-Vitis-io_parallel-resource', diff --git a/test/pytest/test_serialization.py b/test/pytest/test_serialization.py index c993d6be44..7999c71fda 100644 --- a/test/pytest/test_serialization.py +++ b/test/pytest/test_serialization.py @@ -32,7 +32,7 @@ def qkeras_model(input_shape): return model -@pytest.mark.parametrize('backend', ['Vitis', 'Catapult', 'Altera']) +@pytest.mark.parametrize('backend', ['Vitis', 'Catapult', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_save_load__model(test_case_id, io_type, backend): input_shape = (8, 8, 3) @@ -194,7 +194,7 @@ def test_save_load_qonnx_model(test_case_id, backend): np.testing.assert_equal(y_original, y_clone) -@pytest.mark.parametrize('backend', ['Vitis', 'Catapult', 'Altera']) +@pytest.mark.parametrize('backend', ['Vitis', 'Catapult', 'Altera', 'oneAPI']) @pytest.mark.parametrize('io_type', ['io_parallel', 'io_stream']) def test_linking_project(test_case_id, io_type, backend): input_shape = (8, 8, 3) diff --git a/test/pytest/test_stream_clone.py b/test/pytest/test_stream_clone.py index d86e10acc8..03ff13db35 100644 --- a/test/pytest/test_stream_clone.py +++ b/test/pytest/test_stream_clone.py @@ -70,7 +70,7 @@ def data(): return X -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Vitis', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Vitis', 'Altera', 'oneAPI']) def test_multi_clone(test_case_id, model_multi_clone, data, backend: str): output_dir = str(test_root_path / test_case_id) hls_config = hls4ml.utils.config_from_keras_model( @@ -90,7 +90,7 @@ def test_multi_clone(test_case_id, model_multi_clone, data, backend: str): np.testing.assert_allclose(r_hls, r_keras, atol=1e-4, rtol=0) -@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Vitis', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Quartus', 'Vitis', 'Altera', 'oneAPI']) def test_clone_precision_inheritance(test_case_id, model_clone_precision_inheritance, data, backend: str): output_dir = str(test_root_path / test_case_id) layer_config = { diff --git a/test/pytest/test_transpose_concat.py b/test/pytest/test_transpose_concat.py index b52b68ff75..7590f8c207 100644 --- a/test/pytest/test_transpose_concat.py +++ b/test/pytest/test_transpose_concat.py @@ -50,10 +50,12 @@ def hls_model(keras_model, request, test_case_id): ('io_stream', 'Vitis'), ('io_stream', 'Quartus'), ('io_stream', 'Altera'), + ('io_stream', 'oneAPI'), ('io_parallel', 'Vivado'), ('io_parallel', 'Vitis'), ('io_parallel', 'Quartus'), ('io_parallel', 'Altera'), + ('io_parallel', 'oneAPI'), ], indirect=True, ids=[ @@ -61,10 +63,12 @@ def hls_model(keras_model, request, test_case_id): 'vitis_streamq', 'quartus_stream', 'altera_stream', + 'oneapi_stream', 'vivado_parallel', 'vitis_parallel', 'quartus_parallel', 'altera_parallel', + 'oneapi_parallel', ], ) def test_accuracy(data, keras_model, hls_model): @@ -93,7 +97,7 @@ def data_highdim(): @pytest.mark.parametrize('io_type', ['io_stream', 'io_parallel']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Altera', 'oneAPI']) def test_highdim_permute(test_case_id, data_highdim, keras_model_highdim, io_type, backend): X = data_highdim model = keras_model_highdim diff --git a/test/pytest/test_upsampling.py b/test/pytest/test_upsampling.py index 497b115c6f..e084f768d7 100644 --- a/test/pytest/test_upsampling.py +++ b/test/pytest/test_upsampling.py @@ -46,7 +46,7 @@ def keras_model_2d(): @pytest.mark.parametrize('io_type', ['io_stream', 'io_parallel']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'Altera', 'oneAPI']) @pytest.mark.parametrize('model_type', ['1d', '2d']) def test_upsampling(test_case_id, keras_model_1d, keras_model_2d, data_1d, data_2d, model_type, io_type, backend): if model_type == '1d': diff --git a/test/pytest/test_zeropadding.py b/test/pytest/test_zeropadding.py index 63d7cf8bdb..a6e2a9810b 100644 --- a/test/pytest/test_zeropadding.py +++ b/test/pytest/test_zeropadding.py @@ -50,7 +50,7 @@ def keras_model_2d(): @pytest.mark.parametrize('io_type', ['io_stream', 'io_parallel']) -@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'Altera']) +@pytest.mark.parametrize('backend', ['Vivado', 'Vitis', 'Quartus', 'Catapult', 'Altera', 'oneAPI']) @pytest.mark.parametrize('model_type', ['1d', '2d']) def test_zeropadding(test_case_id, keras_model_1d, keras_model_2d, data_1d, data_2d, model_type, io_type, backend): if model_type == '1d':