163
csrc/scripts/opgen/opgen_standalone.py
Normal file
163
csrc/scripts/opgen/opgen_standalone.py
Normal file
@@ -0,0 +1,163 @@
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
||||
# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
# CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
# Please refer to the License for details. You may not use this file except in compliance with the License.
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See LICENSE in the root of the software repository for the full text of the License.
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
|
||||
import argparse
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
import sys
|
||||
|
||||
import regex as re
|
||||
|
||||
|
||||
class OpGenerator:
|
||||
"""算子工程生成器"""
|
||||
|
||||
def __init__(self, op_type, op_name, output_path):
|
||||
self.op_type = op_type
|
||||
self.op_name = op_name
|
||||
self.output_path = output_path
|
||||
self.template_name = "add_example"
|
||||
|
||||
self.script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
self.template_dir = os.path.abspath(os.path.join(self.script_dir, "template", "add"))
|
||||
self.dest_dir = os.path.abspath(os.path.join(self.output_path, self.op_type, self.op_name))
|
||||
|
||||
def run(self):
|
||||
"""执行生成流程"""
|
||||
self._validate_inputs()
|
||||
self._copy_template()
|
||||
self._rename_files()
|
||||
self._replace_content()
|
||||
logging.info("成功为 %s/%s 创建算子工程!", self.op_type, self.op_name)
|
||||
logging.info("工程路径: %s", self.dest_dir)
|
||||
logging.info("Create the initial directory for %s under %s success", self.op_name, self.op_type)
|
||||
|
||||
def _validate_inputs(self):
|
||||
"""校验输入参数的有效性和安全性"""
|
||||
if not self.op_type or not self.op_name:
|
||||
raise ValueError("算子类型和算子名称均不能为空。")
|
||||
|
||||
if not re.match(r"^[a-zA-Z0-9_]+$", self.op_type):
|
||||
raise ValueError(f"算子类型 '{self.op_type}' 包含无效字符。只允许字母、数字和下划线。")
|
||||
|
||||
if not re.match(r"^[a-zA-Z0-9_]+$", self.op_name):
|
||||
raise ValueError(f"算子名称 '{self.op_name}' 包含无效字符。只允许字母、数字和下划线。")
|
||||
|
||||
if os.path.exists(self.dest_dir):
|
||||
raise FileExistsError(f"目标目录 '{self.dest_dir}' 已存在。")
|
||||
|
||||
def _copy_template(self):
|
||||
"""复制模板文件到目标目录"""
|
||||
logging.info("使用模板在 '%s' 创建算子工程...", self.dest_dir)
|
||||
if not os.path.exists(self.template_dir):
|
||||
raise FileNotFoundError(f"找不到模板目录 '{self.template_dir}'。请确保 'template/add' 目录存在。")
|
||||
|
||||
try:
|
||||
shutil.copytree(self.template_dir, self.dest_dir)
|
||||
if not os.path.isfile(os.path.join(os.path.dirname(self.dest_dir), "CMakeLists.txt")):
|
||||
cmake_src = os.path.join(os.path.dirname(self.template_dir), "CMakeLists.txt")
|
||||
cmake_dest = os.path.join(os.path.dirname(self.dest_dir), "CMakeLists.txt")
|
||||
shutil.copy2(cmake_src, cmake_dest)
|
||||
except OSError as e:
|
||||
raise OSError(f"复制模板文件失败: {e}") from e
|
||||
|
||||
def _rename_files(self):
|
||||
"""重命名文件和目录中的占位符"""
|
||||
for root, dirs, files in os.walk(self.dest_dir, topdown=False):
|
||||
for name in files + dirs:
|
||||
if self.template_name not in name:
|
||||
continue
|
||||
|
||||
old_path = os.path.join(root, name)
|
||||
new_name = name.replace(self.template_name, self.op_name)
|
||||
new_path = os.path.join(root, new_name)
|
||||
try:
|
||||
os.rename(old_path, new_path)
|
||||
except OSError as e:
|
||||
raise OSError(f"重命名 '{old_path}' 到 '{new_path}' 失败: {e}") from e
|
||||
|
||||
def _replace_content_in_file(self, file_path, replacements):
|
||||
"""Helper to replace content in a single file."""
|
||||
try:
|
||||
with open(file_path, encoding="utf-8", errors="ignore") as f:
|
||||
content = f.read()
|
||||
except OSError as e:
|
||||
logging.warning("读取文件 '%s' 失败: %s", file_path, e)
|
||||
return
|
||||
|
||||
original_content = content
|
||||
for old, new in replacements.items():
|
||||
content = content.replace(old, new)
|
||||
|
||||
if content == original_content:
|
||||
return
|
||||
|
||||
try:
|
||||
with open(file_path, "w", encoding="utf-8") as f:
|
||||
f.write(content)
|
||||
except OSError as e:
|
||||
logging.warning("写入文件 '%s' 失败: %s", file_path, e)
|
||||
|
||||
def _replace_content(self):
|
||||
"""替换文件内容中的占位符"""
|
||||
op_name_capitalized = "".join(word.capitalize() for word in self.op_name.split("_"))
|
||||
template_name_capitalized = "".join(word.capitalize() for word in self.template_name.split("_"))
|
||||
|
||||
replacements = {
|
||||
self.template_name: self.op_name,
|
||||
self.template_name.upper(): self.op_name.upper(),
|
||||
template_name_capitalized: op_name_capitalized,
|
||||
"add_example": self.op_name,
|
||||
}
|
||||
for root, _, files in os.walk(self.dest_dir):
|
||||
for file in files:
|
||||
if file.endswith((".pyc", ".pyo")):
|
||||
continue
|
||||
|
||||
file_path = os.path.join(root, file)
|
||||
self._replace_content_in_file(file_path, replacements)
|
||||
|
||||
|
||||
def execute(args):
|
||||
"""根据命令行参数执行算子生成"""
|
||||
generator = OpGenerator(op_type=args.op_type, op_name=args.op_name, output_path=args.output_path)
|
||||
generator.run()
|
||||
|
||||
|
||||
def register_parser(subparsers):
|
||||
"""为 opgen 命令注册解析器。"""
|
||||
parser_opgen = subparsers.add_parser("opgen", help="生成项目骨架")
|
||||
parser_opgen.add_argument("--op_type", "-t", required=True, help="算子分类,例如 math")
|
||||
parser_opgen.add_argument("--op_name", "-n", required=True, help="新算子的名称,例如 asinh")
|
||||
parser_opgen.add_argument("--output_path", "-p", default=".", help="生成工程的根路径")
|
||||
parser_opgen.set_defaults(func=execute)
|
||||
|
||||
|
||||
def main():
|
||||
"""主函数,用于独立执行"""
|
||||
logging.basicConfig(level=logging.INFO, format="%(levelname)s: %(message)s", stream=sys.stdout)
|
||||
parser = argparse.ArgumentParser(description="生成项目骨架")
|
||||
|
||||
parser.add_argument("--op_type", "-t", required=True, help="算子分类,例如 math")
|
||||
parser.add_argument("--op_name", "-n", required=True, help="新算子的名称,例如 asinh")
|
||||
parser.add_argument("--output_path", "-p", default=".", help="生成工程的根路径")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
try:
|
||||
execute(args)
|
||||
except Exception as e:
|
||||
logging.error("发生非预期的错误,退出。错误信息: %s", e)
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
29
csrc/scripts/opgen/template/CMakeLists.txt
Normal file
29
csrc/scripts/opgen/template/CMakeLists.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
||||
# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
# CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
# Please refer to the License for details. You may not use this file except in compliance with the License.
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See LICENSE in the root of the software repository for the full text of the License.
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
set(OPTEST_NAME optest_${PKG_NAME})
|
||||
|
||||
file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
|
||||
foreach(SUB_DIR ${CURRENT_DIRS})
|
||||
if (DEFINED ASCEND_OP_NAME AND NOT "${ASCEND_OP_NAME}" STREQUAL "")
|
||||
if (NOT "${ASCEND_OP_NAME}" STREQUAL "all" AND NOT "${ASCEND_OP_NAME}" STREQUAL "ALL")
|
||||
if (NOT ${SUB_DIR} IN_LIST ASCEND_OP_NAME)
|
||||
continue()
|
||||
endif ()
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")
|
||||
add_subdirectory(${SUB_DIR})
|
||||
else()
|
||||
if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/op_host/CMakeLists.txt")
|
||||
add_subdirectory(${SUB_DIR}/op_host)
|
||||
endif()
|
||||
endif()
|
||||
endforeach()
|
||||
19
csrc/scripts/opgen/template/add/CMakeLists.txt
Normal file
19
csrc/scripts/opgen/template/add/CMakeLists.txt
Normal file
@@ -0,0 +1,19 @@
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
||||
# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
# CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
# Please refer to the License for details. You may not use this file except in compliance with the License.
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See LICENSE in the root of the software repository for the full text of the License.
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
|
||||
file(GLOB CURRENT_DIRS RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*)
|
||||
if(NOT ENABLE_TEST AND NOT BENCHMARK)
|
||||
list(REMOVE_ITEM CURRENT_DIRS tests)
|
||||
endif()
|
||||
foreach(SUB_DIR ${CURRENT_DIRS})
|
||||
if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/${SUB_DIR}/CMakeLists.txt")
|
||||
add_subdirectory(${SUB_DIR})
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -0,0 +1,166 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You may not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
// 本文件参考example下示例自动生成
|
||||
// 您可自由修改此文件满足需求
|
||||
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include "acl/acl.h"
|
||||
#include "aclnnop/aclnn_add_example.h"
|
||||
|
||||
#define CHECK_RET(cond, return_expr) \
|
||||
do { \
|
||||
if (!(cond)) { \
|
||||
return_expr; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define LOG_PRINT(message, ...) \
|
||||
do { \
|
||||
printf(message, ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
int64_t GetShapeSize(const std::vector<int64_t>& shape)
|
||||
{
|
||||
int64_t shapeSize = 1;
|
||||
for (auto i : shape) {
|
||||
shapeSize *= i;
|
||||
}
|
||||
return shapeSize;
|
||||
}
|
||||
|
||||
void PrintOutResult(std::vector<int64_t>& shape, void** deviceAddr)
|
||||
{
|
||||
auto size = GetShapeSize(shape);
|
||||
std::vector<float> resultData(size, 0);
|
||||
auto ret = aclrtMemcpy(
|
||||
resultData.data(), resultData.size() * sizeof(resultData[0]), *deviceAddr, size * sizeof(resultData[0]),
|
||||
ACL_MEMCPY_DEVICE_TO_HOST);
|
||||
CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("copy result from device to host failed. ERROR: %d\n", ret); return);
|
||||
for (int64_t i = 0; i < size; i++) {
|
||||
LOG_PRINT("mean result[%ld] is: %f\n", i, resultData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
int Init(int32_t deviceId, aclrtStream* stream)
|
||||
{
|
||||
// 固定写法,初始化
|
||||
auto ret = aclInit(nullptr);
|
||||
CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclInit failed. ERROR: %d\n", ret); return ret);
|
||||
ret = aclrtSetDevice(deviceId);
|
||||
CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSetDevice failed. ERROR: %d\n", ret); return ret);
|
||||
ret = aclrtCreateStream(stream);
|
||||
CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtCreateStream failed. ERROR: %d\n", ret); return ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
int CreateAclTensor(
|
||||
const std::vector<T>& hostData, const std::vector<int64_t>& shape, void** deviceAddr, aclDataType dataType,
|
||||
aclTensor** tensor)
|
||||
{
|
||||
auto size = GetShapeSize(shape) * sizeof(T);
|
||||
// 2. 申请device侧内存
|
||||
auto ret = aclrtMalloc(deviceAddr, size, ACL_MEM_MALLOC_HUGE_FIRST);
|
||||
CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMalloc failed. ERROR: %d\n", ret); return ret);
|
||||
// 3. 调用aclrtMemcpy将host侧数据拷贝到device侧内存上
|
||||
ret = aclrtMemcpy(*deviceAddr, size, hostData.data(), size, ACL_MEMCPY_HOST_TO_DEVICE);
|
||||
CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtMemcpy failed. ERROR: %d\n", ret); return ret);
|
||||
|
||||
// 计算连续tensor的strides
|
||||
std::vector<int64_t> strides(shape.size(), 1);
|
||||
for (int64_t i = shape.size() - 2; i >= 0; i--) {
|
||||
strides[i] = shape[i + 1] * strides[i + 1];
|
||||
}
|
||||
|
||||
// 调用aclCreateTensor接口创建aclTensor
|
||||
*tensor = aclCreateTensor(
|
||||
shape.data(), shape.size(), dataType, strides.data(), 0, aclFormat::ACL_FORMAT_ND, shape.data(), shape.size(),
|
||||
*deviceAddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
// 1. 调用acl进行device/stream初始化
|
||||
int32_t deviceId = 0;
|
||||
aclrtStream stream;
|
||||
auto ret = Init(deviceId, &stream);
|
||||
CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("Init acl failed. ERROR: %d\n", ret); return ret);
|
||||
|
||||
// 2. 构造输入与输出,需要根据API的接口自定义构造
|
||||
aclTensor* selfX = nullptr;
|
||||
void* selfXDeviceAddr = nullptr;
|
||||
std::vector<int64_t> selfXShape = {32, 4, 4, 4};
|
||||
std::vector<float> selfXHostData(2048, 1); // 2048:创建包含32*4*4*4=2048个元素的向量
|
||||
ret = CreateAclTensor(selfXHostData, selfXShape, &selfXDeviceAddr, aclDataType::ACL_FLOAT, &selfX);
|
||||
CHECK_RET(ret == ACL_SUCCESS, return ret);
|
||||
|
||||
aclTensor* selfY = nullptr;
|
||||
void* selfYDeviceAddr = nullptr;
|
||||
std::vector<int64_t> selfYShape = {32, 4, 4, 4};
|
||||
std::vector<float> selfYHostData(2048, 1);
|
||||
ret = CreateAclTensor(selfYHostData, selfYShape, &selfYDeviceAddr, aclDataType::ACL_FLOAT, &selfY);
|
||||
CHECK_RET(ret == ACL_SUCCESS, return ret);
|
||||
|
||||
aclTensor* out = nullptr;
|
||||
void* outDeviceAddr = nullptr;
|
||||
std::vector<int64_t> outShape = {32, 4, 4, 4};
|
||||
std::vector<float> outHostData(2048, 1);
|
||||
ret = CreateAclTensor(outHostData, outShape, &outDeviceAddr, aclDataType::ACL_FLOAT, &out);
|
||||
CHECK_RET(ret == ACL_SUCCESS, return ret);
|
||||
|
||||
// 3. 调用CANN算子库API,需要修改为具体的Api名称
|
||||
uint64_t workspaceSize = 0;
|
||||
aclOpExecutor* executor;
|
||||
|
||||
// 4. 调用aclnnAddExample第一段接口
|
||||
ret = aclnnAddExampleGetWorkspaceSize(selfX, selfY, out, &workspaceSize, &executor);
|
||||
CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAddExampleGetWorkspaceSize failed. ERROR: %d\n", ret); return ret);
|
||||
|
||||
// 根据第一段接口计算出的workspaceSize申请device内存
|
||||
void* workspaceAddr = nullptr;
|
||||
if (workspaceSize > static_cast<uint64_t>(0)) {
|
||||
ret = aclrtMalloc(&workspaceAddr, workspaceSize, ACL_MEM_MALLOC_HUGE_FIRST);
|
||||
CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("allocate workspace failed. ERROR: %d\n", ret); return ret);
|
||||
}
|
||||
|
||||
// 5. 调用aclnnAddExample第二段接口
|
||||
ret = aclnnAddExample(workspaceAddr, workspaceSize, executor, stream);
|
||||
CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclnnAddExample failed. ERROR: %d\n", ret); return ret);
|
||||
|
||||
// 6. (固定写法)同步等待任务执行结束
|
||||
ret = aclrtSynchronizeStream(stream);
|
||||
CHECK_RET(ret == ACL_SUCCESS, LOG_PRINT("aclrtSynchronizeStream failed. ERROR: %d\n", ret); return ret);
|
||||
|
||||
// 5. 获取输出的值,将device侧内存上的结果拷贝至host侧,需要根据具体API的接口定义修改
|
||||
PrintOutResult(outShape, &outDeviceAddr);
|
||||
|
||||
// 7. 释放aclTensor,需要根据具体API的接口定义修改
|
||||
aclDestroyTensor(selfX);
|
||||
aclDestroyTensor(selfY);
|
||||
aclDestroyTensor(out);
|
||||
|
||||
// 8. 释放device资源
|
||||
aclrtFree(selfXDeviceAddr);
|
||||
aclrtFree(selfYDeviceAddr);
|
||||
aclrtFree(outDeviceAddr);
|
||||
if (workspaceSize > static_cast<uint64_t>(0)) {
|
||||
aclrtFree(workspaceAddr);
|
||||
}
|
||||
aclrtDestroyStream(stream);
|
||||
aclrtResetDevice(deviceId);
|
||||
|
||||
// 9. acl去初始化
|
||||
aclFinalize();
|
||||
|
||||
return 0;
|
||||
}
|
||||
18
csrc/scripts/opgen/template/add/op_host/CMakeLists.txt
Normal file
18
csrc/scripts/opgen/template/add/op_host/CMakeLists.txt
Normal file
@@ -0,0 +1,18 @@
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
# Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
||||
# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
# CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
# Please refer to the License for details. You may not use this file except in compliance with the License.
|
||||
# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See LICENSE in the root of the software repository for the full text of the License.
|
||||
# -----------------------------------------------------------------------------------------------------------
|
||||
add_op_to_compiled_list()
|
||||
|
||||
if (BUILD_OPEN_PROJECT)
|
||||
target_sources(op_host_aclnn PRIVATE
|
||||
add_example_def.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
add_modules_sources(OPTYPE add_example ACLNNTYPE aclnn)
|
||||
55
csrc/scripts/opgen/template/add/op_host/add_example_def.cpp
Normal file
55
csrc/scripts/opgen/template/add/op_host/add_example_def.cpp
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You may not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file add_example_def.cpp
|
||||
* \brief
|
||||
*/
|
||||
#include "register/op_def_registry.h"
|
||||
|
||||
namespace ops {
|
||||
class AddExample : public OpDef {
|
||||
public:
|
||||
explicit AddExample(const char* name) : OpDef(name)
|
||||
{
|
||||
// 输入参数说明
|
||||
this->Input("x1") // 输入x1定义
|
||||
.ParamType(REQUIRED) // 必选输入
|
||||
.DataType({ge::DT_FLOAT, ge::DT_INT32}) // 支持数据类型
|
||||
.Format({ge::FORMAT_ND, ge::FORMAT_ND}) // 支持format格式
|
||||
.UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND}) // 未确定大小shape对应format格式
|
||||
.AutoContiguous(); // 内存自动连续化
|
||||
this->Input("x2") // 输入x2定义
|
||||
.ParamType(REQUIRED)
|
||||
.DataType({ge::DT_FLOAT, ge::DT_INT32})
|
||||
.Format({ge::FORMAT_ND, ge::FORMAT_ND})
|
||||
.UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND})
|
||||
.AutoContiguous();
|
||||
this->Output("y") // 输出y定义
|
||||
.ParamType(REQUIRED)
|
||||
.DataType({ge::DT_FLOAT, ge::DT_INT32})
|
||||
.Format({ge::FORMAT_ND, ge::FORMAT_ND})
|
||||
.UnknownShapeFormat({ge::FORMAT_ND, ge::FORMAT_ND})
|
||||
.AutoContiguous();
|
||||
|
||||
OpAICoreConfig aicoreConfig;
|
||||
aicoreConfig.DynamicCompileStaticFlag(true)
|
||||
.DynamicFormatFlag(false)
|
||||
.DynamicRankSupportFlag(true)
|
||||
.DynamicShapeSupportFlag(true)
|
||||
.NeedCheckSupportFlag(false)
|
||||
.PrecisionReduceFlag(true)
|
||||
.ExtendCfgInfo("opFile.value", "add_example"); // 这里制定的值会对应到kernel入口文件名.cpp
|
||||
this->AICore().AddConfig("ascend910b", aicoreConfig); // 其他的soc版本补充部分配置项
|
||||
this->AICore().AddConfig("ascend910_93", aicoreConfig);
|
||||
}
|
||||
};
|
||||
OP_ADD(AddExample); // 添加算子信息库
|
||||
} // namespace ops
|
||||
@@ -0,0 +1,48 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You may not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file add_example_infer.cpp
|
||||
* \brief
|
||||
*/
|
||||
#include "register/op_impl_registry.h"
|
||||
#include "log/log.h"
|
||||
|
||||
using namespace ge;
|
||||
|
||||
namespace ops {
|
||||
static constexpr int64_t IDX_0 = 0;
|
||||
|
||||
static ge::graphStatus InferShapeAddExample(gert::InferShapeContext* context)
|
||||
{
|
||||
OP_LOGD(context->GetNodeName(), "Begin to do InferShapeAddExample");
|
||||
|
||||
// get input shapes
|
||||
const gert::Shape* xShape = context->GetInputShape(IDX_0);
|
||||
OP_CHECK_NULL_WITH_CONTEXT(context, xShape);
|
||||
|
||||
// get output shapes
|
||||
gert::Shape* yShape = context->GetOutputShape(IDX_0);
|
||||
OP_CHECK_NULL_WITH_CONTEXT(context, yShape);
|
||||
|
||||
// 填充输出shape大小
|
||||
auto xShapeSize = xShape->GetDimNum();
|
||||
yShape->SetDimNum(xShapeSize);
|
||||
for (size_t i = 0; i < xShapeSize; i++) {
|
||||
int64_t dim = xShape->GetDim(i);
|
||||
yShape->SetDim(i, dim);
|
||||
}
|
||||
|
||||
OP_LOGD(context->GetNodeName(), "End to do InferShapeAddExample");
|
||||
return GRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
IMPL_OP_INFERSHAPE(AddExample).InferShape(InferShapeAddExample);
|
||||
} // namespace ops
|
||||
156
csrc/scripts/opgen/template/add/op_host/add_example_tiling.cpp
Normal file
156
csrc/scripts/opgen/template/add/op_host/add_example_tiling.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You may not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file add_example_tiling.cpp
|
||||
* \brief
|
||||
*/
|
||||
|
||||
#include "log/log.h"
|
||||
#include "util/math_util.h"
|
||||
#include "tiling_base/tiling_util.h"
|
||||
#include "tiling_base/tiling_templates_registry.h"
|
||||
#include "../op_kernel/add_example_tiling_data.h"
|
||||
#include "../op_kernel/add_example_tiling_key.h"
|
||||
|
||||
namespace optiling {
|
||||
|
||||
using namespace Ops::Transformer::OpTiling;
|
||||
|
||||
const uint32_t BLOCK_DIM = 8;
|
||||
const int64_t TILE_NUM = 8;
|
||||
const uint32_t WS_SYS_SIZE = 16U * 1024U * 1024U;
|
||||
const int32_t DIMS_LIMIT = 4;
|
||||
constexpr int32_t ATTRPOS0 = 0;
|
||||
constexpr uint32_t INDEXZERO = 0;
|
||||
constexpr uint32_t INDEXONE = 1;
|
||||
constexpr uint32_t INDEXTWO = 2;
|
||||
constexpr uint32_t INDEXTHREE = 3;
|
||||
|
||||
struct AddExampleCompileInfo {};
|
||||
|
||||
// 获取平台信息如ubSize, coreNum
|
||||
static ge::graphStatus GetPlatformInfo(gert::TilingContext* context, uint64_t& ubSize, int64_t& coreNum)
|
||||
{
|
||||
// 获取ubsize coreNum
|
||||
fe::PlatFormInfos* platformInfoPtr = context->GetPlatformInfo();
|
||||
OP_CHECK_NULL_WITH_CONTEXT(context, platformInfoPtr);
|
||||
auto ascendcPlatform = platform_ascendc::PlatformAscendC(platformInfoPtr);
|
||||
coreNum = ascendcPlatform.GetCoreNumAiv();
|
||||
OP_CHECK_IF(coreNum == 0, OP_LOGE(context, "coreNum is 0"), return ge::GRAPH_FAILED);
|
||||
ascendcPlatform.GetCoreMemSize(platform_ascendc::CoreMemType::UB, ubSize);
|
||||
OP_CHECK_IF(ubSize == 0, OP_LOGE(context, "ubSize is 0"), return ge::GRAPH_FAILED);
|
||||
return ge::GRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
// 获取属性,shape信息
|
||||
ge::graphStatus GetShapeAttrsInfo(gert::TilingContext* context, int64_t& totalIdx, ge::DataType& dataType)
|
||||
{
|
||||
// 获取输入shape信息
|
||||
auto inputX = context->GetInputShape(0);
|
||||
OP_CHECK_NULL_WITH_CONTEXT(context, inputX);
|
||||
// 如果输入shape 是标量 转换为{1},否则保持原 shape 不变
|
||||
auto inputShapeX = EnsureNotScalar(inputX->GetStorageShape());
|
||||
auto inputY = context->GetInputShape(1);
|
||||
OP_CHECK_NULL_WITH_CONTEXT(context, inputY);
|
||||
auto inputShapeY = EnsureNotScalar(inputY->GetStorageShape());
|
||||
auto outZ = context->GetOutputShape(0);
|
||||
OP_CHECK_NULL_WITH_CONTEXT(context, outZ);
|
||||
auto outShapeZ = EnsureNotScalar(outZ->GetStorageShape());
|
||||
|
||||
// shape校验
|
||||
OP_CHECK_IF(
|
||||
inputShapeX.GetDimNum() != DIMS_LIMIT || inputShapeY.GetDimNum() != DIMS_LIMIT ||
|
||||
outShapeZ.GetDimNum() != DIMS_LIMIT,
|
||||
OP_LOGE(
|
||||
context, "AddExample: inputx,inputy,outputz shape dim = %zu, %zu, %zu, should be equal 4",
|
||||
inputShapeX.GetDimNum(), inputShapeY.GetDimNum(), outShapeZ.GetDimNum()),
|
||||
return ge::GRAPH_FAILED);
|
||||
|
||||
// 获取shape dim值
|
||||
auto nDim = inputShapeX.GetDim(INDEXZERO);
|
||||
auto cDim = inputShapeX.GetDim(INDEXONE);
|
||||
auto hDim = inputShapeX.GetDim(INDEXTWO);
|
||||
auto wDim = inputShapeX.GetDim(INDEXTHREE);
|
||||
totalIdx = nDim * cDim * hDim * wDim;
|
||||
// dtype校验
|
||||
const std::set<ge::DataType> supportedDtype = {ge::DT_FLOAT, ge::DT_INT32};
|
||||
auto inputDesc = context->GetInputDesc(0);
|
||||
OP_CHECK_NULL_WITH_CONTEXT(context, inputDesc);
|
||||
dataType = inputDesc->GetDataType();
|
||||
if (supportedDtype.count(dataType) == 0) {
|
||||
OP_LOGE(context, "invalid dtype");
|
||||
return ge::GRAPH_FAILED;
|
||||
}
|
||||
return ge::GRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
ge::graphStatus GetWorkspaceSize(gert::TilingContext* context)
|
||||
{
|
||||
size_t* currentWorkspace = context->GetWorkspaceSizes(1);
|
||||
OP_CHECK_NULL_WITH_CONTEXT(context, currentWorkspace);
|
||||
currentWorkspace[0] = WS_SYS_SIZE;
|
||||
return ge::GRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
// tiling 分发入口
|
||||
static ge::graphStatus AddExampleTilingFunc(gert::TilingContext* context)
|
||||
{
|
||||
// 1、获取平台运行信息
|
||||
uint64_t ubSize;
|
||||
int64_t coreNum;
|
||||
OP_CHECK_IF(
|
||||
GetPlatformInfo(context, ubSize, coreNum) != ge::GRAPH_SUCCESS, OP_LOGE(context, "GetPlatformInfo error"),
|
||||
return ge::GRAPH_FAILED);
|
||||
// 2、获取shape、属性信息
|
||||
int64_t totalIdx;
|
||||
ge::DataType dataType;
|
||||
|
||||
OP_CHECK_IF(
|
||||
GetShapeAttrsInfo(context, totalIdx, dataType) != ge::GRAPH_SUCCESS,
|
||||
OP_LOGE(context, "GetShapeAttrsInfo error"), return ge::GRAPH_FAILED);
|
||||
// 3、获取WorkspaceSize信息
|
||||
OP_CHECK_IF(
|
||||
GetWorkspaceSize(context) != ge::GRAPH_SUCCESS, OP_LOGE(context, "GetWorkspaceSize error"),
|
||||
return ge::GRAPH_FAILED);
|
||||
|
||||
// 4、设置tiling信息
|
||||
AddExampleTilingData* tiling = context->GetTilingData<AddExampleTilingData>();
|
||||
OP_CHECK_NULL_WITH_CONTEXT(context, tiling);
|
||||
OP_CHECK_IF(
|
||||
memset_s(tiling, sizeof(AddExampleTilingData), 0, sizeof(AddExampleTilingData)) != EOK,
|
||||
OP_LOGE(context, "set tiling data error"), return ge::GRAPH_FAILED);
|
||||
tiling->totalLength = totalIdx;
|
||||
tiling->tileNum = TILE_NUM;
|
||||
|
||||
context->SetBlockDim(BLOCK_DIM);
|
||||
uint64_t tilingKey = 0;
|
||||
// 区分dtype走不同得tiling key分支.
|
||||
if (dataType == ge::DT_FLOAT) {
|
||||
tilingKey = GET_TPL_TILING_KEY(ELEMENTWISE_TPL_SCH_MODE_0);
|
||||
context->SetTilingKey(tilingKey);
|
||||
} else if (dataType == ge::DT_INT32) {
|
||||
tilingKey = GET_TPL_TILING_KEY(ELEMENTWISE_TPL_SCH_MODE_1);
|
||||
context->SetTilingKey(tilingKey);
|
||||
} else {
|
||||
OP_LOGE(context, "get dtype error");
|
||||
return ge::GRAPH_FAILED;
|
||||
}
|
||||
return ge::GRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
static ge::graphStatus TilingParseForAddExample([[maybe_unused]] gert::TilingParseContext* context)
|
||||
{
|
||||
return ge::GRAPH_SUCCESS;
|
||||
}
|
||||
|
||||
// tiling注册入口.
|
||||
IMPL_OP_OPTILING(AddExample).Tiling(AddExampleTilingFunc).TilingParse<AddExampleCompileInfo>(TilingParseForAddExample);
|
||||
} // namespace optiling
|
||||
43
csrc/scripts/opgen/template/add/op_kernel/add_example.cpp
Normal file
43
csrc/scripts/opgen/template/add/op_kernel/add_example.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You may not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file add_example.cpp
|
||||
* \brief
|
||||
*/
|
||||
|
||||
#include "add_example.h"
|
||||
|
||||
enum class AddExampleTilingKey : uint32_t
|
||||
{
|
||||
TILING_KEY_EXAMPLE_FLOAT = 0,
|
||||
TILING_KEY_EXAMPLE_INT32 = 1,
|
||||
};
|
||||
|
||||
template <uint32_t schMode>
|
||||
__global__ __aicore__ void add_example(GM_ADDR x, GM_ADDR y, GM_ADDR z, GM_ADDR workspace, GM_ADDR tiling)
|
||||
{
|
||||
REGISTER_TILING_DEFAULT(AddExampleTilingData);
|
||||
GET_TILING_DATA_WITH_STRUCT(AddExampleTilingData, tilingData, tiling);
|
||||
|
||||
// 场景1
|
||||
if constexpr (schMode == static_cast<uint32_t>(AddExampleTilingKey::TILING_KEY_EXAMPLE_FLOAT)) {
|
||||
NsAddExample::AddExample<float> op; // 算子kernel实例获取
|
||||
op.Init(x, y, z, &tilingData); // 算子kernel实例初始化
|
||||
op.Process(); // 算子kernel实例执行
|
||||
}
|
||||
|
||||
// 场景2
|
||||
if constexpr (schMode == static_cast<uint32_t>(AddExampleTilingKey::TILING_KEY_EXAMPLE_INT32)) {
|
||||
NsAddExample::AddExample<int32_t> op; // 算子kernel实例获取
|
||||
op.Init(x, y, z, &tilingData); // 算子kernel实例初始化
|
||||
op.Process(); // 算子kernel实例执行
|
||||
}
|
||||
}
|
||||
117
csrc/scripts/opgen/template/add/op_kernel/add_example.h
Normal file
117
csrc/scripts/opgen/template/add/op_kernel/add_example.h
Normal file
@@ -0,0 +1,117 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You may not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file add_example.h
|
||||
* \brief
|
||||
*/
|
||||
#ifndef ADD_EXAMPLE_H
|
||||
#define ADD_EXAMPLE_H
|
||||
|
||||
#include "kernel_operator.h"
|
||||
#include "kernel_tiling/kernel_tiling.h"
|
||||
#include "add_example_tiling_data.h"
|
||||
#include "add_example_tiling_key.h"
|
||||
|
||||
namespace NsAddExample {
|
||||
|
||||
using namespace AscendC;
|
||||
|
||||
constexpr int32_t BUFFER_NUM = 2;
|
||||
|
||||
template <typename T>
|
||||
class AddExample
|
||||
{
|
||||
public:
|
||||
__aicore__ inline AddExample(){};
|
||||
|
||||
__aicore__ inline void Init(GM_ADDR x, GM_ADDR y, GM_ADDR z, const AddExampleTilingData* tilingData);
|
||||
__aicore__ inline void Process();
|
||||
|
||||
private:
|
||||
__aicore__ inline void CopyIn(int32_t progress);
|
||||
__aicore__ inline void CopyOut(int32_t progress);
|
||||
__aicore__ inline void Compute(const int32_t dataLength);
|
||||
|
||||
private:
|
||||
TPipe pipe;
|
||||
TQue<QuePosition::VECIN, BUFFER_NUM> inputQueueX;
|
||||
TQue<QuePosition::VECIN, BUFFER_NUM> inputQueueY;
|
||||
TQue<QuePosition::VECOUT, BUFFER_NUM> outputQueueZ;
|
||||
|
||||
GlobalTensor<T> inputGMX;
|
||||
GlobalTensor<T> inputGMY;
|
||||
GlobalTensor<T> outputGMZ;
|
||||
|
||||
int64_t blockLength_ = 0;
|
||||
int64_t tileNum_ = 0;
|
||||
uint32_t tileLength_ = 0;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
__aicore__ inline void AddExample<T>::Init(GM_ADDR x, GM_ADDR y, GM_ADDR z, const AddExampleTilingData* tilingData)
|
||||
{
|
||||
blockLength_ = tilingData->totalLength / AscendC::GetBlockNum();
|
||||
tileNum_ = tilingData->tileNum;
|
||||
tileLength_ = blockLength_ / tileNum_ / BUFFER_NUM;
|
||||
|
||||
inputGMX.SetGlobalBuffer((__gm__ T*)x + blockLength_ * AscendC::GetBlockIdx(), blockLength_);
|
||||
inputGMY.SetGlobalBuffer((__gm__ T*)y + blockLength_ * AscendC::GetBlockIdx(), blockLength_);
|
||||
outputGMZ.SetGlobalBuffer((__gm__ T*)z + blockLength_ * AscendC::GetBlockIdx(), blockLength_);
|
||||
|
||||
pipe.InitBuffer(inputQueueX, BUFFER_NUM, tileLength_ * sizeof(T));
|
||||
pipe.InitBuffer(inputQueueY, BUFFER_NUM, tileLength_ * sizeof(T));
|
||||
pipe.InitBuffer(outputQueueZ, BUFFER_NUM, tileLength_ * sizeof(T));
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__aicore__ inline void AddExample<T>::CopyIn(int32_t progress)
|
||||
{
|
||||
AscendC::LocalTensor<T> xLocal = inputQueueX.AllocTensor<T>();
|
||||
AscendC::LocalTensor<T> yLocal = inputQueueY.AllocTensor<T>();
|
||||
AscendC::DataCopy(xLocal, inputGMX[progress * tileLength_], tileLength_);
|
||||
AscendC::DataCopy(yLocal, inputGMY[progress * tileLength_], tileLength_);
|
||||
inputQueueX.EnQue(xLocal);
|
||||
inputQueueY.EnQue(yLocal);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__aicore__ inline void AddExample<T>::CopyOut(int32_t progress)
|
||||
{
|
||||
AscendC::LocalTensor<T> zLocal = outputQueueZ.DeQue<T>();
|
||||
AscendC::DataCopy(outputGMZ[progress * tileLength_], zLocal, tileLength_);
|
||||
outputQueueZ.FreeTensor(zLocal);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__aicore__ inline void AddExample<T>::Compute(int32_t progress)
|
||||
{
|
||||
AscendC::LocalTensor<T> xLocal = inputQueueX.DeQue<T>();
|
||||
AscendC::LocalTensor<T> yLocal = inputQueueY.DeQue<T>();
|
||||
AscendC::LocalTensor<T> zLocal = outputQueueZ.AllocTensor<T>();
|
||||
AscendC::Add(zLocal, xLocal, yLocal, tileLength_);
|
||||
outputQueueZ.EnQue<T>(zLocal);
|
||||
inputQueueX.FreeTensor(xLocal);
|
||||
inputQueueY.FreeTensor(yLocal);
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
__aicore__ inline void AddExample<T>::Process()
|
||||
{
|
||||
int32_t loopCount = tileNum_ * BUFFER_NUM;
|
||||
for (int32_t i = 0; i < loopCount; i++) {
|
||||
CopyIn(i);
|
||||
Compute(i);
|
||||
CopyOut(i);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace NsAddExample
|
||||
#endif // ADD_EXAMPLE_H
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You may not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file add_example_tiling_data.h
|
||||
* \brief tiling data struct
|
||||
*/
|
||||
|
||||
#ifndef __ADD_EXAMPLE_TILLING_DATA_H__
|
||||
#define __ADD_EXAMPLE_TILLING_DATA_H__
|
||||
|
||||
struct AddExampleTilingData {
|
||||
int64_t totalLength;
|
||||
int64_t tileNum;
|
||||
};
|
||||
#endif
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Huawei Technologies Co., Ltd.
|
||||
* This program is free software, you can redistribute it and/or modify it under the terms and conditions of
|
||||
* CANN Open Software License Agreement Version 2.0 (the "License").
|
||||
* Please refer to the License for details. You may not use this file except in compliance with the License.
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See LICENSE in the root of the software repository for the full text of the License.
|
||||
*/
|
||||
|
||||
/*!
|
||||
* \file add_example_tiling_key.h
|
||||
* \brief add_example tiling key declare
|
||||
*/
|
||||
|
||||
#ifndef __ADD_EXAMPLE_TILING_KEY_H__
|
||||
#define __ADD_EXAMPLE_TILING_KEY_H__
|
||||
|
||||
#include "ascendc/host_api/tiling/template_argument.h"
|
||||
|
||||
/* Mode场景定义 */
|
||||
#define ELEMENTWISE_TPL_SCH_MODE_0 0
|
||||
#define ELEMENTWISE_TPL_SCH_MODE_1 1
|
||||
/* 继续定义其他Mode场景... */
|
||||
|
||||
/* 模板参数 */
|
||||
ASCENDC_TPL_ARGS_DECL(AddExample,
|
||||
ASCENDC_TPL_UINT_DECL(schMode, 1, ASCENDC_TPL_UI_LIST, ELEMENTWISE_TPL_SCH_MODE_0, ELEMENTWISE_TPL_SCH_MODE_1)
|
||||
);
|
||||
|
||||
ASCENDC_TPL_SEL(
|
||||
ASCENDC_TPL_ARGS_SEL(
|
||||
ASCENDC_TPL_UINT_SEL(schMode, ASCENDC_TPL_UI_LIST, ELEMENTWISE_TPL_SCH_MODE_0, ELEMENTWISE_TPL_SCH_MODE_1)));
|
||||
|
||||
#endif
|
||||
0
csrc/scripts/opgen/template/add/tests/ut/.gitkeep
Normal file
0
csrc/scripts/opgen/template/add/tests/ut/.gitkeep
Normal file
Reference in New Issue
Block a user