网页设计和网站开发哪个好昆山网站建设kshuituo
2026/2/6 3:21:50 网站建设 项目流程
网页设计和网站开发哪个好,昆山网站建设kshuituo,外贸网络营销的主动营销有哪些,网站制作过程步骤TVM 现已更新到 0.21.0 版本#xff0c;TVM 中文文档已经和新版本对齐。 Apache TVM 是一个深度的深度学习编译框架#xff0c;适用于 CPU、GPU 和各种机器学习加速芯片。更多 TVM 中文文档可访问 →https://tvm.hyper.ai/ 在部署 TVM 运行时模块时#xff0c;无论目标是 …TVM 现已更新到 0.21.0 版本TVM 中文文档已经和新版本对齐。Apache TVM 是一个深度的深度学习编译框架适用于 CPU、GPU 和各种机器学习加速芯片。更多 TVM 中文文档可访问 →https://tvm.hyper.ai/在部署 TVM 运行时模块时无论目标是 CPU 还是 GPUTVM最终只需要一个动态共享库dynamic shared library。实现这一点的关键就在于统一的模块序列化机制。本文将介绍 TVM 模块序列化的格式标准与实现细节。序列化Serialization​入口 API 为tvm.module.Module的export_library。在此函数内部我们会执行以下步骤收集所有 DSO 模块例如 LLVM 模块和 C 模块。在获得 DSO 模块后调用save函数将它们保存到文件。随后检查是否存在已导入的模块imported modules例如 CUDA、OpenCL 等。这里对模块类型不做限制。如果存在导入模块我们将创建一个名为devc.o/dev.cc的文件用于将这些导入模块的二进制数据打包进最终的动态库中然后调用_PackImportsToLLVM或_PackImportsToC来执行模块序列化。最后调用fcompile其内部会调用_cc.create_shared生成动态共享库。备注对于 C 源码模块CSourceModule我们会将它们编译并与 DSO 模块一同进行链接。是否使用_PackImportsToLLVM或_PackImportsToC取决于 TVM 是否启用了 LLVM。它们本质上实现的是相同的目标。序列化底层机制与格式标准​序列化主要发生在_PackImportsToLLVM或_PackImportsToC中。它们都会调用SerializeModule来序列化 runtime module。在SerializeModule函数中我们首先会构造一个辅助类ModuleSerializer。它会以module为输入进行初始化例如分配模块索引。随后可以调用其SerializeModule方法执行序列化。为了更好地理解让我们更深入地挖掘这个类的实现。下面的代码用于构造ModuleSerializerexplicit ModuleSerializer(runtime::Module mod) : mod_(mod) { Init(); } private: void Init() { CreateModuleIndex(); CreateImportTree(); }在CreateModuleIndex()中我们使用 DFS 遍历模块的导入关系并为每个模块分配索引。根模块固定为索引0。例如llvm_mod:imported_modules - cuda_mod因此LLVM 模块的索引将是 0CUDA 模块的索引将是 1。在构建完模块索引之后我们将尝试构建导入树CreateImportTree()该导入树会在我们重新加载导出的库时用于恢复模块之间的导入关系。在我们的设计中我们使用 CSR 格式来存储导入树每一行对应父节点索引而子数组中的索引对应其子模块索引。在代码中我们使用import_tree_row_ptr_和import_tree_child_indices_来表示它们。在完成初始化之后我们就可以使用SerializeModule函数来序列化模块。在该函数的逻辑中我们假设序列化格式如下所示binary_blob_size binary_blob_type_key binary_blob_logic binary_blob_type_key binary_blob_logic ... _import_tree _import_tree_logicbinary_blob_size是我们在本次序列化步骤中将会包含的 blob 数量。在我们的示例中会有三个 blob分别对应 LLVM 模块、CUDA 模块以及_import_tree。binary_blob_type_key是模块的 blob 类型键。 对于 LLVM / C 模块其 blob 类型键为_lib。对于 CUDA 模块其类型键为cuda可以通过module-type_key()获取。binary_blob_logic是处理该 blob 的逻辑。 对于大多数 blob例如 CUDA、OpenCL我们会调用SaveToBinary函数将 blob 序列化为二进制。然而对于 LLVM / C 模块我们只会写入_lib用于表示这是一个 DSO 模块。备注是否需要实现 SaveToBinary 虚函数取决于模块的使用方式。例如如果模块中包含我们在重新加载动态共享库时需要的信息那么我们就应该实现该函数。像 CUDA 模块在重新加载动态共享库时我们需要将其二进制数据传递给 GPU 驱动因此我们需要实现SaveToBinary来序列化其二进制数据。但对于主机侧模块如 DSO 模块在加载动态共享库时我们并不需要额外信息因此不需要实现SaveToBinary。不过如果未来我们希望记录一些关于 DSO 模块的元信息我们也可以为 DSO 模块实现SaveToBinary。最后除非我们的模块中仅有一个 DSO 模块并且它位于根位置否则我们会写入一个键_import_tree。该键用于在重新加载导出的库时恢复模块导入关系如前文所述。import_tree_logic的内容则是将import_tree_row_ptr_和import_tree_child_indices_写入到流中。在上述步骤完成后我们会将最终结果打包进一个符号runtime::symbol::tvm_ffi_library_bin该符号可在动态库中恢复。现在我们已经完成序列化部分。正如你所看到的我们理论上可以支持导入任意模块。反序列化​入口 API 是tvm.runtime.load。实际上该函数会调用_LoadFromFile。 如果进一步展开可以看到其对应的是Module::LoadFromFile。在我们的示例中文件是deploy.so。根据其函数逻辑我们会在dso_library.cc中调用module.loadfile_so关键代码如下// Load the imported modules const char* library_bin reinterpret_castconst char*( lib-GetSymbol(runtime::symbol::tvm_ffi_library_bin)); Module root_mod; if (library_bin ! nullptr) { root_mod ProcessLibraryBin(library_bin, lib); } else { // Only have one single DSO Module root_mod Module(n); } 如前所述我们会将 blob 打包进符号 runtime::symbol::tvm_ffi_library_bin· 中。 在反序列化阶段我们会检查它。如果存在 runtime::symbol::tvm_ffi_library_bin我们将调用 ProcessLibraryBin其逻辑如下 c READ(blob_size) READ(blob_type_key) for (size_t i 0; i blob_size; i) { if (blob_type_key _lib) { // construct dso module using lib } else if (blob_type_key _import_tree) { // READ(_import_tree_row_ptr) // READ(_import_tree_child_indices) } else { // call module.loadbinary_blob_type_key, such as module.loadbinary_cuda // to restore. } } // Using _import_tree_row_ptr and _import_tree_child_indices to // restore module import relationship. The first module is the // root module according to our invariance as said before. return root_module;完成上述步骤后我们会将ctx_address设置为root_module 以便能够从根模块查找符号使所有符号可见。最终我们就完成了反序列化部分。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询