blob: d2e62ce629a722ce91f4c3ef5ca5b35e8e8f2b33 [file] [log] [blame]
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +01001/*
Ledion Dajab0aacb42023-02-17 09:37:58 +01002 * SPDX-FileCopyrightText: Copyright 2021-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
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]);
Ledion Dajab0aacb42023-02-17 09:37:58 +010069 ETHOSU_PMU_CNTR_Enable(drv, 1u << 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()),
Jonny Svärd9038df92022-04-26 19:02:04 +0200103 commandStream(_commandStream), basePointers(_basePointers), pmu(drv, _pmuEvents) {}
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100104
105CommandStream::~CommandStream() {
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100106 ethosu_release_driver(drv);
107}
108
109int CommandStream::run(size_t repeat) {
110 // Base pointer array
Jonny Svärdc5941c42021-06-01 18:40:45 +0200111 uint64_t baseAddress[ETHOSU_BASEP_INDEXES];
112 size_t baseAddressSize[ETHOSU_BASEP_INDEXES];
113 for (size_t i = 0; i < ETHOSU_BASEP_INDEXES; i++) {
Anton Moberg908a07c2021-04-08 09:50:57 +0200114 baseAddress[i] = reinterpret_cast<uint64_t>(basePointers[i].data);
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100115 baseAddressSize[i] = reinterpret_cast<size_t>(basePointers[i].size);
116 }
117
118 while (repeat-- > 0) {
Kristofer Jonsson5410db12022-01-27 17:39:06 +0100119 int error = ethosu_invoke_v3(
120 drv, commandStream.data, commandStream.size, baseAddress, baseAddressSize, ETHOSU_BASEP_INDEXES, nullptr);
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100121
122 if (error != 0) {
123 printf("Inference failed. error=%d\n", error);
124 return 1;
125 }
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100126 }
127
128 return 0;
129}
130
Jonny Svärd44b250b2022-04-19 15:35:01 +0200131int CommandStream::run_async() {
132 // Base pointer array
133 uint64_t baseAddress[ETHOSU_BASEP_INDEXES];
134 size_t baseAddressSize[ETHOSU_BASEP_INDEXES];
135
136 for (size_t i = 0; i < ETHOSU_BASEP_INDEXES; i++) {
137 baseAddress[i] = reinterpret_cast<uint64_t>(basePointers[i].data);
138 baseAddressSize[i] = reinterpret_cast<size_t>(basePointers[i].size);
139 }
140
141 int error = ethosu_invoke_async(
142 drv, commandStream.data, commandStream.size, baseAddress, baseAddressSize, ETHOSU_BASEP_INDEXES, nullptr);
143
144 if (error != 0) {
145 printf("Inference invoke async failed. error=%d\n", error);
146 return 1;
147 }
148
149 return 0;
150}
151
152int CommandStream::wait_async(bool block) {
153 return ethosu_wait(drv, block);
154}
155
Anton Moberg908a07c2021-04-08 09:50:57 +0200156DataPointer &CommandStream::getCommandStream() {
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100157 return commandStream;
158}
159
Anton Moberg908a07c2021-04-08 09:50:57 +0200160BasePointers &CommandStream::getBasePointers() {
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100161 return basePointers;
162}
163
Anton Moberg908a07c2021-04-08 09:50:57 +0200164Pmu &CommandStream::getPmu() {
Kristofer Jonssonb5f7cfe2021-03-10 17:13:52 +0100165 return pmu;
166}
167
168}; // namespace CommandStream
169}; // namespace EthosU