Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
77c80cc
Adding a hello-world test to VRT
JOOpdenhoevel Apr 16, 2026
2e5cfa9
Adding a simple workflow to run the VRT unit tests
JOOpdenhoevel Apr 16, 2026
4dd05fe
Fixing the multi-line usage in the GitHub Actions workflow
JOOpdenhoevel Apr 16, 2026
0040040
Using sudo to install packages
JOOpdenhoevel Apr 16, 2026
b77214c
Also checking out submodules
JOOpdenhoevel Apr 16, 2026
57d2922
Merge remote-tracking branch 'Xilinx/dev' into feature/vrt-unit-testing
JOOpdenhoevel Apr 20, 2026
a5daf97
Generating test cases for units in VRT that don't need a VBIN file
JOOpdenhoevel Apr 20, 2026
8c1c6cb
Adding code coverage to the VRT unit tests
JOOpdenhoevel Apr 20, 2026
a4936a6
Adding unit tests for emulation and simulation using a stub VBIN
JOOpdenhoevel Apr 20, 2026
f4a8459
Also calling kernels in the sim tests
JOOpdenhoevel Apr 20, 2026
723b6ec
Removing the original VRT unit testing branch as a possible trigger f…
JOOpdenhoevel Apr 20, 2026
6717116
Adding copyright headers
JOOpdenhoevel Apr 21, 2026
72e61f1
Merging the sim tests and emu tests into one test
JOOpdenhoevel Apr 21, 2026
c8be9dc
Adding round-trip testing functionality to the device tests
JOOpdenhoevel Apr 21, 2026
64b4c7d
Merge remote-tracking branch 'Xilinx/dev' into feature/vrt-unit-testing
JOOpdenhoevel Apr 21, 2026
34d7476
Fixing the Device::getKernel function
JOOpdenhoevel Apr 21, 2026
2d35a31
Making VRT unit tests optional
JOOpdenhoevel Apr 24, 2026
1a4c442
Merge remote-tracking branch 'Xilinx/dev' into feature/vrt-unit-testing
JOOpdenhoevel Apr 24, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 74 additions & 0 deletions .github/workflows/vrt-unit-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# ##################################################################################################
# The MIT License (MIT)
# Copyright (c) 2025 Advanced Micro Devices, Inc. All rights reserved.
#
# Permission is hereby granted, free of charge, to any person obtaining a copy of this software
# and associated documentation files (the "Software"), to deal in the Software without restriction,
# including without limitation the rights to use, copy, modify, merge, publish, distribute,
# sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all copies or
# substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT
# NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
# DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# ##################################################################################################

name: VRT unit testing

on:
push:
branches:
- main
- dev
pull_request:

jobs:
vrt_unit_tests:
runs-on: ubuntu-24.04
permissions: { contents: read }

steps:
- name: Checkout code
uses: actions/checkout@v6
with:
submodules: "true"

- name: Install dependencies
run: |
sudo apt update
sudo apt upgrade -y
sudo apt install -y cmake pkg-config ninja-build \
libxml2-dev libzmq3-dev libjsoncpp-dev zlib1g-dev \
libsystemd-dev libinih-dev libcli11-dev lcov python3-zmq

- name: Build and run VRT unit tests
run: |
mkdir vrt/build
cd vrt/build
cmake -DVRT_INCLUDE_VRTD=1 -DVRTD_INCLUDE_LIBSLASH=1 -DENABLE_COVERAGE=1 ..
make unit_tests -j$(nproc)
cd tests && ctest --output-on-failure

- name: Generate coverage report
run: |
cd vrt/build
lcov --capture --directory . --output-file coverage.info \
--ignore-errors mismatch --ignore-errors negative
lcov --remove coverage.info \
'/usr/*' '*/build/_deps/*' '*/vrtd/*' '*/tests/*' \
--output-file coverage.filtered.info \
--ignore-errors unused
genhtml coverage.filtered.info --output-directory coverage-report
lcov --list coverage.filtered.info

- name: Upload coverage report
uses: actions/upload-artifact@v4
with:
name: vrt-coverage-report
path: vrt/build/coverage-report/

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ Thumbs.db

__pycache__/
*.pyc
.venv/

# Build files for package
/pbuild/
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pyzmq
jinja2
pytest
pytest-cov
Expand Down
1 change: 1 addition & 0 deletions submodules/AVED
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is AVED added as submodule here? I thought we already carried AVED as submodule for firmware/shell builds

Submodule AVED added at 839b4a
17 changes: 17 additions & 0 deletions vrt/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

option(VRT_INCLUDE_VRTD "Include vrtd subdirectory instead of building from system" OFF)
option(VRT_BUILD_TESTS "Build unit tests" OFF)

