blob: 95bb3677f31ae1031623eb343ef009307dd3d801 [file] [log] [blame]
SiCong Li8b4c7302019-09-19 12:18:15 +01001# Copyright (c) 2019 ARM Limited.
2#
3# SPDX-License-Identifier: MIT
4#
5# Permission is hereby granted, free of charge, to any person obtaining a copy
6# of this software and associated documentation files (the "Software"), to
7# deal in the Software without restriction, including without limitation the
8# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9# sell copies of the Software, and to permit persons to whom the Software is
10# furnished to do so, subject to the following conditions:
11#
12# The above copyright notice and this permission notice shall be included in all
13# copies or substantial portions of the Software.
14#
15# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21# SOFTWARE.
22
23#!/bin/sh
24
25# Global: Global variables and global settings {{{
26# Treat unset variables as an error when substituting
27set -u
28
29CMD=$( basename $0 )
30
31# All supported strategy options
SiCong Liea803482019-09-26 16:55:49 +010032ALL_STRATEGY_OPTIONS=("native" "reshaped_rhs_only" "reshaped")
SiCong Li8b4c7302019-09-19 12:18:15 +010033
34# Names of example binary for each strategy
SiCong Liea803482019-09-26 16:55:49 +010035EXAMPLE_BIN_NATIVE="benchmark_cl_gemm_native"
SiCong Li8b4c7302019-09-19 12:18:15 +010036EXAMPLE_BIN_RESHAPED_RHS_ONLY="benchmark_cl_gemm_reshaped_rhs_only"
SiCong Libc166d52019-09-26 14:58:53 +010037EXAMPLE_BIN_RESHAPED="benchmark_cl_gemm_reshaped"
SiCong Li8b4c7302019-09-19 12:18:15 +010038
39# Default output directory
40DEFAULT_OUT_DIR="out"
41
42# Number of iterations for each benchmark run
SiCong Libc166d52019-09-26 14:58:53 +010043NUM_ITERATION=5
SiCong Li8b4c7302019-09-19 12:18:15 +010044# Global }}}
45
46# Functions {{{
47#######################################
48# Print gemm shape file help message
49# Globals:
50# None
51# Arguments:
52# None
53# Returns:
54# None
55#######################################
56function help_gemm_shape_file() {
57 cat >&2 << EOF
58Gemm shape file:
59 Gemm shape file is a headerless csv file with fields separated by commas and commas only (there cannot be whitespaces
60 around each field).
61 A gemm shape is a list of 4 positive integers <M, N, K, B> describing the shapes of the two matrices (LHS and RHS)
62 with:
63 M - Number of lhs matrix rows
64 N - Number of rhs matrix columns
65 K - Number of lhs matrix columns/rhs matrix rows
66 B - Batch size
67
68 An example gemm shape file looks like:
69 100,100,30,1
70 100,100,30,3
71 ...
72
73EOF
74}
75
76#######################################
SiCong Liea803482019-09-26 16:55:49 +010077# Print gemm config file for native help message
78# Globals:
79# None
80# Arguments:
81# None
82# Returns:
83# None
84#######################################
85function help_gemm_config_file_native() {
86 cat >&2 << EOF
87Gemm config file (Strategy native):
88 Gemm config file is a headerless csv file with fields separated by commas and commas only (there cannot be whitespaces
89 around each field).
90 A gemm config is a list of 4 positive integers <m0, n0, k0, h0> and 2 boolean values interleave_rhs and transpose_rhs, with:
91 m0 - Number of rows processed by the matrix multiplication
92 n0 - Number of columns processed by the matrix multiplication
93 k0 - Number of partial accumulations performed by the matrix multiplication
94
95 Only the following configurations of M0, N0 and K0 are currently supported:
96 M0 = 1, 2, 3, 4, 5, 6, 7, 8
97 N0 = 2, 3, 4, 8, 16
98 K0 = 2, 3, 4, 8, 16
99
100 An example gemm config file looks like:
101 1,4,4
102 2,3,8
103 ...
104
105EOF
106}
107
108#######################################
SiCong Libc166d52019-09-26 14:58:53 +0100109# Print gemm config file for reshaped_rhs_only help message
SiCong Li8b4c7302019-09-19 12:18:15 +0100110# Globals:
111# None
112# Arguments:
113# None
114# Returns:
115# None
116#######################################
117function help_gemm_config_file_reshaped_rhs_only() {
118 cat >&2 << EOF
119Gemm config file (Strategy reshaped_rhs_only):
120 Gemm config file is a headerless csv file with fields separated by commas and commas only (there cannot be whitespaces
121 around each field).
122 A gemm config is a list of 4 positive integers <m0, n0, k0, h0> and 2 boolean values interleave_rhs and transpose_rhs, with:
123 m0 - Number of rows processed by the matrix multiplication
124 n0 - Number of columns processed by the matrix multiplication
125 k0 - Number of partial accumulations performed by the matrix multiplication
126 h0 - Number of horizontal blocks of size (k0xn0) stored on the same output row
127 interleave_rhs - Interleave rhs matrix (1) / Do not interleave rhs matrix (0)
SiCong Libc166d52019-09-26 14:58:53 +0100128 transpose_rhs - Transpose rhs matrix (1) / Do not transpose rhs matrix (0)
SiCong Li8b4c7302019-09-19 12:18:15 +0100129
130 Only the following configurations of M0, N0 and K0 are currently supported:
131 M0 = 1, 2, 3, 4, 5, 6, 7, 8
132 N0 = 2, 3, 4, 8, 16
133 K0 = 2, 3, 4, 8, 16
134 H0 >= 1
135
136 An example gemm config file looks like:
SiCong Libc166d52019-09-26 14:58:53 +0100137 4,4,4,1,1,1
138 4,4,4,3,1,0
139 ...
140
141EOF
142}
143
144#######################################
145# Print gemm config file for reshaped help message
146# Globals:
147# None
148# Arguments:
149# None
150# Returns:
151# None
152#######################################
153function help_gemm_config_file_reshaped() {
154 cat >&2 << EOF
155Gemm config file (Strategy reshaped):
156 Gemm config file is a headerless csv file with fields separated by commas and commas only (there cannot be whitespaces
157 around each field).
158 A gemm config is a list of 5 positive integers <m0, n0, k0, v0, h0> and 3 boolean values interleave_lhs, interleave_rhs and transpose_rhs, with:
159 m0 - Number of rows processed by the matrix multiplication
160 n0 - Number of columns processed by the matrix multiplication
161 k0 - Number of partial accumulations performed by the matrix multiplication
162 v0 - Number of vertical blocks of size (m0xk0) stored on the same output row
163 h0 - Number of horizontal blocks of size (k0xn0) stored on the same output row
164 interleave_lhs - Interleave lhs matrix (1) / Do not interleave lhs matrix (0)
165 interleave_rhs - Interleave rhs matrix (1) / Do not interleave rhs matrix (0)
166 transpose_rhs - Transpose rhs matrix but not lhs matrix (1) / Do not transpose rhs matrix but do transpose lhs matrix (0)
167
168 If rhs matrix is transposed only the following configurations are currently supported:
169 M0 = 2, 3, 4, 5, 6, 7, 8
170 N0 = 2, 3, 4, 8, 16
171 K0 = 2, 3, 4, 8, 16
172 V0 >= 1
173 H0 >= 1
174
175 If lhs matrix is transposed only the following configurations are currently supported:
176 M0 = 2, 3, 4, 8
177 N0 = 2, 3, 4, 8, 16
178 K0 = 2, 3, 4, 8, 16
179 V0 >= 1
180 H0 >= 1
181
182 An example gemm config file looks like:
183 4,4,4,1,3,1,1,1
184 4,4,4,3,3,1,1,0
SiCong Li8b4c7302019-09-19 12:18:15 +0100185 ...
186
187EOF
188}
189
190#######################################
191# Print usage of this program and exit with Error
192# Globals:
193# Assumes all globals are required
194# Arguments:
195# None
196# Returns:
197# Error(1)
198#######################################
199function usage() {
200 cat >&2 << EOF
201Run gemm examples of a selected strategy, over provided tunable configurationsa and gemm shapes.
202Save the benchmark results to json files in an output directory.
203
SiCong Libc166d52019-09-26 14:58:53 +0100204Usage: ${CMD} [-h] -s <strategy> -e <example_binary_dir> -g <gemm_shape_file> -c <gemm_config_file> [-o <out_dir>]
SiCong Li8b4c7302019-09-19 12:18:15 +0100205
206Options:
207 -h
SiCong Libc166d52019-09-26 14:58:53 +0100208 Print help messages. If a strategy is specified with -s <strategy>, then only display messages relevant to that
209 strategy. Otherwise if no strategy is specified, display messages for all available strategies.
210
211 -s <strategy>
212 Strategy option.
213 Options: ${ALL_STRATEGY_OPTIONS[@]}.
SiCong Li8b4c7302019-09-19 12:18:15 +0100214
215 -e <example_binary_dir>
216 Path to directory that holds all example binaries
217
218 -g <gemm_shape_file>
219 Path to gemm shape csv file
220
221 -c <gemm_config_file>
222 Path to gemm config csv file
223
SiCong Li8b4c7302019-09-19 12:18:15 +0100224 -o <out_dir>
225 Path to output directory that holds output json files
226 Default: ${DEFAULT_OUT_DIR}
227
228EOF
229# Print help messages about gemm shapes and various gemm configs
230$HELP && help_gemm_shape_file
SiCong Liea803482019-09-26 16:55:49 +0100231$HELP && ( [ "${STRATEGY_OPTION}" == "" ] || [ "${STRATEGY_OPTION}" == "native" ] ) && help_gemm_config_file_native
SiCong Li8b4c7302019-09-19 12:18:15 +0100232$HELP && ( [ "${STRATEGY_OPTION}" == "" ] || [ "${STRATEGY_OPTION}" == "reshaped_rhs_only" ] ) && help_gemm_config_file_reshaped_rhs_only
SiCong Libc166d52019-09-26 14:58:53 +0100233$HELP && ( [ "${STRATEGY_OPTION}" == "" ] || [ "${STRATEGY_OPTION}" == "reshaped" ] ) && help_gemm_config_file_reshaped
SiCong Li8b4c7302019-09-19 12:18:15 +0100234exit 1
235}
236
237#######################################
238# Print error message and exit with Error.
239# Globals:
240# None
241# Arguments:
242# $1 - Error message
243# Returns:
244# None
245#######################################
246function error_msg() {
247 echo "Error: $1" 1>&2
248 exit 1
249}
250
251#######################################
252# Convert string to lower-case
253# Globals:
254# None
255# Arguments:
256# target - String
257# Returns:
258# (stdout) - String in lowercase
259#######################################
260function to_lower() {
261 local target=$1
262 echo "$target" | tr '[:upper:]' '[:lower:]'
263}
264
265#######################################
266# Test if the argument is an integer
267# Globals:
268# None
269# Arguments:
270# in - Input
271# Returns:
272# true/false
273#######################################
274function is_integer() {
275 local in=$1
276 [ "$in" -eq "$in" ] 2> /dev/null
277}
278
279#######################################
SiCong Libc166d52019-09-26 14:58:53 +0100280# Test if a string is in an array of strings
281# Globals:
282# None
283# Arguments:
284# target - String to test
285# array - Array of strings to search
286# Returns:
287# true/false
288#######################################
289function arr_contains() {
290 local target=$1
291 shift
292 local array
293 array=("$@")
294 for s in "${array[@]}"
295 do
296 [ "$s" == "${target}" ] && return
297 done
298 false
299}
300
301#######################################
SiCong Lie36b5262019-10-01 19:26:00 +0100302# Run a single example with all tunable gemm configurations on all gemm parameters
SiCong Li8b4c7302019-09-19 12:18:15 +0100303# Globals:
304# OUT_DIR
SiCong Lie36b5262019-10-01 19:26:00 +0100305# OUT_EXTENSION
SiCong Li8b4c7302019-09-19 12:18:15 +0100306# EXAMPLE_BIN_DIR
307# NUM_ITERATION
308# GEMM_CONFIGS_FILE
309# GEMM_SHAPES_FILE
310# Arguments:
311# example_bin Name of the example binary to run
312# Returns:
313# None
314#######################################
315function run() {
316 local example_bin=$1
317 echo "Running all configs for ${example_bin}" 1>&2
318 local example_args
SiCong Lie36b5262019-10-01 19:26:00 +0100319 local expr_count=1
320 # Total number of experiment runs scheduled for this session
321 local total_num_experiment
322 local num_params
323 local num_configs
324 num_params=$( wc -l ${GEMM_SHAPES_FILE} | cut -d " " -f 1)
325 num_configs=$( wc -l ${GEMM_CONFIGS_FILE} | cut -d " " -f 1 )
326 (( total_num_experiment=${num_params} * ${num_configs} ))
327 # Time elapsed since the beginning in seconds
328 local time_elapsed_s
329 # Time estimated to finish in seconds
330 local time_est_s
331 echo "Running a total number of ${total_num_experiment} experiments" 1>&2
332
SiCong Li8b4c7302019-09-19 12:18:15 +0100333 while read gemm_shape
334 do
335 while read gemm_config
336 do
SiCong Lie36b5262019-10-01 19:26:00 +0100337 echo "Running..." 1>&2
SiCong Li8b4c7302019-09-19 12:18:15 +0100338 example_args="${gemm_shape},${gemm_config}"
SiCong Lie36b5262019-10-01 19:26:00 +0100339 # Run experiment
340 ${EXAMPLE_BIN_DIR}/${example_bin} --example_args=${example_args} --iterations=${NUM_ITERATION} --json-file=${OUT_DIR}/${expr_count}.${OUT_EXTENSION} --instruments=OPENCL_TIMER_MS
341 # Print progress
342 print_progress ${expr_count} ${total_num_experiment}
343 # Print time statistics
344 time_elapsed_s=$SECONDS
345 echo "Time elapsed since beginning: $(( $time_elapsed_s / 60 ))m $(( $time_elapsed_s % 60 ))s" 1>&2
346 (( time_est_s=(${total_num_experiment} - ${expr_count}) * ${time_elapsed_s} / ${expr_count} ))
347 echo "Time estimated to finish: $(( $time_est_s / 60 ))m $(( $time_est_s % 60 ))s" 1>&2
348 (( expr_count++ ))
349 echo "Done." 1>&2
SiCong Li8b4c7302019-09-19 12:18:15 +0100350 done < "${GEMM_CONFIGS_FILE}"
351 done < "${GEMM_SHAPES_FILE}"
352 echo "Finished running all configs for ${example_bin}" 1>&2
353 echo "All results saved to ${OUT_DIR}" 1>&2
354}
355
SiCong Lie36b5262019-10-01 19:26:00 +0100356#######################################
357# Print the progress of the current session
358# Globals:
359# None
360# Arguments:
361# current Current number of items
362# total Total number of items
363# Returns:
364# None
365#######################################
366function print_progress() {
367 local current
368 local total
369 current=$1
370 total=$2
371 # Width of progress bar
372 local width
373 width=20
374 (( current_width= $width * current / total ))
375 echo -n -e "Progress [" 1>&2
376 for i in $(seq 1 ${width}); do
377 if [[ $i -le ${current_width} ]]; then
378 echo -n "#" 1>&2
379 else
380 echo -n " " 1>&2
381 fi
382 done
383 echo "] $current / $total Experiments" 1>&2
384}
385
SiCong Li8b4c7302019-09-19 12:18:15 +0100386# Functions }}}
387
388# Main: Main script {{{
389# Path to directory containing all benchmark examples binaries
390EXAMPLE_BIN_DIR=""
391# Path to gemm shapes file
392GEMM_SHAPES_FILE=""
393# Path to gemm configs file
394GEMM_CONFIGS_FILE=""
SiCong Libc166d52019-09-26 14:58:53 +0100395STRATEGY_OPTION=""
SiCong Li8b4c7302019-09-19 12:18:15 +0100396# Path to output directory
397OUT_DIR=${DEFAULT_OUT_DIR}
SiCong Lie36b5262019-10-01 19:26:00 +0100398# Output benchmark result file extension
399OUT_EXTENSION="gemmtuner_benchmark"
SiCong Li8b4c7302019-09-19 12:18:15 +0100400# Toggle help
401HELP=false
402
403# Obtain options
SiCong Libc166d52019-09-26 14:58:53 +0100404while getopts "hs:e:g:c:o:" opt; do
SiCong Li8b4c7302019-09-19 12:18:15 +0100405 case "$opt" in
SiCong Libc166d52019-09-26 14:58:53 +0100406 h) HELP=true ;;
SiCong Li8b4c7302019-09-19 12:18:15 +0100407 s) STRATEGY_OPTION=$(to_lower "${OPTARG}");;
SiCong Libc166d52019-09-26 14:58:53 +0100408 e) EXAMPLE_BIN_DIR="${OPTARG}";;
SiCong Li8b4c7302019-09-19 12:18:15 +0100409 g) GEMM_SHAPES_FILE="${OPTARG}";;
410 c) GEMM_CONFIGS_FILE="${OPTARG}";;
411 o) OUT_DIR="${OPTARG}";;
412 esac
413done
414shift $((OPTIND - 1))
415
416# Lazily print usage (after arguments have been parsed)
417$HELP &&
418 usage
419
420# Parse and validate options
SiCong Libc166d52019-09-26 14:58:53 +0100421# Verify all compulsory arguments are passed in
422( [ ! -z "${STRATEGY_OPTION}" ] && [ ! -z "${EXAMPLE_BIN_DIR}" ] && [ ! -z "${GEMM_SHAPES_FILE}" ] && [ ! -z "${GEMM_CONFIGS_FILE}" ] ) ||
SiCong Li8b4c7302019-09-19 12:18:15 +0100423 usage
424
425# Verify example binaries directory exists
426[ -d "${EXAMPLE_BIN_DIR}" ] ||
427 error_msg "${EXAMPLE_BIN_DIR} does not exist."
428
429# Verify all benchmark example binaries exist
430[ -f "${EXAMPLE_BIN_DIR}/${EXAMPLE_BIN_RESHAPED_RHS_ONLY}" ] ||
431 error_msg "Cannot find ${EXAMPLE_BIN_RESHAPED_RHS_ONLY} at ${EXAMPLE_BIN_DIR}"
432
433# Verify Gemm shapes file exists
434[ -f "${GEMM_SHAPES_FILE}" ] ||
435 error_msg "Cannot find gemm shapes file ${GEMM_SHAPES_FILE}"
436
SiCong Libc166d52019-09-26 14:58:53 +0100437# Verify Gemm configs file exists
SiCong Li8b4c7302019-09-19 12:18:15 +0100438[ -f "${GEMM_CONFIGS_FILE}" ] ||
439 error_msg "Cannot find gemm configs file ${GEMM_CONFIGS_FILE}"
440
441# Verify strategy option is valid
SiCong Libc166d52019-09-26 14:58:53 +0100442arr_contains "${STRATEGY_OPTION}" "${ALL_STRATEGY_OPTIONS[@]}" ||
SiCong Li8b4c7302019-09-19 12:18:15 +0100443 error_msg "Does not support strategy ${STRATEGY_OPTION}"
444
445# Make sure existing benchmark outputs are not overwritten
446[ ! -d "${OUT_DIR}" ] ||
447 error_msg "Output directory ${OUT_DIR} already exists!"
448
449# Make output directory
450mkdir ${OUT_DIR}
451
452# Run selected strategy with all configurations
SiCong Lie36b5262019-10-01 19:26:00 +0100453# Restart the built-in timer
454SECONDS=0
SiCong Liea803482019-09-26 16:55:49 +0100455[ "${STRATEGY_OPTION}" == "native" ] && run $EXAMPLE_BIN_NATIVE
SiCong Li8b4c7302019-09-19 12:18:15 +0100456[ "${STRATEGY_OPTION}" == "reshaped_rhs_only" ] && run $EXAMPLE_BIN_RESHAPED_RHS_ONLY
SiCong Libc166d52019-09-26 14:58:53 +0100457[ "${STRATEGY_OPTION}" == "reshaped" ] && run $EXAMPLE_BIN_RESHAPED
SiCong Li8b4c7302019-09-19 12:18:15 +0100458# Main: Main script }}}