File size: 11,771 Bytes
cfcbbc8 |
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 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
#!/bin/bash
#
# run_smk_sequential.sh - Run Snakemake workflows one at a time for debugging
#
# This script runs each Snakemake workflow sequentially to observe
# the behavior of prompt scripts, supervisor, and coder in real time.
#
# Usage:
# ./run_smk_sequential.sh # Run all steps
# ./run_smk_sequential.sh --step1 # Run summarize_root (both rules)
# ./run_smk_sequential.sh --step2 # Run create_numpy
# ./run_smk_sequential.sh --step3 # Run preprocess
# ./run_smk_sequential.sh --step4 # Run scores
# ./run_smk_sequential.sh --step5 # Run categorization
# ./run_smk_sequential.sh --step1 --step3 # Run summarize_root + preprocess
#
if [ -f ~/.apikeys.sh ]; then
source ~/.apikeys.sh
fi
# Parse command line arguments
RUN_STEP1=false
RUN_STEP2=false
RUN_STEP3=false
RUN_STEP4=false
RUN_STEP5=false
VALIDATE_STEPS=false
OUTPUT_DIR="results"
CONFIG="config.yml"
# Remember the project root where this script is invoked
PROJECT_ROOT="$(pwd)"
while [[ $# -gt 0 ]]; do
case $1 in
--step1)
RUN_STEP1=true
shift
;;
--step2)
RUN_STEP2=true
shift
;;
--step3)
RUN_STEP3=true
shift
;;
--step4)
RUN_STEP4=true
shift
;;
--step5)
RUN_STEP5=true
shift
;;
--validate)
VALIDATE_STEPS=true
shift
;;
--out-dir)
OUTPUT_DIR="$2"
shift
shift
;;
--job-id)
# Create unique directory based on job ID
OUTPUT_DIR="results_job_$2"
shift
shift
;;
--auto-dir)
# Create unique directory with timestamp
TIMESTAMP=$(date +"%Y%m%d_%H%M%S")
OUTPUT_DIR="results_${TIMESTAMP}"
shift
;;
--config)
CONFIG="$2"
shift
shift
;;
--help|-h)
echo "Usage: $0 [OPTIONS]"
echo ""
echo "Run Snakemake workflows for ATLAS analysis"
echo ""
echo "Options:"
echo " --step1 Run summarize_root workflow (both rules: data generation + prompt processing)"
echo " --step2 Run create_numpy workflow"
echo " --step3 Run preprocess workflow"
echo " --step4 Run scores workflow"
echo " --step5 Run categorization workflow"
echo " --validate Run validation after each successful step"
echo " --out-dir DIR Custom output directory (default: results)"
echo " --job-id ID Create unique directory: results_job_ID"
echo " --auto-dir Create unique directory with timestamp: results_YYYYMMDD_HHMMSS"
echo " --help Show this help message"
echo ""
echo "Examples:"
echo " $0 --step1 --auto-dir # results_20250916_143052/"
echo " $0 --step1 --job-id 12345 # results_job_12345/"
echo " $0 --step1 --out-dir my_run_1 # my_run_1/"
echo ""
echo "If no options are provided, all steps are run sequentially."
exit 0
;;
*)
echo "Unknown option: $1"
echo "Use --help for usage information"
exit 1
;;
esac
done
# If no specific steps requested, run all
if [[ "$RUN_STEP1" == "false" && "$RUN_STEP2" == "false" && "$RUN_STEP3" == "false" && "$RUN_STEP4" == "false" && "$RUN_STEP5" == "false" ]]; then
RUN_STEP1=true
RUN_STEP2=true
RUN_STEP3=true
RUN_STEP4=true
RUN_STEP5=true
echo "=== Running All Snakemake Workflows Sequentially (Output: ${OUTPUT_DIR}) ==="
else
echo "=== Running Selected Snakemake Workflows (Output: ${OUTPUT_DIR}) ==="
fi
echo ""
# Set up environment
module load python
conda activate llm_env
# Resolve config file to an absolute path so Snakemake can always find it
if [[ "${CONFIG}" = /* ]]; then
CONFIG_PATH="${CONFIG}"
else
CONFIG_PATH="${PROJECT_ROOT}/${CONFIG}"
fi
if [[ ! -f "${CONFIG_PATH}" ]]; then
echo "❌ Config file not found at ${CONFIG_PATH}"
exit 1
fi
# Copy and prepare workflow files
OUTPUT_DIR="${OUTPUT_DIR%/}"
if [[ "${OUTPUT_DIR}" = /* ]]; then
BASE_DIR="${OUTPUT_DIR}"
else
BASE_DIR="$PWD/${OUTPUT_DIR}"
fi
echo "Preparing workflow files..."
mkdir -p ${OUTPUT_DIR}/prompts_temp
cp -r prompts/* ${OUTPUT_DIR}/prompts_temp/
sed -i "s#{BASE_DIR}#${BASE_DIR}#g" ${OUTPUT_DIR}/prompts_temp/*.txt
cp workflow/summarize_root.smk ${OUTPUT_DIR}/summarize_root_temp.smk
cp workflow/create_numpy.smk ${OUTPUT_DIR}/create_numpy_temp.smk
cp workflow/preprocess.smk ${OUTPUT_DIR}/preprocess_temp.smk
cp workflow/scores.smk ${OUTPUT_DIR}/scores_temp.smk
cp workflow/categorization.smk ${OUTPUT_DIR}/categorization_temp.smk
cp supervisor_coder.py ${OUTPUT_DIR}/supervisor_coder.py
cp write_prompt.py ${OUTPUT_DIR}/write_prompt.py
cp check_soln.py ${OUTPUT_DIR}/check_soln.py
sed -i "s#{BASE_DIR}#${BASE_DIR}#g" ${OUTPUT_DIR}/*_temp.smk
# Replace {CONFIG} in temp snakemake files with the absolute path to the project's config
sed -i "s#{CONFIG}#${CONFIG_PATH}#g" ${OUTPUT_DIR}/*_temp.smk
# Copy solutions for validation
echo "Copying reference solution arrays for validation..."
mkdir -p ${OUTPUT_DIR}/solution/arrays
# Remove any existing files first to avoid permission issues
rm -f ${OUTPUT_DIR}/solution/arrays/*
cp solution/arrays/* ${OUTPUT_DIR}/solution/arrays/
# Create output directory
mkdir -p ${OUTPUT_DIR}/generated_code
mkdir -p ${OUTPUT_DIR}/logs
cp utils.py ${OUTPUT_DIR}/generated_code/utils.py
# Clean up any existing numpy files (store metrics under logs)
rm -f ${OUTPUT_DIR}/logs/success.npy ${OUTPUT_DIR}/logs/calls.npy ${OUTPUT_DIR}/logs/input_tokens.npy ${OUTPUT_DIR}/logs/output_tokens.npy
echo "Starting sequential execution..."
echo ""
# Function to run a single workflow
run_workflow() {
local workflow_name=$1
local smk_file=$2
local target=$3
local step_number=$4
echo "========================================="
echo "Running: $workflow_name"
echo "Target: $target"
echo "Time: $(date)"
echo "========================================="
# cd into OUTPUT_DIR and do all the work there
if ! pushd "$OUTPUT_DIR" > /dev/null; then
echo "❌ Failed to cd into $OUTPUT_DIR"
return 1
fi
# Print the command that will be executed (run inside ${OUTPUT_DIR})
# Commented out original with --stats, kept for reference
# echo "Command: snakemake -s \"$smk_file\" -j 1 --forcerun \"$target\" --rerun-incomplete --configfile \"${CONFIG}\" --latency-wait 120 --verbose --stats logs/${workflow_name}.stats > logs/${workflow_name}.log 2>&1"
echo "Command: snakemake -s \"$smk_file\" -j 1 --forcerun \"$target\" --rerun-incomplete --configfile \"${CONFIG}\" --latency-wait 120 --verbose > logs/${workflow_name}.log 2>&1"
echo ""
local start_time=$SECONDS
# Run snakemake from inside the output directory. Use BASE_DIR for the config file
# so Snakemake can find the main config.yml even when cwd is the job folder.
# Original Snakemake run with --stats (commented out)
# if snakemake -s "$smk_file" -j 1 --forcerun "$target" --rerun-incomplete --configfile "${CONFIG}" --latency-wait 120 --verbose --stats "logs/${workflow_name}.stats" > "logs/${workflow_name}.log" 2>&1; then
if snakemake -s "$smk_file" -j 1 --forcerun "$target" --rerun-incomplete --configfile "${CONFIG_PATH}" --latency-wait 120 --verbose > "logs/${workflow_name}.log" 2>&1; then
local duration=$((SECONDS - start_time))
echo ""
echo "✅ $workflow_name completed successfully in ${duration}s"
echo ""
# Run validation for this step if it completed successfully
if [[ "$VALIDATE_STEPS" == "true" ]]; then
echo "Running validation for Step $step_number..."
if python check_soln.py --out_dir "${BASE_DIR}" --step $step_number >> "logs/${workflow_name}_validation.log" 2>&1; then
echo "✅ Step $step_number validation completed"
# Check if validation passed
if [[ -f "${OUTPUT_DIR}/logs/success.npy" ]]; then
validation_result=$(python -c "import numpy as np; print(np.load('${OUTPUT_DIR}/logs/success.npy')[$step_number-1])")
if [[ "$validation_result" == "1" ]]; then
echo "✅ Step $step_number validation: PASS"
else
echo "❌ Step $step_number validation: FAIL"
fi
fi
else
echo "❌ Step $step_number validation failed to run"
fi
echo ""
fi
popd > /dev/null
return 0
else
local duration=$((SECONDS - start_time))
echo ""
echo "❌ $workflow_name failed after ${duration}s"
echo ""
popd > /dev/null
return 1
fi
}
# Run workflows sequentially based on flags
step_counter=1
if [[ "$RUN_STEP1" == "true" ]]; then
echo "$step_counter. Running summarize_root workflow (both rules)..."
# Run both rules: first summarize_root, then insert_root_summary
run_workflow "summarize_root" "summarize_root_temp.smk" "summarize_root" 1
run_workflow "insert_root_summary" "summarize_root_temp.smk" "insert_root_summary" 1
((step_counter++))
fi
if [[ "$RUN_STEP2" == "true" ]]; then
echo "$step_counter. Running create_numpy workflow..."
run_workflow "create_numpy" "create_numpy_temp.smk" "create_numpy" 2
((step_counter++))
fi
if [[ "$RUN_STEP3" == "true" ]]; then
echo "$step_counter. Running preprocess workflow..."
run_workflow "preprocess" "preprocess_temp.smk" "preprocess" 3
((step_counter++))
fi
if [[ "$RUN_STEP4" == "true" ]]; then
echo "$step_counter. Running scores workflow..."
run_workflow "scores" "scores_temp.smk" "scores" 4
((step_counter++))
fi
if [[ "$RUN_STEP5" == "true" ]]; then
echo "$step_counter. Running categorization workflow..."
run_workflow "categorization" "categorization_temp.smk" "categorization" 5
((step_counter++))
fi
echo ""
echo "=== Sequential Execution Complete ==="
echo "Check ${OUTPUT_DIR}/ for output files"
echo "Check ${OUTPUT_DIR}/logs/*.log files for detailed logs"
if [[ "$VALIDATE_STEPS" == "true" ]]; then
echo "Check ${OUTPUT_DIR}/logs/*_validation.log files for validation results"
fi
# Optional: Run final comprehensive validation (only if all steps were run)
if [[ "$RUN_STEP1" == "true" && "$RUN_STEP2" == "true" && "$RUN_STEP3" == "true" && "$RUN_STEP4" == "true" && "$RUN_STEP5" == "true" ]]; then
echo ""
if [[ "$VALIDATE_STEPS" == "false" ]]; then
read -p "Run final comprehensive validation? (y/n): " -n 1 -r
echo ""
if [[ $REPLY =~ ^[Yy]$ ]]; then
echo "Running final comprehensive validation..."
python check_soln.py --out_dir ${OUTPUT_DIR}
fi
else
echo "Running final comprehensive validation..."
python check_soln.py --out_dir ${OUTPUT_DIR}
fi
else
echo ""
echo "Note: Final comprehensive validation skipped (not all steps were run)"
fi
# Clean up
echo ""
# echo "Cleaning up temporary files..."
# Comment out the next line to keep prompts_temp for inspection
# rm -rf prompts_temp
# rm -f *_temp.smk
# rm -rf .snakemake # Clean up Snakemake's default log directory
echo -e "Done!\n"
|