diff options
author | Per Åstrand <per.astrand@arm.com> | 2020-10-24 20:17:10 +0200 |
---|---|---|
committer | Per Åstrand <per.astrand@arm.com> | 2020-11-16 13:57:40 +0100 |
commit | 2354d3e8a681b282e1fc1b098ecacca3c58e38c0 (patch) | |
tree | 84359938e9f9d71d2d11db35f8ab5ee00b16e343 | |
parent | f7e407a0fe58d76d54e3d1f9d2cb117036cd095b (diff) | |
download | ethos-u-linux-driver-stack-2354d3e8a681b282e1fc1b098ecacca3c58e38c0.tar.gz |
Add APIs for PMU configuration in library
Change-Id: I7694ab9dd5ff20c29feb0506bcf36a1cf4983243
-rw-r--r-- | driver_library/include/ethosu.hpp | 33 | ||||
-rw-r--r-- | driver_library/src/ethosu.cpp | 53 |
2 files changed, 79 insertions, 7 deletions
diff --git a/driver_library/include/ethosu.hpp b/driver_library/include/ethosu.hpp index 12192bf..70d0701 100644 --- a/driver_library/include/ethosu.hpp +++ b/driver_library/include/ethosu.hpp @@ -96,19 +96,46 @@ public: network(network) { std::copy(ifmBegin, ifmEnd, std::back_inserter(ifmBuffers)); std::copy(ofmBegin, ofmEnd, std::back_inserter(ofmBuffers)); - create(); + std::vector<uint32_t> counterConfigs = initializeCounterConfig(); + + create(counterConfigs, false); } + template <typename T, typename U> + Inference(std::shared_ptr<Network> &network, + const T &ifmBegin, + const T &ifmEnd, + const T &ofmBegin, + const T &ofmEnd, + const U &counters, + bool enableCycleCounter) : + network(network) { + std::copy(ifmBegin, ifmEnd, std::back_inserter(ifmBuffers)); + std::copy(ofmBegin, ofmEnd, std::back_inserter(ofmBuffers)); + std::vector<uint32_t> counterConfigs = initializeCounterConfig(); + + if (counters.size() > counterConfigs.size()) + throw EthosU::Exception("PMU Counters argument to large."); + + std::copy(counters.begin(), counters.end(), counterConfigs.begin()); + create(counterConfigs, enableCycleCounter); + } + virtual ~Inference(); - void wait(int timeoutSec = -1); + int wait(int timeoutSec = -1); + const std::vector<uint32_t> getPmuCounters(); + uint64_t getCycleCounter(); bool failed(); int getFd(); std::shared_ptr<Network> getNetwork(); std::vector<std::shared_ptr<Buffer>> &getIfmBuffers(); std::vector<std::shared_ptr<Buffer>> &getOfmBuffers(); + static uint32_t getMaxPmuEventCounters(); + private: - void create(); + void create(std::vector<uint32_t> &counterConfigs, bool enableCycleCounter); + std::vector<uint32_t> initializeCounterConfig(); int fd; std::shared_ptr<Network> network; diff --git a/driver_library/src/ethosu.cpp b/driver_library/src/ethosu.cpp index 9de26af..6b30827 100644 --- a/driver_library/src/ethosu.cpp +++ b/driver_library/src/ethosu.cpp @@ -232,7 +232,7 @@ Inference::~Inference() { close(fd); } -void Inference::create() { +void Inference::create(std::vector<uint32_t> &counterConfigs, bool cycleCounterEnable = false) { ethosu_uapi_inference_create uapi; if (ifmBuffers.size() > ETHOSU_FD_MAX) { @@ -243,6 +243,10 @@ void Inference::create() { throw Exception("OFM buffer overflow"); } + if (counterConfigs.size() != ETHOSU_PMU_EVENT_MAX) { + throw Exception("Wrong size of counter configurations"); + } + uapi.ifm_count = 0; for (auto it : ifmBuffers) { uapi.ifm_fd[uapi.ifm_count++] = it->getFd(); @@ -253,10 +257,24 @@ void Inference::create() { uapi.ofm_fd[uapi.ofm_count++] = it->getFd(); } + for (int i = 0; i < ETHOSU_PMU_EVENT_MAX; i++) { + uapi.pmu_config.events[i] = counterConfigs[i]; + } + + uapi.pmu_config.cycle_count = cycleCounterEnable; + fd = network->ioctl(ETHOSU_IOCTL_INFERENCE_CREATE, static_cast<void *>(&uapi)); } -void Inference::wait(int timeoutSec) { +std::vector<uint32_t> Inference::initializeCounterConfig() { + return std::vector<uint32_t>(ETHOSU_PMU_EVENT_MAX, 0); +} + +uint32_t Inference::getMaxPmuEventCounters() { + return ETHOSU_PMU_EVENT_MAX; +} + +int Inference::wait(int timeoutSec) { pollfd pfd; pfd.fd = fd; @@ -266,12 +284,39 @@ void Inference::wait(int timeoutSec) { int ret = ::poll(&pfd, 1, timeoutSec * 1000); cout << "Poll. ret=" << ret << ", revents=" << pfd.revents << endl; + + return ret; } bool Inference::failed() { - ethosu_uapi_status status = static_cast<ethosu_uapi_status>(eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS)); + ethosu_uapi_result_status uapi; + + eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS, static_cast<void *>(&uapi)); + + return uapi.status != ETHOSU_UAPI_STATUS_OK; +} + +const std::vector<uint32_t> Inference::getPmuCounters() { + ethosu_uapi_result_status uapi; + std::vector<uint32_t> counterValues = std::vector<uint32_t>(ETHOSU_PMU_EVENT_MAX, 0); + + eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS, static_cast<void *>(&uapi)); + + for (int i = 0; i < ETHOSU_PMU_EVENT_MAX; i++) { + if (uapi.pmu_config.events[i]) { + counterValues.at(i) = uapi.pmu_count.events[i]; + } + } + + return counterValues; +} + +uint64_t Inference::getCycleCounter() { + ethosu_uapi_result_status uapi; + + eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS, static_cast<void *>(&uapi)); - return status != ETHOSU_UAPI_STATUS_OK; + return uapi.pmu_count.cycle_count; } int Inference::getFd() { |