Files
BitNet/utils/test_parallel_strategy.sh
T

278 lines
7.5 KiB
Bash
Executable File

#!/bin/bash
# Script: Test different GEMM parallel strategy performance
# Strategies: weight-parallel and no-parallel
# Thread counts: 1,2,4,8,12,16
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
GEMM_CONFIG="$PROJECT_ROOT/include/gemm-config.h"
GEMM_CONFIG_BACKUP="$PROJECT_ROOT/include/gemm-config.h.bak"
BUILD_DIR="$PROJECT_ROOT/build"
STATS_DIR="$PROJECT_ROOT/stats"
CSV_FILE="$STATS_DIR/test_parallel_strategy_benchmark.csv"
MODEL_PATH="$PROJECT_ROOT/models/BitNet-b1.58-2B-4T/ggml-model-original.gguf"
BENCHMARK_CMD="./build/bin/llama-bench"
THREADS_LIST="1 2 4 8 12 16"
# Color output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
log_info() {
echo -e "${GREEN}[INFO]${NC} $1"
}
log_warn() {
echo -e "${YELLOW}[WARN]${NC} $1"
}
log_error() {
echo -e "${RED}[ERROR]${NC} $1"
}
# Check prerequisites
check_prerequisites() {
log_info "Checking prerequisites..."
if [ ! -f "$GEMM_CONFIG" ]; then
log_error "gemm-config.h not found: $GEMM_CONFIG"
exit 1
fi
if [ ! -f "$MODEL_PATH" ]; then
log_error "Model file not found: $MODEL_PATH"
exit 1
fi
if [ ! -d "$BUILD_DIR" ]; then
log_error "Build directory not found: $BUILD_DIR"
exit 1
fi
if [ ! -f "$BUILD_DIR/bin/llama-bench" ]; then
log_warn "llama-bench executable not found, building..."
build_project
fi
if [ ! -d "$STATS_DIR" ]; then
log_info "Creating stats directory..."
mkdir -p "$STATS_DIR"
fi
log_info "Prerequisites check completed"
}
# Backup original config file
backup_config() {
log_info "Backing up gemm-config.h..."
cp "$GEMM_CONFIG" "$GEMM_CONFIG_BACKUP"
log_info "Backup completed: $GEMM_CONFIG_BACKUP"
}
# Restore original config file
restore_config() {
if [ -f "$GEMM_CONFIG_BACKUP" ]; then
log_info "Restoring original gemm-config.h..."
cp "$GEMM_CONFIG_BACKUP" "$GEMM_CONFIG"
rm "$GEMM_CONFIG_BACKUP"
log_info "Restore completed"
else
log_warn "Backup file not found, skipping restore"
fi
}
# Set activation-parallel configuration (keep original ACT_PARALLEL)
set_activation_parallel() {
log_info "Configuration: activation-parallel (keeping #define ACT_PARALLEL)"
log_info "Configuration completed"
}
# Set weight-parallel configuration (remove ACT_PARALLEL)
set_weight_parallel() {
log_info "Configuration: weight-parallel (removing #define ACT_PARALLEL)"
# Remove ACT_PARALLEL definition
sed -i '/#define ACT_PARALLEL/d' "$GEMM_CONFIG"
# Verify modification
if grep -q "^#define ACT_PARALLEL" "$GEMM_CONFIG"; then
log_error "Failed to remove ACT_PARALLEL"
exit 1
fi
log_info "Configuration completed"
}
# Set no-parallel configuration (remove ACT_PARALLEL + modify SIZE to 1)
set_no_parallel() {
log_info "Configuration: no-parallel (removing #define ACT_PARALLEL + modifying SIZE to 1)"
# Remove ACT_PARALLEL definition
sed -i '/#define ACT_PARALLEL/d' "$GEMM_CONFIG"
# Modify all ROW_BLOCK_SIZE and COL_BLOCK_SIZE to 1
sed -i 's/#define ROW_BLOCK_SIZE [0-9]\+/#define ROW_BLOCK_SIZE 1/g' "$GEMM_CONFIG"
sed -i 's/#define COL_BLOCK_SIZE [0-9]\+/#define COL_BLOCK_SIZE 1/g' "$GEMM_CONFIG"
log_info "Configuration completed"
}
# Build project
build_project() {
log_info "Building project..."
cd "$PROJECT_ROOT"
if [ ! -f "$BUILD_DIR/Makefile" ]; then
log_info "First build, running cmake..."
cmake -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=Release > /dev/null 2>&1
fi
cd "$BUILD_DIR"
make -j$(nproc) llama-bench > /dev/null 2>&1
if [ ! -f "./bin/llama-bench" ]; then
log_error "Build failed"
exit 1
fi
log_info "Build completed"
cd "$PROJECT_ROOT"
}
# Run benchmark test
run_benchmark() {
local strategy=$1
local threads=$2
cd "$PROJECT_ROOT"
# Run llama-bench
local output=$($BENCHMARK_CMD -m "$MODEL_PATH" -p 128 -n 0 -t "$threads" -ngl 0 2>&1)
# Extract line containing "pp128"
local line=$(echo "$output" | grep "pp128" | tail -1)
if [ -z "$line" ]; then
return 1
fi
echo "$line"
}
# Extract throughput value from benchmark output
extract_throughput() {
local line=$1
# Remove any leading/trailing whitespace and log messages
# The line format is: | model | size | params | backend | threads | test | throughput |
# We need to extract the last field which contains the throughput in format "XXX.XX ± YY.YY"
local throughput=$(echo "$line" | awk -F'|' '{print $NF}' | xargs | sed 's/\[.*\]//' | xargs)
echo "$throughput"
}
# Initialize CSV file
init_csv() {
log_info "Initializing CSV file: $CSV_FILE"
cat > "$CSV_FILE" << 'EOF'
Strategy,Threads,Throughput
EOF
log_info "CSV file created"
}
# Add result to CSV
add_to_csv() {
local strategy=$1
local threads=$2
local throughput=$3
echo "$strategy,$threads,$throughput" >> "$CSV_FILE"
}
# Main function
main() {
log_info "Starting GEMM parallel strategy benchmark tests"
log_info "================================================"
# Check prerequisites
check_prerequisites
# Backup original configuration
backup_config
# Initialize CSV file
init_csv
# Define strategies to test
local strategies=("activation-parallel" "weight-parallel" "no-parallel")
for strategy in "${strategies[@]}"; do
log_info "================================================"
log_info "Testing strategy: $strategy"
log_info "================================================"
# Restore to original configuration
restore_config
backup_config
# Apply configuration based on strategy
case $strategy in
activation-parallel)
set_activation_parallel
;;
weight-parallel)
set_weight_parallel
;;
no-parallel)
set_no_parallel
;;
esac
# Rebuild project to apply new configuration
log_info "Rebuilding project to apply new configuration..."
build_project
# Run test for each thread count
for threads in $THREADS_LIST; do
log_info ""
log_info "Strategy: $strategy, Threads: $threads"
# Run test (capture only output, not log messages)
local result=$(run_benchmark "$strategy" "$threads")
local test_status=$?
if [ $test_status -eq 0 ]; then
# Extract throughput value from the result line
local throughput=$(extract_throughput "$result")
log_info "Throughput: $throughput"
# Add to CSV
add_to_csv "$strategy" "$threads" "$throughput"
else
log_warn "Test failed for strategy $strategy, threads $threads"
fi
sleep 2 # Give system time to cool down
done
done
# Restore original configuration
restore_config
log_info "================================================"
log_info "Test completed!"
log_info "Results saved to: $CSV_FILE"
log_info "================================================"
# Display CSV content
log_info "CSV file content:"
cat "$CSV_FILE"
}
# Run main function
main "$@"