from typing import Optional, List
import numpy as np
import torch
def compute_error_balance(local_output: torch.Tensor, remote_output: torch.Tensor, small_value=1.0) -> float:
diff_value = torch.subtract(local_output, remote_output)
scalar = torch.full_like(remote_output, small_value)
diff_value_rel = diff_value / torch.max(torch.abs(remote_output), scalar)
return float(torch.mean(diff_value_rel))
def compute_absolute_error(local_output: torch.Tensor, remote_output: torch.Tensor, small_value=1e-7) -> torch.Tensor:
return torch.abs(torch.subtract(local_output, remote_output))
def compute_relative_error(local_output: torch.Tensor, remote_output: torch.Tensor, small_value=1e-7) -> torch.Tensor:
diff_value = torch.abs(torch.subtract(local_output, remote_output))
diff_value_rel = diff_value / (torch.abs(remote_output) + small_value)
return diff_value_rel
def compute_root_mean_squared_error(local_output: torch.Tensor, remote_output: torch.Tensor) -> torch.Tensor:
diff_value = torch.subtract(local_output, remote_output)
root_mean_squared_error = torch.sqrt(torch.sum(diff_value * diff_value) / diff_value.numel()).item()
return root_mean_squared_error
def check_invalid_value(value: torch.Tensor):
has_nan = torch.isnan(value).any()
has_inf = torch.isinf(value).any()
return has_nan or has_inf
def compare_torch_data(data, compare_data):
if not isinstance(data, type(compare_data)):
return False
if isinstance(data, list) or isinstance(data, tuple):
if len(data) != len(compare_data):
return False
return all(compare_torch_data(d, d1) for d, d1 in zip(data, compare_data))
elif isinstance(data, dict):
if set(data.keys()) != set(compare_data.keys()):
return False
return all(compare_torch_data(data[k], compare_data[k]) for k in data)
elif isinstance(data, torch.Tensor):
data = data.cpu()
compare_data = compare_data.cpu()
if data.dtype == torch.complex32:
data = data.to(torch.complex64)
compare_data = compare_data.to(torch.complex64)
nan_mask_data = torch.isnan(data)
nan_mask_cmp = torch.isnan(compare_data)
if not torch.equal(nan_mask_data, nan_mask_cmp):
return False
mask = ~nan_mask_data
return torch.equal(data[mask].cpu(), compare_data[mask].cpu())
else:
return data == compare_data