test_op_benchmark.sh 7.5 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
#!/bin/bash

# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
#     http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

set +ex

[ -z "$PADDLE_ROOT" ] && PADDLE_ROOT=$(cd $(dirname ${BASH_SOURCE[0]})/.. && pwd)

21 22
# PR modify op source files
CHANGE_OP_FILES=()
23 24 25 26 27 28 29 30 31 32 33

# ops that will run benchmark test
declare -A CHANGE_OP_MAP

# ops that benchmark repo has
declare -A BENCHMARK_OP_MAP

function LOG {
  echo "[$0:${BASH_LINENO[0]}] $*" >&2
}

34 35 36 37 38 39 40 41 42 43 44
# Limit cu file directory
function match_cu_file_directory {
  local sub_dir cu_file_dir
  cu_file_dir=$(dirname ${1})
  for sub_dir in "" "/elementwise" "/reduce_ops"
  do
    [ "${cu_file_dir}" == "paddle/fluid/operators${sub_dir}" ] && return 0
  done
  return 1
}

45 46 47 48 49 50 51
# Load op files by header file
function load_CHANGE_OP_FILES_by_header_file {
  local change_file
  for change_file in $(grep -rl "${1}" paddle/fluid/operators)
  do
    if [[ "$change_file" =~ "_op.cu" ]]
    then
52 53
      # match cu file directory limit
      match_cu_file_directory $change_file || continue
54 55 56 57 58 59 60 61 62 63 64 65
      LOG "[INFO] Found \"${1}\" include by \"${change_file}\"."
      CHANGE_OP_FILES[${#CHANGE_OP_FILES[@]}]="$change_file"
    elif [[ "$change_file" =~ ".h" ]]
    then
      LOG "[INFO] Found \"${1}\" include by \"${change_file}\", keep searching."
      load_CHANGE_OP_FILES_by_header_file $change_file
    fi
  done
}

# Load op files that PR changes
function load_CHANGE_OP_FILES {
66
  local sub_dir change_file
67 68
  # TODO(Avin0323): Need to filter the files added by the new OP.
  for change_file in $(git diff --name-only origin/develop)
69 70 71
  do
    # match directory limit
    [[ "$change_file" =~ "paddle/fluid/operators/" ]] || continue
72
    # match file name limit
73
    if [[ "$change_file" =~ "_op.cu" ]]
74
    then
75 76
      # match cu file directory limit
      match_cu_file_directory $change_file || continue
77 78 79 80 81 82
      LOG "[INFO] Found \"${change_file}\" changed."
      CHANGE_OP_FILES[${#CHANGE_OP_FILES[@]}]="$change_file"
    elif [[ "$change_file" =~ ".h" ]]
    then
      LOG "[INFO] Found \"${change_file}\" changed, keep searching."
      load_CHANGE_OP_FILES_by_header_file $change_file
83 84
    fi
  done
85
  [ ${#CHANGE_OP_FILES[@]} -eq 0 ] && LOG "[INFO] No op to test, skip this ci." && exit 0
86 87 88 89 90 91 92 93 94 95 96 97
}

# Clone benchmark repo
function prepare_benchmark_environment {
  LOG "[INFO] Clone benchmark repo ..."
  git clone https://github.com/PaddlePaddle/benchmark.git
  [ $? -ne 0 ] && LOG "[FATAL] Clone benchmark repo fail." && exit -1
  LOG "[INFO] Collect api info ..."
  python benchmark/api/deploy/collect_api_info.py \
      --test_module_name tests_v2                 \
      --info_file api_info.txt >& 2
  [ $? -ne 0 ] && LOG "[FATAL] Collect api info fail." && exit -1
98
  [ ! -f benchmark/ci/scripts/op_benchmark.config ] && LOG "[FATAL] Missing op_benchmark.config!" && exit -1
99 100
}

101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
# Load unique op name from CHANGE_OP_FILES
function load_CHANGE_OP_MAP {
  local op_name change_file change_file_name
  source benchmark/ci/scripts/op_benchmark.config
  for change_file in ${CHANGE_OP_FILES[@]}
  do
    change_file_name=${change_file#*paddle/fluid/operators/}
    if [ -n "${PADDLE_FILENAME_OP_MAP[$change_file_name]}" ]
    then
      for op_name in ${PADDLE_FILENAME_OP_MAP[$change_file_name]}
      do
        LOG "[INFO] Load op: \"${op_name}\"."
        CHANGE_OP_MAP[${op_name}]="$change_file"
      done
    else
116 117 118 119 120 121
      op_name=${change_file_name##*/}
      op_name=${op_name%_cudnn_op*}
      op_name=${op_name%_op*}
      [ -n "${SKIP_OP_MAP[$op_name]}" ] && continue
      LOG "[INFO] Load op: \"${op_name}\"."
      CHANGE_OP_MAP[${op_name}]="$change_file"
122 123 124 125 126
    fi
  done
}

# Load ops that will run benchmark test
127 128
function load_BENCHMARK_OP_MAP {
  local line op_name api_name
129
  source benchmark/ci/scripts/op_benchmark.config
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148
  for line in $(cat api_info.txt)
  do
    api_name=${line%%,*}
    if [ -n "${BENCHMARK_APINAME_OP_MAP[$api_name]}" ]
    then
      op_name=${BENCHMARK_APINAME_OP_MAP[$api_name]}
    else
      op_name=$api_name
    fi
    if [ -n "${CHANGE_OP_MAP[$op_name]}" ]
    then
      LOG "[INFO] Load benchmark settings with op \"${op_name}\"."
      BENCHMARK_OP_MAP[$op_name]=$line
    fi
  done
}

# compile and install paddlepaddle
function compile_install_paddlepaddle {
149
  LOG "[INFO] Compiling install package ..."
150 151 152 153 154 155 156
  export WITH_GPU=ON
  export WITH_AVX=ON
  export WITH_MKL=ON
  export RUN_TEST=OFF
  export WITH_PYTHON=ON
  export WITH_TESTING=OFF
  export BUILD_TYPE=Release
157
  export CUDA_ARCH_NAME=Auto
158 159 160 161
  export WITH_DISTRIBUTE=OFF
  export PYTHON_ABI=cp37-cp37m
  export CMAKE_BUILD_TYPE=Release
  [ -d build ] && rm -rf build
162
  bash paddle/scripts/paddle_build.sh build $(nproc)
163
  [ $? -ne 0 ] && LOG "[FATAL] compile fail." && exit 7
164
  LOG "[INFO] Uninstall Paddle ..."
165
  pip uninstall -y paddlepaddle paddlepaddle_gpu
166
  LOG "[INFO] Install Paddle ..."
167 168 169 170 171
  pip install build/python/dist/paddlepaddle_gpu-0.0.0-cp37-cp37m-linux_x86_64.whl
}

# run op benchmark test
function run_op_benchmark_test {
172
  [ ${#BENCHMARK_OP_MAP[*]} -eq 0 ] && return
173
  local logs_dir op_name branch_name api_info_file
174 175
  [ -z "$VISIBLE_DEVICES" ] && export VISIBLE_DEVICES=0
  [ "$BENCHMARK_PRINT_FAIL_LOG" != "1" ] && export BENCHMARK_PRINT_FAIL_LOG=1
176 177 178 179 180 181
  api_info_file="$(pwd)/api_info.txt"
  [ -f "$api_info_file" ] && rm -f $api_info_file
  for api_info in ${BENCHMARK_OP_MAP[*]}
  do
    echo "$api_info" >> $api_info_file
  done
182 183
  # install tensorflow for testing accuary
  pip install tensorflow==2.3.0 tensorflow-probability
184 185 186
  for branch_name in "develop" "test_pr"
  do
    git checkout $branch_name
187
    [ $? -ne 0 ] && LOG "[FATAL] Missing branch ${branch_name}." && exit 7
188 189 190 191 192 193 194 195 196 197
    LOG "[INFO] Now branch name is ${branch_name}."
    compile_install_paddlepaddle
    logs_dir="$(pwd)/logs-${branch_name}"
    [ -d $logs_dir ] && rm -rf $logs_dir/* || mkdir -p $logs_dir
    pushd benchmark/api > /dev/null
    bash deploy/main_control.sh tests_v2 \
                                tests_v2/configs \
                                $logs_dir \
                                $VISIBLE_DEVICES \
                                "gpu" \
198
                                "both" \
199 200 201 202 203 204 205 206
                                $api_info_file \
                                "paddle"
    popd > /dev/null
  done
}

# diff benchmakr result and miss op
function summary_problems {
207
  local op_name exit_code
208 209 210 211 212 213 214 215
  exit_code=0
  if [ ${#BENCHMARK_OP_MAP[*]} -ne 0 ]
  then
    python ${PADDLE_ROOT}/tools/check_op_benchmark_result.py \
        --develop_logs_dir $(pwd)/logs-develop \
        --pr_logs_dir $(pwd)/logs-test_pr
    exit_code=$?
  fi
216 217 218 219
  for op_name in ${!CHANGE_OP_MAP[@]}
  do
    if [ -z "${BENCHMARK_OP_MAP[$op_name]}" ]
    then
220
      exit_code=8
221
      LOG "[WARNING] Missing test script of \"${op_name}\"(${CHANGE_OP_MAP[$op_name]}) in benchmark."
222 223
    fi
  done
224
  [ $exit_code -ne 0 ] && exit $exit_code
225 226 227 228
}

function main {
  LOG "[INFO] Start run op benchmark test ..."
229 230
  load_CHANGE_OP_FILES
  prepare_benchmark_environment
231 232 233 234 235 236 237 238 239
  load_CHANGE_OP_MAP
  load_BENCHMARK_OP_MAP
  run_op_benchmark_test
  summary_problems
  LOG "[INFO] Op benchmark run success and no error!"
  exit 0
}

main