Path: blob/master/modules/gapi/test/gapi_basic_hetero_tests.cpp
16337 views
// This file is part of OpenCV project.1// It is subject to the license terms in the LICENSE file found in the top-level directory2// of this distribution and at http://opencv.org/license.html.3//4// Copyright (C) 2018 Intel Corporation567#include "test_precomp.hpp"8#include "gapi_mock_kernels.hpp"910#include "opencv2/gapi/fluid/gfluidkernel.hpp"1112namespace opencv_test13{1415namespace16{17GAPI_OCV_KERNEL(OCVFoo, I::Foo)18{19static void run(const cv::Mat &in, cv::Mat &out)20{21out = in + 2;22}23};2425GAPI_OCV_KERNEL(OCVBar, I::Bar)26{27static void run(const cv::Mat &a, const cv::Mat &b, cv::Mat &out)28{29out = 4*(a + b);30}31};3233void FluidFooRow(const uint8_t* in, uint8_t* out, int length)34{35for (int i = 0; i < length; i++)36{37out[i] = in[i] + 3;38}39}4041void FluidBarRow(const uint8_t* in1, const uint8_t* in2, uint8_t* out, int length)42{43for (int i = 0; i < length; i++)44{45out[i] = 3*(in1[i] + in2[i]);46}47}4849GAPI_FLUID_KERNEL(FFoo, I::Foo, false)50{51static const int Window = 1;5253static void run(const cv::gapi::fluid::View &in,54cv::gapi::fluid::Buffer &out)55{56FluidFooRow(in.InLineB(0), out.OutLineB(), in.length());57}58};5960GAPI_FLUID_KERNEL(FBar, I::Bar, false)61{62static const int Window = 1;6364static void run(const cv::gapi::fluid::View &in1,65const cv::gapi::fluid::View &in2,66cv::gapi::fluid::Buffer &out)67{68FluidBarRow(in1.InLineB(0), in2.InLineB(0), out.OutLineB(), in1.length());69}70};7172G_TYPED_KERNEL(FluidFooI, <cv::GMat(cv::GMat)>, "test.kernels.fluid_foo")73{74static cv::GMatDesc outMeta(const cv::GMatDesc &in) { return in; }75};7677G_TYPED_KERNEL(FluidBarI, <cv::GMat(cv::GMat,cv::GMat)>, "test.kernels.fluid_bar")78{79static cv::GMatDesc outMeta(const cv::GMatDesc &in, const cv::GMatDesc &) { return in; }80};8182GAPI_FLUID_KERNEL(FluidFoo, FluidFooI, false)83{84static const int Window = 1;8586static void run(const cv::gapi::fluid::View &in,87cv::gapi::fluid::Buffer &out)88{89FluidFooRow(in.InLineB(0), out.OutLineB(), in.length());90}91};9293GAPI_FLUID_KERNEL(FluidBar, FluidBarI, false)94{95static const int Window = 1;9697static void run(const cv::gapi::fluid::View &in1,98const cv::gapi::fluid::View &in2,99cv::gapi::fluid::Buffer &out)100{101FluidBarRow(in1.InLineB(0), in2.InLineB(0), out.OutLineB(), in1.length());102}103};104105GAPI_FLUID_KERNEL(FluidFoo2lpi, FluidFooI, false)106{107static const int Window = 1;108static const int LPI = 2;109110static void run(const cv::gapi::fluid::View &in,111cv::gapi::fluid::Buffer &out)112{113for (int l = 0; l < out.lpi(); l++)114{115FluidFooRow(in.InLineB(l), out.OutLineB(l), in.length());116}117}118};119120cv::Mat ocvFoo(const cv::Mat &in)121{122cv::Mat out;123OCVFoo::run(in, out);124return out;125}126cv::Mat ocvBar(const cv::Mat &in1, const cv::Mat &in2)127{128cv::Mat out;129OCVBar::run(in1, in2, out);130return out;131}132cv::Mat fluidFoo(const cv::Mat &in)133{134cv::Mat out(in.rows, in.cols, in.type());135for (int y = 0; y < in.rows; y++)136{137FluidFooRow(in.ptr(y), out.ptr(y), in.cols);138}139return out;140}141cv::Mat fluidBar(const cv::Mat &in1, const cv::Mat &in2)142{143cv::Mat out(in1.rows, in1.cols, in1.type());144for (int y = 0; y < in1.rows; y++)145{146FluidBarRow(in1.ptr(y), in2.ptr(y), out.ptr(y), in1.cols);147}148return out;149}150} // anonymous namespace151152struct GAPIHeteroTest: public ::testing::Test153{154cv::GComputation m_comp;155cv::gapi::GKernelPackage m_ocv_kernels;156cv::gapi::GKernelPackage m_fluid_kernels;157cv::gapi::GKernelPackage m_hetero_kernels;158159cv::Mat m_in_mat;160cv::Mat m_out_mat;161162GAPIHeteroTest();163};164165GAPIHeteroTest::GAPIHeteroTest()166: m_comp([](){167cv::GMat in;168cv::GMat out = I::Bar::on(I::Foo::on(in),169I::Foo::on(in));170return cv::GComputation(in, out);171})172, m_ocv_kernels(cv::gapi::kernels<OCVFoo, OCVBar>())173, m_fluid_kernels(cv::gapi::kernels<FFoo, FBar>())174, m_hetero_kernels(cv::gapi::kernels<OCVFoo, FBar>())175, m_in_mat(cv::Mat::eye(cv::Size(64, 64), CV_8UC1))176{177}178179TEST_F(GAPIHeteroTest, TestOCV)180{181EXPECT_TRUE(cv::gapi::cpu::backend() == m_ocv_kernels.lookup<I::Foo>());182EXPECT_TRUE(cv::gapi::cpu::backend() == m_ocv_kernels.lookup<I::Bar>());183184cv::Mat ref = ocvBar(ocvFoo(m_in_mat), ocvFoo(m_in_mat));185EXPECT_NO_THROW(m_comp.apply(m_in_mat, m_out_mat, cv::compile_args(m_ocv_kernels)));186EXPECT_EQ(0, cv::countNonZero(ref != m_out_mat));187}188189TEST_F(GAPIHeteroTest, TestFluid)190{191EXPECT_TRUE(cv::gapi::fluid::backend() == m_fluid_kernels.lookup<I::Foo>());192EXPECT_TRUE(cv::gapi::fluid::backend() == m_fluid_kernels.lookup<I::Bar>());193194cv::Mat ref = fluidBar(fluidFoo(m_in_mat), fluidFoo(m_in_mat));195EXPECT_NO_THROW(m_comp.apply(m_in_mat, m_out_mat, cv::compile_args(m_fluid_kernels)));196EXPECT_EQ(0, cv::countNonZero(ref != m_out_mat));197}198199TEST_F(GAPIHeteroTest, TestBoth)200{201EXPECT_TRUE(cv::gapi::cpu::backend() == m_hetero_kernels.lookup<I::Foo>());202EXPECT_TRUE(cv::gapi::fluid::backend() == m_hetero_kernels.lookup<I::Bar>());203204cv::Mat ref = fluidBar(ocvFoo(m_in_mat), ocvFoo(m_in_mat));205EXPECT_NO_THROW(m_comp.apply(m_in_mat, m_out_mat, cv::compile_args(m_hetero_kernels)));206EXPECT_EQ(0, cv::countNonZero(ref != m_out_mat));207}208209struct GAPIBigHeteroTest : public ::testing::TestWithParam<std::array<int, 9>>210{211cv::GComputation m_comp;212cv::gapi::GKernelPackage m_kernels;213214cv::Mat m_in_mat;215cv::Mat m_out_mat1;216cv::Mat m_out_mat2;217218cv::Mat m_ref_mat1;219cv::Mat m_ref_mat2;220221GAPIBigHeteroTest();222};223224// Foo7225// .-> Foo2 -> Foo3 -<226// Foo0 -> Foo1 Bar -> Foo6227// `-> Foo4 -> Foo5 -`228229GAPIBigHeteroTest::GAPIBigHeteroTest()230: m_comp([&](){231auto flags = GetParam();232std::array<std::function<cv::GMat(cv::GMat)>, 8> foos;233234for (int i = 0; i < 8; i++)235{236foos[i] = flags[i] ? &I::Foo::on : &FluidFooI::on;237}238auto bar = flags[8] ? &I::Bar::on : &FluidBarI::on;239240cv::GMat in;241auto foo1Out = foos[1](foos[0](in));242auto foo3Out = foos[3](foos[2](foo1Out));243auto foo6Out = foos[6](bar(foo3Out,244foos[5](foos[4](foo1Out))));245auto foo7Out = foos[7](foo3Out);246247return cv::GComputation(GIn(in), GOut(foo6Out, foo7Out));248})249, m_kernels(cv::gapi::kernels<OCVFoo, OCVBar, FluidFoo, FluidBar>())250, m_in_mat(cv::Mat::eye(cv::Size(64, 64), CV_8UC1))251{252auto flags = GetParam();253std::array<std::function<cv::Mat(cv::Mat)>, 8> foos;254255for (int i = 0; i < 8; i++)256{257foos[i] = flags[i] ? ocvFoo : fluidFoo;258}259auto bar = flags[8] ? ocvBar : fluidBar;260261cv::Mat foo1OutMat = foos[1](foos[0](m_in_mat));262cv::Mat foo3OutMat = foos[3](foos[2](foo1OutMat));263264m_ref_mat1 = foos[6](bar(foo3OutMat,265foos[5](foos[4](foo1OutMat))));266267m_ref_mat2 = foos[7](foo3OutMat);268}269270TEST_P(GAPIBigHeteroTest, Test)271{272EXPECT_NO_THROW(m_comp.apply(gin(m_in_mat), gout(m_out_mat1, m_out_mat2), cv::compile_args(m_kernels)));273EXPECT_EQ(0, cv::countNonZero(m_ref_mat1 != m_out_mat1));274EXPECT_EQ(0, cv::countNonZero(m_ref_mat2 != m_out_mat2));275}276277static auto configurations = []()278{279// Fill all possible configurations280// from 000000000 to 111111111281std::array<std::array<int, 9>, 512> arr;282for (auto n = 0; n < 512; n++)283{284for (auto i = 0; i < 9; i++)285{286arr[n][i] = (n >> (8 - i)) & 1;287}288}289return arr;290}();291292INSTANTIATE_TEST_CASE_P(GAPIBigHeteroTest, GAPIBigHeteroTest,293::testing::ValuesIn(configurations));294295TEST(GAPIHeteroTestLPI, Test)296{297cv::GMat in;298auto mid = FluidFooI::on(in);299auto out = FluidFooI::on(mid);300cv::gapi::island("isl0", GIn(in), GOut(mid));301cv::gapi::island("isl1", GIn(mid), GOut(out));302cv::GComputation c(in, out);303304cv::Mat in_mat = cv::Mat::eye(cv::Size(64, 64), CV_8UC1);305cv::Mat out_mat;306EXPECT_NO_THROW(c.apply(in_mat, out_mat, cv::compile_args(cv::gapi::kernels<FluidFoo2lpi>())));307cv::Mat ref = fluidFoo(fluidFoo(in_mat));308EXPECT_EQ(0, cv::countNonZero(ref != out_mat));309}310311} // namespace opencv_test312313314