|
Packit |
534379 |
# Quick Start Guide #
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```eval_rst
|
|
Packit |
534379 |
.. toctree::
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## Overview ##
|
|
Packit |
534379 |
The OPAE C library is a lightweight user-space library that provides
|
|
Packit |
534379 |
abstraction for FPGA resources in a compute environment. Built on top of the
|
|
Packit |
534379 |
OPAE Intel® FPGA driver stack that supports Intel® FPGA platforms, the library
|
|
Packit |
534379 |
abstracts away hardware specific and OS specific details and exposes the
|
|
Packit |
534379 |
underlying FPGA resources as a set of features accessible from within
|
|
Packit |
534379 |
software programs running on the host.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
These features include the acceleration logic preconfigured on the
|
|
Packit |
534379 |
device, as well as functions to manage and reconfigure the
|
|
Packit |
534379 |
device. Hence, the library is able to enalbe user applications to
|
|
Packit |
534379 |
transparently and seamlessly leverage FPGA-based acceleration.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
In this document, we will explore the initial steps on how to setup
|
|
Packit |
534379 |
the required libraries and utilities to use the FPGA devices.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## Installing the OPAE Intel® FPGA drivers ##
|
|
Packit |
534379 |
|
|
Packit |
534379 |
If you do not have access to an Intel® Xeon® processor with integrated
|
|
Packit |
534379 |
FPGA, or a programmable FPGA acceleration card for Intel® Xeon®
|
|
Packit |
534379 |
processors, you will not be able to run the examples below. However, you can
|
|
Packit |
534379 |
still make use of the AFU simulation environment (ASE) to develop and test
|
|
Packit |
534379 |
accelerator RTL with OPAE applications.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
For more information about ASE, see the [OPAE AFU Simulation Environment
|
|
Packit |
534379 |
(ASE) User Guide](../../ase_userguide/ase_userguide.html).
|
|
Packit |
534379 |
|
|
Packit |
534379 |
As part of the OPAE SDK release, we provide DKMS-based RPM and DEB packages for
|
|
Packit |
534379 |
distributions using RPM (e.g. Redhat, Fedora, Centos) and DEB (eg. Ubuntu) package managers.
|
|
Packit |
534379 |
Download these package from the respective [release page on
|
|
Packit |
534379 |
GitHub](https://github.com/OPAE/opae-sdk/releases) - they are named
|
|
Packit |
534379 |
`opae-intel-fpga-driver-x.y.z-r.x86_64.rpm` and `opae-intel-fpga-driver_x.y.z-r_amd64.deb`, with `x.y.z-r` being the respective OPAE
|
|
Packit |
534379 |
release's version number.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```eval_rst
|
|
Packit |
534379 |
.. note::
|
|
Packit |
534379 |
The packages require that the DKMS (Dynamic Kernel Module System)
|
|
Packit |
534379 |
package, version greater than 2.2, is already installed.
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
For RPM-based distributions:
|
|
Packit |
534379 |
```console
|
|
Packit |
534379 |
$ sudo yum install opae-intel-fpga-driver-<release>.x86_64.rpm
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
For DEB-based distributions:
|
|
Packit |
534379 |
```console
|
|
Packit |
534379 |
$ sudo dpkg -i opae-intel-fpga-driver_<release>_amd64.deb
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
## Installing the OPAE SDK from rpm or deb packages ##
|
|
Packit |
534379 |
See the [OPAE Installation Guide](/fpga-doc/docs/fpga_api/install_guide/installation_guide.html)
|
|
Packit |
534379 |
for information about OPAE RPM and DEB packages.
|
|
Packit |
534379 |
Assuming the packages are already downloaded and exist in the current folder,
|
|
Packit |
534379 |
then use the commands below to install the OPAE library, tools, and development
|
|
Packit |
534379 |
headers.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
For rpm packages:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```console
|
|
Packit |
534379 |
$ sudo yum install opae-libs-<release>.x86_64.rpm
|
|
Packit |
534379 |
$ sudo yum install opae-tools-<release>.x86_64.rpm
|
|
Packit |
534379 |
$ sudo yum install opae-tools-extra-<release>.x86_64.rpm
|
|
Packit |
534379 |
$ sudo yum install opae-devel-<release>.x86_64.rpm
|
|
Packit |
534379 |
$ sudo yum install opae-ase-<release>.x86_64.rpm
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
For deb packages:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```console
|
|
Packit |
534379 |
$ sudo dpkg -i opae-libs-<release>.x86_64.deb
|
|
Packit |
534379 |
$ sudo dpkg -i opae-tools-<release>.x86_64.deb
|
|
Packit |
534379 |
$ sudo dpkg -i opae-tools-extra-<release>.x86_64.deb
|
|
Packit |
534379 |
$ sudo dpkg -i opae-devel-<release>.x86_64.deb
|
|
Packit |
534379 |
$ sudo dpkg -i opae-ase-<release>.x86_64.deb
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
To use OPAE in the simulation environment, you also need to install the AFU
|
|
Packit |
534379 |
Simulation Environment (ASE) package:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
rpm:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```console
|
|
Packit |
534379 |
$ sudo yum install opae-ase-<release>.x86_64.rpm
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
deb:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```console
|
|
Packit |
534379 |
$ sudo dpkg -i opae-<release>.x86_64-ase.deb
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```eval_rst
|
|
Packit |
534379 |
.. note:
|
|
Packit |
534379 |
If you want to install all the packages, you can also do:
|
|
Packit |
534379 |
rpm: $ sudo yum install opae-*.rpm
|
|
Packit |
534379 |
deb: $ sudo dpkg -i opae-*.deb
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## Building and installing the OPAE SDK from source ##
|
|
Packit |
534379 |
Download the OPAE SDK source package from the respective [release page on
|
|
Packit |
534379 |
GitHub](https://github.com/OPAE/opae-sdk/releases) - click the `Source code
|
|
Packit |
534379 |
(tar.gz)` link under "Downloads".
|
|
Packit |
534379 |
|
|
Packit |
534379 |
After downloading the source, unpack, configure, and compile it:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```console
|
|
Packit |
534379 |
tar xfvz opae-sdk-<release>.tar.gz
|
|
Packit |
534379 |
cd opae-sdk-<release>
|
|
Packit |
534379 |
mkdir build
|
|
Packit |
534379 |
cd build
|
|
Packit |
534379 |
cmake .. -DOPAE_BUILD_SIM=ON
|
|
Packit |
534379 |
make
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
By default, the OPAE SDK will install into `/usr/local` if you also issue the following:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```console
|
|
Packit |
534379 |
make install
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
You can change this installation prefix from `/usr/local` into something else
|
|
Packit |
534379 |
by adding `-DCMAKE_INSTALL_PREFIX=<new prefix>` to the `cmake` command above.
|
|
Packit |
534379 |
The remainder of this guide assumes you installed into `/usr/local`.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## Configuring the FPGA (loading an FPGA AFU)##
|
|
Packit |
534379 |
|
|
Packit |
534379 |
The *fpgaconf* tool exercises the AFU reconfiguration
|
|
Packit |
534379 |
functionality. It shows how to read a bitstream from a disk file,
|
|
Packit |
534379 |
check its validity and compatability, and then injects it into FPGA to
|
|
Packit |
534379 |
be configured as a new AFU, which can then be discovered and used by
|
|
Packit |
534379 |
user applications.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
For this step you require a valid green bitstream (GBS) file. To
|
|
Packit |
534379 |
reconfigure the FPGA slot, you can issue following command as system
|
|
Packit |
534379 |
administrator (*root*):
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```console
|
|
Packit |
534379 |
$ sudo fpgaconf -b 0x5e <filename>.gbs
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
The `-b` parameter to *fpgaconf* indicates the *target bus number* of the
|
|
Packit |
534379 |
FPGA slot to be reconfigured. Alternatively, you can also specify the
|
|
Packit |
534379 |
*target socket number* of the FPGA using the `-s` parameter.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```console
|
|
Packit |
534379 |
$ sudo fpgaconf --help
|
|
Packit |
534379 |
Usage:
|
|
Packit |
534379 |
fpgaconf [-hvn] [-b <bus>] [-d <device>] [-f <function>] [-s <socket>] <gbs>
|
|
Packit |
534379 |
|
|
Packit |
534379 |
-h,--help Print this help
|
|
Packit |
534379 |
-v,--verbose Increase verbosity
|
|
Packit |
534379 |
-n,--dry-run Don't actually perform actions
|
|
Packit |
534379 |
-b,--bus Set target bus number
|
|
Packit |
534379 |
-d,--device Set target device number
|
|
Packit |
534379 |
-f,--function Set target function number
|
|
Packit |
534379 |
-s,--socket Set target socket number
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```eval_rst
|
|
Packit |
534379 |
.. note::
|
|
Packit |
534379 |
The sample application on the Building a Sample Application
|
|
Packit |
534379 |
section requires loading of an AFU called "Native Loopback
|
|
Packit |
534379 |
Adapter" (NLB) on the FPGA. Please refer to the NLB documentation
|
|
Packit |
534379 |
for the location of the NLB's green bitstream. You also can verify
|
|
Packit |
534379 |
if the NLB green bitstream has already been loaded into the FPGA
|
|
Packit |
534379 |
slot by typing the following command and checking the output
|
|
Packit |
534379 |
matches the following:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
$ cat /sys/class/fpga/intel-fpga-dev.0/intel-fpga-port.0/afu_id
|
|
Packit |
534379 |
|
|
Packit |
534379 |
d8424dc4a4a3c413f89e433683f9040b
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
## Building a sample application ##
|
|
Packit |
534379 |
The library source include code samples. Use these samples to learn
|
|
Packit |
534379 |
how to call functions in the library. Build and run these samples as
|
|
Packit |
534379 |
quick sanity checks to determine if your installation and environment
|
|
Packit |
534379 |
are set up properly.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
In this guide, we will build *hello\_fpga.c*. This is the "Hello
|
|
Packit |
534379 |
World!" example of using the library. This code searches for a
|
|
Packit |
534379 |
predefined and known AFU called "Native Loopback Adapter" on the
|
|
Packit |
534379 |
FPGA. If found, it acquires ownership and then interacts with the AFU
|
|
Packit |
534379 |
by sending it a 2MB message and waiting for the message being echoed
|
|
Packit |
534379 |
back. This coe exercises all major components of the API except for
|
|
Packit |
534379 |
AFU reconfiguration: AFU search, enumeration, access, MMIO, and memory
|
|
Packit |
534379 |
management.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
You can also find the source for `hello\_fpga` in the `samples` directory of the
|
|
Packit |
534379 |
OPAE SDK repository on github.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```c
|
|
Packit |
534379 |
int main(int argc, char *argv[])
|
|
Packit |
534379 |
{
|
|
Packit |
534379 |
fpga_properties filter = NULL;
|
|
Packit |
534379 |
fpga_token afu_token;
|
|
Packit |
534379 |
fpga_handle afu_handle;
|
|
Packit |
534379 |
fpga_guid guid;
|
|
Packit |
534379 |
uint32_t num_matches;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
volatile uint64_t *dsm_ptr = NULL;
|
|
Packit |
534379 |
volatile uint64_t *status_ptr = NULL;
|
|
Packit |
534379 |
volatile uint64_t *input_ptr = NULL;
|
|
Packit |
534379 |
volatile uint64_t *output_ptr = NULL;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
uint64_t dsm_wsid;
|
|
Packit |
534379 |
uint64_t input_wsid;
|
|
Packit |
534379 |
uint64_t output_wsid;
|
|
Packit |
534379 |
fpga_result res = FPGA_OK;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (uuid_parse(NLB0_AFUID, guid) < 0) {
|
|
Packit |
534379 |
fprintf(stderr, "Error parsing guid '%s'\n", NLB0_AFUID);
|
|
Packit |
534379 |
goto out_exit;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Look for accelerator by its "afu_id" */
|
|
Packit |
534379 |
res = fpgaGetProperties(NULL, &filter);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_exit, "creating properties object");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = fpgaPropertiesSetObjectType(filter, FPGA_ACCELERATOR);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_destroy_prop, "setting object type");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = fpgaPropertiesSetGuid(filter, guid);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_destroy_prop, "setting GUID");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* TODO: Add selection via BDF / device ID */
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = fpgaEnumerate(&filter, 1, &afu_token, 1, &num_matches);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_destroy_prop, "enumerating accelerators");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
if (num_matches < 1) {
|
|
Packit |
534379 |
fprintf(stderr, "accelerator not found.\n");
|
|
Packit |
534379 |
res = fpgaDestroyProperties(&filter);
|
|
Packit |
534379 |
return FPGA_INVALID_PARAM;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Open accelerator and map MMIO */
|
|
Packit |
534379 |
res = fpgaOpen(afu_token, &afu_handle, 0);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_destroy_tok, "opening accelerator");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = fpgaMapMMIO(afu_handle, 0, NULL);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_close, "mapping MMIO space");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Allocate buffers */
|
|
Packit |
534379 |
res = fpgaPrepareBuffer(afu_handle, LPBK1_DSM_SIZE,
|
|
Packit |
534379 |
(void **)&dsm_ptr, &dsm_wsid, 0);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_close, "allocating DSM buffer");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = fpgaPrepareBuffer(afu_handle, LPBK1_BUFFER_ALLOCATION_SIZE,
|
|
Packit |
534379 |
(void **)&input_ptr, &input_wsid, 0);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_dsm, "allocating input buffer");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = fpgaPrepareBuffer(afu_handle, LPBK1_BUFFER_ALLOCATION_SIZE,
|
|
Packit |
534379 |
(void **)&output_ptr, &output_wsid, 0);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_input, "allocating output buffer");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
printf("Running Test\n");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Initialize buffers */
|
|
Packit |
534379 |
memset((void *)dsm_ptr, 0, LPBK1_DSM_SIZE);
|
|
Packit |
534379 |
memset((void *)input_ptr, 0xAF, LPBK1_BUFFER_SIZE);
|
|
Packit |
534379 |
memset((void *)output_ptr, 0xBE, LPBK1_BUFFER_SIZE);
|
|
Packit |
534379 |
|
|
Packit |
534379 |
cache_line *cl_ptr = (cache_line *)input_ptr;
|
|
Packit |
534379 |
for (uint32_t i = 0; i < LPBK1_BUFFER_SIZE / CL(1); ++i) {
|
|
Packit |
534379 |
cl_ptr[i].uint[15] = i+1; /* set the last uint in every cacheline */
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Reset accelerator */
|
|
Packit |
534379 |
res = fpgaReset(afu_handle);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_output, "resetting accelerator");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Program DMA addresses */
|
|
Packit |
534379 |
uint64_t iova;
|
|
Packit |
534379 |
res = fpgaGetIOAddress(afu_handle, dsm_wsid, &iova);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_output, "getting DSM IOVA");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = fpgaWriteMMIO64(afu_handle, 0, CSR_AFU_DSM_BASEL, iova);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_output, "writing CSR_AFU_DSM_BASEL");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = fpgaWriteMMIO32(afu_handle, 0, CSR_CTL, 0);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_output, "writing CSR_CFG");
|
|
Packit |
534379 |
res = fpgaWriteMMIO32(afu_handle, 0, CSR_CTL, 1);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_output, "writing CSR_CFG");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = fpgaGetIOAddress(afu_handle, input_wsid, &iova);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_output, "getting input IOVA");
|
|
Packit |
534379 |
res = fpgaWriteMMIO64(afu_handle, 0, CSR_SRC_ADDR, CACHELINE_ALIGNED_ADDR(iova));
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_output, "writing CSR_SRC_ADDR");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = fpgaGetIOAddress(afu_handle, output_wsid, &iova);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_output, "getting output IOVA");
|
|
Packit |
534379 |
res = fpgaWriteMMIO64(afu_handle, 0, CSR_DST_ADDR, CACHELINE_ALIGNED_ADDR(iova));
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_output, "writing CSR_DST_ADDR");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
res = fpgaWriteMMIO32(afu_handle, 0, CSR_NUM_LINES, LPBK1_BUFFER_SIZE / CL(1));
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_output, "writing CSR_NUM_LINES");
|
|
Packit |
534379 |
res = fpgaWriteMMIO32(afu_handle, 0, CSR_CFG, 0x42000);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_output, "writing CSR_CFG");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
status_ptr = dsm_ptr + DSM_STATUS_TEST_COMPLETE/8;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Start the test */
|
|
Packit |
534379 |
res = fpgaWriteMMIO32(afu_handle, 0, CSR_CTL, 3);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_output, "writing CSR_CFG");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Wait for test completion */
|
|
Packit |
534379 |
while (0 == ((*status_ptr) & 0x1)) {
|
|
Packit |
534379 |
usleep(100);
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Stop the device */
|
|
Packit |
534379 |
res = fpgaWriteMMIO32(afu_handle, 0, CSR_CTL, 7);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_output, "writing CSR_CFG");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Check output buffer contents */
|
|
Packit |
534379 |
for (uint32_t i = 0; i < LPBK1_BUFFER_SIZE; i++) {
|
|
Packit |
534379 |
if (((uint8_t*)output_ptr)[i] != ((uint8_t*)input_ptr)[i]) {
|
|
Packit |
534379 |
fprintf(stderr, "Output does NOT match input "
|
|
Packit |
534379 |
"at offset %i!\n", i);
|
|
Packit |
534379 |
break;
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
|
|
Packit |
534379 |
printf("Done Running Test\n");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Release buffers */
|
|
Packit |
534379 |
out_free_output:
|
|
Packit |
534379 |
res = fpgaReleaseBuffer(afu_handle, output_wsid);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_input, "releasing output buffer");
|
|
Packit |
534379 |
out_free_input:
|
|
Packit |
534379 |
res = fpgaReleaseBuffer(afu_handle, input_wsid);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_free_dsm, "releasing input buffer");
|
|
Packit |
534379 |
out_free_dsm:
|
|
Packit |
534379 |
res = fpgaReleaseBuffer(afu_handle, dsm_wsid);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_unmap, "releasing DSM buffer");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Unmap MMIO space */
|
|
Packit |
534379 |
out_unmap:
|
|
Packit |
534379 |
res = fpgaUnmapMMIO(afu_handle, 0);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_close, "unmapping MMIO space");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Release accelerator */
|
|
Packit |
534379 |
out_close:
|
|
Packit |
534379 |
res = fpgaClose(afu_handle);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_destroy_tok, "closing accelerator");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Destroy token */
|
|
Packit |
534379 |
out_destroy_tok:
|
|
Packit |
534379 |
res = fpgaDestroyToken(&afu_token);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_destroy_prop, "destroying token");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
/* Destroy properties object */
|
|
Packit |
534379 |
out_destroy_prop:
|
|
Packit |
534379 |
res = fpgaDestroyProperties(&filter);
|
|
Packit |
534379 |
ON_ERR_GOTO(res, out_exit, "destroying properties object");
|
|
Packit |
534379 |
|
|
Packit |
534379 |
out_exit:
|
|
Packit |
534379 |
return res;
|
|
Packit |
534379 |
|
|
Packit |
534379 |
}
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
Linking with the OPAE library is straightforward. Code using this library
|
|
Packit |
534379 |
should include the header file `fpga.h`. Taking the GCC compiler on
|
|
Packit |
534379 |
Linux as an example, the minimalist compile and link line should look
|
|
Packit |
534379 |
like:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```console
|
|
Packit |
534379 |
$ gcc -std=c99 hello_fpga.c -I/usr/local/include -L/usr/local/lib -lopae-c -luuid -ljson-c -lpthread -o hello_fpga
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```eval_rst
|
|
Packit |
534379 |
.. note:
|
|
Packit |
534379 |
The API uses some features from the C99 language standard. The
|
|
Packit |
534379 |
`-std=c99` switch is required if the compiler does not support C99 by
|
|
Packit |
534379 |
default.
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```eval_rst
|
|
Packit |
534379 |
.. note::
|
|
Packit |
534379 |
Third-party library dependency: The library internally uses
|
|
Packit |
534379 |
`libuuid` and `libjson-c`. But they are not distributed as part of the
|
|
Packit |
534379 |
library. Make sure you have these libraries properly installed.
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
To run the *hello_fpga* application; just issue:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```console
|
|
Packit |
534379 |
$ sudo ./hello_fpga
|
|
Packit |
534379 |
|
|
Packit |
534379 |
Running Test
|
|
Packit |
534379 |
Done
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```eval_rst
|
|
Packit |
534379 |
.. note::
|
|
Packit |
534379 |
In order to successfully run hello\_fpga, user need to configure system hugepage to reserve 2M-hugepages.
|
|
Packit |
534379 |
For example, the command below reserves 20 2M-hugepages:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
$ echo 20 | sudo tee /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages
|
|
Packit |
534379 |
|
|
Packit |
534379 |
For x86_64 architecture CPU, user can use following command to find out avaiable huge page sizes:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
$ grep pse /proc/cpuinfo | uniq
|
|
Packit |
534379 |
flags : ... pse ...
|
|
Packit |
534379 |
|
|
Packit |
534379 |
If this commands returns a non-empty string, 2MB pages are supported:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
$ grep pse /proc/cpuinfo | uniq
|
|
Packit |
534379 |
flags : ... pdpe1gb ...
|
|
Packit |
534379 |
|
|
Packit |
534379 |
If this commands returns a non-empty string, 1GB pages are supported:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```eval_rst
|
|
Packit |
534379 |
.. note::
|
|
Packit |
534379 |
The default configuration for many Linux distribution currently sets a relatively low limit for pinned memory allocations per process (RLIMIT_MEMLOCK, often set to a default of 64kiB).
|
|
Packit |
534379 |
To run an OPAE application which attempts to share more memory than specified by this limit between software and an accelerator, you can either:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
* Run the application as root, or
|
|
Packit |
534379 |
* Increase the limit for locked memory via ulimit:
|
|
Packit |
534379 |
|
|
Packit |
534379 |
$ ulimit -l unlimited
|
|
Packit |
534379 |
|
|
Packit |
534379 |
See the Installation Guide for how to permanently adjust the memlock limit.
|
|
Packit |
534379 |
|
|
Packit |
534379 |
```
|