liangsu9988 commited on
Commit
ff2eba6
·
verified ·
1 Parent(s): 662c1da

Uploaded using `kernel-builder`.

Browse files
Files changed (31) hide show
  1. benchmarks/benchmark.py +172 -0
  2. build/torch211-cxx11-cu128-x86_64-linux/__init__.py +49 -0
  3. build/torch211-cxx11-cu128-x86_64-linux/_ops.py +9 -0
  4. build/torch211-cxx11-cu128-x86_64-linux/_small_matrix_cholesky_cuda_f291092.abi3.so +3 -0
  5. build/torch211-cxx11-cu128-x86_64-linux/metadata.json +36 -0
  6. build/torch211-cxx11-cu128-x86_64-linux/small_matrix_cholesky/__init__.py +26 -0
  7. build/torch211-cxx11-cu130-x86_64-linux/__init__.py +49 -0
  8. build/torch211-cxx11-cu130-x86_64-linux/_ops.py +9 -0
  9. build/torch211-cxx11-cu130-x86_64-linux/_small_matrix_cholesky_cuda_f291092.abi3.so +3 -0
  10. build/torch211-cxx11-cu130-x86_64-linux/metadata.json +36 -0
  11. build/torch211-cxx11-cu130-x86_64-linux/small_matrix_cholesky/__init__.py +26 -0
  12. build/torch212-cxx11-cu130-x86_64-linux/__init__.py +49 -0
  13. build/torch212-cxx11-cu130-x86_64-linux/_ops.py +9 -0
  14. build/torch212-cxx11-cu130-x86_64-linux/_small_matrix_cholesky_cuda_f291092.abi3.so +3 -0
  15. build/torch212-cxx11-cu130-x86_64-linux/metadata.json +36 -0
  16. build/torch212-cxx11-cu130-x86_64-linux/small_matrix_cholesky/__init__.py +26 -0
  17. build/torch212-cxx11-cu132-x86_64-linux/__init__.py +49 -0
  18. build/torch212-cxx11-cu132-x86_64-linux/_ops.py +9 -0
  19. build/torch212-cxx11-cu132-x86_64-linux/_small_matrix_cholesky_cuda_f291092.abi3.so +3 -0
  20. build/torch212-cxx11-cu132-x86_64-linux/metadata.json +36 -0
  21. build/torch212-cxx11-cu132-x86_64-linux/small_matrix_cholesky/__init__.py +26 -0
  22. build/torch213-cxx11-cu130-x86_64-linux/__init__.py +49 -0
  23. build/torch213-cxx11-cu130-x86_64-linux/_ops.py +9 -0
  24. build/torch213-cxx11-cu130-x86_64-linux/_small_matrix_cholesky_cuda_f291092.abi3.so +3 -0
  25. build/torch213-cxx11-cu130-x86_64-linux/metadata.json +36 -0
  26. build/torch213-cxx11-cu130-x86_64-linux/small_matrix_cholesky/__init__.py +26 -0
  27. build/torch213-cxx11-cu132-x86_64-linux/__init__.py +49 -0
  28. build/torch213-cxx11-cu132-x86_64-linux/_ops.py +9 -0
  29. build/torch213-cxx11-cu132-x86_64-linux/_small_matrix_cholesky_cuda_f291092.abi3.so +3 -0
  30. build/torch213-cxx11-cu132-x86_64-linux/metadata.json +36 -0
  31. build/torch213-cxx11-cu132-x86_64-linux/small_matrix_cholesky/__init__.py +26 -0
