[torch/utils][Code Clean] Clean asserts in hipify/, jit/, model_dump and tensorboard of torch/utils (#165311)

Including:
- `torch/utils/hipify/`
- `torch/utils/jit/`
- `torch/utils/model_dump/`
- `torch/utils/tensorboard/`

Fixes part of #164878

Pull Request resolved: https://github.com/pytorch/pytorch/pull/165311
Approved by: https://github.com/albanD
This commit is contained in:
KarhouTam
2025-10-14 15:26:23 +00:00
committed by PyTorch MergeBot
parent 45b8c0f75c
commit bf5aeb3148
8 changed files with 117 additions and 70 deletions

View File

@ -510,9 +510,9 @@ class Mod(sympy.Function):
# Evaluate if they are both literals.
if q.is_Number and p.is_Number:
if not (p >= 0):
if p < 0:
raise AssertionError(p)
if not (q >= 1):
if q < 1:
raise AssertionError(q)
return p % q

View File

@ -548,7 +548,8 @@ def get_hip_file_path(rel_filepath, is_pytorch_extension=False):
"""
# At the moment, some PyTorch source files are HIPified in place. The predicate
# is_out_of_place tells us if this is the case or not.
assert not os.path.isabs(rel_filepath)
if os.path.isabs(rel_filepath):
raise AssertionError("rel_filepath must be a relative path")
if not is_pytorch_extension and not is_out_of_place(rel_filepath):
return rel_filepath
@ -615,7 +616,8 @@ def get_hip_file_path(rel_filepath, is_pytorch_extension=False):
def is_out_of_place(rel_filepath):
assert not os.path.isabs(rel_filepath)
if os.path.isabs(rel_filepath):
raise AssertionError("rel_filepath must be a relative path")
if rel_filepath.startswith("torch/"):
return False
if rel_filepath.startswith("third_party/nvfuser/"):
@ -627,7 +629,8 @@ def is_out_of_place(rel_filepath):
# Keep this synchronized with includes/ignores in build_amd.py
def is_pytorch_file(rel_filepath):
assert not os.path.isabs(rel_filepath)
if os.path.isabs(rel_filepath):
raise AssertionError("rel_filepath must be a relative path")
if rel_filepath.startswith("aten/"):
if rel_filepath.startswith("aten/src/ATen/core/"):
return False
@ -658,7 +661,8 @@ def is_special_file(rel_filepath):
return False
def is_caffe2_gpu_file(rel_filepath):
assert not os.path.isabs(rel_filepath)
if os.path.isabs(rel_filepath):
raise AssertionError("rel_filepath must be a relative path")
if rel_filepath.startswith("c10/cuda"):
return True
filename = os.path.basename(rel_filepath)
@ -784,7 +788,8 @@ PYTORCH_MAP: dict[str, object] = {}
PYTORCH_SPECIAL_MAP = {}
for mapping in CUDA_TO_HIP_MAPPINGS:
assert isinstance(mapping, Mapping)
if not isinstance(mapping, Mapping):
raise TypeError("Expected each mapping in CUDA_TO_HIP_MAPPINGS to be a Mapping")
for src, value in mapping.items():
dst = value[0]
meta_data = value[1:]

View File

@ -32,10 +32,14 @@ def make_tensor_from_type(inp_type: torch._C.TensorType):
stride = inp_type.strides()
device = inp_type.device()
dtype = inp_type.dtype()
assert size is not None
assert stride is not None
assert device is not None
assert dtype is not None
if size is None:
raise AssertionError("make_tensor_from_type: 'size' is None (inp_type.sizes() returned None)")
if stride is None:
raise AssertionError("make_tensor_from_type: 'stride' is None (inp_type.strides() returned None)")
if device is None:
raise AssertionError("make_tensor_from_type: 'device' is None (inp_type.device() returned None)")
if dtype is None:
raise AssertionError("make_tensor_from_type: 'dtype' is None (inp_type.dtype() returned None)")
return torch.empty_strided(size=size, stride=stride, device=device, dtype=dtype)
def load_graph_and_inputs(ir: str) -> tuple[Any, list[Any]]:
@ -81,7 +85,8 @@ def run_test(ir, inputs, *, warmup_runs=10, test_runs=20) -> float:
if isinstance(input, torch.Tensor):
is_cpu = input.device.type == "cpu"
break
assert is_cpu is not None
if is_cpu is None:
raise AssertionError("No tensor found in inputs")
out = time_cpu(graph, inputs, test_runs) if is_cpu else time_cuda(graph, inputs, test_runs)
return out

View File

@ -87,19 +87,31 @@ __all__ = ['get_storage_info', 'hierarchical_pickle', 'get_model_info', 'get_inl
'burn_in_info', 'get_info_and_burn_skeleton']
def get_storage_info(storage):
assert isinstance(storage, torch.utils.show_pickle.FakeObject)
assert storage.module == "pers"
assert storage.name == "obj"
assert storage.state is None
assert isinstance(storage.args, tuple)
assert len(storage.args) == 1
if not isinstance(storage, torch.utils.show_pickle.FakeObject):
raise AssertionError(f"storage is not FakeObject: {type(storage)}")
if storage.module != "pers":
raise AssertionError(f"storage.module is not 'pers': {storage.module!r}")
if storage.name != "obj":
raise AssertionError(f"storage.name is not 'obj': {storage.name!r}")
if storage.state is not None:
raise AssertionError(f"storage.state is not None: {storage.state!r}")
if not isinstance(storage.args, tuple):
raise AssertionError(f"storage.args is not a tuple: {type(storage.args)}")
if len(storage.args) != 1:
raise AssertionError(f"len(storage.args) is not 1: {len(storage.args)}")
sa = storage.args[0]
assert isinstance(sa, tuple)
assert len(sa) == 5
assert sa[0] == "storage"
assert isinstance(sa[1], torch.utils.show_pickle.FakeClass)
assert sa[1].module == "torch"
assert sa[1].name.endswith("Storage")
if not isinstance(sa, tuple):
raise AssertionError(f"sa is not a tuple: {type(sa)}")
if len(sa) != 5:
raise AssertionError(f"len(sa) is not 5: {len(sa)}")
if sa[0] != "storage":
raise AssertionError(f"sa[0] is not 'storage': {sa[0]!r}")
if not isinstance(sa[1], torch.utils.show_pickle.FakeClass):
raise AssertionError(f"sa[1] is not FakeClass: {type(sa[1])}")
if sa[1].module != "torch":
raise AssertionError(f"sa[1].module is not 'torch': {sa[1].module!r}")
if not sa[1].name.endswith("Storage"):
raise AssertionError(f"sa[1].name does not end with 'Storage': {sa[1].name!r}")
storage_info = [sa[1].name.replace("Storage", "")] + list(sa[2:])
return storage_info
@ -124,52 +136,69 @@ def hierarchical_pickle(data):
if (
typename.startswith(('__torch__.', 'torch.jit.LoweredWrapper.', 'torch.jit.LoweredModule.'))
):
assert data.args == ()
if data.args != ():
raise AssertionError("data.args is not ()")
return {
"__module_type__": typename,
"state": hierarchical_pickle(data.state),
}
if typename == "torch._utils._rebuild_tensor_v2":
assert data.state is None
if data.state is not None:
raise AssertionError("data.state is not None")
storage, offset, size, stride, requires_grad, *_ = data.args
storage_info = get_storage_info(storage)
return {"__tensor_v2__": [storage_info, offset, size, stride, requires_grad]}
if typename == "torch._utils._rebuild_qtensor":
assert data.state is None
if data.state is not None:
raise AssertionError("data.state is not None")
storage, offset, size, stride, quantizer, requires_grad, *_ = data.args
storage_info = get_storage_info(storage)
assert isinstance(quantizer, tuple)
assert isinstance(quantizer[0], torch.utils.show_pickle.FakeClass)
assert quantizer[0].module == "torch"
if not isinstance(quantizer, tuple):
raise AssertionError("quantizer is not a tuple")
if not isinstance(quantizer[0], torch.utils.show_pickle.FakeClass):
raise AssertionError("quantizer[0] is not a FakeClass")
if quantizer[0].module != "torch":
raise AssertionError("quantizer[0].module is not torch")
if quantizer[0].name == "per_tensor_affine":
assert len(quantizer) == 3
assert isinstance(quantizer[1], float)
assert isinstance(quantizer[2], int)
if len(quantizer) != 3:
raise AssertionError("len(quantizer) is not 3")
if not isinstance(quantizer[1], float):
raise AssertionError("quantizer[1] is not a float")
if not isinstance(quantizer[2], int):
raise AssertionError("quantizer[2] is not an int")
quantizer_extra = list(quantizer[1:3])
else:
quantizer_extra = []
quantizer_json = [quantizer[0].name] + quantizer_extra
return {"__qtensor__": [storage_info, offset, size, stride, quantizer_json, requires_grad]}
if typename == "torch.jit._pickle.restore_type_tag":
assert data.state is None
if data.state is not None:
raise AssertionError("data.state is not None")
obj, typ = data.args
assert isinstance(typ, str)
if not isinstance(typ, str):
raise AssertionError("typ is not a string")
return hierarchical_pickle(obj)
if re.fullmatch(r"torch\.jit\._pickle\.build_[a-z]+list", typename):
assert data.state is None
if data.state is not None:
raise AssertionError("data.state is not None")
ls, = data.args
assert isinstance(ls, list)
if not isinstance(ls, list):
raise AssertionError("ls is not a list")
return hierarchical_pickle(ls)
if typename == "torch.device":
assert data.state is None
if data.state is not None:
raise AssertionError("data.state is not None")
name, = data.args
assert isinstance(name, str)
if not isinstance(name, str):
raise AssertionError("name is not a string")
# Just forget that it was a device and return the name.
return name
if typename == "builtin.UnicodeDecodeError":
assert data.state is None
if data.state is not None:
raise AssertionError("data.state is not None")
msg, = data.args
assert isinstance(msg, str)
if not isinstance(msg, str):
raise AssertionError("msg is not a string")
# Hack: Pretend this is a module so we don't need custom serialization.
# Hack: Wrap the message in a tuple so it looks like a nice state object.
# TODO: Undo at least that second hack. We should support string states.
@ -223,11 +252,13 @@ def get_model_info(
"file_size": zi.file_size,
}
)
assert path_prefix is not None
if path_prefix is None:
raise AssertionError("path_prefix is None")
version = zf.read(path_prefix + "/version").decode("utf-8").strip()
def get_pickle(name):
assert path_prefix is not None
if path_prefix is None:
raise AssertionError("path_prefix is None")
with zf.open(path_prefix + f"/{name}.pkl") as handle:
raw = torch.utils.show_pickle.DumpUnpickler(handle, catch_invalid_utf8=True).load()
return hierarchical_pickle(raw)
@ -285,7 +316,8 @@ def get_model_info(
for di, di_next in itertools.pairwise(debug_info):
start, source_range, *_ = di
end = di_next[0]
assert end > start
if end <= start:
raise AssertionError("end is not greater than start")
source, s_start, s_end = source_range
s_text, s_file, s_line = source
# TODO: Handle this case better. TorchScript ranges are in bytes,

View File

@ -25,9 +25,10 @@ def make_tsv(metadata, save_path, metadata_header=None):
if not metadata_header:
metadata = [str(x) for x in metadata]
else:
assert len(metadata_header) == len(
if len(metadata_header) != len(
metadata[0]
), "len of header must be equal to the number of columns in metadata"
):
raise AssertionError("len of header must be equal to the number of columns in metadata")
metadata = ["\t".join(str(e) for e in l) for l in [metadata_header] + metadata]
metadata_bytes = tf.compat.as_bytes("\n".join(metadata) + "\n")

View File

@ -76,10 +76,12 @@ def _prepare_video(V):
def make_grid(I, ncols=8):
# I: N1HW or N3HW
assert isinstance(I, np.ndarray), "plugin error, should pass numpy array here"
if not isinstance(I, np.ndarray):
raise AssertionError("plugin error, should pass numpy array here")
if I.shape[1] == 1:
I = np.concatenate([I, I, I], 1)
assert I.ndim == 4 and I.shape[1] == 3
if I.ndim != 4 or I.shape[1] != 3:
raise AssertionError("Input should be a 4D numpy array with 3 channels")
nimg = I.shape[0]
H = I.shape[2]
W = I.shape[3]
@ -101,13 +103,12 @@ def make_grid(I, ncols=8):
def convert_to_HWC(tensor, input_format): # tensor: numpy array
assert len(set(input_format)) == len(
input_format
), f"You can not use the same dimension shordhand twice. input_format: {input_format}"
assert len(tensor.shape) == len(
input_format
), f"size of input tensor and input format are different. \
tensor shape: {tensor.shape}, input_format: {input_format}"
if len(set(input_format)) != len(input_format):
raise AssertionError(f"You can not use the same dimension shordhand twice. \
input_format: {input_format}")
if len(tensor.shape) != len(input_format):
raise AssertionError(f"size of input tensor and input format are different. \
tensor shape: {tensor.shape}, input_format: {input_format}")
input_format = input_format.upper()
if len(input_format) == 4:

View File

@ -370,9 +370,9 @@ def scalar(name, tensor, collections=None, new_style=False, double_precision=Fal
ValueError: If tensor has the wrong shape or type.
"""
tensor = make_np(tensor).squeeze()
assert (
tensor.ndim == 0
), f"Tensor should contain one element (0 dimensions). Was given size: {tensor.size} and {tensor.ndim} dimensions."
if tensor.ndim != 0:
raise AssertionError(f"Tensor should contain one element (0 dimensions). \
Was given size: {tensor.size} and {tensor.ndim} dimensions.")
# python float is double precision in numpy
scalar = float(tensor)
if new_style:
@ -700,7 +700,8 @@ def audio(tag, tensor, sample_rate=44100):
if abs(array).max() > 1:
print("warning: audio amplitude out of range, auto clipped.")
array = array.clip(-1, 1)
assert array.ndim == 1, "input tensor should be 1 dimensional."
if array.ndim != 1:
raise AssertionError("input tensor should be 1 dimensional.")
array = (array * np.iinfo(np.int16).max).astype("<i2")
import io
@ -731,7 +732,8 @@ def custom_scalars(layout):
for chart_name, chart_metadata in v.items():
tags = chart_metadata[1]
if chart_metadata[0] == "Margin":
assert len(tags) == 3
if len(tags) != 3:
raise AssertionError("len(tags) != 3")
mgcc = layout_pb2.MarginChartContent(
series=[
layout_pb2.MarginChartContent.Series(

View File

@ -420,7 +420,8 @@ class SummaryWriter:
fw_logdir = self._get_file_writer().get_logdir()
for tag, scalar_value in tag_scalar_dict.items():
fw_tag = fw_logdir + "/" + main_tag.replace("/", "_") + "_" + tag
assert self.all_writers is not None
if self.all_writers is None:
raise AssertionError("self.all_writers is None")
if fw_tag in self.all_writers.keys():
fw = self.all_writers[fw_tag]
else:
@ -930,20 +931,19 @@ class SummaryWriter:
fs.makedirs(save_path)
if metadata is not None:
assert mat.shape[0] == len(
if mat.shape[0] != len(
metadata
), "#labels should equal with #data points"
):
raise AssertionError("#labels should equal with #data points")
make_tsv(metadata, save_path, metadata_header=metadata_header)
if label_img is not None:
assert (
mat.shape[0] == label_img.shape[0]
), "#images should equal with #data points"
if mat.shape[0] != label_img.shape[0]:
raise AssertionError("#images should equal with #data points")
make_sprite(label_img, save_path)
assert (
mat.ndim == 2
), "mat should be 2D, where mat.size(0) is the number of data points"
if mat.ndim != 2:
raise AssertionError("mat should be 2D, where mat.size(0) is the number of data points")
make_mat(mat, save_path)
# Filesystem doesn't necessarily have append semantics, so we store an
@ -1094,7 +1094,8 @@ class SummaryWriter:
torch._C._log_api_usage_once(
"tensorboard.logging.add_custom_scalars_marginchart"
)
assert len(tags) == 3
if len(tags) != 3:
raise AssertionError(f"Expected 3 tags, got {len(tags)}.")
layout = {category: {title: ["Margin", tags]}}
self._get_file_writer().add_summary(custom_scalars(layout))