CharlesCNorton
commited on
Commit
·
3a9b35a
1
Parent(s):
822e28a
Standardize build output filenames with explicit bit widths
Browse filesAdd auto-generated filenames based on configuration:
- Format: neural_{alu|computer}{BITS}[_{MEMORY}].safetensors
- All bit widths (8/16/32) now explicit in filename
- Memory profiles: _reduced, _small, _scratchpad, _registers
- Custom addr-bits: _addrN suffix
- Enhanced CLI help with detailed argument descriptions
- Updated README with new naming scheme and examples
README.md
CHANGED
|
@@ -178,7 +178,7 @@ The weights in this repository implement a complete 8-bit computer: registers, A
|
|
| 178 |
import torch
|
| 179 |
from safetensors.torch import load_file
|
| 180 |
|
| 181 |
-
tensors = load_file("
|
| 182 |
|
| 183 |
def heaviside(x):
|
| 184 |
return (x >= 0).float()
|
|
@@ -705,18 +705,37 @@ This approach treats the problem as what it is: a structured parsing task where
|
|
| 705 |
|
| 706 |
## Build Tool
|
| 707 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 708 |
```bash
|
| 709 |
# 8-bit CPU (default)
|
| 710 |
-
python build.py --apply all #
|
| 711 |
-
python build.py -m none --apply all #
|
| 712 |
-
python build.py -m scratchpad --apply all #
|
|
|
|
|
|
|
|
|
|
|
|
|
| 713 |
|
| 714 |
# 32-bit ALU
|
| 715 |
-
python build.py --bits 32 -m small --apply all #
|
| 716 |
-
python build.py --bits 32 -m none --apply all #
|
| 717 |
|
| 718 |
-
# Custom
|
| 719 |
-
python build.py --bits 16
|
| 720 |
```
|
| 721 |
|
| 722 |
**Bit widths** (`--bits`):
|
|
@@ -729,14 +748,16 @@ python build.py --bits 16 --addr-bits 6 --apply all # 16-bit ALU, 64 byte
|
|
| 729 |
|
| 730 |
**Memory profiles** (`-m`):
|
| 731 |
|
| 732 |
-
| Profile | Size | Params | Use Case |
|
| 733 |
-
|
| 734 |
-
| `none` | 0B | ~32K | Pure ALU |
|
| 735 |
-
| `registers` | 16B | ~34K | Minimal state |
|
| 736 |
-
| `scratchpad` | 256B | ~63K | 8-bit scratch |
|
| 737 |
-
| `small` | 1KB | ~123K | 32-bit scratch |
|
| 738 |
-
| `reduced` | 4KB | ~549K | Small programs |
|
| 739 |
-
| `full` | 64KB | ~8.29M | Full CPU |
|
|
|
|
|
|
|
| 740 |
|
| 741 |
---
|
| 742 |
|
|
|
|
| 178 |
import torch
|
| 179 |
from safetensors.torch import load_file
|
| 180 |
|
| 181 |
+
tensors = load_file("neural_computer8.safetensors")
|
| 182 |
|
| 183 |
def heaviside(x):
|
| 184 |
return (x >= 0).float()
|
|
|
|
| 705 |
|
| 706 |
## Build Tool
|
| 707 |
|
| 708 |
+
Output filenames are auto-generated from configuration:
|
| 709 |
+
|
| 710 |
+
```
|
| 711 |
+
Format: neural_{alu|computer}{BITS}[_{MEMORY}].safetensors
|
| 712 |
+
|
| 713 |
+
Examples:
|
| 714 |
+
neural_alu8.safetensors # 8-bit, no memory
|
| 715 |
+
neural_alu32.safetensors # 32-bit, no memory
|
| 716 |
+
neural_computer8.safetensors # 8-bit, full memory (default)
|
| 717 |
+
neural_computer32.safetensors # 32-bit, full memory
|
| 718 |
+
neural_computer8_small.safetensors # 8-bit, 1KB memory
|
| 719 |
+
neural_computer32_small.safetensors # 32-bit, 1KB memory
|
| 720 |
+
neural_computer8_addr12.safetensors # 8-bit, custom 4KB (2^12 bytes)
|
| 721 |
+
```
|
| 722 |
+
|
| 723 |
```bash
|
| 724 |
# 8-bit CPU (default)
|
| 725 |
+
python build.py --apply all # -> neural_computer8.safetensors
|
| 726 |
+
python build.py -m none --apply all # -> neural_alu8.safetensors
|
| 727 |
+
python build.py -m scratchpad --apply all # -> neural_computer8_scratchpad.safetensors
|
| 728 |
+
|
| 729 |
+
# 16-bit ALU
|
| 730 |
+
python build.py --bits 16 --apply all # -> neural_computer16.safetensors
|
| 731 |
+
python build.py --bits 16 -m none --apply all # -> neural_alu16.safetensors
|
| 732 |
|
| 733 |
# 32-bit ALU
|
| 734 |
+
python build.py --bits 32 -m small --apply all # -> neural_computer32_small.safetensors
|
| 735 |
+
python build.py --bits 32 -m none --apply all # -> neural_alu32.safetensors
|
| 736 |
|
| 737 |
+
# Custom address width
|
| 738 |
+
python build.py --bits 16 -a 6 --apply all # -> neural_computer16_addr6.safetensors
|
| 739 |
```
|
| 740 |
|
| 741 |
**Bit widths** (`--bits`):
|
|
|
|
| 748 |
|
| 749 |
**Memory profiles** (`-m`):
|
| 750 |
|
| 751 |
+
| Profile | Size | Addr Bits | Filename Suffix | Params | Use Case |
|
| 752 |
+
|---------|------|-----------|-----------------|--------|----------|
|
| 753 |
+
| `none` | 0B | — | (uses `alu`) | ~32K | Pure ALU |
|
| 754 |
+
| `registers` | 16B | 4 | `_registers` | ~34K | Minimal state |
|
| 755 |
+
| `scratchpad` | 256B | 8 | `_scratchpad` | ~63K | 8-bit scratch |
|
| 756 |
+
| `small` | 1KB | 10 | `_small` | ~123K | 32-bit scratch |
|
| 757 |
+
| `reduced` | 4KB | 12 | `_reduced` | ~549K | Small programs |
|
| 758 |
+
| `full` | 64KB | 16 | (none) | ~8.29M | Full CPU |
|
| 759 |
+
|
| 760 |
+
**Custom address width** (`-a N`): Memory size = 2^N bytes, suffix = `_addrN`
|
| 761 |
|
| 762 |
---
|
| 763 |
|
build.py
CHANGED
|
@@ -112,7 +112,34 @@ from safetensors import safe_open
|
|
| 112 |
from safetensors.torch import save_file
|
| 113 |
|
| 114 |
|
| 115 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 116 |
MANIFEST_PATH = Path(__file__).resolve().parent / "tensors.txt"
|
| 117 |
|
| 118 |
DEFAULT_ADDR_BITS = 16
|
|
@@ -2288,46 +2315,99 @@ ALU Bit Widths:
|
|
| 2288 |
16 16-bit ALU (0-65535)
|
| 2289 |
32 32-bit ALU (0-4294967295)
|
| 2290 |
|
| 2291 |
-
|
| 2292 |
-
|
| 2293 |
-
|
| 2294 |
-
|
| 2295 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2296 |
"""
|
| 2297 |
)
|
| 2298 |
-
parser.add_argument(
|
| 2299 |
-
|
| 2300 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2301 |
parser.add_argument(
|
| 2302 |
"--bits", "-b",
|
| 2303 |
type=int,
|
| 2304 |
choices=SUPPORTED_BITS,
|
| 2305 |
default=8,
|
| 2306 |
-
help="ALU bit width
|
| 2307 |
)
|
| 2308 |
|
| 2309 |
mem_group = parser.add_mutually_exclusive_group()
|
| 2310 |
mem_group.add_argument(
|
| 2311 |
"--memory-profile", "-m",
|
| 2312 |
choices=list(MEMORY_PROFILES.keys()),
|
| 2313 |
-
help="Memory
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2314 |
)
|
| 2315 |
mem_group.add_argument(
|
| 2316 |
"--addr-bits", "-a",
|
| 2317 |
type=int,
|
| 2318 |
choices=range(0, 17),
|
| 2319 |
metavar="N",
|
| 2320 |
-
help="
|
| 2321 |
)
|
| 2322 |
|
| 2323 |
subparsers = parser.add_subparsers(dest="command", help="Subcommands")
|
| 2324 |
-
subparsers.add_parser("memory", help="Generate memory circuits (
|
| 2325 |
-
subparsers.add_parser("alu", help="Generate ALU
|
| 2326 |
-
subparsers.add_parser("inputs", help="Add .inputs metadata tensors")
|
| 2327 |
-
subparsers.add_parser("all", help="Run memory
|
| 2328 |
|
| 2329 |
args = parser.parse_args()
|
| 2330 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2331 |
if args.command == "memory":
|
| 2332 |
cmd_memory(args)
|
| 2333 |
elif args.command == "alu":
|
|
|
|
| 112 |
from safetensors.torch import save_file
|
| 113 |
|
| 114 |
|
| 115 |
+
MODEL_DIR = Path(__file__).resolve().parent
|
| 116 |
+
|
| 117 |
+
|
| 118 |
+
def get_model_path(bits: int = 8, memory_profile: str = None, addr_bits: int = None) -> Path:
|
| 119 |
+
"""Generate model filename based on configuration."""
|
| 120 |
+
if addr_bits is not None:
|
| 121 |
+
if addr_bits == 0:
|
| 122 |
+
has_memory = False
|
| 123 |
+
mem_suffix = ""
|
| 124 |
+
else:
|
| 125 |
+
has_memory = True
|
| 126 |
+
mem_suffix = f"_addr{addr_bits}"
|
| 127 |
+
elif memory_profile == "none":
|
| 128 |
+
has_memory = False
|
| 129 |
+
mem_suffix = ""
|
| 130 |
+
elif memory_profile == "full" or memory_profile is None:
|
| 131 |
+
has_memory = True
|
| 132 |
+
mem_suffix = ""
|
| 133 |
+
else:
|
| 134 |
+
has_memory = True
|
| 135 |
+
mem_suffix = f"_{memory_profile}"
|
| 136 |
+
|
| 137 |
+
base = "neural_alu" if not has_memory else "neural_computer"
|
| 138 |
+
|
| 139 |
+
return MODEL_DIR / f"{base}{bits}{mem_suffix}.safetensors"
|
| 140 |
+
|
| 141 |
+
|
| 142 |
+
MODEL_PATH = MODEL_DIR / "neural_computer8.safetensors"
|
| 143 |
MANIFEST_PATH = Path(__file__).resolve().parent / "tensors.txt"
|
| 144 |
|
| 145 |
DEFAULT_ADDR_BITS = 16
|
|
|
|
| 2315 |
16 16-bit ALU (0-65535)
|
| 2316 |
32 32-bit ALU (0-4294967295)
|
| 2317 |
|
| 2318 |
+
Output Filenames (auto-generated from config):
|
| 2319 |
+
Format: neural_{alu|computer}{BITS}[_{MEMORY}].safetensors
|
| 2320 |
+
|
| 2321 |
+
Memory suffix:
|
| 2322 |
+
-m full -> (none)
|
| 2323 |
+
-m reduced -> _reduced
|
| 2324 |
+
-m small -> _small
|
| 2325 |
+
-m scratchpad -> _scratchpad
|
| 2326 |
+
-m registers -> _registers
|
| 2327 |
+
-m none -> (uses "alu" instead of "computer")
|
| 2328 |
+
-a N -> _addrN
|
| 2329 |
+
|
| 2330 |
+
Examples:
|
| 2331 |
+
neural_alu8.safetensors # 8-bit, no memory
|
| 2332 |
+
neural_alu16.safetensors # 16-bit, no memory
|
| 2333 |
+
neural_alu32.safetensors # 32-bit, no memory
|
| 2334 |
+
neural_computer8.safetensors # 8-bit, full memory
|
| 2335 |
+
neural_computer16.safetensors # 16-bit, full memory
|
| 2336 |
+
neural_computer32.safetensors # 32-bit, full memory
|
| 2337 |
+
neural_computer8_reduced.safetensors # 8-bit, reduced memory
|
| 2338 |
+
neural_computer32_reduced.safetensors# 32-bit, reduced memory
|
| 2339 |
+
neural_computer8_small.safetensors # 8-bit, small memory
|
| 2340 |
+
neural_computer32_small.safetensors # 32-bit, small memory
|
| 2341 |
+
neural_computer8_addr12.safetensors # 8-bit, custom 12-bit address
|
| 2342 |
+
neural_computer32_addr10.safetensors # 32-bit, custom 10-bit address
|
| 2343 |
+
|
| 2344 |
+
Usage (note: options must come BEFORE subcommand):
|
| 2345 |
+
python build.py --apply all # -> neural_computer8.safetensors
|
| 2346 |
+
python build.py -m none --apply all # -> neural_alu8.safetensors
|
| 2347 |
+
python build.py -m reduced --apply all # -> neural_computer8_reduced.safetensors
|
| 2348 |
+
python build.py --bits 16 --apply all # -> neural_computer16.safetensors
|
| 2349 |
+
python build.py --bits 32 --apply all # -> neural_computer32.safetensors
|
| 2350 |
+
python build.py --bits 32 -m none --apply all # -> neural_alu32.safetensors
|
| 2351 |
+
python build.py --bits 32 -m small --apply all # -> neural_computer32_small.safetensors
|
| 2352 |
+
python build.py --bits 32 -a 10 --apply all # -> neural_computer32_addr10.safetensors
|
| 2353 |
"""
|
| 2354 |
)
|
| 2355 |
+
parser.add_argument(
|
| 2356 |
+
"--model", type=Path, default=None,
|
| 2357 |
+
help="Output path. Auto-generated as neural_{alu|computer}{BITS}[_{MEMORY}].safetensors if not specified"
|
| 2358 |
+
)
|
| 2359 |
+
parser.add_argument(
|
| 2360 |
+
"--apply", action="store_true",
|
| 2361 |
+
help="Apply changes to model file. Without this flag, runs in dry-run mode (no writes)"
|
| 2362 |
+
)
|
| 2363 |
+
parser.add_argument(
|
| 2364 |
+
"--manifest", action="store_true",
|
| 2365 |
+
help="Write tensors.txt manifest listing all tensors (memory command only)"
|
| 2366 |
+
)
|
| 2367 |
parser.add_argument(
|
| 2368 |
"--bits", "-b",
|
| 2369 |
type=int,
|
| 2370 |
choices=SUPPORTED_BITS,
|
| 2371 |
default=8,
|
| 2372 |
+
help="ALU bit width. 8=0-255 (default), 16=0-65535, 32=0-4294967295"
|
| 2373 |
)
|
| 2374 |
|
| 2375 |
mem_group = parser.add_mutually_exclusive_group()
|
| 2376 |
mem_group.add_argument(
|
| 2377 |
"--memory-profile", "-m",
|
| 2378 |
choices=list(MEMORY_PROFILES.keys()),
|
| 2379 |
+
help="""Memory profile:
|
| 2380 |
+
full=64KB/16-bit addr (suffix: none),
|
| 2381 |
+
reduced=4KB/12-bit (suffix: _reduced),
|
| 2382 |
+
small=1KB/10-bit (suffix: _small),
|
| 2383 |
+
scratchpad=256B/8-bit (suffix: _scratchpad),
|
| 2384 |
+
registers=16B/4-bit (suffix: _registers),
|
| 2385 |
+
none=0B/pure ALU (uses 'alu' in filename)"""
|
| 2386 |
)
|
| 2387 |
mem_group.add_argument(
|
| 2388 |
"--addr-bits", "-a",
|
| 2389 |
type=int,
|
| 2390 |
choices=range(0, 17),
|
| 2391 |
metavar="N",
|
| 2392 |
+
help="Custom address bus width 0-16. Memory size=2^N bytes. 0=pure ALU. Suffix: _addrN"
|
| 2393 |
)
|
| 2394 |
|
| 2395 |
subparsers = parser.add_subparsers(dest="command", help="Subcommands")
|
| 2396 |
+
subparsers.add_parser("memory", help="Generate memory circuits (decoder, read mux, write cells)")
|
| 2397 |
+
subparsers.add_parser("alu", help="Generate N-bit ALU circuits (adder, sub, mul, div, cmp, bitwise, shift)")
|
| 2398 |
+
subparsers.add_parser("inputs", help="Add .inputs metadata tensors for gate routing")
|
| 2399 |
+
subparsers.add_parser("all", help="Run all: memory -> alu -> inputs")
|
| 2400 |
|
| 2401 |
args = parser.parse_args()
|
| 2402 |
|
| 2403 |
+
if args.model is None:
|
| 2404 |
+
args.model = get_model_path(
|
| 2405 |
+
bits=args.bits,
|
| 2406 |
+
memory_profile=getattr(args, 'memory_profile', None),
|
| 2407 |
+
addr_bits=getattr(args, 'addr_bits', None)
|
| 2408 |
+
)
|
| 2409 |
+
print(f"Auto-generated model path: {args.model}")
|
| 2410 |
+
|
| 2411 |
if args.command == "memory":
|
| 2412 |
cmd_memory(args)
|
| 2413 |
elif args.command == "alu":
|