aboutsummaryrefslogtreecommitdiff
path: root/chapters/type_conversion.adoc
blob: 26898181a263b3ffffd2ed96e6a8cf7dcf7e6e7b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//
// This confidential and proprietary software may be used only as
// authorised by a licensing agreement from ARM Limited
// (C) COPYRIGHT 2020 ARM Limited
// ALL RIGHTS RESERVED
// The entire notice above must be reproduced on all authorised
// copies and copies may only be made to the extent permitted
// by a licensing agreement from ARM Limited.

=== Type Conversion

==== CAST

Casts a tensor from one data type to another.

*Arguments:*

|===
|Argument|Type|Name|Shape|Description

|Input|in_t|input|shape|Input tensor
|Output|out_t|output|shape|Output tensor
|===

*Operation Function:*

[source,c]
....
for_each (index in shape) {
    in_t in = tensor_read<in_t>(input, shape, index);
    out_t out;
    if (out_t==bool) {
        out = (in!=0) ? true : false;
    } else if (in_t==bool) {
        out = (in) ? 1 : 0;
    } else if (out_t==float) {
        out = round_to_nearest_float(in);
    } else if (in_t==float) {
        out = apply_clip(round_to_nearest_int(in), minimum<out_t>, maximum<out_t>);
    } else if (sizeof(out_t)>=sizeof(in_t)) {
        out = sign_extend(in);
    } else {
        out = truncate(in);
    }
    tensor_write<out_t>(output, shape, index, out)
}
....

*Supported Data Types:*

|===
|Profile|Mode|in_t|out_t

|Any|bool to signed 8|bool|int8
|Any|bool to signed 16|bool|int16
|Any|bool to signed 32|bool|int32
|Any|signed 8 to bool|int8|bool
|Any|signed 8 to signed 16|int8|int16
|Any|signed 8 to signed 32|int8|int32
|Any|signed 8 to float|int8|float
|Any|signed 16 to bool|int16|bool
|Any|signed 16 to signed 8|int16|int8
|Any|signed 16 to signed 32|int16|int32
|Any|signed 16 to float|int16|float
|Any|signed 32 to bool|int32|bool
|Any|signed 32 to signed 8|int32|int8
|Any|signed 32 to signed 16|int32|int16
|Any|signed 32 to float|int32|float
|Any|float to signed 8|float|int8
|Any|float to signed 16|float|int16
|Any|float to signed 32|float|int32
|===

==== RESCALE

Rescale quantized values into a new domain. This function scales by factor: multiplier * 2^-shift^.

*Arguments:*

|===
|Argument|Type|Name|Shape|Description

|Input|in_t*|input|shape|Input tensor from 1 to 4 dims
|Output|out_t*|output|shape|Output tensor with the same shape as input
|===

*Quantization Parameters:*

|===
|Argument|Type|Name|Shape|Description

|Attribute|in_t|input_zp|-|Input tensor zero point
|Attribute|out_t|output_zp|-|Output tensor zero point
|Input (MT profile) Attribute (BI/MI profiles)|mul_t|multiplier[NC]|-|Scaling multiplier array
|Input (MT profile) Attribute (BI/MI profiles)|uint6_t|shift[NC] |-|Scaling shift array
|Input (MT profile) Attribute (BI/MI profiles)|bool|scale32|-|if (scale32) mul_t=int32_t else mul_t=int16_t
|Attribute|bool|double_round|-|Select double round mode
|Attribute|bool|per_channel|-|if (per_channel) NC=shape[dims-1] else NC=1
|===

*Operation Function:*

[source,c]
....
for_each (index in shape) {
    assert(in_t==aint8  || in_t==uint8  || input_zp==0);
    assert(out_t==aint8 || out_t==uint8 || output_zp==0);
    assert((scale32 && in_t!=int48_t) || (!scale32 && !double_round));
    int48_t value = tensor_read<in_t>(input, shape, index, input_zp);
    int c = (per_channel) ? index[dims-1] : 0;
    int32_t result = (scale32) ?
      apply_scale_32(value, multiplier[c], shift[c], double_round) :
      apply_scale_16(value, multiplier[c], shift[c]);
    result = apply_clip(result + output_zp, minimum<out_t>, maximum<out_t>)
    tensor_write<out_t>(output, shape, index, result)
}
....

*Supported Data Types:*

|===
|Profile|Mode|in_t|out_t

|Any|signed 8 to signed 8|aint8|aint8
|Any|signed 8 to signed 16|aint8|int16
|Any|signed 8 to signed 32|aint8|int32
|Any|signed 16 to signed 8|int16|aint8
|Any|signed 16 to signed 16|int16|int16
|Any|signed 16 to signed 32|int16|int32
|Any|signed 32 to signed 8|int32|aint8
|Any|signed 32 to signed 16|int32|int16
|Any|signed 32 to signed 32|int32|int32
|Any|signed 48 to signed 8|int48|aint8
|Any|signed 48 to signed 16|int48|int16
|Any|signed 48 to signed 32|int48|int32
|Any|unsigned 8 to signed 8|uint8|aint8
|Any|signed 8 to unsigned 8|aint8|uint8
|===