/******************************************************************************** * Copyright (c) 2023 CEA-List * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License 2.0 which is available at * http://www.eclipse.org/legal/epl-2.0. * * SPDX-License-Identifier: EPL-2.0 * ********************************************************************************/ #include <catch2/catch_test_macros.hpp> #include <memory> #include "aidge/data/Tensor.hpp" #include "aidge/operator/ReduceMean.hpp" #include "aidge/operator/Conv.hpp" #include "aidge/backend/cpu.hpp" #include "aidge/utils/TensorUtils.hpp" using namespace Aidge; TEST_CASE("[cpu/operator] ReduceMean(forward)", "[ReduceMean][CPU]") { SECTION("KeepDims") { SECTION("test 1") { std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(Array3D<float,3,2,2> { { { { 5.0, 1.0 }, { 20.0, 2.0 } }, { { 30.0, 1.0 }, { 40.0, 2.0 } }, { { 55.0, 1.0 }, { 60.0, 2.0 } } } }); Tensor myOutput = Tensor(Array3D<float,3,1,2> { { {{ 12.5, 1.5 }}, {{ 35.0, 1.5 }}, {{ 57.5, 1.5 }} } }); std::shared_ptr<Node> myReduceMean = ReduceMean({1}, 1); auto op = std::static_pointer_cast<OperatorTensor>(myReduceMean -> getOperator()); op->associateInput(0,myInput); op->setDataType(DataType::Float32); op->setBackend("cpu"); op->computeOutputDims(); myReduceMean->forward(); op->getOutput(0)->print(); REQUIRE(*(op->getOutput(0)) == myOutput); } SECTION("test 2") { std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(Array3D<float,3,3,2> { { { { 0.0, 0.0 }, { 1.0, 1.0 }, { 2.0, 2.0 } }, { { 3.0, 3.0 }, { 4.0, 4.0 }, { 5.0, 5.0 } }, { { 6.0, 6.0 }, { 7.0, 7.0 }, { 8.0, 8.0 } } } }); Tensor myOutput = Tensor(Array3D<float,3,1,1> { { {{ 1.0 }}, {{ 4.0 }}, {{ 7.0 }} } }); std::shared_ptr<Node> myReduceMean = ReduceMean({1, 2}, 1); auto op = std::static_pointer_cast<OperatorTensor>(myReduceMean -> getOperator()); op->associateInput(0,myInput); op->setDataType(DataType::Float32); op->setBackend("cpu"); op->computeOutputDims(); myReduceMean->forward(); myOutput.print(); op->getOutput(0)->print(); REQUIRE(*(op->getOutput(0)) == myOutput); } } SECTION("not_KeepDims") { std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(Array3D<float,3,2,2> { { { { 5.0, 1.0 }, { 20.0, 2.0 } }, { { 30.0, 1.0 }, { 40.0, 2.0 } }, { { 55.0, 1.0 }, { 60.0, 2.0 } } } }); std::shared_ptr<Tensor> myOutput = std::make_shared<Tensor>(Array2D<float,3,2> { { { 12.5, 1.5 }, { 35.0, 1.5 }, { 57.5, 1.5 } } }); std::shared_ptr<Node> myReduceMean = ReduceMean({1}, 0); auto op = std::static_pointer_cast<OperatorTensor>(myReduceMean -> getOperator()); op->associateInput(0,myInput); op->setDataType(DataType::Float32); op->setBackend("cpu"); op->computeOutputDims(); myReduceMean->forward(); op->getOutput(0)->print(); REQUIRE(*(op->getOutput(0)) == *myOutput); } SECTION("all_axes") { SECTION("1") { std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(Array3D<float,3,2,2> { { { { 5.0, 1.0 }, { 20.0, 2.0 } }, { { 30.0, 1.0 }, { 40.0, 2.0 } }, { { 55.0, 1.0 }, { 60.0, 2.0 } } } }); std::shared_ptr<Tensor> myOutput = std::make_shared<Tensor>(Array1D<float,1> { {18.25} }); std::shared_ptr<Node> myReduceMean = ReduceMean({0, 1, 2}, 0); auto op = std::static_pointer_cast<OperatorTensor>(myReduceMean -> getOperator()); op->associateInput(0,myInput); op->setDataType(DataType::Float32); op->setBackend("cpu"); op->computeOutputDims(); myReduceMean->forward(); op->getOutput(0)->print(); REQUIRE(*(op->getOutput(0)) == *myOutput); } SECTION("2") { std::shared_ptr<Tensor> myInput = std::make_shared<Tensor>(Array2D<float,5,4> { {{ 0.004232f, 0.105120f, 0.045124f, 0.009205f}, { 0.000766f, 0.272162f, 0.503560f, 0.044163f}, { 0.049755f, 0.000305f, 0.143634f, 0.013253f}, { 0.096258f, 0.311231f, 0.358143f, 0.000452f}, { 0.468617f, 0.015693f, 0.145316f, 0.000105f}} }); std::shared_ptr<Tensor> myOutput = std::make_shared<Tensor>(Array1D<float,1> { {0.1293547f} }); std::shared_ptr<Node> myReduceMean = ReduceMean({0, 1}, 0); auto op = std::static_pointer_cast<OperatorTensor>(myReduceMean -> getOperator()); op->associateInput(0,myInput); op->setDataType(DataType::Float32); op->setBackend("cpu"); op->computeOutputDims(); myReduceMean->forward(); op->getOutput(0)->print(); // approxEq<float>(*(op->getOutput(0)), *myOutput); REQUIRE(approxEq<float>(*(op->getOutput(0)), *myOutput)); } } }