Skip to content

Commit

Permalink
Update dnn_retrieve_result to receive multiple inputs, update
Browse files Browse the repository at this point in the history
Model.h/.cpp
  • Loading branch information
daquexian committed May 13, 2019
1 parent 469bd79 commit 3191182
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 44 deletions.
49 changes: 28 additions & 21 deletions binaries/dnn_retrieve_result.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ int main(int argc, char **argv) {
string outputBlob = argv[2];
bool quant_input = std::atoi(argv[3]) != 0;
bool quant_output = std::atoi(argv[4]) != 0;
bool use_external_input = argc == 6;
bool use_external_input = argc >= 6;

std::unique_ptr<Model> model;
{
Expand All @@ -47,22 +47,29 @@ int main(int argc, char **argv) {
model = builder.AddOutput(outputBlob)
.Compile(ANEURALNETWORKS_PREFER_SUSTAINED_SPEED);
}
const auto inputLen = model->GetInputSize(0),
outputLen = model->GetOutputSize(0);
float data[inputLen];
if (use_external_input) {
std::ifstream ifs(argv[5]);
float element;
FORZ(i, inputLen) {
if (!(ifs >> element)) {
throw std::invalid_argument("Read file error");
DNN_ASSERT(model->GetOutputs().size() == 1, "the number of outputs can only be 1 here");
const auto outputLen = model->GetSize(model->GetOutputs()[0]);
std::vector<std::vector<float>> inputs;
for (int i = 5, n = 0; i < argc; i++, n++) {
const auto &input_name = model->GetInputs()[n];
const auto input_size = model->GetSize(input_name);
std::vector<float> input_data;
input_data.reserve(input_size);
if (use_external_input) {
std::ifstream ifs(argv[i]);
float element;
FORZ(i, model->GetSize(input_name)) {
if (!(ifs >> element)) {
throw std::invalid_argument("Read file error");
}
input_data.push_back(element);
}
} else {
FORZ(j, input_size) {
input_data.push_back(j);
}
data[i] = element;
}
} else {
FORZ(i, inputLen) {
data[i] = i;
}
inputs.push_back(input_data);
}

uint8_t output_uint8[outputLen];
Expand All @@ -74,14 +81,14 @@ int main(int argc, char **argv) {
model->SetOutputBuffer(0, output_float);
}
if (quant_input) {
uint8_t uint8_data[inputLen];
FORZ(i, inputLen) {
uint8_data[i] = data[i];
std::vector<std::vector<uint8_t>> uint8_inputs;
for (const auto &input : inputs) {
std::vector<uint8_t> uint8_input(input.begin(), input.end());
uint8_inputs.push_back(uint8_input);
}
model->Predict(std::vector{uint8_data});
model->Predict(uint8_inputs);
} else {
model->Predict(std::vector{data});
std::ofstream ofs("/data/local/tmp/result");
model->Predict(inputs);
}
std::ofstream ofs("/data/local/tmp/result");
if (quant_output) {
Expand Down
46 changes: 27 additions & 19 deletions dnnlibrary/include/Model.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,32 +36,40 @@ class Model {
void SetInputBuffer(const int32_t index, const uint8_t *buffer);
void SetInputBuffer(const int32_t index, const void *buffer, const size_t elemsize);
void PrepareForExecution();
void PredictAfterSetInputBuffer();
bool prepared_for_exe_;
Model() = default;

public:
template <typename T>
void Predict(std::vector<T *> inputs) {
void Predict(const std::vector<T> &input) {
DNN_ASSERT_EQ(input.size, GetSize(GetInputs()[0]));
// const_cast is a ugly workaround, vector<const T*> causes strange errors
Predict<T>({const_cast<T *>(input.data())});
}
template <typename T>
void Predict(const std::vector<std::vector<T>> &inputs) {
std::vector<T *> input_ptrs;
for (size_t i = 0; i < inputs.size(); i++) {
auto &input = inputs[i];
DNN_ASSERT_EQ(input.size(), GetSize(GetInputs()[i]));
// const_cast is a ugly workaround, vector<const T*> causes strange errors
input_ptrs.push_back(const_cast<T *>(input.data()));
}
Predict<T>(input_ptrs);
}
template <typename T>
void Predict(const T *input) {
Predict<T>(std::vector<T*>{input});
}
template <typename T>
void Predict(const std::vector<T *> &inputs) {
DNN_ASSERT_EQ(inputs.size(), GetInputs().size());
if (!prepared_for_exe_) PrepareForExecution();
for (size_t i = 0; i < inputs.size(); i++) {
SetInputBuffer(i, inputs[i]);
}
ANeuralNetworksEvent *event = nullptr;
if (int ret = ANeuralNetworksExecution_startCompute(execution_, &event);
ret != ANEURALNETWORKS_NO_ERROR) {
throw std::invalid_argument(
"Error in startCompute, return value: " + std::to_string(ret));
}

if (int ret = ANeuralNetworksEvent_wait(event);
ret != ANEURALNETWORKS_NO_ERROR) {
throw std::invalid_argument("Error in wait, return value: " +
std::to_string(ret));
}

ANeuralNetworksEvent_free(event);
ANeuralNetworksExecution_free(execution_);
prepared_for_exe_ = false;
PredictAfterSetInputBuffer();
}

~Model();
Expand All @@ -70,8 +78,8 @@ class Model {
void SetOutputBuffer(const int32_t index, char *buffer);
void SetOutputBuffer(const int32_t index, void *buffer, const size_t elemsize);
size_t GetSize(const std::string &name);
size_t GetInputSize(const int &index);
size_t GetOutputSize(const int &index);
std::vector<std::string> GetInputs();
std::vector<std::string> GetOutputs();
};

#endif // NNAPIEXAMPLE_MODEL_H
28 changes: 24 additions & 4 deletions dnnlibrary/src/Model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,25 @@ void Model::SetOutputBuffer(const int32_t index, void *buffer, const size_t elem
}
}

void Model::PredictAfterSetInputBuffer() {
ANeuralNetworksEvent *event = nullptr;
if (int ret = ANeuralNetworksExecution_startCompute(execution_, &event);
ret != ANEURALNETWORKS_NO_ERROR) {
throw std::invalid_argument(
"Error in startCompute, return value: " + std::to_string(ret));
}

if (int ret = ANeuralNetworksEvent_wait(event);
ret != ANEURALNETWORKS_NO_ERROR) {
throw std::invalid_argument("Error in wait, return value: " +
std::to_string(ret));
}

ANeuralNetworksEvent_free(event);
ANeuralNetworksExecution_free(execution_);
prepared_for_exe_ = false;
}

void Model::AddInput(const std::string &name, const Shaper::Shape &shape) {
input_names_.push_back(name);
shaper_.AddShape(name, shape);
Expand All @@ -89,10 +108,11 @@ size_t Model::GetSize(const std::string &name) {
return shaper_.GetSize(name);
}

size_t Model::GetInputSize(const int &index) {
return shaper_.GetSize(input_names_[index]);
std::vector<std::string> Model::GetInputs() {
return input_names_;
}

size_t Model::GetOutputSize(const int &index) {
return shaper_.GetSize(output_names_[index]);
std::vector<std::string> Model::GetOutputs() {
return output_names_;
}

0 comments on commit 3191182

Please sign in to comment.