文档
注册

了解开发工程

为了更好的匹配开发者的多种开发调用场景,Ascend C提供如下两种算子工程对算子实现中的算子核心实现(host侧tiling实现、device侧kernel实现等)进行组织,开发者基于算子工程进行算子的开发和调用。

  • Kernel直调工程:基于该工程,开发者完成算子核函数的开发和tiling实现后,即可通过AscendCL运行时接口,完成算子的调用。是简单直接的开发方式,tiling开发不受CANN框架的限制。
  • 自定义算子工程:按照工程创建->算子实现->编译部署>算子调用的流程完成算子开发和调用。基于工程代码框架完成算子核函数的开发和tiling实现,通过工程编译脚本完成算子的编译部署。tiling开发基于CANN提供的编程框架进行,后续更易于借助框架功能实现单算子API调用、图模式算子调用等。

基于kernel直调工程的算子开发流程图如下:

基于自定义算子工程的算子开发流程图如下:

下面具体介绍两种开发工程的对比:主要的差异体现在算子的调用方式、开发过程和发布方式,其中自定义算子工程可以支持单算子API调用、图模式调用,而kernel直调工程只支持kernel直调接口调用。

差异点

自定义算子工程

Kernel直调工程

调用方式

单算子API执行(aclnn)调用

支持

不支持

图模式调用

支持

不支持

kernel直调接口调用

不支持

支持

开发过程

算子原型定义

需要

不需要

tiling实现

需要

可选

tiling开发不受CANN框架的限制。

shape、data type推导等入图所需函数实现

可选,入图需要

不需要

kernel侧算子实现

需要

需要

发布形式

.run包

.a/.so/bin

调用方式对比

  • 基于自定义算子工程开发的算子,支持多种调用方式,这里以单算子API(aclnn接口)调用为例:需要创建aclTensor,并调用两段式接口完成。
        size_t workspace_size = 0;
        aclOpExecutor *handle;
        int32_t ret;
        int64_t shape_1[] = {1024, 1024};
        void *data;
        aclTensor *tensors[3];
        aclrtMalloc(&data, shape_1[0] * shape_1[1] * 2, ACL_MEM_MALLOC_HUGE_FIRST)
           tensors[0] = aclCreateTensor(shape_1, 2, ACL_FLOAT16, NULL, 0, ACL_FORMAT_ND, shape_1, 2, data);
        aclrtMalloc(&data, shape_1[0] * shape_1[1] * 2, ACL_MEM_MALLOC_HUGE_FIRST)
           tensors[1] = aclCreateTensor(shape_1, 2, ACL_FLOAT16, NULL, 0, ACL_FORMAT_ND, shape_1, 2, data);
        aclrtMalloc(&data, shape_1[0] * shape_1[1] * 2, ACL_MEM_MALLOC_HUGE_FIRST)
           tensors[2] = aclCreateTensor(shape_1, 2, ACL_FLOAT16, NULL, 0, ACL_FORMAT_ND, shape_1, 2, data);
        // 两段式接口:1、获取workspace大小
        ret = aclnnMyAddGetWorkspaceSize(tensors[0], tensors[1], tensors[2], &workspace_size, &handle);
        void *workspace = NULL;
        if (workspace_size != 0) {
            if (aclrtMalloc(&workspace, workspace_size, ACL_MEM_MALLOC_HUGE_FIRST) != ACL_SUCCESS) {
                printf("Malloc device memory failed\n");
            }
        }
        // 两段式接口:2、执行算子
        ret = aclnnMyAdd(workspace, workspace_size, handle, stream);
        if (aclrtSynchronizeStreamWithTimeout(stream, 5000) != ACL_SUCCESS) {
            printf("Synchronize stream failed\n");
        }
  • Kernel直调工程开发的算子,支持直接使用device指针进行kernel调用。
        int64_t shape_1[] = {1024, 1024};
        void *data[3];
        aclrtMalloc(&data[0], shape_1[0] * shape_1[1] * 2, ACL_MEM_MALLOC_HUGE_FIRST);
        aclrtMalloc(&data[1], shape_1[0] * shape_1[1] * 2, ACL_MEM_MALLOC_HUGE_FIRST);
        aclrtMalloc(&data[2], shape_1[0] * shape_1[1] * 2, ACL_MEM_MALLOC_HUGE_FIRST);
        // kernel调用
        ACLRT_LAUNCH_KERNEL(my_add)(blockDim, stream, data[0], data[1], data[2]);
        
        if (aclrtSynchronizeStreamWithTimeout(stream, 5000) != ACL_SUCCESS) {
            printf("Synchronize stream failed\n");
        }

开发过程对比

自定义算子工程含分离的host/kernel开发目录,以及整体编译入口脚本、代码生成、打包脚本等,kernel直调工程只有一个CMakeLists入口和kernel源码、测试代码目录。

  • 自定义算子工程
    AddCustom
    ├── build.sh         // 编译入口脚本
    ├── cmake 
    ├── CMakeLists.txt    // 算子工程的CMakeLists.txt
    ├── CMakePresets.json    // 编译配置项
    ├── op_host                      // host侧实现文件
    │   ├── add_custom_tiling.h    // 算子tiling定义文件
    │   ├── add_custom.cpp         // 算子原型注册、shape推导、信息库、tiling实现等内容文件
    │   ├── CMakeLists.txt
    ├── op_kernel                   // kernel侧实现文件
    │   ├── CMakeLists.txt   
    │   ├── add_custom.cpp        // 算子代码实现文件 
    └── scripts                     // 自定义算子工程打包相关脚本所在目录
  • Kernel直调工程
    |-- cmake                                                 // CMake编译文件
    |-- CMakeLists.txt                                        // CMake编译配置文件
    |-- my_add.cpp                                            // kernel实现
    |-- main.cpp                                              // 测试程序调用kernel直调入口

自定义算子工程需要完整开发算子的实现文件,如算子原型定义、tiling函数、shape及data type推导函数(可选,入图时需要)、kernel函数;kernel直调工程只需要开发kernel函数。

代码文件

自定义算子工程

Kernel直调工程

算子原型定义

需要

不需要

tiling实现

需要

可选

tiling开发不受CANN框架的限制。

shape、data type推导等入图所需函数实现

可选,入图需要

不需要

kernel侧算子实现

需要

需要

发布形式

自定义算子工程当前以run包形式发布,内部包含了tiling函数库、入图接口库、aclnn库、device object等;kernel直调工程则最终只发布成静态库、动态库、可执行程序形式。

搜索结果
找到“0”个结果

当前产品无相关内容

未找到相关内容,请尝试其他搜索词