benchmarks/benchmark.py ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """Benchmark small FP32 Cholesky against preallocated PyTorch POTRF."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import argparse
7
+ import importlib
8
+ import math
9
+ import statistics
10
+ import sys
11
+ from pathlib import Path
12
+
13
+ import torch
14
+
15
+ TESTS = Path(__file__).resolve().parents[1] / "tests"
16
+ sys.path.insert(0, str(TESTS))
17
+ from _source_loader import load_source_ops # noqa: E402
18
+
19
+
20
+ def load_installed_ops(artifact: str | None):
21
+ if artifact:
22
+ sys.path.insert(0, artifact)
23
+ try:
24
+ return importlib.import_module("small_matrix_cholesky")
25
+ finally:
26
+ if artifact:
27
+ sys.path.remove(artifact)
28
+
29
+
30
+ def make_spd(batch: int, n: int) -> torch.Tensor:
31
+ generator = torch.Generator(device="cuda").manual_seed(41000 + n + batch)
32
+ x = torch.randn(
33
+ batch,
34
+ n,
35
+ n,
36
+ device="cuda",
37
+ dtype=torch.float32,
38
+ generator=generator,
39
+ ) / n**0.5
40
+ return (
41
+ x @ x.transpose(-1, -2)
42
+ + 0.5 * torch.eye(n, device="cuda", dtype=torch.float32)
43
+ ).contiguous()
44
+
45
+
46
+ def median_ms(fn, warmup: int, iterations: int) -> float:
47
+ for _ in range(warmup):
48
+ fn()
49
+ torch.cuda.synchronize()
50
+ samples: list[float] = []
51
+ for _ in range(iterations):
52
+ start = torch.cuda.Event(enable_timing=True)
53
+ end = torch.cuda.Event(enable_timing=True)
54
+ start.record()
55
+ fn()
56
+ end.record()
57
+ end.synchronize()
58
+ samples.append(start.elapsed_time(end))
59
+ return statistics.median(samples)
60
+
61
+
62
+ def main() -> int:
63
+ parser = argparse.ArgumentParser()
64
+ parser.add_argument(
65
+ "--backend", choices=["source", "installed"], default="source"
66
+ )
67
+ parser.add_argument("--artifact", default=None)
68
+ parser.add_argument("--registration-include", default=None)
69
+ parser.add_argument("--warmup", type=int, default=10)
70
+ parser.add_argument("--iterations", type=int, default=50)
71
+ args = parser.parse_args()
72
+
73
+ if not torch.cuda.is_available():
74
+ raise RuntimeError("CUDA is required")
75
+ ops = (
76
+ load_source_ops(args.registration_include)
77
+ if args.backend == "source"
78
+ else load_installed_ops(args.artifact)
79
+ )
80
+
81
+ shapes = [(4096, 32), (1024, 64), (256, 128)]
82
+ candidate_times: list[float] = []
83
+ baseline_times: list[float] = []
84
+ compiled_times: list[float] = []
85
+
86
+ def pytorch_reference(
87
+ input: torch.Tensor,
88
+ output: torch.Tensor,
89
+ info: torch.Tensor,
90
+ ) -> torch.Tensor:
91
+ torch.linalg.cholesky_ex(
92
+ input,
93
+ check_errors=False,
94
+ out=(output, info),
95
+ )
96
+ return output
97
+
98
+ compiled_reference = torch.compile(pytorch_reference, fullgraph=True)
99
+ print(
100
+ "batch,n,candidate_ms,pytorch_eager_ms,pytorch_compile_ms,"
101
+ "speedup_eager,speedup_compile,candidate_tflops,io_gbps"
102
+ )
103
+ for batch, n in shapes:
104
+ input = make_spd(batch, n)
105
+ candidate_output = torch.empty_like(input)
106
+ baseline_output = torch.empty_like(input)
107
+ info = torch.empty(batch, device="cuda", dtype=torch.int32)
108
+
109
+ def candidate() -> None:
110
+ ops.cholesky_small_fp32(input, out=candidate_output)
111
+
112
+ def baseline() -> None:
113
+ pytorch_reference(input, baseline_output, info)
114
+
115
+ def baseline_compiled() -> None:
116
+ compiled_reference(input, baseline_output, info)
117
+
118
+ candidate()
119
+ baseline()
120
+ baseline_compiled()
121
+ torch.cuda.synchronize()
122
+ torch.testing.assert_close(
123
+ candidate_output,
124
+ baseline_output,
125
+ rtol=5e-4,
126
+ atol=2e-4,
127
+ )
128
+
129
+ candidate_ms = median_ms(candidate, args.warmup, args.iterations)
130
+ baseline_ms = median_ms(baseline, args.warmup, args.iterations)
131
+ compiled_ms = median_ms(
132
+ baseline_compiled, args.warmup, args.iterations
133
+ )
134
+ flops = batch * n**3 / 3.0
135
+ tflops = flops / (candidate_ms * 1e-3) / 1e12
136
+ io_bytes = 2 * batch * n * n * 4
137
+ io_gbps = io_bytes / (candidate_ms * 1e-3) / 1e9
138
+ candidate_times.append(candidate_ms)
139
+ baseline_times.append(baseline_ms)
140
+ compiled_times.append(compiled_ms)
141
+ print(
142
+ f"{batch},{n},{candidate_ms:.6f},{baseline_ms:.6f},"
143
+ f"{compiled_ms:.6f},{baseline_ms / candidate_ms:.3f},"
144
+ f"{compiled_ms / candidate_ms:.3f},{tflops:.3f},{io_gbps:.3f}"
145
+ )
146
+
147
+ candidate_geomean = math.exp(
148
+ sum(math.log(value) for value in candidate_times)
149
+ / len(candidate_times)
150
+ )
151
+ baseline_geomean = math.exp(
152
+ sum(math.log(value) for value in baseline_times)
153
+ / len(baseline_times)
154
+ )
155
+ compiled_geomean = math.exp(
156
+ sum(math.log(value) for value in compiled_times)
157
+ / len(compiled_times)
158
+ )
159
+ print(f"candidate_geomean_ms={candidate_geomean:.6f}")
160
+ print(f"pytorch_geomean_ms={baseline_geomean:.6f}")
161
+ print(f"pytorch_compile_geomean_ms={compiled_geomean:.6f}")
162
+ print(
163
+ f"geomean_speedup_eager={baseline_geomean / candidate_geomean:.3f}"
164
+ )
165
+ print(
166
+ f"geomean_speedup_compile={compiled_geomean / candidate_geomean:.3f}"
167
+ )
168
+ return 0
169
+
170
+
171
+ if __name__ == "__main__":
172
+ raise SystemExit(main())
build/torch211-cxx11-cu128-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Batched FP32 Cholesky kernels for small CUDA matrices."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ @torch.library.register_fake(
13
+ add_op_namespace_prefix("cholesky_small_fp32_out")
14
+ )
15
+ def _cholesky_small_fp32_out_fake(
16
+ input: torch.Tensor,
17
+ output: torch.Tensor,
18
+ ) -> None:
19
+ if input.dim() < 2:
20
+ raise RuntimeError("input must have at least two dimensions")
21
+ if input.shape != output.shape:
22
+ raise RuntimeError("output must have the same shape as input")
23
+ if input.shape[-2] != input.shape[-1]:
24
+ raise RuntimeError("the last two dimensions must be square")
25
+ if input.shape[-1] not in (32, 64, 128):
26
+ raise RuntimeError("supported matrix orders are 32, 64, and 128")
27
+ return None
28
+
29
+
30
+ def cholesky_small_fp32(
31
+ input: torch.Tensor,
32
+ *,
33
+ out: Optional[torch.Tensor] = None,
34
+ ) -> torch.Tensor:
35
+ """Compute a lower-triangular Cholesky factor for small FP32 matrices.
36
+
37
+ ``input`` must be a contiguous CUDA FP32 tensor whose last two dimensions
38
+ are ``(n, n)`` with ``n`` equal to 32, 64, or 128. All leading dimensions
39
+ are flattened into a batch. The input matrices must be symmetric positive
40
+ definite. The output's upper triangle is explicitly zero.
41
+ """
42
+
43
+ if out is None:
44
+ out = torch.empty_like(input)
45
+ ops.cholesky_small_fp32_out(input, out)
46
+ return out
47
+
48
+
49
+ __all__ = ["cholesky_small_fp32"]
build/torch211-cxx11-cu128-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _small_matrix_cholesky_cuda_f291092
3
+ ops = torch.ops._small_matrix_cholesky_cuda_f291092
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_small_matrix_cholesky_cuda_f291092::{op_name}"
build/torch211-cxx11-cu128-x86_64-linux/_small_matrix_cholesky_cuda_f291092.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b32d19456d2625c8485c51a15fd75a7d12c2d215554fb9639627ff0bd0f4f947
3
+ size 582984
build/torch211-cxx11-cu128-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "small-matrix-cholesky",
3
+ "id": "_small_matrix_cholesky_cuda_f291092",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "10.0",
11
+ "12.0",
12
+ "8.0",
13
+ "9.0"
14
+ ]
15
+ },
16
+ "digest": {
17
+ "algorithm": "sha256",
18
+ "files": {
19
+ "__init__.py": "Sc7qcYjgjttvRwa0SznImIQhKoGy51oSJJjOznvvj18=",
20
+ "_ops.py": "wQ0b98E+GklbX93H03G+NzmGEGs2jD8ZzF6+DdmylWA=",
21
+ "_small_matrix_cholesky_cuda_f291092.abi3.so": "sy0ZRW0mJchIXFGhX9dafRLC0hVVT7ljlif/C9D0+Uc=",
22
+ "small_matrix_cholesky/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
23
+ }
24
+ },
25
+ "provenance": {
26
+ "kernel-builder": {
27
+ "version": "0.17.0-dev0",
28
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
29
+ "dirty": false
30
+ },
31
+ "kernel": {
32
+ "sha": "f2910927e5fe824a1212a8147067b687e6b6d2ed",
33
+ "dirty": false
34
+ }
35
+ }
36
+ }
build/torch211-cxx11-cu128-x86_64-linux/small_matrix_cholesky/__init__.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ import importlib.util
3
+ import sys
4
+ from pathlib import Path
5
+ from types import ModuleType
6
+
7
+
8
+ def _import_from_path(file_path: Path) -> ModuleType:
9
+ # We cannot use the module name as-is, after adding it to `sys.modules`,
10
+ # it would also be used for other imports. So, we make a module name that
11
+ # depends on the path for it to be unique using the hex-encoded hash of
12
+ # the path.
13
+ path_hash = "{:x}".format(ctypes.c_size_t(hash(file_path.absolute())).value)
14
+ module_name = path_hash
15
+ spec = importlib.util.spec_from_file_location(module_name, file_path)
16
+ if spec is None:
17
+ raise ImportError(f"Cannot load spec for {module_name} from {file_path}")
18
+ module = importlib.util.module_from_spec(spec)
19
+ if module is None:
20
+ raise ImportError(f"Cannot load module {module_name} from spec")
21
+ sys.modules[module_name] = module
22
+ spec.loader.exec_module(module) # type: ignore
23
+ return module
24
+
25
+
26
+ globals().update(vars(_import_from_path(Path(__file__).parent.parent / "__init__.py")))
build/torch211-cxx11-cu130-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Batched FP32 Cholesky kernels for small CUDA matrices."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ @torch.library.register_fake(
13
+ add_op_namespace_prefix("cholesky_small_fp32_out")
14
+ )
15
+ def _cholesky_small_fp32_out_fake(
16
+ input: torch.Tensor,
17
+ output: torch.Tensor,
18
+ ) -> None:
19
+ if input.dim() < 2:
20
+ raise RuntimeError("input must have at least two dimensions")
21
+ if input.shape != output.shape:
22
+ raise RuntimeError("output must have the same shape as input")
23
+ if input.shape[-2] != input.shape[-1]:
24
+ raise RuntimeError("the last two dimensions must be square")
25
+ if input.shape[-1] not in (32, 64, 128):
26
+ raise RuntimeError("supported matrix orders are 32, 64, and 128")
27
+ return None
28
+
29
+
30
+ def cholesky_small_fp32(
31
+ input: torch.Tensor,
32
+ *,
33
+ out: Optional[torch.Tensor] = None,
34
+ ) -> torch.Tensor:
35
+ """Compute a lower-triangular Cholesky factor for small FP32 matrices.
36
+
37
+ ``input`` must be a contiguous CUDA FP32 tensor whose last two dimensions
38
+ are ``(n, n)`` with ``n`` equal to 32, 64, or 128. All leading dimensions
39
+ are flattened into a batch. The input matrices must be symmetric positive
40
+ definite. The output's upper triangle is explicitly zero.
41
+ """
42
+
43
+ if out is None:
44
+ out = torch.empty_like(input)
45
+ ops.cholesky_small_fp32_out(input, out)
46
+ return out
47
+
48
+
49
+ __all__ = ["cholesky_small_fp32"]
build/torch211-cxx11-cu130-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _small_matrix_cholesky_cuda_f291092
3
+ ops = torch.ops._small_matrix_cholesky_cuda_f291092
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_small_matrix_cholesky_cuda_f291092::{op_name}"
build/torch211-cxx11-cu130-x86_64-linux/_small_matrix_cholesky_cuda_f291092.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:005558eb0ae2ae44d7eea858f3f726080d871063736fad8f85e61daa8cf2f380
3
+ size 585392
build/torch211-cxx11-cu130-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "small-matrix-cholesky",
3
+ "id": "_small_matrix_cholesky_cuda_f291092",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "10.0",
11
+ "12.0",
12
+ "8.0",
13
+ "9.0"
14
+ ]
15
+ },
16
+ "digest": {
17
+ "algorithm": "sha256",
18
+ "files": {
19
+ "__init__.py": "Sc7qcYjgjttvRwa0SznImIQhKoGy51oSJJjOznvvj18=",
20
+ "_ops.py": "wQ0b98E+GklbX93H03G+NzmGEGs2jD8ZzF6+DdmylWA=",
21
+ "_small_matrix_cholesky_cuda_f291092.abi3.so": "AFVY6wrirkTX7qhY8/cmCA2HEGNzb62PheYdqozy84A=",
22
+ "small_matrix_cholesky/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
23
+ }
24
+ },
25
+ "provenance": {
26
+ "kernel-builder": {
27
+ "version": "0.17.0-dev0",
28
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
29
+ "dirty": false
30
+ },
31
+ "kernel": {
32
+ "sha": "f2910927e5fe824a1212a8147067b687e6b6d2ed",
33
+ "dirty": false
34
+ }
35
+ }
36
+ }
build/torch211-cxx11-cu130-x86_64-linux/small_matrix_cholesky/__init__.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ import importlib.util
3
+ import sys
4
+ from pathlib import Path
5
+ from types import ModuleType
6
+
7
+
8
+ def _import_from_path(file_path: Path) -> ModuleType:
9
+ # We cannot use the module name as-is, after adding it to `sys.modules`,
10
+ # it would also be used for other imports. So, we make a module name that
11
+ # depends on the path for it to be unique using the hex-encoded hash of
12
+ # the path.
13
+ path_hash = "{:x}".format(ctypes.c_size_t(hash(file_path.absolute())).value)
14
+ module_name = path_hash
15
+ spec = importlib.util.spec_from_file_location(module_name, file_path)
16
+ if spec is None:
17
+ raise ImportError(f"Cannot load spec for {module_name} from {file_path}")
18
+ module = importlib.util.module_from_spec(spec)
19
+ if module is None:
20
+ raise ImportError(f"Cannot load module {module_name} from spec")
21
+ sys.modules[module_name] = module
22
+ spec.loader.exec_module(module) # type: ignore
23
+ return module
24
+
25
+
26
+ globals().update(vars(_import_from_path(Path(__file__).parent.parent / "__init__.py")))
build/torch212-cxx11-cu130-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Batched FP32 Cholesky kernels for small CUDA matrices."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ @torch.library.register_fake(
13
+ add_op_namespace_prefix("cholesky_small_fp32_out")
14
+ )
15
+ def _cholesky_small_fp32_out_fake(
16
+ input: torch.Tensor,
17
+ output: torch.Tensor,
18
+ ) -> None:
19
+ if input.dim() < 2:
20
+ raise RuntimeError("input must have at least two dimensions")
21
+ if input.shape != output.shape:
22
+ raise RuntimeError("output must have the same shape as input")
23
+ if input.shape[-2] != input.shape[-1]:
24
+ raise RuntimeError("the last two dimensions must be square")
25
+ if input.shape[-1] not in (32, 64, 128):
26
+ raise RuntimeError("supported matrix orders are 32, 64, and 128")
27
+ return None
28
+
29
+
30
+ def cholesky_small_fp32(
31
+ input: torch.Tensor,
32
+ *,
33
+ out: Optional[torch.Tensor] = None,
34
+ ) -> torch.Tensor:
35
+ """Compute a lower-triangular Cholesky factor for small FP32 matrices.
36
+
37
+ ``input`` must be a contiguous CUDA FP32 tensor whose last two dimensions
38
+ are ``(n, n)`` with ``n`` equal to 32, 64, or 128. All leading dimensions
39
+ are flattened into a batch. The input matrices must be symmetric positive
40
+ definite. The output's upper triangle is explicitly zero.
41
+ """
42
+
43
+ if out is None:
44
+ out = torch.empty_like(input)
45
+ ops.cholesky_small_fp32_out(input, out)
46
+ return out
47
+
48
+
49
+ __all__ = ["cholesky_small_fp32"]
build/torch212-cxx11-cu130-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _small_matrix_cholesky_cuda_f291092
3
+ ops = torch.ops._small_matrix_cholesky_cuda_f291092
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_small_matrix_cholesky_cuda_f291092::{op_name}"
build/torch212-cxx11-cu130-x86_64-linux/_small_matrix_cholesky_cuda_f291092.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8c29f7d9ecb3691144a91cfa1f99ad42da913db83c495db5ddba59d95106aceb
3
+ size 592168
build/torch212-cxx11-cu130-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "small-matrix-cholesky",
3
+ "id": "_small_matrix_cholesky_cuda_f291092",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "10.0",
11
+ "12.0",
12
+ "8.0",
13
+ "9.0"
14
+ ]
15
+ },
16
+ "digest": {
17
+ "algorithm": "sha256",
18
+ "files": {
19
+ "__init__.py": "Sc7qcYjgjttvRwa0SznImIQhKoGy51oSJJjOznvvj18=",
20
+ "_ops.py": "wQ0b98E+GklbX93H03G+NzmGEGs2jD8ZzF6+DdmylWA=",
21
+ "_small_matrix_cholesky_cuda_f291092.abi3.so": "jCn32eyzaRFEqRz6H5mtQtqRPbg8SV213bpZ2VEGrOs=",
22
+ "small_matrix_cholesky/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
23
+ }
24
+ },
25
+ "provenance": {
26
+ "kernel-builder": {
27
+ "version": "0.17.0-dev0",
28
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
29
+ "dirty": false
30
+ },
31
+ "kernel": {
32
+ "sha": "f2910927e5fe824a1212a8147067b687e6b6d2ed",
33
+ "dirty": false
34
+ }
35
+ }
36
+ }
build/torch212-cxx11-cu130-x86_64-linux/small_matrix_cholesky/__init__.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ import importlib.util
3
+ import sys
4
+ from pathlib import Path
5
+ from types import ModuleType
6
+
7
+
8
+ def _import_from_path(file_path: Path) -> ModuleType:
9
+ # We cannot use the module name as-is, after adding it to `sys.modules`,
10
+ # it would also be used for other imports. So, we make a module name that
11
+ # depends on the path for it to be unique using the hex-encoded hash of
12
+ # the path.
13
+ path_hash = "{:x}".format(ctypes.c_size_t(hash(file_path.absolute())).value)
14
+ module_name = path_hash
15
+ spec = importlib.util.spec_from_file_location(module_name, file_path)
16
+ if spec is None:
17
+ raise ImportError(f"Cannot load spec for {module_name} from {file_path}")
18
+ module = importlib.util.module_from_spec(spec)
19
+ if module is None:
20
+ raise ImportError(f"Cannot load module {module_name} from spec")
21
+ sys.modules[module_name] = module
22
+ spec.loader.exec_module(module) # type: ignore
23
+ return module
24
+
25
+
26
+ globals().update(vars(_import_from_path(Path(__file__).parent.parent / "__init__.py")))
build/torch212-cxx11-cu132-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Batched FP32 Cholesky kernels for small CUDA matrices."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ @torch.library.register_fake(
13
+ add_op_namespace_prefix("cholesky_small_fp32_out")
14
+ )
15
+ def _cholesky_small_fp32_out_fake(
16
+ input: torch.Tensor,
17
+ output: torch.Tensor,
18
+ ) -> None:
19
+ if input.dim() < 2:
20
+ raise RuntimeError("input must have at least two dimensions")
21
+ if input.shape != output.shape:
22
+ raise RuntimeError("output must have the same shape as input")
23
+ if input.shape[-2] != input.shape[-1]:
24
+ raise RuntimeError("the last two dimensions must be square")
25
+ if input.shape[-1] not in (32, 64, 128):
26
+ raise RuntimeError("supported matrix orders are 32, 64, and 128")
27
+ return None
28
+
29
+
30
+ def cholesky_small_fp32(
31
+ input: torch.Tensor,
32
+ *,
33
+ out: Optional[torch.Tensor] = None,
34
+ ) -> torch.Tensor:
35
+ """Compute a lower-triangular Cholesky factor for small FP32 matrices.
36
+
37
+ ``input`` must be a contiguous CUDA FP32 tensor whose last two dimensions
38
+ are ``(n, n)`` with ``n`` equal to 32, 64, or 128. All leading dimensions
39
+ are flattened into a batch. The input matrices must be symmetric positive
40
+ definite. The output's upper triangle is explicitly zero.
41
+ """
42
+
43
+ if out is None:
44
+ out = torch.empty_like(input)
45
+ ops.cholesky_small_fp32_out(input, out)
46
+ return out
47
+
48
+
49
+ __all__ = ["cholesky_small_fp32"]
build/torch212-cxx11-cu132-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _small_matrix_cholesky_cuda_f291092
3
+ ops = torch.ops._small_matrix_cholesky_cuda_f291092
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_small_matrix_cholesky_cuda_f291092::{op_name}"
build/torch212-cxx11-cu132-x86_64-linux/_small_matrix_cholesky_cuda_f291092.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6c66049b384edcff07a4bffd59d1ef409c259232b9873c6bd99b63c9a790d299
3
+ size 596264
build/torch212-cxx11-cu132-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "small-matrix-cholesky",
3
+ "id": "_small_matrix_cholesky_cuda_f291092",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "10.0",
11
+ "12.0",
12
+ "8.0",
13
+ "9.0"
14
+ ]
15
+ },
16
+ "digest": {
17
+ "algorithm": "sha256",
18
+ "files": {
19
+ "__init__.py": "Sc7qcYjgjttvRwa0SznImIQhKoGy51oSJJjOznvvj18=",
20
+ "_ops.py": "wQ0b98E+GklbX93H03G+NzmGEGs2jD8ZzF6+DdmylWA=",
21
+ "_small_matrix_cholesky_cuda_f291092.abi3.so": "bGYEmzhO3P8HpL/9WdHvQJwlkjK5hzxr2ZtjyaeQ0pk=",
22
+ "small_matrix_cholesky/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
23
+ }
24
+ },
25
+ "provenance": {
26
+ "kernel-builder": {
27
+ "version": "0.17.0-dev0",
28
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
29
+ "dirty": false
30
+ },
31
+ "kernel": {
32
+ "sha": "f2910927e5fe824a1212a8147067b687e6b6d2ed",
33
+ "dirty": false
34
+ }
35
+ }
36
+ }
build/torch212-cxx11-cu132-x86_64-linux/small_matrix_cholesky/__init__.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ import importlib.util
3
+ import sys
4
+ from pathlib import Path
5
+ from types import ModuleType
6
+
7
+
8
+ def _import_from_path(file_path: Path) -> ModuleType:
9
+ # We cannot use the module name as-is, after adding it to `sys.modules`,
10
+ # it would also be used for other imports. So, we make a module name that
11
+ # depends on the path for it to be unique using the hex-encoded hash of
12
+ # the path.
13
+ path_hash = "{:x}".format(ctypes.c_size_t(hash(file_path.absolute())).value)
14
+ module_name = path_hash
15
+ spec = importlib.util.spec_from_file_location(module_name, file_path)
16
+ if spec is None:
17
+ raise ImportError(f"Cannot load spec for {module_name} from {file_path}")
18
+ module = importlib.util.module_from_spec(spec)
19
+ if module is None:
20
+ raise ImportError(f"Cannot load module {module_name} from spec")
21
+ sys.modules[module_name] = module
22
+ spec.loader.exec_module(module) # type: ignore
23
+ return module
24
+
25
+
26
+ globals().update(vars(_import_from_path(Path(__file__).parent.parent / "__init__.py")))
build/torch213-cxx11-cu130-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Batched FP32 Cholesky kernels for small CUDA matrices."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ @torch.library.register_fake(
13
+ add_op_namespace_prefix("cholesky_small_fp32_out")
14
+ )
15
+ def _cholesky_small_fp32_out_fake(
16
+ input: torch.Tensor,
17
+ output: torch.Tensor,
18
+ ) -> None:
19
+ if input.dim() < 2:
20
+ raise RuntimeError("input must have at least two dimensions")
21
+ if input.shape != output.shape:
22
+ raise RuntimeError("output must have the same shape as input")
23
+ if input.shape[-2] != input.shape[-1]:
24
+ raise RuntimeError("the last two dimensions must be square")
25
+ if input.shape[-1] not in (32, 64, 128):
26
+ raise RuntimeError("supported matrix orders are 32, 64, and 128")
27
+ return None
28
+
29
+
30
+ def cholesky_small_fp32(
31
+ input: torch.Tensor,
32
+ *,
33
+ out: Optional[torch.Tensor] = None,
34
+ ) -> torch.Tensor:
35
+ """Compute a lower-triangular Cholesky factor for small FP32 matrices.
36
+
37
+ ``input`` must be a contiguous CUDA FP32 tensor whose last two dimensions
38
+ are ``(n, n)`` with ``n`` equal to 32, 64, or 128. All leading dimensions
39
+ are flattened into a batch. The input matrices must be symmetric positive
40
+ definite. The output's upper triangle is explicitly zero.
41
+ """
42
+
43
+ if out is None:
44
+ out = torch.empty_like(input)
45
+ ops.cholesky_small_fp32_out(input, out)
46
+ return out
47
+
48
+
49
+ __all__ = ["cholesky_small_fp32"]
build/torch213-cxx11-cu130-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _small_matrix_cholesky_cuda_f291092
3
+ ops = torch.ops._small_matrix_cholesky_cuda_f291092
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_small_matrix_cholesky_cuda_f291092::{op_name}"
build/torch213-cxx11-cu130-x86_64-linux/_small_matrix_cholesky_cuda_f291092.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:10d82c9d01a56acfadadebf1456e4947136d80f1cbf3b9347f7a106fc13f4d51
3
+ size 592008
build/torch213-cxx11-cu130-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "small-matrix-cholesky",
3
+ "id": "_small_matrix_cholesky_cuda_f291092",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "10.0",
11
+ "12.0",
12
+ "8.0",
13
+ "9.0"
14
+ ]
15
+ },
16
+ "digest": {
17
+ "algorithm": "sha256",
18
+ "files": {
19
+ "__init__.py": "Sc7qcYjgjttvRwa0SznImIQhKoGy51oSJJjOznvvj18=",
20
+ "_ops.py": "wQ0b98E+GklbX93H03G+NzmGEGs2jD8ZzF6+DdmylWA=",
21
+ "_small_matrix_cholesky_cuda_f291092.abi3.so": "ENgsnQGlas+trevxRW5JRxNtgPHL87k0f3oQb8E/TVE=",
22
+ "small_matrix_cholesky/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
23
+ }
24
+ },
25
+ "provenance": {
26
+ "kernel-builder": {
27
+ "version": "0.17.0-dev0",
28
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
29
+ "dirty": false
30
+ },
31
+ "kernel": {
32
+ "sha": "f2910927e5fe824a1212a8147067b687e6b6d2ed",
33
+ "dirty": false
34
+ }
35
+ }
36
+ }
build/torch213-cxx11-cu130-x86_64-linux/small_matrix_cholesky/__init__.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ import importlib.util
3
+ import sys
4
+ from pathlib import Path
5
+ from types import ModuleType
6
+
7
+
8
+ def _import_from_path(file_path: Path) -> ModuleType:
9
+ # We cannot use the module name as-is, after adding it to `sys.modules`,
10
+ # it would also be used for other imports. So, we make a module name that
11
+ # depends on the path for it to be unique using the hex-encoded hash of
12
+ # the path.
13
+ path_hash = "{:x}".format(ctypes.c_size_t(hash(file_path.absolute())).value)
14
+ module_name = path_hash
15
+ spec = importlib.util.spec_from_file_location(module_name, file_path)
16
+ if spec is None:
17
+ raise ImportError(f"Cannot load spec for {module_name} from {file_path}")
18
+ module = importlib.util.module_from_spec(spec)
19
+ if module is None:
20
+ raise ImportError(f"Cannot load module {module_name} from spec")
21
+ sys.modules[module_name] = module
22
+ spec.loader.exec_module(module) # type: ignore
23
+ return module
24
+
25
+
26
+ globals().update(vars(_import_from_path(Path(__file__).parent.parent / "__init__.py")))
build/torch213-cxx11-cu132-x86_64-linux/__init__.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Batched FP32 Cholesky kernels for small CUDA matrices."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Optional
6
+
7
+ import torch
8
+
9
+ from ._ops import add_op_namespace_prefix, ops
10
+
11
+
12
+ @torch.library.register_fake(
13
+ add_op_namespace_prefix("cholesky_small_fp32_out")
14
+ )
15
+ def _cholesky_small_fp32_out_fake(
16
+ input: torch.Tensor,
17
+ output: torch.Tensor,
18
+ ) -> None:
19
+ if input.dim() < 2:
20
+ raise RuntimeError("input must have at least two dimensions")
21
+ if input.shape != output.shape:
22
+ raise RuntimeError("output must have the same shape as input")
23
+ if input.shape[-2] != input.shape[-1]:
24
+ raise RuntimeError("the last two dimensions must be square")
25
+ if input.shape[-1] not in (32, 64, 128):
26
+ raise RuntimeError("supported matrix orders are 32, 64, and 128")
27
+ return None
28
+
29
+
30
+ def cholesky_small_fp32(
31
+ input: torch.Tensor,
32
+ *,
33
+ out: Optional[torch.Tensor] = None,
34
+ ) -> torch.Tensor:
35
+ """Compute a lower-triangular Cholesky factor for small FP32 matrices.
36
+
37
+ ``input`` must be a contiguous CUDA FP32 tensor whose last two dimensions
38
+ are ``(n, n)`` with ``n`` equal to 32, 64, or 128. All leading dimensions
39
+ are flattened into a batch. The input matrices must be symmetric positive
40
+ definite. The output's upper triangle is explicitly zero.
41
+ """
42
+
43
+ if out is None:
44
+ out = torch.empty_like(input)
45
+ ops.cholesky_small_fp32_out(input, out)
46
+ return out
47
+
48
+
49
+ __all__ = ["cholesky_small_fp32"]
build/torch213-cxx11-cu132-x86_64-linux/_ops.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from . import _small_matrix_cholesky_cuda_f291092
3
+ ops = torch.ops._small_matrix_cholesky_cuda_f291092
4
+
5
+ def add_op_namespace_prefix(op_name: str):
6
+ """
7
+ Prefix op by namespace.
8
+ """
9
+ return f"_small_matrix_cholesky_cuda_f291092::{op_name}"
build/torch213-cxx11-cu132-x86_64-linux/_small_matrix_cholesky_cuda_f291092.abi3.so ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b39ed276bb8022d95688b0560eb3ae4acef9e0f31e2b0ab4ac224f5a4da1209f
3
+ size 596104
build/torch213-cxx11-cu132-x86_64-linux/metadata.json ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "small-matrix-cholesky",
3
+ "id": "_small_matrix_cholesky_cuda_f291092",
4
+ "version": 1,
5
+ "license": "Apache-2.0",
6
+ "python-depends": [],
7
+ "backend": {
8
+ "type": "cuda",
9
+ "archs": [
10
+ "10.0",
11
+ "12.0",
12
+ "8.0",
13
+ "9.0"
14
+ ]
15
+ },
16
+ "digest": {
17
+ "algorithm": "sha256",
18
+ "files": {
19
+ "__init__.py": "Sc7qcYjgjttvRwa0SznImIQhKoGy51oSJJjOznvvj18=",
20
+ "_ops.py": "wQ0b98E+GklbX93H03G+NzmGEGs2jD8ZzF6+DdmylWA=",
21
+ "_small_matrix_cholesky_cuda_f291092.abi3.so": "s57SdruAItlWiLBWDrOuSs754PMeKwq0rCJPWk2hIJ8=",
22
+ "small_matrix_cholesky/__init__.py": "DFYPlrhXwYjEqCl/8n0SmWGZV8NFml5DPhMjKfv98GY="
23
+ }
24
+ },
25
+ "provenance": {
26
+ "kernel-builder": {
27
+ "version": "0.17.0-dev0",
28
+ "sha": "19aaa6421e674e9fecc352bbae6eab81d19a6bf4",
29
+ "dirty": false
30
+ },
31
+ "kernel": {
32
+ "sha": "f2910927e5fe824a1212a8147067b687e6b6d2ed",
33
+ "dirty": false
34
+ }
35
+ }
36
+ }
build/torch213-cxx11-cu132-x86_64-linux/small_matrix_cholesky/__init__.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import ctypes
2
+ import importlib.util
3
+ import sys
4
+ from pathlib import Path
5
+ from types import ModuleType
6
+
7
+
8
+ def _import_from_path(file_path: Path) -> ModuleType:
9
+ # We cannot use the module name as-is, after adding it to `sys.modules`,
10
+ # it would also be used for other imports. So, we make a module name that
11
+ # depends on the path for it to be unique using the hex-encoded hash of
12
+ # the path.
13
+ path_hash = "{:x}".format(ctypes.c_size_t(hash(file_path.absolute())).value)
14
+ module_name = path_hash
15
+ spec = importlib.util.spec_from_file_location(module_name, file_path)
16
+ if spec is None:
17
+ raise ImportError(f"Cannot load spec for {module_name} from {file_path}")
18
+ module = importlib.util.module_from_spec(spec)
19
+ if module is None:
20
+ raise ImportError(f"Cannot load module {module_name} from spec")
21
+ sys.modules[module_name] = module
22
+ spec.loader.exec_module(module) # type: ignore
23
+ return module
24
+
25
+
26
+ globals().update(vars(_import_from_path(Path(__file__).parent.parent / "__init__.py")))
Free AI Image Generator No sign-up. Instant results. Open Now