blob: 61e39793f841cc9c5cd0ea40307d4f0b31a68389 [file] [log] [blame]
/*
* Copyright (c) 2012-2017 The Khronos Group Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#if defined OPENVX_USE_ENHANCED_VISION || OPENVX_CONFORMANCE_VISION
#include "test_engine/test.h"
#include <VX/vx.h>
#include <VX/vxu.h>
//#define CT_EXECUTE_ASYNC
static void referenceAbsDiff(CT_Image src0, CT_Image src1, CT_Image dst)
{
uint32_t i, j;
ASSERT(src0 && src1 && dst);
ASSERT(src0->width == src1->width && src0->width == dst->width);
ASSERT(src0->height == src1->height && src0->height == dst->height);
ASSERT(src0->format == src1->format && src1->format == VX_DF_IMAGE_S16);
ASSERT(dst->format == VX_DF_IMAGE_S16 || dst->format == VX_DF_IMAGE_U16);
if (dst->format == VX_DF_IMAGE_S16)
{
for (i = 0; i < dst->height; ++i)
{
for (j = 0; j < dst->width; ++j)
{
int32_t val = src0->data.s16[i * src0->stride + j] - src1->data.s16[i * src1->stride + j];
val = val < 0 ? -val : val;
dst->data.s16[i * dst->stride + j] = CT_CAST_S16(val);
}
}
}
else if (dst->format == VX_DF_IMAGE_U16)
{
for (i = 0; i < dst->height; ++i)
{
for (j = 0; j < dst->width; ++j)
{
int32_t val = src0->data.s16[i * src0->stride + j] - src1->data.s16[i * src1->stride + j];
val = val < 0 ? -val : val;
dst->data.u16[i * dst->stride + j] = CT_CAST_U16(val);
}
}
}
}
typedef vx_status (VX_API_CALL *vxuBinopFunction)(vx_context, vx_image, vx_image, vx_image);
typedef vx_node (VX_API_CALL *vxBinopFunction) (vx_graph, vx_image, vx_image, vx_image);
typedef void (*referenceFunction)(CT_Image, CT_Image, CT_Image);
TESTCASE(vxuBinOp16s, CT_VXContext, ct_setup_vx_context, 0)
TESTCASE(vxBinOp16s, CT_VXContext, ct_setup_vx_context, 0)
typedef struct {
const char* name;
vxuBinopFunction vxuFunc;
vxBinopFunction vxFunc;
referenceFunction referenceFunc;
} func_arg;
#define FUNC_ARG(func) ARG(#func, vxu##func, vx##func##Node, reference##func)
TEST_WITH_ARG(vxuBinOp16s, testNegativeSizes, func_arg, FUNC_ARG(AbsDiff))
{
vx_image src1_32x32, src1_64x64, src2_32x32, src2_32x64, dst32x32, dst88x16;
vx_context context = context_->vx_context_;
ASSERT_VX_OBJECT(src1_32x32 = vxCreateImage(context, 32, 32, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(src1_64x64 = vxCreateImage(context, 64, 64, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(src2_32x32 = vxCreateImage(context, 32, 32, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(src2_32x64 = vxCreateImage(context, 32, 64, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(dst32x32 = vxCreateImage(context, 32, 32, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(dst88x16 = vxCreateImage(context, 88, 16, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
// initialize to guarantee that images are allocated
ASSERT_NO_FAILURE(ct_fill_image_random(src1_32x32, &CT()->seed_));
ASSERT_NO_FAILURE(ct_fill_image_random(src1_64x64, &CT()->seed_));
ASSERT_NO_FAILURE(ct_fill_image_random(src2_32x32, &CT()->seed_));
ASSERT_NO_FAILURE(ct_fill_image_random(src2_32x64, &CT()->seed_));
EXPECT_NE_VX_STATUS(VX_SUCCESS, arg_->vxuFunc(context, src1_32x32, src2_32x32, dst88x16));
EXPECT_NE_VX_STATUS(VX_SUCCESS, arg_->vxuFunc(context, src1_32x32, src2_32x64, dst32x32));
EXPECT_NE_VX_STATUS(VX_SUCCESS, arg_->vxuFunc(context, src1_64x64, src2_32x32, dst32x32));
EXPECT_NE_VX_STATUS(VX_SUCCESS, arg_->vxuFunc(context, src1_64x64, src2_32x64, dst32x32));
VX_CALL(vxReleaseImage(&src1_32x32));
VX_CALL(vxReleaseImage(&src2_32x32));
VX_CALL(vxReleaseImage(&src1_64x64));
VX_CALL(vxReleaseImage(&src2_32x64));
VX_CALL(vxReleaseImage(&dst32x32));
VX_CALL(vxReleaseImage(&dst88x16));
}
TEST_WITH_ARG(vxBinOp16s, testNegativeSizes, func_arg, FUNC_ARG(AbsDiff))
{
vx_image src1_32x32, src1_64x64, src2_32x32, src2_32x64, dst32x32, dst88x16;
vx_graph graph1, graph2, graph3, graph4;
vx_context context = context_->vx_context_;
ASSERT_VX_OBJECT(src1_32x32 = vxCreateImage(context, 32, 32, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(src1_64x64 = vxCreateImage(context, 64, 64, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(src2_32x32 = vxCreateImage(context, 32, 32, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(src2_32x64 = vxCreateImage(context, 32, 64, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(dst32x32 = vxCreateImage(context, 32, 32, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(dst88x16 = vxCreateImage(context, 88, 16, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(graph1 = vxCreateGraph(context), VX_TYPE_GRAPH);
ASSERT_VX_OBJECT(arg_->vxFunc(graph1, src1_32x32, src2_32x32, dst88x16), VX_TYPE_NODE);
EXPECT_NE_VX_STATUS(VX_SUCCESS, vxVerifyGraph(graph1));
ASSERT_VX_OBJECT(graph2 = vxCreateGraph(context), VX_TYPE_GRAPH);
ASSERT_VX_OBJECT(arg_->vxFunc(graph2, src1_32x32, src2_32x64, dst32x32), VX_TYPE_NODE);
EXPECT_NE_VX_STATUS(VX_SUCCESS, vxVerifyGraph(graph2));
ASSERT_VX_OBJECT(graph3 = vxCreateGraph(context), VX_TYPE_GRAPH);
ASSERT_VX_OBJECT(arg_->vxFunc(graph3, src1_64x64, src2_32x32, dst32x32), VX_TYPE_NODE);
EXPECT_NE_VX_STATUS(VX_SUCCESS, vxVerifyGraph(graph3));
ASSERT_VX_OBJECT(graph4 = vxCreateGraph(context), VX_TYPE_GRAPH);
ASSERT_VX_OBJECT(arg_->vxFunc(graph4, src1_64x64, src2_32x64, dst32x32), VX_TYPE_NODE);
EXPECT_NE_VX_STATUS(VX_SUCCESS, vxVerifyGraph(graph4));
VX_CALL(vxReleaseImage(&src1_32x32));
VX_CALL(vxReleaseImage(&src2_32x32));
VX_CALL(vxReleaseImage(&src1_64x64));
VX_CALL(vxReleaseImage(&src2_32x64));
VX_CALL(vxReleaseImage(&dst32x32));
VX_CALL(vxReleaseImage(&dst88x16));
VX_CALL(vxReleaseGraph(&graph1));
VX_CALL(vxReleaseGraph(&graph2));
VX_CALL(vxReleaseGraph(&graph3));
VX_CALL(vxReleaseGraph(&graph4));
}
static vx_image inference_image;
static vx_action VX_CALLBACK inference_image_test(vx_node node)
{
vx_uint32 width = 0;
vx_uint32 height = 0;
vx_df_image format = 0;
EXPECT_EQ_VX_STATUS(VX_SUCCESS, vxQueryImage(inference_image, VX_IMAGE_WIDTH, &width, sizeof(width)));
EXPECT_EQ_VX_STATUS(VX_SUCCESS, vxQueryImage(inference_image, VX_IMAGE_HEIGHT, &height, sizeof(height)));
EXPECT_EQ_VX_STATUS(VX_SUCCESS, vxQueryImage(inference_image, VX_IMAGE_FORMAT, &format, sizeof(format)));
EXPECT_EQ_INT(640, width);
EXPECT_EQ_INT(480, height);
EXPECT_EQ_INT(VX_DF_IMAGE_S16, format);
return VX_ACTION_CONTINUE;
}
TEST_WITH_ARG(vxBinOp16s, testInference, func_arg, FUNC_ARG(AbsDiff))
{
vx_image src1, src2, dst, gr;
vx_graph graph;
vx_node n, tmp;
vx_context context = context_->vx_context_;
ASSERT_VX_OBJECT(graph = vxCreateGraph(context), VX_TYPE_GRAPH);
ASSERT_VX_OBJECT(src1 = vxCreateImage(context, 640, 480, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(src2 = vxCreateImage(context, 640, 480, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(dst = vxCreateVirtualImage(graph, 0, 0, VX_DF_IMAGE_VIRT), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(n = arg_->vxFunc(graph, src1, src2, dst), VX_TYPE_NODE);
// grounding
ASSERT_VX_OBJECT(gr = vxCreateImage(context, 640, 480, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(tmp = vxAddNode(graph, dst, src2, VX_CONVERT_POLICY_WRAP, gr), VX_TYPE_NODE);
// test
inference_image = dst;
EXPECT_EQ_VX_STATUS(VX_SUCCESS, vxAssignNodeCallback(n, inference_image_test));
ASSERT_EQ_VX_STATUS(VX_SUCCESS, vxProcessGraph(graph));
VX_CALL(vxReleaseNode(&n));
VX_CALL(vxReleaseNode(&tmp));
VX_CALL(vxReleaseImage(&src1));
VX_CALL(vxReleaseImage(&src2));
VX_CALL(vxReleaseImage(&dst));
VX_CALL(vxReleaseImage(&gr));
VX_CALL(vxReleaseGraph(&graph));
}
typedef struct {
const char* name;
uint32_t width;
uint32_t height;
vxuBinopFunction vxuFunc;
vxBinopFunction vxFunc;
referenceFunction referenceFunc;
} fuzzy_arg;
#define FUZZY_ARG(func,w,h) ARG(#func ": " #w "x" #h, w, h, vxu##func, vx##func##Node, reference##func)
#define BINOP_SIZE_ARGS(func) \
FUZZY_ARG(func, 640, 480), \
ARG_EXTENDED_BEGIN(), \
FUZZY_ARG(func, 1, 1), \
FUZZY_ARG(func, 15, 17), \
FUZZY_ARG(func, 32, 32), \
FUZZY_ARG(func, 1231, 1234), \
FUZZY_ARG(func, 1280, 720), \
FUZZY_ARG(func, 1920, 1080), \
ARG_EXTENDED_END()
TEST_WITH_ARG(vxuBinOp16s, testFuzzy, fuzzy_arg, BINOP_SIZE_ARGS(AbsDiff))
{
vx_image src1, src2, dst;
CT_Image ref1, ref2, refdst, vxdst;
vx_context context = context_->vx_context_;
ASSERT_VX_OBJECT(src1 = vxCreateImage(context, arg_->width, arg_->height, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(src2 = vxCreateImage(context, arg_->width, arg_->height, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(dst = vxCreateImage(context, arg_->width, arg_->height, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_NO_FAILURE(ct_fill_image_random(src1, &CT()->seed_));
ASSERT_NO_FAILURE(ct_fill_image_random(src2, &CT()->seed_));
ASSERT_EQ_VX_STATUS(VX_SUCCESS, arg_->vxuFunc(context, src1, src2, dst));
ref1 = ct_image_from_vx_image(src1);
ref2 = ct_image_from_vx_image(src2);
vxdst = ct_image_from_vx_image(dst);
refdst = ct_allocate_image(arg_->width, arg_->height, VX_DF_IMAGE_S16);
arg_->referenceFunc(ref1, ref2, refdst);
ASSERT_EQ_CTIMAGE(refdst, vxdst);
// checked release vx images
VX_CALL(vxReleaseImage(&dst));
VX_CALL(vxReleaseImage(&src1));
VX_CALL(vxReleaseImage(&src2));
EXPECT_EQ_PTR(NULL, dst);
EXPECT_EQ_PTR(NULL, src1);
EXPECT_EQ_PTR(NULL, src2);
}
TEST_WITH_ARG(vxBinOp16s, testFuzzy, fuzzy_arg, BINOP_SIZE_ARGS(AbsDiff))
{
vx_image src1, src2, dst;
vx_graph graph;
CT_Image ref1, ref2, refdst, vxdst;
vx_context context = context_->vx_context_;
ASSERT_VX_OBJECT(graph = vxCreateGraph(context), VX_TYPE_GRAPH);
ASSERT_VX_OBJECT(dst = vxCreateImage(context, arg_->width, arg_->height, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(src1 = vxCreateImage(context, arg_->width, arg_->height, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_VX_OBJECT(src2 = vxCreateImage(context, arg_->width, arg_->height, VX_DF_IMAGE_S16), VX_TYPE_IMAGE);
ASSERT_NO_FAILURE(ct_fill_image_random(src1, &CT()->seed_));
ASSERT_NO_FAILURE(ct_fill_image_random(src2, &CT()->seed_));
// build one-node graph
ASSERT_VX_OBJECT(arg_->vxFunc(graph, src1, src2, dst), VX_TYPE_NODE);
// run graph
#ifdef CT_EXECUTE_ASYNC
ASSERT_EQ_VX_STATUS(VX_SUCCESS, vxScheduleGraph(graph));
ASSERT_EQ_VX_STATUS(VX_SUCCESS, vxWaitGraph(graph));
#else
ASSERT_EQ_VX_STATUS(VX_SUCCESS, vxProcessGraph(graph));
#endif
ref1 = ct_image_from_vx_image(src1);
ref2 = ct_image_from_vx_image(src2);
vxdst = ct_image_from_vx_image(dst);
refdst = ct_allocate_image(arg_->width, arg_->height, VX_DF_IMAGE_S16);
arg_->referenceFunc(ref1, ref2, refdst);
ASSERT_EQ_CTIMAGE(refdst, vxdst);
VX_CALL(vxReleaseImage(&src1));
VX_CALL(vxReleaseImage(&src2));
VX_CALL(vxReleaseImage(&dst));
VX_CALL(vxReleaseGraph(&graph));
}
TESTCASE_TESTS(vxuBinOp16s, DISABLED_testNegativeSizes, testFuzzy)
TESTCASE_TESTS(vxBinOp16s, DISABLED_testNegativeSizes, testInference, testFuzzy)
#endif //OPENVX_USE_ENHANCED_VISION || OPENVX_CONFORMANCE_VISION