1#!/bin/bash
2
3#
4# Copyright (C) 2017 The Android Open Source Project
5#
6# Licensed under the Apache License, Version 2.0 (the "License");
7# you may not use this file except in compliance with the License.
8# You may obtain a copy of the License at
9#
10#      http://www.apache.org/licenses/LICENSE-2.0
11#
12# Unless required by applicable law or agreed to in writing, software
13# distributed under the License is distributed on an "AS IS" BASIS,
14# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15# See the License for the specific language governing permissions and
16# limitations under the License.
17
18set -Eeuo pipefail
19
20NNAPI_VERSION="
21V1_0
22V1_1
23V1_2
24"
25
26# Process one test spec, and optionally provide the log file argument
27# for the slicing tool. The first argument is the test spec file; the
28# second optional argument specifies the log file this test should dump
29# results into. Only used by the test slicing tool to collect reference
30# outputs from the CPU. Also, it outputs the right #includes in the
31# test harness so the test would be invoked by TestGenerated.cpp
32#
33# This function shouldn't be directly called from other scripts. Use
34# generate_wrapper below for generating models and examples and updating the
35# test framework in one shot.
36
37export NNAPI_BASE=$ANDROID_BUILD_TOP/frameworks/ml/nn
38: ${TEST_DIR:=frameworks/ml/nn/runtime/test}
39: ${FORCE:=""}
40
41function generate_one_testcase {
42  # Generate one testcase
43  local LOGFILE=$2
44  if [ -n "$2" ]; then
45    local LOGFILE="-l $2"
46  fi
47  local BASENAME=`basename -s .mod.py $1`
48  local MODEL="-m $ANDROID_BUILD_TOP/$TEST_DIR/generated/models/$BASENAME.model.cpp"
49  local EXAMPLE="-e $ANDROID_BUILD_TOP/$TEST_DIR/generated/examples/$BASENAME.example.cpp"
50  local TEST="-t $ANDROID_BUILD_TOP/$TEST_DIR/generated/tests/$(basename $1).cpp"
51
52  $NNAPI_BASE/tools/test_generator/cts_generator.py $FORCE ./`basename $1` \
53    $MODEL $EXAMPLE $TEST $LOGFILE
54  ret=$?
55  return $ret
56}
57
58# Driver for generate_one_testcase. Append the output of generate_one_testcase
59# (which are C++ snippets that invokes the test harness) to the
60# all_generated_tests.cpp
61# Optionally, the "LOG" file ($2), only used by the slicing tool, would be
62# passed to generate_one_testcase.
63#
64# This function should be called to process one test spec from other scripts.
65function generate_wrapper {
66  local LOGFILE=""
67  if [ $1 = "log" ]; then
68    local LOGFILE=$2
69    shift
70    shift
71  fi
72  cd $ANDROID_BUILD_TOP/$TEST_DIR/specs
73  FOUND=0
74
75  CTSONEFILE=$ANDROID_BUILD_TOP/$TEST_DIR/for-cts/TestGeneratedOneFile.cpp
76  echo "// clang-format off" > $CTSONEFILE
77  echo "// DO NOT EDIT;" >> $CTSONEFILE
78  echo "// Generated by ml/nn/runtime/test/specs/generate_test.sh" >> $CTSONEFILE
79  echo "#include \"../GeneratedUtils.cpp\"" >> $CTSONEFILE
80
81  for ver in $NNAPI_VERSION;
82  do
83    VER_DIR=$ANDROID_BUILD_TOP/$TEST_DIR/specs/$ver
84    [ ! -d $VER_DIR ] && continue
85    pushd $VER_DIR > /dev/null
86    for f in $@;
87    do
88      if [ -f $(basename $f) ]; then
89        generate_one_testcase $f "$LOGFILE" >> $CTSONEFILE
90        if [ $? -ne 0 ]; then
91          echo "Failed processing $f"
92          return $?
93        fi
94        FOUND=1
95      fi
96    done
97    popd > /dev/null
98  done
99  if [[ $FOUND -eq 0 ]]; then
100    echo did not find any files for $@
101    exit 1
102  fi
103  return $?
104}
105
106# Process all test spec directory specified by NNAPI_VERSION.
107function generate_spec_dirs {
108  cd $ANDROID_BUILD_TOP/$TEST_DIR/specs
109
110  CTSONEFILE=$ANDROID_BUILD_TOP/$TEST_DIR/for-cts/TestGeneratedOneFile.cpp
111  echo "// clang-format off" > $CTSONEFILE
112  echo "// DO NOT EDIT;" >> $CTSONEFILE
113  echo "// Generated by ml/nn/runtime/test/specs/generate_test.sh" >> $CTSONEFILE
114  echo "#include \"../GeneratedUtils.cpp\"" >> $CTSONEFILE
115
116  for ver in $NNAPI_VERSION;
117  do
118    VER_DIR=$ANDROID_BUILD_TOP/$TEST_DIR/specs/$ver
119    [ ! -d $VER_DIR ] && continue
120    pushd $VER_DIR > /dev/null
121
122    TARGET_MODEL_DIR="-m $ANDROID_BUILD_TOP/$TEST_DIR/generated/models"
123    TARGET_EXAMPLE_DIR="-e $ANDROID_BUILD_TOP/$TEST_DIR/generated/examples"
124    TARGET_TEST_DIR="-t $ANDROID_BUILD_TOP/$TEST_DIR/generated/tests"
125
126    $NNAPI_BASE/tools/test_generator/cts_generator.py $FORCE $VER_DIR \
127        $TARGET_MODEL_DIR $TARGET_EXAMPLE_DIR $TARGET_TEST_DIR >> $CTSONEFILE
128    if [ $? -ne 0 ]; then
129        echo "Failed processing $VER_DIR"
130        return $?
131    fi
132    popd > /dev/null
133  done
134  return $?
135}
136
137# Only run the following when not sourced by another script
138if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
139  set -eu
140  if [ $# -gt 0 ]; then
141    if  [ $1 = "-f" ] || [ $1 = "--force" ]; then
142      FORCE="-f"
143      shift
144    fi
145  fi
146  if [ $# -eq 0 ]; then
147    generate_spec_dirs $FORCE
148  else
149    FILES="$@"
150    generate_wrapper $FILES
151  fi
152  if [ $? -ne 0 ]; then
153    exit $?
154  fi
155fi # [[ "${BASH_SOURCE[0]}" == "${0}" ]]
156
157