blob: a2cb63e90040e998668fa7e40a23c4552c4f1cef [file] [log] [blame]
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +01001/*
Kristofer Jonsson5410db12022-01-27 17:39:06 +01002 * Copyright (c) 2021-2022 Arm Limited. All rights reserved.
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +01003 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
19/****************************************************************************
20 * Includes
21 ****************************************************************************/
22
23#include "command_stream.hpp"
24
25#include <inttypes.h>
26#include <stdio.h>
27
28using namespace std;
29
30namespace EthosU {
31namespace CommandStream {
32
33/****************************************************************************
34 * DataPointer
35 ****************************************************************************/
36
37DataPointer::DataPointer() : data(nullptr), size(0) {}
38
39DataPointer::DataPointer(const char *_data, size_t _size) : data(_data), size(_size) {}
40
41bool DataPointer::operator!=(const DataPointer &other) {
42 if (size != other.size) {
43 return true;
44 }
45
46 for (size_t i = 0; i < size; i++) {
47 if (data[i] != other.data[i]) {
48 return true;
49 }
50 }
51
52 return false;
53}
54
55/****************************************************************************
56 * PmuConfig
57 ****************************************************************************/
58
Anton Moberg908a07c2021-04-08 09:50:57 +020059Pmu::Pmu(ethosu_driver *_drv, const PmuEvents &_config) : drv(_drv), config(_config) {
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +010060 // Enable PMU block
Anton Moberg0cb936d2021-05-03 17:03:41 +020061 ETHOSU_PMU_Enable(drv);
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +010062
63 // Enable cycle counter
Anton Moberg0cb936d2021-05-03 17:03:41 +020064 ETHOSU_PMU_CNTR_Enable(drv, ETHOSU_PMU_CCNT_Msk);
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +010065
66 // Configure event types
67 for (size_t i = 0; i < config.size(); i++) {
Anton Moberg0cb936d2021-05-03 17:03:41 +020068 ETHOSU_PMU_Set_EVTYPER(drv, i, config[i]);
69 ETHOSU_PMU_CNTR_Enable(drv, 1 << i);
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +010070 }
71}
72
73void Pmu::clear() {
Anton Moberg0cb936d2021-05-03 17:03:41 +020074 ETHOSU_PMU_CYCCNT_Reset(drv);
75 ETHOSU_PMU_EVCNTR_ALL_Reset(drv);
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +010076}
77
78void Pmu::print() {
79 printf("PMU={cycleCount=%llu, events=[%" PRIu32 ", %" PRIu32 ", %" PRIu32 ", %" PRIu32 "]}\n",
Anton Moberg0cb936d2021-05-03 17:03:41 +020080 ETHOSU_PMU_Get_CCNTR(drv),
81 ETHOSU_PMU_Get_EVCNTR(drv, 0),
82 ETHOSU_PMU_Get_EVCNTR(drv, 1),
83 ETHOSU_PMU_Get_EVCNTR(drv, 2),
84 ETHOSU_PMU_Get_EVCNTR(drv, 3));
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +010085}
86
87uint64_t Pmu::getCycleCount() const {
Anton Moberg0cb936d2021-05-03 17:03:41 +020088 return ETHOSU_PMU_Get_CCNTR(drv);
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +010089}
90
91uint32_t Pmu::getEventCount(size_t index) const {
Anton Moberg0cb936d2021-05-03 17:03:41 +020092 return ETHOSU_PMU_Get_EVCNTR(drv, index);
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +010093}
94
95/****************************************************************************
96 * CommandStream
97 ****************************************************************************/
98
99CommandStream::CommandStream(const DataPointer &_commandStream,
100 const BasePointers &_basePointers,
101 const PmuEvents &_pmuEvents) :
102 drv(ethosu_reserve_driver()),
Anton Moberg908a07c2021-04-08 09:50:57 +0200103 commandStream(_commandStream), basePointers(_basePointers), pmu(drv, _pmuEvents) {
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100104
105 // Use simplified driver setup
Anton Mobergebe9a152021-05-03 09:28:52 +0200106 ethosu_set_power_mode(drv, true);
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100107}
108
109CommandStream::~CommandStream() {
Anton Mobergebe9a152021-05-03 09:28:52 +0200110 ethosu_set_power_mode(drv, false);
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100111 ethosu_release_driver(drv);
112}
113
114int CommandStream::run(size_t repeat) {
115 // Base pointer array
Jonny Svärdc5941c42021-06-01 18:40:45 +0200116 uint64_t baseAddress[ETHOSU_BASEP_INDEXES];
117 size_t baseAddressSize[ETHOSU_BASEP_INDEXES];
118 for (size_t i = 0; i < ETHOSU_BASEP_INDEXES; i++) {
Anton Moberg908a07c2021-04-08 09:50:57 +0200119 baseAddress[i] = reinterpret_cast<uint64_t>(basePointers[i].data);
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100120 baseAddressSize[i] = reinterpret_cast<size_t>(basePointers[i].size);
121 }
122
123 while (repeat-- > 0) {
Kristofer Jonsson5410db12022-01-27 17:39:06 +0100124 int error = ethosu_invoke_v3(
125 drv, commandStream.data, commandStream.size, baseAddress, baseAddressSize, ETHOSU_BASEP_INDEXES, nullptr);
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100126
127 if (error != 0) {
128 printf("Inference failed. error=%d\n", error);
129 return 1;
130 }
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100131 }
132
133 return 0;
134}
135
Jonny Svärd44b250b2022-04-19 15:35:01 +0200136int CommandStream::run_async() {
137 // Base pointer array
138 uint64_t baseAddress[ETHOSU_BASEP_INDEXES];
139 size_t baseAddressSize[ETHOSU_BASEP_INDEXES];
140
141 for (size_t i = 0; i < ETHOSU_BASEP_INDEXES; i++) {
142 baseAddress[i] = reinterpret_cast<uint64_t>(basePointers[i].data);
143 baseAddressSize[i] = reinterpret_cast<size_t>(basePointers[i].size);
144 }
145
146 int error = ethosu_invoke_async(
147 drv, commandStream.data, commandStream.size, baseAddress, baseAddressSize, ETHOSU_BASEP_INDEXES, nullptr);
148
149 if (error != 0) {
150 printf("Inference invoke async failed. error=%d\n", error);
151 return 1;
152 }
153
154 return 0;
155}
156
157int CommandStream::wait_async(bool block) {
158 return ethosu_wait(drv, block);
159}
160
Anton Moberg908a07c2021-04-08 09:50:57 +0200161DataPointer &CommandStream::getCommandStream() {
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100162 return commandStream;
163}
164
Anton Moberg908a07c2021-04-08 09:50:57 +0200165BasePointers &CommandStream::getBasePointers() {
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100166 return basePointers;
167}
168
Anton Moberg908a07c2021-04-08 09:50:57 +0200169Pmu &CommandStream::getPmu() {
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100170 return pmu;
171}
172
173}; // namespace CommandStream
174}; // namespace EthosU