Skip to content

Commit 632a6e1

Browse files
dbortfacebook-github-bot
authored andcommitted
Make bundled_executor_runner use MethodMeta interface and adjust non-const indices (#319)
Summary: Pull Request resolved: #319 The new MethodMeta interface avoids the need to adjust non-const buffer indices by 1. While I'm here, stop using runtime_allocator to create the outputs list: it's not legal to touch the runtime_allocator after the Method is created. Reviewed By: JacobSzwejbka Differential Revision: D49208343 fbshipit-source-id: 86850941ae1e1d3896e0704130785ccd0a06ed37
1 parent a404e28 commit 632a6e1

File tree

1 file changed

+24
-39
lines changed

1 file changed

+24
-39
lines changed

examples/bundled_executor_runner/bundled_executor_runner.cpp

Lines changed: 24 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -115,15 +115,22 @@ int main(int argc, char** argv) {
115115
ET_LOG(Info, "Model file %s is loaded.", model_path);
116116

117117
// Use the first method in the program.
118-
const size_t plan_index = 0;
119118
const char* method_name = nullptr;
120119
{
121-
const auto method_name_result = program->get_method_name(plan_index);
120+
const auto method_name_result = program->get_method_name(0);
122121
ET_CHECK_MSG(method_name_result.ok(), "Program has no methods");
123122
method_name = *method_name_result;
124123
}
125124
ET_LOG(Info, "Running method %s", method_name);
126125

126+
// MethodMeta describes the memory requirements of the method.
127+
Result<MethodMeta> method_meta = program->method_meta(method_name);
128+
ET_CHECK_MSG(
129+
method_meta.ok(),
130+
"Failed to get method_meta for %s: 0x%x",
131+
method_name,
132+
(unsigned int)method_meta.error());
133+
127134
//
128135
// The runtime does not use malloc/new; it allocates all memory using the
129136
// MemoryManger provided by the client. Clients are responsible for allocating
@@ -156,33 +163,13 @@ int main(int argc, char** argv) {
156163
// have more than one for, e.g., slow/large DRAM and fast/small SRAM.
157164
std::vector<std::unique_ptr<uint8_t[]>> non_const_buffers;
158165
std::vector<MemoryAllocator> non_const_allocators;
159-
size_t num_non_const_buffers = 0;
160-
{
161-
auto result = program->num_non_const_buffers(method_name);
162-
ET_CHECK_MSG(
163-
result.ok(),
164-
"Failed to get number of non-const buffers for method %s: 0x%x",
165-
method_name,
166-
(unsigned int)result.error());
167-
num_non_const_buffers = *result;
168-
}
169-
// Note that this loop starts at ID 1, because ID 0 is reserved. But, the
170-
// HierarchicalAllocator indices are zero-based, so it's later adjusted by -1.
171-
for (size_t id = 1; id < num_non_const_buffers; ++id) {
172-
auto buffer_size = program->get_non_const_buffer_size(id, method_name);
173-
ET_CHECK_MSG(
174-
buffer_size.ok(),
175-
"Failed to get size of non-const buffer %zu for method %s: 0x%x",
176-
id,
177-
method_name,
178-
(unsigned int)buffer_size.error());
179-
ET_LOG(
180-
Info, "Setting up non-const buffer %zu, size %zu.", id, *buffer_size);
181-
non_const_buffers.push_back(std::make_unique<uint8_t[]>(*buffer_size));
182-
// Since the list of allocators began empty, buffer ID N will live at index
183-
// N-1.
166+
size_t num_non_const_buffers = method_meta->num_non_const_buffers();
167+
for (size_t id = 0; id < num_non_const_buffers; ++id) {
168+
size_t buffer_size = method_meta->non_const_buffer_size(id).get();
169+
ET_LOG(Info, "Setting up non-const buffer %zu, size %zu.", id, buffer_size);
170+
non_const_buffers.push_back(std::make_unique<uint8_t[]>(buffer_size));
184171
non_const_allocators.push_back(
185-
MemoryAllocator(*buffer_size, non_const_buffers.back().get()));
172+
MemoryAllocator(buffer_size, non_const_buffers.back().get()));
186173
non_const_allocators.back().enable_profiling("non_const_allocators");
187174
}
188175
HierarchicalAllocator non_const_allocator(
@@ -254,19 +241,17 @@ int main(int argc, char** argv) {
254241
status);
255242
ET_LOG(Info, "Model executed successfully.");
256243

257-
auto output_list =
258-
runtime_allocator.allocateList<EValue>(method->outputs_size());
259-
status = method->get_outputs(output_list, method->outputs_size());
244+
// Print the outputs.
245+
std::vector<EValue> outputs(method->outputs_size());
246+
status = method->get_outputs(outputs.data(), outputs.size());
260247
ET_CHECK(status == Error::Ok);
261-
// The following code assumes all output EValues are floating point
262-
// tensors. We need to handle other types of EValues and tensor
263-
// dtypes. Furthermore, we need a util to print tensors in a more
264-
// interpretable (e.g. size, dtype) and readable way.
265-
// TODO for the above at T159700776
266-
for (size_t i = 0; i < method->outputs_size(); i++) {
267-
auto output_tensor = output_list[i].toTensor();
248+
for (EValue& output : outputs) {
249+
// TODO(T159700776): This assumes that all outputs are fp32 tensors. Add
250+
// support for other EValues and Tensor dtypes, and print tensors in a more
251+
// readable way.
252+
auto output_tensor = output.toTensor();
268253
auto data_output = output_tensor.const_data_ptr<float>();
269-
for (size_t j = 0; j < output_list[i].toTensor().numel(); ++j) {
254+
for (size_t j = 0; j < output_tensor.numel(); ++j) {
270255
ET_LOG(Info, "%f", data_output[j]);
271256
}
272257
}

0 commit comments

Comments
 (0)