def convert_tensor_to_device(tensor_obj, device: str = "cpu"):
"""
if is tensor sequence, convert to device, else return self
:param tensor_obj:
:param device:
:return:
"""
if isinstance(tensor_obj, torch.Tensor):
return tensor_obj.to(device)
if isinstance(tensor_obj, dict):
return {k: convert_tensor_to_device(v, device) for k, v in tensor_obj.items()}
if isinstance(tensor_obj, (tuple, list)):
return type(tensor_obj)([convert_tensor_to_device(v, device) for v in tensor_obj])
return tensor_obj
def convert_tensor_dtype_double(tensor_seq, is_high_precision: bool = False):
"""
During CPU calculation, the input of float16 or bfloat16 is converted into float32.
:return:
"""
if isinstance(tensor_seq, torch.Tensor):
if tensor_seq.dtype in [torch.float16, torch.bfloat16]:
return tensor_seq.to(torch.float32)
if tensor_seq.dtype == torch.float32:
return tensor_seq.to(torch.float64)
return tensor_seq
if isinstance(tensor_seq, dict):
return {k: convert_tensor_dtype_double(v) for k, v in tensor_seq.items()}
if isinstance(tensor_seq, (tuple, list)):
return type(tensor_seq)([convert_tensor_dtype_double(v) for v in tensor_seq])
return tensor_seq
def set_tensors_required_grad(inputs, grad_inputs):
if isinstance(inputs, torch.Tensor) and torch.is_floating_point(inputs):
inputs.requires_grad = True
grad_inputs.append(inputs)
return inputs
if isinstance(inputs, dict):
return {k: set_tensors_required_grad(v, grad_inputs) for k, v in inputs.items()}
if isinstance(inputs, (tuple, list)):
return type(inputs)([set_tensors_required_grad(v, grad_inputs) for v in inputs])
return inputs
def set_tensors_by_needs_input_grad(needs_input_grad, inputs, grad_inputs):
if isinstance(inputs, (tuple, list)):
input_data = [set_tensors_by_needs_input_grad(needs_input_grad[i], v, grad_inputs) for i, v in
enumerate(inputs)]
return type(inputs)(input_data)
if isinstance(inputs, dict):
return {k: set_tensors_by_needs_input_grad(needs_input_grad[k], v, grad_inputs) for k, v in inputs.items()}
if needs_input_grad is True:
inputs.requires_grad = True
grad_inputs.append(inputs)
return inputs
return inputs
def generate_grad_output(output_data):
if torch.is_tensor(output_data) and torch.is_floating_point(output_data):
return (torch.ones_like(output_data.detach()),)
if isinstance(output_data, (list, tuple)):
return (
torch.ones_like(i.detach())
for i in output_data
if torch.is_tensor(i) and torch.is_floating_point(i)
)
return tuple()
Thanks for sending an issue! Please fill in the following template to help quickly solve your problem.
Describe the current behavior / 问题描述 (Mandatory / 必填)
lstmbackward算子反向kernel报错

