已合并
add aclnn golden #4593
fengdaoyong创建于 23 天前
add aclnn golden #4593
已合并
fengdaoyong创建于 23 天前
17 个文件变更+665-165
@@ -0,0 +1,34 @@
1+#!/usr/bin/env python3
2+# -*- coding: UTF-8 -*-
3+# ----------------------------------------------------------------------------
4+# Copyright (c) 2026 Huawei Technologies Co., Ltd.
5+# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
6+# CANN Open Software License Agreement Version 2.0 (the "License").
7+# Please refer to the License for details. You may not use this file except in compliance with the License.
8+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
9+# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
10+# See LICENSE in the root of the software repository for the full text of the License.
11+# ----------------------------------------------------------------------------
12+ 
13+__golden__ = {"aclnn": {"aclnnAdd": "aclnn_add_golden"}}
14+ 
15+ 
16+def aclnn_add_golden(self, other, alpha, out, **kwargs):
17+ """
18+ Aclnn golden for aclnnAdd.
19+ All the parameters (name & order) follow \
20+ function `aclnnAddGetWorkspaceSize` in @aclnn_add.h \
21+ without `workspaceSize` & `executor`.
22+ When all dtypes are natively supported by torch, \
23+ the Tensors in the parameters are all torch.Tensor. \
24+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
25+ 
26+ Args:
27+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
28+ 
29+ Returns:
30+ Output tensors.
31+ """
32+ import torch
33+ 
34+ return torch.add(self, other, alpha=alpha)
@@ -13,29 +13,49 @@ import numpy
13import torch13import torch
14 14 
15__golden__ = {15__golden__ = {
16- "kernel": {16+ "kernel": {"addcdiv": "addcdiv_golden"},
17- "addcdiv": "addcdiv_golden"17+ "aclnn": {"aclnnAddcdiv": "aclnn_addcdiv_golden"},
18- }
19}18}
20 19 
21-def addcdiv_golden(input_data, x1, x2, value,20+ 
22- **kwargs):21+def addcdiv_golden(input_data, x1, x2, value, **kwargs):
23- '''22+ """
24 Kernel golden for addcdiv.23 Kernel golden for addcdiv.
25 All the parameters follow @addcdiv_def.cpp without outputs.24 All the parameters follow @addcdiv_def.cpp without outputs.
26 All the input Tensors are numpy.ndarray.25 All the input Tensors are numpy.ndarray.
27- kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes, 26+ kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes,
28 input_formats, output_formats, input_ori_formats, output_ori_formats,27 input_formats, output_formats, input_ori_formats, output_ori_formats,
29 input_dtypes, output_dtypes.28 input_dtypes, output_dtypes.
30- '''29+ """
31 data_type = input_data.dtype30 data_type = input_data.dtype
32 input_data = torch.from_numpy(input_data.astype(numpy.float32))31 input_data = torch.from_numpy(input_data.astype(numpy.float32))
33 x1 = torch.from_numpy(x1.astype(numpy.float32))32 x1 = torch.from_numpy(x1.astype(numpy.float32))
34 x2 = torch.from_numpy(x2.astype(numpy.float32))33 x2 = torch.from_numpy(x2.astype(numpy.float32))
35- value = value.item() 34+ value = value.item()
36- 35+ 
37 res = torch.addcdiv(input_data, x1, x2, value=value)36 res = torch.addcdiv(input_data, x1, x2, value=value)
38 res_np = res.numpy()37 res_np = res.numpy()
39 res_np = res_np.astype(data_type, copy=False)38 res_np = res_np.astype(data_type, copy=False)
40 39 
41 return res_np40 return res_np
41+ 
42+ 
43+def aclnn_addcdiv_golden(self, tensor1, tensor2, value, out, **kwargs):
44+ """
45+ Aclnn golden for aclnnAddcdiv.
46+ All the parameters (name & order) follow \
47+ function `aclnnAddcdivGetWorkspaceSize` in @aclnn_addcdiv.h \
48+ without `workspaceSize` & `executor`.
49+ When all dtypes are natively supported by torch, \
50+ the Tensors in the parameters are all torch.Tensor. \
51+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
52+ 
53+ Args:
54+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
55+ 
56+ Returns:
57+ Output tensors.
58+ """
59+ import torch
60+ 
61+ return torch.addcdiv(self, tensor1, tensor2, value=value)
@@ -12,21 +12,20 @@
12import numpy12import numpy
13 13 
14__golden__ = {14__golden__ = {
15- "kernel": {15+ "kernel": {"addcmul": "addcmul_golden"},
16- "addcmul": "addcmul_golden"16+ "aclnn": {"aclnnAddcmul": "aclnn_addcmul_golden"},
17- }
18}17}
19 18 
20-def addcmul_golden(input_data, x1, x2, value,19+ 
21- **kwargs):20+def addcmul_golden(input_data, x1, x2, value, **kwargs):
22- '''21+ """
23 Kernel golden for addcmul.22 Kernel golden for addcmul.
24 All the parameters follow @addcmul_def.cpp without outputs.23 All the parameters follow @addcmul_def.cpp without outputs.
25 All the input Tensors are numpy.ndarray.24 All the input Tensors are numpy.ndarray.
26- kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes, 25+ kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes,
27- input_formats, output_formats, input_ori_formats, output_ori_formats,26+ input_formats, output_formats, input_ori_formats, output_ori_formats,
28- input_dtypes, output_dtypes.27+ input_dtypes, output_dtypes.
29- '''28+ """
30 import torch29 import torch
31 from ml_dtypes import bfloat1630 from ml_dtypes import bfloat16
32 31 
@@ -35,7 +34,7 @@ def addcmul_golden(input_data, x1, x2, value,
35 input_data = torch.from_numpy(input_data.astype(numpy.float32))34 input_data = torch.from_numpy(input_data.astype(numpy.float32))
36 x1 = torch.from_numpy(x1.astype(numpy.float32))35 x1 = torch.from_numpy(x1.astype(numpy.float32))
37 x2 = torch.from_numpy(x2.astype(numpy.float32))36 x2 = torch.from_numpy(x2.astype(numpy.float32))
38- else :37+ else:
39 input_data = torch.from_numpy(input_data)38 input_data = torch.from_numpy(input_data)
40 x1 = torch.from_numpy(x1)39 x1 = torch.from_numpy(x1)
41 x2 = torch.from_numpy(x2)40 x2 = torch.from_numpy(x2)
@@ -46,3 +45,23 @@ def addcmul_golden(input_data, x1, x2, value,
46 45 
47 return res_np46 return res_np
48 47 
48+ 
49+def aclnn_addcmul_golden(self, tensor1, tensor2, value, out, **kwargs):
50+ """
51+ Aclnn golden for aclnnAddcmul.
52+ All the parameters (name & order) follow \
53+ function `aclnnAddcmulGetWorkspaceSize` in @aclnn_addcmul.h \
54+ without `workspaceSize` & `executor`.
55+ When all dtypes are natively supported by torch, \
56+ the Tensors in the parameters are all torch.Tensor. \
57+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
58+ 
59+ Args:
60+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
61+ 
62+ Returns:
63+ Output tensors.
64+ """
65+ import torch
66+ 
67+ return torch.addcmul(self, tensor1, tensor2, value=value)
@@ -13,14 +13,14 @@
13import numpy as np13import numpy as np
14 14 
15__golden__ = {15__golden__ = {
16- "kernel": {16+ "kernel": {"bincount": "bincount_golden"},
17- "bincount": "bincount_golden"17+ "aclnn": {"aclnnBincount": "aclnn_bincount_golden"},
18- }
19}18}
20 19 
21 20 
22def numpy_to_torch_tensor(np_array):21def numpy_to_torch_tensor(np_array):
23 import torch22 import torch
23+ 
24 if np_array is None:24 if np_array is None:
25 return None25 return None
26 np_dtype = np_array.dtype.name26 np_dtype = np_array.dtype.name
@@ -34,6 +34,7 @@ def numpy_to_torch_tensor(np_array):
34 34 
35def torch_to_numpy_tensor(torch_tensor):35def torch_to_numpy_tensor(torch_tensor):
36 import torch36 import torch
37+ 
37 if torch_tensor is None:38 if torch_tensor is None:
38 return None39 return None
39 if not isinstance(torch_tensor, torch.Tensor):40 if not isinstance(torch_tensor, torch.Tensor):
@@ -48,7 +49,7 @@ def torch_to_numpy_tensor(torch_tensor):
48 49 
49 50 
50def bincount_golden(array, size, weight, **kwargs):51def bincount_golden(array, size, weight, **kwargs):
51- '''52+ """
52 Golden function for bincount.53 Golden function for bincount.
53 All the parameters (names and order) follow @bincount_def.cpp without outputs.54 All the parameters (names and order) follow @bincount_def.cpp without outputs.
54 All the input Tensors are numpy.ndarray.55 All the input Tensors are numpy.ndarray.
@@ -59,7 +60,7 @@ def bincount_golden(array, size, weight, **kwargs):
59 60 
60 Returns:61 Returns:
61 Output tensor62 Output tensor
62- '''63+ """
63 import torch64 import torch
64 65 
65 array_tensor = numpy_to_torch_tensor(array)66 array_tensor = numpy_to_torch_tensor(array)
@@ -72,3 +73,28 @@ def bincount_golden(array, size, weight, **kwargs):
72 res = torch.bincount(array_tensor, weights=weight_tensor, minlength=size)73 res = torch.bincount(array_tensor, weights=weight_tensor, minlength=size)
73 74 
74 return torch_to_numpy_tensor(res)75 return torch_to_numpy_tensor(res)
76+ 
77+ 
78+def aclnn_bincount_golden(self, weights, minlength, out, **kwargs):
79+ """
80+ Aclnn golden for aclnnBincount.
81+ All the parameters (name & order) follow \
82+ function `aclnnBincountGetWorkspaceSize` in @aclnn_bincount.h \
83+ without `workspaceSize` & `executor`.
84+ When all dtypes are natively supported by torch, \
85+ the Tensors in the parameters are all torch.Tensor. \
86+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
87+ 
88+ Args:
89+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
90+ 
91+ Returns:
92+ Output tensors.
93+ """
94+ import torch
95+ 
96+ if weights is None:
97+ res = torch.bincount(self, minlength=minlength)
98+ else:
99+ res = torch.bincount(self, weights=weights, minlength=minlength)
atomgit-bot
atomgit-botatomgit-bot23 天前

