Skip to content
This repository was archived by the owner on Feb 16, 2019. It is now read-only.

Commit 1f4ab66

Browse files
author
rgiduthuri
committed
release 0.9.5 - fixed issue #13 and added basic framework for tensors
1 parent e814b4d commit 1f4ab66

17 files changed

+1641
-25
lines changed

openvx/ago/ago_interface.cpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1457,7 +1457,7 @@ vx_status agoVerifyNode(AgoNode * node)
14571457
}
14581458
// make sure that the data come from output validator matches with object
14591459
if (data->u.arr.itemtype != meta->data.u.arr.itemtype) {
1460-
agoAddLogEntry(&kernel->ref, VX_ERROR_INVALID_TYPE, "ERROR: agoVerifyGraph: kernel %s: invalid type for argument#%d\n", kernel->name, arg);
1460+
agoAddLogEntry(&kernel->ref, VX_ERROR_INVALID_TYPE, "ERROR: agoVerifyGraph: kernel %s: invalid array type for argument#%d\n", kernel->name, arg);
14611461
return VX_ERROR_INVALID_TYPE;
14621462
}
14631463
else if (!data->u.arr.capacity || (meta->data.u.arr.capacity && meta->data.u.arr.capacity > data->u.arr.capacity)) {
@@ -1484,7 +1484,7 @@ vx_status agoVerifyNode(AgoNode * node)
14841484
else if (meta->data.ref.type == VX_TYPE_MATRIX) {
14851485
// make sure that the data come from output validator matches with object
14861486
if ((data->u.mat.type != meta->data.u.mat.type) || (data->u.mat.columns != meta->data.u.mat.columns) || (data->u.mat.rows != meta->data.u.mat.rows)) {
1487-
agoAddLogEntry(&kernel->ref, VX_ERROR_INVALID_TYPE, "ERROR: agoVerifyGraph: kernel %s: invalid type for argument#%d\n", kernel->name, arg);
1487+
agoAddLogEntry(&kernel->ref, VX_ERROR_INVALID_TYPE, "ERROR: agoVerifyGraph: kernel %s: invalid matrix meta for argument#%d\n", kernel->name, arg);
14881488
return VX_ERROR_INVALID_TYPE;
14891489
}
14901490
}
@@ -1497,6 +1497,21 @@ vx_status agoVerifyNode(AgoNode * node)
14971497
else if (meta->data.ref.type == VX_TYPE_REMAP) {
14981498
// nothing to do
14991499
}
1500+
else if (meta->data.ref.type == VX_TYPE_TENSOR) {
1501+
// make sure that the data come from output validator matches with object
1502+
bool mismatched = false;
1503+
if ((data->u.tensor.num_dims != meta->data.u.tensor.num_dims) || (data->u.tensor.data_type != meta->data.u.tensor.data_type) || (data->u.tensor.fixed_point_pos != meta->data.u.tensor.fixed_point_pos)) {
1504+
mismatched = true;
1505+
}
1506+
for (vx_size i = 0; i < data->u.tensor.num_dims; i++) {
1507+
if (data->u.tensor.dims[i] != meta->data.u.tensor.dims[i])
1508+
mismatched = true;
1509+
}
1510+
if (mismatched) {
1511+
agoAddLogEntry(&kernel->ref, VX_ERROR_INVALID_TYPE, "ERROR: agoVerifyGraph: kernel %s: invalid tensor meta for argument#%d\n", kernel->name, arg);
1512+
return VX_ERROR_INVALID_TYPE;
1513+
}
1514+
}
15001515
else if (meta->data.ref.type == AGO_TYPE_CANNY_STACK) {
15011516
// nothing to do
15021517
}

openvx/ago/ago_internal.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ THE SOFTWARE.
3434
//
3535

3636
// version
37-
#define AGO_VERSION "0.9.4"
37+
#define AGO_VERSION "0.9.5"
3838

3939
// debug configuration
4040
#define ENABLE_DEBUG_MESSAGES 0 // 0:disable 1:enable
@@ -103,6 +103,7 @@ THE SOFTWARE.
103103
// AGO limites
104104
#define AGO_MAX_CONVOLUTION_DIM 9 // maximum size of convolution matrix
105105
#define AGO_OPTICALFLOWPYRLK_MAX_DIM 15 // maximum size of opticalflow block size
106+
#define AGO_MAX_TENSOR_DIMENSIONS 4 // maximum dimensions supported by tensor
106107

107108
// AGO remap data precision
108109
#define AGO_REMAP_FRACTIONAL_BITS 3 // number of fractional bits in re-map locations
@@ -327,6 +328,17 @@ struct AgoConfigThreshold {
327328
vx_int32 threshold_lower, threshold_upper;
328329
vx_int32 true_value, false_value;
329330
};
331+
struct AgoConfigTensor {
332+
vx_size num_dims;
333+
vx_size dims[AGO_MAX_TENSOR_DIMENSIONS];
334+
vx_enum data_type;
335+
vx_uint32 fixed_point_pos;
336+
vx_size stride[AGO_MAX_TENSOR_DIMENSIONS];
337+
vx_size offset;
338+
AgoData * roiMaster;
339+
vx_size start[AGO_MAX_TENSOR_DIMENSIONS];
340+
vx_size end[AGO_MAX_TENSOR_DIMENSIONS];
341+
};
330342
struct AgoConfigCannyStack {
331343
vx_uint32 count;
332344
vx_uint32 stackTop;
@@ -369,6 +381,7 @@ struct AgoData {
369381
AgoConfigThreshold thr;
370382
AgoConfigCannyStack cannystack;
371383
AgoConfigScaleMatrix scalemat;
384+
AgoConfigTensor tensor;
372385
} u;
373386
vx_size size;
374387
vx_enum import_type;

openvx/ago/ago_util.cpp

Lines changed: 201 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ static struct { const char * name; vx_enum value; vx_size size; } s_table_consta
7878
{ "UINT8", VX_TYPE_UINT8, sizeof(vx_uint8) },
7979
{ "INT8", VX_TYPE_INT8, sizeof(vx_int8) },
8080
{ "CHAR", VX_TYPE_CHAR, sizeof(vx_int8) },
81+
{ "FLOAT16", VX_TYPE_FLOAT16, sizeof(vx_int16) },
8182
{ "FLOAT32", VX_TYPE_FLOAT32, sizeof(vx_float32) },
8283
{ "FLOAT64", VX_TYPE_FLOAT64, sizeof(vx_float64) },
8384
{ "SIZE", VX_TYPE_SIZE, sizeof(vx_size) },
@@ -95,6 +96,7 @@ static struct { const char * name; vx_enum value; vx_size size; } s_table_consta
9596
{ "VX_TYPE_ARRAY", VX_TYPE_ARRAY },
9697
{ "VX_TYPE_IMAGE", VX_TYPE_IMAGE },
9798
{ "VX_TYPE_REMAP", VX_TYPE_REMAP },
99+
{ "VX_TYPE_TENSOR", VX_TYPE_TENSOR },
98100
{ "VX_TYPE_STRING", VX_TYPE_STRING_AMD },
99101
{ "AGO_TYPE_MEANSTDDEV_DATA", AGO_TYPE_MEANSTDDEV_DATA },
100102
{ "AGO_TYPE_MINMAXLOC_DATA", AGO_TYPE_MINMAXLOC_DATA },
@@ -848,6 +850,7 @@ void agoGetDescriptionFromData(AgoContext * acontext, char * desc, AgoData * dat
848850
else if (data->u.scalar.type == VX_TYPE_INT64) sprintf(desc + strlen(desc), "scalar%s:INT64,%" PRId64, virt, data->u.scalar.u.i64);
849851
else if (data->u.scalar.type == VX_TYPE_UINT64) sprintf(desc + strlen(desc), "scalar%s:UINT64,%" PRIu64, virt, data->u.scalar.u.u64);
850852
else if (data->u.scalar.type == VX_TYPE_STRING_AMD) sprintf(desc + strlen(desc), "scalar%s:STRING,%s", virt, data->buffer ? (const char *)data->buffer : "");
853+
else if (data->u.scalar.type == VX_TYPE_FLOAT16) sprintf(desc + strlen(desc), "scalar%s:FLOAT16,%u", virt, data->u.scalar.u.u & 0xffff);
851854
else sprintf(desc + strlen(desc), "scalar%s:UNSUPPORTED,NULL", virt);
852855
}
853856
else if (data->ref.type == VX_TYPE_DISTRIBUTION) {
@@ -874,6 +877,12 @@ void agoGetDescriptionFromData(AgoContext * acontext, char * desc, AgoData * dat
874877
else if (data->ref.type == VX_TYPE_REMAP) {
875878
sprintf(desc + strlen(desc), "remap%s:%u,%u,%u,%u", virt, data->u.remap.src_width, data->u.remap.src_height, data->u.remap.dst_width, data->u.remap.dst_height);
876879
}
880+
else if (data->ref.type == VX_TYPE_TENSOR) {
881+
char dims[64] = "";
882+
for (vx_size i = 0; i < data->u.tensor.num_dims; i++)
883+
sprintf(dims + strlen(dims), "%s%u", i ? "," : "", (vx_uint32)data->u.tensor.dims[i]);
884+
sprintf(desc + strlen(desc), "tensor%s:%u,{%s},%s,%u", virt, (vx_uint32)data->u.tensor.num_dims, dims, agoEnum2Name(data->u.tensor.data_type), (vx_uint32)data->u.tensor.fixed_point_pos);
885+
}
877886
else if (data->ref.type == AGO_TYPE_MEANSTDDEV_DATA) {
878887
sprintf(desc + strlen(desc), "ago-meanstddev-data%s:", virt);
879888
}
@@ -889,6 +898,50 @@ void agoGetDescriptionFromData(AgoContext * acontext, char * desc, AgoData * dat
889898
else sprintf(desc + strlen(desc), "UNSUPPORTED%s:0x%08x", virt, data->ref.type);
890899
}
891900

901+
int agoParseWordFromDescription(const char *& desc, vx_size size, char * word)
902+
{
903+
for (vx_uint32 i = 0; i < (size - 1) && *desc && *desc != ',' && *desc != '}'; i++) {
904+
*word++ = *desc++;
905+
}
906+
*word = 0;
907+
return 0;
908+
}
909+
910+
int agoParseValueFromDescription(const char *& desc, vx_uint32& value)
911+
{
912+
char word[32];
913+
if (agoParseWordFromDescription(desc, sizeof(word), word) < 0)
914+
return -1;
915+
value = atoi(word);
916+
return 0;
917+
}
918+
919+
int agoParseValueFromDescription(const char *& desc, vx_size& value)
920+
{
921+
char word[32];
922+
if (agoParseWordFromDescription(desc, sizeof(word), word) < 0)
923+
return -1;
924+
value = atoi(word);
925+
return 0;
926+
}
927+
928+
int agoParseListFromDescription(const char *& desc, vx_size num_dims, vx_size * dims)
929+
{
930+
if (*desc != '{')
931+
return -1;
932+
for (vx_uint32 i = 0; i < num_dims; i++) {
933+
if (*desc != '{' && *desc != ',')
934+
return -1;
935+
desc++;
936+
if (agoParseValueFromDescription(desc, dims[i]) < 0)
937+
return -1;
938+
}
939+
if (*desc != '}')
940+
return -1;
941+
desc++;
942+
return 0;
943+
}
944+
892945
int agoGetDataFromDescription(AgoContext * acontext, AgoGraph * agraph, AgoData * data, const char * desc)
893946
{
894947
if (!data->ref.context) data->ref.context = acontext; // needed by recursive calls to agoDataSanityCheckAndUpdate
@@ -1447,6 +1500,11 @@ int agoGetDataFromDescription(AgoContext * acontext, AgoGraph * agraph, AgoData
14471500
if (sscanf(s, "%g", &data->u.scalar.u.f) == 1)
14481501
data->isInitialized = vx_true_e;
14491502
}
1503+
else if (data->u.scalar.type == VX_TYPE_FLOAT16) {
1504+
data->u.scalar.itemsize = sizeof(vx_uint16);
1505+
if (sscanf(s, "%g", &data->u.scalar.u.u) == 1)
1506+
data->isInitialized = vx_true_e;
1507+
}
14501508
else if (data->u.scalar.type == VX_TYPE_BOOL) {
14511509
data->u.scalar.itemsize = sizeof(vx_bool);
14521510
if (sscanf(s, "%d", &data->u.scalar.u.i) == 1)
@@ -1513,6 +1571,127 @@ int agoGetDataFromDescription(AgoContext * acontext, AgoGraph * agraph, AgoData
15131571
}
15141572
return 0;
15151573
}
1574+
else if (!strncmp(desc, "tensor:", 7) || !strncmp(desc, "tensor-virtual:", 7 + 8)) {
1575+
data->isVirtual = !strncmp(desc, "tensor-virtual:", 7 + 8) ? vx_true_e : vx_false_e;
1576+
desc += 7 + (data->isVirtual ? 8 : 0);
1577+
// get configuration
1578+
data->ref.type = VX_TYPE_TENSOR;
1579+
if (agoParseValueFromDescription(desc, data->u.tensor.num_dims) < 0)
1580+
return -1;
1581+
if (*desc++ != ',') return -1;
1582+
if (data->u.tensor.num_dims < 1 || data->u.tensor.num_dims > AGO_MAX_TENSOR_DIMENSIONS)
1583+
return -1;
1584+
if (agoParseListFromDescription(desc, data->u.tensor.num_dims, data->u.tensor.dims) < 0)
1585+
return -1;
1586+
if (*desc++ != ',') return -1;
1587+
char data_type[64] = { 0 };
1588+
if (agoParseWordFromDescription(desc, sizeof(data_type), data_type) < 0)
1589+
return -1;
1590+
data->u.tensor.data_type = agoName2Enum(data_type);
1591+
if (data->u.tensor.data_type != VX_TYPE_INT16 && data->u.tensor.data_type != VX_TYPE_FLOAT32 && data->u.tensor.data_type != VX_TYPE_FLOAT16) {
1592+
agoAddLogEntry(&data->ref, VX_FAILURE, "ERROR: agoGetDataFromDescription: invalid data_type for tensor: %s\n", data_type);
1593+
return -1;
1594+
}
1595+
data->u.tensor.fixed_point_pos = 0;
1596+
if (data->u.tensor.data_type == VX_TYPE_INT16) {
1597+
if (*desc++ != ',') return -1;
1598+
if (agoParseValueFromDescription(desc, data->u.tensor.fixed_point_pos) < 0)
1599+
return -1;
1600+
}
1601+
vx_size elem_size = agoType2Size(data->ref.context, data->u.tensor.data_type);
1602+
data->u.tensor.offset = 0;
1603+
data->size = elem_size;
1604+
for (vx_size i = 0; i < data->u.tensor.num_dims; i++) {
1605+
data->u.tensor.start[i] = 0;
1606+
data->u.tensor.end[i] = data->u.tensor.dims[i];
1607+
data->u.tensor.stride[i] = data->size;
1608+
data->size *= data->u.tensor.dims[i];
1609+
// make sure that the size and stride[1] are multiple of 4
1610+
if (i == 0 && (data->size & 3)) {
1611+
data->size = (data->size + 3) & ~3;
1612+
}
1613+
}
1614+
for (vx_size i = data->u.tensor.num_dims; i < AGO_MAX_TENSOR_DIMENSIONS; i++) {
1615+
data->u.tensor.start[i] = 0;
1616+
data->u.tensor.end[i] = 1;
1617+
data->u.tensor.dims[i] = 1;
1618+
data->u.tensor.stride[i] = data->u.tensor.stride[data->u.tensor.num_dims - 1];
1619+
}
1620+
if (!data->size)
1621+
return -1;
1622+
// sanity check and update
1623+
if (agoDataSanityCheckAndUpdate(data)) {
1624+
agoAddLogEntry(&data->ref, VX_FAILURE, "ERROR: agoGetDataFromDescription: agoDataSanityCheckAndUpdate failed for tensor\n");
1625+
return -1;
1626+
}
1627+
return 0;
1628+
}
1629+
else if (!strncmp(desc, "tensor-from-roi:", 16)) {
1630+
desc += 16;
1631+
// get configuration
1632+
data->ref.type = VX_TYPE_TENSOR;
1633+
char masterName[64];
1634+
vx_size num_dims, start[AGO_MAX_TENSOR_DIMENSIONS], end[AGO_MAX_TENSOR_DIMENSIONS];
1635+
if (agoParseWordFromDescription(desc, sizeof(masterName), masterName) < 0)
1636+
return -1;
1637+
AgoData * dataMaster = agoFindDataByName(acontext, agraph, masterName);
1638+
if (!dataMaster || dataMaster->ref.type != VX_TYPE_TENSOR) {
1639+
agoAddLogEntry(&dataMaster->ref, VX_FAILURE, "ERROR: agoGetDataFromDescription: tensor-from-roi: master tensor is invalid: %s\n", masterName);
1640+
return -1;
1641+
}
1642+
if (*desc++ != ',') return -1;
1643+
if (agoParseValueFromDescription(desc, num_dims) < 0)
1644+
return -1;
1645+
if (num_dims != dataMaster->u.tensor.num_dims) {
1646+
agoAddLogEntry(&dataMaster->ref, VX_FAILURE, "ERROR: agoGetDataFromDescription: tensor-from-roi: num_of_dims (%u) doesn't match master\n", (vx_uint32)num_dims);
1647+
return -1;
1648+
}
1649+
if (*desc++ != ',') return -1;
1650+
if (agoParseListFromDescription(desc, num_dims, start) < 0)
1651+
return -1;
1652+
if (*desc++ != ',') return -1;
1653+
if (agoParseListFromDescription(desc, num_dims, end) < 0)
1654+
return -1;
1655+
while (dataMaster && dataMaster->ref.type == VX_TYPE_TENSOR && dataMaster->u.tensor.roiMaster) {
1656+
for (vx_size i = 0; i < num_dims; i++) {
1657+
start[i] += dataMaster->u.tensor.start[i];
1658+
end[i] += dataMaster->u.tensor.start[i];
1659+
}
1660+
dataMaster = dataMaster->u.tensor.roiMaster;
1661+
}
1662+
if (!dataMaster || dataMaster->ref.type != VX_TYPE_TENSOR) {
1663+
agoAddLogEntry(&dataMaster->ref, VX_FAILURE, "ERROR: agoGetDataFromDescription: tensor-from-roi: master tensor is invalid: %s\n", masterName);
1664+
return -1;
1665+
}
1666+
data->isVirtual = dataMaster->isVirtual;
1667+
data->isInitialized = dataMaster->isInitialized;
1668+
data->u.tensor.num_dims = dataMaster->u.tensor.num_dims;
1669+
data->u.tensor.data_type = dataMaster->u.tensor.data_type;
1670+
data->u.tensor.fixed_point_pos = dataMaster->u.tensor.fixed_point_pos;
1671+
data->u.tensor.roiMaster = dataMaster;
1672+
data->u.tensor.offset = 0;
1673+
data->size = data->u.tensor.stride[0];
1674+
for (vx_size i = 0; i < data->u.tensor.num_dims; i++) {
1675+
data->u.tensor.start[i] = start[i];
1676+
data->u.tensor.end[i] = end[i];
1677+
data->u.tensor.dims[i] = end[i] - start[i];
1678+
data->u.tensor.stride[i] = dataMaster->u.tensor.stride[i];
1679+
data->u.tensor.offset += start[i] * dataMaster->u.tensor.stride[i];
1680+
data->size *= data->u.tensor.dims[i];
1681+
}
1682+
for (vx_size i = data->u.tensor.num_dims; i < AGO_MAX_TENSOR_DIMENSIONS; i++) {
1683+
data->u.tensor.start[i] = 0;
1684+
data->u.tensor.end[i] = 1;
1685+
data->u.tensor.dims[i] = 1;
1686+
data->u.tensor.stride[i] = data->u.tensor.stride[data->u.tensor.num_dims - 1];
1687+
}
1688+
// sanity check and update
1689+
if (agoDataSanityCheckAndUpdate(data)) {
1690+
agoAddLogEntry(&data->ref, VX_FAILURE, "ERROR: agoGetDataFromDescription: agoDataSanityCheckAndUpdate failed for tensor-from-view\n");
1691+
return -1;
1692+
}
1693+
return 0;
1694+
}
15161695
else if (!strncmp(desc, "ago-meanstddev-data:", 20) || !strncmp(desc, "ago-meanstddev-data-virtual:", 20 + 8)) {
15171696
if (!strncmp(desc, "ago-meanstddev-data-virtual:", 20 + 8)) {
15181697
data->isVirtual = vx_true_e;
@@ -1632,6 +1811,7 @@ int agoInitializeImageComponentsAndPlanes(AgoContext * acontext)
16321811
agoSetImageComponentsAndPlanes(acontext, VX_DF_IMAGE_F32x3_AMD, 3, 1, 3 * 32, VX_COLOR_SPACE_NONE, VX_CHANNEL_RANGE_FULL);
16331812
agoSetImageComponentsAndPlanes(acontext, VX_DF_IMAGE_F32_AMD, 1, 1, 32, VX_COLOR_SPACE_NONE, VX_CHANNEL_RANGE_FULL);
16341813
agoSetImageComponentsAndPlanes(acontext, VX_DF_IMAGE_F64_AMD, 1, 1, 64, VX_COLOR_SPACE_NONE, VX_CHANNEL_RANGE_FULL);
1814+
agoSetImageComponentsAndPlanes(acontext, VX_DF_IMAGE_F16_AMD, 1, 1, 16, VX_COLOR_SPACE_NONE, VX_CHANNEL_RANGE_FULL);
16351815
return 0;
16361816
}
16371817

@@ -1998,6 +2178,9 @@ int agoDataSanityCheckAndUpdate(AgoData * data)
19982178
if (!data->size)
19992179
return -1;
20002180
}
2181+
else if (data->ref.type == VX_TYPE_TENSOR) {
2182+
// nothing to check yet
2183+
}
20012184
else if (data->ref.type == VX_TYPE_DISTRIBUTION) {
20022185
// calculate other attributes and buffer size
20032186
data->size = data->u.dist.numbins * sizeof(vx_uint32);
@@ -2291,6 +2474,24 @@ int agoAllocData(AgoData * data)
22912474
else if (data->ref.type == AGO_TYPE_SCALE_MATRIX) {
22922475
// nothing to do
22932476
}
2477+
else if (data->ref.type == VX_TYPE_TENSOR) {
2478+
if (data->u.tensor.roiMaster) {
2479+
// make sure that the master image has been allocated
2480+
if (!data->u.tensor.roiMaster->buffer) {
2481+
if (agoAllocData(data->u.tensor.roiMaster) < 0) {
2482+
return -1;
2483+
}
2484+
}
2485+
// get the region from master image
2486+
data->buffer = data->u.tensor.roiMaster->buffer + data->u.tensor.offset;
2487+
}
2488+
else {
2489+
// allocate buffer and get aligned buffer with 16-byte alignment
2490+
data->buffer = data->buffer_allocated = (vx_uint8 *)agoAllocMemory(data->size);
2491+
if (!data->buffer_allocated)
2492+
return -1;
2493+
}
2494+
}
22942495
else return -1;
22952496
return 0;
22962497
}

0 commit comments

Comments
 (0)