import torch
from torch import Tensor
import torch_npu
from ascend_ops.trans_conv3d_format import ncdhw_to_ndc1hwc0, ncdhw_to_fz3d, ndc1hwc0_to_ncdhw
__all__ = ["conv3d_custom",]
"""
3D卷积自定义算子接口函数
该函数是3D卷积操作的高级Python接口,负责:
1. 根据NPU设备类型选择对应的算子实现
2. 对于Ascend910B设备,进行数据格式转换
3. 调用底层C++算子实现
4. 返回计算结果
设备支持情况:
- Ascend950PR_9589: 使用conv3d_v2_custom算子,输入输出为NCDHW格式
- Ascend910B (其他设备): 使用conv3d_custom算子,需要转换为NDC1HWC0和FRACTAL_Z_3D格式
数据格式说明:
- NCDHW: 标准格式 [N, C, D, H, W]
- NDC1HWC0: Ascend优化格式 [N, D, C1, H, W, C0],其中C0=16
- FRACTAL_Z_3D: 权重格式 [Kd*C1*Kh*Kw, N1, N0, C0]
@param input 输入张量 [N, C, D, H, W] (NCDHW格式)
@param weight 权重张量 [Co, Ci, Kd, Kh, Kw] (NCDHW格式)
@param strides 步长 [strideD, strideH, strideW]
@param pads padding [padD, padH, padW] (每个方向2面,共6面)
@param dilations 膨胀 [dilationD, dilationH, dilationW]
@param bias 偏置张量 [Co] (可选)
@param enable_hf32 是否启用HF32混合精度模式(仅Ascend910B支持)
@return 输出张量 [N, Co, Do, Ho, Wo] (NCDHW格式)
"""
def conv3d_custom(input: Tensor, weight: Tensor, strides: list, pads: list, dilations: list,
bias: Tensor = None, enable_hf32: bool = False) -> Tensor:
if torch_npu.npu.get_device_name().startswith("Ascend950"):
print(torch.ops.ascend_ops.conv3d_v2_custom)
assert hasattr(torch.ops.ascend_ops, "conv3d_v2_custom"), "The 'conv3d_v2_custom' operator is not registered in 'torch.ops.ascend_ops' namespace."
origin_input_shape = list(input.shape)
origin_weight_shape = list(weight.shape)
input = input.npu()
weight = weight.npu()
bias = bias.npu() if bias is not None else None
output = torch.ops.ascend_ops.conv3d_v2_custom(input, weight, strides, pads, dilations, origin_input_shape,
origin_weight_shape, bias).cpu()
return output
print(torch.ops.ascend_ops.conv3d_custom)
assert hasattr(torch.ops.ascend_ops, "conv3d_custom"), "The 'conv3d_custom' operator is not registered in 'torch.ops.ascend_ops' namespace."
origin_input_shape = list(input.shape)
origin_weight_shape = list(weight.shape)
origin_cout = origin_weight_shape[0]
input = ncdhw_to_ndc1hwc0(input).npu()
weight = ncdhw_to_fz3d(weight).npu()
bias = bias.npu() if bias is not None else None
output = torch.ops.ascend_ops.conv3d_custom(input, weight, strides, pads, dilations, origin_input_shape,
origin_weight_shape, bias, enable_hf32).cpu()
return ndc1hwc0_to_ncdhw(output, origin_cout)