Skip to content

Commit

Permalink
Update nnapi wrapper from tensorflow
Browse files Browse the repository at this point in the history
  • Loading branch information
daquexian committed Jul 26, 2019
1 parent ab22710 commit 4168162
Show file tree
Hide file tree
Showing 14 changed files with 1,868 additions and 5,974 deletions.
10 changes: 5 additions & 5 deletions binaries/dnn_benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ bool hasEnding(std::string const &fullString, std::string const &ending) {
}

auto GetModel(css &daqName, const bool allow_fp16,
const PreferenceCode &compile_preference) {
const int compile_preference) {
std::unique_ptr<Model> model;
ModelBuilder builder;
if (hasEnding(daqName, ".daq")) {
Expand All @@ -64,7 +64,7 @@ auto GetModel(css &daqName, const bool allow_fp16,
return model;
}

auto PrefCodeToStr(const PreferenceCode &preference_code) {
auto PrefCodeToStr(const int &preference_code) {
if (preference_code == ANEURALNETWORKS_PREFER_FAST_SINGLE_ANSWER) {
return "fast single";
}
Expand Down Expand Up @@ -129,13 +129,13 @@ int main(int argc, char **argv) {
} \
}

const std::vector<PreferenceCode> preference_candidates{
const std::vector<int> preference_candidates{
ANEURALNETWORKS_PREFER_FAST_SINGLE_ANSWER,
ANEURALNETWORKS_PREFER_SUSTAINED_SPEED,
ANEURALNETWORKS_PREFER_LOW_POWER};
if (quant) {
uint8_t data[input_len];
uint8_t output[output_len];
float output[output_len];
WARM_UP;
const std::vector<bool> fp16_candidates{false};
BENCHMARK(fp16_candidates, preference_candidates);
Expand All @@ -149,7 +149,7 @@ int main(int argc, char **argv) {
WARM_UP;

const std::vector<bool> fp16_candidates =
ModelBuilder::GetAndroidSdkVersion() >= __ANDROID_API_P__
GetAndroidSdkVersion() >= __ANDROID_API_P__
? std::vector<bool>{false, true}
: std::vector<bool>{false};
BENCHMARK(fp16_candidates, preference_candidates);
Expand Down
3 changes: 2 additions & 1 deletion dnnlibrary/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ set(dnnlibrary_src
${PROJECT_SOURCE_DIR}/include/dnnlibrary/ModelBuilder.h
${PROJECT_SOURCE_DIR}/include/dnnlibrary/Model.h
${PROJECT_SOURCE_DIR}/include/dnnlibrary/DaqReader.h
${PROJECT_SOURCE_DIR}/include/dnnlibrary/NeuralNetworksWrapper.h
${PROJECT_SOURCE_DIR}/include/dnnlibrary/nnapi_implementation.h
android_log_helper.h
operand_helper.h
flatbuffers_helper.h
ModelBuilder.cpp
Model.cpp
DaqReader.cpp
NeuralNetworksWrapper.cpp
nnapi_implementation.cc
${PROJECT_SOURCE_DIR}/include/common/Shaper.h
${PROJECT_SOURCE_DIR}/common/Shaper.cpp
${PROJECT_SOURCE_DIR}/include/common/StrKeyMap.h
Expand Down
8 changes: 4 additions & 4 deletions dnnlibrary/DaqReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,13 +59,13 @@ std::string layer_type_to_str(DNN::LayerType type) {
int convert_fuse_code_to_nnapi(const DNN::FuseCode fuse_code) {
switch (fuse_code) {
case DNN::FuseCode::None:
return FuseCode::ANEURALNETWORKS_FUSED_NONE;
return ANEURALNETWORKS_FUSED_NONE;
case DNN::FuseCode::Relu:
return FuseCode::ANEURALNETWORKS_FUSED_RELU;
return ANEURALNETWORKS_FUSED_RELU;
case DNN::FuseCode::Relu1:
return FuseCode::ANEURALNETWORKS_FUSED_RELU1;
return ANEURALNETWORKS_FUSED_RELU1;
case DNN::FuseCode::Relu6:
return FuseCode::ANEURALNETWORKS_FUSED_RELU6;
return ANEURALNETWORKS_FUSED_RELU6;
}
throw std::invalid_argument("Invalid fuse_code");
}
Expand Down
29 changes: 17 additions & 12 deletions dnnlibrary/Model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,19 @@ void Model::PrepareForExecution() {
throw std::invalid_argument(
"Error in PrepareForExecution, compilation_ == nullptr");
}
THROW_ON_ERROR(ANeuralNetworksExecution_create(compilation_, &execution_));
THROW_ON_ERROR(
nnapi_->ANeuralNetworksExecution_create(compilation_, &execution_));
prepared_for_exe_ = true;
}

Model::Model() : nnapi_(NnApiImplementation()) {
}

Model::~Model() {
munmap(data_, data_size_);
ANeuralNetworksModel_free(model_);
ANeuralNetworksCompilation_free(compilation_);
ANeuralNetworksMemory_free(memory_);
nnapi_->ANeuralNetworksModel_free(model_);
nnapi_->ANeuralNetworksCompilation_free(compilation_);
nnapi_->ANeuralNetworksMemory_free(memory_);
}

void Model::SetInputBuffer(const int32_t index, const float *buffer) {
Expand All @@ -52,8 +56,8 @@ void Model::SetInputBuffer(const int32_t index, const void *buffer,
const size_t elemsize) {
if (!prepared_for_exe_) PrepareForExecution();
auto size = shaper_.GetSize(input_names_[index]) * elemsize;
THROW_ON_ERROR(ANeuralNetworksExecution_setInput(execution_, index, nullptr,
buffer, size))
THROW_ON_ERROR(nnapi_->ANeuralNetworksExecution_setInput(
execution_, index, nullptr, buffer, size))
}

void Model::SetOutputBuffer(const int32_t index, float *buffer) {
Expand All @@ -72,17 +76,18 @@ void Model::SetOutputBuffer(const int32_t index, void *buffer,
const size_t elemsize) {
if (!prepared_for_exe_) PrepareForExecution();
auto size = shaper_.GetSize(output_names_[index]) * elemsize;
THROW_ON_ERROR(ANeuralNetworksExecution_setOutput(execution_, index,
nullptr, buffer, size))
THROW_ON_ERROR(nnapi_->ANeuralNetworksExecution_setOutput(
execution_, index, nullptr, buffer, size))
}

void Model::PredictAfterSetInputBuffer() {
ANeuralNetworksEvent *event = nullptr;
THROW_ON_ERROR(ANeuralNetworksExecution_startCompute(execution_, &event));
THROW_ON_ERROR(ANeuralNetworksEvent_wait(event));
THROW_ON_ERROR(
nnapi_->ANeuralNetworksExecution_startCompute(execution_, &event));
THROW_ON_ERROR(nnapi_->ANeuralNetworksEvent_wait(event));

ANeuralNetworksEvent_free(event);
ANeuralNetworksExecution_free(execution_);
nnapi_->ANeuralNetworksEvent_free(event);
nnapi_->ANeuralNetworksExecution_free(execution_);
prepared_for_exe_ = false;
}

Expand Down
80 changes: 25 additions & 55 deletions dnnlibrary/ModelBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,41 +30,6 @@ using std::stringstream;
using std::vector;
using namespace android::nn::wrapper;

// Copy from
// https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/nnapi/nnapi_implementation.cc
int32_t ModelBuilder::GetAndroidSdkVersion() {
const char *sdkProp = "ro.build.version.sdk";
char sdkVersion[PROP_VALUE_MAX];
int length = __system_property_get(sdkProp, sdkVersion);
if (length != 0) {
int32_t result = 0;
for (int i = 0; i < length; ++i) {
int digit = sdkVersion[i] - '0';
if (digit < 0 || digit > 9) {
// Non-numeric SDK version, assume it's higher than expected;
return 0xffff;
}
result = result * 10 + digit;
}
// TODO(levp): remove once SDK gets updated to 29th level
// Upgrade SDK version for pre-release Q to be able to test
// functionality available from SDK level 29.
if (result == 28) {
char versionCodename[PROP_VALUE_MAX];
const char *versionCodenameProp = "ro.build.version.codename";
length =
__system_property_get(versionCodenameProp, versionCodename);
if (length != 0) {
if (versionCodename[0] == 'Q') {
return 29;
}
}
}
return result;
}
return 0;
}

void ModelBuilder::RegisterOperand(const std::string &name,
ModelBuilder::Index index,
const OperandType &operand_type) {
Expand Down Expand Up @@ -539,7 +504,7 @@ ModelBuilder::Index ModelBuilder::AddDequantize(const std::string &input,
input_indexes.push_back(input_idx);
shaper_.Identity(input, output);
const OperandType operand_type =
GetOperandType(Type::FLOAT32, shaper_[output]);
GetOperandType(Type::TENSOR_FLOAT32, shaper_[output]);
const auto output_idx = AddOperation(ANEURALNETWORKS_DEQUANTIZE,
input_indexes, operand_type)[0];
RegisterOperand(output, output_idx, operand_type);
Expand Down Expand Up @@ -696,7 +661,7 @@ OperandType ModelBuilder::GetOperandType(const QuantInfo &quant_info,
map_type##_operand_map_.end()) { \
const auto index = AddNewOperand({Type::op_type}); \
THROW_ON_ERROR_WITH_NOTE( \
ANeuralNetworksModel_setOperandValue( \
nnapi_->ANeuralNetworksModel_setOperandValue( \
dnn_model_->model_, index, &value, sizeof(value)), \
"value: " + std::to_string(value)); \
map_type##_operand_map_[value] = index; \
Expand All @@ -713,15 +678,15 @@ DEFINE_OPERAND_FROM_SCALAR(float, float32, FLOAT32);
ModelBuilder::Index ModelBuilder::AddMissingOperand(
const OperandType &operand_type) {
const auto index = AddNewOperand(operand_type);
THROW_ON_ERROR(ANeuralNetworksModel_setOperandValue(dnn_model_->model_,
index, nullptr, 0));
THROW_ON_ERROR(nnapi_->ANeuralNetworksModel_setOperandValue(
dnn_model_->model_, index, nullptr, 0));
return index;
}

ModelBuilder::Index ModelBuilder::AddNewOperand(
const OperandType &operand_type) {
THROW_ON_ERROR(ANeuralNetworksModel_addOperand(dnn_model_->model_,
&operand_type.operandType));
THROW_ON_ERROR(nnapi_->ANeuralNetworksModel_addOperand(
dnn_model_->model_, &operand_type.operandType));
return next_index_++;
}

Expand All @@ -732,7 +697,7 @@ ModelBuilder::Index ModelBuilder::AddTensorFromMemory(const string &name,
throw std::invalid_argument("");
DNN_ASSERT(!dimen.empty(), "");
const auto index = AddNewOperand({Type::TENSOR_FLOAT32, dimen});
THROW_ON_ERROR(ANeuralNetworksModel_setOperandValueFromMemory(
THROW_ON_ERROR(nnapi_->ANeuralNetworksModel_setOperandValueFromMemory(
dnn_model_->model_, index, dnn_model_->memory_,
addr - dnn_model_->data_, Product(dimen) * sizeof(float)));
shaper_.AddShape(name, dimen);
Expand Down Expand Up @@ -775,7 +740,7 @@ ModelBuilder::Index ModelBuilder::AddTensorFromBuffer(
typeToStr(operand_type.type));
}
uint32_t index = AddNewOperand(operand_type);
THROW_ON_ERROR(ANeuralNetworksModel_setOperandValue(
THROW_ON_ERROR(nnapi_->ANeuralNetworksModel_setOperandValue(
dnn_model_->model_, index, buffer,
Product(operand_type.dimensions) * element_size));
shaper_.AddShape(name, operand_type.dimensions);
Expand All @@ -797,27 +762,28 @@ std::unique_ptr<Model> ModelBuilder::Compile(uint32_t preference) {
}
}
THROW_ON_ERROR_WITH_NOTE(
ANeuralNetworksModel_identifyInputsAndOutputs(
nnapi_->ANeuralNetworksModel_identifyInputsAndOutputs(
dnn_model_->model_, static_cast<uint32_t>(input_index_vec_.size()),
&input_index_vec_[0],
static_cast<uint32_t>(output_index_vec_.size()),
&output_index_vec_[0]),
"on identifyInputsAndOutputs");

THROW_ON_ERROR_WITH_NOTE(ANeuralNetworksModel_finish(dnn_model_->model_),
"on model finish");
THROW_ON_ERROR_WITH_NOTE(
nnapi_->ANeuralNetworksModel_finish(dnn_model_->model_),
"on model finish");

;
THROW_ON_ERROR_WITH_NOTE(ANeuralNetworksCompilation_create(
THROW_ON_ERROR_WITH_NOTE(nnapi_->ANeuralNetworksCompilation_create(
dnn_model_->model_, &dnn_model_->compilation_),
"on create");

THROW_ON_ERROR_WITH_NOTE(ANeuralNetworksCompilation_setPreference(
THROW_ON_ERROR_WITH_NOTE(nnapi_->ANeuralNetworksCompilation_setPreference(
dnn_model_->compilation_, preference),
"on setPreference");

THROW_ON_ERROR_WITH_NOTE(
ANeuralNetworksCompilation_finish(dnn_model_->compilation_),
nnapi_->ANeuralNetworksCompilation_finish(dnn_model_->compilation_),
"on compilation finish");

VLOG(5) << "Finishing.. Here are operands in the model:";
Expand Down Expand Up @@ -904,7 +870,7 @@ ModelBuilder::IndexSeq ModelBuilder::AddOperation(
}

THROW_ON_ERROR_WITH_NOTE(
ANeuralNetworksModel_addOperation(
nnapi_->ANeuralNetworksModel_addOperation(
dnn_model_->model_, op, input_indexes.size(), &input_indexes[0],
output_indexes.size(), &output_indexes[0]),
"op = " + std::to_string(op));
Expand All @@ -914,16 +880,16 @@ ModelBuilder::IndexSeq ModelBuilder::AddOperation(

void ModelBuilder::Prepare() {
dnn_model_ = std::unique_ptr<Model>(new Model());
const auto ret = ANeuralNetworksModel_create(&dnn_model_->model_);
const auto ret = nnapi_->ANeuralNetworksModel_create(&dnn_model_->model_);
if (ret == ANEURALNETWORKS_OUT_OF_MEMORY) {
throw std::bad_alloc();
}
}

void ModelBuilder::SetMemory(int fd, size_t size, size_t offset) {
ANeuralNetworksMemory *mem = nullptr;
THROW_ON_ERROR(
ANeuralNetworksMemory_createFromFd(size, PROT_READ, fd, offset, &mem));
THROW_ON_ERROR(nnapi_->ANeuralNetworksMemory_createFromFd(
size, PROT_READ, fd, offset, &mem));
dnn_model_->memory_ = mem;
}

Expand All @@ -938,10 +904,14 @@ ModelBuilder &ModelBuilder::AddOutput(const std::string &name) {
}

ModelBuilder &ModelBuilder::AllowFp16(const bool allowed) {
if (GetAndroidSdkVersion() >= __ANDROID_API_P__) {
ANeuralNetworksModel_relaxComputationFloat32toFloat16(
if (nnapi_->ANeuralNetworksModel_relaxComputationFloat32toFloat16 !=
nullptr) {
nnapi_->ANeuralNetworksModel_relaxComputationFloat32toFloat16(
dnn_model_->model_, allowed);
}
return *this;
}

ModelBuilder::ModelBuilder() : nnapi_(NnApiImplementation()) {
}
} // namespace dnn
2 changes: 1 addition & 1 deletion dnnlibrary/NeuralNetworksWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ OperandType::OperandType(Type type, std::vector<uint32_t> d, float scale,
dimensions = {1};
}
} else {
DNN_ASSERT(!isScalarType(type), typeToStr(type));
DNN_ASSERT(!isScalarType(type), typeToStr(type), " ", dimensions);
}
operandType = {
.type = static_cast<int32_t>(type),
Expand Down
2 changes: 1 addition & 1 deletion dnnlibrary/nnapi_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#include <string>

#include <dnnlibrary/NeuralNetworksWrapper.h>
#include <dnnlibrary/NeuralNetworksTypes.h>

#define THROW_ON_ERROR(val) \
{ \
Expand Down
Loading

0 comments on commit 4168162

Please sign in to comment.