Repository navigation
Expand file tree
/
Copy pathMakefile
More file actions
118 lines (93 loc) · 4.52 KB
/
Copy pathMakefile
File metadata and controls
118 lines (93 loc) · 4.52 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
CXX ?= c++
CXXFLAGS ?= -O2 -Wall -Wextra
# The language standard is kept out of CXXFLAGS, so that
# `make CXXFLAGS=...` (e.g. to add sanitizers) cannot drop it.
STD = -std=c++20
# Shared code, named once. Headers are listed as prerequisites so that
# editing one rebuilds what uses it; $(filter %.cpp,$^) then passes only
# the .cpp files to the compiler.
CORE = weights.cpp safetensors.cpp json.cpp mmap.cpp profile.cpp threads.cpp cpu.cpp \
weights.h safetensors.h json.h mmap.h profile.h threads.h cpu.h
MODEL_SRC = ops.cpp ops.h quant.cpp quant.h blocks.cpp blocks.h encoder.cpp encoder.h \
temporal.cpp temporal.h depth.cpp depth.h conv.cpp conv.h codec.cpp codec.h
BUILD = $(CXX) $(STD) $(CXXFLAGS) -o $@ $(filter %.cpp,$^)
all: mrt2 mrt2dump mrt2info
# The program: generate music. Audio output uses the OS's own API, linked
# from the system: CoreAudio (macOS) or ALSA (Linux, needs the libasound
# development headers to build); Windows (WASAPI) needs only ole32.
UNAME := $(shell uname -s)
ifeq ($(UNAME),Darwin)
AUDIO_LIBS = -framework AudioToolbox -framework CoreFoundation
else ifeq ($(OS),Windows_NT)
AUDIO_LIBS = -lole32
else
AUDIO_LIBS = -lasound -lpthread
endif
mrt2: mrt2.cpp audio.cpp audio.h ring.h $(MODEL_SRC) $(CORE)
$(BUILD) $(AUDIO_LIBS)
mrt2dump: mrt2dump.cpp mmap.cpp mmap.h
$(BUILD)
mrt2info: mrt2info.cpp $(CORE)
$(BUILD)
tests/test_mmap: tests/test_mmap.cpp mmap.cpp mmap.h
$(BUILD)
tests/test_weights: tests/test_weights.cpp $(CORE)
$(BUILD)
tests/test_ops: tests/test_ops.cpp tests/test.h ops.cpp ops.h $(CORE)
$(BUILD)
tests/test_conv: tests/test_conv.cpp tests/test.h conv.cpp conv.h ops.cpp ops.h profile.cpp profile.h \
threads.cpp threads.h cpu.cpp cpu.h
$(BUILD)
tests/test_encoder: tests/test_encoder.cpp tests/test.h $(MODEL_SRC) $(CORE)
$(BUILD)
tests/test_temporal: tests/test_temporal.cpp tests/test.h $(MODEL_SRC) $(CORE)
$(BUILD)
tests/test_depth: tests/test_depth.cpp tests/test.h $(MODEL_SRC) $(CORE)
$(BUILD)
tests/test_codec: tests/test_codec.cpp tests/test.h $(MODEL_SRC) $(CORE)
$(BUILD)
tests/test_threads: tests/test_threads.cpp tests/test.h $(MODEL_SRC) $(CORE)
$(BUILD)
tests/test_ring: tests/test_ring.cpp tests/test.h ring.h
$(BUILD)
tests/test_quant: tests/test_quant.cpp tests/test.h $(MODEL_SRC) $(CORE)
$(BUILD)
# Speed spike (measurement tool, not the engine): built the way release
# code will be, fully optimized for this machine's CPU.
NATIVE = $(if $(filter arm64 aarch64,$(shell uname -m)),-mcpu=native,-march=native)
tools/spike_bench: tools/spike_bench.cpp ops.cpp ops.h $(CORE)
$(CXX) $(STD) -O3 $(NATIVE) -Wall -Wextra -o $@ $(filter %.cpp,$^)
spike: tools/spike_bench
./tools/spike_bench "$(MODEL)"
# Benchmark (step 8): the real model with the profiler on, built the way
# release code will be. `make bench` prints the roofline table.
tools/bench: tools/bench.cpp $(MODEL_SRC) $(CORE)
$(CXX) $(STD) -O3 $(NATIVE) -DMRT2_PROFILE -Wall -Wextra -o $@ $(filter %.cpp,$^)
bench: tools/bench
./tools/bench "$(MODEL)"
# The tests read the real model; the ones in REF_TESTS also compare with
# Google's numbers (create those once with `make ref`).
# Override the paths with `make test MODEL=... REF=...`.
MODEL ?= $(HOME)/models/magenta-rt-v2/checkpoints/mrt2_small.safetensors
REF ?= $(HOME)/models/magenta-rt-v2/ref/ref_small.safetensors
UNIT_TESTS = tests/test_conv tests/test_ring
FILE_TESTS = tests/test_mmap tests/test_weights
REF_TESTS = tests/test_ops tests/test_encoder tests/test_temporal tests/test_depth tests/test_codec \
tests/test_threads tests/test_quant
TESTS = $(UNIT_TESTS) $(FILE_TESTS) $(REF_TESTS)
# Build every test, then run each one; make stops at the first failure.
# Last, check that every weight in the model is a real number.
test: $(TESTS) mrt2info
@for t in $(UNIT_TESTS); do echo "== $$t"; ./$$t || exit 1; done
@for t in $(FILE_TESTS); do echo "== $$t"; ./$$t "$(MODEL)" || exit 1; done
@for t in $(REF_TESTS); do echo "== $$t"; ./$$t "$(MODEL)" "$(REF)" || exit 1; done
@echo "== mrt2info --verify"; ./mrt2info --verify "$(MODEL)"
# Reference data from Google's JAX model (Python, dev only), then check
# the plan's model spec against it. Re-run only if the dump tool changes.
ref:
MAGENTA_HOME=$(HOME)/models JAX_PLATFORMS=cpu .venv/bin/python tools/dump_reference.py --out "$(REF)"
.venv/bin/python tools/check_spec.py "$(REF)" "$(MODEL)"
clean:
rm -f mrt2 mrt2dump mrt2info $(TESTS) tools/spike_bench tools/bench
rm -rf *.dSYM tests/*.dSYM tools/*.dSYM
.PHONY: all clean test ref spike bench