ONE - On-device Neural Engine
Loading...
Searching...
No Matches
Driver.cpp
Go to the documentation of this file.
1/*
2 * Copyright (c) 2018 Samsung Electronics Co., Ltd. All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <enco/Frontend.h>
18#include <enco/Backend.h>
19
20#include <cmdline/View.h>
21
22#include <string>
23#include <vector>
24
25#include <functional>
26
27namespace cmdline
28{
29
30// TODO Extract this helper class
31class Vector : public cmdline::View
32{
33public:
34 uint32_t size(void) const { return _args.size(); }
35
36public:
37 const char *at(uint32_t nth) const { return _args.at(nth).c_str(); }
38
39public:
40 Vector &append(const std::string &arg)
41 {
42 _args.emplace_back(arg);
43 return (*this);
44 }
45
46private:
47 std::vector<std::string> _args;
48};
49
50} // namespace cmdline
51
52namespace
53{
54
55class Zone
56{
57public:
58 Zone() = default;
59
60public:
61 const cmdline::View *args(void) const { return &_args; }
62
63public:
64 void append(const std::string &arg) { _args.append(arg); }
65
66private:
67 cmdline::Vector _args;
68};
69
70} // namespace
71
72#include <dlfcn.h>
73
74namespace
75{
76
77class FrontendFactory
78{
79public:
80 FrontendFactory(const std::string &path)
81 {
82 _handle = dlopen(path.c_str(), RTLD_LAZY);
83 assert(_handle != nullptr);
84 }
85
86public:
87 // Copy is not allowed to avoid double close
88 FrontendFactory(const FrontendFactory &) = delete;
89 FrontendFactory(FrontendFactory &&) = delete;
90
91public:
92 ~FrontendFactory() { dlclose(_handle); }
93
94private:
95 using Entry = std::unique_ptr<enco::Frontend> (*)(const cmdline::View &);
96
97private:
98 Entry entry(void) const
99 {
100 auto entry = reinterpret_cast<Entry>(dlsym(_handle, "make_frontend"));
101 assert(entry != nullptr);
102 return entry;
103 }
104
105public:
106 std::unique_ptr<enco::Frontend> make(const cmdline::View *args) const
107 {
108 auto fn = entry();
109 return fn(*args);
110 }
111
112private:
113 void *_handle;
114};
115
116} // namespace
117
118namespace
119{
120
121class FrontendZone : public Zone
122{
123public:
124 FrontendZone(const std::string &path) : _factory{path}
125 {
126 // DO NOTHING
127 }
128
129public:
130 const FrontendFactory *factory(void) const { return &_factory; }
131
132private:
133 FrontendFactory _factory;
134};
135
136} // namespace
137
138#include <memory>
139#include <map>
140
141#include <iostream>
142#include <stdexcept>
143
144static int entry(int argc, char **argv)
145{
146 // Usage:
147 // [Command] --frontend [Frontend .so path] --frontend-arg ...
148 std::unique_ptr<FrontendZone> frontend_zone;
149 cmdline::Vector backend_args;
150
151 // Simple argument parser (based on map)
152 std::map<std::string, std::function<void(const std::string &arg)>> argparse;
153
154 argparse["--frontend"] = [&](const std::string &path) {
155 frontend_zone = std::make_unique<FrontendZone>(path);
156 };
157
158 argparse["--frontend-arg"] = [&](const std::string &arg) { frontend_zone->append(arg); };
159 argparse["--backend-arg"] = [&](const std::string &arg) { backend_args.append(arg); };
160
161 if (argc < 2)
162 {
163 std::cerr << "Usage:" << std::endl;
164 std::cerr << "[Command] --frontend [.so path]" << std::endl;
165 std::cerr << " --frontend-arg [argument] ..." << std::endl;
166 std::cerr << " --backend-arg [argument] ..." << std::endl;
167 return 255;
168 }
169
170 for (int n = 1; n < argc; n += 2)
171 {
172 const std::string tag{argv[n]};
173 const std::string arg{argv[n + 1]};
174
175 auto it = argparse.find(tag);
176
177 if (it == argparse.end())
178 {
179 std::cerr << "Option '" << tag << "' is not supported" << std::endl;
180 return 255;
181 }
182
183 it->second(arg);
184 }
185
186 assert(frontend_zone != nullptr);
187
188 auto frontend = frontend_zone->factory()->make(frontend_zone->args());
189
190 auto bundle = frontend->load();
191
192 auto backend = make_backend(backend_args);
193
194 backend->compile(bundle.module(), bundle.data());
195
196 return 0;
197}
198
199#ifdef NDEBUG
200int main(int argc, char **argv)
201{
202 try
203 {
204 return entry(argc, argv);
205 }
206 catch (const std::exception &e)
207 {
208 std::cerr << "ERROR: " << e.what() << std::endl;
209 }
210
211 return 255;
212}
213#else // NDEBUG
214int main(int argc, char **argv)
215{
216 // NOTE main does not catch internal exceptions for debug build to make it easy to
217 // check the stacktrace with a debugger
218 return entry(argc, argv);
219}
220#endif // !NDEBUG
int main(void)
Vector & append(const std::string &arg)
Definition Driver.cpp:40
uint32_t size(void) const
Definition Driver.cpp:34
const char * at(uint32_t nth) const
Definition Driver.cpp:37
int entry(const int argc, char **argv)
Definition Driver.cpp:53
int entry(int argc, char **argv)
Definition Driver.cpp:29
std::unique_ptr< enco::Backend > make_backend(const cmdline::View &)
Definition Backend.cpp:174
Definition View.h:23
args
Definition infer.py:21