Altera

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 the Intel oneAPI toolchain and is now continued by the Altera HLS IP Gen toolchain. The functionality and terminology used by hls4ml remain largely unchanged.

The Altera 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 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.

The produced work areas use cmake to build the projects in a style based on Altera HLS IP Gen hls-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 is there if desired.

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.

io_parallel and io_stream

As mentioned in the I/O Types section, io_parallel is for small models, while io_stream is for 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, relying on pipelining within the task for good performance. In contrast, the Vitis backend sometimes uses dataflow with io_parallel.

Namespace

SYCL registers pipe IDs process-wide by their type name, and the pipe names are derived from the layer names. To allow several compiled models to be loaded into the same Python process, the kernel and pipe declarations are placed in a namespace. If the namespace argument is passed to the converter, it is used as given. Otherwise the project name is used, except for the default project name myproject, in which case a random stamp that changes on every write() is appended. To get a deterministic IP, set either project_name or namespace. Two models with the same layer names and the same explicit namespace (or the same non-default project name) cannot be loaded into the same process.