Blame opae-libs/pyopae/README.md

Packit 534379
# OPAE Python Bindings
Packit 534379
Packit 534379
OPAE (Open Programmable Acceleration Engine) now includes Python bindings for
Packit 534379
interacting with FPGA resources. The OPAE Python API is built on top of the
Packit 534379
OPAE C++ Core API and its object model. Because of this, developing OPAE
Packit 534379
applications in Python is very similar to developing OPAE applications in C++
Packit 534379
which significantly reduces the learning curve required to adapt to the Python API.
Packit 534379
While the object model remains the same, some static factory functions in the
Packit 534379
OPAE C++ Core API have been moved to module level methods in the OPAE Python API
Packit 534379
with the exception of the properties class. The goal of the OPAE Python API is
Packit 534379
to enable fast prototyping, test automation, infrastructure managment, and an
Packit 534379
easy to use framework for FPGA resource interactions that don't rely on software
Packit 534379
algorithms with a high runtime complexity.
Packit 534379
Packit 534379
Currently, the only Python package that is part of OPAE is `opae.fpga`
Packit 534379
Packit 534379
## Implementation
Packit 534379
Packit 534379
The OPAE Python API is implemented by creating a Python extension using `pybind11
Packit 534379
<http://pybind11.readthedocs.io/en/stable>`_.
Packit 534379
This extension is created by using the pybind11 API which relies mostly on
Packit 534379
macros and compile time introspection to define the module initialization point
Packit 534379
as well as type converters between OPAE C++ Core types and OPAE Python types.
Packit 534379
Packit 534379
## Benefits
Packit 534379
The major benefits of using pybind11 for developing the OPAE Python API
Packit 534379
include, but are not limited to, the following features of pybind11:
Packit 534379
Packit 534379
* Uses C++ 11 standard library although it can use C++ 14 or C++17.
Packit 534379
* Automatic conversions of shared_ptr types
Packit 534379
* Built-in support for numpy and Eigen numerical libraries
Packit 534379
* Interoperable with the Python C API
Packit 534379
Packit 534379
## Runtime Requirements
Packit 534379
Because opae.fpga is built on top of the opae-cxx-core API, it does require
Packit 534379
that the runtime libraries for both opae-cxx-core and opae-c be installed on
Packit 534379
the system (as well as any other libraries they depend on). Those libraries can
Packit 534379
be installed using the opae-libs package (from either RPM or DEB format -
Packit 534379
depending on your Linux distribution).
Packit 534379
Packit 534379
## Installation
Packit 534379
Packit 534379
## Python Wheels
Packit 534379
The preferred method of installation is to use a binary wheel package for your
Packit 534379
version of Python.
Packit 534379
Packit 534379
The following table lists example names for different Python versions and
Packit 534379
platforms.
Packit 534379
Packit 534379
| Python Version | Python ABI      | Linux Platform | Package Name |
Packit 534379
|----------------|-----------------|----------------|--------------|
Packit 534379
| 2.7 | CPython w/ UCS4 | x86_64 | opae.fpga.<release>-cp27-cp27mu-linux_x86_64.whl |
Packit 534379
| 3.4 | CPython w/ UCS4 | x86_64 | opae.fpga.<release>-cp34-cp34mu-linux_x86_64.whl |
Packit 534379
| 3.6 | CPython w/ UCS4 | x86_64 | opae.fpga.<release>-cp36-cp36mu-linux_x86_64.whl |
Packit 534379
Packit 534379
Packit 534379
opae.fpga is currently not available in the Python Package Index but once it
Packit 534379
does become available, one should be able to install using pip by simply typing
Packit 534379
the following:
Packit 534379
```shell
Packit 534379
> pip install --user opae.fpga
Packit 534379
```
Packit 534379
Packit 534379
## Installing From Source
Packit 534379
In addition to the runtime libraries mentioned above, installing from source
Packit 534379
does require that the OPAE header files be installed as well as those header
Packit 534379
files for pybind11. The former can be installed with the opae-devel package and
Packit 534379
the latter can be installed by installing pybind11 Python module.
Packit 534379
Packit 534379
### Example Installation
Packit 534379
The following example shows how to build from source by installing the
Packit 534379
prerequisites before running the setup.py file.
Packit 534379
Packit 534379
```shell
Packit 534379
>sudo yum install opae-libs-<release>.x86_64.rpm
Packit 534379
>sudo yum install opae-devel-<release>.x86_64.rpm
Packit 534379
>pip install --user pybind11
Packit 534379
>pip install --user opae.fpga-<release>.tar.gz
Packit 534379
```
Packit 534379
Packit 534379
Packit 534379
_NOTE_: The `pip` examples above use the `--user` flag to avoid requiring root
Packit 534379
permissions. Those packages will be installed in the user's `site-packages`
Packit 534379
directory found in the user's `.local` directory.
Packit 534379
Packit 534379
## Example Scripts
Packit 534379
The following example is an implementation of the sample, hello_fpga.c, which
Packit 534379
is designed to configure the NLB0 diagnostic accelerator for a simple loopback.
Packit 534379
Packit 534379
Packit 534379
```Python
Packit 534379
import time
Packit 534379
from opae import fpga
Packit 534379
Packit 534379
NLB0 = "d8424dc4-a4a3-c413-f89e-433683f9040b"
Packit 534379
CTL = 0x138
Packit 534379
CFG = 0x140
Packit 534379
NUM_LINES = 0x130
Packit 534379
SRC_ADDR = 0x0120
Packit 534379
DST_ADDR = 0x0128
Packit 534379
DSM_ADDR = 0x0110
Packit 534379
DSM_STATUS = 0x40
Packit 534379
Packit 534379
def cl_align(addr):
Packit 534379
    return addr >> 6
Packit 534379
Packit 534379
tokens = fpga.enumerate(type=fpga.ACCELERATOR, guid=NLB0)
Packit 534379
assert tokens, "Could not enumerate accelerator: {}".format(NlB0)
Packit 534379
Packit 534379
with fpga.open(tokens[0], fpga.OPEN_SHARED) as handle:
Packit 534379
    src = fpga.allocate_shared_buffer(handle, 4096)
Packit 534379
    dst = fpga.allocate_shared_buffer(handle, 4096)
Packit 534379
    dsm = fpga.allocate_shared_buffer(handle, 4096)
Packit 534379
    handle.write_csr32(CTL, 0)
Packit 534379
    handle.write_csr32(CTL, 1)
Packit 534379
    handle.write_csr64(DSM_ADDR, dsm.io_address())
Packit 534379
    handle.write_csr64(SRC_ADDR, cl_align(src.io_address())) # cacheline-aligned
Packit 534379
    handle.write_csr64(DST_ADDR, cl_align(dst.io_address())) # cacheline-aligned
Packit 534379
    handle.write_csr32(CFG, 0x42000)
Packit 534379
    handle.write_csr32(NUM_LINES, 4096/64)
Packit 534379
    handle.write_csr32(CTL, 3)
Packit 534379
    while dsm[DSM_STATUS] & 0x1 == 0:
Packit 534379
        time.sleep(0.001)
Packit 534379
    handle.write_csr32(CTL, 7)
Packit 534379
Packit 534379
```
Packit 534379
Packit 534379
This example shows how one might reprogram (Partial Reconfiguration) an
Packit 534379
accelerator on a given bus, 0x5e, using a bitstream file, m0.gbs.
Packit 534379
Packit 534379
```Python
Packit 534379
from opae import fpga
Packit 534379
Packit 534379
BUS = 0x5e
Packit 534379
GBS = 'm0.gbs'
Packit 534379
tokens = fpga.enumerate(type=fpga.DEVICE, bus=BUS)
Packit 534379
assert tokens, "Could not enumerate device on bus: {}".format(BUS)
Packit 534379
with open(GBS, 'rb') as fd, fpga.open(tokens[0]) as device:
Packit 534379
    device.reconfigure(0, fd)
Packit 534379
```
Packit 534379