Environment / 环境信息 (Mandatory / 必填)
Atlas A3 训练系列产品/Atlas A3 推理系列产品 √
Atlas A2 训练系列产品/Atlas A2 推理系列产品 √
Steps to reproduce the issue / 重现步骤 (Mandatory / 必填)
import copy
import pickle
import glob
import os
import torch
import torch_npu
from compare import benchmark_compare
from util_test import data_compare
torch_npu.npu.config.allow_internal_format = False
torch.npu.aclnn.allow_hf32 = False
def convert_tensor_to_device(tensor_obj, device: str = "cpu"):
"""
if is tensor sequence, convert to device, else return self
:param tensor_obj:
:param device:
:return:
"""
if isinstance(tensor_obj, torch.Tensor):
return tensor_obj.to(device)
if isinstance(tensor_obj, dict):
return {k: convert_tensor_to_device(v, device) for k, v in tensor_obj.items()}
if isinstance(tensor_obj, (tuple, list)):
return type(tensor_obj)([convert_tensor_to_device(v, device) for v in tensor_obj])
return tensor_obj
def convert_tensor_dtype_double(tensor_seq, is_high_precision: bool = False):
"""
During CPU calculation, the input of float16 or bfloat16 is converted into float32.
:return:
"""
if isinstance(tensor_seq, torch.Tensor):
if tensor_seq.dtype in [torch.float16, torch.bfloat16]:
return tensor_seq.to(torch.float32)
if tensor_seq.dtype == torch.float32:
return tensor_seq.to(torch.float64)
return tensor_seq
if isinstance(tensor_seq, dict):
return {k: convert_tensor_dtype_double(v) for k, v in tensor_seq.items()}
if isinstance(tensor_seq, (tuple, list)):
return type(tensor_seq)([convert_tensor_dtype_double(v) for v in tensor_seq])
return tensor_seq
def set_tensors_required_grad(inputs, grad_inputs):
if isinstance(inputs, torch.Tensor) and torch.is_floating_point(inputs):
inputs.requires_grad = True
grad_inputs.append(inputs)
return inputs
if isinstance(inputs, dict):
return {k: set_tensors_required_grad(v, grad_inputs) for k, v in inputs.items()}
if isinstance(inputs, (tuple, list)):
return type(inputs)([set_tensors_required_grad(v, grad_inputs) for v in inputs])
return inputs
def set_tensors_by_needs_input_grad(needs_input_grad, inputs, grad_inputs):
if isinstance(inputs, (tuple, list)):
input_data = [set_tensors_by_needs_input_grad(needs_input_grad[i], v, grad_inputs) for i, v in
enumerate(inputs)]
return type(inputs)(input_data)
if isinstance(inputs, dict):
return {k: set_tensors_by_needs_input_grad(needs_input_grad[k], v, grad_inputs) for k, v in inputs.items()}
if needs_input_grad is True:
inputs.requires_grad = True
grad_inputs.append(inputs)
return inputs
return inputs
def generate_grad_output(output_data):
if torch.is_tensor(output_data) and torch.is_floating_point(output_data):
return (torch.ones_like(output_data.detach()),)
if isinstance(output_data, (list, tuple)):
return (
torch.ones_like(i.detach())
for i in output_data
if torch.is_tensor(i) and torch.is_floating_point(i)
)
return tuple()
directory_path = "./"
files = glob.glob(os.path.join(directory_path, 'f8b3371f4042c934_2025.p'))
file_path = f"./outputs/input_data/torch.nn.BatchNorm2d/4cf57e1098259b38_33877933.p"
for file in files:
print("file",file)
with open(file, "rb") as f:
data = pickle.load(f)
torch.manual_seed(2025)
call_param_args = data.get("call_param_args")
call_param_kwargs = data.get("call_param_kwargs")
needs_input_grad = data.get("needs_input_grad")
grad_output = data.get("grad_output")
grad_output_npu = data.get("grad_output")
init_param_args = data.get("init_param_args")
init_param_kwargs = data.get("init_param_kwargs")
print("call_param_args",call_param_args[0].dtype)
grad_inputs = []
grad_inputs_npu = []
# call_param_args_new = list(call_param_args)
# call_param_args_new1 = call_param_args_new[0].to(torch.float32)
# call_param_args_new[0] = call_param_args_new1
init_cls_cpu = torch.nn.LSTM(*init_param_args, **init_param_kwargs).to(call_param_args[0].dtype)
# init_cls_npu = copy.deepcopy(init_cls_cpu)
call_param_args_npu = convert_tensor_to_device(tensor_obj=call_param_args, device="npu:0")
call_param_kwargs_npu = convert_tensor_to_device(tensor_obj=call_param_kwargs, device="npu:0")
# if call_param_args[0].dtype == torch.float16:
# call_param_args_db = convert_tensor_dtype_double(call_param_args, True)
# call_param_kwargs_db = convert_tensor_dtype_double(call_param_kwargs, True)
# else:
# call_param_args_db = call_param_args
# call_param_kwargs_db = call_param_kwargs
# print("call_param_args_db",call_param_args_db)
if grad_output:
# call_param_args_cpu = set_tensors_by_needs_input_grad(needs_input_grad["args"], call_param_args_db,
# grad_inputs)
# call_param_kwargs_cpu = set_tensors_by_needs_input_grad(needs_input_grad["kwargs"], call_param_kwargs_db,
# grad_inputs)
call_param_args_npu1 = set_tensors_by_needs_input_grad(needs_input_grad.get("args"), call_param_args_npu,
grad_inputs_npu)
call_param_kwargs_npu1 = set_tensors_by_needs_input_grad(needs_input_grad.get("kwargs"), call_param_kwargs_npu,
grad_inputs_npu)
else:
# call_param_args_cpu = set_tensors_required_grad(call_param_args_db, grad_inputs)
# call_param_kwargs_cpu = set_tensors_required_grad(call_param_kwargs_db, grad_inputs)
call_param_args_npu1 = set_tensors_required_grad(call_param_args_npu, grad_inputs_npu)
call_param_kwargs_npu1 = set_tensors_required_grad(call_param_kwargs_npu, grad_inputs_npu)
Describe the expected behavior / 预期结果 (Mandatory / 必填)
不报错
Related log / screenshot / 日志 / 截图 (Mandatory / 必填)
Special notes for this issue/备注 (Optional / 选填)