2.4.1. Nanos6 FPGA Architecture API

The following sections list and summarize the Nanos++ FPGA Architecture API. The documentation is for the version 10.

Memory Management

nanos6_fpga_malloc

Allocates memory in the FPGA address space and returns a pointer valid for the FPGA tasks. The returned pointer cannot be dereferenced in the host code.

Arguments:
  • size: Size in bytes to allocate.
  • fpga_addr: Pointer to the FPGA address space as a 64-bit integer.
Return value:
  • NANOS6_FPGA_SUCCESS on success, NANOS6_FPGA_ERROR on error.
typedef enum {
    NANOS6_FPGA_SUCCESS,
    NANOS6_FPGA_ERROR
} nanos6_fpga_stat_t;

nanos6_fpga_stat_t nanos6_fpga_malloc(uint64_t size, uint64_t* fpga_addr);

nanos_fpga_free

nanos6_fpga_stat_t nanos6_fpga_free(uint64_t fpga_addr);

nanos_fpga_memcpy

typedef enum {
    NANOS6_FPGA_DEV_TO_HOST,
    NANOS6_FPGA_HOST_TO_DEV
} nanos6_fpga_copy_t;

nanos6_fpga_stat_t nanos6_fpga_memcpy(
    void* usr_ptr,
    uint64_t fpga_addr,
    uint64_t size,
    nanos6_fpga_copy_t copy_type);

Data copies

These Nanos6 API only can be called inside an FPGA task. They alloy copies to be performed through a single port that can be wider than the data type being copied.

If any of the data copy API calls are used, the fompss-fpga-memory-port-width option is mandatory.

Data accessed through this functions, has to be aligned to the port width. Otherwise this will result in undefined behaviour.

Also, data should to be multiple of the port width. If this cannot be guaranteed, fompss-fpga-check-limits-memory-port option is needed so that no out of bounds data is accessed. Otherwise this will result in undefined behaviour.

nanos6_fpga_memcpy_wideport_in

nanos6_fpga_stat_t nanos6_fpga_memcpy_wideport_in(void* dst, const unsigned long long int addr, const unsigned int num_elems);

Arguments:

  • dst: Pointer to the destination (local) data. It can be any data type.
  • addr: FPGA memory address space where the data is stored.
  • num_elems: Number of elements of the array type to be copied.

nanos6_fpga_memcpy_wideport_out

nanos6_fpga_stat_t nanos6_fpga_memcpy_wideport_out(void* dst, const unsigned long long int addr, const unsigned int num_elems);

Arguments:

  • dst: Pointer to the source (local) data. It can be any data type.
  • addr: FPGA memory address space where the data is written.
  • num_elems: Number of elements of the array type to be copied.

OMPIF cluster API

OMPIF is an API that allows direct FPGA-to-FPGA communication.

OMPIF API resembles MPI API with few assumptions and simplifications.

  • Data types are not used, raw data and its size in bytes is used instead.
  • A single implicit communicator that includes all FPGAs in the cluster is assumed in collectives.
  • For send/receive, dependencies can be added for task synchronization.

API calls are defined as follows:

void OMPIF_Send(const void *data, unsigned int size, int destination, unsigned char tag, unsigned char numDeps, const unsigned long long int deps[]);
void OMPIF_Recv(void *data, unsigned int size, int source, unsigned char tag, unsigned char numDeps, const unsigned long long int deps[]);
void OMPIF_Allgather(void* data, unsigned int size);
void OMPIF_Bcast(void* data, unsigned int size, int root);
unsigned char OMPIF_Comm_rank();
unsigned char OMPIF_Comm_size();