| 136 | } |
| 137 | |
| 138 | Module Module::LoadFromFile(const String& file_name) { |
| 139 | String format = [&file_name]() -> String { |
| 140 | const char* data = file_name.data(); |
| 141 | for (size_t i = file_name.size(); i > 0; i--) { |
| 142 | if (data[i - 1] == '.') { |
| 143 | return String(data + i, file_name.size() - i); |
| 144 | } |
| 145 | } |
| 146 | TVM_FFI_THROW(RuntimeError) << "Failed to get file format from " << file_name; |
| 147 | TVM_FFI_UNREACHABLE(); |
| 148 | }(); |
| 149 | |
| 150 | if (format == "dll" || format == "dylib" || format == "dso") { |
| 151 | format = "so"; |
| 152 | } |
| 153 | String loader_name = "ffi.Module.load_from_file." + format; |
| 154 | const auto floader = tvm::ffi::Function::GetGlobal(loader_name); |
| 155 | if (!floader.has_value()) { |
| 156 | TVM_FFI_THROW(RuntimeError) << "Loader for `." << format << "` files is not registered," |
| 157 | << " resolved to (" << loader_name << ") in the global registry." |
| 158 | << "Ensure that you have loaded the correct runtime code, and" |
| 159 | << "that you are on the correct hardware architecture."; |
| 160 | } |
| 161 | return (*floader)(file_name, format).cast<Module>(); |
| 162 | } |
| 163 | |
| 164 | TVM_FFI_STATIC_INIT_BLOCK() { |
| 165 | namespace refl = tvm::ffi::reflection; |