Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/graph-ar

bench/run.sh

#!/usr/bin/env bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

# Runs every bench case and appends one JSON line per run to $OUT.
#   run.sh <work-dir> <label>
# <work-dir> holds data/<dataset>-input, data/<dataset>-info-<format> and bin/
# (graphar-bench, gar_bench_cpp, optional graphar-rs-bench). RUNS (default 5),
# DATASETS (default "ldbc mimir") and FORMATS (default "parquet csv orc")
# narrow it down.
set -euo pipefail
W=${1:?work dir}
LABEL=${2:?label}
RUNS=${RUNS:-5}
DATASETS=${DATASETS:-ldbc mimir}
FORMATS=${FORMATS:-parquet csv orc}
OUT=${OUT:-$W/raw/$LABEL.jsonl}
NATIVE=$W/bin/graphar-bench
CPP=$W/bin/gar_bench_cpp
GRS=$W/bin/graphar-rs-bench
mkdir -p "$(dirname "$OUT")" "$W/out"

# One run: <dataset> <format> <graph-writer> <run> <cmd...>; adds the peak RSS.
one() {
  local ds=$1 fmt=$2 writer=$3 run=$4; shift 4
  local tmp
  tmp=$(mktemp)
  if /usr/bin/time -f '%M' -o "$tmp.rss" "$@" > "$tmp" 2> "$tmp.err"; then
    local rss
    rss=$(tail -1 "$tmp.rss")
    while read -r line; do
      [ -n "$line" ] || continue
      echo "{\"label\":\"$LABEL\",\"dataset\":\"$ds\",\"format\":\"$fmt\",\"graph\":\"$writer\",\"run\":$run,\"rss_kb\":$rss,\"row\":$line}" >> "$OUT"
    done < "$tmp"
  else
    echo "{\"label\":\"$LABEL\",\"dataset\":\"$ds\",\"format\":\"$fmt\",\"graph\":\"$writer\",\"run\":$run,\"error\":$(head -c 300 "$tmp.err" | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))'),\"cmd\":\"$*\"}" >> "$OUT"
  fi
  rm -f "$tmp" "$tmp.rss" "$tmp.err"
}

clean() {
  local d=${1:?}
  case "$d" in "$W"/out/*) rm -rf -- "$d" ;; *) echo "refusing to remove $d" >&2; exit 1 ;; esac
}

for ds in $DATASETS; do
  prop=name; [ "$ds" = ldbc ] && prop=firstName
  for fmt in $FORMATS; do
    info=$W/data/$ds-info-$fmt
    input=$W/data/$ds-input
    impls="native cpp"
    for impl in $impls; do
      bin=$NATIVE; [ "$impl" = cpp ] && bin=$CPP
      for api in table builder; do
        for r in $(seq 1 "$RUNS"); do
          g=$W/out/$ds-$fmt-$impl-$api
          clean "$g"
          one "$ds" "$fmt" "$impl-$api" "$r" "$bin" write "$api" "$input" "$info" "$g"
        done
      done
    done
    # The graphs the reads use: one more table write per writer, retried
    # until it succeeds (the C++ table writer fails now and then, see the
    # error rows), so a failed timed run never leaves a partial graph behind.
    for impl in $impls; do
      bin=$NATIVE; [ "$impl" = cpp ] && bin=$CPP
      g=$W/out/$ds-$fmt-$impl-table
      for try in 1 2 3 4 5; do
        clean "$g"
        if "$bin" write table "$input" "$info" "$g" > /dev/null 2>&1; then break; fi
        echo "{\"label\":\"$LABEL\",\"dataset\":\"$ds\",\"format\":\"$fmt\",\"graph\":\"$impl-table\",\"run\":0,\"error\":\"reference write failed, try $try\",\"cmd\":\"$bin write table\"}" >> "$OUT"
      done
    done
    if [ -x "$GRS" ]; then
      for r in $(seq 1 "$RUNS"); do
        g=$W/out/$ds-$fmt-graphar-rs-builder
        clean "$g"
        one "$ds" "$fmt" "graphar-rs-builder" "$r" "$GRS" write-builder "$input" "$info" "$g"
      done
    fi
    # Reads: every reader on the graphs written by each table writer.
    for writer in $impls; do
      g=$W/out/$ds-$fmt-$writer-table
      for impl in $impls; do
        bin=$NATIVE; [ "$impl" = cpp ] && bin=$CPP
        for r in $(seq 1 "$RUNS"); do
          one "$ds" "$fmt" "$writer-table" "$r" "$bin" read-prop "$g" "$prop"
          one "$ds" "$fmt" "$writer-table" "$r" "$bin" read-csr "$g"
          one "$ds" "$fmt" "$writer-table" "$r" "$bin" scan "$g"
        done
      done
    done
  done
done
# The upstream sample graph (written by the Spark library) read by both.
if [ -n "${UPSTREAM_TESTING:-}" ]; then
  for fmt in parquet csv orc; do
    g=$UPSTREAM_TESTING/ldbc_sample/$fmt
    for bin in "$NATIVE" "$CPP"; do
      for r in $(seq 1 "$RUNS"); do
        one ldbc-upstream "$fmt" spark "$r" "$bin" read-prop "$g" firstName
        one ldbc-upstream "$fmt" spark "$r" "$bin" read-csr "$g"
        one ldbc-upstream "$fmt" spark "$r" "$bin" scan "$g"
      done
    done
  done
fi
echo "wrote $OUT"