[tools.darkcult] add enable break/continue mode option -c|--continuable

This commit is contained in:
bolero-MURAKAMI 2013-09-29 14:47:04 +09:00
parent 4f477dd0dc
commit e56429ad0a
4 changed files with 157 additions and 54 deletions

View file

@ -10,29 +10,46 @@ import sys
import optparse import optparse
import subprocess import subprocess
import multiprocessing import multiprocessing
import logging
import tty
def compile(command): def build(command):
sys.stdout.write(".") sys.stdout.write(".")
sys.stdout.flush() sys.stdout.flush()
return subprocess.call(command, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) 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(): def main():
parser = optparse.OptionParser(description='darkcult.py') parser = optparse.OptionParser(description='darkcult.py')
parser.add_option('--src', type='string') parser.add_option('--source', type='string', default='../../example/darkroom/two_spheres.hpp')
parser.add_option('--stagedir', type='string') parser.add_option('--stagedir', type='string', default='darkroom')
parser.add_option('--output', type='string') parser.add_option('--output', type='string', default='out.ppm')
parser.add_option('--compiler', type='string') parser.add_option('--compiler', type='string', default='g++')
parser.add_option('--width', type='int') parser.add_option('--width', type='int', default=16)
parser.add_option('--height', type='int') parser.add_option('--height', type='int', default=16)
parser.add_option('--tile_width', type='int') parser.add_option('--tile_width', type='int', default=16)
parser.add_option('--tile_height', type='int') parser.add_option('--tile_height', type='int', default=16)
parser.add_option('--compile_options', type='string') 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('--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() (opts, args) = parser.parse_args()
pool = multiprocessing.Pool(opts.max_procs if opts.max_procs != 0 else None)
def format_command(x, y): def format_command(x, y):
bin = "%s/%d/%d.out" % (opts.stagedir, y, x) bin = "%s/%d/%d.out" % (opts.stagedir, y, x)
out = "%s/%d/%d.ppm" % (opts.stagedir, y, x) out = "%s/%d/%d.ppm" % (opts.stagedir, y, x)
@ -46,18 +63,56 @@ def main():
" && %s > %s" \ " && %s > %s" \
% (opts.compiler, bin, % (opts.compiler, bin,
opts.compile_options, opts.compile_options,
opts.src, opts.source,
opts.width, opts.height, opts.width, opts.height,
opts.tile_width, opts.tile_height, opts.tile_width, opts.tile_height,
x, y, x, y,
opts.darkcult_cpp, opts.darkcult_cpp,
bin, out bin, out
) )
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( return any(pool.map(
compile, build,
[format_command(x, y) [format_command(x, y)
for y in range(0, opts.height, opts.tile_height) for y in range(opts.top, opts.bottom, opts.tile_height)
for x in range(0, opts.width, opts.tile_width) for x in range(opts.left, opts.right, opts.tile_width)
] ]
)) ))

View file

