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 reduces register spillage and improves
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_vand 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);
The API supports vector conversions between data types. It allows arbitrary conversion, for example int8 to int32.
-
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
AIE-ML v2 Block Floating-Point Conversion
Floating-point accumulator to an mx data type is available as well as mx data type to floating-point accumulator. They can be invoked as follows:
aie::accum<accfloat, 64> acc;
aie::block_vector<mx9, 64> v = acc.to_vector<mx9>(); // Convert the floating-point accumulator to an mx9 vector
acc.from_vector(v); // converts an mx9 vector into a floating-point accumulator