include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
Expand All @@ -55,6 +56,15 @@ if(ENABLE_SANITIZERS)
add_link_options(-fsanitize=address,undefined)
endif()

option(ENABLE_COVERAGE "Build with gcov coverage instrumentation" OFF)
if(ENABLE_COVERAGE)
if(ENABLE_SANITIZERS)
message(FATAL_ERROR "ENABLE_COVERAGE and ENABLE_SANITIZERS cannot be used together")
endif()
add_compile_options(--coverage -fno-inline)
add_link_options(--coverage)
endif()

# Generate the header
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/vrt_version.hpp.in"
Expand Down Expand Up @@ -131,6 +141,13 @@ target_link_libraries(vrt
PkgConfig::PC_ZMQ
)

# Testing
if(VRT_BUILD_TESTS)
add_subdirectory(tests)
endif()

# Installation

set_target_properties(vrt PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)

install(
Expand Down
6 changes: 6 additions & 0 deletions vrt/include/vrt/kernel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ class Kernel {
*/
void setVrtdBar(const std::optional<vrtd::Bar>& bar);

/**
* @brief Sets the ZeroMQ server for emulation and simulation.
* @param server The ZeroMQ server handle.
*/
void setServer(std::shared_ptr<ZmqServer> server);

/**
* @brief Writes a value to a register.
* @param offset The offset of the register.
Expand Down
6 changes: 3 additions & 3 deletions vrt/include/vrt/streaming_buffer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

#include <regex>

#include "api/device.hpp"
#include "device.hpp"
#include "qdma/qdma_connection.hpp"
#include "qdma/qdma_intf.hpp"
#include "utils/platform.hpp"
Expand Down Expand Up @@ -110,7 +110,7 @@ template <typename T>
StreamingBuffer<T>::StreamingBuffer(Device device, Kernel kernel, const std::string& portName,
size_t size)
: device(device), size(size), kernel(kernel), portName(portName) {
std::vector<QdmaConnection> qdmaConnections = device.getQdmaConnections();
std::vector<QdmaConnection> qdmaConnections = device.getHandle()->getQdmaConnections();
bool gotQdma = false;
for (const auto& con : qdmaConnections) {
if (con.getKernel() == kernel.getName() && portName == con.getInterface()) {
Expand Down Expand Up @@ -162,7 +162,7 @@ template <typename T>
void StreamingBuffer<T>::sync() {
Platform platform = device.getPlatform();
if (platform == Platform::EMULATION) {
ZmqServer* server = device.getHandle()->getZmqServer();
auto server = device.getHandle()->getZmqServer();
if (syncType == StreamDirection::HOST_TO_DEVICE) {
std::vector<uint8_t> sendData;
std::size_t dataSize = size * sizeof(T);
Expand Down
14 changes: 9 additions & 5 deletions vrt/src/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,12 +306,16 @@ void Device::parseSystemMap() {
clockFreq = parser.getClockFrequency();
this->platform = parser.getPlatform();
kernels = parser.getKernels();

std::optional<vrtd::Bar> barHandle = std::nullopt;
if (platform == Platform::HARDWARE && vrtdDevice.has_value()) {
std::optional<vrtd::Bar> barHandle = vrtdDevice->getBar(bar);
for (auto& kernel : kernels) {
kernel.second.setVrtdBar(barHandle);
kernel.second.setPlatform(platform);
}
barHandle = vrtdDevice->getBar(bar);
}

for (auto&kernel : kernels) {
kernel.second.setPlatform(platform);
kernel.second.setVrtdBar(barHandle);
kernel.second.setServer(zmqServer);
}
this->qdmaConnections = parser.getQdmaConnections();
}
Expand Down
2 changes: 2 additions & 0 deletions vrt/src/kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ uint32_t Kernel::read(uint32_t offset) {

void Kernel::setVrtdBar(const std::optional<vrtd::Bar>& bar) { this->vrtdBar = bar; }

void Kernel::setServer(std::shared_ptr<ZmqServer> server) { this->server = server; }

void Kernel::setFunctionalArgs(const std::vector<FunctionalArg>& args) {
functionalArgs = args;
std::sort(functionalArgs.begin(), functionalArgs.end(),
Expand Down
92 changes: 92 additions & 0 deletions vrt/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
include(FetchContent)
FetchContent_Declare(
googletest
URL https://github.com/google/googletest/archive/refs/tags/v1.17.0.zip
)
FetchContent_MakeAvailable(googletest)

enable_testing()

include(GoogleTest)

add_custom_target(unit_tests)

macro(add_vrt_test test_name test_source)
add_executable(${test_name} ${test_source})
target_link_libraries(${test_name} PRIVATE GTest::gtest_main GTest::gmock vrt::vrt)
gtest_discover_tests(${test_name})
add_dependencies(unit_tests ${test_name})
endmacro()

add_vrt_test(register_test register_test.cpp)
add_vrt_test(qdma_connection_test qdma_connection_test.cpp)
add_vrt_test(logger_test logger_test.cpp)
add_vrt_test(utilization_data_test utilization_data_test.cpp)
add_vrt_test(filesystem_cache_test filesystem_cache_test.cpp)
add_vrt_test(xml_parser_test xml_parser_test.cpp)
add_vrt_test(utilization_parser_test utilization_parser_test.cpp)
add_vrt_test(kernel_test kernel_test.cpp)
add_vrt_test(vrtbin_test vrtbin_test.cpp)

# --- Stub VBIN generation ---
set(STUB_VBIN_DIR ${CMAKE_CURRENT_SOURCE_DIR}/fixtures/stub_vbin)

set(STUB_EMU_VBIN ${CMAKE_CURRENT_BINARY_DIR}/stub_emu.vbin)
add_custom_command(
OUTPUT ${STUB_EMU_VBIN}
COMMAND ${CMAKE_COMMAND} -E rm -rf ${CMAKE_CURRENT_BINARY_DIR}/stub_emu_staging
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/stub_emu_staging
COMMAND ${CMAKE_COMMAND} -E copy
${STUB_VBIN_DIR}/system_map_emu.xml
${CMAKE_CURRENT_BINARY_DIR}/stub_emu_staging/system_map.xml
COMMAND ${CMAKE_COMMAND} -E copy
${STUB_VBIN_DIR}/emu_manifest.json
${CMAKE_CURRENT_BINARY_DIR}/stub_emu_staging/emu_manifest.json
COMMAND ${CMAKE_COMMAND} -E copy
${STUB_VBIN_DIR}/vrt_stub_server.py
${CMAKE_CURRENT_BINARY_DIR}/stub_emu_staging/vpp_emu
COMMAND chmod +x ${CMAKE_CURRENT_BINARY_DIR}/stub_emu_staging/vpp_emu
COMMAND tar cf ${STUB_EMU_VBIN}
-C ${CMAKE_CURRENT_BINARY_DIR}/stub_emu_staging .
DEPENDS
${STUB_VBIN_DIR}/system_map_emu.xml
${STUB_VBIN_DIR}/emu_manifest.json
${STUB_VBIN_DIR}/vrt_stub_server.py
COMMENT "Creating emulation stub VBIN"
)

set(STUB_SIM_VBIN ${CMAKE_CURRENT_BINARY_DIR}/stub_sim.vbin)
add_custom_command(
OUTPUT ${STUB_SIM_VBIN}
COMMAND ${CMAKE_COMMAND} -E rm -rf ${CMAKE_CURRENT_BINARY_DIR}/stub_sim_staging
COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_CURRENT_BINARY_DIR}/stub_sim_staging
COMMAND ${CMAKE_COMMAND} -E copy
${STUB_VBIN_DIR}/system_map_sim.xml
${CMAKE_CURRENT_BINARY_DIR}/stub_sim_staging/system_map.xml
COMMAND ${CMAKE_COMMAND} -E copy
${STUB_VBIN_DIR}/vrt_stub_server.py
${CMAKE_CURRENT_BINARY_DIR}/stub_sim_staging/vpp_sim
COMMAND chmod +x ${CMAKE_CURRENT_BINARY_DIR}/stub_sim_staging/vpp_sim
COMMAND tar cf ${STUB_SIM_VBIN}
-C ${CMAKE_CURRENT_BINARY_DIR}/stub_sim_staging .
DEPENDS
${STUB_VBIN_DIR}/system_map_sim.xml
${STUB_VBIN_DIR}/vrt_stub_server.py
COMMENT "Creating simulation stub VBIN"
)

add_custom_target(stub_vbins DEPENDS ${STUB_EMU_VBIN} ${STUB_SIM_VBIN})

macro(add_vrt_vbin_test test_name test_source)
add_executable(${test_name} ${test_source})
target_link_libraries(${test_name} PRIVATE GTest::gtest_main GTest::gmock vrt::vrt)
target_compile_definitions(${test_name} PRIVATE
STUB_EMU_VBIN_PATH="${STUB_EMU_VBIN}"
STUB_SIM_VBIN_PATH="${STUB_SIM_VBIN}")
add_dependencies(${test_name} stub_vbins)
gtest_discover_tests(${test_name})
add_dependencies(unit_tests ${test_name})
endmacro()

add_vrt_vbin_test(vrtbin_integration_test vrtbin_integration_test.cpp)
add_vrt_vbin_test(device_test device_test.cpp)
Loading