From e446b42e711e56974d07f242e18129c335966604 Mon Sep 17 00:00:00 2001 From: Davide Grohmann Date: Tue, 19 Oct 2021 15:33:23 +0200 Subject: Improve granularity of wait call in Inference class It now accepts a timeout expressed in nanoseconds. Change-Id: I77fb89c33dc117f846b86494883548ef3241f0ab --- driver_library/include/ethosu.hpp | 2 +- driver_library/src/ethosu.cpp | 25 ++++++++++++++++--------- driver_library/src/ethosu_stub.cpp | 12 +++++++++--- utils/inference_runner/inference_runner.cpp | 14 ++++++++------ 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/driver_library/include/ethosu.hpp b/driver_library/include/ethosu.hpp index d70ec95..fe3dc83 100644 --- a/driver_library/include/ethosu.hpp +++ b/driver_library/include/ethosu.hpp @@ -214,7 +214,7 @@ public: virtual ~Inference(); - int wait(int timeoutSec = -1); + int wait(int64_t timeoutNanos = -1); const std::vector getPmuCounters(); uint64_t getCycleCounter(); bool failed(); diff --git a/driver_library/src/ethosu.cpp b/driver_library/src/ethosu.cpp index 4457e3f..45e8525 100644 --- a/driver_library/src/ethosu.cpp +++ b/driver_library/src/ethosu.cpp @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -52,10 +53,11 @@ __attribute__((weak)) int eopen(const char *pathname, int flags) { return fd; } -__attribute__((weak)) int epoll(struct pollfd *fds, nfds_t nfds, int timeout) { - int result = ::poll(fds, nfds, timeout); +__attribute__((weak)) int +eppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigmask) { + int result = ::ppoll(fds, nfds, tmo_p, sigmask); if (result < 0) { - throw Exception("Failed to wait for poll event"); + throw Exception("Failed to wait for ppoll event or signal"); } return result; @@ -391,18 +393,23 @@ uint32_t Inference::getMaxPmuEventCounters() { return ETHOSU_PMU_EVENT_MAX; } -int Inference::wait(int timeoutSec) { - pollfd pfd; - +int Inference::wait(int64_t timeoutNanos) { + struct pollfd pfd; pfd.fd = fd; pfd.events = POLLIN | POLLERR; pfd.revents = 0; - int ret = epoll(&pfd, 1, timeoutSec * 1000); + // if timeout negative wait forever + if (timeoutNanos < 0) { + return eppoll(&pfd, 1, NULL, NULL); + } - cout << "Poll. ret=" << ret << ", revents=" << pfd.revents << endl; + struct timespec tmo_p; + int64_t nanosec = 1000000000; + tmo_p.tv_sec = timeoutNanos / nanosec; + tmo_p.tv_nsec = timeoutNanos % nanosec; - return ret; + return eppoll(&pfd, 1, &tmo_p, NULL); } bool Inference::failed() { diff --git a/driver_library/src/ethosu_stub.cpp b/driver_library/src/ethosu_stub.cpp index 510007f..428d276 100644 --- a/driver_library/src/ethosu_stub.cpp +++ b/driver_library/src/ethosu_stub.cpp @@ -76,9 +76,15 @@ int eioctl(int, unsigned long cmd, void *) { } } -int epoll(struct pollfd *, nfds_t, int timeout_ms) { - int t = 1000 * timeout_ms / 2; - usleep(t); +int eppoll(struct pollfd *, nfds_t, const struct timespec *tmo_p, const sigset_t *) { + if (tmo_p == NULL) { + // sleep one second + usleep(1000000ul); + } else { + unsigned long t = tmo_p->tv_sec / 2; // sleep half of the time + t = t * 1000ul * 1000ul; // sec to microsec + usleep(t); + } return 1; } } // namespace EthosU diff --git a/utils/inference_runner/inference_runner.cpp b/utils/inference_runner/inference_runner.cpp index e8c4144..a72a954 100644 --- a/utils/inference_runner/inference_runner.cpp +++ b/utils/inference_runner/inference_runner.cpp @@ -31,7 +31,7 @@ using namespace std; using namespace EthosU; namespace { -int defaultTimeout = 60; +int64_t defaultTimeout = 60000000000; void help(const string exe) { cerr << "Usage: " << exe << " [ARGS]\n"; @@ -44,7 +44,7 @@ void help(const string exe) { cerr << " -P --pmu [0.." << Inference::getMaxPmuEventCounters() << "] eventid.\n"; cerr << " PMU counter to enable followed by eventid, can be passed multiple times.\n"; cerr << " -C --cycles Enable cycle counter for inference.\n"; - cerr << " -t --timeout Timeout in seconds (default " << defaultTimeout << ").\n"; + cerr << " -t --timeout Timeout in nanoseconds (default " << defaultTimeout << ").\n"; cerr << " -p Print OFM.\n"; cerr << endl; } @@ -141,7 +141,7 @@ int main(int argc, char *argv[]) { list ifmArg; vector enabledCounters(Inference::getMaxPmuEventCounters()); string ofmArg; - int timeout = defaultTimeout; + int64_t timeout = defaultTimeout; bool print = false; bool enableCycleCounter = false; @@ -162,7 +162,7 @@ int main(int argc, char *argv[]) { ofmArg = argv[i]; } else if (arg == "--timeout" || arg == "-t") { rangeCheck(++i, argc, arg); - timeout = stoi(argv[i]); + timeout = stoll(argv[i]); } else if (arg == "--pmu" || arg == "-P") { unsigned pmu = 0, event = 0; rangeCheck(++i, argc, arg); @@ -244,8 +244,10 @@ int main(int argc, char *argv[]) { for (auto &inference : inferences) { /* make sure the wait completes ok */ - if (inference->wait(timeout) <= 0) { - cout << "Failed to wait for inference completion" << endl; + try { + inference->wait(timeout); + } catch (std::exception &e) { + cout << "Failed to wait for inference completion: " << e.what() << endl; exit(1); } -- cgit v1.2.1