/* * Copyright (c) Meta Platforms, Inc. and affiliates. * All rights reserved. * * This source code is licensed under the BSD-style license found in the * LICENSE file in the root directory of this source tree. */ #include #include #include #include #include #include #include using namespace torch::executor; using torch::executor::util::FileDataLoader; static uint8_t method_allocator_pool[1024]; static uint8_t activation_pool[512]; int main(int argc, char** argv) { runtime_init(); ET_CHECK_MSG(argc == 2, "Expected model file argument."); MemoryAllocator method_allocator( sizeof(method_allocator_pool), method_allocator_pool); method_allocator.enable_profiling("method allocator"); Span memory_planned_buffers[1]{ {activation_pool, sizeof(activation_pool)}}; HierarchicalAllocator planned_memory({memory_planned_buffers, 1}); MemoryManager memory_manager(&method_allocator, &planned_memory); Result loader = FileDataLoader::from(argv[1]); ET_CHECK_MSG( loader.ok(), "FileDataLoader::from() failed: 0x%" PRIx32, static_cast(loader.error())); uint32_t prof_tok = EXECUTORCH_BEGIN_PROF("de-serialize model"); const auto program = Program::load(&loader.get()); EXECUTORCH_END_PROF(prof_tok); ET_CHECK_MSG( program.ok(), "Program::load() failed: 0x%" PRIx32, static_cast(program.error())); ET_LOG(Info, "Program file %s loaded.", argv[1]); // Use the first method in the program. const char* method_name = nullptr; { const auto method_name_result = program->get_method_name(0); ET_CHECK_MSG(method_name_result.ok(), "Program has no methods"); method_name = *method_name_result; } ET_LOG(Info, "Loading method %s", method_name); prof_tok = EXECUTORCH_BEGIN_PROF("load model"); Result method = program->load_method(method_name, &memory_manager); EXECUTORCH_END_PROF(prof_tok); ET_CHECK(method.ok()); ET_LOG(Info, "Method loaded."); // Prepare for inputs // It assumes the input is one tensor. float data[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0}; Tensor::SizesType sizes[] = {6}; Tensor::DimOrderType dim_order[] = {0}; TensorImpl impl(ScalarType::Float, 1, sizes, data, dim_order); Tensor t(&impl); Error set_input_error = method->set_input(t, 0); ET_CHECK(set_input_error == Error::Ok); ET_LOG(Info, "Inputs prepared."); prof_tok = EXECUTORCH_BEGIN_PROF("run model"); Error status = method->execute(); EXECUTORCH_END_PROF(prof_tok); ET_CHECK(status == Error::Ok); ET_LOG(Info, "Model executed successfully."); // print output auto output_list = method_allocator.allocateList(method->outputs_size()); status = method->get_outputs(output_list, method->outputs_size()); ET_CHECK(status == Error::Ok); // It assumes the outputs are all tensors. for (size_t i = 0; i < method->outputs_size(); i++) { auto output_tensor = output_list[i].toTensor(); auto data_output = output_tensor.const_data_ptr(); for (size_t j = 0; j < output_list[i].toTensor().numel(); ++j) { ET_LOG(Info, "%f", data_output[j]); } } prof_result_t prof_result; EXECUTORCH_DUMP_PROFILE_RESULTS(&prof_result); if (prof_result.num_bytes != 0) { FILE* ptr = fopen("prof_result.bin", "w+"); fwrite(prof_result.prof_data, 1, prof_result.num_bytes, ptr); fclose(ptr); } return 0; }