1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248
|
#!/bin/bash
#------------------------------------------------------------------------------
# ========= |
# \\ / F ield | OpenFOAM: The Open Source CFD Toolbox
# \\ / O peration |
# \\ / A nd | Copyright (C) 2011-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
# wmakeScheduler
#
# Usage
# wmakeScheduler COMMAND
# run 'COMMAND' on one of the slots listed in WM_HOSTS
#
# wmakeScheduler -count
# count the total number of slots available in WM_HOSTS
# eg, export WM_NCOMPPROCS=$(wmakeScheduler -count)
#
# Description
# Scheduler for network distributed compilations using wmake.
# - WM_HOSTS contains a list of hosts and number of concurrent processes
# eg,
# export WM_HOSTS="hostA:1 hostB:2 hostC:1"
# - WM_COLOURS contains a list of colours to cycle through
# export WM_COLOURS="black blue green cyan red magenta yellow"
#
# Sources the relevant cshrc/bashrc if not set.
#
# WM_PROJECT_DIR, WM_PROJECT and WM_PROJECT_VERSION will have been set
# before calling this routine.
# FOAM_INST_DIR may possibly have been set (to find installation)
#
#-------------------------------------------------------------------------------
Script=${0##*/}
# csh sets HOST, bash sets HOSTNAME
: ${HOST:=$HOSTNAME}
lockDir=$HOME/.$WM_PROJECT/.wmake
# Fallback - 1 core on current host
: ${WM_HOSTS:=$HOST:1}
# Count the total number of slots available and exit
if [ "$1" = "-count" ]
then
expr $(
for slotGroup in $WM_HOSTS
do
n=${slotGroup##*:}
[ "$n" = "${slotGroup%%:*}" ] && n=1 # missing ':'
echo "+ ${n:-1}"
done
)
exit 0
fi
# Where to source WM_PROJECT settings in a remote shell
# This code tries to figure out which cshrc or bashrc to execute.
# !! Assumes remote computer running same shell and startup files
# in same location
sourceFoam=false # Fallback command
case $SHELL in
*/csh | */tcsh ) # [t]csh vs bash|ksh|sh
shellRc=cshrc
;;
*)
shellRc=bashrc
;;
esac
# Check ~/.$WM_PROJECT/$WM_PROJECT_VERSION/
# Check ~/.$WM_PROJECT/
# Check <installedProject>/etc/
if [ "$WM_PROJECT" ]
then
for i in \
$HOME/.$WM_PROJECT/$WM_PROJECT_VERSION \
$HOME/.$WM_PROJECT \
$WM_PROJECT_DIR/etc \
;
do
if [ -f "$i/$shellRc" ]
then
sourceFoam="$i/$shellRc"
break
fi
done
fi
# Construct test string for remote execution.
# Source WM_PROJECT settings if WM_PROJECT environment not set.
# Attempt to preserve the installation directory 'FOAM_INST_DIR'
# Use FOAM_SETTINGS to pass command-line settings
case $sourceFoam in
*/bashrc)
if [ "$FOAM_INST_DIR" ]
then
sourceFoam='[ "$WM_PROJECT" ] || '"FOAM_INST_DIR=$FOAM_INST_DIR . $sourceFoam $FOAM_SETTINGS"
else
sourceFoam='[ "$WM_PROJECT" ] || '". $sourceFoam $FOAM_SETTINGS"
fi
;;
*/cshrc)
# TODO: csh equivalent to bash code (preserving FOAM_INST_DIR)
sourceFoam='if ( ! $?WM_PROJECT ) source '"$sourceFoam $FOAM_SETTINGS"
;;
esac
# Quote double-quotes for remote command line
rcmd=$(echo $* | sed -e s/\"/\'\"\'/g)
# The same, without forking (not ksh, maybe not /bin/sh either)
# rcmd=$(while [ "$#" -gt 0 ]; do echo "${1//\"/'\"'}"; shift; done)
# Convert WM_COLOURS into an array
declare colourList
nColours=0
for col in $WM_COLOURS
do
colourList[$nColours]=$col
((nColours = $nColours + 1))
done
# Bashism: make pipe fail early.
# This ensures the return value of the command is returned and not of the
# colouring pipe etc.
set -o pipefail
#------------------------------------------------------------------------------
# Colour output by argument 1
#------------------------------------------------------------------------------
colourPipe()
{
if tty -s <&1 # [ "$1" ]
then
(
while read line
do
setterm -foreground $1
echo "$line"
done
setterm -foreground default
)
else
cat
fi
}
colourIndex=0
# Check for existence of lockfile binary
if ! type -p lockfile >/dev/null
then
echo "$Script: Could not find executable 'lockfile'"
exit 1
fi
while :
do
for slotGroup in $WM_HOSTS
do
# Split 'host:N', but catch 'host:' and 'host' too
host=${slotGroup%%:*}
n=${slotGroup##*:}
[ "$n" = "$host" ] && n=1 # missing ':'
: ${n:=1}
i=0
while [ "$i" -lt "$n" ]
do
lockFile="$lockDir/$host:$i"
if lockfile -r0 "$lockFile" 2>/dev/null
then
if [ "$nColours" -gt 0 ]
then
# Set colour
colour="${colourList[$colourIndex]}"
if [ "$host" = "$HOST" ]; then
eval $* 2>&1 | colourPipe "$colour"
else
ssh $host "$sourceFoam 2>/dev/null; cd $PWD && $rcmd" \
2>&1 | colourPipe "$colour"
fi
retval=$?
else
if [ "$host" = "$HOST" ]; then
eval $* 2>&1
else
ssh $host "$sourceFoam 2>/dev/null; cd $PWD && $rcmd" \
2>&1
fi
retval=$?
fi
# Release lock
rm -f "$lockFile" 2>/dev/null
exit $retval
fi
i=$(expr $i + 1)
# Cycle through colours. Note: outside lock clause!
colourIndex=$(expr $colourIndex + 1)
[ "$colourIndex" -lt "$nColours" ] || colourIndex=0
done
done
# Did not find any free slots. Rest a bit.
sleep 1
done
if [ "$nColours" -gt 0 ]
then
setterm -foreground default
fi
#------------------------------------------------------------------------------
# Cleanup local variables and functions
#------------------------------------------------------------------------------
unset Script
#------------------------------------------------------------------------------
|