This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] gcc parallel make check
- From: Jakub Jelinek <jakub at redhat dot com>
- To: David Malcolm <dmalcolm at redhat dot com>
- Cc: Mike Stump <mikestump at comcast dot net>, VandeVondele Joost <joost dot vandevondele at mat dot ethz dot ch>, "gcc at gcc dot gnu dot org" <gcc at gcc dot gnu dot org>, "fortran at gcc dot gnu dot org" <fortran at gcc dot gnu dot org>, "gcc-patches at gcc dot gnu dot org" <gcc-patches at gcc dot gnu dot org>
- Date: Thu, 11 Sep 2014 16:53:00 +0200
- Subject: Re: [PATCH] gcc parallel make check
- Authentication-results: sourceware.org; auth=none
- References: <908103EDB4893A42920B21D3568BFD93150F414C at MBX23 dot d dot ethz dot ch> <20140905145304 dot GM17454 at tucnak dot redhat dot com> <908103EDB4893A42920B21D3568BFD93150F7F45 at MBX23 dot d dot ethz dot ch> <908103EDB4893A42920B21D3568BFD93150F816B at MBX23 dot d dot ethz dot ch> <229476F6-B901-4C6E-AE0B-3A53521AE996 at comcast dot net> <1410381512 dot 28338 dot 9 dot camel at surprise> <20140910210822 dot GK17454 at tucnak dot redhat dot com> <20140910212334 dot GL17454 at tucnak dot redhat dot com> <20140911075123 dot GN17454 at tucnak dot redhat dot com> <20140911080640 dot GP17454 at tucnak dot redhat dot com>
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
On Thu, Sep 11, 2014 at 10:06:40AM +0200, Jakub Jelinek wrote:
> There is an option to touch say *-parallel/finished file once any of the
> check-parallel-gcc-{1,2,...} goals is done (because when it finishes, it
> means all the tests for the particular check-$lang that are parallelizable
> have either finished, or at least touched their file) and not start runtest
> at all if finished already exists, but guess it would be still undesirable to have
> tens of thousands of goals by default, so perhaps we could go with say
> 128 subgoals by default and have some env var to override it, so on the
> really highly parallel boxes you'd specify
> make -j512 -k check GCC_TEST_PARALLEL_SLOTS=512
> or similar.
Here is a patch I'm testing now:
--- gcc/Makefile.in.jj 2014-09-08 22:12:56.000000000 +0200
+++ gcc/Makefile.in 2014-09-11 16:06:36.641219430 +0200
@@ -513,34 +513,10 @@ xm_include_list=@xm_include_list@
xm_defines=@xm_defines@
lang_checks=
lang_checks_parallelized=
-dg_target_exps:=aarch64.exp,alpha.exp,arm.exp,avr.exp,bfin.exp,cris.exp
-dg_target_exps:=$(dg_target_exps),epiphany.exp,frv.exp,i386.exp,ia64.exp
-dg_target_exps:=$(dg_target_exps),m68k.exp,microblaze.exp,mips.exp,powerpc.exp
-dg_target_exps:=$(dg_target_exps),rx.exp,s390.exp,sh.exp,sparc.exp,spu.exp
-dg_target_exps:=$(dg_target_exps),tic6x.exp,xstormy16.exp
-# This lists a couple of test files that take most time during check-gcc.
-# When doing parallelized check-gcc, these can run in parallel with the
-# remaining tests. Each word in this variable stands for work for one
-# make goal and one extra make goal is added to handle all the *.exp
-# files not handled explicitly already. If multiple *.exp files
-# should be run in the same runtest invocation (usually if they aren't
-# very long running, but still should be split of from the check-parallel-$lang
-# remaining tests runtest invocation), they should be concatenated with commas.
-# Note that [a-zA-Z] wildcards need to have []s prefixed with \ (needed
-# by tcl) and as the *.exp arguments are mached both as is and with
-# */ prefixed to it in runtest_file_p, it is usually desirable to include
-# a subdirectory name.
-check_gcc_parallelize=execute.exp=execute/2* \
- execute.exp=execute/\[013-9a-fA-F\]* \
- execute.exp=execute/\[pP\]*,dg.exp \
- execute.exp=execute/\[g-oq-zG-OQ-Z\]*,compile.exp=compile/2* \
- compile.exp=compile/\[9pP\]*,builtins.exp \
- compile.exp=compile/\[013-8a-oq-zA-OQ-Z\]* \
- dg-torture.exp,ieee.exp \
- vect.exp,unsorted.exp \
- guality.exp \
- struct-layout-1.exp,stackalign.exp \
- $(dg_target_exps)
+# Upper limit to which it is useful to parallelize this lang target.
+# It doesn't make sense to try e.g. 128 goals for small testsuites
+# like objc or go.
+check_gcc_parallelize=10000
lang_opt_files=@lang_opt_files@ $(srcdir)/c-family/c.opt $(srcdir)/common.opt
lang_specs_files=@lang_specs_files@
lang_tree_files=@lang_tree_files@
@@ -3631,27 +3607,32 @@ $(filter-out $(lang_checks_parallelized)
export TCL_LIBRARY ; fi ; \
$(RUNTEST) --tool $* $(RUNTESTFLAGS))
-$(patsubst %,%-subtargets,$(filter-out $(lang_checks_parallelized),$(lang_checks))): check-%-subtargets:
+$(patsubst %,%-subtargets,$(lang_checks)): check-%-subtargets:
@echo check-$*
check_p_tool=$(firstword $(subst _, ,$*))
-check_p_vars=$(check_$(check_p_tool)_parallelize)
+check_p_count=$(check_$(check_p_tool)_parallelize)
check_p_subno=$(word 2,$(subst _, ,$*))
-check_p_comma=,
-check_p_subwork=$(subst $(check_p_comma), ,$(if $(check_p_subno),$(word $(check_p_subno),$(check_p_vars))))
-check_p_numbers=1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
+check_p_numbers0:=1 2 3 4 5 6 7 8 9
+check_p_numbers1:=0 $(check_p_numbers0)
+check_p_numbers2:=$(foreach i,$(check_p_numbers0),$(patsubst %,$(i)%,$(check_p_numbers1)))
+check_p_numbers3:=$(patsubst %,0%,$(check_p_numbers1)) $(check_p_numbers2)
+check_p_numbers4:=$(foreach i,$(check_p_numbers0),$(patsubst %,$(i)%,$(check_p_numbers3)))
+check_p_numbers5:=$(patsubst %,0%,$(check_p_numbers3)) $(check_p_numbers4)
+check_p_numbers6:=$(foreach i,$(check_p_numbers0),$(patsubst %,$(i)%,$(check_p_numbers5)))
+check_p_numbers:=$(check_p_numbers0) $(check_p_numbers2) $(check_p_numbers4) $(check_p_numbers6)
check_p_subdir=$(subst _,,$*)
-check_p_subdirs=$(wordlist 1,$(words $(check_$*_parallelize)),$(check_p_numbers))
+check_p_subdirs=$(wordlist 1,$(check_p_count),$(wordlist 1,$(or $(GCC_TEST_PARALLEL_SLOTS),128),$(check_p_numbers)))
# For parallelized check-% targets, this decides whether parallelization
# is desirable (if -jN is used and RUNTESTFLAGS doesn't contain anything
# but optional --target_board or --extra_opts arguments). If desirable,
# recursive make is run with check-parallel-$lang{,1,2,3,4,5} etc. goals,
# which can be executed in parallel, as they are run in separate directories.
-# check-parallel-$lang{1,2,3,4,5} etc. goals invoke runtest with the longest
-# running *.exp files from the testsuite, as determined by check_$lang_parallelize
-# variable. The check-parallel-$lang goal in that case invokes runtest with
-# all the remaining *.exp files not handled by the separate goals.
+# check-parallel-$lang{,1,2,3,4,5} etc. goals invoke runtest with
+# GCC_RUNTEST_PARALLELIZE_DIR var in the environment and runtest_file_p
+# dejaGNU procedure is overridden to additionally synchronize through
+# a $lang-parallel directory which tests will be run by which runtest instance.
# Afterwards contrib/dg-extract-results.sh is used to merge the sum and log
# files. If parallelization isn't desirable, only one recursive make
# is run with check-parallel-$lang goal and check_$lang_parallelize variable
@@ -3662,76 +3643,61 @@ check_p_subdirs=$(wordlist 1,$(words $(c
# to lang_checks_parallelized variable and define check_$lang_parallelize
# variable (see above check_gcc_parallelize description).
$(lang_checks_parallelized): check-% : site.exp
+ -rm -rf $(TESTSUITEDIR)/$*-parallel
@if [ -z "$(filter-out --target_board=%,$(filter-out --extra_opts%,$(RUNTESTFLAGS)))" ] \
&& [ "$(filter -j, $(MFLAGS))" = "-j" ]; then \
+ test -d $(TESTSUITEDIR) || mkdir $(TESTSUITEDIR) || true; \
+ test -d $(TESTSUITEDIR)/$*-parallel || mkdir $(TESTSUITEDIR)/$*-parallel || true; \
+ GCC_RUNTEST_PARALLELIZE_DIR=`${PWD_COMMAND}`/$(TESTSUITEDIR)/$(check_p_tool)-parallel ; \
+ export GCC_RUNTEST_PARALLELIZE_DIR ; \
$(MAKE) TESTSUITEDIR="$(TESTSUITEDIR)" RUNTESTFLAGS="$(RUNTESTFLAGS)" \
check-parallel-$* \
$(patsubst %,check-parallel-$*_%, $(check_p_subdirs)); \
- for file in $(TESTSUITEDIR)/$*/$* \
- $(patsubst %,$(TESTSUITEDIR)/$*%/$*,$(check_p_subdirs));\
+ sums= ; logs= ; \
+ for dir in $(TESTSUITEDIR)/$* \
+ $(patsubst %,$(TESTSUITEDIR)/$*%,$(check_p_subdirs));\
do \
- mv -f $$file.sum $$file.sum.sep; mv -f $$file.log $$file.log.sep; \
+ if [ -d $$dir ]; then \
+ mv -f $$dir/$*.sum $$dir/$*.sum.sep; mv -f $$dir/$*.log $$dir/$*.log.sep; \
+ sums="$$sums $$dir/$*.sum.sep"; logs="$$logs $$dir/$*.log.sep"; \
+ fi; \
done; \
- $(SHELL) $(srcdir)/../contrib/dg-extract-results.sh \
- $(TESTSUITEDIR)/$*/$*.sum.sep \
- $(patsubst %,$(TESTSUITEDIR)/$*%/$*.sum.sep,$(check_p_subdirs)) \
+ $(SHELL) $(srcdir)/../contrib/dg-extract-results.sh $$sums \
> $(TESTSUITEDIR)/$*/$*.sum; \
- $(SHELL) $(srcdir)/../contrib/dg-extract-results.sh -L \
- $(TESTSUITEDIR)/$*/$*.log.sep \
- $(patsubst %,$(TESTSUITEDIR)/$*%/$*.log.sep,$(check_p_subdirs)) \
+ $(SHELL) $(srcdir)/../contrib/dg-extract-results.sh -L $$logs \
> $(TESTSUITEDIR)/$*/$*.log; \
+ rm -rf $(TESTSUITEDIR)/$*-parallel || true; \
else \
$(MAKE) TESTSUITEDIR="$(TESTSUITEDIR)" RUNTESTFLAGS="$(RUNTESTFLAGS)" \
check_$*_parallelize= check-parallel-$*; \
fi
-# Just print the parallelized subtargets for those that want to split
-# the testing across machines.
-$(patsubst %,%-subtargets,$(lang_checks_parallelized)): check-%-subtargets:
- @echo check-parallel-$* \
- $(patsubst %,check-parallel-$*_%, $(check_p_subdirs))
-
-# In the if [ -n "$(check_p_subno)" ] case runtest should be given the name of
-# the given *.exp file(s). See comment above check_gcc_parallelize variable
-# for details on the content of these variables.
-#
-# In the elif [ -n "$(check_p_vars)" ] case runtest should be given
-# names of all the *.exp files for this tool that aren't already handled by
-# other goals. First it finds all the *.exp files for this tool, then
-# prunes those already specified in check_$lang_parallelize or duplicates.
-#
-# Otherwise check-$lang isn't parallelized and runtest is invoked just with
-# the $(RUNTESTFLAGS) arguments.
check-parallel-% : site.exp
-test -d plugin || mkdir plugin
-test -d $(TESTSUITEDIR) || mkdir $(TESTSUITEDIR)
test -d $(TESTSUITEDIR)/$(check_p_subdir) || mkdir $(TESTSUITEDIR)/$(check_p_subdir)
-(rootme=`${PWD_COMMAND}`; export rootme; \
srcdir=`cd ${srcdir}; ${PWD_COMMAND}` ; export srcdir ; \
- cd $(TESTSUITEDIR)/$(check_p_subdir); \
- rm -f tmp-site.exp; \
- sed '/set tmpdir/ s|testsuite$$|$(TESTSUITEDIR)/$(check_p_subdir)|' \
+ if [ -n "$(check_p_subno)" \
+ -a -n "$$GCC_RUNTEST_PARALLELIZE_DIR" \
+ -a -f $(TESTSUITEDIR)/$(check_p_tool)-parallel/finished ]; then \
+ rm -rf $(TESTSUITEDIR)/$(check_p_subdir); \
+ else \
+ cd $(TESTSUITEDIR)/$(check_p_subdir); \
+ rm -f tmp-site.exp; \
+ sed '/set tmpdir/ s|testsuite$$|$(TESTSUITEDIR)/$(check_p_subdir)|' \
< ../../site.exp > tmp-site.exp; \
- $(SHELL) $${srcdir}/../move-if-change tmp-site.exp site.exp; \
- EXPECT=${EXPECT} ; export EXPECT ; \
- if [ -f $${rootme}/../expect/expect ] ; then \
- TCL_LIBRARY=`cd .. ; cd $${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
- export TCL_LIBRARY ; fi ; \
- runtestflags= ; \
- if [ -n "$(check_p_subno)" ] ; then \
- runtestflags="$(check_p_subwork)"; \
- elif [ -n "$(check_p_vars)" ] ; then \
- parts="`echo ' $(strip $(subst $(check_p_comma), ,$(check_p_vars))) ' \
- | sed 's/=[^ ]* / /g'`"; \
- for part in `find $$srcdir/testsuite/$(check_p_tool)* -name \*.exp` ; do \
- part=`basename $$part` ; \
- case " $$parts $$runtestflags " in \
- *" $$part "*) ;; \
- *) runtestflags="$$runtestflags $$part" ;; \
- esac ; \
- done ; \
- fi ; \
- $(RUNTEST) --tool $(check_p_tool) $(RUNTESTFLAGS) $$runtestflags)
+ $(SHELL) $${srcdir}/../move-if-change tmp-site.exp site.exp; \
+ EXPECT=${EXPECT} ; export EXPECT ; \
+ if [ -f $${rootme}/../expect/expect ] ; then \
+ TCL_LIBRARY=`cd .. ; cd $${srcdir}/../tcl/library ; ${PWD_COMMAND}` ; \
+ export TCL_LIBRARY ; \
+ fi ; \
+ $(RUNTEST) --tool $(check_p_tool) $(RUNTESTFLAGS); \
+ if [ -n "$$GCC_RUNTEST_PARALLELIZE_DIR" ] ; then \
+ touch $${rootme}/$(TESTSUITEDIR)/$(check_p_tool)-parallel/finished; \
+ fi ; \
+ fi )
# QMTest targets
--- gcc/go/Make-lang.in.jj 2014-05-02 15:39:49.766921376 +0200
+++ gcc/go/Make-lang.in 2014-09-11 16:08:50.049547349 +0200
@@ -131,11 +131,7 @@ go.srcman: doc/gccgo.1
lang_checks += check-go
lang_checks_parallelized += check-go
-check_go_parallelize = go-test.exp=*/test/\[0-57-9a-bd-hj-qs-zA-Z\]* \
- go-test.exp=*/test/c* \
- go-test.exp=*/test/i* \
- go-test.exp=*/test/r* \
- go-test.exp=*/test/6*
+check_go_parallelize = 10
# Install hooks.
--- gcc/fortran/Make-lang.in.jj 2014-01-03 11:40:51.548352536 +0100
+++ gcc/fortran/Make-lang.in 2014-09-11 16:08:36.788612700 +0200
@@ -168,12 +168,7 @@ check-fortran-subtargets : check-gfortra
lang_checks += check-gfortran
lang_checks_parallelized += check-gfortran
# For description see comment above check_gcc_parallelize in gcc/Makefile.in.
-check_gfortran_parallelize = dg.exp=gfortran.dg/\[adAD\]* \
- dg.exp=gfortran.dg/\[bcBC\]* \
- dg.exp=gfortran.dg/\[nopNOP\]* \
- dg.exp=gfortran.dg/\[isuvISUV\]* \
- dg.exp=gfortran.dg/\[efhkqrxzEFHKQRXZ\]* \
- dg.exp=gfortran.dg/\[0-9gjlmtwyGJLMTWY\]*
+check_gfortran_parallelize = 10000
# GFORTRAN documentation.
GFORTRAN_TEXI = \
--- gcc/cp/Make-lang.in.jj 2014-09-10 21:57:10.240320174 +0200
+++ gcc/cp/Make-lang.in 2014-09-11 16:08:27.367658600 +0200
@@ -156,11 +156,7 @@ check-c++-subtargets : check-g++-subtarg
lang_checks += check-g++
lang_checks_parallelized += check-g++
# For description see comment above check_gcc_parallelize in gcc/Makefile.in.
-check_g++_parallelize = old-deja.exp \
- dg.exp=g++.dg/[0-9A-Za-bd-su-z]* \
- dg.exp=g++.dg/[ct]* \
- dg.exp=c-c++-common/*,dg-torture.exp
-
+check_g++_parallelize = 10000
#
# Install hooks:
# cc1plus is installed elsewhere as part of $(COMPILERS).
--- gcc/testsuite/lib/gcc-defs.exp.jj 2014-09-11 11:02:36.045944898 +0200
+++ gcc/testsuite/lib/gcc-defs.exp 2014-09-11 14:29:54.546328102 +0200
@@ -188,6 +188,30 @@ if { [info procs runtest_file_p] == "" }
}
}
+if { [info exists env(GCC_RUNTEST_PARALLELIZE_DIR)] \
+ && [info procs runtest_file_p] != [list] \
+ && [info procs gcc_parallelize_saved_runtest_file_p] == [list] } then {
+ rename runtest_file_p gcc_parallelize_saved_runtest_file_p
+ global gcc_runtest_parallelize_counter
+
+ set gcc_runtest_parallelize_counter 0
+ proc runtest_file_p { runtests testcase } {
+ global gcc_runtest_parallelize_counter
+ if ![gcc_parallelize_saved_runtest_file_p $runtests $testcase] {
+ return 0
+ }
+
+ set dir [getenv GCC_RUNTEST_PARALLELIZE_DIR]
+ set path $dir/$gcc_runtest_parallelize_counter
+ set gcc_runtest_parallelize_counter [expr {$gcc_runtest_parallelize_counter + 1}]
+ if {![catch {open $path {RDWR CREAT EXCL} 0600} fd]} {
+ close $fd
+ return 1
+ }
+ return 0
+ }
+}
+
# Like dg-options, but adds to the default options rather than replacing them.
proc dg-additional-options { args } {
--- gcc/objc/Make-lang.in.jj 2014-01-03 11:40:35.471444709 +0100
+++ gcc/objc/Make-lang.in 2014-09-11 16:09:02.671483908 +0200
@@ -96,7 +96,7 @@ lang_checks += check-objc
# The following allows you to do 'make check-objc -j2'. The
# execute.exp tests will be run in parallel with all the other ones.
lang_checks_parallelized += check-objc
-check_objc_parallelize = gnu-encoding.exp execute.exp exceptions.exp
+check_objc_parallelize = 6
#
# Install hooks:
Jakub