NeuralNetworks.h revision 689d892203c06c66c7bb2e374462a8434e40b75f
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#ifndef ANDROID_ML_NN_RUNTIME_NEURAL_NETWORKS_H
18#define ANDROID_ML_NN_RUNTIME_NEURAL_NETWORKS_H
19
20// TODO Before submitting to NDK, fix all the TODOs in here.
21
22#if __ANDROID_API__ >= __ANDROID_API_O_MR1__
23
24// TODO These may be useful when we broaden the shared memory support
25//     but would be available only for system apps.
26//#include <android/hardware_buffer.h>
27//#include <hardware/gralloc.h>
28//#include <android/hidl/memory/1.0/IMemory.h>
29#include <stddef.h>
30#include <stdint.h>
31#include <sys/cdefs.h>
32
33__BEGIN_DECLS
34
35/**
36 * Operand types.
37 *
38 * The type of operands that can be added to a model.
39 *
40 * Although we define many types, most operators accept just a few
41 * types.  Most used are ANEURALNETWORKS_TENSOR_FLOAT32,
42 * ANEURALNETWORKS_TENSOR_QUANT8_ASYMM, and ANEURALNETWORKS_INT32.
43 */
44enum {
45    // The following entries are used to declare scalars.
46    ANEURALNETWORKS_FLOAT16 = 0,  // A 16 bit floating point scalar value.
47    ANEURALNETWORKS_FLOAT32 = 1,  // A 32 bit floating point scalar value.
48    ANEURALNETWORKS_INT8 = 2,     // A signed 8 bit integer scalar value.
49    ANEURALNETWORKS_UINT8 = 3,    // An unsigned 8 bit integer scalar value.
50    ANEURALNETWORKS_INT16 = 4,    // A signed 16 bit integer scalar value.
51    ANEURALNETWORKS_UINT16 = 5,   // An unsigned 16 bit integer scalar value.
52    ANEURALNETWORKS_INT32 = 6,    // A signed 32 bit integer scalar value.
53    ANEURALNETWORKS_UINT32 = 7,   // An unsigned 32 bit integer scalar value.
54
55    // The following entries are used to declare tensors.
56    ANEURALNETWORKS_TENSOR_FLOAT16 = 8,  // A tensor of 16 bit floating point values.
57    ANEURALNETWORKS_TENSOR_FLOAT32 = 9,  // A tensor of 32 bit floating point values.
58    ANEURALNETWORKS_TENSOR_INT32 = 10,   // A tensor of 32 bit integer values.
59    /* A tensor of 8 bit integers that represent real numbers.
60     *
61     * Attached to this tensor are two numbers that can be used to convert
62     * the 8 bit integer to the real value and vice versa.  These two numbers are:
63     * - scale: a 32 bit floating point value
64     * - zero_value: an 32 bit integer
65     *
66     * The formula is:
67     * real_value = (integer_value - zero_value) * scale.
68     */
69    ANEURALNETWORKS_TENSOR_QUANT8_ASYMM = 11,
70};
71
72/**
73 * Operation types.
74 *
75 * The type of operations that can be added to a model.
76 */
77enum {
78    /* OEM specific operation.
79     *
80     * This operation is OEM specific. It should only be used for OEM applications.
81     */
82    ANEURALNETWORKS_OEM_OPERATION = 0,
83    /* Adds two tensors.
84     *
85     * Takes two input tensors of identical dimensions. The output is the sum of both input tensors
86     * optionally modified by an activation function.
87     *
88     * TODO: Do we accept any number of dimensions? TENSOR_FLOAT16, TENSOR_FLOAT32, TENSOR_INT32,
89     *       TENSOR_QUANT8_ASYMM?
90     * TODO: Define "broadcast requirements" and have a link for Broadcast.
91     * TODO: Define "fused activation" and have a link for FusedActivation.
92     *
93     * Inputs:
94     * 0: A tensor.
95     * 1: A tensor of the same type as input0.  It should have the same shape too or satisfy
96     *    broadcast requirements.  See Broadcast.
97     * 2: An optional INT32? value.  Specifies the activation to invoke on the result of each
98     *    addition.  See FusedActivation.
99     *
100     * Ouputs:
101     * 0: The sum, a tensor of the same type and shape as input0.
102     */
103    ANEURALNETWORKS_ADD = 1,
104    // TODO Document all the other ops.
105    ANEURALNETWORKS_AVERAGE_POOL = 2,
106    ANEURALNETWORKS_CAST = 3,
107    ANEURALNETWORKS_CONCATENATION = 4,
108    ANEURALNETWORKS_CONV = 5,
109    ANEURALNETWORKS_DEPTHWISE_CONV = 6,
110    ANEURALNETWORKS_DEPTH_TO_SPACE = 7,
111    ANEURALNETWORKS_DEQUANTIZE = 8,
112    ANEURALNETWORKS_EMBEDDING_LOOKUP = 9,
113    ANEURALNETWORKS_FAKE_QUANT = 10,
114    ANEURALNETWORKS_FLOOR = 11,
115    ANEURALNETWORKS_FULLY_CONNECTED = 12,
116    ANEURALNETWORKS_GATHER = 13,
117    ANEURALNETWORKS_HASHTABLE_LOOKUP = 14,
118    ANEURALNETWORKS_L2_NORMALIZATION = 15,
119    ANEURALNETWORKS_L2_POOL = 16,
120    ANEURALNETWORKS_LOCAL_RESPONSE_NORMALIZATION = 17,
121    ANEURALNETWORKS_LOGISTIC = 18,
122    ANEURALNETWORKS_LSH_PROJECTION = 19,
123    ANEURALNETWORKS_LSTM = 20,
124    ANEURALNETWORKS_MAX_POOL = 21,
125    ANEURALNETWORKS_MUL = 22,
126    ANEURALNETWORKS_RELU = 23,
127    ANEURALNETWORKS_RELU1 = 24,
128    ANEURALNETWORKS_RELU6 = 25,
129    ANEURALNETWORKS_RESHAPE = 26,
130    ANEURALNETWORKS_RESIZE_BILINEAR = 27,
131    ANEURALNETWORKS_RNN = 28,
132    ANEURALNETWORKS_SOFTMAX = 29,
133    ANEURALNETWORKS_SPACE_TO_DEPTH = 30,
134    ANEURALNETWORKS_SPLIT = 31,
135    ANEURALNETWORKS_SVDF = 32,
136    ANEURALNETWORKS_TANH = 33,
137};
138
139/**
140 * Request execution preferences.
141 */
142enum {
143    /**
144     * Prefer executing the request in a way that minimizes battery drain.
145     * This is desirable for requests that will be executed often.
146     */
147    ANEURALNETWORKS_PREFER_LOW_POWER = 0,
148    /**
149     * Prefer returning a single answer as fast as possible, even if this causes
150     * more power consumption.
151     */
152    ANEURALNETWORKS_PREFER_FAST_SINGLE_ANSWER = 1,
153    /**
154     * Prefer maximizing the throughput of successive frames, for example when
155     * processing successive frames coming from the camera.
156     */
157    ANEURALNETWORKS_PREFER_SUSTAINED_SPEED = 2,
158};
159
160/**
161 * Result codes.
162 */
163enum {
164    ANEURALNETWORKS_NO_ERROR = 0,
165    ANEURALNETWORKS_OUT_OF_MEMORY = 1,
166    ANEURALNETWORKS_INCOMPLETE = 2,
167    ANEURALNETWORKS_UNEXPECTED_NULL = 3,
168    ANEURALNETWORKS_BAD_DATA = 4,
169    ANEURALNETWORKS_OP_FAILED = 5,
170};
171
172/**
173 * ANeuralNetworksMemory is an opaque type that represents shared memory.
174 *
175 * By using shared memory, a program can efficiently communicate to the
176 * runtime and the drivers the weights and other tensors that define a model.
177 * See {@Link ANeuralNetworksModel_setOperandValueFromMemory}.
178 *
179 * An application should typically create one shared memory object that
180 * contains every weight and tensor needed to define one or more models.
181 *
182 * Shared memory can also be used when specifying the input and output
183 * arguments of a request.  See calling {@Link ANeuralNetworksRequest_setInputFromMemory}
184 * and {@Link ANeuralNetworksRequest_setOutputFromMemory}.
185 *
186 * Shared memory handles are created by calling {@link ANeuralNetworksMemory_create}
187 * and similar functions.
188 */
189typedef struct ANeuralNetworksMemory ANeuralNetworksMemory;
190
191/**
192 * ANeuralNetworksRequest is an opaque type that can be used to apply a machine
193 * learning model to a set of inputs.
194 *
195 * <p>To use:<ul>
196 *    <li>Create a new request instance by calling the
197 *        {@link ANeuralNetworksRequest_create} function.</li>
198 *    <li>Associate data to the model inputs with
199 *        {@link ANeuralNetworksRequest_setInput} or
200 *        {@Link ANeuralNetworksRequest_setInputFromMemory}.</li>
201 *    <li>Associate output buffers to the model outputs with
202 *        {@link ANeuralNetworksRequest_setOutput} or
203 *        {@Link ANeuralNetworksRequest_setOutputFromMemory}.</li>
204 *    <li>Apply the model with {@link ANeuralNetworksRequest_startCompute}.</li>
205 *    <li>Wait for the request to complete with {@link
206 * ANeuralNetworksRequest_wait}.</li> <li>Repeat the previous steps as often as
207 * needed.</li> <li>Destroy the request with {@link
208 * ANeuralNetworksRequest_free}.</li></ul></p>
209 *
210 * <p>A request can be reused by simply modifying the content of the input
211 * buffers and restarting the computation. It's also valid to call
212 * ANeuralNetworksRequest_setInput or ANeuralNetworksRequest_setOutput before
213 * restarting the request, as long as only the address of the buffer
214 * changes.</p>
215 *
216 * <p>The functions that manipulate requests are thread safe.</p>
217 * [TODO: We could have it that it's the responsibility of the application to
218 * ensure that no two threads manipulate the same request concurrently. Internal
219 * structures not specific to a request would always be protected.]
220 */
221typedef struct ANeuralNetworksRequest ANeuralNetworksRequest;
222
223/**
224 * ANeuralNetworksModel is an opaque type that contains a description of the
225 * mathematical operations that constitute the model.
226 *
227 * <p>The model will be built by calling<ul>
228 * <li>{@link ANeuralNetworksModel_create},</li>
229 * <li>{@link ANeuralNetworksModel_addOperation},</li>
230 * <li>{@link ANeuralNetworksModel_addOperand},</li>
231 * </ul>
232 *
233 * A model is destroyed by calling{@link ANeuralNetworksModel_free}.
234 */
235typedef struct ANeuralNetworksModel ANeuralNetworksModel;
236
237typedef struct ANeuralNetworksIntList {
238    uint32_t count;
239    const uint32_t* data;
240} ANeuralNetworksIntList;
241
242/**
243 * ANeuralNetworksOperandType describes the type of an operand.
244 * This structure is used to describe both scalars and tensors.
245 */
246typedef struct ANeuralNetworksOperandType {
247    // The data type, e.g ANEURALNETWORKS_INT8.
248    uint32_t type;
249    // Count and size of each dimension.  The count should be 0 for scalars.
250    ANeuralNetworksIntList dimensions;
251    /* These two fields are only used for quantized tensors.
252     * They should be zero for scalars and non-fixed point tensors.
253     * The dequantized value of each entry is (value - offset) * scale.
254     * TODO: revisit once we have a final representation for quantization.
255     */
256    float scale;
257    int32_t offset;
258} ANeuralNetworksOperandType;
259
260/**
261 * ANeuralNetworksEvent is an opaque type that represents an event
262 * that will be signaled once a request completes.
263 */
264typedef struct ANeuralNetworksEvent ANeuralNetworksEvent;
265
266typedef uint32_t ANeuralNetworksOperationType;
267
268/**
269 * Initializes the machine learning runtime.
270 *
271 * This should be called before any other ANeuralNetworks functions.
272 * This function may start work threads, may clean up part of the
273 * cache, and query the capabilities of the drivers.
274 *
275 * As the initialization may take some time, you may want to call
276 * this function outside of the initialization path of your application,
277 * so that your application starts quickly. [TODO verify the startup cost]
278 *
279 * Your application should call {@link ANeuralNetworksShutdown} to tear
280 * down the runtime.
281 *
282 * It is safe for a process to call this function multiple times.
283 * The first call performs the initialization. Successive calls increase
284 * an internal reference count. An equivalent number of calls to
285 * ANeuralNetworksShutdown must be performed for the runtime to be
286 * destroyed. This enables libraries to safely call Initialize and Shutdown.
287 *
288 * This function is thread safe.
289 *
290 * @return NO_ERROR if successful, else [?]
291 */
292int ANeuralNetworksInitialize();
293
294/**
295 * Destroys the machine learning runtime.
296 *
297 * This function frees any resource used by the runtime. It will wait
298 * until in flight requests have completed and will prevent new ones
299 * from being started with {@link ANeuralNetworksRequest_startCompute}.
300 *
301 * Threads blocked on {@link ANeuralNetworksRequest_wait} calls will be
302 * released before this function terminates.
303 *
304 * See {@link ANeuralNetworksInitialize} for details on how multiple calls
305 * to Initialize and Shutdown work.
306 *
307 * This function is thread safe.
308 *
309 * [TODO It's possible that the Initialize and Shutdown calls don't need to
310 *  affect the models created by the ANeuralNetworksModel_* APIs.  If so,
311 *  we may want to modify the name of this API and specify it here.]
312 */
313void ANeuralNetworksShutdown();
314
315/**
316 * Creates a shared memory object.
317 *
318 * Creates a shared memory region of the specified size in bytes.
319 * See {@link ANeuralNetworksMemory} for a description on how to use
320 * this shared memory.
321 */
322int ANeuralNetworksMemory_create(size_t size, ANeuralNetworksMemory** memory);
323
324/* TODO Should we also have from Surface, IONBuffer, ashmem and:
325int ANeuralNetworksMemory_createFromHidlMemory(android::hardware::hidl_memory hidlMemory,
326                                               ANeuralNetworksMemory** memory);
327int ANeuralNetworksMemory_createFromFd(int fd, ANeuralNetworksMemory** memory);
328int ANeuralNetworksMemory_createFromGrallocBuffer(buffer_handle_t buffer,
329                                                  ANeuralNetworksMemory** memory);
330int ANeuralNetworksMemory_createFromHardwareBuffer(AHardwareBuffer* buffer,
331                                                   ANeuralNetworksMemory** memory);
332*/
333
334/**
335 * Returns a pointer to the content of the shared memory.
336 *
337 * Returns a pointer to the shared memory created by {@link ANeuralNetworksMemory_create}.
338 */
339uint8_t* ANeuralNetworksMemory_getPointer(ANeuralNetworksMemory* memory);
340
341/**
342 * Delete a shared memory object.
343 *
344 * Destroys the object used by the run time to keep track of the shared memory.
345 * This will free the underlying actual shared memory if no other code has open
346 * handles to this memory.  [TODO verify]
347 */
348void ANeuralNetworksMemory_free(ANeuralNetworksMemory* memory);
349
350/**
351 * Create an empty {@link ANeuralNetworksModel}.
352 *
353 * <p>This only creates the object.  Computation is performed once
354 * {@link ANeuralNetworksRequest_startCompute} is invoked.
355 *
356 * The model should be constructed with calls to
357 * {@link ANeuralNetworksModel_addOperation} and
358 * {@link ANeuralNetworksModel_addOperand}
359 *
360 * <p>{@link ANeuralNetworksModel_free} should be called once the model
361 * is no longer needed.</p>
362 *
363 * This function is thread safe.
364 *
365 * @param model The {@link ANeuralNetworksModel} to be created.
366 *              Set to NULL if unsuccessful.
367 *
368 * @return NO_ERROR if successful, [?] otherwise.
369 */
370int ANeuralNetworksModel_create(ANeuralNetworksModel** model);
371
372/**
373 * Destroy a model.
374 *
375 * An application is responsible to make sure that no other thread uses
376 * the model at the same time.
377 *
378 * @param model The model to be destroyed. Passing NULL is acceptable and
379 *              results in no operation.
380 */
381void ANeuralNetworksModel_free(ANeuralNetworksModel* model);
382
383/**
384 * Add an operand to a model.
385 *
386 * The order in which the operands are added is important. The first one added
387 * to a model will have the index value 0, the second 1, etc.  These indexes are
388 * used as operand identifiers in {@link ANeuralNetworksModel_addOperation},
389 * {@link ANeuralNetworksRequest_setInput},
390 * {@Link ANeuralNetworksRequest_setInputFromMemory},
391 * {@link ANeuralNetworksRequest_setOutput},
392 * {@Link ANeuralNetworksRequest_setOutputFromMemory} and
393 * {@link ANeuralNetworksRequest_setOperandValue}.
394 *
395 * To build a model that can accomodate inputs of various sizes, as you may want
396 * to do for a CNN, set the size of the dimensions that will vary at run time to
397 * 0. These dimensions will have to be set when the application calls
398 * {@link ANeuralNetworksRequest_setInput}.
399 *
400 * An application is responsible to make sure that no other thread uses
401 * the model at the same time.
402 *
403 * A model can't be modified once a request has been created for it by
404 * {@link ANeuralNetworksRequest_create}.
405 *
406 * @param model The model to be modified.
407 * @param type The {@link ANeuralNetworksOperandType} that describes the shape
408 * of the operand.
409 *
410 * @return NO_ERROR if successful, [?] otherwise.
411 */
412int ANeuralNetworksModel_addOperand(ANeuralNetworksModel* model,
413                                    const ANeuralNetworksOperandType* type);
414
415/**
416 * Sets an operand to a constant value.
417 *
418 * This value can't be changed when a request is executed.
419 *
420 * A model can't be modified once a request has been created for it by
421 * {@link ANeuralNetworksRequest_create}.
422 */
423int ANeuralNetworksModel_setOperandValue(ANeuralNetworksModel* model, int32_t index,
424                                         const void* buffer, size_t length);
425
426/**
427 * Sets an operand to a value stored in shared memory.
428 *
429 * This value can't be changed when a request is executed.
430 *
431 * A model can't be modified once a request has been created for it by
432 * {@link ANeuralNetworksRequest_create}.
433 */
434int ANeuralNetworksModel_setOperandValueFromMemory(ANeuralNetworksModel* model, int32_t index,
435                                                   const ANeuralNetworksMemory* buffer,
436                                                   uint32_t offset, size_t length);
437
438/**
439 * Add an operation to a model.
440 *
441 * @param model The model to be modified.
442 * @param type The type of the operation.
443 * @param inputs An array of indexes identifying each an operand.
444 * @param outputs An array of indexes identifying each an operand.
445 * [TODO: Make sure these are compatible with TensorFlow Lite.]
446 *
447 * The operands specified by inputs and outputs must have been
448 * previously added by calls to {@link ANeuralNetworksModel_addOperand}.
449 *
450 * An application is responsible to make sure that no other thread uses
451 * the model at the same time.
452 *
453 * A model can't be modified once a request has been created for it by
454 * {@link ANeuralNetworksRequest_create}.
455 *
456 * @return NO_ERROR if successful, [?] otherwise.
457 */
458int ANeuralNetworksModel_addOperation(ANeuralNetworksModel* model,
459                                      ANeuralNetworksOperationType type,
460                                      ANeuralNetworksIntList* inputs,
461                                      ANeuralNetworksIntList* outputs);
462
463/**
464 * Specfifies which operands will be the model's inputs and outputs.
465 *
466 * TODO: Can an operand be used for both input and output?
467 *
468 * @param model The model to be modified.
469 * @param inputs An array of indexes identifying the input operands.
470 * @param outputs An array of indexes identifying the output operands.
471 *
472 * The operands specified by inputs and outputs must have been
473 * previously added by calls to {@link ANeuralNetworksModel_addOperand}.
474 *
475 * A model can't be modified once a request has been created for it by
476 * {@link ANeuralNetworksRequest_create}.
477 */
478int ANeuralNetworksModel_setInputsAndOutputs(ANeuralNetworksModel* model,
479                                             ANeuralNetworksIntList* inputs,
480                                             ANeuralNetworksIntList* outputs);
481
482/**
483 * Create a {@link ANeuralNetworksRequest} to apply the given model.
484 * This only creates the object.  Computation is only performed once
485 * {@link ANeuralNetworksRequest_startCompute} is invoked.
486 *
487 * <p>The provided model must outlive the request.</p>
488 *
489 * This function is thread safe.
490 *
491 * @param model The {@link ANeuralNetworksModel} to be evaluated.
492 * @param request The newly created object or NULL if unsuccessful.
493 *
494 * @return NO_ERROR if successful, BAD_DATA if the model is invalid.
495 */
496int ANeuralNetworksRequest_create(ANeuralNetworksModel* model, ANeuralNetworksRequest** request);
497
498/**
499 * Destroy a request.
500 *
501 * <p>If called on a request for which
502 * {@link ANeuralNetworksRequest_startCompute} has been called, the
503 * function will return immediately but will mark the request to be deleted
504 * once the computation completes. The related {@link ANeuralNetworksEvent}
505 * will be signaled but the {link ANeuralNetworksRequest_wait} will return
506 * ERROR_DELETED.
507 *
508 * This function is thread safe.
509 *
510 * @param request The request to be destroyed. Passing NULL is acceptable and
511 *                results in no operation.
512 */
513void ANeuralNetworksRequest_free(ANeuralNetworksRequest* request);
514
515/**
516 * Sets the execution preference.
517 *
518 * <p>Provides guidance to the runtime when trade-offs are possible.</p>
519 *
520 * This function is thread safe.
521 *
522 * @param request The request to be modified.
523 * @param preference Either {@link PREFER_LOW_POWER},
524 *                  {@link PREFER_SINGLE_FAST_ANSWER}, or
525 *                  {@link PREFER_SUSTAINED_SPEED}.
526 *
527 * @return NO_ERROR if successful.
528 */
529int ANeuralNetworksRequest_setPreference(ANeuralNetworksRequest* request, uint32_t preference);
530
531/**
532 * Associate a user buffer with an input of the model of the
533 * {@link ANeuralNetworksRequest}.
534 *
535 * <p>The provided buffer must outlive the request.</p>
536 *
537 * This function is thread safe.
538 *
539 * @param request The request to be modified.
540 * @param index The index of the model operand we're associating the input to.
541 * @param type The type of the operand. This is useful if the model did not
542 * fully specify the operand. If specified in the model, type should be NULL or
543 *             have the same value as specified in the model.
544 *             [TODO: We know the dimensions may change.  Anything else?  Base
545 * type?]
546 * @param buffer The buffer containing the data.
547 * @param length The length in bytes of the buffer.
548 *
549 * @return NO_ERROR if successful, BAD_DATA if the name is not recognized
550 *         or the buffer is too small for the input.
551 */
552int ANeuralNetworksRequest_setInput(ANeuralNetworksRequest* request, int32_t index,
553                                    const ANeuralNetworksOperandType* type, const void* buffer,
554                                    size_t length);
555
556/**
557 * Associate part of a shared memory with an input of the model of the
558 * {@link ANeuralNetworksRequest}.
559 *
560 * <p>The provided shared memory must outlive the request.</p>
561 *
562 * This function is thread safe.
563 *
564 * @param request The request to be modified.
565 * @param index The index of the model operand we're associating the input to.
566 * @param type The type of the operand. This is useful if the model did not
567 * fully specify the operand. If specified in the model, type should be NULL or
568 *             have the same value as specified in the model.
569 *             [TODO: We know the dimensions may change.  Anything else?  Base
570 * type?]
571 * @param memory The shared memory containing the data.
572 * @param offset This specifies the location of the data whithin the shared memory.
573 *               The offset is in bytes from the start of shared memory.
574 *
575 * @return NO_ERROR if successful, BAD_DATA if the name is not recognized
576 *         or the buffer is too small for the input.
577 */
578int ANeuralNetworksRequest_setInputFromMemory(ANeuralNetworksRequest* request, int32_t index,
579                                              const ANeuralNetworksOperandType* type,
580                                              const ANeuralNetworksMemory* memory, uint32_t offset,
581                                              uint32_t length);
582
583/**
584 * Associate a user buffer with an output of the model of the
585 * {@link ANeuralNetworksRequest}.
586 *
587 * <p>The provided buffer must outlive the request.</p>
588 *
589 * This function is thread safe.
590 *
591 * @param request The request to be modified.
592 * @param index The index of the model operand we're associating the input to.
593 * @param type The type of the operand. This is useful if the model did not
594 * fully specify the operand. If specified in the model, type should be NULL or
595 *             have the same value as specified in the model.
596 *             [TODO: We know the dimensions may change.  Anything else?  Base
597 * type?]
598 * @param buffer The buffer where the data will be written.
599 * @param length The length in bytes of the buffer.
600 *
601 * @return NO_ERROR if successful, BAD_DATA if the name is not recognized
602 *         or the buffer is too small for the output.
603 */
604int ANeuralNetworksRequest_setOutput(ANeuralNetworksRequest* request, int32_t index,
605                                     const ANeuralNetworksOperandType* type, void* buffer,
606                                     size_t length);
607
608/**
609 * Associate part of a shared memory with an output of the model of the
610 * {@link ANeuralNetworksRequest}.
611 *
612 * <p>The provided shared memory must outlive the request.</p>
613 *
614 * @param request The request to be modified.
615 * @param index The index of the model operand we're associating the input to.
616 * @param type The type of the operand. This is useful if the model did not
617 * fully specify the operand. If specified in the model, type should be NULL or
618 *             have the same value as specified in the model.
619 *             [TODO: We know the dimensions may change.  Anything else?  Base
620 * type?]
621 * @param offset This specifies the location of the data whithin the shared memory.
622 *               The offset is in bytes from the start of shared memory.
623 * [todo Would it be useful to have a rect param?]
624 *
625 * @return NO_ERROR if successful, BAD_DATA if the name is not recognized
626 *         or the buffer is too small for the output.
627 */
628int ANeuralNetworksRequest_setOutputFromMemory(ANeuralNetworksRequest* request, int32_t index,
629                                               const ANeuralNetworksOperandType* type,
630                                               const ANeuralNetworksMemory* memory, uint32_t offset,
631                                               uint32_t length);
632
633/**
634 * Schedule the request for execution.
635 *
636 * <p>Schedules the request for execution. Once the model has been
637 * applied and the outputs are ready to be consumed, the returned event will be
638 * signaled. Use {@link ANeuralNetworksRequest_wait} to wait for that event.
639 * </p>
640 *
641 * Multiple requests can be scheduled and executed concurrently. The runtime makes
642 * no guarantee on the ordering of the completion of the requests.  If it's
643 * important to the application, the application should enforce the ordering by
644 * using the returned events.
645 *
646 * ANeuralNetworksRequest_wait must be called to recuperate the resources used
647 * by the event.
648 *
649 * This function is thread safe.
650 *
651 * @param request The request to be modified.
652 * @param event The event that will be signaled on completion.
653 *              [TODO define the functions to create/delete events?
654 *                    or startCompute creates, and free deletes?]
655 *
656 * @return NO_ERROR if successful, BAD_DATA if callback is NULL.
657 */
658int ANeuralNetworksRequest_startCompute(ANeuralNetworksRequest* request,
659                                        ANeuralNetworksEvent** event);
660
661/**
662 * Waits until the request completes.
663 *
664 * More than one thread can wait on an event.  When the request completes,
665 * all threads will be released.
666 * [TODO Should we free just one to enable thread pools?]
667 *
668 * This function is thread safe.
669 *
670 * @return NO_ERROR if the request completed normally.
671 */
672int ANeuralNetworksEvent_wait(ANeuralNetworksEvent* event);
673
674/**
675 * Destroys the event.
676 *
677 * TODO: Figure out lifetime management if multiple threads can wait on an
678 * event.
679 */
680void ANeuralNetworksEvent_free(ANeuralNetworksEvent* event);
681
682__END_DECLS
683
684#endif  //  __ANDROID_API__ >= 27
685
686#endif  // ANDROID_ML_NN_RUNTIME_NEURAL_NETWORKS_H
687