下载
中文
注册

使用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性能指标。

支持的型号

Atlas 200I/500 A2 推理产品

Atlas A2 训练系列产品/Atlas 800I A2 推理产品

前提条件

  • 请确保完成使用前准备
  • 设置如下环境变量:
    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参考

表1 Activity 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不会被遗漏。

表2 Callback API

接口

说明

Function类型

msptiSubscribe

通过该接口向MSPTI注册回调函数。

msptiUnsubscribe

向MSPTI注销当前订阅者。

msptiEnableCallback

为特定domainCallbackId的订阅者开启或关闭回调。

msptiEnableDomain

为特定domain的订阅者开启或关闭所有回调。

Typedef类型

msptiCallbackFunc

回调函数类型。

msptiCallbackId

注册的Callback调用点ID

msptiSubscriberHandle

订阅者的句柄。

Enumeration类型

msptiCallbackDomain

相关API函数或CANN驱动程序活动的回调点。

msptiApiCallbackSite

指定API调用中发出回调的点,如回调的开始和回调的结束

msptiCallbackIdRuntime

Runtime API函数的索引定义。

msptiCallbackIdHccl

HCCL API函数的索引的简要定义。

Data Structure类型

msptiCallbackData

用于指定传递到回调函数的数据。

表3 Result Codes

接口

说明

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;
}
Callback 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
#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;
}