#!/bin/bash DIR=$(dirname $0) ROOT=$DIR/.. BIN=$ROOT/build/bin LIB=$ROOT/build/lib SCAF=$LIB/LLVMScaffold.dylib OPT=$BIN/opt CLANG=$BIN/clang LLVM_LINK=$BIN/llvm-link LLI=$BIN/lli I_FLAGS="-I/usr/include -I/usr/include/x86_64-linux-gnu -I/usr/lib/gcc/x86_64-linux-gnu/4.8/include" # Capacity of each SIMD region D=(1024) # Number of SIMD regions K=(4) # Module flattening thresholds: must be picked from the set in scripts/flattening_thresh.py THRESHOLDS=(010k) # Full schedule? otherwise only generates metrics (faster) FULL_SCHED=true # Create directory to put all byproduct and output files in for f in $*; do b=$(basename $f .scaffold) echo "[gen-lpfs.sh] $b: Creating output directory ..." mkdir -p "$b" #mv ./*${b}* ${b} 2>/dev/null done # Generate .ll file if not done already for f in $*; do b=$(basename $f .scaffold) echo "[gen-lpfs.sh] $b: Compiling ..." if [ ! -e ${b}/${b}.ll ]; then # Generate compiled files $ROOT/scaffold.sh -r $f mv ${b}11.ll ${b}11.ll.keep_me # clean intermediary compilation files (comment out for speed) #$ROOT/scaffold.sh -c $f # Keep the final output for the compilation mv ${b}11.ll.keep_me ${b}/${b}.ll fi done # Module flattening pass with different thresholds for f in $*; do b=$(basename $f .scaffold) echo "[gen-lpfs.sh] $b: Computing module gate counts ..." $OPT -S -load $SCAF -ResourceCount2 ${b}/${b}.ll > /dev/null 2> ${b}.out python $DIR/flattening_thresh.py ${b} for th in ${THRESHOLDS[@]}; do if [ ! -e ${b}/${b}.flat${th}.ll ]; then echo "[gen-lpfs.sh] $b_flat${th}: Flattening ..." mv ${b}.flat${th}.txt flat_info.txt $OPT -S -load $SCAF -FlattenModule -dce -internalize -globaldce ${b}/${b}.ll -o ${b}/${b}.flat${th}.ll fi done rm -f *flat*.txt ${b}.out done # Perform resource estimation for f in $*; do b=$(basename $f .scaffold) for th in ${THRESHOLDS[@]}; do echo "[gen-lpfs.sh] $b.flat${th}: Resource count ..." if [ -n ${b}/${b}.flat${th}.resources ]; then $OPT -S -load $SCAF -ResourceCount ${b}/${b}.flat${th}.ll > /dev/null 2> ${b}/${b}.flat${th}.resources fi done done # For different K and D values specified above, generate MultiSIMD schedules for f in $*; do b=$(basename $f .scaffold) for d in ${D[@]}; do for k in ${K[@]}; do for th in ${THRESHOLDS[@]}; do echo "[gen-lpfs.sh] $b.flat${th}: Generating SIMD K=$k D=$d leaves ..." if [ ! -e ${b}/${b}.flat${th}.simd.${k}.${d}.leaves.local ]; then $OPT -load $SCAF -GenLPFSSchedule -simd-kconstraint-lpfs $k -simd-dconstraint-lpfs $d -simd_l 1 -full_sched 1 -local_mem 1 ${b}/${b}.flat${th}.ll > /dev/null 2> ${b}/${b}.flat${th}.simd.${k}.${d}.leaves.local fi done done done done # Take into account the penalty of ballistic communication for f in $*; do b=$(basename $f .scaffold) cd ${b} echo "[gen-lpfs.sh] $b: Adding communication latencies ..." ../${DIR}/comm_aware.pl ${b}*.leaves.local cd .. done # Obtain coarse-grain schedules by co-scheduling modules for f in $*; do b=$(basename $f .scaffold) cd ${b} for th in ${THRESHOLDS[@]}; do echo "[gen-lpfs.sh] $b.flat${th}: Coarse-grain schedule ..." for c in comm_aware_schedule.txt.${b}.flat${th}_*; do k=$(perl -e '$ARGV[0] =~ /_K(\d+)/; print $1' $c) d=$(perl -e '$ARGV[0] =~ /_D(\d+)/; print $1' $c) x=$(perl -e '$ARGV[0] =~ /.*_(.+)/; print $1' $c) th=$(perl -e '$ARGV[0] =~ /.flat(\d+[a-zA-Z])/; print $1' $c) mv $c comm_aware_schedule.txt if [ ! -e ${b}/${b}.flat${th}.simd.${k}.${d}.${x}.time ]; then ../$OPT -load ../$SCAF -GenCGSIMDSchedule -simd-kconstraint-cg $k -simd-dconstraint-cg $d ${b}.flat${th}.ll > /dev/null 2> ${b}.flat${th}.simd.${k}.${d}.${x}.time fi done done rm -f comm_aware_schedule.txt histogram_data.txt cd .. done # Rename to simple names rename 's/\.simd\.(\d)\.(\d+)\.leaves\.local/\.lpfs/' ${b}/*leaves.local rename 's/\.simd\.(\d)\.(\d+)\.local\.time/\.cg/' ${b}/*time # Perform module frequency estimation #for f in $*; do # b=$(basename $f .scaffold) # b_dir=$(dirname "$(readlink -f $f)") # echo "[gen-lpfs.sh] Compiling frequency-estimation-hybrid.c" >&2 # $CLANG -c -O1 -emit-llvm frequency-estimation-hybrid.c -o frequency-estimation-hybrid.bc # echo "[gen-lpfs.sh] $b: Frequency count ..." >&2 # if [ -n ${b}/${b}.freq ]; then # cp ${b}/${b}.ll ${b}/${b}_dynamic.ll # echo -e "\t[gen-lpfs.sh] Decomposing Toffolis" >&2 # $OPT -S -load $SCAF -ToffoliReplace ${b}/${b}_dynamic.ll -o ${b}/${b}_dynamic.ll # echo -e "\t[gen-lpfs.sh] Identifying Loops to retain..." >&2 # $OPT -S -mem2reg -instcombine -loop-simplify -loop-rotate -indvars ${b}/${b}_dynamic.ll -o ${b}/${b}_marked.ll # echo -e "\t[gen-lpfs.sh] Rolling up Loops" >&2 # $OPT -S -load $SCAF -dyn-rollup-loops ${b}/${b}_marked.ll -o ${b}/${b}_rolled.ll # echo -e "\t[gen-lpfs.sh] Linking frequency-estimation-hybrid.bc and ${b}/${b}_rolled.ll" >&2 # $LLVM_LINK frequency-estimation-hybrid.bc ${b}/${b}_rolled.ll -S -o=${b}/${b}_linked.ll # echo -e "\t[gen-lpfs.sh] Instrumenting ${b}/${b}_linked.ll" >&2 # $OPT -S -load $SCAF -runtime-frequency-estimation-hybrid ${b}/${b}_linked.ll -o ${b}/${b}_instr.ll # $OPT -S -dce -dse -dce ${b}/${b}_instr.ll -o ${b}/${b}_instr2.ll # $OPT -S -O1 ${b}/${b}_instr2.ll -o ${b}/${b}_instr.ll # echo -e "\t[gen-lpfs.sh] Executing ${b}/${b}_instr.ll with lli" >&2 # $LLI ${b}/${b}_instr.ll > ${b}/${b}.freq # echo -e "\t[gen-lpfs.sh] Frequency estimates written to ${b}.freq" # fi # rm frequency-estimation-hybrid.bc ${b}/${b}*_dynamic.ll ${b}/${b}*_marked.ll ${b}/${b}*_rolled.ll ${b}/${b}*_linked.ll ${b}/${b}*_instr.ll ${b}/${b}*_instr2.ll #done