aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPer Åstrand <per.astrand@arm.com>2020-10-24 20:17:10 +0200
committerPer Åstrand <per.astrand@arm.com>2020-11-16 13:57:40 +0100
commit2354d3e8a681b282e1fc1b098ecacca3c58e38c0 (patch)
tree84359938e9f9d71d2d11db35f8ab5ee00b16e343
parentf7e407a0fe58d76d54e3d1f9d2cb117036cd095b (diff)
downloadethos-u-linux-driver-stack-2354d3e8a681b282e1fc1b098ecacca3c58e38c0.tar.gz
Add APIs for PMU configuration in library
Change-Id: I7694ab9dd5ff20c29feb0506bcf36a1cf4983243
-rw-r--r--driver_library/include/ethosu.hpp33
-rw-r--r--driver_library/src/ethosu.cpp53
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() {