1 /*
2  * Copyright (C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.nn.benchmark.app;
18 
19 import android.annotation.SuppressLint;
20 import android.app.Activity;
21 import android.content.Intent;
22 import android.os.Bundle;
23 import android.util.Log;
24 import android.view.WindowManager;
25 import android.widget.TextView;
26 import com.android.nn.benchmark.core.BenchmarkException;
27 import com.android.nn.benchmark.core.BenchmarkResult;
28 import com.android.nn.benchmark.core.Processor;
29 import com.android.nn.benchmark.core.TestModels.TestModelEntry;
30 import java.io.IOException;
31 import java.time.Duration;
32 import java.util.concurrent.ExecutorService;
33 import java.util.concurrent.Executors;
34 
35 public class NNBenchmark extends Activity implements Processor.Callback {
36     public static final String TAG = "NN_BENCHMARK";
37 
38     public static final String EXTRA_ENABLE_LONG = "enable long";
39     public static final String EXTRA_ENABLE_PAUSE = "enable pause";
40     public static final String EXTRA_DISABLE_NNAPI = "disable NNAPI";
41     public static final String EXTRA_TESTS = "tests";
42 
43     public static final String EXTRA_RESULTS_TESTS = "tests";
44     public static final String EXTRA_RESULTS_RESULTS = "results";
45     public static final long PROCESSOR_TERMINATION_TIMEOUT_MS = Duration.ofSeconds(20).toMillis();
46     public static final String EXTRA_MAX_ITERATIONS = "max_iterations";
47 
48     private int mTestList[];
49 
50     private Processor mProcessor;
51     private final ExecutorService executorService = Executors.newSingleThreadExecutor();
52 
53     private TextView mTextView;
54 
55     // Initialize the parameters for Instrumentation tests.
prepareInstrumentationTest()56     protected void prepareInstrumentationTest() {
57         mTestList = new int[1];
58         mProcessor = new Processor(this, this, mTestList);
59     }
60 
setUseNNApi(boolean useNNApi)61     public void setUseNNApi(boolean useNNApi) {
62         mProcessor.setUseNNApi(useNNApi);
63     }
64 
setCompleteInputSet(boolean completeInputSet)65     public void setCompleteInputSet(boolean completeInputSet) {
66         mProcessor.setCompleteInputSet(completeInputSet);
67     }
68 
enableCompilationCachingBenchmarks( float warmupTimeSeconds, float runTimeSeconds, int maxIterations)69     public void enableCompilationCachingBenchmarks(
70             float warmupTimeSeconds, float runTimeSeconds, int maxIterations) {
71         mProcessor.enableCompilationCachingBenchmarks(
72                 warmupTimeSeconds, runTimeSeconds, maxIterations);
73     }
74 
75     @SuppressLint("SetTextI18n")
76     @Override
onCreate(Bundle savedInstanceState)77     protected void onCreate(Bundle savedInstanceState) {
78         super.onCreate(savedInstanceState);
79         mTextView = new TextView(this);
80         mTextView.setTextSize(20);
81         mTextView.setText("Running NN benchmark...");
82         setContentView(mTextView);
83         getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
84     }
85 
86     @Override
onPause()87     protected void onPause() {
88         super.onPause();
89         if (mProcessor != null) {
90             mProcessor.exitWithTimeout(PROCESSOR_TERMINATION_TIMEOUT_MS);
91             mProcessor = null;
92         }
93     }
94 
onBenchmarkFinish(boolean ok)95     public void onBenchmarkFinish(boolean ok) {
96         if (ok) {
97             Intent intent = new Intent();
98             intent.putExtra(EXTRA_RESULTS_TESTS, mTestList);
99             intent.putExtra(EXTRA_RESULTS_RESULTS, mProcessor.getTestResults());
100             setResult(RESULT_OK, intent);
101         } else {
102             setResult(RESULT_CANCELED);
103         }
104         finish();
105     }
106 
107     @SuppressLint("DefaultLocale")
onStatusUpdate(int testNumber, int numTests, String modelName)108     public void onStatusUpdate(int testNumber, int numTests, String modelName) {
109         runOnUiThread(
110                 () -> {
111                     mTextView.setText(
112                             String.format(
113                                     "Running test %d of %d: %s", testNumber, numTests, modelName));
114                 });
115     }
116 
117     @Override
onResume()118     protected void onResume() {
119         super.onResume();
120         Intent i = getIntent();
121         mTestList = i.getIntArrayExtra(EXTRA_TESTS);
122         if (mTestList != null && mTestList.length > 0) {
123             Log.v(TAG, String.format("Starting benchmark with %d test", mTestList.length));
124             mProcessor = new Processor(this, this, mTestList);
125             mProcessor.setToggleLong(i.getBooleanExtra(EXTRA_ENABLE_LONG, false));
126             mProcessor.setTogglePause(i.getBooleanExtra(EXTRA_ENABLE_PAUSE, false));
127             mProcessor.setUseNNApi(!i.getBooleanExtra(EXTRA_DISABLE_NNAPI, false));
128             mProcessor.setMaxRunIterations(i.getIntExtra(EXTRA_MAX_ITERATIONS, 0));
129             executorService.submit(mProcessor);
130         } else {
131             Log.v(TAG, "No test to run, doing nothing");
132         }
133     }
134 
135     @Override
onDestroy()136     protected void onDestroy() {
137         super.onDestroy();
138     }
139 
runSynchronously(TestModelEntry testModel, float warmupTimeSeconds, float runTimeSeconds)140     public BenchmarkResult runSynchronously(TestModelEntry testModel,
141         float warmupTimeSeconds, float runTimeSeconds) throws IOException, BenchmarkException {
142         return mProcessor.getInstrumentationResult(testModel, warmupTimeSeconds, runTimeSeconds);
143     }
144 }
145