You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
8.4 KiB
156 lines
8.4 KiB
/*
|
|
* Copyright (C) 2020 The Android Open Source Project
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#ifndef ANDROID_FRAMEWORKS_ML_NN_COMMON_NNAPI_IBURST_H
|
|
#define ANDROID_FRAMEWORKS_ML_NN_COMMON_NNAPI_IBURST_H
|
|
|
|
#include <android-base/scopeguard.h>
|
|
|
|
#include <functional>
|
|
#include <memory>
|
|
#include <optional>
|
|
#include <utility>
|
|
#include <vector>
|
|
|
|
#include "nnapi/Types.h"
|
|
|
|
namespace android::nn {
|
|
|
|
/**
|
|
* IBurst represents a burst execution object.
|
|
*
|
|
* Burst executions are a sequence of executions of the same prepared model that occur in rapid
|
|
* succession, such as frames of a camera capture or successive audio samples. A burst object is
|
|
* used to control a set of burst executions, and to preserve resources between executions, enabling
|
|
* executions to have lower overhead. Burst objects enable some optimizations:
|
|
* (1) A burst object is created before a sequence of executions, and freed when the sequence has
|
|
* ended. Because of this, the lifetime of the burst object hints to a driver how long it should
|
|
* remain in a high performance state.
|
|
* (2) A burst object can preserve resources between executions. For example, a driver can map a
|
|
* memory object on the first execution and cache the mapping in the burst object for reuse in
|
|
* subsequent executions. Any cached resource can be released when the burst object is destroyed
|
|
* or when the NNAPI runtime notifies the burst object that the resource is no longer required.
|
|
* (3) A burst object may be used for at most one execution at a time. This enables any transient
|
|
* execution resources such as intermediate tensors to be allocated once when the burst object
|
|
* is created and freed when the burst object is destroyed.
|
|
*
|
|
* This interface is thread-safe, and any class that implements this interface must be thread-safe.
|
|
*/
|
|
class IBurst {
|
|
public:
|
|
using OptionalCacheHold = std::shared_ptr<const base::ScopeGuard<std::function<void()>>>;
|
|
|
|
/**
|
|
* Cache a memory object in the burst.
|
|
*
|
|
* This can enable multiple executions that reuse the same memory to be more efficient.
|
|
*
|
|
* @param memory The memory object to be cached as long as CacheHandle is held.
|
|
* @return An optional cache handle that will release the corresponding cahced object once the
|
|
* cache handle is released, or nullptr.
|
|
*/
|
|
virtual OptionalCacheHold cacheMemory(const SharedMemory& memory) const = 0;
|
|
|
|
/**
|
|
* Performs a synchronous execution on a prepared model.
|
|
*
|
|
* At most one execution may occur on a burst object at any given time.
|
|
*
|
|
* The execution is performed synchronously with respect to the caller. IBurst::execute must
|
|
* verify the inputs to the function are correct. If there is an error, IBurst::execute must
|
|
* immediately return {@link ErrorStatus::INVALID_ARGUMENT} as a ExecutionError. If the inputs
|
|
* to the function are valid and there is no error, IBurst::execute must perform the execution,
|
|
* and must not return until the execution is complete.
|
|
*
|
|
* The caller must not change the content of any data object referenced by request (described by
|
|
* the {@link DataLocation} of a {@link RequestArgument}) until IBurst::execute returns.
|
|
* IBurst::execute must not change the content of any of the data objects corresponding to
|
|
* request inputs.
|
|
*
|
|
* If the prepared model was prepared from a model wherein all tensor operands have fully
|
|
* specified dimensions, and the inputs to the function are valid, and at execution time every
|
|
* operation's input operands have legal values, then the execution should complete
|
|
* successfully. There must be no failure unless the device itself is in a bad state.
|
|
*
|
|
* @param request The input and output information on which the prepared model is to be
|
|
* executed.
|
|
* @param measure Specifies whether or not to measure duration of the execution.
|
|
* @param deadline Optional time point. If provided, execute is expected to complete by this
|
|
* time point. If it is not able to be completed by the deadline, the execution may be
|
|
* aborted.
|
|
* @param loopTimeoutDuration The maximum amount of time that should be spent executing a {@link
|
|
* OperationType::WHILE} operation. If a loop condition model does not output `false` within
|
|
* this duration, the execution must be aborted. If no loop timeout duration is provided,
|
|
* the maximum amount of time is {@link kControlFlowTimeoutDefault}. When provided, the
|
|
* duration must not exceed {@link kControlFlowTimeoutMaximum}.
|
|
* @return A pair consisting of:
|
|
* - A list of shape information of model output operands. The index into "outputShapes"
|
|
* corresponds to the index of the output operand in the Request outputs vector.
|
|
* outputShapes must be empty unless the execution is successful or the ExecutionResult is
|
|
* {@link ErrorStatus::OUTPUT_INSUFFICIENT_SIZE}. outputShapes may be empty if the
|
|
* execution is successful and all model output operands are fully-specified at execution
|
|
* time. outputShapes must have the same number of elements as the number of model output
|
|
* operands if the ExecutionResult is {@link ErrorStatus::OUTPUT_INSUFFICIENT_SIZE}, or if
|
|
* the execution is successful and the model has at least one output operand that is not
|
|
* fully-specified.
|
|
* - Duration of execution. Unless measure is YES and the execution is successful, all times
|
|
* must be reported as std::nullopt. A driver may choose to report any time as
|
|
* std::nullopt, indicating that measurement is not available.
|
|
*/
|
|
virtual ExecutionResult<std::pair<std::vector<OutputShape>, Timing>> execute(
|
|
const Request& request, MeasureTiming measure, const nn::OptionalTimePoint& deadline,
|
|
const nn::OptionalDuration& loopTimeoutDuration) const = 0;
|
|
|
|
/**
|
|
* Create a reusable burst execution object.
|
|
*
|
|
* IBurst::createReusableExecution must verify the inputs to the function are correct. If there
|
|
* is an error, IBurst::createReusableExecution must immediately return {@link
|
|
* ErrorStatus::INVALID_ARGUMENT} as a GeneralError. If the inputs to the function are valid and
|
|
* there is no error, IBurst::createReusableExecution must construct a reusable execution.
|
|
*
|
|
* @param request The input and output information on which the prepared model is to be
|
|
* executed.
|
|
* @param measure Specifies whether or not to measure duration of the computation.
|
|
* @param loopTimeoutDuration The maximum amount of time that should be spent executing a {@link
|
|
* OperationType::WHILE} operation. If a loop condition model does not output `false` within
|
|
* this duration, the execution must be aborted. If no loop timeout duration is provided,
|
|
* the maximum amount of time is {@link kControlFlowTimeoutDefault}. When provided, the
|
|
* duration must not exceed {@link kControlFlowTimeoutMaximum}.
|
|
* @return execution An IExecution object representing a reusable burst execution that has been
|
|
* specialized for a fixed request, otherwise GeneralError.
|
|
*/
|
|
virtual GeneralResult<SharedExecution> createReusableExecution(
|
|
const Request& request, MeasureTiming measure,
|
|
const nn::OptionalDuration& loopTimeoutDuration) const = 0;
|
|
|
|
// Public virtual destructor to allow objects to be stored (and destroyed) as smart pointers.
|
|
// E.g., std::unique_ptr<IBurst>.
|
|
virtual ~IBurst() = default;
|
|
|
|
protected:
|
|
// Protect the non-destructor special member functions to prevent object slicing.
|
|
IBurst() = default;
|
|
IBurst(const IBurst&) = default;
|
|
IBurst(IBurst&&) noexcept = default;
|
|
IBurst& operator=(const IBurst&) = default;
|
|
IBurst& operator=(IBurst&&) noexcept = default;
|
|
};
|
|
|
|
} // namespace android::nn
|
|
|
|
#endif // ANDROID_FRAMEWORKS_ML_NN_COMMON_NNAPI_IBURST_H
|