diff --git a/tools/darkroom/darkcult.py b/tools/darkroom/darkcult.py index d164af70..fa538899 100755 --- a/tools/darkroom/darkcult.py +++ b/tools/darkroom/darkcult.py @@ -10,29 +10,46 @@ import sys import optparse import subprocess import multiprocessing +import logging +import tty -def compile(command): +def build(command): sys.stdout.write(".") sys.stdout.flush() return subprocess.call(command, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) +def continue_build(command): + if command[2]: + sys.stdout.write("*") + sys.stdout.flush() + return 0 + sys.stdout.write(".") + sys.stdout.flush() + result = subprocess.call(command[0], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) + logging.critical(command[1]) + return result + def main(): parser = optparse.OptionParser(description='darkcult.py') - parser.add_option('--src', type='string') - parser.add_option('--stagedir', type='string') - parser.add_option('--output', type='string') - parser.add_option('--compiler', type='string') - parser.add_option('--width', type='int') - parser.add_option('--height', type='int') - parser.add_option('--tile_width', type='int') - parser.add_option('--tile_height', type='int') - parser.add_option('--compile_options', type='string') + parser.add_option('--source', type='string', default='../../example/darkroom/two_spheres.hpp') + parser.add_option('--stagedir', type='string', default='darkroom') + parser.add_option('--output', type='string', default='out.ppm') + parser.add_option('--compiler', type='string', default='g++') + parser.add_option('--width', type='int', default=16) + parser.add_option('--height', type='int', default=16) + parser.add_option('--tile_width', type='int', default=16) + parser.add_option('--tile_height', type='int', default=16) + parser.add_option('--left', type='int', default=0) + parser.add_option('--top', type='int', default=0) + parser.add_option('--right', type='int') + parser.add_option('--bottom', type='int') + parser.add_option('--compile_options', type='string', default='') parser.add_option('--darkcult_cpp', type='string') - parser.add_option('--max_procs', type='int') + parser.add_option('--continuable', type='int', default=0) + parser.add_option('--continue_file', type='string', default='continue.log') + parser.add_option('--max_procs', type='int', default=0) (opts, args) = parser.parse_args() - pool = multiprocessing.Pool(opts.max_procs if opts.max_procs != 0 else None) - def format_command(x, y): bin = "%s/%d/%d.out" % (opts.stagedir, y, x) out = "%s/%d/%d.ppm" % (opts.stagedir, y, x) @@ -46,20 +63,58 @@ def main(): " && %s > %s" \ % (opts.compiler, bin, opts.compile_options, - opts.src, + opts.source, opts.width, opts.height, opts.tile_width, opts.tile_height, x, y, opts.darkcult_cpp, bin, out ) - return any(pool.map( - compile, - [format_command(x, y) - for y in range(0, opts.height, opts.tile_height) - for x in range(0, opts.width, opts.tile_width) - ] - )) + + if opts.continuable: + logging.basicConfig( + filename=opts.continue_file, + format="%(message)s" + ) + completed = [line.strip() for line in open(opts.continue_file)] + + fd = sys.stdin.fileno() + tc_old = tty.tcgetattr(fd) + tty.setcbreak(fd) + + def format_continue_command(x, y): + key = "%d %d" % (x, y) + return (format_command(x, y), key, key in completed) + + pool = multiprocessing.Pool(opts.max_procs if opts.max_procs != 0 else None) + try: + results = pool.map_async( + continue_build, + [format_continue_command(x, y) + for y in range(opts.top, opts.bottom, opts.tile_height) + for x in range(opts.left, opts.right, opts.tile_width) + ] + ) + while True: + code = sys.stdin.read(1) + if results.ready(): + break + if code == 'q': + pool.terminate() + return 2 + return any(results.get()) + finally: + tty.tcsetattr(fd, tty.TCSADRAIN, tc_old) + logging.shutdown() + else: + pool = multiprocessing.Pool(opts.max_procs if opts.max_procs != 0 else None) + return any(pool.map( + build, + [format_command(x, y) + for y in range(opts.top, opts.bottom, opts.tile_height) + for x in range(opts.left, opts.right, opts.tile_width) + ] + )) if __name__=="__main__": sys.exit(main()) diff --git a/tools/darkroom/darkcult.sh b/tools/darkroom/darkcult.sh index fcb849ac..376d1e2e 100755 --- a/tools/darkroom/darkcult.sh +++ b/tools/darkroom/darkcult.sh @@ -18,15 +18,21 @@ width=16 height=16 tile_width=16 tile_height=16 +l=0 +t=0 +r= +b= +declare -a common_options=() declare -a user_macros=() declare -a include_paths=() -max_procs=1 +max_procs= force=0 +continuable=0 use_help=0 darkcult_cpp=$(cd $(dirname $0); pwd)/darkcult.cpp darkcult_py=$(cd $(dirname $0); pwd)/darkcult.py -args=`getopt -o s:S:o:C:w:h:W:H:D:I:P:f -l source:,stagedir:,output:,compiler:,width:,height:,tile-width:,tile-height:,define:,include:,max-procs:,force,help -- "$@"` +args=`getopt -o s:S:o:C:w:h:W:H:l:t:r:b:O:D:I:P:fc -l source:,stagedir:,output:,compiler:,width:,height:,tile-width:,tile-height:,left:,top:,right:,bottom:,option:,define:,include:,max-procs:,force,continuable,help -- "$@"` if [ "$?" -ne 0 ]; then echo >&2 "error: options parse error. See 'darkcult.sh --help'" exit 1 @@ -42,15 +48,23 @@ while [ -n "$1" ]; do -h|--height) height=$2; shift 2;; -W|--tile-width) tile_width=$2; shift 2;; -H|--tile-height) tile_height=$2; shift 2;; + -l|--left) l=$2; shift 2;; + -t|--top) t=$2; shift 2;; + -r|--right) r=$2; shift 2;; + -b|--bottom) b=$2; shift 2;; + -O|--option) common_options=(${common_options[@]} "$2"); shift 2;; -D|--define) user_macros=(${user_macros[@]} "$2"); shift 2;; -I|--include) include_paths=(${include_paths[@]} "$2"); shift 2;; -P|--max-procs) max_procs=$2; shift 2;; -f|--force) force=1; shift;; + -c|--continuable) continuable=1; shift;; --help) use_help=1; shift;; --) shift; break;; *) echo >&2 "error: unknown option($1) used."; exit 1;; esac done +: ${r:=${width}} +: ${b:=${height}} if [ ${use_help} -ne 0 ]; then echo "help:" @@ -79,17 +93,34 @@ if [ ${use_help} -ne 0 ]; then echo " -H, --tile-height= Output height of divided rendering." echo " Default; 16" echo "" + echo " -l, --left= Left X position of rendering range." + echo " Default; 0" + echo "" + echo " -t, --top= Top Y position of rendering range." + echo " Default; 0" + echo "" + echo " -r, --right= Right X position of rendering range." + echo " Default; " + echo "" + echo " -b, --bottom= Bottom Y position of rendering range." + echo " Default; " + echo "" + echo " -O, --option= Add compile option." + echo "" echo " -D, --define= Define macro for preprocessor." echo "" echo " -I, --include= Add system include path." echo "" echo " -P, --max-procs= The maximum number of process use." - echo " If other than 1, processing in parallel mode." + echo " If other than null, processing in parallel mode." echo " If 0, using the number of CPUs in the system." - echo " Default; 1" echo "" echo " -f, --force Allow overwrite of ." echo "" + echo " -c, --continuable Enable break/continue mode." + echo " Press ; check finished." + echo " Press 'q' ; terminate compile." + echo "" echo " --help This message." exit 0 fi @@ -103,10 +134,15 @@ echo " width = ${width}" echo " height = ${height}" echo " tile-width = ${tile_width}" echo " tile-height = ${tile_height}" +echo " left = ${l}" +echo " top = ${t}" +echo " right = ${r}" +echo " bottom = ${b}" echo " user-macros = (${user_macros[*]})" echo " include-paths = (${include_paths[*]})" echo " max-procs = ${max_procs}" echo " force = ${force}" +echo " continuable = ${continuable}" if [ ! -f "${src}" -a ! -f "$(cd $(dirname $0); pwd)/${src}" ]; then echo >&2 "error: source(${src}) not exists." @@ -119,15 +155,18 @@ done for include_path in ${include_paths}; do include_options="${include_options} -I${include_path}" done -compile_options="-std=c++11 ${define_options} ${include_options}" +compile_options="-std=c++11 ${define_options} ${include_options} ${common_options[*]}" if [ -d "${stagedir}" ]; then if [ ${force} -eq 0 ]; then - echo >&2 "error: stagedir(${stagedir}) already exists." - exit 1 + if [ ${continuable} -eq 0 ]; then + echo >&2 "error: stagedir(${stagedir}) already exists." + exit 1 + fi else rm -f -r ${stagedir}/* fi + rm -f ${stagedir}/*.ppm else mkdir -p ${stagedir} fi @@ -138,13 +177,13 @@ done echo "rendering:" start=${SECONDS} -if [ ${max_procs} -eq 1 ]; then - for ((y=0; y ${out} if [ $? -ne 0 ]; then echo "" - echo >&2 "error: compile(${y}/${x}) failed." + echo >&2 " error: compile(${y}/${x}) failed." exit 1 fi done @@ -169,16 +208,26 @@ if [ ${max_procs} -eq 1 ]; then done else echo " processing in parallel mode." + if [ ${continuable} -ne 0 ]; then + echo " enable break/continue mode." + fi echo -n " " python "${darkcult_py}" \ - "--src=${src}" "--stagedir=${stagedir}" "--output=${output}" "--compiler=${compiler}" \ + "--source=${src}" "--stagedir=${stagedir}" "--output=${output}" "--compiler=${compiler}" \ "--width=${width}" "--height=${height}" \ "--tile_width=${tile_width}" "--tile_height=${tile_height}"" "\ + "--left=${l}" "--top=${t}" \ + "--right=${r}" "--bottom=${b}" \ "--compile_options=${compile_options}" "--darkcult_cpp=${darkcult_cpp}" \ + "--continuable=${continuable}" "--continue_file=${stagedir}/continue.log" \ "--max_procs=${max_procs}" + result=$? echo "" - if [ $? -ne 0 ]; then - echo >&2 "error: compile failed." + if [ ${result} -eq 2 ]; then + echo " compile terminated." + exit 0 + elif [ ${result} -ne 0 ]; then + echo >&2 " error: compile failed." exit 1 fi fi diff --git a/tools/testspr/test.py b/tools/testspr/test.py index c84cd34b..1162add1 100644 --- a/tools/testspr/test.py +++ b/tools/testspr/test.py @@ -11,26 +11,24 @@ import optparse import subprocess import multiprocessing -def compile(command): +def build(command): sys.stdout.write(".") sys.stdout.flush() return subprocess.call(command, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) def main(): parser = optparse.OptionParser(description='test.py') - parser.add_option('--stagedir', type='string') - parser.add_option('--gcc_version', type='string') - parser.add_option('--clang_version', type='string') - parser.add_option('--gcc_root', type='string') - parser.add_option('--clang_root', type='string') - parser.add_option('--compile_options', type='string') + parser.add_option('--stagedir', type='string', default='testspr') + parser.add_option('--gcc_version', type='string', default='.') + parser.add_option('--clang_version', type='string', default='.') + parser.add_option('--gcc_root', type='string', default='/usr/local') + parser.add_option('--clang_root', type='string', default='/usr/local') + parser.add_option('--compile_options', type='string', default='') parser.add_option('--test_cpp', type='string') - parser.add_option('--serialized_version_specific_options', type='string') - parser.add_option('--max_procs', type='int') + parser.add_option('--serialized_version_specific_options', type='string', default='{}') + parser.add_option('--max_procs', type='int', default=0) (opts, args) = parser.parse_args() - pool = multiprocessing.Pool(opts.max_procs if opts.max_procs != 0 else None) - def format_command(name, version, root): base = "%s-%s" % (name, version) if version != "." else name bin = "%s/test.%s.out" % (opts.stagedir, base.replace('.', '')) @@ -46,8 +44,10 @@ def main(): opts.test_cpp, compile_log, bin, execute_log ) + + pool = multiprocessing.Pool(opts.max_procs if opts.max_procs != 0 else None) return sum(result != 0 for result in pool.map( - compile, + build, [format_command('gcc', version, opts.gcc_root) for version in opts.gcc_version.split(' ') ] diff --git a/tools/testspr/test.sh b/tools/testspr/test.sh index 5e5053cd..74cebf65 100755 --- a/tools/testspr/test.sh +++ b/tools/testspr/test.sh @@ -16,7 +16,7 @@ gcc_root="/usr/local" clang_root="/usr/local" declare -a user_macros=() declare -a include_paths=() -max_procs=1 +max_procs= force=0 use_help=0 declare -a common_options=() @@ -27,7 +27,7 @@ declare -A version_specific_options=( test_cpp=$(cd $(dirname $0); pwd)/test.cpp test_py=$(cd $(dirname $0); pwd)/test.py -args=`getopt -o S:g:c:O:o:D:I:P:f -l stagedir:,gcc-version:,clang-version:,gcc-root:,clang-root:,option:,version-option:,define:,include:,max-procs:,force,help -- "$@"` +args=`getopt -o S:g:c:O:V:D:I:P:f -l stagedir:,gcc-version:,clang-version:,gcc-root:,clang-root:,option:,version-option:,define:,include:,max-procs:,force,help -- "$@"` if [ "$?" -ne 0 ]; then echo >&2 "error: options parse error. See 'test.sh --help'" exit 1 @@ -41,7 +41,7 @@ while [ -n "$1" ]; do --gcc-root) gcc_root="$2"; shift 2;; --clang-root) clang_root="$2"; shift 2;; -O|--option) common_options=(${common_options[@]} "$2"); shift 2;; - -o|--version-option) version_options=(${version_options[@]} "$2"); shift 2;; + -V|--version-option) version_options=(${version_options[@]} "$2"); shift 2;; -D|--define) user_macros=(${user_macros[@]} "$2"); shift 2;; -I|--include) include_paths=(${include_paths[@]} "$2"); shift 2;; -P|--max-procs) max_procs=$2; shift 2;; @@ -74,7 +74,7 @@ if [ ${use_help} -ne 0 ]; then echo "" echo " -O, --option= Add compile option." echo "" - echo " -o, --version-option= Add version specific compile option." + echo " -V, --version-option= Add version specific compile option." echo " Example; [clang-3.3]='-ftemplate-depth=512'" echo "" echo " -D, --define= Define macro for preprocessor." @@ -82,9 +82,8 @@ if [ ${use_help} -ne 0 ]; then echo " -I, --include= Add system include path." echo "" echo " -P, --max-procs= The maximum number of process use." - echo " If other than 1, processing in parallel mode." + echo " If other than null, processing in parallel mode." echo " If 0, using the number of CPUs in the system." - echo " Default; 1" echo "" echo " -f, --force Allow overwrite of ." echo "" @@ -162,7 +161,7 @@ compile() { fi return 0 } -if [ ${max_procs} -eq 1 ]; then +if [ -z "${max_procs}" ]; then fail_count=0 for version in ${gcc_version}; do compile gcc ${version} ${test_cpp} ${compile_options} ${version_specific_options} ${gcc_root}