Casting functions (aie::vector_cast<DstT>(const Vec& v)
and aie::vector.cast_to<DstT>()
) allow value casting
between vector types with the same size in bits. Accumulator vector types have the
casting function aie::accum.cast_to<DstT>()
.
Generally, using the smallest data type possible will reduce register spillage and
improve performance. For example, if a 32-bit accumulator (acc32) can meet the
design requirements then it is preferable to use that instead of a larger 64-bit
accumulator (acc64).
aie::vector<int16,8> iv;
aie::vector<cint16,4> cv=iv.cast_to<cint16>();
aie::vector<cint16,4> cv2=aie::vector_cast<cint16>(iv);
aie::accum<cacc64,4> acc=aie::mul(cv,cv2);
aie::accum<acc64,8> acc2=acc.cast_to<acc64>();
Standard C++ casts can be also used. But the recommended ways of reading vectors from a buffer are as follows.
- Use
aie::load_v
and increment the scalar pointer by the number of elements in the vector. - Using vector iterators.
Additional details about aie::load_v
and iterators are covered in the following sections.
int16 coeff_buffer[16];
aie::vector<int32,8> coeff=aie::load_v<8>((int32*)coeff_buffer);//cast to int32 and load
auto it = aie::begin_vector<8>(coeff_buffer);//create vector<int16,8> iterator
aie::vector<int16,8> vec0=*it++;//read first vector<int16,8>
aie::vector<int16,8> vec1=*it;//read second vector<int16,8>
Hardware support is built-in for floating-point to fixed-point
(to_fixed()
) and fixed-point to floating-point
(to_float()
) conversions. For example, the
fixed-point square root, inverse square root, and inverse (reciprocal) are
implemented with floating-point precision and the to_float()
and to_fixed()
conversions
are used before and after the function.
The conversion functions (to_float()
and to_fixed()
) can convert either a vector or
scalar to float or fixed type.
int a=48;
float f1=aie::to_float(a); //f1=48.0
float f2=aie::to_float(a,/*position of input binary point*/2); //f2=12.0
int b1=aie::to_fixed(f1);//b1=48
int b2=aie::to_fixed(f1,/*position of output decimal point*/2);//b2=192
aie::vector<float,32> fv;
aie::vector<int32,32> iv=aie::to_fixed<int32>(fv,/*position of output decimal point*/2);
Data can be moved from vector to accumulator using aie::accum.from_vector()
or from accumulator to vector
using aie::accum.to_vector<DstT>()
with
shifting and rounding as shown in the following example.
aie::vector<int16,16> v;
aie::accum<acc32,16> acc;
acc.from_vector(v, 0);
aie::accum<acc32,16> acc2;
aie::vector<int16,16> v2;
v2 = acc2.to_vector<int16>(15);
-
aie::pack
: Return a vector by converting each element into half the number of bits. -
aie::unpack
: Return a vector by converting each element into twice the number of bits.
The following is an example code of data conversion and its example output:
aie::vector<int16,16> data;
aie::print(data,true,"data=");
aie::vector<int8,16> data_smaller=data.pack();
aie::vector<int16,16> data_larger=data_smaller.unpack();
aie::print(data_smaller,true,"smaller data=");
aie::print(data_larger,true,"larger data=");
//Example output:
//data=0 1 2 -32768 -4 -5 -6 32767 3 4 126 130 -8 -9 -300 0
//smaller data=0 1 2 0 -4 -5 -6 -1 3 4 126 -126 -8 -9 -44 0
//larger data=0 1 2 0 -4 -5 -6 -1 3 4 126 -126 -8 -9 -44 0