From 6b77d86563147cea3bb2e1528228dddb41b16aa0 Mon Sep 17 00:00:00 2001 From: Henry Weller <http://cfd.direct> Date: Sun, 3 Jul 2016 22:55:16 +0100 Subject: [PATCH] wmakeCollect: Experimental scheduler for wmake to speed-up parallel compilations wmakeCollect collects the compilation commands for the all of the object files to be compiled into a single makefile which is passed to make to schedule the compilations in parallel efficiently. Before wmakeCollect can be called the lnInclude directories must be up-to-date and after wmakeCollect the linkage stage of the compilation must executed using wmake. This entire process is now handled by wmake using the new '-queue' or '-q' option to compile sections of the OpenFOAM source tree or the entire tree efficiently. The number of cores the compilation executes on may be specified either using the WM_NCOMPPROCS variable or the '-j' option. To efficiently compile OpenFOAM after a 'git pull' the '-update' option is provided which updates lnInclude directories, dep files and removes deprecated files and directories. This option may be used with '-q': wmake -q -update --- wmake/wmake | 112 +++++++++++++++++++++++++------ wmake/wmakeCollect | 160 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 251 insertions(+), 21 deletions(-) create mode 100755 wmake/wmakeCollect diff --git a/wmake/wmake b/wmake/wmake index 6d3f116d99c..0e4f6504a83 100755 --- a/wmake/wmake +++ b/wmake/wmake @@ -49,7 +49,7 @@ # wdep -h # # See also -# wmakeLnInclude, wmakeLnIncludeAll, wdep, wrmdep, wrmo, +# wmakeLnInclude, wmakeLnIncludeAll, wmakeQueue, wdep, wrmdep, wrmo, # wclean, wcleanPlatform, wcleanLnIncludeAll # #------------------------------------------------------------------------------ @@ -64,8 +64,15 @@ Usage: $Script [OPTION] [dir] $Script [OPTION] target [dir [MakeDir]] options: - -s | -silent Run make in 'silent' mode (do not echo commands) - -a | -all Run wmake in all subdirectories + -s | -silent 'silent' mode (does not echo commands) + -a | -all wmake all sub-directories, running Allwmake if present + -q | -queue wmakeQueue all sub-directories, running Allwmake if present + -k or -non-stop Compile without stopping when errors occur + -j Compile using all local cores/hyperthreads + -jN or -j N Compile using N cores/hyperthreads + -no-scheduler Compile without wmakeScheduler + -update Update lnInclude directories, dep files, remove deprecated + files and directories -h | -help Print the usage @@ -76,7 +83,8 @@ The 'target' is a Makefile target: e.g., platforms/linux64GccDPOpt/.../fvMesh.o or a special target: - all wmake all subdirectories, running Allwmake files if present + all wmake all sub-directories, running Allwmake if present + queue wmakeQueue all sub-directories, running Allwmake if present exe Compile statically linked executable lib Compile statically linked archive lib (.a) libo Compile statically linked lib (.o) @@ -104,24 +112,65 @@ all= while [ "$#" -gt 0 ] do case "$1" in - -h | -help) - usage - ;; - -s | -silent) - make="$make -s" - shift - ;; - -a | -all | all) - all="all" - shift - ;; - -*) - usage "unknown option: '$*'" - ;; - *) - break - ;; + # Print help + -h | -help) + usage + ;; + -s | -silent) + make="$make -s" + ;; + -a | -all | all) + all="all" + ;; + -q | -queue | queue) + all="queue" + ;; + # Parallel compilation on all cores of local machine + -j) + setWM_NCOMPPROCS + test $# -ge 2 && expr $2 + 1 > /dev/null 2>&1 \ + && shift && export WM_NCOMPPROCS=$1 + echo "Compiling enabled on $WM_NCOMPPROCS cores" + ;; + # Parallel compilation on specified number of cores + -j*) + export WM_NCOMPPROCS=${1#-j} + echo "Compiling enabled on $WM_NCOMPPROCS cores" + ;; + # Non-stop compilation, ignoring errors + -k | -non-stop) + export WM_CONTINUE_ON_ERROR=1 + ;; + # Disable scheduled parallel compilation + -no-scheduler) + unset WM_SCHEDULER + ;; + # Meant to be used following a pull, this will: + # - remove dep files that depend on deleted files; + # - remove stale dep files; + # - update lnInclude directories; + # - remove empty directories, along with deprecated object directories + # and respective binaries. + -update) + wrmdep -update + wrmdep -old + wmakeLnIncludeAll + wclean empty + export WM_UPDATE_DEPENDENCIES=yes + [ -z "$all" ] && all="all" + ;; + --) + shift + break + ;; + -*) + usage "unknown option: '$*'" + ;; + *) + break + ;; esac + shift done @@ -252,6 +301,27 @@ then fi +#------------------------------------------------------------------------------ +# Recurse the source tree to compile "all" targets using wmakeQueue +#------------------------------------------------------------------------------ + +#scheduler="wmakeQueue" +scheduler="wmakeCollect" + +if [ "$all" = "queue" ] +then + ( \ + wmakeLnIncludeAll -j$WM_NCOMPPROCS \ + && WM_ID=$(stat --format=%d.%i $PWD) \ + WM_SCHEDULER=$scheduler \ + trap '$scheduler -kill' TERM INT; \ + wmake -all objects \ + && $scheduler \ + ) && wmake -all + exit $? +fi + + #------------------------------------------------------------------------------ # Search up the directory tree for the Make sub-directory, # check the existance of the 'files' file and build there if present diff --git a/wmake/wmakeCollect b/wmake/wmakeCollect new file mode 100755 index 00000000000..4a3525a3422 --- /dev/null +++ b/wmake/wmakeCollect @@ -0,0 +1,160 @@ +#!/bin/bash +#------------------------------------------------------------------------------ +# ========= | +# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox +# \\ / O peration | +# \\ / A nd | Copyright (C) 2016 OpenFOAM Foundation +# \\/ M anipulation | +#------------------------------------------------------------------------------- +# License +# This file is part of OpenFOAM. +# +# OpenFOAM is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# OpenFOAM is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# for more details. +# +# You should have received a copy of the GNU General Public License +# along with OpenFOAM. If not, see <http://www.gnu.org/licenses/>. +# +# Script +# wmakeCollect +# +# Usage +# wmakeCollect [OPTION] <command> +# +# Description +# wmake scheduler for efficient parallel compilations. +# +#------------------------------------------------------------------------------- +Script=${0##*/} + +usage() { + exec 1>&2 + while [ "$#" -ge 1 ]; do echo "$1"; shift; done + cat<<USAGE + +Usage: $Script [OPTION] <command> + +options: + -kill Removes temporary makefiles + -h | -help Print the usage + +Collecting scheduler for fast parallel compilation of large numbers of object +files. Can be used in compiling OpenFOAM by setting the WM_SCHEDULER variable. + +When called with a compilation command it is written into a file in the +directory ~.\$WM_PROJECT/.collect/$WM_ID. + +When called without a command the files in the ~.\$WM_PROJECT/.collect/$WM_ID +are combined into a single Makefile which is passed to make to compile all of +the object files in parallel. + +Typical usage for compiling OpenFOAM: + + - Ensure all lnInclude directories are up-to-date: + wmakeLnIncludeAll + + - Compile all with this scheduler: + wmake -queue or wmake -q + +USAGE + exit 1 +} + +# Set true to clean-up file if interupted +cleanup= + +while [ "$#" -gt 0 ] +do + case "$1" in + -h | -help) + usage + ;; + -kill) + cleanup="true" + shift + ;; + -*) + usage "unknown option: '$*'" + break + ;; + *) + break + ;; + esac +done + + +if [ -z "$WM_ID" ] +then + echo "$Script error: build ID variable WM_ID not set" + exit 1 +fi + +# Location of the wmakeCollect makefiles +wmakeCollectDir=$HOME/.$WM_PROJECT/.collect + +# Make sure directories exist +mkdir -p $wmakeCollectDir + +# Location of the wmakeCollect makefiles for this build +collectDir=$wmakeCollectDir/$WM_ID + +# Collected makefile for this build +makefile="$wmakeCollectDir/Makefile.$WM_ID" + + +# Clean-up files and exit +if [ -n "$cleanup" ] +then + rm -rf $collectDir + rm -f $makefile + exit 0 +fi + + +if [ "$#" -gt 0 ] +then + # Make sure directories exist + mkdir -p $collectDir + + # Unique file name for makefile for the current target + file="$collectDir/$$_${RANDOM}" + + # The current target + object="${@: -1:1}" + + # Add the current target to the list of objects + echo "OBJECTS += $object" >> $file + + # Add the build rule for the current target + echo "$object: $makefile" >> $file + echo -e "\t cd $PWD && \\" >> $file + echo -e "\t${@:1:($#-1)} $object" >> $file + echo >> $file +else + if [ -d $collectDir ] + then + # Collect all the makefiles into a single makefiles for this build + cat $collectDir/* > $makefile + + # Add a build rule for all of the targets + echo 'all: $(OBJECTS)' >> $makefile + + # Clear out all of the target makefiles + rm -rf $collectDir + + # Run make on the collected makefile + make -j $WM_NCOMPPROCS -f $makefile all + + rm -f $makefile + fi +fi + +#------------------------------------------------------------------------------ -- GitLab