#include <OperationsUtils.h>
+#include <NeuralNetworks.h>
+
#include <arm_compute/core/TensorShape.h>
#include <arm_compute/core/TensorInfo.h>
#include "../IO_accessor.h"
CLUniqueTensor bias(arm_compute::TensorInfo(bias_shape, arm_compute::Format::F32));
CLUniqueTensor filter(arm_compute::TensorInfo(filter_shape, arm_compute::Format::F32));
- arm_compute::CLConvolutionLayer conv_f;
- conv_f.configure(input.ptr(), filter.ptr(), bias.ptr(), output.ptr(), conv_info);
+ assert(activation == ANEURALNETWORKS_FUSED_NONE || activation == ANEURALNETWORKS_FUSED_RELU);
+
+ std::vector<std::shared_ptr<arm_compute::IFunction>> fns;
+
+ auto conv_f = std::make_shared<arm_compute::CLConvolutionLayer>();
+
+ conv_f->configure(input.ptr(), filter.ptr(), bias.ptr(), output.ptr(), conv_info);
+
+ fns.emplace_back(conv_f);
+
+ if (ANEURALNETWORKS_FUSED_RELU == activation)
+ {
+ auto relu_f = std::make_shared<arm_compute::CLActivationLayer>();
+
+ const arm_compute::ActivationLayerInfo relu_info{arm_compute::ActivationLayerInfo::ActivationFunction::RELU};
+
+ // Do in-place update
+ relu_f->configure(output.ptr(), nullptr, relu_info);
+
+ fns.emplace_back(relu_f);
+ }
input.allocate();
output.allocate();
TensorAccess<BiasAccessor>(bias.ref(), biasData, biasShape);
TensorAccess<WeightAccessor>(filter.ref(), filterData, filterShape);
- conv_f.run();
+ for (const auto &fn : fns)
+ {
+ fn->run();
+ }
arm_compute::CLScheduler::get().sync();
EXPECT_EQ(bret, true);
}
+TEST(KernelACL_TC, convFloat32_3x3to3x3_RELU)
+{
+ float inputData[9];
+ const android::nn::Shape inputShape = { OperandType::FLOAT32, {1,3,3,1}, 1.0, 0 };
+ float filterData[9];
+ const android::nn::Shape filterShape = { OperandType::FLOAT32, {1,3,3,1}, 1.0, 0 };
+ float biasData[1] = { -5.0f };
+ const android::nn::Shape biasShape = { OperandType::FLOAT32, {1}, 1.0, 0 };
+ int32_t padding_left = 1;
+ int32_t padding_right = 1;
+ int32_t padding_top = 1;
+ int32_t padding_bottom = 1;
+ int32_t stride_width = 1;
+ int32_t stride_height = 1;
+ int32_t activation = static_cast<int32_t>(FusedActivationFunc::RELU);
+ float outputData[9];
+ const android::nn::Shape outputShape = { OperandType::FLOAT32, {1,3,3,1}, 1.0, 0 };
+ bool bret;
+
+ util::initData(inputData, sizeof(inputData) / sizeof(inputData[0]), 1.0);
+ util::initData(filterData, sizeof(filterData) / sizeof(filterData[0]), 1.0);
+ util::initData(outputData, sizeof(outputData) / sizeof(outputData[0]), 0.0);
+
+ bret = convFloat32(inputData, inputShape,
+ filterData, filterShape,
+ biasData, biasShape,
+ padding_left, padding_right,
+ padding_top, padding_bottom,
+ stride_width, stride_height,
+ activation,
+ outputData, outputShape);
+ EXPECT_EQ(bret, true);
+
+ float expectData[] =
+ {
+ 0.0f, 1.0f, 0.0f,
+ 1.0f, 4.0f, 1.0f,
+ 0.0f, 1.0f, 0.0f
+ };
+
+ bret = util::compareData(outputData, expectData, outputShape);
+ EXPECT_EQ(bret, true);
+}
+
TEST(KernelACL_TC, convFloat32_3x5to3x3)
{
float inputData[15] = {