--- /dev/null
+#include <nnapi.h>
+#include <stdexcept>
+#include <iostream>
+#include <string>
+#include <map>
+#include <cassert>
+#include <boost/format.hpp>
+// ACL Headers
+#include <arm_compute/graph/Graph.h>
+#include <arm_compute/graph/Nodes.h>
+#include <utils/GraphUtils.h>
+#include <utils/Utils.h>
+
+//
+// Asynchronous Event
+//
+struct ANeuralNetworksEvent
+{
+};
+
+ResultCode ANeuralNetworksEvent_wait(ANeuralNetworksEvent* event)
+{
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+ResultCode ANeuralNetworksEvent_free(ANeuralNetworksEvent* event)
+{
+ delete event;
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+//
+// Memory
+//
+struct ANeuralNetworksMemory
+{
+ // 1st approach - Store all the data inside ANeuralNetworksMemory object
+ // 2nd approach - Store metadata only, and defer data loading as much as possible
+};
+
+ResultCode ANeuralNetworksMemory_createFromFd(size_t size, int protect, int fd, size_t offset, ANeuralNetworksMemory** memory)
+{
+ *memory = new ANeuralNetworksMemory;
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+ResultCode ANeuralNetworksMemory_free(ANeuralNetworksMemory* memory)
+{
+ delete memory;
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+//
+// Model
+//
+struct ANeuralNetworksModel
+{
+ // ANeuralNetworksModel should be a factory for Graph IR (a.k.a ISA Frontend)
+ // TODO Record # of operands
+ uint32_t numOperands;
+
+ ANeuralNetworksModel() : numOperands(0)
+ {
+ // DO NOTHING
+ }
+};
+
+ResultCode ANeuralNetworksModel_create(ANeuralNetworksModel** model)
+{
+ *model = new ANeuralNetworksModel;
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+ResultCode ANeuralNetworksModel_free(ANeuralNetworksModel* model)
+{
+ delete model;
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+ResultCode ANeuralNetworksModel_addOperand(ANeuralNetworksModel* model, const ANeuralNetworksOperandType *type)
+{
+ model->numOperands += 1;
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+ResultCode ANeuralNetworksModel_setOperandValue(ANeuralNetworksModel* model, int32_t index, const void* buffer, size_t length)
+{
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+ResultCode ANeuralNetworksModel_setOperandValueFromMemory(ANeuralNetworksModel* model, int32_t index, const ANeuralNetworksMemory* memory, size_t offset, size_t length)
+{
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+ResultCode ANeuralNetworksModel_addOperation(ANeuralNetworksModel* model, ANeuralNetworksOperationType type, uint32_t inputCount, const uint32_t* inputs, uint32_t outputCount, const uint32_t* outputs)
+{
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+ResultCode ANeuralNetworksModel_identifyInputsAndOutputs(ANeuralNetworksModel* model, uint32_t inputCount, const uint32_t* inputs, uint32_t outputCount, const uint32_t* outputs)
+{
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+ResultCode ANeuralNetworksModel_finish(ANeuralNetworksModel* model)
+{
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+//
+// Compilation
+//
+struct ANeuralNetworksCompilation
+{
+ // ANeuralNetworksCompilation should hold a compiled IR
+};
+
+ResultCode ANeuralNetworksCompilation_create(ANeuralNetworksModel* model, ANeuralNetworksCompilation** compilation)
+{
+ *compilation = new ANeuralNetworksCompilation;
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+ResultCode ANeuralNetworksCompilation_finish(ANeuralNetworksCompilation* compilation)
+{
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+//
+// Execution
+//
+struct ANeuralNetworksExecution
+{
+ // ANeuralNetworksExecution corresponds to NPU::Interp::Session
+
+ arm_compute::graph::Graph graph;
+};
+
+ResultCode ANeuralNetworksExecution_create(ANeuralNetworksCompilation* compilation, ANeuralNetworksExecution** execution)
+{
+ std::cout << __FUNCTION__ << " +++" << std::endl;
+ *execution = new ANeuralNetworksExecution;
+
+ using arm_compute::DataType;
+ using arm_compute::graph::Tensor;
+ using arm_compute::graph::TargetHint;
+ using arm_compute::graph::Graph;
+ using arm_compute::TensorInfo;
+ using arm_compute::TensorShape;
+
+ ANeuralNetworksExecution* execlocal = *execution;
+ arm_compute::graph::Graph& graph = execlocal->graph;
+
+ TargetHint target_hint;
+ std::string image;
+ std::string label;
+ std::string data_path;
+ std::string weight_path;
+ std::string bias_path;
+ constexpr float mean_r = 1.0f; // Mean value to subtract from red channel
+ constexpr float mean_g = 1.0f; // Mean value to subtract from green channel
+ constexpr float mean_b = 1.0f; // Mean value to subtract from blue channel
+
+ // 0 = NEON, 1 = OpenCL
+ // arm_compute::graph_utils can't be used with 'using'
+ // TODO: set NEON/OpenCL hint by Environment variable
+ target_hint = arm_compute::graph_utils::set_target_hint(1);
+
+ graph << target_hint
+ << Tensor(TensorInfo(TensorShape(3U, 3U, 1U, 1U), 1, DataType::F32),
+ arm_compute::graph_utils::get_input_accessor(image, mean_r, mean_g, mean_b))
+ << arm_compute::graph::ConvolutionLayer(
+ 3U, 3U, 1U,
+ arm_compute::graph_utils::get_weights_accessor(data_path, weight_path),
+ arm_compute::graph_utils::get_weights_accessor(data_path, bias_path),
+ arm_compute::PadStrideInfo(1, 1, 1, 1))
+ << Tensor(arm_compute::graph_utils::get_output_accessor(label, 1));
+ ;
+
+ std::cout << __FUNCTION__ << " ---" << std::endl;
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+// ANeuralNetworksExecution_setInput and ANeuralNetworksExecution_setOutput specify HOST buffer for input/output
+ResultCode ANeuralNetworksExecution_setInput(ANeuralNetworksExecution* execution, int32_t index, const ANeuralNetworksOperandType* type, const void* buffer, size_t length)
+{
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+ResultCode ANeuralNetworksExecution_setOutput(ANeuralNetworksExecution* execution, int32_t index, const ANeuralNetworksOperandType* type, const void* buffer, size_t length)
+{
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+ResultCode ANeuralNetworksExecution_startCompute(ANeuralNetworksExecution* execution, ANeuralNetworksEvent** event)
+{
+ std::cout << __FUNCTION__ << " +++" << std::endl;
+ *event = new ANeuralNetworksEvent;
+
+ // graph.run() fails with segment fail when only target_hint is added.
+ // after fix adding 'Tensor' we may call graph.run()
+ arm_compute::graph::Graph& graph = execution->graph;
+ graph.run();
+
+ std::cout << __FUNCTION__ << " ---" << std::endl;
+ return ANEURALNETWORKS_NO_ERROR;
+}
+
+ResultCode ANeuralNetworksExecution_free(ANeuralNetworksExecution* execution)
+{
+ delete execution;
+ return ANEURALNETWORKS_NO_ERROR;
+}