Files
amethyst/quartz/benchmarks/run_all.sh
T
Claude fa0da7fae3 feat: upgrade negentropy-kmp to v1.0.2, enable macosArm64 target
negentropy-kmp v1.0.2 now publishes a macosArm64 artifact, unblocking
the macOS native target. Wired macosMain/macosTest source sets through
appleMain/appleTest and updated run_all.sh to run the K/Native
benchmark on both Linux (linuxX64) and macOS (macosArm64).

https://claude.ai/code/session_01WSNE6QKiYM2ZutQD2UihCW
2026-04-11 00:44:33 +00:00

171 lines
6.0 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# Run all secp256k1 benchmarks.
# Run from the amethyst root directory:
#
# ./quartz/benchmarks/run_all.sh
#
# Runs: C native, Kotlin/Native, JVM (always), and Android (if device connected).
#
set -uo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
BENCH_DIR="$ROOT/quartz/benchmarks"
# ============================================================================
# Platform detection
# ============================================================================
OS_NAME="$(uname -s)"
ARCH="$(uname -m)"
case "$OS_NAME" in
Linux)
SO_NAME="libsecp256k1-jni.so"
JAR_PLATFORM="linux"
case "$ARCH" in
aarch64|arm64) SO_PATH_PATTERN="*linux-aarch64*" ;;
*) SO_PATH_PATTERN="*linux-x86_64*" ;;
esac
;;
Darwin)
SO_NAME="libsecp256k1-jni.dylib"
JAR_PLATFORM="darwin"
SO_PATH_PATTERN="*darwin*"
;;
*)
echo "Unsupported OS: $OS_NAME"
exit 1
;;
esac
# ============================================================================
# 1. C native benchmark
# ============================================================================
echo "=== Building C native benchmark ==="
SO_PATH=$(find "$HOME/.gradle" -path "*/secp256k1-kmp-jni-jvm-${JAR_PLATFORM}*" -name "*.jar" 2>/dev/null | head -1)
if [ -z "$SO_PATH" ]; then
echo "ACINQ secp256k1-kmp-jni-jvm-${JAR_PLATFORM} JAR not found in Gradle cache."
echo "Run './gradlew :quartz:jvmTest --tests *.Secp256k1Test' first to download it."
exit 1
fi
WORK=$(mktemp -d)
(cd "$WORK" && jar xf "$SO_PATH") 2>/dev/null || true
SO_FILE=$(find "$WORK" -name "$SO_NAME" -path "$SO_PATH_PATTERN" 2>/dev/null | head -1)
if [ -z "$SO_FILE" ]; then
echo "Could not find $SO_NAME for $OS_NAME-$ARCH in JAR."
exit 1
fi
cp "$SO_FILE" "$WORK/"
# On macOS the dylib's LC_ID_DYLIB (install name) is a relative path like
# "build/darwin/libsecp256k1-jni.dylib". dyld resolves it literally, ignoring
# -rpath, so the binary fails at launch. Rewrite the install name to use
# @rpath so the -Wl,-rpath we pass to gcc actually works.
if [ "$OS_NAME" = "Darwin" ]; then
install_name_tool -id "@rpath/$SO_NAME" "$WORK/$SO_NAME" 2>/dev/null || true
fi
if ! gcc -O2 -o "$WORK/bench" "$BENCH_DIR/secp256k1_native_bench.c" \
-L"$WORK" -lsecp256k1-jni -Wl,-rpath,"$WORK" 2>&1; then
echo "gcc compilation failed"
fi
echo "=== Running C native benchmark ==="
if [ -f "$WORK/bench" ]; then
"$WORK/bench" 2>&1
else
echo "(skipped — compilation failed)"
fi
echo ""
# ============================================================================
# 2. Kotlin/Native benchmark (Linux and macOS)
# ============================================================================
echo "=== Running Kotlin/Native benchmark ==="
case "$OS_NAME" in
Linux) KN_TARGET="linuxX64Test" ;;
Darwin) KN_TARGET="macosArm64Test" ;;
esac
"$ROOT/gradlew" -p "$ROOT" ":quartz:$KN_TARGET" --tests "*.Secp256k1NativeBenchmark" \
2>/dev/null || true
KN_XML="$ROOT/quartz/build/test-results/$KN_TARGET/TEST-${KN_TARGET}.com.vitorpamplona.quartz.utils.secp256k1.Secp256k1NativeBenchmark.xml"
if [ -f "$KN_XML" ]; then
sed -n '/<!\[CDATA\[/,/\]\]>/p' "$KN_XML" | grep -v 'CDATA\|]]>'
else
echo "K/Native benchmark XML not found."
fi
echo ""
# ============================================================================
# 3. JVM benchmark
# ============================================================================
echo "=== Running JVM benchmark ==="
"$ROOT/gradlew" -p "$ROOT" :quartz:jvmTest --tests "*.Secp256k1Benchmark" \
2>/dev/null || true
JVM_XML="$ROOT/quartz/build/test-results/jvmTest/TEST-com.vitorpamplona.quartz.utils.secp256k1.Secp256k1Benchmark.xml"
if [ -f "$JVM_XML" ]; then
sed -n '/<!\[CDATA\[/,/\]\]>/p' "$JVM_XML" | grep -v 'CDATA\|]]>'
else
echo "JVM benchmark XML not found."
fi
echo ""
# ============================================================================
# 4. Android benchmark (if device/emulator connected)
# ============================================================================
if command -v adb &>/dev/null && adb devices 2>/dev/null | grep -q "device$"; then
echo "=== Running Android benchmark (device detected) ==="
# Record start time so we can find results generated by this run.
ANDROID_STAMP="$WORK/.android_stamp"
touch "$ANDROID_STAMP"
"$ROOT/gradlew" -p "$ROOT" :benchmark:connectedBenchmarkAndroidTest \
-Pandroid.testInstrumentationRunnerArguments.class=com.vitorpamplona.quartz.benchmark.Secp256k1Benchmark \
2>/dev/null || true
FOUND=false
# 1. Test-results XML (contains benchmark data in CDATA, like JVM results)
ANDROID_XML=$(find "$ROOT/benchmark/build" \
\( -path "*test-results*" -o -path "*androidTest-results*" \) \
-name "*.xml" -newer "$ANDROID_STAMP" 2>/dev/null | head -1)
if [ -n "$ANDROID_XML" ] && [ -f "$ANDROID_XML" ]; then
sed -n '/<!\[CDATA\[/,/\]\]>/p' "$ANDROID_XML" | grep -v 'CDATA\|]]>'
FOUND=true
fi
# 2. Pulled benchmark JSON (AndroidX Benchmark writes here via Gradle)
if [ "$FOUND" = false ]; then
BENCH_JSON=$(find "$ROOT/benchmark/build/outputs" \
-path "*connected_android_test_additional_output*" \
-name "*.json" -newer "$ANDROID_STAMP" 2>/dev/null | head -1)
if [ -n "$BENCH_JSON" ] && [ -f "$BENCH_JSON" ]; then
cat "$BENCH_JSON"
FOUND=true
fi
fi
# 3. On-device benchmark JSON (legacy / older AndroidX Benchmark versions)
if [ "$FOUND" = false ]; then
BENCH_JSON=$(adb shell "ls /sdcard/Download/*benchmark*json 2>/dev/null" 2>/dev/null | head -1 | tr -d '\r')
if [ -n "$BENCH_JSON" ]; then
adb shell "cat '$BENCH_JSON'" 2>/dev/null
FOUND=true
fi
fi
if [ "$FOUND" = false ]; then
echo "Android benchmark ran but results not found."
fi
echo ""
else
echo "=== Skipping Android benchmark (no device/emulator connected) ==="
echo ""
fi