issue/1311 - feat: refactor InfiniCore cpu runtime to InfiniRT#1342
issue/1311 - feat: refactor InfiniCore cpu runtime to InfiniRT#1342spike-zhu wants to merge 1 commit into
Conversation
22ae5cc to
2a5e0e1
Compare
There was a problem hiding this comment.
这个文件的修改是因为 InfiniRT 里面还差图的部分没有对吧,所以搞了个这个 workaround。我的问题是,如果不修改这个文件,还能编译通过并且跑通不开图的推理嘛?如果不能的话就暂时保留,如果不修改这个文件能跑通不开图的推理,那其实也可以不修改这个文件。
There was a problem hiding this comment.
这个文件的修改是因为 InfiniRT 里面还差图的部分没有对吧,所以搞了个这个 workaround。我的问题是,如果不修改这个文件,还能编译通过并且跑通不开图的推理嘛?如果不能的话就暂时保留,如果不修改这个文件能跑通不开图的推理,那其实也可以不修改这个文件。
当前 InfiniRT public runtime 还没有 graph 相关接口。如果不加 USE_INFINIRT_GRAPH 保护,即使 --graph=n,graph.cc 里旧的 infinirtGraph* 符号也可能被编译进 libinfinicore_cpp_api.so,当前链接 standalone InfiniRT 时会导致 import 阶段 undefined symbol,进而影响不开图的推理。这里主要是为了避免不开图路径被旧 graph 符号影响。
| std::vector<int> device_counter(static_cast<size_t>(Device::Type::COUNT), 0); | ||
| infini::rt::set_runtime_device_type(infini::rt::Device::Type::kCpu); | ||
| INFINICORE_CHECK_ERROR(infini_rt::rtErrorToInfiniCoreStatus(infini::rt::runtime::GetDeviceCount(&device_counter[0]))); | ||
|
|
||
| // Reserve runtime slot for all devices. | ||
| // Current InfiniRT public runtime integration only enables CPU here. | ||
| runtime_table_[0].resize(device_counter[0]); | ||
| runtime_table_[0][0] = std::unique_ptr<Runtime>(new Runtime(Device(Device::Type::CPU, 0))); | ||
|
|
||
| // Context will try to use the first non-cpu available device as the default runtime. | ||
| for (int i = int(Device::Type::COUNT) - 1; i > 0; i--) { | ||
| if (device_counter[i] > 0) { | ||
| runtime_table_[i].resize(device_counter[i]); | ||
| if (current_runtime_ == nullptr) { | ||
| runtime_table_[i][0] = std::unique_ptr<Runtime>(new Runtime(Device(Device::Type(i), 0))); | ||
| current_runtime_ = runtime_table_[i][0].get(); | ||
| } | ||
| } | ||
| } | ||
|
|
||
| if (current_runtime_ == nullptr) { | ||
| if (device_counter[0] > 0) { | ||
| runtime_table_[0][0] = std::unique_ptr<Runtime>(new Runtime(Device(Device::Type::CPU, 0))); |
There was a problem hiding this comment.
这部分修改可能牵扯其余平台,建议至少加上英伟达尝试一下。
There was a problem hiding this comment.
我看了一下,这个文件主要就是为了搭桥,但是后面两个函数一个在这个 PR 里出现了 2 次,一个只出现了 1 次,那我觉得就没有必要单独抽出 helper,直接在原来的地方换成对应的 InfiniRT 调用即可。所以这个文件作为一个过渡文件,其实只需要提供转换函数就行,可以用以下的形式,也许更优雅一些:
namespace infinicore::bridge::infini::rt {
inline infiniStatus_t translate(::infini::rt::runtime::Error error) {
switch (error) {
case ::infini::rt::runtime::kSuccess:
return INFINI_STATUS_SUCCESS;
default:
return INFINI_STATUS_INTERNAL_ERROR;
}
}
inline ::infini::rt::Device::Type translate(infiniDevice_t device) {
switch (device) {
case INFINI_DEVICE_CPU:
return ::infini::rt::Device::Type::kCpu;
default:
return ::infini::rt::Device::Type::kUnknown;
}
}
inline infiniDevice_t translate(::infini::rt::Device::Type device) {
switch (device) {
case ::infini::rt::Device::Type::kCpu:
return INFINI_DEVICE_CPU;
default:
return INFINI_DEVICE_TYPE_COUNT;
}
}
} // namespace infinicore::bridge::infini::rt调用时大概是这样:
infini::rt::set_runtime_device_type(bridge::infini::rt::translate(device));
INFINICORE_CHECK_ERROR(bridge::infini::rt::translate(infini::rt::runtime::SetDevice(device_id)));
当然上面这些只是例子,而且 switch 里面的 case 肯定也不全,但是大概思想是这样。文件名和路径也可以按照这个思路修改一下。按理来说,其实最终形态应该是这些 enum 也全部替换成新的,不过我能理解咱们不可能一步到位,目前这样只添加 translate 就已经很好了。
| if (device_.getType() != Device::Type::CPU) { | ||
| INFINICORE_CHECK_ERROR(bridge::infini::rt::translate(infini::rt::runtime::MallocAsync(&ptr, size, context::getStream()))); | ||
| } else { | ||
| INFINICORE_CHECK_ERROR(bridge::infini::rt::translate(infini::rt::runtime::Malloc(&ptr, size))); | ||
| } |
There was a problem hiding this comment.
这块后面可以讨论一下,看看要不要把 CPU 的 Async 改成 noop,这样就不用 if-else 了。
There was a problem hiding this comment.
嘉成,这个是指把原来 cpu runtime 中的:
static Error MallocAsync(void** ptr, std::size_t size, Stream) {
return kErrorInvalidValue;
}
修改为
static Error MallocAsync(void **ptr, std::size_t size, Stream) {
return Malloc(ptr, size);
}
来规避 if-else 吗?
| if (device_.getType() != Device::Type::CPU) { | ||
| INFINICORE_CHECK_ERROR(bridge::infini::rt::translate(infini::rt::runtime::FreeAsync(ptr, context::getStream()))); | ||
| } else { | ||
| INFINICORE_CHECK_ERROR(bridge::infini::rt::translate(infini::rt::runtime::Free(ptr))); | ||
| } |
There was a problem hiding this comment.
这个文件的修改是必要的嘛?我看里面还去掉了好几个平台的 import,这块是不是有点不对劲。
|
哦对,还有就是 CI,因为咱们相当于是引入了新的 InfiniRT 作为依赖,所以如果想让 CI 通过的话应该也需要做些 workflow 的修改。 |
将 InfiniCore 中 CPU runtime 的实现调整为复用 InfiniRT 已有的 CPU runtime 接口,对应 InfiniRT 中更改见 InfiniTensor/InfiniRT#8
单算子测试截图:

