跳转至

MindStudio Sanitizer 对外接口使用说明


接口列表

接口简介

msSanitizer工具包含sanitizer接口和mstx扩展接口两种类型。sanitizer接口用于CANN软件栈的检测,与ACL系列接口一一对应。此类接口会在ACL对应接口的功能基础上,额外向工具上报接口调用位置的代码文件和行号信息,使用时需导入sanitizer API头文件和链接动态库,具体请参见《MindStudio Sanitizer典型案例》中的“检测CANN软件栈的内存>导入API头文件和链接动态库”。mstx扩展接口用于用户自定义上报内存池信息,以实现更准确的检测,具体请参见mstx扩展功能

表 1 msSanitizer工具接口列表

接口名称 功能简介
sanitizer接口 在ACL对应接口的功能基础上,向msSanitizer工具上报sanitizer接口调用位置的代码文件和行号信息。
sanitizerRtMalloc 调用aclrtMalloc接口在Device上分配size大小的线性内存,并通过*devPtr返回已分配内存的指针,并向检测工具上报内存分配信息。实际的内存分配行为和参数含义与aclrtMalloc一致。
sanitizerRtMallocCached 调用aclrtMallocCached接口在Device上申请size大小的线性内存,通过*devPtr返回已分配内存的指针,并向检测工具上报内存分配信息。该接口在任何场景下,申请的内存都支持cache缓存。实际的内存分配行为和参数含义与aclrtMallocCached一致。
sanitizerRtFree 调用aclrtFree接口释放Device上的内存,并向检测工具上报内存释放信息。实际的内存释放行为和参数含义与aclrtFree一致。
sanitizerRtMemset 调用aclrtMemset接口初始化内存,将内存中的内容设置为指定值,并向检测工具上报内存初始化信息。实际的内存初始化行为和参数含义与aclrtMemset一致。
sanitizerRtMemsetAsync 调用aclrtMemsetAsync接口初始化内存,将内存中的内容设置为指定的值,并向检测工具上报内存初始化信息。此接口为异步接口。实际的内存初始化行为和参数含义与aclrtMemsetAsync一致。
sanitizerRtMemcpy 调用aclrtMemcpy接口完成内存复制,并向检测工具上报内存复制信息。实际的内存复制行为和参数含义与aclrtMemcpy一致。
sanitizerRtMemcpyAsync 调用aclrtMemcpyAsync接口完成内存复制,并向检测工具上报内存复制信息。此接口为异步接口。实际的内存复制行为和参数含义与aclrtMemcpyAsync一致。
sanitizerRtMemcpy2d 调用aclrtMemcpy2d接口完成矩阵数据内存复制,并向检测工具上报内存复制信息。实际的矩阵数据内存复制行为和参数含义与aclrtMemcpy2d一致。
sanitizerRtMemcpy2dAsync 调用aclrtMemcpy2dAsync接口完成矩阵数据内存复制,并向检测工具上报内存复制信息。此接口为异步接口。实际的矩阵数据内存复制行为和参数含义与aclrtMemcpy2dAsync一致。
sanitizerReportMalloc 手动上报GM内存分配信息。
sanitizerReportFree 手动上报GM内存释放信息。
mstx扩展功能 mstx接口是MindStudio提供的一套扩展接口,它允许用户在应用程序中插入特定的标记,以便在工具进行内存检测时能够更精确地定位特定算子的内存问题。
mstxDomainCreateA 创建域。
mstxMemHeapRegister 内存池注册接口。
mstxMemHeapUnregister 内存池注销接口。
mstxMemRegionsRegister 内存池二次分配注册接口。
mstxMemRegionsUnregister 内存池二次分配注销接口。
mstxMemPermissionsAssign 内存权限上报接口。

sanitizer接口


sanitizerRtMalloc


功能说明

调用aclrtMalloc接口在Device上分配size大小的线性内存,并通过*devPtr返回已分配内存的指针,并向检测工具上报内存分配信息。实际的内存分配行为和参数含义与aclrtMalloc一致。

[!NOTE] 可参见《应用开发接口》手册中“acl API参考(C) > 运行时管理 > 内存管理”章节查看aclrtMalloc的详细说明。

函数原型

aclError sanitizerRtMalloc(void **devPtr, size_t size, aclrtMemMallocPolicy policy, char const *filename, int lineno);

参数说明

表 2 参数说明

参数名 输入/输出 描述
devPtr 输出 指向“Device上已分配内存的指针”的指针。
size 输入 申请内存的大小,单位为Byte,size不能为0。
policy 输入 内存分配规则,类型定义请参见aclrtMemMallocPolicy
filename 输入 内存分配被调用处的文件名。
lineno 输入 内存分配被调用处的行号。

返回值

返回0表示成功,返回其它值表示失败,请参见aclError

调用示例

具体操作请参见使用示例的《MindStudio Sanitizer典型案例》中的“检测CANN软件栈的内存>排查步骤里的步骤4”。



sanitizerRtMallocCached


功能说明

调用aclrtMallocCached接口在Device上申请size大小的线性内存,通过*devPtr返回已分配内存的指针,并向检测工具上报内存分配信息。该接口在任何场景下,申请的内存都支持cache缓存。实际的内存分配行为和参数含义与aclrtMallocCached一致。

[!NOTE] 可参见《应用开发接口》手册中“acl API参考(C) > 运行时管理 > 内存管理”章节查看aclrtMallocCached的详细说明。

函数原型

aclError sanitizerRtMallocCached(void **devPtr, size_t size, aclrtMemMallocPolicy policy, char const *filename, int lineno);

参数说明

表 3 参数说明

参数名 输入/输出 描述
devPtr 输出 指向“Device上已分配内存的指针”的指针。
size 输入 申请内存的大小,单位为Byte。size不能为0。
policy 输入 内存分配规则,类型定义请参见aclrtMemMallocPolicy
filename 输入 内存分配被调用处的文件名。
lineno 输入 内存分配被调用处的行号。

返回值

返回0表示成功,返回其它值表示失败,请参见aclError

调用示例

具体操作请参见使用示例的《MindStudio Sanitizer典型案例》中的“检测CANN软件栈的内存>排查步骤里的步骤4”。



sanitizerRtFree


功能说明

调用aclrtFree接口释放Device上的内存,并向检测工具上报内存释放信息。实际的内存释放行为和参数含义与aclrtFree一致。

[!NOTE] 可参见《应用开发接口》手册中“acl API参考(C) > 运行时管理 > 内存管理”章节查看aclrtFree的详细说明。

函数原型

aclError sanitizerRtFree(void *devPtr, char const *filename, int lineno);

参数说明

表 4 参数说明

参数名 输入/输出 描述
devPtr 输入 待释放内存的指针。
filename 输入 内存释放被调用处的文件名。
lineno 输入 内存释放被调用处的行号。

返回值

返回0表示成功,返回其它值表示失败,请参见aclError

调用示例

具体操作请参见使用示例的《MindStudio Sanitizer典型案例》中的“检测CANN软件栈的内存>排查步骤里的步骤4”。



sanitizerRtMemset


功能说明

调用aclrtMemset接口初始化内存,将内存中的内容设置为指定值,并向检测工具上报内存初始化信息。实际的内存初始化行为和参数含义与aclrtMemset一致。

[!NOTE] 可参见《应用开发接口》手册中“acl API参考(C) > 运行时管理 > 内存管理”章节查看aclrtMemset的详细说明。

函数原型

aclError sanitizerRtMemset(void *devPtr, size_t maxCount, int32_t value, size_t count, char const *filename, int lineno);

参数说明

表 5 参数说明

参数名 输入/输出 描述
devPtr 输入 内存起始地址的指针。
maxCount 输入 内存的最大长度,单位为Byte。
value 输入 初始化内存的指定值。
count 输入 需要设置为指定值的内存长度,单位为Byte。
filename 输入 内存初始化被调用处的文件名。
lineno 输入 内存初始化被调用处的行号。

返回值

返回0表示成功,返回其它值表示失败,请参见aclError

调用示例

具体操作请参见使用示例的《MindStudio Sanitizer典型案例》中的“检测CANN软件栈的内存>排查步骤里的步骤4”。



sanitizerRtMemsetAsync


功能说明

调用aclrtMemsetAsync接口初始化内存,将内存中的内容设置为指定的值,并向检测工具上报内存初始化信息。此接口为异步接口。实际的内存初始化行为和参数含义与aclrtMemsetAsync一致。

[!NOTE] 可参见《应用开发接口》手册中“acl API参考(C) > 运行时管理 > 内存管理”章节查看aclrtMemsetAsync的详细说明。

函数原型

aclError sanitizerRtMemsetAsync(void *devPtr, size_t maxCount, int32_t value, size_t count, aclrtStream stream, char const *filename, int lineno);

参数说明

表 6 参数说明

参数名 输入/输出 描述
devPtr 输入 内存起始地址的指针。
maxCount 输入 内存的最大长度,单位为Byte。
value 输入 初始化内存的指定值。
count 输入 初始化内存的长度,单位为Byte。
stream 输入 指定执行内存复制任务的Stream。
filename 输入 内存初始化被调用处的文件名。
lineno 输入 内存初始化被调用处的行号。

返回值

返回0表示成功,返回其它值表示失败,请参见aclError

调用示例

具体操作请参见使用示例的《MindStudio Sanitizer典型案例》中的“检测CANN软件栈的内存>排查步骤里的步骤4”。



sanitizerRtMemcpy


功能说明

调用aclrtMemcpy接口完成内存复制,并向检测工具上报内存复制信息。实际的内存复制行为和参数含义与aclrtMemcpy一致。

[!NOTE] 可参见《应用开发接口》手册中“acl API参考(C) > 运行时管理 > 内存管理”章节查看aclrtMemcpy的详细说明。

函数原型

aclError sanitizerRtMemcpy(void *dst, size_t destMax, const void *src, size_t count, aclrtMemcpyKind kind, char const *filename, int lineno);

参数说明

表 7 参数说明

参数名 输入/输出 描述
dst 输入 目的内存地址指针。
destMax 输入 目的内存地址的最大内存长度,单位为Byte。
src 输入 源内存地址指针。
count 输入 内存复制的长度,单位为Byte。
kind 输入 内存复制的类型,预留参数,配置枚举值中的值无效,系统内部会根据源内存地址指针、目的内存地址指针判断是否可以将源地址的数据复制到目的地址,如果不可以,则系统会返回报错。
filename 输入 内存复制被调用处的文件名。
lineno 输入 内存复制被调用处的行号。

返回值

返回0表示成功,返回其它值表示失败,请参见aclError

调用示例

具体操作请参见使用示例的《MindStudio Sanitizer典型案例》中的“检测CANN软件栈的内存>排查步骤里的步骤4”。



sanitizerRtMemcpyAsync


功能说明

调用aclrtMemcpyAsync接口完成内存复制,并向检测工具上报内存复制信息。此接口为异步接口。实际的内存复制行为和参数含义与aclrtMemcpyAsync一致。

[!NOTE] 可参见《应用开发接口》手册中“acl API参考(C) > 运行时管理 > 内存管理”章节查看aclrtMemcpyAsync的详细说明。

函数原型

aclError sanitizerRtMemcpyAsync(void *dst, size_t destMax, const void *src, size_t count, aclrtMemcpyKind kind, aclrtStream stream, char const *filename, int lineno);

参数说明

表 8 参数说明

参数名 输入/输出 描述
dst 输入 目的内存地址指针。
destMax 输入 目的内存地址的最大内存长度,单位为Byte。
src 输入 源内存地址指针。
count 输入 内存复制的长度,单位为Byte。
kind 输入 内存复制的类型,预留参数,配置枚举值中的值无效,系统内部会根据源内存地址指针、目的内存地址指针判断是否可以将源地址的数据复制到目的地址,如果不可以,则系统会返回报错。
stream 输入 指定执行内存复制任务的Stream。
filename 输入 内存复制被调用处的文件名。
lineno 输入 内存复制被调用处的行号。

返回值

返回0表示成功,返回其它值表示失败,请参见aclError

调用示例

具体操作请参见使用示例的《MindStudio Sanitizer典型案例》中的“检测CANN软件栈的内存>排查步骤里的步骤4”。



sanitizerRtMemcpy2d


功能说明

调用aclrtMemcpy2d接口完成矩阵数据内存复制,并向检测工具上报内存复制信息。实际的矩阵数据内存复制行为和参数含义与aclrtMemcpy2d一致。

[!NOTE] 可参见《应用开发接口》手册中“acl API参考(C) > 运行时管理 > 内存管理”章节查看aclrtMemcpy2d的详细说明。

函数原型

aclError sanitizerRtMemcpy2d(void *dst, size_t dpitch, const void *src, size_t spitch, size_t width, size_t height, aclrtMemcpyKind kind, char const *filename, int lineno);

参数说明

表 9 参数说明

参数名 输入/输出 描述
dst 输入 目的内存地址指针。
dpitch 输入 目的内存中相邻两列向量的地址距离。
src 输入 源内存地址指针。
spitch 输入 源内存中相邻两列向量的地址距离。
width 输入 待复制的矩阵宽度。
height 输入 待复制的矩阵高度。height最大可设置为510241024=5242880,否则接口返回失败。
kind 输入 内存复制的类型,预留参数,配置枚举值中的值无效,系统内部会根据源内存地址指针、目的内存地址指针判断是否可以将源地址的数据复制到目的地址,如果不可以,则系统会返回报错。
filename 输入 矩阵数据内存复制被调用处的文件名。
lineno 输入 矩阵数据内存复制被调用处的行号。

返回值

返回0表示成功,返回其它值表示失败,请参见aclError

调用示例

具体操作请参见使用示例的《MindStudio Sanitizer典型案例》中的“检测CANN软件栈的内存>排查步骤里的步骤4”。



sanitizerRtMemcpy2dAsync


功能说明

调用aclrtMemcpy2dAsync接口完成矩阵数据内存复制,并向检测工具上报内存复制信息。此接口为异步接口。实际的矩阵数据内存复制行为和参数含义与aclrtMemcpy2dAsync一致。

[!NOTE] 可参见《应用开发接口》手册中“acl API参考(C) > 运行时管理 > 内存管理”章节查看aclrtMemcpy2dAsync的详细说明。

函数原型

aclError sanitizerRtMemcpy2dAsync(void *dst, size_t dpitch, const void *src, size_t spitch, size_t width, size_t height, aclrtMemcpyKind kind, aclrtStream stream, char const *filename, int lineno);

参数说明

表 10 参数说明

参数名 输入/输出 描述
dst 输入 目的内存地址指针。
dpitch 输入 目的内存中相邻两列向量的地址距离。
src 输入 源内存地址指针。
spitch 输入 源内存中相邻两列向量的地址距离。
width 输入 待复制的矩阵宽度。
height 输入 待复制的矩阵高度。height最大设置为510241024=5242880,否则接口返回失败。
kind 输入 内存复制的类型,预留参数,配置枚举值中的值无效,系统内部会根据源内存地址指针、目的内存地址指针判断是否可以将源地址的数据复制到目的地址,如果不可以,则系统会返回报错。
stream 输入 指定执行内存复制任务的Stream。
filename 输入 矩阵数据内存复制被调用处的文件名。
lineno 输入 矩阵数据内存复制被调用处的行号。

返回值

返回0表示成功,返回其它值表示失败,请参见aclError

调用示例

具体操作请参见使用示例的《MindStudio Sanitizer典型案例》中的“检测CANN软件栈的内存>排查步骤里的步骤4”。



sanitizerReportMalloc


功能说明

手动上报GM内存分配信息。

函数原型

void sanitizerReportMalloc(void *ptr, uint64_t size);

[!NOTE] 此接口是__sanitizer_report_malloc接口的封装,__sanitizer_report_malloc接口为弱函数,只有当用户程序被检测工具拉起时才会生效。

参数说明

表 11 参数说明

参数名 输入/输出 描述
ptr 输入 分配的内存地址。
size 输入 分配的内存长度。

返回值

调用示例


sanitizerReportFree


功能说明

手动上报GM内存释放信息。

函数原型

void sanitizerReportFree(void *ptr);

[!NOTE] 此接口是__sanitizer_report_free接口的封装,__sanitizer_report_free接口为弱函数,只有当用户程序被检测工具拉起时才会生效。

参数说明

表 12 参数说明

参数名 输入/输出 描述
ptr 输入 释放的内存地址。

返回值

调用示例

mstx扩展功能

mstx接口简介

mstx接口是MindStudio提供的一套扩展接口,它允许用户在应用程序中插入特定的标记,以便在工具进行内存检测时能够更精确地定位特定算子的内存问题。例如,针对二级指针类算子,在不使能mstx接口的情况下,得到的地址空间可能不准确。通过《MindStudio Tools Extension Library接口文档》的mstxMemRegionsRegister和mstxMemRegionsUnregister接口,可以将准确的地址空间传递给异常检测工具,实现更精准的内存检测。

[!NOTE] 《MindStudio Sanitizer工具用户指南》中的“异常检测功能介绍>功能说明>调用场景>Kernel直调算子开发”中的内核调用符场景暂不支持使用mstx接口。

mstx接口列表

msSanitizer工具调用的mstx接口列表如表1所示,具体使用情况请参考《mstx_api》。

表 13 msSanitizer工具调用的mstx接口列表

接口名称 功能简介
mstxDomainCreateA 创建一个新的mstx域。
mstxMemHeapRegister 注册内存池。用户在调用该接口注册内存池时,需确保该内存已提前申请。
mstxMemRegionsRegister 注册内存池二次分配。用户需保证RegionsRegister的内存位于mstxMemHeapRegister注册的范围内,否则工具会提示越界读写。
mstxMemRegionsUnregister 注销内存池二次分配。
mstxMemHeapUnregister 注销内存池时,与之关联的Regions将一并被注销。
mstxMemPermissionsAssign 通过该接口上报内存读写属性,使用mssanitizer拉起算子程序时,如果算子内进行了与内存属性不符的读写操作,可以检测出非法访问的错误。

mstx接口的使用

  • msSanitizer工具默认使能mstx接口,允许用户使用mstx接口自定义算子使用的内存空间地址和大小,可识别并快速界定算子的内存问题。
  • mstx当前提供了两种API的使用方式:库文件和头文件,以AclNNInvocation中代码为例:

    [!NOTE] 此样例工程不支持Atlas A3 训练系列产品/Atlas A3 推理系列产品。

  • ${git_clone_path}/samples/operator/ascendc/0_introduction/1_add_frameworklaunch/AclNNInvocation/src/CMakeLists.txt路径下新增库文件libms_tools_ext.so,地址为:${INSTALL_DIR}/lib64/libms_tools_ext.so

        # Header path
        include_directories(
             ...
            ${CUST_PKG_PATH}/include
        )
        ...
        target_link_libraries(
            ...
            dl
        )
    
  • ${git_clone_path}/samples/operator/ascendc/0_introduction/1_add_frameworklaunch/AclNNInvocation/src/main.cpp路径下,将用户程序编译链接dl库,对应的头文件ms_tools_ext.h地址:${INSTALL_DIR}/include/mstx

    ...
    #include "mstx/ms_tools_ext.h"
    ...
    

    [!NOTE] ${INSTALL_DIR}请替换为CANN软件安装后文件存储路径。以root用户安装为例,安装后文件默认存储路径为:/usr/local/Ascend/cann。

内存池注册调用示例

    mstxMemVirtualRangeDesc_t rangeDesc = {};
    rangeDesc.deviceId = deviceId;       // 设备编号
    rangeDesc.ptr = gm;                  // 注册的内存池CM首地址
    rangeDesc.size = 1024;               // 内存池大小
    mstxMemHeapDesc_t heapDesc{};
    heapDesc.typeSpecificDesc = &rangeDesc;
    mstxMemHeapHandle_t memPool = mstxMemHeapRegister(globalDomain, &heapDesc); // 注册内存池
    mstxMemVirtualRangeDesc_t rangesDesc[1] = {};                // 二次分配包含的region数量
    mstxMemRegionHandle_t regionHandles[1] = {};
    rangesDesc[0].deviceId = deviceId;                           // 设备编号
    rangesDesc[0].ptr = gm;                                      // 二次分配GM地址
    rangesDesc[0].size = 256;                                    // 二次分配大小
    mstxMemRegionsRegisterBatch_t regionsDesc{};
    regionsDesc.heap = memPool;
    regionsDesc.regionType = MSTX_MEM_TYPE_VIRTUAL_ADDRESS;
    regionsDesc.regionCount = 1;
    regionsDesc.regionDescArray = rangesDesc;
    regionsDesc.regionHandleArrayOut = regionHandles;
    mstxMemRegionsRegister(globalDomain, regionsDesc);              // 二次分配注册
    Do(blockDim, nullptr, stream, gm);                            // 算子Kernel函数
    mstxMemRegionRef_t regionRef[1] = {};
    regionRef[0].refType = MSTX_MEM_REGION_REF_TYPE_HANDLE;
    regionRef[0].handle = regionHandles[0];
    mstxMemRegionsUnregisterBatch_t refsDesc = {};
    refsDesc.refCount = 1;
    refsDesc.refArray = regionRef;
    mstxMemRegionsUnregister(globalDomain, &refsDesc);                   // 注销二次分配
    mstxMemHeapUnregister(globalDomain, memPool);                        // 注销内存池

内存权限设置调用示例

mstxMemRegionsRegisterBatch_t regions{};
mstxMemVirtualRangeDesc_t ranges[2]; // 准备数组用于保存 2 个虚拟内存区间信息
mstxMemRegionHandle_t handles[2]; // 准备数组用于接收返回的内存区间句柄
ranges[0].ptr = gm1; // 内存地址
ranges[0].size = 100; // 内存长度
ranges[1].ptr = gm2;
ranges[1].size = 200;
regions.regionType = MSTX_MEM_TYPE_VIRTUAL_ADDRESS;
regions.regionCount = 2;
regions.regionDescArray = ranges;
regions.regionHandleArrayOut = handles;
mstxMemRegionsRegister(globalDomain, &regions); // 注册内存区间信息

mstxMemPermissionsAssignBatch_t assignBatch{};
mstxMemPermissionsAssignRegionsDesc_t assignRegion[2]; // 准备数组用于保存 2 个内存区间的权限属性
assignRegion[0].flags = MSTX_MEM_PERMISSIONS_REGION_FLAGS_READ; // 第一个内存区间设置为只读
assignRegion[0].region.refType = MSTX_MEM_REGION_REF_TYPE_HANDLE;
assignRegion[0].region.handle = handles[0]; // 通过句柄指定设置第一个内存区间的属性
assignRegion[1].flags = MSTX_MEM_PERMISSIONS_REGION_FLAGS_WRITE; // 第二个内存区间设置为只写
assignRegion[1].region.refType = MSTX_MEM_REGION_REF_TYPE_HANDLE;
assignRegion[1].region.handle = handles[1]; // 通过句柄指定设置第二个内存区间的属性
assignBatch.regionCount = 2;
assignBatch.regionDescArray = assignRegion;
mstxMemPermissionsAssign(globalDomain, &assignBatch); // 设置内存区间属性