From 86da1cd8fb54b1bc37b8790c8c30ea9630aa9c97 Mon Sep 17 00:00:00 2001 From: Dongju Chae Date: Wed, 17 Mar 2021 12:53:30 +0900 Subject: [PATCH] [Test/Preempt] Add an apptest to test the task preemption This patch adds an apptest to test the task preemption by comparing vISA execution sequences. Signed-off-by: Dongju Chae --- tests/apptests/meson.build | 10 +++ tests/apptests/tvn_triv2_preempt.cc | 141 ++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100644 tests/apptests/tvn_triv2_preempt.cc diff --git a/tests/apptests/meson.build b/tests/apptests/meson.build index c6aeb19..2b6edd5 100644 --- a/tests/apptests/meson.build +++ b/tests/apptests/meson.build @@ -113,3 +113,13 @@ executable ('apptest_tvn_triv2_profile', install_rpath : ne_libdir, install_dir : join_paths(ne_bindir, 'apptests') ) + +executable ('apptest_tvn_triv2_preempt', + 'tvn_triv2_preempt.cc', + include_directories : ne_apptest_inc, + dependencies : ne_test_utils_dep, + link_with : ne_library_shared, + install : true, + install_rpath : ne_libdir, + install_dir : join_paths(ne_bindir, 'apptests') +) diff --git a/tests/apptests/tvn_triv2_preempt.cc b/tests/apptests/tvn_triv2_preempt.cc new file mode 100644 index 0000000..6457604 --- /dev/null +++ b/tests/apptests/tvn_triv2_preempt.cc @@ -0,0 +1,141 @@ +/** + * Proprietary + * Copyright (C) 2021 Samsung Electronics + * Copyright (C) 2021 Dongju Chae + */ +/** + * @file tvn_triv2_preempt.cc + * @date 15 Mar 2021 + * @brief AppTest to test task preemption + * @author Dongju Chae + * @bug No known bugs except for NYI items + */ + +#include + +#define NPU_TIMEOUT_MS 5000 +#define MID_MODEL_NAME "MOBILENET_V1" +#define HIGH_MODEL_NAME "MAX_POOL_2D_000" + +using namespace std; + +/** @brief C++ class to describe how to use npu-engine library */ +class Tester : public UtilTRIV2 +{ + public: + Tester () : mid_model_id_ (0), high_model_id_ (0) {} + + /** @brief initilize the device handle */ + int init (std::string models_dir) { + int status = UtilTRIV2::init (); + if (status != test_ret_success) { + cerr << "Failed to initialize\n"; + return status; + } + + status = UtilTRIV2::loadModel (models_dir + "/" + MID_MODEL_NAME, + &mid_model_id_, NPU_PRIORITY_MID, NPU_TIMEOUT_MS); + if (status != test_ret_success) { + cerr << "Failed to find a model: " << MID_MODEL_NAME << "\n"; + return status; + } + + status = UtilTRIV2::loadModel (models_dir + "/" + HIGH_MODEL_NAME, + &high_model_id_, NPU_PRIORITY_HIGH, NPU_TIMEOUT_MS); + if (status != test_ret_success) { + cerr << "Failed to find a model: " << HIGH_MODEL_NAME << "\n"; + return status; + } + + return 0; + } + + /** @brief run the inference */ + int run () { + if (mid_model_id_ == 0 || high_model_id_ == 0) + return test_ret_failure; + + int mid_task_id = UtilTRIV2::run (mid_model_id_); + if (mid_task_id < 0) + return mid_task_id; + + int high_task_id = UtilTRIV2::run (high_model_id_); + if (high_task_id < 0) + return high_task_id; + + int result = wait () == 2 ? test_ret_success : test_ret_failure; + + if (result == test_ret_success) { + int64_t mid_last_seq = get_last_sequence (mid_task_id); + int64_t high_last_seq = get_last_sequence (high_task_id); + + /** The expected execution order: mid --> high --> mid */ + if (high_last_seq > mid_last_seq) { + cerr << "Unable to confirm the evidence of preemption\n"; + result = test_ret_failure; + } + } + + return result; + } + + /** @brief get the last sequence */ + int64_t get_last_sequence (int task_id) { + npu_profile profile; + int64_t sequence = -1; + int status; + + status = UtilTRIV2::getProfile (task_id, &profile); + if (status == 0) { + if (profile.layers != nullptr) + sequence = profile.layers[profile.num_layers - 1].visa_exec_seq; + + putNPU_profile (&profile); + } else { + cerr << "Failed to get profile: " << status << "\n"; + sequence = status; + } + + return sequence; + } + + private: + uint32_t mid_model_id_; + uint32_t high_model_id_; +}; + +/** @brief apptest main */ +int +main (int argc, char **argv) +{ + Tester tester; + char * dir; + int status; + + status = tester.parseArgs (argc, argv, &dir, "[models' dir]"); + if (status == test_ret_skipped || dir == nullptr) + goto skip; + else if (status != test_ret_success) + goto err; + + /** initialize triv2 device */ + status = tester.init (dir); + if (status < test_ret_success) + goto err; + + /** run the inference with the device */ + status = tester.run (); + if (status < test_ret_success) + goto err; + + cerr << "[APPTEST] " << argv[0] << ": PASSED\n"; + return 0; + +err: + cerr << "[APPTEST] " << argv[0] << ": FAILED (" << status << ")\n"; + return status; + +skip: + cerr << "[APPTEST] " << argv[0] << ": SKIPPED\n"; + return 0; +} -- 2.7.4