@@ -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+
892945int 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