• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright 2019 The TensorFlow Authors. All Rights Reserved.
2 
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6 
7     http://www.apache.org/licenses/LICENSE-2.0
8 
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15 
16 package org.tensorflow.lite.nnapi;
17 
18 import org.tensorflow.lite.Delegate;
19 import org.tensorflow.lite.InterpreterFactoryApi;
20 import org.tensorflow.lite.TensorFlowLite;
21 
22 /** {@link Delegate} for NNAPI inference. */
23 public class NnApiDelegate implements Delegate, AutoCloseable {
24   /**
25    * Interface used for implementing NnApiDelegate. This is for use only by packages in
26    * org.tensorflow.lite.
27    *
28    * @hide
29    */
30   public static interface PrivateInterface extends Delegate, AutoCloseable {
31     /** See NnApiDelegate#getNnApiErrno. */
getNnapiErrno()32     public int getNnapiErrno();
33 
34     @Override
close()35     public void close();
36   }
37 
38   /** Delegate options. */
39   public static final class Options {
Options()40     public Options() {}
41 
42     /**
43      * undefined, specifies default behavior. so far, the default setting of NNAPI is
44      * EXECUTION_PREFERENCE_FAST_SINGLE_ANSWER
45      */
46     public static final int EXECUTION_PREFERENCE_UNDEFINED = -1;
47 
48     /**
49      * Prefer executing in a way that minimizes battery drain. This is desirable for compilations
50      * that will be executed often.
51      */
52     public static final int EXECUTION_PREFERENCE_LOW_POWER = 0;
53 
54     /**
55      * Prefer returning a single answer as fast as possible, even if this causes more power
56      * consumption.
57      */
58     public static final int EXECUTION_PREFERENCE_FAST_SINGLE_ANSWER = 1;
59 
60     /**
61      * Prefer maximizing the throughput of successive frames, for example when processing successive
62      * frames coming from the camera.
63      */
64     public static final int EXECUTION_PREFERENCE_SUSTAINED_SPEED = 2;
65 
66     /**
67      * Sets the inference preference for precision/compilation/runtime tradeoffs.
68      *
69      * @param preference One of EXECUTION_PREFERENCE_LOW_POWER,
70      *     EXECUTION_PREFERENCE_FAST_SINGLE_ANSWER, or EXECUTION_PREFERENCE_SUSTAINED_SPEED.
71      */
setExecutionPreference(int preference)72     public Options setExecutionPreference(int preference) {
73       this.executionPreference = preference;
74       return this;
75     }
76 
77     /**
78      * Specifies the name of the target accelerator to be used by NNAPI. If this parameter is
79      * specified the {@link #setUseNnapiCpu(boolean)} method won't have any effect.
80      *
81      * <p>Only effective on Android 10 (API level 29) and above.
82      */
setAcceleratorName(String name)83     public Options setAcceleratorName(String name) {
84       this.acceleratorName = name;
85       return this;
86     }
87 
88     /**
89      * Configure the location to be used to store model compilation cache entries. If either {@code
90      * cacheDir} or {@code modelToken} parameters are unset NNAPI caching will be disabled.
91      *
92      * <p>Only effective on Android 10 (API level 29) and above.
93      */
setCacheDir(String cacheDir)94     public Options setCacheDir(String cacheDir) {
95       this.cacheDir = cacheDir;
96       return this;
97     }
98 
99     /**
100      * Sets the token to be used to identify this model in the model compilation cache. If either
101      * {@code cacheDir} or {@code modelToken} parameters are unset NNAPI caching will be disabled.
102      *
103      * <p>Only effective on Android 10 (API level 29) and above.
104      */
setModelToken(String modelToken)105     public Options setModelToken(String modelToken) {
106       this.modelToken = modelToken;
107       return this;
108     }
109 
110     /**
111      * Sets the maximum number of graph partitions that the delegate will try to delegate. If more
112      * partitions could be delegated than the limit, the ones with the larger number of nodes will
113      * be chosen. If unset it will use the NNAPI default limit.
114      */
setMaxNumberOfDelegatedPartitions(int limit)115     public Options setMaxNumberOfDelegatedPartitions(int limit) {
116       this.maxDelegatedPartitions = limit;
117       return this;
118     }
119 
120     /**
121      * Enable or disable the NNAPI CPU Device "nnapi-reference". If unset it will use the NNAPI
122      * default settings.
123      *
124      * <p>Only effective on Android 10 (API level 29) and above.
125      */
setUseNnapiCpu(boolean enable)126     public Options setUseNnapiCpu(boolean enable) {
127       this.useNnapiCpu = enable;
128       return this;
129     }
130 
131     /**
132      * Enable or disable to allow fp32 computation to be run in fp16 in NNAPI. See
133      * https://source.android.com/devices/neural-networks#android-9
134      *
135      * <p>Only effective on Android 9 (API level 28) and above.
136      */
setAllowFp16(boolean enable)137     public Options setAllowFp16(boolean enable) {
138       this.allowFp16 = enable;
139       return this;
140     }
141 
setNnApiSupportLibraryHandle(long handle)142     public Options setNnApiSupportLibraryHandle(long handle) {
143       this.nnApiSupportLibraryHandle = handle;
144       return this;
145     }
146 
147     /**
148      * Returns the inference preference for precision/compilation/runtime tradeoffs.
149      *
150      * @return One of EXECUTION_PREFERENCE_LOW_POWER, EXECUTION_PREFERENCE_FAST_SINGLE_ANSWER, or
151      *     EXECUTION_PREFERENCE_SUSTAINED_SPEED.
152      */
getExecutionPreference()153     public int getExecutionPreference() {
154       return this.executionPreference;
155     }
156 
157     /** Returns the name of the target accelerator to be used by NNAPI. */
getAcceleratorName()158     public String getAcceleratorName() {
159       return this.acceleratorName;
160     }
161 
162     /** Returns the location to be used to store model compilation cache entries. */
getCacheDir()163     public String getCacheDir() {
164       return this.cacheDir;
165     }
166 
167     /** Returns the token to be used to identify this model in the model compilation cache. */
getModelToken()168     public String getModelToken() {
169       return this.modelToken;
170     }
171 
172     /**
173      * Returns the maximum number of graph partitions that the delegate will try to delegate. Or -1
174      * if no maximum has neen set.
175      */
getMaxNumberOfDelegatedPartitions()176     public int getMaxNumberOfDelegatedPartitions() {
177       return this.maxDelegatedPartitions == null ? -1 : this.maxDelegatedPartitions;
178     }
179 
180     /**
181      * Returns whether the NNAPI CPU Device "nnapi-reference" is enabled.
182      *
183      * @return true if the NNAPI CPU Device "nnapi-reference" is explicitly enabled.
184      * @return false if the NNAPI CPU Device "nnapi-reference" is explicitly disabled.
185      * @return null if use of the NNAPI CPU Device "nnapi-reference" will be determined by the NNAPI
186      *     default settings.
187      */
getUseNnapiCpu()188     public Boolean getUseNnapiCpu() {
189       return this.useNnapiCpu;
190     }
191 
192     /** Returns true if allowing fp32 computation to be run in fp16 in NNAPI is enabled. */
getAllowFp16()193     public boolean getAllowFp16() {
194       return this.allowFp16 != null && this.allowFp16;
195     }
196 
197     /** Returns the native handle to the NNAPI Support Library. */
getNnApiSupportLibraryHandle()198     public long getNnApiSupportLibraryHandle() {
199       return this.nnApiSupportLibraryHandle;
200     }
201 
202     private int executionPreference = EXECUTION_PREFERENCE_UNDEFINED;
203     private String acceleratorName = null;
204     private String cacheDir = null;
205     private String modelToken = null;
206     private Integer maxDelegatedPartitions = null;
207     private Boolean useNnapiCpu = null;
208     private Boolean allowFp16 = null;
209     private long nnApiSupportLibraryHandle = 0;
210   }
211 
212   private Options options;
213   private PrivateInterface impl;
214   private boolean initialized;
215 
NnApiDelegate(Options options)216   public NnApiDelegate(Options options) {
217     // Ensure the native TensorFlow Lite libraries are available.
218     TensorFlowLite.init();
219     this.options = options;
220     // this.impl will be initialized later.
221   }
222 
NnApiDelegate()223   public NnApiDelegate() {
224     this(new Options());
225   }
226 
227   /**
228    * Called when an interpreter is constructed with this delegate. This method is only for use by TF
229    * Lite itself, and should not be used by application developers.
230    *
231    * @hide
232    */
initWithInterpreterFactoryApi(InterpreterFactoryApi interpreterFactoryApi)233   public void initWithInterpreterFactoryApi(InterpreterFactoryApi interpreterFactoryApi) {
234     impl = interpreterFactoryApi.createNnApiDelegateImpl(options);
235     initialized = true;
236   }
237 
238   @Override
getNativeHandle()239   public long getNativeHandle() {
240     checkNotClosed();
241     return impl.getNativeHandle();
242   }
243 
244   /**
245    * Frees TFLite resources in C runtime.
246    *
247    * <p>User is expected to call this method explicitly.
248    */
249   @Override
close()250   public void close() {
251     if (impl != null) {
252       impl.close();
253       impl = null;
254     }
255   }
256 
257   /**
258    * Returns the latest error code returned by an NNAPI call or zero if NO calls to NNAPI failed.
259    * The error code is reset when the delegate is associated with an <a
260    * href=https://www.tensorflow.org/lite/api_docs/java/org/tensorflow/lite/Interpreter>interpreter</a>.
261    *
262    * <p>For details on NNAPI error codes see <a
263    * href="https://developer.android.com/ndk/reference/group/neural-networks#resultcode">the NNAPI
264    * documentation</a>.
265    *
266    * @throws IllegalStateException if the method is called after {@link #close() close}.
267    */
getNnapiErrno()268   public int getNnapiErrno() {
269     if (!initialized) {
270       return 0 /*ANEURALNETWORKS_NO_ERROR*/;
271     }
272     checkNotClosed();
273     return impl.getNnapiErrno();
274   }
275 
276   /**
277    * Returns true if any NNAPI call failed since this delegate was associated with an <a
278    * href=https://www.tensorflow.org/lite/api_docs/java/org/tensorflow/lite/Interpreter>interpreter</a>.
279    *
280    * @throws IllegalStateException if the method is called after {@link #close() close}.
281    */
hasErrors()282   public boolean hasErrors() {
283     return getNnapiErrno() != 0 /*ANEURALNETWORKS_NO_ERROR*/;
284   }
285 
checkNotClosed()286   private void checkNotClosed() {
287     if (impl == null) {
288       throw new IllegalStateException(
289           initialized
290               ? "Should not access delegate after delegate has been closed."
291               : "Should not access delegate before interpreter has been constructed.");
292     }
293   }
294 }
295