已合并
add aclnn golden #4593
fengdaoyong创建于 23 天前
add aclnn golden #4593
已合并
共 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 | |||
| 13 | import torch | 13 | import 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.dtype | 30 | 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_np | 40 | 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 @@ | |||
| 12 | import numpy | 12 | import 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 torch | 29 | import torch |
| 31 | from ml_dtypes import bfloat16 | 30 | 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_np | 46 | 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 @@ | |||
| 13 | import numpy as np | 13 | import 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 | ||
| 22 | def numpy_to_torch_tensor(np_array): | 21 | def numpy_to_torch_tensor(np_array): |
| 23 | import torch | 22 | import torch |
| 23 | + | ||
| 24 | if np_array is None: | 24 | if np_array is None: |
| 25 | return None | 25 | return None |
| 26 | np_dtype = np_array.dtype.name | 26 | np_dtype = np_array.dtype.name |
| @@ -34,6 +34,7 @@ def numpy_to_torch_tensor(np_array): | |||
| 34 | 34 | ||
| 35 | def torch_to_numpy_tensor(torch_tensor): | 35 | def torch_to_numpy_tensor(torch_tensor): |
| 36 | import torch | 36 | import torch |
| 37 | + | ||
| 37 | if torch_tensor is None: | 38 | if torch_tensor is None: |
| 38 | return None | 39 | 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 | ||
| 50 | def bincount_golden(array, size, weight, **kwargs): | 51 | def 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 tensor | 62 | Output tensor |
| 62 | - ''' | 63 | + """ |
| 63 | import torch | 64 | 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) | ||
| 100 | + return res.to(out.dtype) | ||
| @@ -13,9 +13,8 @@ | |||
| 13 | import numpy | 13 | import 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_value | 28 | 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 | ||
| 40 | def div_golden(x1, x2, **kwargs): | 42 | def 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 tensor | 53 | Output tensor |
| 52 | - ''' | 54 | + """ |
| 53 | ori_dtype = x1.dtype | 55 | 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 & float16 | 58 | + 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 res | 112 | return res |
| 109 | else: | 113 | else: |
| 110 | import tensorflow as tf | 114 | 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 | ||
| 13 | import torch | 12 | import 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.dtype | 30 | 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 @@ | |||
| 12 | import numpy as np | 12 | import 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 @@ | |||
| 12 | import numpy as np | 12 | import 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 | ||
| 13 | import torch | 12 | import 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.dtype | 29 | 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 res | 40 | 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 | ||
| 13 | import torch | 12 | import 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.dtype | 29 | 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 res | 40 | 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 @@ | |||
| 12 | import numpy | 12 | import 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 | + | ||
| 20 | def numpy_to_torch_tensor(np_array): | 20 | def numpy_to_torch_tensor(np_array): |
| 21 | import torch | 21 | import torch |
| 22 | + | ||
| 22 | if np_array is None: | 23 | if np_array is None: |
| 23 | return None | 24 | return None |
| 24 | np_dtype = np_array.dtype.name | 25 | np_dtype = np_array.dtype.name |
| @@ -32,6 +33,7 @@ def numpy_to_torch_tensor(np_array): | |||
| 32 | 33 | ||
| 33 | def torch_to_numpy_tensor(torch_tensor): | 34 | def torch_to_numpy_tensor(torch_tensor): |
| 34 | import torch | 35 | import torch |
| 36 | + | ||
| 35 | if torch_tensor is None: | 37 | if torch_tensor is None: |
| 36 | return None | 38 | 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 | + | ||
| 45 | def muls_golden(x, value, **kwargs): | 48 | def 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 torch | 57 | 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 | |||
| 13 | import torch | 13 | import 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 tf | 30 | import tensorflow.compat.v1 as tf |
| 33 | from tensorflow.python.ops import gen_array_ops | 31 | 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.dtype | 35 | 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 res | 44 | 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 | |||
| 13 | import torch | 13 | import 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 | + | ||
| 25 | def _bfloat16_conversion(dtypes): | 21 | def _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 result | 28 | return result |
| 33 | 29 | ||
| 30 | + | ||
| 34 | def _torch_dtype_conversion(dtypes): | 31 | def _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 dt | 43 | + 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 result | 50 | return result |
| 54 | 51 | ||
| 52 | + | ||
| 55 | def _range_golden(start, limit, delta, *, is_closed=False, **kwargs): | 53 | def _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 values | 64 | 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 | + | ||
| 95 | def aclnn_arange_golden(start, end, step, out, **kwargs): | 110 | def 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 | + | ||
| 20 | def sub_golden(x1, x2, **kwargs): | 19 | def 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 torch | 28 | import torch |
| 30 | 29 | ||
| 31 | dtype = x1.dtype | 30 | 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 res | 43 | 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) | ||
🟡 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=None且minlength > 0(或minlength大于输入数组最大值的任何值)。建议:在
weights is None分支中也传入minlength=minlength,使两个分支的minlength行为一致。