使用MSPTI采集
MSPTI(MindStudio Profiling Tool Interface,MindStudio Profiling工具接口)是MindStudio针对Ascend设备提出的一套Profiling API,用户可以通过MSPTI构建针对NPU应用程序的工具,用于分析应用程序的性能。
MSPTI为通用场景接口,使用MSPTI API开发的Profiling分析工具可以在各种框架的推理训练场景生效。
- Tracing:在MSPTI中Tracing是指CANN应用程序执行启动CANN活动的时间戳和附加信息的收集,如CANN API、Kernel、内存拷贝等。通过了解程序运行耗时,识别CANN代码的性能问题。可以使用Activity API和Callback API收集Tracing信息。
- Profiling:在MSPTI中Profiling是指单独收集一个或一组Kernel的NPU性能指标。
支持的型号
前提条件
- 请确保完成使用前准备。
- 设置如下环境变量:
export LD_PRELOAD=CANN软件安装目录/ascend-toolkit/latest/lib64/libmspti.so
MSPTI工具API介绍
当前提供如下类型的API:
- Activity API:异步记录CANN活动,例如:CANN API、Kernel、内存拷贝等。
- Callback API:CANN事件回调机制,用于实时通知用户(订阅者)特定的CANN事件已执行,例如:CANN的runtime内存拷贝。
具体接口如下:
详细接口介绍请参见MSPTI API参考。
接口 |
说明 |
---|---|
Function类型 |
|
msptiActivityRegisterCallbacks |
向MSPTI注册回调函数,用于Activity Buffer处理。 |
msptiActivityEnable |
用于使能指定Activity类型数据的采集。 |
msptiActivityDisable |
停止收集特定类型的Activity Record。 |
msptiActivityGetNextRecord |
依次从Activity Buffer获取Activity Record数据。 |
msptiActivityFlushAll |
订阅者手动Flush Activity Buffer中记录的数据。 |
Typedef类型 |
|
msptiBuffersCallbackRequestFunc |
向MSPTI注册回调函数,申请Activity Buffer的存储空间。 |
msptiBuffersCallbackCompleteFunc |
向MSPTI注册回调函数,释放Activity Buffer中的数据。 |
Enumeration类型 |
|
msptiActivityKind |
MSPTI支持的所有Activity类型。 |
msptiActivityFlag |
Activity Record的活动标记。 |
msptiActivitySourceKind |
标记Activity数据来源。 |
Data Structure类型 |
|
msptiActivity |
Activity Record的基础结构体。 |
msptiActivityApi |
Activity Record类型MSPTI_ACTIVITY_KIND_API对应的结构体。 |
msptiActivityMarker |
Activity Record类型MSPTI_ACTIVITY_KIND_MARKER对应的结构体。 |
msptiActivityKernel |
Activity Record类型MSPTI_ACTIVITY_KIND_KERNEL对应的结构体。 |
Activity Record:NPU的Profiling记录,使用结构体表示,如msptiActivityApi、msptiActivityMarker等。
Activity Buffer:用于缓存Activity Record数据,并将一个或多个Activity Record从MSPTI传输到客户端。用户根据业务需要提供空的Activity Buffer缓冲区,以确保Activity Record不会被遗漏。
接口 |
说明 |
---|---|
Function类型 |
|
msptiSubscribe |
通过该接口向MSPTI注册回调函数。 |
msptiUnsubscribe |
向MSPTI注销当前订阅者。 |
msptiEnableCallback |
为特定domain和CallbackId的订阅者开启或关闭回调。 |
msptiEnableDomain |
为特定domain的订阅者开启或关闭所有回调。 |
Typedef类型 |
|
msptiCallbackFunc |
回调函数类型。 |
msptiCallbackId |
注册的Callback调用点ID。 |
msptiSubscriberHandle |
订阅者的句柄。 |
Enumeration类型 |
|
msptiCallbackDomain |
相关API函数或CANN驱动程序活动的回调点。 |
msptiApiCallbackSite |
指定API调用中发出回调的点,如回调的开始和回调的结束。 |
msptiCallbackIdRuntime |
Runtime API函数的索引定义。 |
msptiCallbackIdHccl |
HCCL API函数的索引的简要定义。 |
Data Structure类型 |
|
msptiCallbackData |
用于指定传递到回调函数的数据。 |
接口 |
说明 |
---|---|
Enumeration类型 |
|
msptiResult |
MSPTI返回的错误和结果代码。 |
使用示例
Activity API
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | #include "mspti.h" void UserBufferRequest(uint8_t **buffer, size_t *size, size_t *maxNumRecords) { constexpr uint32_t SIZE = 5 * 1024 * 1024; uint8_t *pBuffer = (uint8_t *) malloc(SIZE + ALIGN_SIZE); *buffer = ALIGN_BUFFER(pBuffer, ALIGN_SIZE); *size = 5 * 1024 * 1024; *maxNumRecords = 0; } void UserBufferComplete(uint8_t *buffer, size_t size, size_t validSize) { if (validSize > 0) { msptiActivity *pRecord = NULL; msptiResult status = MSPTI_SUCCESS; do { status = msptiActivityGetNextRecord(buffer, validSize, &pRecord); if (status == MSPTI_SUCCESS) { if (pRecord->kind == MSPTI_ACTIVITY_KIND_MARKER) { ... 消费数据逻辑 } } else if (status == MSPTI_ERROR_MAX_LIMIT_REACHED) { break; } } while (1); } free(buffer); } int main() { // 根据自己的实际device填写deviceId int32_t deviceId = 1; aclrtContext context; aclrtStream stream; msptiSubscriberHandle subscriber; msptiSubscribe(&subscriber, nullptr, nullptr); // 注册Request和Complete函数 msptiActivityRegisterCallbacks(UserBufferRequest, UserBufferComplete); // 开启MARKER类型数据采集 msptiActivityEnable(MSPTI_ACTIVITY_KIND_MARKER); auto ret = Init(deviceId, &context, &stream); // acl初始化 for (size_t i = 0; i < 3; ++i) { mstxMarkA("AAA", stream); } aclFinalize(); msptiActivityDisable(MSPTI_ACTIVITY_KIND_MARKER); // 刷新落盘 msptiActivityFlushAll(1); msptiUnsubscribe(subscriber); return 0; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | #include <iostream> #include <vector> #include "acl/acl.h" #include "aclnnop/aclnn_add.h" #include "mspti.h" int Init(int32_t deviceId, aclrtContext* context, aclrtStream* stream) { // acl初始化 auto ret = aclrtSetDevice(deviceId); ret = aclrtCreateContext(context, deviceId); ret = aclrtSetCurrentContext(*context); ret = aclrtCreateStream(stream); ret = aclInit(nullptr); return 0; } // 用户回调函数 void UserCallback(void *pUserData, msptiCallbackDomain domain, msptiCallbackId callbackId, const msptiCallbackData *pCallbackInfo) { if (pCallbackInfo->callbackSite == MSPTI_API_ENTER) { LOG_PRINT("Enter: %s\n", pCallbackInfo->functionName); } else if (pCallbackInfo->callbackSite == MSPTI_API_EXIT) { LOG_PRINT("Exit: %s\n", pCallbackInfo->functionName); } } int main() { // (固定写法)device/context/stream初始化 int32_t deviceId = 0; aclrtContext context; aclrtStream stream; // 订阅MSPTI msptiSubscriberHandle subscriber; msptiSubscribe(&subscriber, UserCallback, nullptr); // 开启MSPTI_CBID_RUNTIME_CONTEXT_CREATED_EX回调 msptiEnableCallback(1, subscriber, MSPTI_CB_DOMAIN_RUNTIME, MSPTI_CBID_RUNTIME_CONTEXT_CREATED_EX); ... msptiEnableCallback(0, subscriber, MSPTI_CB_DOMAIN_RUNTIME, MSPTI_CBID_RUNTIME_CONTEXT_CREATED_EX); auto ret = Init(deviceId, &context, &stream); // 取消订阅 msptiUnsubscribe(subscriber); return 0; } |