Skip to content

Commit 7b9685a

Browse files
authored
FPGA: Add new sample SVD (#2320)
Adding a new FPGA reference design Singular Value Decomposition.
1 parent 885e033 commit 7b9685a

File tree

16 files changed

+3204
-47
lines changed

16 files changed

+3204
-47
lines changed

DirectProgramming/C++SYCL_FPGA/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ All the Tier 4 samples are in the [ReferenceDesigns](ReferenceDesigns) category.
191191
| [pca](ReferenceDesigns/pca) | How to implement high performance principal component analysis on a FPGA
192192
| [qrd](ReferenceDesigns/qrd) | Implementing a high performance FPGA version of the Gram-Schmidt QR decomposition algorithm
193193
| [qri](ReferenceDesigns/qri) | Implementing a high performance FPGA version of the Gram-Schmidt QR decomposition to compute a matrix inversion
194+
| [svd](ReferenceDesigns/svd) | How to implement a high performance Singular Value Decomposition on an FPGA
194195

195196
#### Start exploring the FPGA code samples with this selection
196197

Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
# Direct CMake to use icpx rather than the default C++ compiler/linker on Linux
2+
# and icx-cl on Windows
3+
if(UNIX)
4+
set(CMAKE_CXX_COMPILER icpx)
5+
else() # Windows
6+
include (CMakeForceCompiler)
7+
CMAKE_FORCE_CXX_COMPILER (icx-cl IntelDPCPP)
8+
include (Platform/Windows-Clang)
9+
endif()
10+
11+
cmake_minimum_required (VERSION 3.7.2)
12+
13+
project(SVD CXX)
14+
15+
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
16+
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
17+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR})
18+
19+
###############################################################################
20+
### Customize these build variables
21+
###############################################################################
22+
set(SOURCE_FILES src/svd_demo.cpp)
23+
set(TARGET_NAME svd)
24+
25+
# Use cmake -DFPGA_DEVICE=<board-support-package>:<board-variant> to choose a
26+
# different device.
27+
# Note that depending on your installation, you may need to specify the full
28+
# path to the board support package (BSP), this usually is in your install
29+
# folder.
30+
#
31+
# You can also specify a device family (E.g. "Arria10" or "Stratix10") or a
32+
# specific part number (E.g. "10AS066N3F40E2SG") to generate a standalone IP.
33+
if(NOT DEFINED FPGA_DEVICE)
34+
set(FPGA_DEVICE "Agilex7")
35+
message(STATUS "FPGA_DEVICE was not specified.\
36+
\nConfiguring the design to the default FPGA family target: ${FPGA_DEVICE}\
37+
\nPlease refer to the README for information on target selection.")
38+
else()
39+
# Check if the target is a BSP
40+
if(IS_BSP MATCHES "1")
41+
set(BSP_FLAG "-DIS_BSP")
42+
else()
43+
set(BSP_FLAG "")
44+
message(STATUS "The selected target ${FPGA_DEVICE} is assumed to be an FPGA part number, so the IS_BSP macro will not be passed to your C++ code.")
45+
message(STATUS "If the target is actually a BSP, run cmake with -DIS_BSP=1 to pass the IS_BSP macro to your C++ code.")
46+
endif()
47+
endif()
48+
49+
if(NOT DEFINED FIXED_ITERATIONS)
50+
set(FIXED_ITERATIONS 55)
51+
endif()
52+
message(STATUS "FIXED_ITERATIONS=${FIXED_ITERATIONS}")
53+
54+
# Print the device being used for the compiles
55+
message(STATUS "Configuring the design to run on FPGA board ${FPGA_DEVICE}")
56+
57+
# Use cmake -DUSER_FPGA_FLAGS=<flags> to set extra flags for FPGA backend
58+
# compilation.
59+
set(USER_FPGA_FLAGS ${USER_FPGA_FLAGS})
60+
61+
# Use cmake -DUSER_FLAGS=<flags> to set extra flags for general compilation.
62+
set(USER_FLAGS ${USER_FLAGS};-DFIXED_ITERATIONS=${FIXED_ITERATIONS};${BSP_FLAG})
63+
64+
# Use cmake -DUSER_INCLUDE_PATHS=<paths> to set extra paths for general
65+
# compilation.
66+
set(USER_INCLUDE_PATHS ../../include;${USER_INCLUDE_PATHS})
67+
68+
###############################################################################
69+
### no changes after here
70+
###############################################################################
71+
72+
# Set the names of the makefile targets to be generated by cmake
73+
set(EMULATOR_TARGET fpga_emu)
74+
set(SIMULATOR_TARGET fpga_sim)
75+
set(REPORT_TARGET report)
76+
set(FPGA_TARGET fpga)
77+
78+
# Set the names of the generated files per makefile target
79+
set(EMULATOR_OUTPUT_NAME ${TARGET_NAME}.${EMULATOR_TARGET})
80+
set(SIMULATOR_OUTPUT_NAME ${TARGET_NAME}.${SIMULATOR_TARGET})
81+
set(REPORT_OUTPUT_NAME ${TARGET_NAME}.${REPORT_TARGET})
82+
set(FPGA_OUTPUT_NAME ${TARGET_NAME}.${FPGA_TARGET})
83+
84+
message(STATUS "Additional USER_FPGA_FLAGS=${USER_FPGA_FLAGS}")
85+
message(STATUS "Additional USER_FLAGS=${USER_FLAGS}")
86+
87+
include_directories(${USER_INCLUDE_PATHS})
88+
message(STATUS "Additional USER_INCLUDE_PATHS=${USER_INCLUDE_PATHS}")
89+
90+
link_directories(${USER_LIB_PATHS})
91+
message(STATUS "Additional USER_LIB_PATHS=${USER_LIB_PATHS}")
92+
93+
link_libraries(${USER_LIBS})
94+
message(STATUS "Additional USER_LIBS=${USER_LIBS}")
95+
96+
if(WIN32)
97+
# add qactypes for Windows
98+
set(QACTYPES "-Qactypes")
99+
# This is a Windows-specific flag that enables exception handling in host code
100+
set(WIN_FLAG "/EHsc")
101+
else()
102+
# add qactypes for Linux
103+
set(QACTYPES "-qactypes")
104+
endif()
105+
106+
string(TOLOWER "${CMAKE_BUILD_TYPE}" LOWER_BUILD_TYPE)
107+
if(LOWER_BUILD_TYPE MATCHES debug)
108+
# Set debug flags
109+
if(WIN32)
110+
set(DEBUG_FLAGS /DEBUG /Od)
111+
else()
112+
set(DEBUG_FLAGS -g -O0)
113+
endif()
114+
else()
115+
set(DEBUG_FLAGS "")
116+
endif()
117+
118+
if(WIN32)
119+
set(EXT ".exe")
120+
endif()
121+
122+
set(COMMON_COMPILE_FLAGS -fintelfpga -Wall ${WIN_FLAG} ${QACTYPES} ${USER_FLAGS})
123+
set(COMMON_LINK_FLAGS -fintelfpga ${QACTYPES} ${USER_FLAGS})
124+
125+
# A SYCL ahead-of-time (AoT) compile processes the device code in two stages.
126+
# 1. The "compile" stage compiles the device code to an intermediate
127+
# representation (SPIR-V).
128+
# 2. The "link" stage invokes the compiler's FPGA backend before linking. For
129+
# this reason, FPGA backend flags must be passed as link flags in CMake.
130+
set(EMULATOR_COMPILE_FLAGS -DFPGA_EMULATOR ${DEBUG_FLAGS})
131+
set(EMULATOR_LINK_FLAGS )
132+
set(REPORT_COMPILE_FLAGS -DFPGA_HARDWARE)
133+
set(REPORT_LINK_FLAGS -Xshardware -Xstarget=${FPGA_DEVICE} ${USER_FPGA_FLAGS} -fsycl-link=early)
134+
set(SIMULATOR_COMPILE_FLAGS -Xssimulation -DFPGA_SIMULATOR)
135+
set(SIMULATOR_LINK_FLAGS -Xssimulation -Xsghdl -Xstarget=${FPGA_DEVICE} ${USER_FPGA_FLAGS} -reuse-exe=${CMAKE_BINARY_DIR}/${SIMULATOR_OUTPUT_NAME}${EXT})
136+
set(FPGA_COMPILE_FLAGS -DFPGA_HARDWARE)
137+
set(FPGA_LINK_FLAGS -Xshardware -Xstarget=${FPGA_DEVICE} ${USER_FPGA_FLAGS} -reuse-exe=${CMAKE_BINARY_DIR}/${FPGA_OUTPUT_NAME}${EXT})
138+
139+
###############################################################################
140+
### FPGA Emulator
141+
###############################################################################
142+
add_executable(${EMULATOR_TARGET} ${SOURCE_FILES})
143+
target_compile_options(${EMULATOR_TARGET} PRIVATE ${COMMON_COMPILE_FLAGS})
144+
target_compile_options(${EMULATOR_TARGET} PRIVATE ${EMULATOR_COMPILE_FLAGS})
145+
target_link_libraries(${EMULATOR_TARGET} ${COMMON_LINK_FLAGS})
146+
target_link_libraries(${EMULATOR_TARGET} ${EMULATOR_LINK_FLAGS})
147+
set_target_properties(${EMULATOR_TARGET} PROPERTIES OUTPUT_NAME ${EMULATOR_OUTPUT_NAME})
148+
149+
###############################################################################
150+
### FPGA Simulator
151+
###############################################################################
152+
add_executable(${SIMULATOR_TARGET} EXCLUDE_FROM_ALL ${SOURCE_FILES})
153+
target_compile_options(${SIMULATOR_TARGET} PRIVATE ${COMMON_COMPILE_FLAGS})
154+
target_compile_options(${SIMULATOR_TARGET} PRIVATE ${SIMULATOR_COMPILE_FLAGS})
155+
target_link_libraries(${SIMULATOR_TARGET} ${COMMON_LINK_FLAGS})
156+
target_link_libraries(${SIMULATOR_TARGET} ${SIMULATOR_LINK_FLAGS})
157+
set_target_properties(${SIMULATOR_TARGET} PROPERTIES OUTPUT_NAME ${SIMULATOR_OUTPUT_NAME})
158+
159+
###############################################################################
160+
### Generate Report
161+
###############################################################################
162+
add_executable(${REPORT_TARGET} EXCLUDE_FROM_ALL ${SOURCE_FILES})
163+
target_compile_options(${REPORT_TARGET} PRIVATE ${COMMON_COMPILE_FLAGS})
164+
target_compile_options(${REPORT_TARGET} PRIVATE ${REPORT_COMPILE_FLAGS})
165+
166+
# The report target does not need the QACTYPES flag at link stage
167+
set(MODIFIED_COMMON_LINK_FLAGS_REPORT ${COMMON_LINK_FLAGS})
168+
list(REMOVE_ITEM MODIFIED_COMMON_LINK_FLAGS_REPORT ${QACTYPES})
169+
170+
target_link_libraries(${REPORT_TARGET} ${MODIFIED_COMMON_LINK_FLAGS_REPORT})
171+
target_link_libraries(${REPORT_TARGET} ${REPORT_LINK_FLAGS})
172+
set_target_properties(${REPORT_TARGET} PROPERTIES OUTPUT_NAME ${REPORT_OUTPUT_NAME})
173+
174+
###############################################################################
175+
### FPGA Hardware
176+
###############################################################################
177+
add_executable(${FPGA_TARGET} EXCLUDE_FROM_ALL ${SOURCE_FILES})
178+
target_compile_options(${FPGA_TARGET} PRIVATE ${COMMON_COMPILE_FLAGS})
179+
target_compile_options(${FPGA_TARGET} PRIVATE ${FPGA_COMPILE_FLAGS})
180+
target_link_libraries(${FPGA_TARGET} ${COMMON_LINK_FLAGS})
181+
target_link_libraries(${FPGA_TARGET} ${FPGA_LINK_FLAGS})
182+
set_target_properties(${FPGA_TARGET} PROPERTIES OUTPUT_NAME ${FPGA_OUTPUT_NAME})
183+
184+
###############################################################################
185+
### This part only manipulates cmake variables to print the commands cmake is expected to run to the user
186+
###############################################################################
187+
188+
# set the correct object file extension depending on the target platform
189+
if(WIN32)
190+
set(OBJ_EXTENSION "obj")
191+
else()
192+
set(OBJ_EXTENSION "o")
193+
endif()
194+
195+
# Set the source file names in a string
196+
set(SOURCE_FILE_NAME "${SOURCE_FILES}")
197+
198+
function(getCompileCommands common_compile_flags special_compile_flags common_link_flags special_link_flags target output_name)
199+
200+
set(file_names ${SOURCE_FILE_NAME})
201+
set(COMPILE_COMMAND )
202+
set(LINK_COMMAND )
203+
204+
foreach(source ${file_names})
205+
# Get the relative path to the source and object files
206+
file(RELATIVE_PATH CURRENT_SOURCE_FILE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_LIST_DIR}/${source})
207+
file(RELATIVE_PATH OBJ_FILE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${target}.dir/${source}.${OBJ_EXTENSION})
208+
209+
# Creating a string that contains the compile command
210+
# Start by the compiler invocation
211+
set(COMPILE_COMMAND "${COMPILE_COMMAND}${CMAKE_CXX_COMPILER}")
212+
213+
# Add all the potential includes
214+
foreach(INCLUDE ${USER_INCLUDE_PATHS})
215+
if(NOT IS_ABSOLUTE ${INCLUDE})
216+
file(RELATIVE_PATH INCLUDE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_LIST_DIR}/${INCLUDE})
217+
endif()
218+
set(COMPILE_COMMAND "${COMPILE_COMMAND} -I${INCLUDE}")
219+
endforeach()
220+
221+
# Add all the common compile flags
222+
foreach(FLAG ${common_compile_flags})
223+
set(COMPILE_COMMAND "${COMPILE_COMMAND} ${FLAG}")
224+
endforeach()
225+
226+
# Add all the specific compile flags
227+
foreach(FLAG ${special_compile_flags})
228+
set(COMPILE_COMMAND "${COMPILE_COMMAND} ${FLAG}")
229+
endforeach()
230+
231+
# Get the location of the object file
232+
file(RELATIVE_PATH OBJ_FILE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${target}.dir/${source}.${OBJ_EXTENSION})
233+
234+
# Add the source file and the output file
235+
set(COMPILE_COMMAND "${COMPILE_COMMAND} -c ${CURRENT_SOURCE_FILE} -o ${OBJ_FILE}\n")
236+
endforeach()
237+
238+
set(COMPILE_COMMAND "${COMPILE_COMMAND}" PARENT_SCOPE)
239+
240+
# Creating a string that contains the link command
241+
# Start by the compiler invocation
242+
set(LINK_COMMAND "${LINK_COMMAND}${CMAKE_CXX_COMPILER}")
243+
244+
# Add all the common link flags
245+
foreach(FLAG ${common_link_flags})
246+
set(LINK_COMMAND "${LINK_COMMAND} ${FLAG}")
247+
endforeach()
248+
249+
# Add all the specific link flags
250+
foreach(FLAG ${special_link_flags})
251+
set(LINK_COMMAND "${LINK_COMMAND} ${FLAG}")
252+
endforeach()
253+
254+
# Add the output file
255+
set(LINK_COMMAND "${LINK_COMMAND} -o ${output_name}")
256+
257+
foreach(source ${file_names})
258+
# Get the relative path to the source and object files
259+
file(RELATIVE_PATH OBJ_FILE ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${target}.dir/${source}.${OBJ_EXTENSION})
260+
261+
# Add the source file and the output file
262+
set(LINK_COMMAND "${LINK_COMMAND} ${OBJ_FILE}")
263+
endforeach()
264+
265+
# Add all the potential library paths
266+
foreach(LIB_PATH ${USER_LIB_PATHS})
267+
if(NOT IS_ABSOLUTE ${LIB_PATH})
268+
file(RELATIVE_PATH LIB_PATH ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_LIST_DIR}/${LIB_PATH})
269+
endif()
270+
if(NOT WIN32)
271+
set(LINK_COMMAND "${LINK_COMMAND} -L${LIB_PATH}")
272+
else()
273+
set(LINK_COMMAND "${LINK_COMMAND} -L${LIB_PATH} -Wl,-rpath,${LIB_PATH}")
274+
endif()
275+
endforeach()
276+
277+
# Add all the potential includes
278+
foreach(LIB ${USER_LIBS})
279+
set(LINK_COMMAND "${LINK_COMMAND} -l${LIB}")
280+
endforeach()
281+
282+
set(LINK_COMMAND "${LINK_COMMAND}" PARENT_SCOPE)
283+
284+
endfunction()
285+
286+
# Windows executable is going to have the .exe extension
287+
if(WIN32)
288+
set(EXECUTABLE_EXTENSION ".exe")
289+
endif()
290+
291+
# Display the compile instructions in the emulation flow
292+
getCompileCommands("${COMMON_COMPILE_FLAGS}" "${EMULATOR_COMPILE_FLAGS}" "${COMMON_LINK_FLAGS}" "${EMULATOR_LINK_FLAGS}" "${EMULATOR_TARGET}" "${EMULATOR_OUTPUT_NAME}${EXECUTABLE_EXTENSION}")
293+
294+
add_custom_target( displayEmulationCompileCommands
295+
${CMAKE_COMMAND} -E cmake_echo_color --cyan ""
296+
COMMENT "\nTo compile manually:\n${COMPILE_COMMAND}\nTo link manually:\n${LINK_COMMAND}")
297+
add_dependencies(${EMULATOR_TARGET} displayEmulationCompileCommands)
298+
299+
# Display the compile instructions in the simulation flow
300+
getCompileCommands("${COMMON_COMPILE_FLAGS}" "${SIMULATOR_COMPILE_FLAGS}" "${COMMON_LINK_FLAGS}" "${SIMULATOR_LINK_FLAGS}" "${SIMULATOR_TARGET}" "${SIMULATOR_OUTPUT_NAME}${EXECUTABLE_EXTENSION}")
301+
302+
add_custom_target( displaySimulationCompileCommands
303+
${CMAKE_COMMAND} -E cmake_echo_color --cyan ""
304+
COMMENT "\nTo compile manually:\n${COMPILE_COMMAND}\nTo link manually:\n${LINK_COMMAND}")
305+
add_dependencies(${SIMULATOR_TARGET} displaySimulationCompileCommands)
306+
307+
# Display the compile instructions in the report flow
308+
getCompileCommands("${COMMON_COMPILE_FLAGS}" "${REPORT_COMPILE_FLAGS}" "${MODIFIED_COMMON_LINK_FLAGS_REPORT}" "${REPORT_LINK_FLAGS}" "${REPORT_TARGET}" "${REPORT_OUTPUT_NAME}${EXECUTABLE_EXTENSION}")
309+
310+
add_custom_target( displayReportCompileCommands
311+
${CMAKE_COMMAND} -E cmake_echo_color --cyan ""
312+
COMMENT "\nTo compile manually:\n${COMPILE_COMMAND}\nTo link manually:\n${LINK_COMMAND}")
313+
add_dependencies(${REPORT_TARGET} displayReportCompileCommands)
314+
315+
# Display the compile instructions in the fpga flow
316+
getCompileCommands("${COMMON_COMPILE_FLAGS}" "${FPGA_COMPILE_FLAGS}" "${COMMON_LINK_FLAGS}" "${FPGA_LINK_FLAGS}" "${FPGA_TARGET}" "${FPGA_OUTPUT_NAME}${EXECUTABLE_EXTENSION}")
317+
318+
add_custom_target( displayFPGACompileCommands
319+
${CMAKE_COMMAND} -E cmake_echo_color --cyan ""
320+
COMMENT "\nTo compile manually:\n${COMPILE_COMMAND}\nTo link manually:\n${LINK_COMMAND}")
321+
add_dependencies(${FPGA_TARGET} displayFPGACompileCommands)

0 commit comments

Comments
 (0)