🟡 Medium Priority

changed line 98-101: 当 weights is None 时,aclnn_bincount_golden 调用 torch.bincount(self) 未传入 minlength 参数,导致 minlength 取默认值 0。

根据 ACLNN API 定义(aclnnBincountGetWorkspaceSize(const aclTensor* self, const aclTensor* weights, int64_t minlength, aclTensor* out, ...)),minlength 始终由调用方传入。当 weights=None 且调用方指定了非零 minlength(如 minlength=10)时,算子输出长度应为 minlength,但 golden 函数因未传递该参数,会按输入数组最大值自动确定输出长度,导致 golden 预期值与算子实际输出不一致,测试出现假阳性或假阴性。

触发条件:weights=Noneminlength > 0(或 minlength 大于输入数组最大值的任何值)。

建议:在 weights is None 分支中也传入 minlength=minlength,使两个分支的 minlength 行为一致。

改动建议
99
+ if weights is None:
100
+ res = torch.bincount(self, minlength=minlength)
101
+ else:
99
102
  res = torch.bincount(self, weights=weights, minlength=minlength)
应用建议
likedislike
100+ return res.to(out.dtype)
@@ -13,9 +13,8 @@
13import numpy13import numpy
14 14 
15__golden__ = {15__golden__ = {
16- "kernel": {16+ "kernel": {"div": "div_golden"},
17- "div": "div_golden"17+ "aclnn": {"aclnnDiv": "aclnn_div_golden"},
18- }
19}18}
20 19 
21 20 
@@ -27,10 +26,13 @@ def broadcast_to_maxshape(shapes: list):
27 else:26 else:
28 max_value = no_one_shape[0]27 max_value = no_one_shape[0]
29 return max_value28 return max_value
29+ 
30 max_dim_length = max(len(list(shape)) for shape in shapes)30 max_dim_length = max(len(list(shape)) for shape in shapes)
31 input_shapes = []31 input_shapes = []
32 for shape in shapes:32 for shape in shapes:
33- input_shapes.append([1 for _ in range(max_dim_length - len(shape))] + list(shape))33+ input_shapes.append(
34+ [1 for _ in range(max_dim_length - len(shape))] + list(shape)
35+ )
34 input_shapes = list(map(list, zip(*input_shapes)))36 input_shapes = list(map(list, zip(*input_shapes)))
35 max_shape = [_max(shape) for shape in input_shapes]37 max_shape = [_max(shape) for shape in input_shapes]
36 input_shapes = list(map(list, zip(*input_shapes)))38 input_shapes = list(map(list, zip(*input_shapes)))
@@ -38,7 +40,7 @@ def broadcast_to_maxshape(shapes: list):
38 40 
39 41 
40def div_golden(x1, x2, **kwargs):42def div_golden(x1, x2, **kwargs):
41- '''43+ """
42 Golden function for div.44 Golden function for div.
43 All the parameters (names and order) follow @div_def.cpp without outputs.45 All the parameters (names and order) follow @div_def.cpp without outputs.
44 All the input Tensors are numpy.ndarray.46 All the input Tensors are numpy.ndarray.
@@ -49,11 +51,11 @@ def div_golden(x1, x2, **kwargs):
49 51 
50 Returns:52 Returns:
51 Output tensor53 Output tensor
52- '''54+ """
53 ori_dtype = x1.dtype55 ori_dtype = x1.dtype
54- input_dtypes = kwargs.get('input_dtypes', [ori_dtype.name, ori_dtype.name])56+ input_dtypes = kwargs.get("input_dtypes", [ori_dtype.name, ori_dtype.name])
55- 57+ 
56- if "float16" in str(ori_dtype): #include bfloat16 & float1658+ if "float16" in str(ori_dtype): # include bfloat16 & float16
57 x1, x2 = x1.astype("float32"), x2.astype("float32")59 x1, x2 = x1.astype("float32"), x2.astype("float32")
58 60 
59 if "complex32" in input_dtypes:61 if "complex32" in input_dtypes:
@@ -98,7 +100,9 @@ def div_golden(x1, x2, **kwargs):
98 zreal = torch.zeros_like(input_xr)100 zreal = torch.zeros_like(input_xr)
99 zimag = torch.zeros_like(input_xr)101 zimag = torch.zeros_like(input_xr)
100 for i in range(len(input_xr)):102 for i in range(len(input_xr)):
101- zreal[i], zimag[i] = complex32_div(input_xr[i],input_xi[i], input_yr[i], input_yi[i])103+ zreal[i], zimag[i] = complex32_div(
104+ input_xr[i], input_xi[i], input_yr[i], input_yi[i]
105+ )
102 106 
103 zreal = zreal.numpy()107 zreal = zreal.numpy()
104 zimag = zimag.numpy()108 zimag = zimag.numpy()
@@ -108,6 +112,7 @@ def div_golden(x1, x2, **kwargs):
108 return res112 return res
109 else:113 else:
110 import tensorflow as tf114 import tensorflow as tf
115+ 
111 tf.compat.v1.disable_eager_execution()116 tf.compat.v1.disable_eager_execution()
112 _, _, shape_max = broadcast_to_maxshape([x1.shape, x2.shape])117 _, _, shape_max = broadcast_to_maxshape([x1.shape, x2.shape])
113 x1 = numpy.broadcast_to(x1, shape_max)118 x1 = numpy.broadcast_to(x1, shape_max)
@@ -122,3 +127,24 @@ def div_golden(x1, x2, **kwargs):
122 sess.run(init_op)127 sess.run(init_op)
123 res = sess.run(out, feed_dict=feed_dict)128 res = sess.run(out, feed_dict=feed_dict)
124 return res.astype(ori_dtype, copy=False)129 return res.astype(ori_dtype, copy=False)
130+ 
131+ 
132+def aclnn_div_golden(self, other, out, **kwargs):
133+ """
134+ Aclnn golden for aclnnDiv.
135+ All the parameters (name & order) follow \
136+ function `aclnnDivGetWorkspaceSize` in @aclnn_div.h \
137+ without `workspaceSize` & `executor`.
138+ When all dtypes are natively supported by torch, \
139+ the Tensors in the parameters are all torch.Tensor. \
140+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
141+ 
142+ Args:
143+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
144+ 
145+ Returns:
146+ Output tensors.
147+ """
148+ import torch
149+ 
150+ return torch.div(self, other)
@@ -0,0 +1,60 @@
1+#!/usr/bin/env python3
2+# -*- coding: UTF-8 -*-
3+# ----------------------------------------------------------------------------
4+# Copyright (c) 2026 Huawei Technologies Co., Ltd.
5+# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
6+# CANN Open Software License Agreement Version 2.0 (the "License").
7+# Please refer to the License for details. You may not use this file except in compliance with the License.
8+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
9+# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
10+# See LICENSE in the root of the software repository for the full text of the License.
11+# ----------------------------------------------------------------------------
12+ 
13+__golden__ = {
14+ "aclnn": {
15+ "aclnnEqTensor": "aclnn_eq_tensor_golden",
16+ "aclnnEqScalar": "aclnn_eq_scalar_golden",
17+ }
18+}
19+ 
20+ 
21+def aclnn_eq_tensor_golden(self, other, out, **kwargs):
22+ """
23+ Aclnn golden for aclnnEqTensor.
24+ All the parameters (name & order) follow \
25+ function `aclnnEqTensorGetWorkspaceSize` in @aclnn_eq_tensor.h \
26+ without `workspaceSize` & `executor`.
27+ When all dtypes are natively supported by torch, \
28+ the Tensors in the parameters are all torch.Tensor. \
29+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
30+ 
31+ Args:
32+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
33+ 
34+ Returns:
35+ Output tensors.
36+ """
37+ import torch
38+ 
39+ return torch.eq(self, other)
40+ 
41+ 
42+def aclnn_eq_scalar_golden(self, other, out, **kwargs):
43+ """
44+ Aclnn golden for aclnnEqScalar.
45+ All the parameters (name & order) follow \
46+ function `aclnnEqScalarGetWorkspaceSize` in @aclnn_eq_scalar.h \
47+ without `workspaceSize` & `executor`.
48+ When all dtypes are natively supported by torch, \
49+ the Tensors in the parameters are all torch.Tensor. \
50+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
51+ 
52+ Args:
53+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
54+ 
55+ Returns:
56+ Output tensors.
57+ """
58+ import torch
59+ 
60+ return torch.eq(self, other)
@@ -9,28 +9,26 @@
9# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.9# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
10# See LICENSE in the root of the software repository for the full text of the License.10# See LICENSE in the root of the software repository for the full text of the License.
11# ----------------------------------------------------------------------------11# ----------------------------------------------------------------------------
12-import numpy as np
13import torch12import torch
14 13 
15__golden__ = {14__golden__ = {
16- "kernel": {15+ "kernel": {"lerp": "lerp_golden"},
17- "lerp": "lerp_golden"16+ "aclnn": {"aclnnLerp": "aclnn_lerp_golden", "aclnnLerps": "aclnn_lerps_golden"},
18- }
19}17}
20- 18+ 
21-def lerp_golden(start, end, weight,19+ 
22- **kwargs):20+def lerp_golden(start, end, weight, **kwargs):
23- '''21+ """
24 Kernel golden for lerp.22 Kernel golden for lerp.
25 All the parameters follow @lerp_def.cpp without outputs.23 All the parameters follow @lerp_def.cpp without outputs.
26 All the input Tensors are numpy.ndarray.24 All the input Tensors are numpy.ndarray.
27- kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes, 25+ kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes,
28- input_formats, output_formats, input_ori_formats, output_ori_formats,26+ input_formats, output_formats, input_ori_formats, output_ori_formats,
29- input_dtypes, output_dtypes.27+ input_dtypes, output_dtypes.
30- '''28+ """
31- 29+ 
32 dtype = start.dtype30 dtype = start.dtype
33- 31+ 
34 if "bfloat16" in str(start.dtype):32 if "bfloat16" in str(start.dtype):
35 start = start.astype("float32")33 start = start.astype("float32")
36 if "bfloat16" in str(end.dtype):34 if "bfloat16" in str(end.dtype):
@@ -41,6 +39,48 @@ def lerp_golden(start, end, weight,
41 start_tensor = torch.from_numpy(start).to(torch.float32)39 start_tensor = torch.from_numpy(start).to(torch.float32)
42 end_tensor = torch.from_numpy(end).to(torch.float32)40 end_tensor = torch.from_numpy(end).to(torch.float32)
43 weight_tensor = torch.from_numpy(weight).to(torch.float32)41 weight_tensor = torch.from_numpy(weight).to(torch.float32)
44- 42+ 
45 golden = torch.lerp(start_tensor, end_tensor, weight_tensor).numpy()43 golden = torch.lerp(start_tensor, end_tensor, weight_tensor).numpy()
46 return golden.astype(dtype, copy=False)44 return golden.astype(dtype, copy=False)
45+ 
46+ 
47+def aclnn_lerp_golden(self, end, weight, out, **kwargs):
48+ """
49+ Aclnn golden for aclnnLerp.
50+ All the parameters (name & order) follow \
51+ function `aclnnLerpGetWorkspaceSize` in @aclnn_lerp_tensor.h \
52+ without `workspaceSize` & `executor`.
53+ When all dtypes are natively supported by torch, \
54+ the Tensors in the parameters are all torch.Tensor. \
55+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
56+ 
57+ Args:
58+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
59+ 
60+ Returns:
61+ Output tensors.
62+ """
63+ import torch
64+ 
65+ return torch.lerp(self, end, weight)
66+ 
67+ 
68+def aclnn_lerps_golden(self, end, weight, out, **kwargs):
69+ """
70+ Aclnn golden for aclnnLerps.
71+ All the parameters (name & order) follow \
72+ function `aclnnLerpsGetWorkspaceSize` in @aclnn_lerp_scalar.h \
73+ without `workspaceSize` & `executor`.
74+ When all dtypes are natively supported by torch, \
75+ the Tensors in the parameters are all torch.Tensor. \
76+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
77+ 
78+ Args:
79+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
80+ 
81+ Returns:
82+ Output tensors.
83+ """
84+ import torch
85+ 
86+ return torch.lerp(self, end, weight)
@@ -0,0 +1,34 @@
1+#!/usr/bin/env python3
2+# -*- coding: UTF-8 -*-
3+# ----------------------------------------------------------------------------
4+# Copyright (c) 2026 Huawei Technologies Co., Ltd.
5+# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
6+# CANN Open Software License Agreement Version 2.0 (the "License").
7+# Please refer to the License for details. You may not use this file except in compliance with the License.
8+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
9+# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
10+# See LICENSE in the root of the software repository for the full text of the License.
11+# ----------------------------------------------------------------------------
12+ 
13+__golden__ = {"aclnn": {"aclnnLinspace": "aclnn_linspace_golden"}}
14+ 
15+ 
16+def aclnn_linspace_golden(start, end, steps, out, **kwargs):
17+ """
18+ Aclnn golden for aclnnLinspace.
19+ All the parameters (name & order) follow \
20+ function `aclnnLinspaceGetWorkspaceSize` in @aclnn_linspace.h \
21+ without `workspaceSize` & `executor`.
22+ When all dtypes are natively supported by torch, \
23+ the Tensors in the parameters are all torch.Tensor. \
24+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
25+ 
26+ Args:
27+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
28+ 
29+ Returns:
30+ Output tensors.
31+ """
32+ import torch
33+ 
34+ return torch.linspace(start, end, steps, dtype=out.dtype)
@@ -12,24 +12,44 @@
12import numpy as np12import numpy as np
13 13 
14__golden__ = {14__golden__ = {
15- "kernel": {15+ "kernel": {"logical_and": "logical_and_golden"},
16- "logical_and": "logical_and_golden"16+ "aclnn": {"aclnnLogicalAnd": "aclnn_logical_and_golden"},
17- }
18}17}
19- 18+ 
20-def logical_and_golden(x1, x2,19+ 
21- **kwargs):20+def logical_and_golden(x1, x2, **kwargs):
22- '''21+ """
23 Kernel golden for logical_and.22 Kernel golden for logical_and.
24 All the parameters follow @logical_and_def.cpp without outputs.23 All the parameters follow @logical_and_def.cpp without outputs.
25 All the input Tensors are numpy.ndarray.24 All the input Tensors are numpy.ndarray.
26- kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes, 25+ kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes,
27- input_formats, output_formats, input_ori_formats, output_ori_formats,26+ input_formats, output_formats, input_ori_formats, output_ori_formats,
28- input_dtypes, output_dtypes.27+ input_dtypes, output_dtypes.
29- '''28+ """
30 shape_list = np.broadcast_shapes(x1.shape, x2.shape)29 shape_list = np.broadcast_shapes(x1.shape, x2.shape)
31 x1 = x1.astype("float16")30 x1 = x1.astype("float16")
32 x2 = x2.astype("float16")31 x2 = x2.astype("float16")
33 x1 = np.broadcast_to(x1, shape_list)32 x1 = np.broadcast_to(x1, shape_list)
34 x2 = np.broadcast_to(x2, shape_list)33 x2 = np.broadcast_to(x2, shape_list)
35 return np.multiply(x1, x2).astype("int8")34 return np.multiply(x1, x2).astype("int8")
35+ 
36+ 
37+def aclnn_logical_and_golden(self, other, out, **kwargs):
38+ """
39+ Aclnn golden for aclnnLogicalAnd.
40+ All the parameters (name & order) follow \
41+ function `aclnnLogicalAndGetWorkspaceSize` in @aclnn_logical_and.h \
42+ without `workspaceSize` & `executor`.
43+ When all dtypes are natively supported by torch, \
44+ the Tensors in the parameters are all torch.Tensor. \
45+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
46+ 
47+ Args:
48+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
49+ 
50+ Returns:
51+ Output tensors.
52+ """
53+ import torch
54+ 
55+ return torch.logical_and(self, other)
@@ -12,24 +12,44 @@
12import numpy as np12import numpy as np
13 13 
14__golden__ = {14__golden__ = {
15- "kernel": {15+ "kernel": {"logical_or": "logical_or_golden"},
16- "logical_or": "logical_or_golden"16+ "aclnn": {"aclnnLogicalOr": "aclnn_logical_or_golden"},
17- }
18}17}
19- 18+ 
20-def logical_or_golden(x1, x2,19+ 
21- **kwargs):20+def logical_or_golden(x1, x2, **kwargs):
22- '''21+ """
23 Kernel golden for logical_or.22 Kernel golden for logical_or.
24 All the parameters follow @logical_or_def.cpp without outputs.23 All the parameters follow @logical_or_def.cpp without outputs.
25 All the input Tensors are numpy.ndarray.24 All the input Tensors are numpy.ndarray.
26- kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes, 25+ kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes,
27- input_formats, output_formats, input_ori_formats, output_ori_formats,26+ input_formats, output_formats, input_ori_formats, output_ori_formats,
28- input_dtypes, output_dtypes.27+ input_dtypes, output_dtypes.
29- '''28+ """
30 shape_list = np.broadcast_shapes(x1.shape, x2.shape)29 shape_list = np.broadcast_shapes(x1.shape, x2.shape)
31 x1 = x1.astype("float16")30 x1 = x1.astype("float16")
32 x2 = x2.astype("float16")31 x2 = x2.astype("float16")
33 x1 = np.broadcast_to(x1, shape_list)32 x1 = np.broadcast_to(x1, shape_list)
34 x2 = np.broadcast_to(x2, shape_list)33 x2 = np.broadcast_to(x2, shape_list)
35 return np.maximum(x1, x2).astype("int8")34 return np.maximum(x1, x2).astype("int8")
35+ 
36+ 
37+def aclnn_logical_or_golden(self, other, out, **kwargs):
38+ """
39+ Aclnn golden for aclnnLogicalOr.
40+ All the parameters (name & order) follow \
41+ function `aclnnLogicalOrGetWorkspaceSize` in @aclnn_logical_or.h \
42+ without `workspaceSize` & `executor`.
43+ When all dtypes are natively supported by torch, \
44+ the Tensors in the parameters are all torch.Tensor. \
45+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
46+ 
47+ Args:
48+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
49+ 
50+ Returns:
51+ Output tensors.
52+ """
53+ import torch
54+ 
55+ return torch.logical_or(self, other)
@@ -9,30 +9,28 @@
9# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.9# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
10# See LICENSE in the root of the software repository for the full text of the License.10# See LICENSE in the root of the software repository for the full text of the License.
11# ----------------------------------------------------------------------------11# ----------------------------------------------------------------------------
12-import numpy as np
13import torch12import torch
14 13 
15__golden__ = {14__golden__ = {
16- "kernel": {15+ "kernel": {"maximum": "maximum_golden"},
17- "maximum": "maximum_golden"16+ "aclnn": {"aclnnMaximum": "aclnn_maximum_golden"},
18- }
19}17}
20- 18+ 
21-def maximum_golden(x1, x2,19+ 
22- **kwargs):20+def maximum_golden(x1, x2, **kwargs):
23- '''21+ """
24 Kernel golden for maximum.22 Kernel golden for maximum.
25 All the parameters follow @maximum_def.cpp without outputs.23 All the parameters follow @maximum_def.cpp without outputs.
26 All the input Tensors are numpy.ndarray.24 All the input Tensors are numpy.ndarray.
27- kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes, 25+ kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes,
28- input_formats, output_formats, input_ori_formats, output_ori_formats,26+ input_formats, output_formats, input_ori_formats, output_ori_formats,
29- input_dtypes, output_dtypes.27+ input_dtypes, output_dtypes.
30- '''28+ """
31 dtype = x1.dtype29 dtype = x1.dtype
32 if "bfloat16" in str(dtype):30 if "bfloat16" in str(dtype):
33 x1 = x1.astype("float32")31 x1 = x1.astype("float32")
34 x2 = x2.astype("float32")32 x2 = x2.astype("float32")
35- 33+ 
36 x = torch.from_numpy(x1)34 x = torch.from_numpy(x1)
37 y = torch.from_numpy(x2)35 y = torch.from_numpy(x2)
38 res = torch.maximum(x, y).numpy()36 res = torch.maximum(x, y).numpy()
@@ -40,3 +38,24 @@ def maximum_golden(x1, x2,
40 if "bfloat16" in str(dtype):38 if "bfloat16" in str(dtype):
41 res = res.astype(dtype)39 res = res.astype(dtype)
42 return res40 return res
41+ 
42+ 
43+def aclnn_maximum_golden(self, other, out, **kwargs):
44+ """
45+ Aclnn golden for aclnnMaximum.
46+ All the parameters (name & order) follow \
47+ function `aclnnMaximumGetWorkspaceSize` in @aclnn_maximum.h \
48+ without `workspaceSize` & `executor`.
49+ When all dtypes are natively supported by torch, \
50+ the Tensors in the parameters are all torch.Tensor. \
51+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
52+ 
53+ Args:
54+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
55+ 
56+ Returns:
57+ Output tensors.
58+ """
59+ import torch
60+ 
61+ return torch.maximum(self, other)
@@ -9,30 +9,28 @@
9# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.9# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
10# See LICENSE in the root of the software repository for the full text of the License.10# See LICENSE in the root of the software repository for the full text of the License.
11# ----------------------------------------------------------------------------11# ----------------------------------------------------------------------------
12-import numpy as np
13import torch12import torch
14 13 
15__golden__ = {14__golden__ = {
16- "kernel": {15+ "kernel": {"minimum": "minimum_golden"},
17- "minimum": "minimum_golden"16+ "aclnn": {"aclnnMinimum": "aclnn_minimum_golden"},
18- }
19}17}
20- 18+ 
21-def minimum_golden(x1, x2,19+ 
22- **kwargs):20+def minimum_golden(x1, x2, **kwargs):
23- '''21+ """
24 Kernel golden for minimum.22 Kernel golden for minimum.
25 All the parameters follow @minimum_def.cpp without outputs.23 All the parameters follow @minimum_def.cpp without outputs.
26 All the input Tensors are numpy.ndarray.24 All the input Tensors are numpy.ndarray.
27- kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes, 25+ kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes,
28- input_formats, output_formats, input_ori_formats, output_ori_formats,26+ input_formats, output_formats, input_ori_formats, output_ori_formats,
29- input_dtypes, output_dtypes.27+ input_dtypes, output_dtypes.
30- '''28+ """
31 dtype = x1.dtype29 dtype = x1.dtype
32 if "bfloat16" in str(dtype):30 if "bfloat16" in str(dtype):
33 x1 = x1.astype("float32")31 x1 = x1.astype("float32")
34 x2 = x2.astype("float32")32 x2 = x2.astype("float32")
35- 33+ 
36 x = torch.from_numpy(x1)34 x = torch.from_numpy(x1)
37 y = torch.from_numpy(x2)35 y = torch.from_numpy(x2)
38 res = torch.minimum(x, y).numpy()36 res = torch.minimum(x, y).numpy()
@@ -40,3 +38,24 @@ def minimum_golden(x1, x2,
40 if "bfloat16" in str(dtype):38 if "bfloat16" in str(dtype):
41 res = res.astype(dtype)39 res = res.astype(dtype)
42 return res40 return res
41+ 
42+ 
43+def aclnn_minimum_golden(self, other, out, **kwargs):
44+ """
45+ Aclnn golden for aclnnMinimum.
46+ All the parameters (name & order) follow \
47+ function `aclnnMinimumGetWorkspaceSize` in @aclnn_minimum.h \
48+ without `workspaceSize` & `executor`.
49+ When all dtypes are natively supported by torch, \
50+ the Tensors in the parameters are all torch.Tensor. \
51+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
52+ 
53+ Args:
54+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
55+ 
56+ Returns:
57+ Output tensors.
58+ """
59+ import torch
60+ 
61+ return torch.minimum(self, other)
@@ -12,13 +12,14 @@
12import numpy12import numpy
13 13 
14__golden__ = {14__golden__ = {
15- "kernel": {15+ "kernel": {"muls": "muls_golden"},
16- "muls": "muls_golden"16+ "aclnn": {"aclnnMuls": "aclnn_muls_golden"},
17- }
18}17}
19 18 
19+ 
20def numpy_to_torch_tensor(np_array):20def numpy_to_torch_tensor(np_array):
21 import torch21 import torch
22+ 
22 if np_array is None:23 if np_array is None:
23 return None24 return None
24 np_dtype = np_array.dtype.name25 np_dtype = np_array.dtype.name
@@ -32,6 +33,7 @@ def numpy_to_torch_tensor(np_array):
32 33 
33def torch_to_numpy_tensor(torch_tensor):34def torch_to_numpy_tensor(torch_tensor):
34 import torch35 import torch
36+ 
35 if torch_tensor is None:37 if torch_tensor is None:
36 return None38 return None
37 if not isinstance(torch_tensor, torch.Tensor):39 if not isinstance(torch_tensor, torch.Tensor):
@@ -42,15 +44,16 @@ def torch_to_numpy_tensor(torch_tensor):
42 else:44 else:
43 return torch_tensor.numpy()45 return torch_tensor.numpy()
44 46 
47+ 
45def muls_golden(x, value, **kwargs):48def muls_golden(x, value, **kwargs):
46- '''49+ """
47 Kernel golden for muls.50 Kernel golden for muls.
48 All the parameters follow @muls_def.cpp without outputs.51 All the parameters follow @muls_def.cpp without outputs.
49 All the input Tensors are numpy.ndarray.52 All the input Tensors are numpy.ndarray.
50 kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes,53 kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes,
51- input_formats, output_formats, input_ori_formats, output_ori_formats,54+ input_formats, output_formats, input_ori_formats, output_ori_formats,
52- input_dtypes, output_dtypes.55+ input_dtypes, output_dtypes.
53- '''56+ """
54 import torch57 import torch
55 58 
56 x_torch = numpy_to_torch_tensor(x)59 x_torch = numpy_to_torch_tensor(x)
@@ -60,3 +63,24 @@ def muls_golden(x, value, **kwargs):
60 res_np = torch_to_numpy_tensor(res)63 res_np = torch_to_numpy_tensor(res)
61 64 
62 return res_np.astype(x.dtype, copy=False)65 return res_np.astype(x.dtype, copy=False)
66+ 
67+ 
68+def aclnn_muls_golden(self, other, out, **kwargs):
69+ """
70+ Aclnn golden for aclnnMuls.
71+ All the parameters (name & order) follow \
72+ function `aclnnMulsGetWorkspaceSize` in @aclnn_muls.h \
73+ without `workspaceSize` & `executor`.
74+ When all dtypes are natively supported by torch, \
75+ the Tensors in the parameters are all torch.Tensor. \
76+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
77+ 
78+ Args:
79+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
80+ 
81+ Returns:
82+ Output tensors.
83+ """
84+ import torch
85+ 
86+ return torch.mul(self, other)
@@ -13,31 +13,103 @@ import numpy as np
13import torch13import torch
14 14 
15__golden__ = {15__golden__ = {
16- "kernel": {16+ "kernel": {"one_hot": "one_hot_golden"},
17- "one_hot": "one_hot_golden"17+ "aclnn": {"aclnnOneHot": "aclnn_one_hot_golden"},
18- }
19}18}
20- 19+ 
21-def one_hot_golden(x, depth, on_value, off_value,20+ 
22- axis: int=-1,21+def one_hot_golden(x, depth, on_value, off_value, axis: int = -1, **kwargs):
23- **kwargs):22+ """
24- '''
25 Kernel golden for one_hot.23 Kernel golden for one_hot.
26 All the parameters follow @one_hot_def.cpp without outputs.24 All the parameters follow @one_hot_def.cpp without outputs.
27 All the input Tensors are numpy.ndarray.25 All the input Tensors are numpy.ndarray.
28- kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes, 26+ kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes,
29- input_formats, output_formats, input_ori_formats, output_ori_formats,27+ input_formats, output_formats, input_ori_formats, output_ori_formats,
30- input_dtypes, output_dtypes.28+ input_dtypes, output_dtypes.
31- '''29+ """
32 import tensorflow.compat.v1 as tf30 import tensorflow.compat.v1 as tf
33 from tensorflow.python.ops import gen_array_ops31 from tensorflow.python.ops import gen_array_ops
32+ 
34 tf.disable_eager_execution()33 tf.disable_eager_execution()
35 34 
36 data_dtype = on_value.dtype35 data_dtype = on_value.dtype
37 on_value_const = tf.constant(on_value, shape=(), dtype=data_dtype)36 on_value_const = tf.constant(on_value, shape=(), dtype=data_dtype)
38 off_value_const = tf.constant(off_value, shape=(), dtype=data_dtype)37 off_value_const = tf.constant(off_value, shape=(), dtype=data_dtype)
39 axis = max(axis, -1)38 axis = max(axis, -1)
40- out = gen_array_ops.one_hot(x, max(int(depth), 0), on_value_const, off_value_const, axis)39+ out = gen_array_ops.one_hot(
40+ x, max(int(depth), 0), on_value_const, off_value_const, axis
41+ )
41 with tf.Session() as sess:42 with tf.Session() as sess:
42 res = sess.run(out)43 res = sess.run(out)
43 return res44 return res
45+ 
46+ 
47+def _to_torch_tensor(arr):
48+ """Convert numpy.ndarray (incl. bfloat16) to torch.Tensor."""
49+ if arr is None:
50+ return None
51+ if isinstance(arr, torch.Tensor):
52+ return arr
53+ np_dtype = arr.dtype.name
54+ if "bfloat16" in np_dtype:
55+ return torch.from_numpy(arr.view(np.int16)).view(torch.bfloat16)
56+ return torch.from_numpy(arr)
57+ 
58+ 
59+def _scalar_value(t):
60+ """Extract Python scalar from 0-dim / 1-elem tensor or ndarray."""
61+ if isinstance(t, (torch.Tensor,)):
62+ return t.item() if t.numel() == 1 else t.flatten()[0].item()
63+ if isinstance(t, np.ndarray):
64+ return t.item() if t.size == 1 else t.flatten()[0].item()
65+ return t
66+ 
67+ 
68+def aclnn_one_hot_golden(self, numClasses, onValue, offValue, axis, out, **kwargs):
69+ """
70+ Aclnn golden for aclnnOneHot.
71+ Params (name & order) follow aclnnOneHotGetWorkspaceSize in @aclnn_one_hot.h
72+ without workspaceSize & executor:
73+ (self, numClasses, onValue, offValue, axis, out)
74+ All params are passed positionally by the framework (including output `out`).
75+ - self/onValue/offValue/out: tensors (torch.Tensor or numpy.ndarray).
76+ - numClasses/axis: C int/int64_t values.
77+ Returns: output tensor matching NPU aclnnOneHot semantics.
78+ """
79+ idx = _to_torch_tensor(self)
80+ on_v = _scalar_value(
81+ onValue if isinstance(onValue, (torch.Tensor, np.ndarray)) else onValue
82+ )
83+ off_v = _scalar_value(
84+ offValue if isinstance(offValue, (torch.Tensor, np.ndarray)) else offValue
85+ )
86+ 
87+ # Infer output dtype from out tensor (authoritative), fallback to onValue.
88+ if out is not None:
89+ out_t = _to_torch_tensor(out)
90+ out_dtype = out_t.dtype if out_t is not None else torch.get_default_dtype()
91+ elif isinstance(onValue, (torch.Tensor, np.ndarray)):
92+ out_dtype = _to_torch_tensor(onValue).dtype
93+ else:
94+ out_dtype = torch.get_default_dtype()
95+ 
96+ depth = max(int(numClasses), 0)
97+ idx_long = idx.long()
98+ # NPU kernel treats out-of-range indices (< 0 or >= depth) as off_value.
99+ # torch.nn.functional.one_hot raises on out-of-range, so mark invalid
100+ # indices with a sentinel (depth, which is out-of-range for one_hot) and
101+ # use a mask to set those positions to off_value afterwards.
102+ invalid_mask = (idx_long < 0) | (idx_long >= depth)
103+ idx_safe = idx_long.clamp(0, max(depth - 1, 0))
104+ oh = torch.nn.functional.one_hot(idx_safe, depth) # [..., depth], int64
105+ result = torch.where(
106+ oh.bool(),
107+ torch.tensor(on_v, dtype=out_dtype),
108+ torch.tensor(off_v, dtype=out_dtype),
109+ )
110+ # Overwrite positions where the original index was out-of-range with off_value.
111+ if invalid_mask.any():
112+ result[invalid_mask] = off_v
113+ # one_hot appends new dim at -1; move to the specified axis.
114+ result = torch.movedim(result, -1, int(axis))
115+ return result
@@ -13,37 +13,34 @@ import numpy as np
13import torch13import torch
14 14 
15__golden__ = {15__golden__ = {
16- "kernel": {16+ "kernel": {"range": "_range_golden"},
17- "range": "_range_golden"17+ "aclnn": {"aclnnArange": "aclnn_arange_golden", "aclnnRange": "aclnn_range_golden"},
18- },
19- "aclnn": {
20- "aclnnArange": "aclnn_arange_golden",
21- "aclnnRange": "aclnn_range_golden"
22- }
23}18}
24 19 
20+ 
25def _bfloat16_conversion(dtypes):21def _bfloat16_conversion(dtypes):
26 result = []22 result = []
27 for dt in dtypes:23 for dt in dtypes:
28- if 'bfloat16' in str(dt):24+ if "bfloat16" in str(dt):
29- result.append(np.dtype('bfloat16'))25+ result.append(np.dtype("bfloat16"))
30 else:26 else:
31 result.append(dt)27 result.append(dt)
32 return result28 return result
33 29 
30+ 
34def _torch_dtype_conversion(dtypes):31def _torch_dtype_conversion(dtypes):
35 mapping = {32 mapping = {
36- 'float16': torch.float16,33+ "float16": torch.float16,
37- 'float32': torch.float,34+ "float32": torch.float,
38- 'float': torch.float,35+ "float": torch.float,
39- 'int32': torch.int32,36+ "int32": torch.int32,
40- 'int64': torch.int64,37+ "int64": torch.int64,
41- 'bfloat16': torch.bfloat16,38+ "bfloat16": torch.bfloat16,
42- 'double': torch.double,39+ "double": torch.double,
43 }40 }
44 result = []41 result = []
45 for dt in dtypes:42 for dt in dtypes:
46- dt_str = str(dt) if hasattr(dt, '__str__') else dt43+ dt_str = str(dt) if hasattr(dt, "__str__") else dt
47 for key in mapping:44 for key in mapping:
48 if key in dt_str.lower():45 if key in dt_str.lower():
49 result.append(mapping[key])46 result.append(mapping[key])
@@ -52,8 +49,9 @@ def _torch_dtype_conversion(dtypes):
52 result.append(torch.float)49 result.append(torch.float)
53 return result50 return result
54 51 
52+ 
55def _range_golden(start, limit, delta, *, is_closed=False, **kwargs):53def _range_golden(start, limit, delta, *, is_closed=False, **kwargs):
56- '''54+ """
57 Golden function for range kernel.55 Golden function for range kernel.
58 All the parameters (names and order) follow range_def.cpp without outputs.56 All the parameters (names and order) follow range_def.cpp without outputs.
59 All the input Tensors are numpy.ndarray.57 All the input Tensors are numpy.ndarray.
@@ -64,36 +62,53 @@ def _range_golden(start, limit, delta, *, is_closed=False, **kwargs):
64 62 
65 Returns:63 Returns:
66 Output tensor with range values64 Output tensor with range values
67- '''65+ """
68- output_dtypes = kwargs.get('output_dtypes', ['float32'])66+ output_dtypes = kwargs.get("output_dtypes", ["float32"])
69- input_dtypes = kwargs.get('input_dtypes', ['float32'])67+ input_dtypes = kwargs.get("input_dtypes", ["float32"])
70- 68+ 
71 src_type = _bfloat16_conversion(output_dtypes)[0]69 src_type = _bfloat16_conversion(output_dtypes)[0]
72 torch_dtype = _torch_dtype_conversion(output_dtypes)[0]70 torch_dtype = _torch_dtype_conversion(output_dtypes)[0]
73 input_dtypes_torch = _torch_dtype_conversion(input_dtypes)71 input_dtypes_torch = _torch_dtype_conversion(input_dtypes)
74- 72+ 
75 start_val = torch.tensor(start, dtype=input_dtypes_torch[0]).item()73 start_val = torch.tensor(start, dtype=input_dtypes_torch[0]).item()
76 stop_val = torch.tensor(limit, dtype=input_dtypes_torch[1]).item()74 stop_val = torch.tensor(limit, dtype=input_dtypes_torch[1]).item()
77 step_val = torch.tensor(delta, dtype=input_dtypes_torch[2]).item()75 step_val = torch.tensor(delta, dtype=input_dtypes_torch[2]).item()
78 76 
79- if step_val == 0 or (step_val > 0 and start_val > stop_val) or (step_val < 0 and start_val < stop_val):77+ if (
78+ step_val == 0
79+ or (step_val > 0 and start_val > stop_val)
80+ or (step_val < 0 and start_val < stop_val)
81+ ):
80 return np.array([], dtype=src_type)82 return np.array([], dtype=src_type)
81 83 
82 if "bfloat16" in str(src_type):84 if "bfloat16" in str(src_type):
83 if is_closed:85 if is_closed:
84- golden = torch.range(start_val, stop_val, step_val, dtype=torch_dtype).float().numpy()86+ golden = (
87+ torch.range(start_val, stop_val, step_val, dtype=torch_dtype)
88+ .float()
89+ .numpy()
90+ )
85 else:91 else:
86- golden = torch.arange(start_val, stop_val, step_val, dtype=torch_dtype).float().numpy()92+ golden = (
93+ torch.arange(start_val, stop_val, step_val, dtype=torch_dtype)
94+ .float()
95+ .numpy()
96+ )
87 else:97 else:
88 if is_closed:98 if is_closed:
89- golden = torch.range(start_val, stop_val, step_val, dtype=torch_dtype).numpy()99+ golden = torch.range(
100+ start_val, stop_val, step_val, dtype=torch_dtype
101+ ).numpy()
90 else:102 else:
91- golden = torch.arange(start_val, stop_val, step_val, dtype=torch_dtype).numpy()103+ golden = torch.arange(
92- 104+ start_val, stop_val, step_val, dtype=torch_dtype
105+ ).numpy()
106+ 
93 return golden.astype(src_type)107 return golden.astype(src_type)
94 108 
109+ 
95def aclnn_arange_golden(start, end, step, out, **kwargs):110def aclnn_arange_golden(start, end, step, out, **kwargs):
96- '''111+ """
97 Aclnn golden for aclnnArange.112 Aclnn golden for aclnnArange.
98 All the parameters (name & order) follow \113 All the parameters (name & order) follow \
99 function `aclnnArangeGetWorkspaceSize` in @aclnn_arange.h \114 function `aclnnArangeGetWorkspaceSize` in @aclnn_arange.h \
@@ -107,11 +122,12 @@ def aclnn_arange_golden(start, end, step, out, **kwargs):
107 122 
108 Returns:123 Returns:
109 Output tensors.124 Output tensors.
110- '''125+ """
111 return torch.arange(start, end, step, dtype=out.dtype)126 return torch.arange(start, end, step, dtype=out.dtype)
112 127 
113-def aclnn_range_golden(start, limit, delta, is_closed, out, **kwargs):128+ 
114- '''129+def aclnn_range_golden(start, end, step, out, **kwargs):
130+ """
115 Aclnn golden for aclnnRange.131 Aclnn golden for aclnnRange.
116 All the parameters (name & order) follow \132 All the parameters (name & order) follow \
117 function `aclnnRangeGetWorkspaceSize` in @aclnn_range.h \133 function `aclnnRangeGetWorkspaceSize` in @aclnn_range.h \
@@ -125,8 +141,5 @@ def aclnn_range_golden(start, limit, delta, is_closed, out, **kwargs):
125 141 
126 Returns:142 Returns:
127 Output tensors.143 Output tensors.
128- '''144+ """
129- if is_closed:145+ return torch.range(start, end, step, dtype=out.dtype)
130- return torch.range(start, limit, delta, dtype=out.dtype)
131- else:
132- return torch.arange(start, limit, delta, dtype=out.dtype)
@@ -0,0 +1,34 @@
1+#!/usr/bin/env python3
2+# -*- coding: UTF-8 -*-
3+# ----------------------------------------------------------------------------
4+# Copyright (c) 2026 Huawei Technologies Co., Ltd.
5+# This program is free software, you can redistribute it and/or modify it under the terms and conditions of
6+# CANN Open Software License Agreement Version 2.0 (the "License").
7+# Please refer to the License for details. You may not use this file except in compliance with the License.
8+# THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
9+# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
10+# See LICENSE in the root of the software repository for the full text of the License.
11+# ----------------------------------------------------------------------------
12+ 
13+__golden__ = {"aclnn": {"aclnnSignbit": "aclnn_signbit_golden"}}
14+ 
15+ 
16+def aclnn_signbit_golden(self, out, **kwargs):
17+ """
18+ Aclnn golden for aclnnSignbit.
19+ All the parameters (name & order) follow \
20+ function `aclnnSignbitGetWorkspaceSize` in @aclnn_signbit.h \
21+ without `workspaceSize` & `executor`.
22+ When all dtypes are natively supported by torch, \
23+ the Tensors in the parameters are all torch.Tensor. \
24+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
25+ 
26+ Args:
27+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
28+ 
29+ Returns:
30+ Output tensors.
31+ """
32+ import torch
33+ 
34+ return torch.signbit(self)
@@ -9,23 +9,22 @@
9# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.9# INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
10# See LICENSE in the root of the software repository for the full text of the License.10# See LICENSE in the root of the software repository for the full text of the License.
11# ----------------------------------------------------------------------------11# ----------------------------------------------------------------------------
12-import numpy
13 12 
14__golden__ = {13__golden__ = {
15- "kernel": {14+ "kernel": {"sub": "sub_golden"},
16- "sub": "sub_golden"15+ "aclnn": {"aclnnSub": "aclnn_sub_golden"},
17- }
18}16}
19 17 
18+ 
20def sub_golden(x1, x2, **kwargs):19def sub_golden(x1, x2, **kwargs):
21- '''20+ """
22 Kernel golden for sub.21 Kernel golden for sub.
23 All the parameters follow @sub_def.cpp without outputs.22 All the parameters follow @sub_def.cpp without outputs.
24 All the input Tensors are numpy.ndarray.23 All the input Tensors are numpy.ndarray.
25 kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes,24 kwargs may contain: short_soc_version, input_ori_shapes, output_ori_shapes,
26- input_formats, output_formats, input_ori_formats, output_ori_formats,25+ input_formats, output_formats, input_ori_formats, output_ori_formats,
27- input_dtypes, output_dtypes.26+ input_dtypes, output_dtypes.
28- '''27+ """
29 import torch28 import torch
30 29 
31 dtype = x1.dtype30 dtype = x1.dtype
@@ -42,3 +41,24 @@ def sub_golden(x1, x2, **kwargs):
42 res = res.astype(dtype)41 res = res.astype(dtype)
43 42 
44 return res43 return res
44+ 
45+ 
46+def aclnn_sub_golden(self, other, alpha, out, **kwargs):
47+ """
48+ Aclnn golden for aclnnSub.
49+ All the parameters (name & order) follow \
50+ function `aclnnSubGetWorkspaceSize` in @aclnn_sub.h \
51+ without `workspaceSize` & `executor`.
52+ When all dtypes are natively supported by torch, \
53+ the Tensors in the parameters are all torch.Tensor. \
54+ Conversely, when not, the Tensors in the parameters are all numpy.ndarray.
55+ 
56+ Args:
57+ kwargs: tensor_{dtypes, formats}, scalar_dtypes, short_soc_version, testcase_name
58+ 
59+ Returns:
60+ Output tensors.
61+ """
62+ import torch
63+ 
64+ return torch.sub(self, other, alpha=alpha)