Merged
fix: circular_pad_grad golden 支持 torch.Tensor 输入并对非法输入零值降级 #6873
tan_xinAdd on 11 days ago
fix: circular_pad_grad golden 支持 torch.Tensor 输入并对非法输入零值降级 #6873
Merged
Merged fromtan_xin/ops-mathmaster-tileintocann/ops-mathmaster
Total: 1 files changed+37-10
| @@ -140,6 +140,12 @@ def circular_pad_grad_golden(x, paddings, **kwargs): | |||
| 140 | """ | 140 | """ |
| 141 | grad_output = x | 141 | grad_output = x |
| 142 | 142 | ||
| 143 | + import torch | ||
| 144 | + | ||
| 145 | + if isinstance(grad_output, torch.Tensor): | ||
| 146 | + grad_output = grad_output.detach().cpu().numpy() | ||
| 147 | + if isinstance(paddings, torch.Tensor): | ||
| 148 | + paddings = paddings.detach().cpu().numpy() | ||
| 143 | paddings_arr = np.array(paddings).astype(np.int64) | 149 | paddings_arr = np.array(paddings).astype(np.int64) |
| 144 | if paddings_arr.ndim == 1: | 150 | if paddings_arr.ndim == 1: |
| 145 | paddings_arr = paddings_arr.reshape(-1, 2) | 151 | paddings_arr = paddings_arr.reshape(-1, 2) |
| @@ -166,15 +172,21 @@ def _aclnn_circular_pad_grad_golden(grad_output_np, self_np, padding): | |||
| 166 | 172 | ||
| 167 | padding 为扁平序列,[0,1] 作用于 self 最后一维、[2,3] 倒数第二维、[4,5] 倒数第三维, | 173 | padding 为扁平序列,[0,1] 作用于 self 最后一维、[2,3] 倒数第二维、[4,5] 倒数第三维, |
| 168 | 与 F.pad 的 pad 元组顺序(末维在前)一致,可直接透传。 | 174 | 与 F.pad 的 pad 元组顺序(末维在前)一致,可直接透传。 |
| 175 | + aclnn 通路对 torch 原生 dtype 传 torch.Tensor(CPU host 侧),非原生 dtype(bfloat16) | ||
| 176 | + 传 numpy 视图——两种输入均直接支持。 | ||
| 169 | """ | 177 | """ |
| 170 | import torch | 178 | import torch |
| 171 | 179 | ||
| 172 | pad_flat = np.array(padding).reshape(-1).tolist() | 180 | pad_flat = np.array(padding).reshape(-1).tolist() |
| 173 | pads = tuple(int(v) for v in pad_flat) | 181 | pads = tuple(int(v) for v in pad_flat) |
| 174 | - origin_dtype = grad_output_np.dtype.name | 182 | + if isinstance(grad_output_np, torch.Tensor): |
| 175 | - grad_output = _numpy_to_torch_tensor(grad_output_np) | 183 | + grad_output = grad_output_np |
| 184 | + origin_dtype = str(grad_output.dtype) | ||
| 185 | + else: | ||
| 186 | + origin_dtype = grad_output_np.dtype.name | ||
| 187 | + grad_output = _numpy_to_torch_tensor(grad_output_np) | ||
| 176 | self_t = torch.zeros(list(self_np.shape), dtype=grad_output.dtype) | 188 | self_t = torch.zeros(list(self_np.shape), dtype=grad_output.dtype) |
| 177 | - if origin_dtype == "bfloat16": | 189 | + if "bfloat16" in origin_dtype: |
| 178 | grad_output = grad_output.to(torch.float32) | 190 | grad_output = grad_output.to(torch.float32) |
| 179 | self_t = self_t.to(torch.float32) | 191 | self_t = self_t.to(torch.float32) |
| 180 | self_t.requires_grad_(True) | 192 | self_t.requires_grad_(True) |
| @@ -182,11 +194,22 @@ def _aclnn_circular_pad_grad_golden(grad_output_np, self_np, padding): | |||
| 182 | loss = (grad_output * out).sum() | 194 | loss = (grad_output * out).sum() |
| 183 | loss.backward() | 195 | loss.backward() |
| 184 | grad_input = self_t.grad | 196 | grad_input = self_t.grad |
| 185 | - if origin_dtype == "bfloat16": | 197 | + if "bfloat16" in origin_dtype: |
| 186 | grad_input = grad_input.to(torch.bfloat16) | 198 | grad_input = grad_input.to(torch.bfloat16) |
| 187 | return _torch_to_numpy_tensor(grad_input) | 199 | return _torch_to_numpy_tensor(grad_input) |
| 188 | 200 | ||
| 189 | 201 | ||
| 202 | +def _aclnn_zero_fallback(grad_input): | ||
| 203 | + """非法输入(expected_error 用例)降级:golden 数学必然失败,返回与输出 | ||
| 204 | + 容器同 shape/dtype 的零参考,让用例继续进入算子侧校验,由算子拒收产生证据; | ||
| 205 | + 不先行 GOLDEN_FAILURE 中断流程。""" | ||
| 206 | + import torch | ||
| 207 | + | ||
| 208 | + if isinstance(grad_input, torch.Tensor): | ||
| 209 | + return torch.zeros(grad_input.shape, dtype=grad_input.dtype) | ||
| 210 | + return np.zeros(grad_input.shape, dtype=grad_input.dtype) | ||
| 211 | + | ||
| 212 | + | ||
| 190 | class CircularPadGradTorchImpl: | 213 | class CircularPadGradTorchImpl: |
| 191 | """third_party torch 实现:F.pad(circular) + autograd 反向(本算子无同名第三方算子)。""" | 214 | """third_party torch 实现:F.pad(circular) + autograd 反向(本算子无同名第三方算子)。""" |
| 192 | 215 | ||
| @@ -214,9 +237,11 @@ class CircularPadGradTestSpec: | |||
| 214 | 237 | ||
| 215 | 238 | ||
| 216 | class AclnnCircularPad2dBackwardSpec: | 239 | class AclnnCircularPad2dBackwardSpec: |
| 217 | - def golden(gradOutput, self, padding, **kwargs): | 240 | + def golden(gradOutput, self, padding, gradInput, **kwargs): |
| 218 | - del kwargs | 241 | + try: |
| 219 | - return [_aclnn_circular_pad_grad_golden(gradOutput, self, padding)] | 242 | + return [_aclnn_circular_pad_grad_golden(gradOutput, self, padding)] |
| 243 | + except Exception: | ||
| 244 | + return [_aclnn_zero_fallback(gradInput)] | ||
| 220 | 245 | ||
| 221 | third_party = {"torch": CircularPadGradTorchImpl} | 246 | third_party = {"torch": CircularPadGradTorchImpl} |
| 222 | 247 | ||
| @@ -228,9 +253,11 @@ class AclnnCircularPad2dBackwardSpec: | |||
| 228 | 253 | ||
| 229 | 254 | ||
| 230 | class AclnnCircularPad3dBackwardSpec: | 255 | class AclnnCircularPad3dBackwardSpec: |
| 231 | - def golden(gradOutput, self, padding, **kwargs): | 256 | + def golden(gradOutput, self, padding, gradInput, **kwargs): |
| 232 | - del kwargs | 257 | + try: |
| 233 | - return [_aclnn_circular_pad_grad_golden(gradOutput, self, padding)] | 258 | + return [_aclnn_circular_pad_grad_golden(gradOutput, self, padding)] |
| 259 | + except Exception: | ||
| 260 | + return [_aclnn_zero_fallback(gradInput)] | ||
| 234 | 261 | ||
| 235 | third_party = {"torch": CircularPadGradTorchImpl} | 262 | third_party = {"torch": CircularPadGradTorchImpl} |
| 236 | 263 | ||