File size: 7,048 Bytes
8604228 | 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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | #!/bin/sh
# OB-1b: stand up the ob1b engine build.
#
# WHY THIS IS NOT A PLAIN FRESH BUILD. The landed OB-1 build
# (/root/rs053/llama.cpp/build, branch ob1 head c087083) is configured with
# GGML_CUDA=ON, so a from-scratch reconfigure recompiles several hundred nvcc
# translation units (measured: still grinding through
# ggml-cuda/template-instances after 3 minutes at -j4) for a change of ONE
# character in one CPU-side source file. This script instead copies the landed
# build tree into the ob1b worktree, rewrites the absolute source paths inside
# it, lets cmake regenerate its makefiles against the new source root, and then
# recompiles ONLY the translation units that actually changed.
#
# THE SOUNDNESS CHECK IS PHASE A, AND IT IS NOT TAUTOLOGICAL. Phase A touches
# src/ob1-lease.cpp with its CONTENT UNCHANGED and runs make. That genuinely
# recompiles that translation unit in the new tree and relinks libllama.so and
# llama-perplexity. The results are then compared by sha256 against the landed
# binaries. A match proves the copied object tree plus this toolchain reproduce
# the landed engine byte for byte, so that after phase B the ONLY thing
# separating the ob1b binary from the ob1 binary is the one-line guard change.
# A mismatch is reported literally, not worked around.
set -e
SRC=/root/rs053/llama.cpp
DST=/root/ob1b/llama.cpp
LEASE=$DST/src/ob1-lease.cpp
echo "=== OB1B BUILD ==="
echo "utc_start $(date -u +%Y-%m-%dT%H:%M:%SZ)"
# This script must be re-runnable. Restore src/ob1-lease.cpp to its pristine
# c087083 content first, so that phase A always compiles UNPATCHED source no
# matter how many times the script has run before. (Found the hard way: a second
# invocation reused the already-patched file left by the first, which would have
# made phase A compare the patched build against the landed one and call the
# guard change a build-system artefact.)
echo "--- restore pristine source ---"
git -C $DST checkout -- src/ob1-lease.cpp
git -C $DST status --short
echo "guard line as checked out:"
grep -n "OB1_K=%d out of range" $LEASE
echo "--- landed binaries (the reference) ---"
sha256sum $SRC/build/bin/llama-perplexity $SRC/build/bin/libllama.so
echo "--- copy build tree ---"
rm -rf $DST/build
cp -a $SRC/build $DST/build
echo "--- rewrite absolute source paths in text files only (grep -I skips binaries) ---"
echo "text files referencing old source dir: $(grep -rlI "$SRC" $DST/build | wc -l)"
grep -rlI "$SRC" $DST/build | xargs sed -i "s|$SRC|$DST|g"
echo "remaining after rewrite: $(grep -rlI "$SRC" $DST/build | wc -l)"
echo "--- cmake reconfigure against the new source root ---"
# -ffile-prefix-map is what makes phase A an EXACT check rather than an
# approximate one. Source files embed their own path through __FILE__ (llama.cpp
# uses it in its assert macros), so a translation unit recompiled under
# /root/ob1b/... would differ from the landed /root/rs053/... object in that
# string alone -- a benign difference, but one that would leave phase A unable
# to say "byte for byte". Measured on the first attempt of this script, without
# the flag: landed libllama.so carried 151 occurrences of "rs053/llama.cpp" and
# the rebuilt one carried 150 plus 1 occurrence of "ob1b/llama.cpp", exactly the
# one recompiled translation unit. The flag maps the new root back to the old
# one for embedded paths only; it changes no code generation.
cmake -S $DST -B $DST/build -DCMAKE_CXX_FLAGS="-ffile-prefix-map=$DST=$SRC" \
> /root/ob1b/cmake-reconf.log 2>&1 || {
echo "CMAKE RECONFIGURE FAILED, log verbatim:"; cat /root/ob1b/cmake-reconf.log; exit 1; }
tail -3 /root/ob1b/cmake-reconf.log
echo "--- age the checked-out sources so make does not rebuild all 392 objects ---"
# git worktree add stamped every checked-out file with the checkout time, which
# is newer than every copied .o; and the sed above bumped every makefile. Both
# would make make rebuild the world. The objects were compiled from byte-
# identical sources at the same commit, so reusing them is sound -- and phase A
# is the check that proves it rather than assuming it.
find $DST -path $DST/build -prune -o -type f -print | xargs -r touch -d "2020-01-01 00:00:00"
sleep 1
find $DST/build \( -name "*.o" -o -name "*.a" -o -name "*.so" -o -name "*.so.*" \) -print | xargs -r touch
find $DST/build/bin -type f -print | xargs -r touch
sleep 1
echo "--- confirm the tree is now fully up to date (make should have nothing to do) ---"
nice -n 10 make -C $DST/build llama-perplexity -j4 2>&1 | tail -5
echo "=== PHASE A: recompile ob1-lease.cpp UNCHANGED, must reproduce the landed binaries ==="
touch $LEASE
nice -n 10 make -C $DST/build llama-perplexity -j4 2>&1 | tail -12
echo "--- phase A digests ---"
sha256sum $DST/build/bin/llama-perplexity $DST/build/bin/libllama.so
A1=$(sha256sum $SRC/build/bin/llama-perplexity | cut -d" " -f1)
A2=$(sha256sum $DST/build/bin/llama-perplexity | cut -d" " -f1)
B1=$(sha256sum $SRC/build/bin/libllama.so | cut -d" " -f1)
B2=$(sha256sum $DST/build/bin/libllama.so | cut -d" " -f1)
if [ "$A1" = "$A2" ] && [ "$B1" = "$B2" ]; then
echo "PHASE A: MATCH (object reuse + relink reproduces the landed engine byte for byte)"
else
echo "PHASE A: DIFFER"
echo " llama-perplexity landed=$A1 ob1b=$A2"
echo " libllama.so landed=$B1 ob1b=$B2"
echo " sizes:"; ls -l $SRC/build/bin/libllama.so $DST/build/bin/libllama.so
echo " --- does the binary embed its own source path? (the usual benign cause) ---"
echo " landed hits: $(strings $SRC/build/bin/libllama.so | grep -c "rs053/llama.cpp" || true)"
echo " ob1b hits: $(strings $DST/build/bin/libllama.so | grep -c "ob1b/llama.cpp" || true)"
fi
echo "=== PHASE B: the one-line K=0 guard fix ==="
echo "--- before ---"
grep -n "OB1_K=%d out of range" $LEASE
# Exact literal replacement with a count assertion. Not sed: the line contains
# "||", and every convenient sed delimiter collides with something in it.
python3 - "$LEASE" <<'PYEOF'
import sys
p = sys.argv[1]
old = 'if (g_K <= 0 || g_K > g_E) ob1_fatal("OB1_K=%d out of range 1..%d", g_K, g_E);'
new = 'if (g_K < 0 || g_K > g_E) ob1_fatal("OB1_K=%d out of range 0..%d", g_K, g_E);'
s = open(p).read()
n = s.count(old)
if n != 1:
sys.exit("GUARD EDIT ABORTED: expected exactly 1 occurrence, found %d" % n)
open(p, "w").write(s.replace(old, new))
print("guard edit applied: 1 occurrence replaced")
PYEOF
echo "--- after ---"
grep -n "OB1_K=%d out of range" $LEASE
echo "--- diff ---"
cd $DST && git diff --stat && git diff
nice -n 10 make -C $DST/build llama-perplexity -j4 2>&1 | tail -12
echo "--- phase B digests (the binary every OB-1b run uses) ---"
sha256sum $DST/build/bin/llama-perplexity $DST/build/bin/libllama.so
C2=$(sha256sum $DST/build/bin/libllama.so | cut -d" " -f1)
if [ "$B1" = "$C2" ]; then
echo "PHASE B: libllama.so UNCHANGED after the edit -- the edit did not take, STOP"
else
echo "PHASE B: libllama.so changed, as the one-line edit requires"
fi
echo "utc_end $(date -u +%Y-%m-%dT%H:%M:%SZ)"
echo "=== END OB1B BUILD ==="
|