ANN_OPERATION(MAX_POOL_2D, ANEURALNETWORKS_MAX_POOL_2D)
ANN_OPERATION(AVG_POOL_2D, ANEURALNETWORKS_AVERAGE_POOL_2D)
ANN_OPERATION(RELU, ANEURALNETWORKS_RELU)
+ANN_OPERATION(RELU6, ANEURALNETWORKS_RELU6)
ANN_OPERATION(PAD, ANEURALNETWORKS_PAD)
coco::FeatureObject *_ofm;
};
+class ANNReLU6Appender final : public ANNOpAppender
+{
+public:
+ void ifm(coco::FeatureObject *ifm) { _ifm = ifm; }
+ void ofm(coco::FeatureObject *ofm) { _ofm = ofm; }
+
+public:
+ void append(ANNBinder *binder) const override
+ {
+ auto ifm = binder->addOperand<float>(_ifm);
+ auto ofm = binder->addOperand<float>(_ofm);
+
+ binder->addOperation(ann::Operation::Code::RELU6, {ifm}, {ofm});
+ }
+
+private:
+ coco::FeatureObject *_ifm;
+ coco::FeatureObject *_ofm;
+};
+
class ANNMaxPool2DAppender final : public ANNOpAppender
{
public:
return std::move(app);
}
}
+ else if (auto relu6 = eval->op()->asReLU6())
+ {
+ if (auto load = relu->arg()->asLoad())
+ {
+ // Let's compile the following code fragment:
+ //
+ // %ofm = eval(ReLU6(Load(%ifm))
+ //
+ // TODO Support objects of other kinds, such as Tensor
+ auto ifm = load->object()->asFeature();
+ auto ofm = eval->out()->asFeature();
+
+ assert(ifm != nullptr && ofm != nullptr);
+
+ auto app = make_unique<ANNReLUAppender>();
+
+ app->ifm(ifm);
+ app->ofm(ofm);
+
+ return std::move(app);
+ }
+ }
// Return nullptr if a given Eval instruction is incompatible
return nullptr;