Files
sum-parts-test/scripts/patch_numpy_aliases.sh
nbrightandClaude Opus 5 609d9a6972 Add SUM Parts reproduction and Seosan Myeongcheon application pipeline
Reproduces the SUM Parts (CVPR 2025) face-labeling benchmark on a single
consumer GPU, then applies it to drone-photogrammetry road survey meshes.

Verified on RTX 3060 12GB / WSL2 Ubuntu 22.04 / CUDA 11.8 / torch 2.0.1:
- CUDA extensions build (pointnet2_batch, pointops, chamfer_dist, emd,
  subsampling)
- PointNet 100 epochs reaches mIoU 17.19, matching the paper's reported 15.1
- OBJ -> PLY conversion round-trips through the model and yields per-point
  predictions

Four upstream source patches, all idempotent, originals preserved:
- numpy aliases removed in 1.24 (np.long etc.) and collections ABCs moved in
  python 3.10
- the blind test split ships label = -1, which crashed ConfusionMatrix
- mode=val referenced `epoch` before assignment

Documents the traps that cost the most time, including VRAM overflow silently
falling back to host RAM on WSL2 (25-100x slowdown, no OOM) and the colour
scale mismatch between r/g/b float32 and red/green/blue uint8.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-21 10:29:25 +09:00

83 lines
2.9 KiB
Bash

#!/usr/bin/env bash
# SUM Parts - modernise APIs the upstream code uses that newer runtimes removed
#
# Two families, same root cause (2022 code on a 2025 toolchain):
# 1. numpy aliases removed in numpy 1.24
# 2. collections ABCs moved to collections.abc in python 3.10
#
# The upstream env pins numpy 1.20, where np.long / np.int / np.float / np.bool
# / np.object / np.str still existed as aliases. numpy 1.24 removed them, so on
# any modern numpy the dataset loaders die inside a DataLoader worker with
#
# AttributeError: module 'numpy' has no attribute 'long'
#
# and the traceback points at the worker, not at the version mismatch.
#
# Downgrading numpy is not an option here: torch 2.0.1 needs numpy<2 but
# numpy 1.20 has no python 3.10 wheels. So patch the source instead.
#
# Mapping follows what the aliases actually were:
# np.long -> np.int64 (alias of python int, i.e. C long)
# np.int -> int
# np.float -> float
# np.bool -> bool
# np.object -> object
# np.str -> str
#
# Idempotent: re-running finds nothing to change. Writes .bak files on first
# touch only.
set -euo pipefail
REPO="${1:-$HOME/sum-parts/semantic_segmentation/PointNeXt_bundle}"
if [ ! -d "$REPO/openpoints" ]; then
echo "error: $REPO does not look like PointNeXt_bundle" >&2
exit 1
fi
cd "$REPO"
ABCS='Iterable\|Mapping\|MutableMapping\|Sequence\|Callable\|Hashable\|Iterator\|Container\|Sized'
PATTERN="np\.long\b\|np\.int\b\|np\.float\b\|np\.bool\b\|np\.object\b\|np\.str\b\|collections\.\($ABCS\)\b"
echo "=== before ==="
grep -rn "$PATTERN" --include='*.py' . || echo " (none)"
# \b keeps np.int from matching np.int32/np.int64, np.float from np.float32, etc.
# The collections rule skips anything already written as collections.abc.X.
find . -name '*.py' -print0 | xargs -0 sed -i.bak \
-e 's/\bnp\.long\b/np.int64/g' \
-e 's/\bnp\.int\b/int/g' \
-e 's/\bnp\.float\b/float/g' \
-e 's/\bnp\.bool\b/bool/g' \
-e 's/\bnp\.object\b/object/g' \
-e 's/\bnp\.str\b/str/g' \
-e "s/\bcollections\.\($ABCS\)\b/collections.abc.\1/g"
# sed -i.bak writes a .bak for every file it opens, not just changed ones
find . -name '*.py.bak' -print0 | while IFS= read -r -d '' b; do
if cmp -s "$b" "${b%.bak}"; then rm -f "$b"; fi
done
# `import collections` alone does not pull in collections.abc on every python,
# so make sure any file that now references collections.abc imports it.
grep -rl 'collections\.abc\.' --include='*.py' . | while IFS= read -r f; do
if ! grep -q '^import collections.abc' "$f"; then
sed -i 's/^import collections$/import collections\nimport collections.abc/' "$f"
fi
done
echo
echo "=== after ==="
if grep -rn "$PATTERN" --include='*.py' .; then
echo "WARNING: some occurrences remain" >&2
else
echo " clean"
fi
echo
echo "=== files changed (.bak kept) ==="
find . -name '*.py.bak' | sed 's/\.bak$//' || true
echo "PATCH DONE"