@ -18,15 +18,21 @@ width=16
height=16 height=16
tile_width=16 tile_width=16
tile_height=16 tile_height=16
l=0
t=0
r=
b=
declare -a common_options=()
declare -a user_macros=() declare -a user_macros=()
declare -a include_paths=() declare -a include_paths=()
max_procs=1 max_procs=
force=0 force=0
continuable=0
use_help=0 use_help=0
darkcult_cpp=$(cd $(dirname $0); pwd)/darkcult.cpp darkcult_cpp=$(cd $(dirname $0); pwd)/darkcult.cpp
darkcult_py=$(cd $(dirname $0); pwd)/darkcult.py 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 if [ "$?" -ne 0 ]; then
echo >&2 "error: options parse error. See 'darkcult.sh --help'" echo >&2 "error: options parse error. See 'darkcult.sh --help'"
exit 1 exit 1
@ -42,15 +48,23 @@ while [ -n "$1" ]; do
-h|--height) height=$2; shift 2;; -h|--height) height=$2; shift 2;;
-W|--tile-width) tile_width=$2; shift 2;; -W|--tile-width) tile_width=$2; shift 2;;
-H|--tile-height) tile_height=$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;; -D|--define) user_macros=(${user_macros[@]} "$2"); shift 2;;
-I|--include) include_paths=(${include_paths[@]} "$2"); shift 2;; -I|--include) include_paths=(${include_paths[@]} "$2"); shift 2;;
-P|--max-procs) max_procs=$2; shift 2;; -P|--max-procs) max_procs=$2; shift 2;;
-f|--force) force=1; shift;; -f|--force) force=1; shift;;
-c|--continuable) continuable=1; shift;;
--help) use_help=1; shift;; --help) use_help=1; shift;;
--) shift; break;; --) shift; break;;
*) echo >&2 "error: unknown option($1) used."; exit 1;; *) echo >&2 "error: unknown option($1) used."; exit 1;;
esac esac
done done
: ${r:=${width}}
: ${b:=${height}}
if [ ${use_help} -ne 0 ]; then if [ ${use_help} -ne 0 ]; then
echo "help:" echo "help:"
@ -79,17 +93,34 @@ if [ ${use_help} -ne 0 ]; then
echo " -H, --tile-height=<value> Output height of divided rendering." echo " -H, --tile-height=<value> Output height of divided rendering."
echo " Default; 16" echo " Default; 16"
echo "" echo ""
echo " -l, --left=<value> Left X position of rendering range."
echo " Default; 0"
echo ""
echo " -t, --top=<value> Top Y position of rendering range."
echo " Default; 0"
echo ""
echo " -r, --right=<value> Right X position of rendering range."
echo " Default; <width>"
echo ""
echo " -b, --bottom=<value> Bottom Y position of rendering range."
echo " Default; <height>"
echo ""
echo " -O, --option=<opt> Add compile option."
echo ""
echo " -D, --define=<identifier> Define macro for preprocessor." echo " -D, --define=<identifier> Define macro for preprocessor."
echo "" echo ""
echo " -I, --include=<dir> Add system include path." echo " -I, --include=<dir> Add system include path."
echo "" echo ""
echo " -P, --max-procs=<value> The maximum number of process use." echo " -P, --max-procs=<value> 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 " If 0, using the number of CPUs in the system."
echo " Default; 1"
echo "" echo ""
echo " -f, --force Allow overwrite of <stagedir>." echo " -f, --force Allow overwrite of <stagedir>."
echo "" echo ""
echo " -c, --continuable Enable break/continue mode."
echo " Press <Enter>; check finished."
echo " Press 'q' ; terminate compile."
echo ""
echo " --help This message." echo " --help This message."
exit 0 exit 0
fi fi
@ -103,10 +134,15 @@ echo " width = ${width}"
echo " height = ${height}" echo " height = ${height}"
echo " tile-width = ${tile_width}" echo " tile-width = ${tile_width}"
echo " tile-height = ${tile_height}" echo " tile-height = ${tile_height}"
echo " left = ${l}"
echo " top = ${t}"
echo " right = ${r}"
echo " bottom = ${b}"
echo " user-macros = (${user_macros[*]})" echo " user-macros = (${user_macros[*]})"
echo " include-paths = (${include_paths[*]})" echo " include-paths = (${include_paths[*]})"
echo " max-procs = ${max_procs}" echo " max-procs = ${max_procs}"
echo " force = ${force}" echo " force = ${force}"
echo " continuable = ${continuable}"
if [ ! -f "${src}" -a ! -f "$(cd $(dirname $0); pwd)/${src}" ]; then if [ ! -f "${src}" -a ! -f "$(cd $(dirname $0); pwd)/${src}" ]; then
echo >&2 "error: source(${src}) not exists." echo >&2 "error: source(${src}) not exists."
@ -119,15 +155,18 @@ done
for include_path in ${include_paths}; do for include_path in ${include_paths}; do
include_options="${include_options} -I${include_path}" include_options="${include_options} -I${include_path}"
done 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 [ -d "${stagedir}" ]; then
if [ ${force} -eq 0 ]; then if [ ${force} -eq 0 ]; then
if [ ${continuable} -eq 0 ]; then
echo >&2 "error: stagedir(${stagedir}) already exists." echo >&2 "error: stagedir(${stagedir}) already exists."
exit 1 exit 1
fi
else else
rm -f -r ${stagedir}/* rm -f -r ${stagedir}/*
fi fi
rm -f ${stagedir}/*.ppm
else else
mkdir -p ${stagedir} mkdir -p ${stagedir}
fi fi
@ -138,13 +177,13 @@ done
echo "rendering:" echo "rendering:"
start=${SECONDS} start=${SECONDS}
if [ ${max_procs} -eq 1 ]; then if [ -z "${max_procs}" ]; then
for ((y=0; y<height; y+=tile_height)); do for ((y=t; y<b; y+=tile_height)); do
echo " y = (${y}/${height})..." echo " y = (${y}/${height})..."
y_start=${SECONDS} y_start=${SECONDS}
echo -n " x = " echo -n " x = "
for ((x=0; x<width; x+=tile_width)); do for ((x=l; x<r; x+=tile_width)); do
echo -n "(${x}/${height})." echo -n "(${x}/${height})."
bin=${stagedir}/${y}/${x}.out bin=${stagedir}/${y}/${x}.out
out=${stagedir}/${y}/${x}.ppm out=${stagedir}/${y}/${x}.ppm
@ -169,15 +208,25 @@ if [ ${max_procs} -eq 1 ]; then
done done
else else
echo " processing in parallel mode." echo " processing in parallel mode."
if [ ${continuable} -ne 0 ]; then
echo " enable break/continue mode."
fi
echo -n " " echo -n " "
python "${darkcult_py}" \ python "${darkcult_py}" \
"--src=${src}" "--stagedir=${stagedir}" "--output=${output}" "--compiler=${compiler}" \ "--source=${src}" "--stagedir=${stagedir}" "--output=${output}" "--compiler=${compiler}" \
"--width=${width}" "--height=${height}" \ "--width=${width}" "--height=${height}" \
"--tile_width=${tile_width}" "--tile_height=${tile_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}" \ "--compile_options=${compile_options}" "--darkcult_cpp=${darkcult_cpp}" \
"--continuable=${continuable}" "--continue_file=${stagedir}/continue.log" \
"--max_procs=${max_procs}" "--max_procs=${max_procs}"
result=$?
echo "" echo ""
if [ $? -ne 0 ]; then if [ ${result} -eq 2 ]; then
echo " compile terminated."
exit 0
elif [ ${result} -ne 0 ]; then
echo >&2 " error: compile failed." echo >&2 " error: compile failed."
exit 1 exit 1
fi fi

View file

@ -11,26 +11,24 @@ import optparse
import subprocess import subprocess
import multiprocessing import multiprocessing
def compile(command): def build(command):
sys.stdout.write(".") sys.stdout.write(".")
sys.stdout.flush() sys.stdout.flush()
return subprocess.call(command, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE) return subprocess.call(command, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
def main(): def main():
parser = optparse.OptionParser(description='test.py') parser = optparse.OptionParser(description='test.py')
parser.add_option('--stagedir', type='string') parser.add_option('--stagedir', type='string', default='testspr')
parser.add_option('--gcc_version', type='string') parser.add_option('--gcc_version', type='string', default='.')
parser.add_option('--clang_version', type='string') parser.add_option('--clang_version', type='string', default='.')
parser.add_option('--gcc_root', type='string') parser.add_option('--gcc_root', type='string', default='/usr/local')
parser.add_option('--clang_root', type='string') parser.add_option('--clang_root', type='string', default='/usr/local')
parser.add_option('--compile_options', type='string') parser.add_option('--compile_options', type='string', default='')
parser.add_option('--test_cpp', type='string') parser.add_option('--test_cpp', type='string')
parser.add_option('--serialized_version_specific_options', type='string') parser.add_option('--serialized_version_specific_options', type='string', default='{}')
parser.add_option('--max_procs', type='int') parser.add_option('--max_procs', type='int', default=0)
(opts, args) = parser.parse_args() (opts, args) = parser.parse_args()
pool = multiprocessing.Pool(opts.max_procs if opts.max_procs != 0 else None)
def format_command(name, version, root): def format_command(name, version, root):
base = "%s-%s" % (name, version) if version != "." else name base = "%s-%s" % (name, version) if version != "." else name
bin = "%s/test.%s.out" % (opts.stagedir, base.replace('.', '')) bin = "%s/test.%s.out" % (opts.stagedir, base.replace('.', ''))
@ -46,8 +44,10 @@ def main():
opts.test_cpp, compile_log, opts.test_cpp, compile_log,
bin, execute_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( return sum(result != 0 for result in pool.map(
compile, build,
[format_command('gcc', version, opts.gcc_root) [format_command('gcc', version, opts.gcc_root)
for version in opts.gcc_version.split(' ') for version in opts.gcc_version.split(' ')
] ]

View file

@ -16,7 +16,7 @@ gcc_root="/usr/local"
clang_root="/usr/local" clang_root="/usr/local"
declare -a user_macros=() declare -a user_macros=()
declare -a include_paths=() declare -a include_paths=()
max_procs=1 max_procs=
force=0 force=0
use_help=0 use_help=0
declare -a common_options=() declare -a common_options=()
@ -27,7 +27,7 @@ declare -A version_specific_options=(
test_cpp=$(cd $(dirname $0); pwd)/test.cpp test_cpp=$(cd $(dirname $0); pwd)/test.cpp
test_py=$(cd $(dirname $0); pwd)/test.py 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 if [ "$?" -ne 0 ]; then
echo >&2 "error: options parse error. See 'test.sh --help'" echo >&2 "error: options parse error. See 'test.sh --help'"
exit 1 exit 1
@ -41,7 +41,7 @@ while [ -n "$1" ]; do
--gcc-root) gcc_root="$2"; shift 2;; --gcc-root) gcc_root="$2"; shift 2;;
--clang-root) clang_root="$2"; shift 2;; --clang-root) clang_root="$2"; shift 2;;
-O|--option) common_options=(${common_options[@]} "$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;; -D|--define) user_macros=(${user_macros[@]} "$2"); shift 2;;
-I|--include) include_paths=(${include_paths[@]} "$2"); shift 2;; -I|--include) include_paths=(${include_paths[@]} "$2"); shift 2;;
-P|--max-procs) max_procs=$2; shift 2;; -P|--max-procs) max_procs=$2; shift 2;;
@ -74,7 +74,7 @@ if [ ${use_help} -ne 0 ]; then
echo "" echo ""
echo " -O, --option=<opt> Add compile option." echo " -O, --option=<opt> Add compile option."
echo "" echo ""
echo " -o, --version-option=<opt> Add version specific compile option." echo " -V, --version-option=<opt> Add version specific compile option."
echo " Example; [clang-3.3]='-ftemplate-depth=512'" echo " Example; [clang-3.3]='-ftemplate-depth=512'"
echo "" echo ""
echo " -D, --define=<identifier> Define macro for preprocessor." echo " -D, --define=<identifier> Define macro for preprocessor."
@ -82,9 +82,8 @@ if [ ${use_help} -ne 0 ]; then
echo " -I, --include=<directory> Add system include path." echo " -I, --include=<directory> Add system include path."
echo "" echo ""
echo " -P, --max-procs=<value> The maximum number of process use." echo " -P, --max-procs=<value> 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 " If 0, using the number of CPUs in the system."
echo " Default; 1"
echo "" echo ""
echo " -f, --force Allow overwrite of <stagedir>." echo " -f, --force Allow overwrite of <stagedir>."
echo "" echo ""
@ -162,7 +161,7 @@ compile() {
fi fi
return 0 return 0
} }
if [ ${max_procs} -eq 1 ]; then if [ -z "${max_procs}" ]; then
fail_count=0 fail_count=0
for version in ${gcc_version}; do for version in ${gcc_version}; do
compile gcc ${version} ${test_cpp} ${compile_options} ${version_specific_options} ${gcc_root} compile gcc ${version} ${test_cpp} ${compile_options} ${version_specific_options} ${gcc_root}