-
Notifications
You must be signed in to change notification settings - Fork 1
feat: add graph runtime api #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
0f53e62
82a450d
77688e2
63413be
3daf6cb
6668bcb
a0e5246
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,12 @@ | ||
| #ifndef INFINI_RT_ASCEND_RUNTIME__H_ | ||
| #define INFINI_RT_ASCEND_RUNTIME__H_ | ||
|
|
||
| #include <dlfcn.h> | ||
|
|
||
| #include <cassert> | ||
| #include <cstddef> | ||
| #include <cstdint> | ||
| #include <type_traits> | ||
|
|
||
| // clang-format off | ||
| #include "acl/acl.h" | ||
|
|
@@ -21,8 +24,14 @@ struct Runtime<Device::Type::kAscend> | |
|
|
||
| using Stream = aclrtStream; | ||
|
|
||
| using Graph = void*; | ||
|
|
||
| using GraphExec = void*; | ||
|
|
||
| using Event = void*; | ||
|
|
||
| using StreamCaptureMode = int; | ||
|
|
||
| static constexpr Device::Type kDeviceType = Device::Type::kAscend; | ||
|
|
||
| static constexpr Error kSuccess = ACL_SUCCESS; | ||
|
|
@@ -41,7 +50,7 @@ struct Runtime<Device::Type::kAscend> | |
|
|
||
| static constexpr auto DeviceSynchronize = aclrtSynchronizeDevice; | ||
|
|
||
| static constexpr auto Malloc = [](void** ptr, size_t size) { | ||
| static constexpr auto Malloc = [](void** ptr, std::size_t size) { | ||
| return aclrtMalloc(ptr, size, ACL_MEM_MALLOC_HUGE_FIRST); | ||
| }; | ||
|
|
||
|
|
@@ -59,14 +68,14 @@ struct Runtime<Device::Type::kAscend> | |
|
|
||
| static Error MemGetInfo(std::size_t*, std::size_t*) { return Unsupported(); } | ||
|
|
||
| static constexpr auto Memcpy = [](void* dst, const void* src, size_t count, | ||
| aclrtMemcpyKind kind) { | ||
| static constexpr auto Memcpy = [](void* dst, const void* src, | ||
| std::size_t count, aclrtMemcpyKind kind) { | ||
| return aclrtMemcpy(dst, count, src, count, kind); | ||
| }; | ||
|
|
||
| static constexpr auto MemcpyAsync = [](void* dst, const void* src, | ||
| size_t count, aclrtMemcpyKind kind, | ||
| Stream stream) { | ||
| std::size_t count, | ||
| aclrtMemcpyKind kind, Stream stream) { | ||
| return aclrtMemcpyAsync(dst, count, src, count, kind, stream); | ||
| }; | ||
|
|
||
|
|
@@ -78,7 +87,7 @@ struct Runtime<Device::Type::kAscend> | |
|
|
||
| static constexpr auto kMemcpyDeviceToDevice = ACL_MEMCPY_DEVICE_TO_DEVICE; | ||
|
|
||
| static constexpr auto Memset = [](void* ptr, int value, size_t count) { | ||
| static constexpr auto Memset = [](void* ptr, int value, std::size_t count) { | ||
| return aclrtMemset(ptr, count, value, count); | ||
| }; | ||
|
|
||
|
|
@@ -112,6 +121,151 @@ struct Runtime<Device::Type::kAscend> | |
|
|
||
| static Error EventElapsedTime(float*, Event, Event) { return Unsupported(); } | ||
|
|
||
| static constexpr StreamCaptureMode kStreamCaptureModeGlobal = 0; | ||
|
|
||
| static constexpr StreamCaptureMode kStreamCaptureModeThreadLocal = 1; | ||
|
|
||
| static constexpr StreamCaptureMode kStreamCaptureModeRelaxed = 2; | ||
|
|
||
| struct RIApi { | ||
| using CaptureBeginFn = aclError (*)(aclrtStream, int); | ||
| using CaptureGetInfoFn = aclError (*)(aclrtStream, int*, void**); | ||
| using CaptureEndFn = aclError (*)(aclrtStream, void**); | ||
| using RIExecuteAsyncFn = aclError (*)(void*, aclrtStream); | ||
| using RIDestroyFn = aclError (*)(void*); | ||
|
|
||
| CaptureBeginFn capture_begin = nullptr; | ||
| CaptureGetInfoFn capture_get_info = nullptr; | ||
| CaptureEndFn capture_end = nullptr; | ||
| RIExecuteAsyncFn execute_async = nullptr; | ||
| RIDestroyFn destroy = nullptr; | ||
|
|
||
| bool available() const { | ||
| return capture_begin != nullptr && capture_get_info != nullptr && | ||
| capture_end != nullptr && execute_async != nullptr; | ||
| } | ||
| }; | ||
|
|
||
| static const RIApi& GraphApi() { | ||
| static const RIApi api = [] { | ||
| RIApi loaded{}; | ||
| auto load_symbols = [](void* lib, RIApi* api) { | ||
| api->capture_begin = reinterpret_cast<RIApi::CaptureBeginFn>( | ||
| dlsym(lib, "aclmdlRICaptureBegin")); | ||
| api->capture_get_info = reinterpret_cast<RIApi::CaptureGetInfoFn>( | ||
| dlsym(lib, "aclmdlRICaptureGetInfo")); | ||
| api->capture_end = reinterpret_cast<RIApi::CaptureEndFn>( | ||
| dlsym(lib, "aclmdlRICaptureEnd")); | ||
| api->execute_async = reinterpret_cast<RIApi::RIExecuteAsyncFn>( | ||
| dlsym(lib, "aclmdlRIExecuteAsync")); | ||
| api->destroy = | ||
| reinterpret_cast<RIApi::RIDestroyFn>(dlsym(lib, "aclmdlRIDestroy")); | ||
| }; | ||
|
|
||
| load_symbols(RTLD_DEFAULT, &loaded); | ||
| if (loaded.available()) { | ||
| return loaded; | ||
| } | ||
|
|
||
| void* lib = dlopen("libascendcl.so", RTLD_NOW | RTLD_NOLOAD); | ||
| if (lib == nullptr) { | ||
| lib = dlopen("libascendcl.so", RTLD_NOW); | ||
| } | ||
| if (lib == nullptr) { | ||
| return loaded; | ||
| } | ||
|
|
||
| load_symbols(lib, &loaded); | ||
| return loaded; | ||
| }(); | ||
| return api; | ||
| } | ||
|
|
||
| static aclError UnsupportedGraphApi() { return static_cast<aclError>(1); } | ||
|
Comment on lines
+130
to
+184
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这部分应该放到后面单独的一个 然后就是根据 Google C++ Style Guide,这几个函数指针的命名可以改成遵循函数命名的方式。
哦对,这个函数跟下面的一样,返回值应该是 |
||
|
|
||
| static aclError StreamBeginCapture(Stream stream, StreamCaptureMode mode) { | ||
| const auto& api = GraphApi(); | ||
| if (!api.available()) { | ||
| return UnsupportedGraphApi(); | ||
| } | ||
| return api.capture_begin(stream, mode); | ||
| } | ||
|
|
||
| static aclError StreamEndCapture(Stream stream, Graph* graph) { | ||
| assert(graph != nullptr); | ||
| const auto& api = GraphApi(); | ||
| if (!api.available()) { | ||
| return UnsupportedGraphApi(); | ||
| } | ||
| int capture_status = 0; | ||
| void* capturing_model_ri = nullptr; | ||
| const auto info_status = | ||
| api.capture_get_info(stream, &capture_status, &capturing_model_ri); | ||
| if (info_status != ACL_SUCCESS) { | ||
| return info_status; | ||
| } | ||
| void* model_ri = nullptr; | ||
| const auto status = api.capture_end(stream, &model_ri); | ||
| if (status != ACL_SUCCESS) { | ||
| return status; | ||
| } | ||
| *graph = model_ri; | ||
| return ACL_SUCCESS; | ||
| } | ||
|
|
||
| static aclError GraphDestroy(Graph graph) { | ||
| const auto& api = GraphApi(); | ||
| if (api.destroy == nullptr || graph == nullptr) { | ||
| return ACL_SUCCESS; | ||
| } | ||
| return api.destroy(graph); | ||
| } | ||
|
|
||
| static aclError GraphInstantiate(GraphExec* graph_exec, Graph graph) { | ||
| assert(graph_exec != nullptr); | ||
| *graph_exec = graph; | ||
| return ACL_SUCCESS; | ||
| } | ||
|
|
||
| static aclError GraphExecDestroy(GraphExec) { return ACL_SUCCESS; } | ||
|
|
||
| static aclError GraphLaunch(GraphExec graph_exec, Stream stream) { | ||
| const auto& api = GraphApi(); | ||
| if (!api.available()) { | ||
| return UnsupportedGraphApi(); | ||
| } | ||
| return api.execute_async(graph_exec, stream); | ||
| } | ||
|
Comment on lines
+186
to
+238
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 这些函数的返回值应该是 |
||
|
|
||
| static constexpr bool Validate() { | ||
| DeviceRuntime<Runtime<Device::Type::kAscend>>::Validate(); | ||
| static_assert(sizeof(Graph) > 0, | ||
| "`Runtime` must define a `Graph` type alias."); | ||
| static_assert(sizeof(GraphExec) > 0, | ||
| "`Runtime` must define a `GraphExec` type alias."); | ||
| static_assert(std::is_invocable_v<decltype(StreamBeginCapture), Stream, | ||
| StreamCaptureMode>, | ||
| "`Runtime::StreamBeginCapture` must be callable with " | ||
| "`(Stream, StreamCaptureMode)`."); | ||
| static_assert( | ||
| std::is_invocable_v<decltype(StreamEndCapture), Stream, Graph*>, | ||
| "`Runtime::StreamEndCapture` must be callable with " | ||
| "`(Stream, Graph*)`."); | ||
| static_assert(std::is_invocable_v<decltype(GraphDestroy), Graph>, | ||
| "`Runtime::GraphDestroy` must be callable with `(Graph)`."); | ||
| static_assert( | ||
| std::is_invocable_v<decltype(GraphInstantiate), GraphExec*, Graph>, | ||
| "`Runtime::GraphInstantiate` must be callable with " | ||
| "`(GraphExec*, Graph)`."); | ||
| static_assert( | ||
| std::is_invocable_v<decltype(GraphExecDestroy), GraphExec>, | ||
| "`Runtime::GraphExecDestroy` must be callable with `(GraphExec)`."); | ||
| static_assert( | ||
| std::is_invocable_v<decltype(GraphLaunch), GraphExec, Stream>, | ||
| "`Runtime::GraphLaunch` must be callable with `(GraphExec, Stream)`."); | ||
| return true; | ||
| } | ||
|
Comment on lines
+240
to
+267
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
|
||
| private: | ||
| static Error Unsupported() { return static_cast<Error>(1); } | ||
| }; | ||
|
|
||

There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
这个地方只是个疑问,不一定必须要修改:我看目前昇腾的接入是使用 dynamic linking 相关的东西进行的,但是这部分的跨平台性不一定很好,所以好奇为啥不能像别的平台或者别的昇腾 API 一样直接调用呢?当然国产平台都很神奇,而且目前来看,咱们也只在 Linux 上跑,所以跨操作系统也是个伪命题,因此如果确认必要的话,暂时就这样也可以。