forked from karpathy/autoresearch
-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathutils.py
More file actions
123 lines (98 loc) · 4.11 KB
/
Copy pathutils.py
File metadata and controls
123 lines (98 loc) · 4.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
import os
import random
import numpy as np
import torch
def set_seed(seed: int = 42) -> None:
random.seed(seed)
np.random.seed(seed)
torch.manual_seed(seed)
if torch.cuda.is_available():
torch.cuda.manual_seed(seed)
torch.cuda.manual_seed_all(seed)
def get_device(use_cuda: bool = True) -> torch.device:
if use_cuda:
if torch.cuda.is_available():
return torch.device("cuda")
if torch.backends.mps.is_available():
return torch.device("mps")
return torch.device("cpu")
# Adapted from https://github.com/linkedin/Liger-Kernel/blob/main/test/utils.py
@torch.no_grad()
def verbose_allclose(
received: torch.Tensor,
expected: torch.Tensor,
rtol: float = 1e-05,
atol: float = 1e-08,
max_print: int = 5,
) -> list[str]:
if received.shape != expected.shape:
return ["SIZE MISMATCH"]
diff = torch.abs(received - expected)
tolerance = atol + rtol * torch.abs(expected)
tol_mismatched = diff > tolerance
nan_mismatched = torch.logical_xor(torch.isnan(received), torch.isnan(expected))
posinf_mismatched = torch.logical_xor(torch.isposinf(received), torch.isposinf(expected))
neginf_mismatched = torch.logical_xor(torch.isneginf(received), torch.isneginf(expected))
mismatched = torch.logical_or(
torch.logical_or(tol_mismatched, nan_mismatched),
torch.logical_or(posinf_mismatched, neginf_mismatched),
)
mismatched_indices = torch.nonzero(mismatched)
num_mismatched = mismatched.count_nonzero().item()
if num_mismatched >= 1:
details = [f"Number of mismatched elements: {num_mismatched}"]
for index in mismatched_indices[:max_print]:
i = tuple(index.tolist())
details.append(f"ERROR AT {i}: {received[i]} {expected[i]}")
if num_mismatched > max_print:
details.append(f"... and {num_mismatched - max_print} more mismatched elements.")
return details
return []
@torch.no_grad()
def verbose_allequal(
received: torch.Tensor, expected: torch.Tensor, max_print: int = 5
) -> list[str]:
mismatched = torch.not_equal(received, expected)
mismatched_indices = torch.nonzero(mismatched)
num_mismatched = mismatched.count_nonzero().item()
if num_mismatched >= 1:
details = [f"Number of mismatched elements: {num_mismatched}"]
for index in mismatched_indices[:max_print]:
i = tuple(index.tolist())
details.append(f"ERROR AT {i}: {received[i]} {expected[i]}")
if num_mismatched > max_print:
details.append(f"... and {num_mismatched - max_print} more mismatched elements.")
return details
return []
def match_reference(data, output, reference, rtol: float = 1e-05, atol: float = 1e-08):
expected = reference(data)
reasons = verbose_allclose(output, expected, rtol=rtol, atol=atol)
if len(reasons) > 0:
return False, "mismatch found! custom implementation doesn't match reference: " + " ".join(reasons)
return True, ""
def make_match_reference(reference, **kwargs):
def wrapped(data, output):
return match_reference(data, output, reference=reference, **kwargs)
return wrapped
class DeterministicContext:
def __init__(self):
self.allow_tf32 = None
self.deterministic = None
self.cublas = None
def __enter__(self):
self.cublas = os.environ.get("CUBLAS_WORKSPACE_CONFIG", "")
self.allow_tf32 = torch.backends.cudnn.allow_tf32
self.deterministic = torch.backends.cudnn.deterministic
torch.backends.cudnn.allow_tf32 = False
torch.backends.cudnn.deterministic = True
torch.use_deterministic_algorithms(True)
return self
def __exit__(self, exc_type, exc_value, traceback):
torch.backends.cudnn.allow_tf32 = self.allow_tf32
torch.backends.cudnn.deterministic = self.deterministic
torch.use_deterministic_algorithms(False)
os.environ["CUBLAS_WORKSPACE_CONFIG"] = self.cublas
def clear_l2_cache() -> None:
dummy = torch.empty((32, 1024, 1024), dtype=torch.int64, device="cuda")
dummy.fill_(42)
del dummy