|
|
|
// 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
|
|
|
|
// 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
|