Open Source Computer Vision Library https://opencv.org/
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

655 lines
29 KiB

// This file is part of OpenCV project.
// It is subject to the license terms in the LICENSE file found in the top-level directory
// of this distribution and at http://opencv.org/license.html.
//
// Copyright (C) 2018 Intel Corporation
#include "../test_precomp.hpp"
#include "compiler/gmodel.hpp"
#include "compiler/gcompiled_priv.hpp"
#include "compiler/gmodel_priv.hpp"
namespace opencv_test
{
////////////////////////////////////////////////////////////////////////////////
// Tests on a plain graph
//
// (in) -> Blur1 -> (tmp0) -> Blur2 -> (tmp1) -> Blur3 -> (tmp2) -> Blur4 -> (out)
//
namespace
{
struct PlainIslandsFixture
{
cv::GMat in;
cv::GMat tmp[3];
cv::GMat out;
PlainIslandsFixture()
{
tmp[0] = cv::gapi::boxFilter(in, -1, cv::Size(3,3));
tmp[1] = cv::gapi::boxFilter(tmp[0], -1, cv::Size(3,3));
tmp[2] = cv::gapi::boxFilter(tmp[1], -1, cv::Size(3,3));
out = cv::gapi::boxFilter(tmp[2], -1, cv::Size(3,3));
}
};
struct Islands: public ::testing::Test, public PlainIslandsFixture {};
using GIntArray = GArray<int>;
G_TYPED_KERNEL(CreateMatWithDiag, <GMat(GIntArray)>, "test.array.create_mat_with_diag")
{
static GMatDesc outMeta(const GArrayDesc&) { return cv::GMatDesc{CV_32S, 1,{3, 3}}; }
};
GAPI_OCV_KERNEL(CreateMatWithDiagImpl, CreateMatWithDiag)
{
static void run(const std::vector<int> &in, cv::Mat& out)
{
auto size = static_cast<int>(in.size());
out = Mat::zeros(size, size, CV_32SC1);
for(int i = 0; i < out.rows; i++)
{
auto* row = out.ptr<int>(i);
row[i] = in[i];
}
}
};
G_TYPED_KERNEL(Mat2Array, <GIntArray(GMat)>, "test.array.mat2array")
{
static GArrayDesc outMeta(const GMatDesc&) { return empty_array_desc(); }
};
GAPI_OCV_KERNEL(Mat2ArrayImpl, Mat2Array)
{
static void run(const cv::Mat& in, std::vector<int> &out)
{
GAPI_Assert(in.depth() == CV_32S && in.isContinuous());
out.reserve(in.cols * in.rows);
out.assign((int*)in.datastart, (int*)in.dataend);
}
};
}
TEST_F(Islands, SmokeTest)
{
// (in) -> Blur1 -> (tmp0) -> Blur2 -> (tmp1) -> Blur3 -> (tmp2) -> Blur4 -> (out)
// : "test" :
// :<------------------------->:
cv::gapi::island("test", cv::GIn(tmp[0]), cv::GOut(tmp[2]));
auto cc = cv::GComputation(in, out).compile(cv::GMatDesc{CV_8U,1,{640,480}});
const auto &gm = cc.priv().model();
const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
// tmp1 and tmp3 is not a part of any island
EXPECT_FALSE(gm.metadata(tmp0_nh).contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(tmp2_nh).contains<cv::gimpl::Island>());
// tmp2 is part of "test" island
EXPECT_TRUE(gm.metadata(tmp1_nh).contains<cv::gimpl::Island>());
EXPECT_EQ("test", gm.metadata(tmp1_nh).get<cv::gimpl::Island>().island);
}
TEST_F(Islands, TwoIslands)
{
// (in) -> Blur1 -> (tmp0) -> Blur2 -> (tmp1) -> Blur3 -> (tmp2) -> Blur4 -> (out)
// : "test1" : : "test2" :
// :<---------------------------->: :<--------------------------------->
EXPECT_NO_THROW(cv::gapi::island("test1", cv::GIn(in), cv::GOut(tmp[1])));
EXPECT_NO_THROW(cv::gapi::island("test2", cv::GIn(tmp[1]), cv::GOut(out)));
auto cc = cv::GComputation(in, out).compile(cv::GMatDesc{CV_8U,1,{640,480}});
const auto &gm = cc.priv().model();
const auto in_nh = cv::gimpl::GModel::dataNodeOf(gm, in);
const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
const auto out_nh = cv::gimpl::GModel::dataNodeOf(gm, out);
// Only tmp0 and tmp2 should be listed in islands.
EXPECT_TRUE (gm.metadata(tmp0_nh).contains<cv::gimpl::Island>());
EXPECT_TRUE (gm.metadata(tmp2_nh).contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(in_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(tmp1_nh).contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(out_nh) .contains<cv::gimpl::Island>());
EXPECT_EQ("test1", gm.metadata(tmp0_nh).get<cv::gimpl::Island>().island);
EXPECT_EQ("test2", gm.metadata(tmp2_nh).get<cv::gimpl::Island>().island);
}
// FIXME: Disabled since currently merge procedure merges two into one
6 years ago
// successfully
TEST_F(Islands, DISABLED_Two_Islands_With_Same_Name_Should_Fail)
{
// (in) -> Blur1 -> (tmp0) -> Blur2 -> (tmp1) -> Blur3 -> (tmp2) -> Blur4 -> (out)
// : "test1" : : "test1" :
// :<---------------------------->: :<--------------------------------->
EXPECT_NO_THROW(cv::gapi::island("test1", cv::GIn(in), cv::GOut(tmp[1])));
EXPECT_NO_THROW(cv::gapi::island("test1", cv::GIn(tmp[1]), cv::GOut(out)));
EXPECT_ANY_THROW(cv::GComputation(in, out).compile(cv::GMatDesc{CV_8U,1,{640,480}}));
}
// (in) -> Blur1 -> (tmp0) -> Blur2 -> (tmp1) -> Blur3 -> (tmp2) -> Blur4 -> (out)
// : "test1": : :
// :<----------------:----------->: :
// : :
// : "test2" :
// :<------------------------->:
TEST_F(Islands, OverlappingIslands1)
{
EXPECT_NO_THROW (cv::gapi::island("test1", cv::GIn(in), cv::GOut(tmp[1])));
EXPECT_ANY_THROW(cv::gapi::island("test2", cv::GIn(tmp[0]), cv::GOut(tmp[2])));
}
TEST_F(Islands, OverlappingIslands2)
{
EXPECT_NO_THROW (cv::gapi::island("test2", cv::GIn(tmp[0]), cv::GOut(tmp[2])));
EXPECT_ANY_THROW(cv::gapi::island("test1", cv::GIn(in), cv::GOut(tmp[1])));
}
////////////////////////////////////////////////////////////////////////////////
// Tests on a complex graph
//
// (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0)
// ^ ^
// (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----'
// :
// `------------> Median -> (tmp3) --> Blur -------> (out1)
//
namespace
{
struct ComplexIslandsFixture
{
cv::GMat in[2];
cv::GMat tmp[4];
cv::GScalar scl;
cv::GMat out[2];
ComplexIslandsFixture()
{
tmp[0] = cv::gapi::bitwise_not(in[0]);
tmp[1] = cv::gapi::boxFilter(in[1], -1, cv::Size(3,3));
tmp[2] = tmp[0] + tmp[1]; // FIXME: handle tmp[2] = tmp[0]+tmp[2] typo
scl = cv::gapi::sum(tmp[1]);
tmp[3] = cv::gapi::medianBlur(tmp[1], 3);
out[0] = tmp[2] + scl;
out[1] = cv::gapi::boxFilter(tmp[3], -1, cv::Size(3,3));
}
};
struct ComplexIslands: public ::testing::Test, public ComplexIslandsFixture {};
} // namespace
TEST_F(ComplexIslands, SmokeTest)
{
// isl0 #internal1
// ........................... ........
// (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0)
// :............ ........^...: :.^....:
// ... : :
// (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----'
// : isl1
// : ..............................
// `------------> Median -> (tmp3) --> Blur -------> (out1)
// :............................:
cv::gapi::island("isl0", cv::GIn(in[0], tmp[1]), cv::GOut(tmp[2]));
cv::gapi::island("isl1", cv::GIn(tmp[1]), cv::GOut(out[1]));
auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]))
.compile(cv::GMatDesc{CV_8U,1,{640,480}},
cv::GMatDesc{CV_8U,1,{640,480}});
const auto &gm = cc.priv().model();
const auto in0_nh = cv::gimpl::GModel::dataNodeOf(gm, in[0]);
const auto in1_nh = cv::gimpl::GModel::dataNodeOf(gm, in[1]);
const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[3]);
const auto scl_nh = cv::gimpl::GModel::dataNodeOf(gm, scl);
const auto out0_nh = cv::gimpl::GModel::dataNodeOf(gm, out[0]);
const auto out1_nh = cv::gimpl::GModel::dataNodeOf(gm, out[1]);
// tmp0, tmp3 are in islands, others are not
EXPECT_TRUE(gm.metadata(tmp0_nh) .contains<cv::gimpl::Island>()); // isl0
EXPECT_TRUE(gm.metadata(tmp3_nh) .contains<cv::gimpl::Island>()); // isl1
EXPECT_FALSE(gm.metadata(in0_nh) .contains<cv::gimpl::Island>()); // (input is never fused)
EXPECT_FALSE(gm.metadata(in1_nh) .contains<cv::gimpl::Island>()); // (input is never fused)
EXPECT_TRUE (gm.metadata(tmp1_nh).contains<cv::gimpl::Island>()); // <internal island>
EXPECT_FALSE(gm.metadata(tmp2_nh).contains<cv::gimpl::Island>()); // #not fused as cycle-causing#
EXPECT_FALSE(gm.metadata(scl_nh) .contains<cv::gimpl::Island>()); // #not fused as cycle-causing#
EXPECT_FALSE(gm.metadata(out0_nh).contains<cv::gimpl::Island>()); // (output is never fused)
EXPECT_FALSE(gm.metadata(out1_nh).contains<cv::gimpl::Island>()); // (output is never fused)
EXPECT_EQ("isl0", gm.metadata(tmp0_nh).get<cv::gimpl::Island>().island);
EXPECT_EQ("isl1", gm.metadata(tmp3_nh).get<cv::gimpl::Island>().island);
EXPECT_NE("isl0", gm.metadata(tmp1_nh).get<cv::gimpl::Island>().island);
EXPECT_NE("isl1", gm.metadata(tmp1_nh).get<cv::gimpl::Island>().island);
// FIXME: Add a test with same graph for Fusion and check GIslandModel
}
TEST_F(ComplexIslands, DistinictIslandsWithSameName)
{
// isl0
// ...........................
// (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0)
// :............ ........^...: ^
// ... : :
// (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----'
// : isl0
// : ..............................
// `------------> Median -> (tmp3) --> Blur -------> (out1)
// :............................:
cv::gapi::island("isl0", cv::GIn(in[0], tmp[1]), cv::GOut(tmp[2]));
cv::gapi::island("isl0", cv::GIn(tmp[1]), cv::GOut(out[1]));
auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]));
EXPECT_ANY_THROW(cc.compile(cv::GMatDesc{CV_8U,1,{640,480}},
cv::GMatDesc{CV_8U,1,{640,480}}));
}
TEST_F(ComplexIslands, FullGraph)
{
cv::gapi::island("isl0", cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]));
auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]))
.compile(cv::GMatDesc{CV_8U,1,{640,480}},
cv::GMatDesc{CV_8U,1,{640,480}});
const auto &gm = cc.priv().model();
std::vector<ade::NodeHandle> handles_inside = {
cv::gimpl::GModel::dataNodeOf(gm, tmp[0]),
cv::gimpl::GModel::dataNodeOf(gm, tmp[1]),
cv::gimpl::GModel::dataNodeOf(gm, tmp[2]),
cv::gimpl::GModel::dataNodeOf(gm, tmp[3]),
cv::gimpl::GModel::dataNodeOf(gm, scl),
};
std::vector<ade::NodeHandle> handles_outside = {
cv::gimpl::GModel::dataNodeOf(gm, in[0]),
cv::gimpl::GModel::dataNodeOf(gm, in[1]),
cv::gimpl::GModel::dataNodeOf(gm, out[0]),
cv::gimpl::GModel::dataNodeOf(gm, out[1]),
};
for (auto nh_inside : handles_inside)
{
EXPECT_EQ("isl0", gm.metadata(nh_inside).get<cv::gimpl::Island>().island);
}
for (auto nh_outside : handles_outside)
{
EXPECT_FALSE(gm.metadata(nh_outside).contains<cv::gimpl::Island>());
}
}
TEST_F(ComplexIslands, ViaScalar)
{
//
// .........................................#internal0.
// (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0)
// :....................^.........................^...:
// : :
// .....................:.........(isl0). :
// (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----'
// :..........:.........................:
// :
// : ..................#internal1.
// `------------> Median -> (tmp3) --> Blur -------> (out1)
// :...........................:
cv::gapi::island("isl0", cv::GIn(in[1]), cv::GOut(scl));
auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]))
.compile(cv::GMatDesc{CV_8U,1,{640,480}},
cv::GMatDesc{CV_8U,1,{640,480}});
const auto &gm = cc.priv().model();
const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[3]);
EXPECT_NE("isl0", gm.metadata(tmp0_nh).get<cv::gimpl::Island>().island); // <internal>
EXPECT_EQ("isl0", gm.metadata(tmp1_nh).get<cv::gimpl::Island>().island); // isl0
EXPECT_NE("isl0", gm.metadata(tmp2_nh).get<cv::gimpl::Island>().island); // <internal>
EXPECT_NE("isl0", gm.metadata(tmp3_nh).get<cv::gimpl::Island>().island); // <internal>
std::vector<ade::NodeHandle> handles_outside = {
cv::gimpl::GModel::dataNodeOf(gm, in[0]),
cv::gimpl::GModel::dataNodeOf(gm, in[1]),
cv::gimpl::GModel::dataNodeOf(gm, scl),
cv::gimpl::GModel::dataNodeOf(gm, out[0]),
cv::gimpl::GModel::dataNodeOf(gm, out[1]),
};
for (auto nh_outside : handles_outside)
{
EXPECT_FALSE(gm.metadata(nh_outside).contains<cv::gimpl::Island>());
}
}
TEST_F(ComplexIslands, BorderDataIsland)
{
// .................................(isl0)..
// : :
// (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0)
// : ^ : ^
// : : : :
// (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----'
// :...........:...........................:
// : : :
// : : :.........................................(isl1)..
// : `------------> Median -> (tmp3) --> Blur -------> (out1)
// : :
// :......................................................:
cv::gapi::island("isl0", cv::GIn(in[0], in[1]), cv::GOut(tmp[2], scl));
cv::gapi::island("isl1", cv::GIn(tmp[1]), cv::GOut(out[1]));
auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]))
.compile(cv::GMatDesc{CV_8U,1,{640,480}},
cv::GMatDesc{CV_8U,1,{640,480}});
const auto &gm = cc.priv().model();
const auto in0_nh = cv::gimpl::GModel::dataNodeOf(gm, in[0]);
const auto in1_nh = cv::gimpl::GModel::dataNodeOf(gm, in[1]);
const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[3]);
const auto scl_nh = cv::gimpl::GModel::dataNodeOf(gm, scl);
const auto out0_nh = cv::gimpl::GModel::dataNodeOf(gm, out[0]);
const auto out1_nh = cv::gimpl::GModel::dataNodeOf(gm, out[1]);
// Check handles inside isl0
EXPECT_EQ("isl0", gm.metadata(tmp0_nh).get<cv::gimpl::Island>().island);
EXPECT_EQ("isl0", gm.metadata(tmp1_nh).get<cv::gimpl::Island>().island);
// ^^^ Important - tmp1 is assigned to isl0, not isl1
// Check handles inside isl1
EXPECT_EQ("isl1", gm.metadata(tmp3_nh).get<cv::gimpl::Island>().island);
// Check outside handles
EXPECT_FALSE(gm.metadata(in0_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(in1_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(tmp2_nh).contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(scl_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(out0_nh).contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(out1_nh).contains<cv::gimpl::Island>());
}
TEST_F(ComplexIslands, IncompleteSpec)
{
// isl0
// ...........................
// (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0)
// :...........xxx.......^...: ^
// : :
// (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----'
// :
// :
// `------------> Median -> (tmp3) --> Blur -------> (out1)
//
// tmp1 is missing in the below spec
EXPECT_ANY_THROW(cv::gapi::island("isl0", cv::GIn(in[0]), cv::GOut(tmp[2])));
// empty range
EXPECT_ANY_THROW(cv::gapi::island("isl1", cv::GIn(tmp[2]), cv::GOut(tmp[2])));
}
TEST_F(ComplexIslands, InputOperationFromDifferentIslands)
{
// isl1
// ........................... ........
// (in0)--> Not -> (tmp0) --> Add :--------> (tmp2)-->: AddC : -------> (out0)
// :......................^..: : ^ :
// isl0 : : : :
// .......................:....................... : :
// (in1) :-> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----- :
// :....................................................:
// isl0 :
// `------------> Median -> (tmp3) --> Blur -------> (out1)
//
cv::gapi::island("isl0", cv::GIn(in[1], tmp[2]), cv::GOut(out[0]));
cv::gapi::island("isl1", cv::GIn(in[0], tmp[1]), cv::GOut(tmp[2]));
auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]))
.compile(cv::GMatDesc{CV_8U,1,{640,480}},
cv::GMatDesc{CV_8U,1,{640,480}});
const auto &gm = cc.priv().model();
const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
EXPECT_EQ("isl1", gm.metadata(tmp0_nh).get<cv::gimpl::Island>().island);
EXPECT_EQ("isl0", gm.metadata(tmp1_nh).get<cv::gimpl::Island>().island);
EXPECT_FALSE(gm.metadata(tmp2_nh).contains<cv::gimpl::Island>());
}
TEST_F(ComplexIslands, NoWayBetweenNodes)
{
// (in0) -> Not -> (tmp0) --> Add ---------> (tmp2) --> AddC -------> (out0)
// ^ ^
// (in1) -> Blur -> (tmp1) ----'--> Sum ----> (scl0) ----'
// :
// `------------> Median -> (tmp3) --> Blur -------> (out1)
EXPECT_ANY_THROW(cv::gapi::island("isl0", cv::GIn(in[1]), cv::GOut(tmp[0])));
}
TEST_F(ComplexIslands, IslandsContainUnusedPart)
{
// Unused part of the graph
// x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x
// x x
// x(in0) -> Not -> (tmp0) --> Add ---------> (tmp2)---> AddC ---------> (out0) x
// x ^ ^ x
// x x x x x x x x x x x x x x x | x x | x
// | x | x
// ...... | x | x
// (in1) -> :Blur:----------> (tmp1) x-----> Sum ------> (scl0) x
// ...... : x x x x x x x x x x x x x x x x x x x x x x x x
// isl0
// :
// `------------> Median -> (tmp3) --> Blur -------> (out1)
cv::gapi::island("isl0", cv::GIn(in[1]), cv::GOut(scl));
auto cc = cv::GComputation(cv::GIn(in[1]), cv::GOut(out[1]))
.compile(cv::GMatDesc{CV_8U,1,{640,480}});
const auto &gm = cc.priv().model();
const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
//The output 0 is not specified in the graph
//means that there will not be a node scl, so that tmp1 will not assign to the island
// FIXME Check that blur assigned to island using the function producerOf
// After merge islands fusion
EXPECT_FALSE(gm.metadata(tmp1_nh) .contains<cv::gimpl::Island>());
}
TEST_F(ComplexIslands, FullGraphInTwoIslands)
{
// isl0
// ..................................................
// (in0) -> :Not -> (tmp0) --> Add ---------> (tmp2) --> AddC: -------> (out0)
// ...................^.... ^ :
// ............... | : : :
// (in1) -> :Blur-> (tmp1):----'-->:Sum ----> (scl0) ----' :
// ........ | : ...........................
// isl1 : | :............................................
// : `------------> Median -> (tmp3) --> Blur ------->:(out1)
// ....................................................
cv::gapi::island("isl0", cv::GIn(in[0], tmp[1]), cv::GOut(out[0]));
cv::gapi::island("isl1", cv::GIn(in[1]), cv::GOut(out[1]));
auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]))
.compile(cv::GMatDesc{CV_8U,1,{640,480}},
cv::GMatDesc{CV_8U,1,{640,480}});
const auto &gm = cc.priv().model();
const auto in0_nh = cv::gimpl::GModel::dataNodeOf(gm, in[0]);
const auto in1_nh = cv::gimpl::GModel::dataNodeOf(gm, in[1]);
const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[3]);
const auto scl_nh = cv::gimpl::GModel::dataNodeOf(gm, scl);
const auto out0_nh = cv::gimpl::GModel::dataNodeOf(gm, out[0]);
const auto out1_nh = cv::gimpl::GModel::dataNodeOf(gm, out[1]);
// Check handles inside isl0
EXPECT_EQ("isl0", gm.metadata(tmp0_nh).get<cv::gimpl::Island>().island);
EXPECT_EQ("isl0", gm.metadata(tmp2_nh).get<cv::gimpl::Island>().island);
EXPECT_EQ("isl0", gm.metadata(scl_nh).get<cv::gimpl::Island>().island);
// Check handles inside isl1
EXPECT_EQ("isl1", gm.metadata(tmp1_nh).get<cv::gimpl::Island>().island);
EXPECT_EQ("isl1", gm.metadata(tmp3_nh).get<cv::gimpl::Island>().island);
// Check outside handles
EXPECT_FALSE(gm.metadata(in0_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(in1_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(out0_nh).contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(out1_nh).contains<cv::gimpl::Island>());
}
TEST_F(ComplexIslands, OnlyOperationsAssignedToIslands)
{
cv::gapi::island("isl0", cv::GIn(in[1]), cv::GOut(tmp[1]));
cv::gapi::island("isl1", cv::GIn(tmp[1]), cv::GOut(scl));
cv::gapi::island("isl2", cv::GIn(scl, tmp[2]), cv::GOut(out[0]));
cv::gapi::island("isl3", cv::GIn(in[0]), cv::GOut(tmp[0]));
cv::gapi::island("isl4", cv::GIn(tmp[0], tmp[1]), cv::GOut(tmp[2]));
cv::gapi::island("isl5", cv::GIn(tmp[1]), cv::GOut(tmp[3]));
cv::gapi::island("isl6", cv::GIn(tmp[3]), cv::GOut(out[1]));
auto cc = cv::GComputation(cv::GIn(in[0], in[1]), cv::GOut(out[0], out[1]))
.compile(cv::GMatDesc{CV_8U,1,{640,480}},
cv::GMatDesc{CV_8U,1,{640,480}});
const auto &gm = cc.priv().model();
//FIXME: Check that operation handles are really assigned to isl0..isl6
const auto in0_nh = cv::gimpl::GModel::dataNodeOf(gm, in[0]);
const auto in1_nh = cv::gimpl::GModel::dataNodeOf(gm, in[1]);
const auto tmp0_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[0]);
const auto tmp1_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[1]);
const auto tmp2_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[2]);
const auto tmp3_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp[3]);
const auto scl_nh = cv::gimpl::GModel::dataNodeOf(gm, scl);
const auto out0_nh = cv::gimpl::GModel::dataNodeOf(gm, out[0]);
const auto out1_nh = cv::gimpl::GModel::dataNodeOf(gm, out[1]);
EXPECT_FALSE(gm.metadata(in0_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(in1_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(tmp0_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(tmp1_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(tmp2_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(tmp3_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(scl_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(out0_nh).contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(out1_nh).contains<cv::gimpl::Island>());
}
namespace
{
struct IslandStructureWithGArray
{
GIntArray in, out;
GMat tmp;
IslandStructureWithGArray()
{
tmp = CreateMatWithDiag::on(in);
out = Mat2Array::on(tmp);
}
};
struct IslandsWithGArray: public ::testing::Test, public IslandStructureWithGArray {};
} // namespace
TEST_F(IslandsWithGArray, IslandWithGArrayAsInput)
{
cv::gapi::island("isl0", cv::GIn(in), cv::GOut(tmp));
const auto pkg = cv::gapi::kernels<CreateMatWithDiagImpl, Mat2ArrayImpl>();
auto cc = cv::GComputation(cv::GIn(in), GOut(out)).compile(cv::empty_array_desc(), cv::compile_args(pkg));
const auto &gm = cc.priv().model();
const auto in_nh = cv::gimpl::GModel::dataNodeOf(gm, in.strip());
const auto out_nh = cv::gimpl::GModel::dataNodeOf(gm, out.strip());
const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp);
GAPI_Assert(tmp_nh->inNodes().size() == 1);
const auto create_diag_mat_nh = tmp_nh->inNodes().front();
EXPECT_EQ("isl0", gm.metadata(create_diag_mat_nh).get<cv::gimpl::Island>().island);
EXPECT_FALSE(gm.metadata(in_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(out_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(tmp_nh) .contains<cv::gimpl::Island>());
}
TEST_F(IslandsWithGArray, IslandWithGArrayAsOutput)
{
cv::gapi::island("isl0", cv::GIn(tmp), cv::GOut(out));
const auto pkg = cv::gapi::kernels<CreateMatWithDiagImpl, Mat2ArrayImpl>();
auto cc = cv::GComputation(cv::GIn(in), GOut(out)).compile(cv::empty_array_desc(), cv::compile_args(pkg));
const auto &gm = cc.priv().model();
const auto in_nh = cv::gimpl::GModel::dataNodeOf(gm, in.strip());
const auto out_nh = cv::gimpl::GModel::dataNodeOf(gm, out.strip());
const auto tmp_nh = cv::gimpl::GModel::dataNodeOf(gm, tmp);
GAPI_Assert(tmp_nh->inNodes().size() == 1);
const auto mat2array_nh = out_nh->inNodes().front();
EXPECT_EQ("isl0", gm.metadata(mat2array_nh).get<cv::gimpl::Island>().island);
EXPECT_FALSE(gm.metadata(in_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(out_nh) .contains<cv::gimpl::Island>());
EXPECT_FALSE(gm.metadata(tmp_nh) .contains<cv::gimpl::Island>());
}
////////////////////////////////////////////////////////////////////////////////
// Wrong input tests on island name
//
namespace
{
struct CheckName : public TestWithParam<std::tuple<bool, const char*> >,
public PlainIslandsFixture
{
void assignIsland(const std::string &s)
{
cv::gapi::island(s, cv::GIn(tmp[0]), cv::GOut(tmp[2]));
};
};
TEST_P(CheckName, Test)
{
bool correct = false;
const char *name = "";
std::tie(correct, name) = GetParam();
if (correct) EXPECT_NO_THROW(assignIsland(name));
else EXPECT_ANY_THROW(assignIsland(name));
}
} // namespace
INSTANTIATE_TEST_CASE_P(IslandName, CheckName,
Values(std::make_tuple(true, "name"),
std::make_tuple(true, " name "),
std::make_tuple(true, " n a m e "),
std::make_tuple(true, " 123 $$ %%"),
std::make_tuple(true, ".: -"),
std::make_tuple(false, ""),
std::make_tuple(false, " "),
std::make_tuple(false, " \t "),
std::make_tuple(false, " \t \t ")));
// FIXME: add <internal> test on unrollExpr() use for islands
} // opencv_test