Visible to Intel only — GUID: GUID-25377E57-4E0C-4C26-8B60-648EE13964DE
Why is FPGA Compilation Different?
Types of SYCL* FPGA Compilation
FPGA Compilation Flags
Emulate and Debug Your Design
Evaluate Your Kernel Through Simulation
Device Selectors for FPGA
FPGA IP Authoring Flow
Fast Recompile for FPGA
Generate Multiple FPGA Images (Linux only)
FPGA BSPs and Boards
Targeting Multiple Homogeneous FPGA Devices
Targeting Multiple Platforms
FPGA-CPU Interaction
FPGA Performance Optimization
Use of RTL Libraries for FPGA
Use SYCL Shared Library With Third-Party Applications
FPGA Workflows in IDEs
Intel oneAPI DPC++ Library (oneDPL)
Intel oneAPI Math Kernel Library (oneMKL)
Intel oneAPI Threading Building Blocks (oneTBB)
Intel oneAPI Data Analytics Library (oneDAL)
Intel oneAPI Collective Communications Library (oneCCL)
Intel oneAPI Deep Neural Network Library (oneDNN)
Intel oneAPI Video Processing Library (oneVPL)
Other Libraries
Visible to Intel only — GUID: GUID-25377E57-4E0C-4C26-8B60-648EE13964DE
Memory-Mapped Host Interfaces Using Accessors
The following example shows how to create multiple memory-mapped (mm_host) interfaces using the buffer_location property in SYCL*:
#include <sycl/sycl.hpp>
#include <iostream>
#include <sycl/ext/intel/fpga_extensions.hpp>
#include <vector>
using namespace sycl;
// Forward declare the kernel name in the global scope.
// This is an FPGA best practice that reduces name mangling in the
// optimization reports.
class SimpleVAdd;
// The members of the functor serve as inputs and outputs to your IP.
// The code inside the operator()() function describes your IP.
template <class AccA, class AccB, class AccC>
struct SimpleVAddKernel {
AccA A;
AccB B;
AccC C;
int count;
void operator()() const {
for (int i = 0; i < count; i++) {
C[i] = A[i] + B[i];
}
}
};
constexpr int VECT_SIZE = 4;
int main() {
#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
queue q(selector);
int count = VECT_SIZE; // pass array size by value
// declare arrays and fill them
std::vector<int> VA;
std::vector<int> VB;
std::vector<int> VC(count);
for (int i = 0; i < count; i++) {
VA.push_back(i);
VB.push_back(count - i);
}
std::cout << "add two vectors of size " << count << std::endl;
buffer bufferA{VA};
buffer bufferB{VB};
buffer bufferC{VC};
q.submit([&](handler &h) {
accessor accessorA{bufferA, h, read_only};
accessor accessorB{bufferB, h, read_only};
accessor accessorC{bufferC, h, read_write, no_init};
h.single_task<SimpleVAdd>(SimpleVAddKernel<decltype(accessorA), decltype(accessorB), decltype(accessorC)>{accessorA, accessorB, accessorC, count});
});
// verify that VC is correct
bool passed = true;
for (int i = 0; i < count; i++) {
int expected = VA[i] + VB[i];
std::cout << "idx=" << i << ": result " << VC[i] << ", expected (" << expected << ") VA=" << VA[i] << " + VB=" << VB[i] << std::endl;
if (VC[i] != expected) {
passed = false;
}
}
std::cout << (passed ? "PASSED" : "FAILED") << std::endl;
return passed ? EXIT_SUCCESS : EXIT_FAILURE;
}