blob: c5a62f6b5e63f30d2945023aea436653ac3bdbee [file] [log] [blame]
Kristofer Jonsson116a6352020-08-20 17:25:23 +02001/*
2 * Copyright (c) 2020 Arm Limited. All rights reserved.
3 *
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
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020019#include <ethosu.hpp>
Kristofer Jonsson116a6352020-08-20 17:25:23 +020020#include <uapi/ethosu.h>
21
Kristofer Jonsson116a6352020-08-20 17:25:23 +020022#include <fstream>
23#include <iomanip>
24#include <iostream>
25#include <list>
26#include <string>
Kristofer Jonsson79689c52020-10-16 14:42:19 +020027#include <unistd.h>
Kristofer Jonsson116a6352020-08-20 17:25:23 +020028
29using namespace std;
30using namespace EthosU;
31
Kristofer Jonsson79689c52020-10-16 14:42:19 +020032namespace {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020033int defaultTimeout = 60;
34
Kristofer Jonsson79689c52020-10-16 14:42:19 +020035void help(const string exe) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020036 cerr << "Usage: " << exe << " [ARGS]\n";
37 cerr << "\n";
38 cerr << "Arguments:\n";
39 cerr << " -h --help Print this help message.\n";
40 cerr << " -n --network File to read network from.\n";
41 cerr << " -i --ifm File to read IFM from.\n";
42 cerr << " -o --ofm File to write IFM to.\n";
43 cerr << " -t --timeout Timeout in seconds (default " << defaultTimeout << ").\n";
44 cerr << " -p Print OFM.\n";
45 cerr << endl;
46}
47
Kristofer Jonsson79689c52020-10-16 14:42:19 +020048void rangeCheck(const int i, const int argc, const string arg) {
49 if (i >= argc) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020050 cerr << "Error: Missing argument to '" << arg << "'" << endl;
51 exit(1);
52 }
53}
54
Kristofer Jonsson79689c52020-10-16 14:42:19 +020055shared_ptr<Buffer> allocAndFill(Device &device, const string filename) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020056 ifstream stream(filename, ios::binary);
Kristofer Jonsson79689c52020-10-16 14:42:19 +020057 if (!stream.is_open()) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020058 cerr << "Error: Failed to open '" << filename << "'" << endl;
59 exit(1);
60 }
61
62 stream.seekg(0, ios_base::end);
63 size_t size = stream.tellg();
64 stream.seekg(0, ios_base::beg);
65
66 shared_ptr<Buffer> buffer = make_shared<Buffer>(device, size);
67 buffer->resize(size);
68 stream.read(buffer->data(), size);
69
70 return buffer;
71}
72
Kristofer Jonsson79689c52020-10-16 14:42:19 +020073shared_ptr<Inference> createInference(Device &device, shared_ptr<Network> &network, const string &filename) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020074 // Open IFM file
75 ifstream stream(filename, ios::binary);
Kristofer Jonsson79689c52020-10-16 14:42:19 +020076 if (!stream.is_open()) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020077 cerr << "Error: Failed to open '" << filename << "'" << endl;
78 exit(1);
79 }
80
81 // Get IFM file size
82 stream.seekg(0, ios_base::end);
83 size_t size = stream.tellg();
84 stream.seekg(0, ios_base::beg);
85
Kristofer Jonsson79689c52020-10-16 14:42:19 +020086 if (size != network->getIfmSize()) {
87 cerr << "Error: IFM size does not match network size. filename=" << filename << ", size=" << size
88 << ", network=" << network->getIfmSize() << endl;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020089 exit(1);
90 }
91
92 // Create IFM buffers
93 vector<shared_ptr<Buffer>> ifm;
Kristofer Jonsson79689c52020-10-16 14:42:19 +020094 for (auto size : network->getIfmDims()) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020095 shared_ptr<Buffer> buffer = make_shared<Buffer>(device, size);
96 buffer->resize(size);
97 stream.read(buffer->data(), size);
98
Kristofer Jonsson79689c52020-10-16 14:42:19 +020099 if (!stream) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200100 cerr << "Error: Failed to read IFM" << endl;
101 exit(1);
102 }
103
104 ifm.push_back(buffer);
105 }
106
107 // Create OFM buffers
108 vector<shared_ptr<Buffer>> ofm;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200109 for (auto size : network->getOfmDims()) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200110 ofm.push_back(make_shared<Buffer>(device, size));
111 }
112
113 return make_shared<Inference>(network, ifm.begin(), ifm.end(), ofm.begin(), ofm.end());
114}
115
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200116ostream &operator<<(ostream &os, Buffer &buf) {
117 char *c = buf.data();
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200118 const char *end = c + buf.size();
119
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200120 while (c < end) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200121 os << hex << setw(2) << static_cast<int>(*c++) << " " << dec;
122 }
123
124 return os;
125}
126
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200127} // namespace
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200128
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200129int main(int argc, char *argv[]) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200130 const string exe = argv[0];
131 string networkArg;
132 list<string> ifmArg;
133 string ofmArg;
134 int timeout = defaultTimeout;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200135 bool print = false;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200136
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200137 for (int i = 1; i < argc; ++i) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200138 const string arg(argv[i]);
139
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200140 if (arg == "-h" || arg == "--help") {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200141 help(exe);
142 exit(1);
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200143 } else if (arg == "--network" || arg == "-n") {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200144 rangeCheck(++i, argc, arg);
145 networkArg = argv[i];
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200146 } else if (arg == "--ifm" || arg == "-i") {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200147 rangeCheck(++i, argc, arg);
148 ifmArg.push_back(argv[i]);
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200149 } else if (arg == "--ofm" || arg == "-o") {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200150 rangeCheck(++i, argc, arg);
151 ofmArg = argv[i];
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200152 } else if (arg == "--timeout" || arg == "-t") {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200153 rangeCheck(++i, argc, arg);
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200154 timeout = stoi(argv[i]);
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200155 } else if (arg == "-p") {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200156 print = true;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200157 } else {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200158 cerr << "Error: Invalid argument '" << arg << "'" << endl;
159 help(exe);
160 exit(1);
161 }
162 }
163
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200164 if (networkArg.empty()) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200165 cerr << "Error: Missing 'network' argument" << endl;
166 exit(1);
167 }
168
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200169 if (ifmArg.empty()) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200170 cerr << "Error: Missing 'ifm' argument" << endl;
171 exit(1);
172 }
173
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200174 if (ofmArg.empty()) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200175 cerr << "Error: Missing 'ofm' argument" << endl;
176 exit(1);
177 }
178
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200179 try {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200180 Device device;
181
182 cout << "Send ping" << endl;
183 device.ioctl(ETHOSU_IOCTL_PING);
184
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200185 /* Create network */
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200186 cout << "Create network" << endl;
187 shared_ptr<Buffer> networkBuffer = allocAndFill(device, networkArg);
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200188 shared_ptr<Network> network = make_shared<Network>(device, networkBuffer);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200189
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200190 /* Create one inference per IFM */
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200191 list<shared_ptr<Inference>> inferences;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200192 for (auto &filename : ifmArg) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200193 cout << "Create inference" << endl;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200194 inferences.push_back(createInference(device, network, filename));
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200195 }
196
197 cout << "Wait for inferences" << endl;
198
199 int ofmIndex = 0;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200200 for (auto &inference : inferences) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200201 inference->wait(timeout);
202
203 string status = inference->failed() ? "failed" : "success";
204 cout << "Inference status: " << status << endl;
205
206 string ofmFilename = ofmArg + "." + to_string(ofmIndex);
207 ofstream ofmStream(ofmFilename, ios::binary);
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200208 if (!ofmStream.is_open()) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200209 cerr << "Error: Failed to open '" << ofmFilename << "'" << endl;
210 exit(1);
211 }
212
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200213 if (!inference->failed()) {
214 for (auto &ofmBuffer : inference->getOfmBuffers()) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200215 cout << "OFM size: " << ofmBuffer->size() << endl;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200216
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200217 if (print) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200218 cout << "OFM data: " << *ofmBuffer << endl;
219 }
220
221 ofmStream.write(ofmBuffer->data(), ofmBuffer->size());
222 }
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200223 }
224
225 ofmIndex++;
226 }
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200227 } catch (Exception &e) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200228 cerr << "Error: " << e.what() << endl;
229 return 1;
230 }
231
232 return 0;
233}