1/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20/*!
21 * \file runtime/static_library.cc
22 * \brief Represents a generic '.o' static library which can be linked into the final output
23 * dynamic library by export_library.
24 */
25#include "./static_library.h"
26
27#include <tvm/runtime/memory.h>
28#include <tvm/runtime/module.h>
29#include <tvm/runtime/packed_func.h>
30#include <tvm/runtime/registry.h>
31
32#include <iostream>
33
34#include "file_utils.h"
35
36namespace tvm {
37namespace runtime {
38
39namespace {
40
41/*!
42 * \brief A '.o' library which can be linked into the final output library by export_library.
43 * Can be used by external codegen tools which can produce a ready-to-link artifact.
44 */
45class StaticLibraryNode final : public runtime::ModuleNode {
46 public:
47 ~StaticLibraryNode() override = default;
48
49 const char* type_key() const final { return "static_library"; }
50
51 PackedFunc GetFunction(const std::string& name, const ObjectPtr<Object>& sptr_to_self) final {
52 if (name == "get_func_names") {
53 return PackedFunc([sptr_to_self, this](TVMArgs args, TVMRetValue* rv) { *rv = func_names_; });
54 } else {
55 return {};
56 }
57 }
58
59 void SaveToFile(const std::string& file_name, const std::string& format) final {
60 VLOG(0) << "Saving static library of " << data_.size() << " bytes implementing " << FuncNames()
61 << " to '" << file_name << "'";
62 SaveBinaryToFile(file_name, data_);
63 }
64
65 bool IsDSOExportable() const final { return true; }
66
67 bool ImplementsFunction(const String& name, bool query_imports) final {
68 return std::find(func_names_.begin(), func_names_.end(), name) != func_names_.end();
69 }
70
71 std::string FuncNames() {
72 std::ostringstream os;
73 os << "[";
74 bool first = true;
75 for (const auto& func_name : func_names_) {
76 if (first) {
77 first = false;
78 } else {
79 os << ", ";
80 }
81 os << "'" << func_name << "'";
82 }
83 os << "]";
84 return os.str();
85 }
86
87 /*! \brief Contents of the object file. */
88 std::string data_;
89 /*! \brief Function names exported by the above. */
90 Array<String> func_names_;
91};
92
93} // namespace
94
95Module LoadStaticLibrary(const std::string& filename, Array<String> func_names) {
96 auto node = make_object<StaticLibraryNode>();
97 LoadBinaryFromFile(filename, &node->data_);
98 node->func_names_ = std::move(func_names);
99 VLOG(0) << "Loaded static library from '" << filename << "' implementing " << node->FuncNames();
100 return Module(node);
101}
102
103TVM_REGISTER_GLOBAL("runtime.ModuleLoadStaticLibrary").set_body_typed(LoadStaticLibrary);
104
105} // namespace runtime
106} // namespace tvm
107