forked from microsoft/CNTK
-
Notifications
You must be signed in to change notification settings - Fork 0
/
build-and-test
executable file
·338 lines (301 loc) · 11.9 KB
/
build-and-test
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
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
#!/bin/bash
# Setting some default values
BUILD=1
RUN=1
CLEAN_AFTER=0
CLEAN_BEFORE=0
RANDOM_OUTPUT=0
FLAVORS="debug:release"
TARGETS="cpu:gpu"
TESTTARGETS="cpu:gpu"
# parsing command line arguments:
while [[ $# > 0 ]]
do
key="$1"
case $key in
-h|--help)
echo "Usage: build-and-test [options]"
echo "Options:"
echo " -q|--quiet-build - redirect build output to file"
echo " -r|--run-only - elides build step, runs the binaries that have already been built"
echo " -b|--build-only - just build, do not run"
echo " -f|--flavors <flavor1:flavor2...> - which flavor to build (by default $FLAVORS)"
echo " -t|--targets <target1:target2...> - which target to build (by default $TARGETS)"
echo " -tt|--test-targets <testtarget1:testtarget2...> - which target to test (by default $TESTTARGETS)"
echo " -cb|--clean-build - clean up the enlistment binaries before build"
echo " -cba|--clean-build-after - clean up the enlistment binaries after build"
echo " -rnd|--random-output-suffix - add random suffix to output directory"
echo " -o|--output-directory <output_dir> - specify output directory to use (by default those will be in <cntk_root>.run-<operating_system>)"
echo "The root directory used to build and run CNTK is hosts the Scripts directory that contains this script"
exit 1
;;
-q|--quiet)
QUIET_BUILD=1
;;
-r|--run-only)
BUILD=0
RUN=1
;;
-rnd|--random-output-suffix)
RANDOM_OUTPUT=1
;;
-b|--build-only)
BUILD=1
RUN=0
;;
-cb|--clean-build)
CLEAN_BEFORE=1
BUILD=1
;;
-cba|--clean-build-after)
CLEAN_AFTER=1
BUILD=1
;;
-f|--flavors)
FLAVORS="${2,,}"
shift # past argument
;;
-t|--targets)
TARGETS="${2,,}"
shift # past argument
;;
-tt|--test-targets)
TESTTARGETS="${2,,}"
shift # past argument
;;
-o|--output-directory)
OUTPUT_DIR="$2"
shift # past argument
;;
*)
echo Unkown option $key
exit 1
;;
esac
shift # past argument or value
done
# Step 0 -- Validate all necessary prerequisites and check for incompatible options
# It is possible to use this script on Windows to build CNTK
# from Cygwin window with Visual C++ environment loaded.
# In that case OS environment variable will be set and we
# can use it to differentiate from Linux.
if [[ $CLEAN_BEFORE == 1 && $RUN == 1 && $BUILD == 0 ]]; then
echo "============ ERROR: Incompatible options RUN and CLEAN_BEFORE set without BUILD ============"
exit 1
fi
if [[ $OS == "Windows_NT" && $OSTYPE == "cygwin" ]]; then
DEBUG_DIR=Debug
RELEASE_DIR=Release
PREFIX_DIR=x64
BIN_NAME=CNTK.exe
BUILD_OS="windows"
if [[ $VS120COMNTOOLS == "" ]]; then
echo "============ Visual Studio 12.0 environment not properly setup or VS not installed ============"
echo "============ Please find and run the appropriate vcvarsall.bat script ============"
exit 1
fi
if [[ $ACML_PATH == "" ]]; then
echo "============ ACML path not set ============"
echo "============ ACML libraries are needed to successfully build CNTK ============"
exit 1
fi
if [[ "${TARGETS,,}" =~ "1bitsgd" && "${TARGETS,,}" =~ "gpu" ]]; then
echo "============ Cannot specify both GPU and 1bit-SGD as targets, please choose one ============"
exit 1
fi
elif [[ $OSTYPE == "linux-gnu" ]]; then
DEBUG_DIR=build/$TARGET/debug
RELEASE_DIR=build/$TARGET/release
PREFIX_DIR=
# Make sure no dependencies on current directory
BIN_NAME=bin/cntk
MAKEFILE=Makefile
BUILD_OS="linux"
else
echo "============ ERROR: Unsupported OS ============"
echo "============ Script supports only building from Linux and Windows through Cygwin ============"
exit 1
fi
# Step 1 -- Prepare temporary folders and files, tweak settings if necessary
# Get to the root path from which we know how to build and run
SCRIPT=`readlink -f $0`
SCRIPT_DIR=`dirname $SCRIPT`
CNTK_ROOT=`dirname $SCRIPT_DIR`
# Setup the output directory
if [[ $OUTPUT_DIR == "" ]]; then
OUTPUT_DIR="$CNTK_ROOT/.run-$BUILD_OS"
fi
# Add random number at the end of the output directory to prevent overwriting previous results
if [[ $RANDOM_OUTPUT == 1 ]]; then
OUTPUT_DIR="$OUTPUT_DIR-$RANDOM"
fi
echo "============ Creating CNTK temp directory in $OUTPUT_DIR ============"
mkdir -p $OUTPUT_DIR || exit $?
CONF_FILE="$OUTPUT_DIR/Simple.cntk"
BUILD_FILE="$OUTPUT_DIR/Build"
RUN_FILE="$OUTPUT_DIR/Result"
if ! [[ -d "$CNTK_ROOT/Source" ]]; then
echo "============ ERROR: Build script located in the wrong directory ($SCRIPT_DIR) ============"
exit 1
fi
cd $CNTK_ROOT
if ! [[ -f $CONF_FILE ]]; then
cp Examples/Other/Simple2d/Config/Simple.cntk $CONF_FILE || exit $?
# This chmod is necessary due to restrictive Cygwin interpretation of Windows permissions.
# Cygwin interprets Windows permissions as ----rwx---, which lacks read permissions for user.
chmod a+r $CONF_FILE || exit $?
fi
if [[ $QUIET_BUILD == 1 ]]; then
echo "============ WARNING: You have selected quiet build. All build output will be placed in ($OUTPUT_DIR) ============"
fi
# Initialize lists of flavors and targets
flavorArray=(${FLAVORS//:/ })
targetArray=(${TARGETS//:/ })
testTargetArray=(${TESTTARGETS//:/ })
# Step 2 -- Build the project for all requested flavors and targets
if [[ $BUILD == 1 ]]; then
for FLAVOR in "${flavorArray[@]}"
do
for TARGET in "${targetArray[@]}"
do
echo "============ Building CNTK $TARGET/$FLAVOR (clean=$CLEAN_BEFORE) ============"
# Our make is too noisy right now and it is difficult to spot
# issues from stdout and stderr. In the quiet mode these are
# redirected to a file where they could be examined after the fact
if [[ $QUIET_BUILD == 1 ]]; then
exec 6>$BUILD_FILE.$FLAVOR.out || exit $?
exec 7>$BUILD_FILE.$FLAVOR.err || exit $?
else
exec 6>&1 || exit $?
exec 7>&2 || exit $?
fi
if [[ $OS == "Windows_NT" ]]; then
OneBitSGDOPT=/property:CNTK_ENABLE_1BitSGD=
if [[ $TARGET == "cpu" ]]; then
CONFIGURATION=${FLAVOR}_CpuOnly
else
CONFIGURATION=${FLAVOR}
if [[ $TARGET == "1bitsgd" ]]; then
OneBitSGDOPT=/property:CNTK_ENABLE_1BitSGD=true
fi
fi
if [[ $CLEAN_BEFORE == 1 ]]; then
msbuild.exe /nologo /verbosity:m /property:Configuration=$CONFIGURATION /t:Clean 1>&6 2>&7 || exit $?
fi
msbuild.exe /nologo /verbosity:m /m /property:Configuration=$CONFIGURATION $OneBitSGDOPT 1>&6 2>&7 || exit $?
else
OneBitSGDOPT=no
BUILD_DIR=build/$TARGET/$FLAVOR
if [[ $TARGET == "cpu" ]]; then
CUDAOPT=no
else
CUDAOPT=yes
if [[ $TARGET == "1bitsgd" ]]; then
OneBitSGDOPT=yes
fi
fi
./configure --with-build-top=$BUILD_DIR --with-acml=$ACML_PATH --with-buildtype=$FLAVOR --cuda=$CUDAOPT --1bitsgd=$OneBitSGDOPT
if [[ $CLEAN_BEFORE == 1 ]]; then
make -C $BUILD_DIR -f $MAKEFILE clean 1>&6 2>&7 || exit $?
fi
make -C $BUILD_DIR -j `nproc` -f $MAKEFILE 1>&6 2>&7 || exit $?
fi
if [[ $QUIET_BUILD == 1 ]]; then
chmod a+r $BUILD_FILE.*
fi
done
done
fi
# Step 3 -- Run the project tests, both debug and release, if requested
if [[ $RUN == 1 ]]; then
cd $PREFIX_DIR
echo "============ cp Examples/Other/Simple2d/Config/Simple.cntk $CONF_FILE ============"
echo "============ cd $CNTK_ROOT/Examples/Other/Simple2d/Data ============"
for FLAVOR in "${flavorArray[@]}"
do
for TARGET in "${targetArray[@]}"
do
for TESTTARGET in "${testTargetArray[@]}"
do
# Determine how to set the deviceId parameter in the configuration.
# 0 will pick the first GPU (or fail. -1 will pick the CPU.
if [[ $TESTTARGET == gpu ]]; then
DEVICE_ID=0
else
DEVICE_ID=-1
fi
if [[ $TESTTARGET == gpu && $TARGET == cpu ]]; then
# CPU-only builds cannot run GPU test targets
continue;
fi
if [[ $OSTYPE == "linux-gnu" ]]; then
FLAVOR_DIR=build/$TARGET/$FLAVOR
else
if [[ $FLAVOR == "debug" ]]; then
FLAVOR_DIR="$DEBUG_DIR"
else
FLAVOR_DIR="$RELEASE_DIR"
fi
if [[ $TARGET == cpu ]]; then
FLAVOR_DIR="${FLAVOR}_CpuOnly"
fi
fi
OUT_FILE="$RUN_FILE.$FLAVOR.$TARGET.$TESTTARGET.out"
BIN_PATH=$CNTK_ROOT/$PREFIX_DIR/$FLAVOR_DIR/$BIN_NAME
if ! [[ -f $BIN_PATH ]]; then
echo "============ ERROR: CNTK did not build properly for $TARGET/$FLAVOR ============"
echo "Missing file: $BIN_PATH"
exit 1
fi
if [[ $OS == "Windows_NT" ]]; then
echo "============ Running $BIN_PATH configFile=`cygpath -w $CONF_FILE` for $TARGET/$FLAVOR (on $TESTTARGET) ============"
else
echo "============ Running $BIN_PATH configFile=$CONF_FILE for $TARGET/$FLAVOR (on $TESTTARGET) ============"
fi
echo "============ output in ($OUT_FILE) ============"
cd $CNTK_ROOT/Examples/Other/Simple2d/Data
rm -rf "$OUTPUT_DIR/Models"
if [[ $OS == "Windows_NT" ]]; then
# We have to use cygpath on Windows to modify the file paths into the format readable by cntk.
time $BIN_PATH configFile="`cygpath -w $CONF_FILE`" deviceId=$DEVICE_ID OutputDir="`cygpath -w $OUTPUT_DIR`" &>$OUT_FILE || exit $?
else
time $BIN_PATH configFile=$CONF_FILE deviceId=$DEVICE_ID OutputDir="$OUTPUT_DIR" &>$OUT_FILE || exit $?
fi
chmod a+r $RUN_FILE.*
# Check if execution was successful
grep -q "Using ${TESTTARGET^^}" "$OUT_FILE" || {
echo "============ ERROR: Run output (in $OUT_FILE) did not contain information about target device ($TESTTARGET) ============"
exit 1
}
grep -q "EXCEPTION" "$OUT_FILE" && {
echo "============ ERROR: Run output in ($OUT_FILE) contains exceptions ============"
grep "EXCEPTION" "$OUT_FILE"
exit 1
}
done
done
done
fi
# Step 5 -- Optionally clean after builds and tests
if [[ $CLEAN_AFTER == 1 ]]; then
cd $CNTK_ROOT
for FLAVOR in "${flavorArray[@]}"
do
for TARGET in "${targetArray[@]}"
do
echo "============ Cleaning up CNTK $TARGET/$FLAVOR ============"
if [[ $OS == "Windows_NT" ]]; then
if [[ $TARGET == "cpu" ]]; then
CONFIGURATION=${FLAVOR}_CpuOnly
else
CONFIGURATION=${FLAVOR}
fi
msbuild.exe /nologo /verbosity:m /property:Configuration=$CONFIGURATION /t:clean 1>&6 2>&7 || exit $?
else
make -C build/$TARGET/$FLAVOR -f $MAKEFILE clean 1>&6 2>&7 || exit $?
fi
done
done
rm -rf "$OUTPUT_DIR"
fi
echo "============ Build and test of CNTK was successful! ============"