Skip to content

Commit

Permalink
VITIS-6327 xbutil valdiate changes to support ps kernel testing (#7624)
Browse files Browse the repository at this point in the history
* VITIS-6327 IFunctional testing. Needs work

Signed-off-by: Daniel Benusovich <[email protected]>

* VITIS-6327 Update ps_validate test to use boost program options. Move dependency generation into XRT

Signed-off-by: Daniel Benusovich <[email protected]>

* VITIS-6327 Pass xclbin path as part of arguments

Signed-off-by: Daniel Benusovich <[email protected]>

* VITIS-6327 Update host executables to use new property tree command options. Add dependency vectors into host executables

Signed-off-by: Daniel Benusovich <[email protected]>

* VITIS-6327 Fix compilation errors for host executables

Signed-off-by: Daniel Benusovich <[email protected]>

* VITIS-6327 Revert change to test case path

Signed-off-by: Daniel Benusovich <[email protected]>

* VITIS-6327 fix misspelled variable name

Signed-off-by: Daniel Benusovich <[email protected]>

* VITIS-6327 Fix testing warnings. Resolve validation errors

Signed-off-by: Daniel Benusovich <[email protected]>

* VITIS-6327 Revert testcase path change

Signed-off-by: Daniel Benusovich <[email protected]>

---------

Signed-off-by: Daniel Benusovich <[email protected]>
  • Loading branch information
dbenusov committed Jul 19, 2023
1 parent 2dd2fb8 commit e67fab6
Show file tree
Hide file tree
Showing 8 changed files with 320 additions and 224 deletions.
236 changes: 154 additions & 82 deletions src/runtime_src/core/tools/xbutil2/SubCmdValidate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ void logger(boost::property_tree::ptree& _ptTest, const std::string& tag, const
* search for xclbin for an SSV2 platform
*/
std::string
searchSSV2Xclbin(const std::string& logic_uuid,
const std::string& xclbin, boost::property_tree::ptree& _ptTest)
searchSSV2Xclbin( const std::string& logic_uuid,
boost::property_tree::ptree& _ptTest)
{
std::string formatted_fw_path("/opt/xilinx/firmware/");
boost::filesystem::path fw_dir(formatted_fw_path);
Expand Down Expand Up @@ -136,7 +136,7 @@ searchSSV2Xclbin(const std::string& logic_uuid,
++iter;
}
else if (uuids[0].compare(logic_uuid) == 0) {
return cm.str(1) + "test/" + xclbin;
return cm.str(1) + "test/";
}
}
else if (iter.level() > 4) {
Expand All @@ -146,7 +146,7 @@ searchSSV2Xclbin(const std::string& logic_uuid,
++iter;
}
}
logger(_ptTest, "Details", boost::str(boost::format("%s not available. Skipping validation") % xclbin));
logger(_ptTest, "Details", boost::str(boost::format("Platform path not available. Skipping validation")));
_ptTest.put("status", test_token_skipped);
return "";
}
Expand Down Expand Up @@ -174,35 +174,103 @@ getXsaPath(const uint16_t vendor)
* search for xclbin for a legacy platform
*/
std::string
searchLegacyXclbin(const uint16_t vendor, const std::string& dev_name, const std::string& xclbin, boost::property_tree::ptree& _ptTest)
searchLegacyXclbin( const uint16_t vendor,
const std::string& dev_name,
boost::property_tree::ptree& _ptTest)
{
const std::string dsapath("/opt/xilinx/dsa/");
const std::string xsapath(getXsaPath(vendor));

if (!boost::filesystem::is_directory(dsapath) && !boost::filesystem::is_directory(xsapath)) {
logger(_ptTest, "Error", boost::str(boost::format("Failed to find '%s' or '%s'") % dsapath % xsapath));
const auto fmt = boost::format("Failed to find '%s' or '%s'") % dsapath % xsapath;
logger(_ptTest, "Error", boost::str(fmt));
logger(_ptTest, "Error", "Please check if the platform package is installed correctly");
_ptTest.put("status", test_token_failed);
return "";
XBUtilities::throw_cancel(fmt);
}

//create possible xclbin paths
std::string xsaXclbinPath = xsapath + dev_name + "/test/" + xclbin;
std::string dsaXclbinPath = dsapath + dev_name + "/test/" + xclbin;
std::string xsaXclbinPath = xsapath + dev_name + "/test/";
std::string dsaXclbinPath = dsapath + dev_name + "/test/";
boost::filesystem::path xsa_xclbin(xsaXclbinPath);
boost::filesystem::path dsa_xclbin(dsaXclbinPath);
if (boost::filesystem::exists(xsa_xclbin)) {
if (boost::filesystem::exists(xsa_xclbin))
return xsaXclbinPath;
}
else if (boost::filesystem::exists(dsa_xclbin)) {
else if (boost::filesystem::exists(dsa_xclbin))
return dsaXclbinPath;
}

logger(_ptTest, "Details", boost::str(boost::format("%s not available. Skipping validation") % xclbin));
const std::string fmt = "Platform path not available. Skipping validation";
logger(_ptTest, "Details", fmt);
_ptTest.put("status", test_token_skipped);
XBUtilities::throw_cancel(fmt);
return "";
}

static std::string
findPlatformPath(const std::shared_ptr<xrt_core::device>& _dev,
boost::property_tree::ptree& _ptTest)
{
//check if a 2RP platform
const auto logic_uuid = xrt_core::device_query_default<xrt_core::query::logic_uuids>(_dev, {});

if (!logic_uuid.empty())
return searchSSV2Xclbin(logic_uuid.front(), _ptTest);
else {
auto vendor = xrt_core::device_query<xrt_core::query::pcie_vendor>(_dev);
auto name = xrt_core::device_query<xrt_core::query::rom_vbnv>(_dev);
return searchLegacyXclbin(vendor, name, _ptTest);
}
}

static std::string
findXclbinPath( const std::shared_ptr<xrt_core::device>& _dev,
const std::string& xclbin,
boost::property_tree::ptree& _ptTest)
{
const auto platform_path = findPlatformPath(_dev, _ptTest);
const auto xclbin_path = _ptTest.get<std::string>("xclbin_directory", platform_path) + xclbin;
if (!boost::filesystem::exists(xclbin_path)) {
const auto fmt = boost::format("%s not available. Skipping validation.") % xclbin_path;
logger(_ptTest, "Details", boost::str(fmt));
_ptTest.put("status", test_token_skipped);
}
return xclbin_path;
}

static std::vector<std::string>
findDependencies( const std::string& test_path,
const std::string& ps_kernel_name)
{
const std::string dependency_json = "/lib/firmware/xilinx/ps_kernels/test_dependencies.json";
boost::filesystem::path dep_path(dependency_json);
if (!boost::filesystem::exists(dep_path))
return {};

std::vector<std::string> dependencies;
try {
boost::property_tree::ptree pt;
boost::property_tree::read_json(dependency_json, pt);

// Find the ps kernel in the dependency JSON and generate paths to the required xclbins
auto ps_kernels = pt.get_child("ps_kernel_mappings");
for (const auto& ps_kernel : ps_kernels) {
boost::property_tree::ptree ps_kernel_pt = ps_kernel.second;
if (!boost::equals(ps_kernel_name, ps_kernel_pt.get<std::string>("name")))
continue;

auto ps_kernel_dep = ps_kernel_pt.get_child("dependencies");
for (const auto& dependency : ps_kernel_dep) {
const std::string dependency_name = dependency.second.get_value<std::string>();
const std::string dependency_path = test_path + dependency_name;
dependencies.push_back(dependency_path);
}
}
} catch (const std::exception& e) {
throw xrt_core::error(boost::str(boost::format("Bad JSON format while marshaling dependency metadata (%s)") % e.what()));
}
return dependencies;
}

/*
* helper funtion for kernel and bandwidth test cases
* Steps:
Expand All @@ -212,65 +280,41 @@ searchLegacyXclbin(const uint16_t vendor, const std::string& dev_name, const std
* 4. Check results
*/
void
runTestCase( const std::shared_ptr<xrt_core::device>& _dev, const std::string& py,
const std::string& xclbin,
boost::property_tree::ptree& _ptTest)
runTestCase(const std::shared_ptr<xrt_core::device>& _dev,
const std::string& py,
const std::string& xclbin,
boost::property_tree::ptree& _ptTest)
{
std::string name;
try {
name = xrt_core::device_query<xrt_core::query::rom_vbnv>(_dev);
} catch (...) {
logger(_ptTest, "Error", "Unable to find device VBNV");

_ptTest.put("status", test_token_failed);
return;
}

//check if a 2RP platform
std::vector<std::string> logic_uuid;
try{
logic_uuid = xrt_core::device_query<xrt_core::query::logic_uuids>(_dev);
} catch (...) { }

std::string xclbinPath;
auto xclbin_location = _ptTest.get<std::string>("xclbin_directory", "");
if (!xclbin_location.empty()) {
xclbinPath = xclbin_location + xclbin;
}
else if (!logic_uuid.empty()) {
xclbinPath = searchSSV2Xclbin(logic_uuid.front(), xclbin, _ptTest);
}
else {
auto vendor = xrt_core::device_query<xrt_core::query::pcie_vendor>(_dev);
xclbinPath = searchLegacyXclbin(vendor, name, xclbin, _ptTest);
}
const auto xclbinPath = findXclbinPath(_dev, xclbin, _ptTest);

// 0RP (nonDFX) flat shell support.
// Currently, there isn't a clean way to determine if a nonDFX shell's interface is truly flat.
// At this time, this is determined by whether or not it delivers an accelerator (e.g., verify.xclbin)
const auto logic_uuid = xrt_core::device_query_default<xrt_core::query::logic_uuids>(_dev, {});
if (!logic_uuid.empty() && !boost::filesystem::exists(xclbinPath)) {
logger(_ptTest, "Details", "Verify xclbin not available or shell partition is not programmed. Skipping validation.");
_ptTest.put("status", test_token_skipped);
return;
}

//check if xclbin is present
if (xclbinPath.empty() || !boost::filesystem::exists(xclbinPath)) {
_ptTest.put("status", test_token_skipped);
return;
}

// log xclbin test dir for debugging purposes
boost::filesystem::path xclbin_path(xclbinPath);
auto test_dir = xclbin_path.parent_path().string();
logger(_ptTest, "Xclbin", test_dir);
auto xclbin_parent_path = xclbin_path.parent_path().string();
logger(_ptTest, "Xclbin", xclbin_parent_path);

auto json_exists = [test_dir]() {
std::string platform_path = findPlatformPath(_dev, _ptTest);
auto json_exists = [platform_path]() {
const static std::string platform_metadata = "/platform.json";
std::string platform_json_path(test_dir + platform_metadata);
std::string platform_json_path(platform_path + platform_metadata);
return boost::filesystem::exists(platform_json_path) ? true : false;
};

// Some testcases require additional binaries to be present on the device
std::string dependency_args;
const auto dependencies = findDependencies(platform_path, xclbin);
for (const auto& dependency : dependencies)
dependency_args += dependency + " ";

std::ostringstream os_stdout;
std::ostringstream os_stderr;
static std::chrono::seconds MAX_TEST_DURATION(60 * 5); //5 minutes
Expand Down Expand Up @@ -306,8 +350,15 @@ runTestCase( const std::shared_ptr<xrt_core::device>& _dev, const std::string& p
// log testcase path for debugging purposes
logger(_ptTest, "Testcase", xrtTestCasePath);

std::vector<std::string> args = { "-p", test_dir,
std::vector<std::string> args = { "-x", xclbinPath,
"-p", platform_path,
"-d", xrt_core::query::pcie_bdf::to_string(xrt_core::device_query<xrt_core::query::pcie_bdf>(_dev)) };

if (!dependency_args.empty()) {
args.push_back("-i");
args.push_back(dependency_args);
}

try {
int exit_code = XBU::runScript("sh", xrtTestCasePath, args, "Running Test", MAX_TEST_DURATION, os_stdout, os_stderr);
if (exit_code == EOPNOTSUPP) {
Expand Down Expand Up @@ -668,31 +719,7 @@ search_and_program_xclbin(const std::shared_ptr<xrt_core::device>& dev, boost::p
uuid_parse(xrt_core::device_query<xrt_core::query::xclbin_uuid>(dev).c_str(), uuid);
std::string xclbin = ptTest.get<std::string>("xclbin", "");

//if no xclbin is loaded, locate the default xclbin
//check if a 2RP platform
std::vector<std::string> logic_uuid;
try {
logic_uuid = xrt_core::device_query<xrt_core::query::logic_uuids>(dev);
} catch (...) { }

std::string xclbinPath;
auto xclbin_location = ptTest.get<std::string>("xclbin_directory", "");
if (!xclbin_location.empty()) {
xclbinPath = xclbin_location + xclbin;
}
else if (!logic_uuid.empty()) {
xclbinPath = searchSSV2Xclbin(logic_uuid.front(), xclbin, ptTest);
} else {
auto vendor = xrt_core::device_query<xrt_core::query::pcie_vendor>(dev);
auto name = xrt_core::device_query<xrt_core::query::rom_vbnv>(dev);
xclbinPath = searchLegacyXclbin(vendor, name, xclbin, ptTest);
}

if (!boost::filesystem::exists(xclbinPath)) {
logger(ptTest, "Details", boost::str(boost::format("%s not available. Skipping validation.") % xclbin));
ptTest.put("status", test_token_skipped);
return false;
}
std::string xclbinPath = findXclbinPath(dev, xclbin, ptTest);

try {
program_xclbin(dev, xclbinPath);
Expand Down Expand Up @@ -1248,6 +1275,47 @@ aiePlTest(const std::shared_ptr<xrt_core::device>& _dev, boost::property_tree::p
runTestCase(_dev, "aie_pl.exe", _ptTest.get<std::string>("xclbin"), _ptTest);
}

/*
* TEST #14
*/
void
psBandwidthTest(const std::shared_ptr<xrt_core::device>& _dev, boost::property_tree::ptree& _ptTest)
{
_ptTest.put("xclbin_directory", "/lib/firmware/xilinx/ps_kernels/");
runTestCase(_dev, "ps_bandwidth.exe", _ptTest.get<std::string>("xclbin"), _ptTest);
}

/*
* TEST #15
*/
void
psAieTest(const std::shared_ptr<xrt_core::device>& _dev, boost::property_tree::ptree& _ptTest)
{
_ptTest.put("xclbin_directory", "/lib/firmware/xilinx/ps_kernels/");
runTestCase(_dev, "ps_aie.exe", _ptTest.get<std::string>("xclbin"), _ptTest);
}

/*
* TEST #16
*/
void
psValidateTest(const std::shared_ptr<xrt_core::device>& _dev, boost::property_tree::ptree& _ptTest)
{
_ptTest.put("xclbin_directory", "/lib/firmware/xilinx/ps_kernels/");
runTestCase(_dev, "ps_validate.exe", _ptTest.get<std::string>("xclbin"), _ptTest);
}

/*
* TEST #17
*/
void
psIopsTest(const std::shared_ptr<xrt_core::device>& _dev, boost::property_tree::ptree& _ptTest)
{
_ptTest.put("xclbin_directory", "/lib/firmware/xilinx/ps_kernels/");
runTestCase(_dev, "ps_iops_test.exe", _ptTest.get<std::string>("xclbin"), _ptTest);
}


/*
* helper function to initialize test info
*/
Expand Down Expand Up @@ -1282,7 +1350,11 @@ static std::vector<TestCollection> testSuite = {
{ create_init_test("hostmem-bw", "Run 'bandwidth kernel' when host memory is enabled", "bandwidth.xclbin"), hostMemBandwidthKernelTest },
{ create_init_test("bist", "Run BIST test", "verify.xclbin", true), bistTest },
{ create_init_test("vcu", "Run decoder test", "transcode.xclbin"), vcuKernelTest },
{ create_init_test("aie-pl", "Run AIE PL test", "aie_control_config.json"), aiePlTest }
{ create_init_test("aie", "Run AIE PL test", "aie_control_config.json"), aiePlTest },
{ create_init_test("ps-aie", "Run PS controlled AIE test", "ps_aie.xclbin"), psAieTest },
{ create_init_test("ps-pl-verify", "Run PS controlled 'Hello World' PL kernel test", "ps_bandwidth.xclbin"), psBandwidthTest },
{ create_init_test("ps-verify", "Run 'Hello World' PS kernel test", "ps_validate.xclbin"), psValidateTest },
{ create_init_test("ps-iops", "Run IOPS PS test", "ps_validate.xclbin"), psIopsTest }
};


Expand Down
4 changes: 1 addition & 3 deletions tests/validate/aie_pl_test/src/host.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,14 +258,12 @@ main(int argc, char* argv[])
boost::program_options::bool_switch(&bSupported),
"Supported")("help,h", "Prints this help menu.");

po::positional_options_description positionals;

// Parse sub-command ...
po::variables_map vm;
try {
po::store(po::command_line_parser(argc, argv)
.options(desc)
.positional(positionals)
.allow_unregistered()
.run(),
vm);
// Print out the help menu
Expand Down
2 changes: 1 addition & 1 deletion tests/validate/ps_aie_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ add_executable(${TESTNAME}
../common/includes/logger/logger.cpp src/host.cpp
)

target_link_libraries(${TESTNAME} PRIVATE ${xrt_coreutil_LIBRARY})
target_link_libraries(${TESTNAME} PRIVATE ${xrt_coreutil_LIBRARY} ${Boost_PROGRAM_OPTIONS_LIBRARY} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY})

if (NOT WIN32)
target_link_libraries(${TESTNAME} PRIVATE ${uuid_LIBRARY} pthread ${xrt_coreutil_LIBRARY} ${xrt_core_LIBRARY})
Expand Down
Loading

0 comments on commit e67fab6

Please sign in to comment.