下面是一个简单的Ascend C的"Hello World"样例,展示了一个Ascend C核函数(设备侧实现的入口函数)的基本写法,及其如何被调用的流程
- 包含核函数的Kernel实现文件hello_world.cpp代码如下:核函数hello_world的核心逻辑为打印"Hello World"字符串。hello_world_do封装了核函数的调用程序,通过<<<>>>内核调用符对核函数进行调用。
#include "kernel_operator.h"
using namespace AscendC;
extern "C" __global__ __aicore__ void hello_world() {
printf("Hello World!!!\n");
}
void hello_world_do(uint32_t blockDim, void* stream) {
hello_world<<<blockDim, nullptr, stream>>>();
}
- 调用核函数的应用程序main.cpp代码如下:
#include "acl/acl.h"
extern void hello_world_do(uint32_t coreDim, void* stream);
int32_t main(int argc, char const *argv[]) {
// AscendCL初始化
aclInit(nullptr);
// 运行管理资源申请
aclrtContext context;
int32_t deviceId = 0;
aclrtSetDevice(deviceId);
aclrtCreateContext(&context,deviceId);
aclrtStream stream = nullptr;
aclrtCreateStream(&stream);
// 设置参与运算的核数为8
constexpr uint32_t blockDim = 8;
// 用内核调用符<<<>>>调用核函数,hello_world_do中封装了<<<>>>调用
hello_world_do(blockDim, stream);
aclrtSynchronizeStream(stream);
// 资源释放和AscendCL去初始化
aclrtDestroyStream(stream);
aclrtDestroyContext(context);
aclrtResetDevice(deviceId);
aclFinalize();
return 0;
}
- 代码工程目录结构如下
|-- CMakeLists.txt // CMake编译配置文件
|-- hello_world.cpp // Kernel实现
|-- main.cpp // 调用核函数的主程序
|-- run.sh // 一键式编译运行脚本
- CMakeLists.txt内容
# CMake lowest version requirement
cmake_minimum_required(VERSION 3.16.0)
# project information
project(Ascend_C)
set(SOC_VERSION "Ascend310P3" CACHE STRING "system on chip type")
set(ASCEND_CANN_PACKAGE_PATH "/usr/local/Ascend/ascend-toolkit/latest" CACHE PATH "ASCEND CANN package installation directory")
set(RUN_MODE "npu" CACHE STRING "run mode: npu")
set(CMAKE_BUILD_TYPE "Debug" CACHE STRING "Build type Release/Debug (default Debug)" FORCE)
set(CMAKE_INSTALL_PREFIX "${CMAKE_CURRENT_LIST_DIR}/out" CACHE STRING "path for install()" FORCE)
if(EXISTS ${ASCEND_CANN_PACKAGE_PATH}/tools/tikcpp/ascendc_kernel_cmake)
set(ASCENDC_CMAKE_DIR ${ASCEND_CANN_PACKAGE_PATH}/tools/tikcpp/ascendc_kernel_cmake)
elseif(EXISTS ${ASCEND_CANN_PACKAGE_PATH}/compiler/tikcpp/ascendc_kernel_cmake)
set(ASCENDC_CMAKE_DIR ${ASCEND_CANN_PACKAGE_PATH}/compiler/tikcpp/ascendc_kernel_cmake)
elseif(EXISTS ${ASCEND_CANN_PACKAGE_PATH}/ascendc_devkit/tikcpp/samples/cmake)
set(ASCENDC_CMAKE_DIR ${ASCEND_CANN_PACKAGE_PATH}/ascendc_devkit/tikcpp/samples/cmake)
else()
message(FATAL_ERROR "ascendc_kernel_cmake does not exist, please check whether the cann package is installed.")
endif()
- run.sh内容
#!/bin/bash
CURRENT_DIR=$(
cd $(dirname ${BASH_SOURCE:-$0})
pwd
)
cd $CURRENT_DIR
SHORT=v:,
LONG=soc-version:,
OPTS=$(getopt -a --options $SHORT --longoptions $LONG -- "$@")
eval set -- "$OPTS"
while :; do
case "$1" in
-v | --soc-version)
SOC_VERSION="$2"
shift 2
;;
--)
shift
break
;;
*)
echo "[ERROR] Unexpected option: $1"
break
;;
esac
done
if [ -n "$ASCEND_INSTALL_PATH" ]; then
_ASCEND_INSTALL_PATH=$ASCEND_INSTALL_PATH
elif [ -n "$ASCEND_HOME_PATH" ]; then
_ASCEND_INSTALL_PATH=$ASCEND_HOME_PATH
else
if [ -d "$HOME/Ascend/ascend-toolkit/latest" ]; then
_ASCEND_INSTALL_PATH=$HOME/Ascend/ascend-toolkit/latest
else
_ASCEND_INSTALL_PATH=/usr/local/Ascend/ascend-toolkit/latest
fi
fi
source $_ASCEND_INSTALL_PATH/bin/setenv.bash
rm -rf build
mkdir -p build
cmake -B build \
-DSOC_VERSION=${SOC_VERSION} \
-DASCEND_CANN_PACKAGE_PATH=${_ASCEND_INSTALL_PATH}
cmake --build build -j
cmake --install build
check_msg="Hello World"
file_path=output_msg.txt
./build/main | tee $file_path
count=$(grep -c "$check_msg" $file_path)
if [ $count -ne 8 ]; then
echo "Error, Expected 8 occurrences of $check_msg, but found $count occurrences."
exit 1
- 编译和运行:
bash run.sh -v Ascend310P1
本样例共调度八个核,分别打印了每个核的核号和"Hello World"信息。