32-bit Vector Prepare API
void vect_s32_add_prepare()
获取用于对两个16位或32位BFP向量进行加法或减法运算的输出指数和输入位移。
本库中执行向量加法或减法的块浮点函数的一般形式如下:
和 是具有指数 和 的输入尾数向量,它们的每个元素共享相同的指数。 是具有指数 的输出尾数向量。此函数还需要两个附加属性 和 ,它们分别是尾数向量 和 的头空间。
为了避免输出尾数的溢出,必须选择输出指数 ,使得最大(绝对值意义上)可能的输出尾数适合分配的空间(例如,对于 vect_s32_add(),为32位)。一旦选择了 ,就可以计算输入位移 和 ,以实现该结果指数。
此函数选择 为已知的最小指数,以避免溢出,给定输入指数( 和 )和输入头空间( 和 )。
此函数用于计算以下每个函数的输出指数和输入位移:
- vect_s16_add()
- vect_s32_add()
- vect_s16_sub()
- vect_s32_sub()
- vect_complex_s16_add()
- vect_complex_s32_add()
- vect_complex_s16_sub()
- vect_complex_s32_sub()
参数:
-
exponent_t* a_exp– [out] 输出尾数向量 的关联指数 -
right_shift_t* b_shr– [out] 应用于 元素的有符号算术右移位数。用于计算输出尾数 的函数中使用 -
right_shift_t* c_shr– [out] 应用于 元素的有符号算术右移位数。用 于计算输出尾数 的函数中使用 -
const exponent_t b_exp– [in] BFP向量 的指数 -
const exponent_t c_exp– [in] BFP向量 的指数 -
const headroom_t b_hr– [in] BFP向量 的头空间 -
const headroom_t c_hr– [in] BFP向量 的头空间
#define vect_s32_add_scalar_prepare vect_s32_add_prepare
获取调用 vect_s32_add_scalar() 所需的输出指数和位移。
计算 vect_s32_add_scalar() 的位移和指数的逻辑与 vect_s32_add() 相同。
这个宏提供给开发人员,作为一种便利的方式,并使代码更加易读。
void vect_s32_clip_prepare()
获取用于调用 vect_s32_clip() 的输出指数、输入位移和修改的边界。
此函数与 vect_s32_clip() 结合使用,将32位BFP向量的元素限制在指定范围内。
此函数计算 a_exp、b_shr、lower_bound 和 upper_bound。
a_exp 是由 vect_s32_clip() 计算的与32位尾数向量 关联的指数。
b_shr 是 vect_s32_clip() 所需的位移参数,用于实现输出指数 a_exp。
lower_bound 和 upper_bound 是指示下限和上限剪裁边界的32位尾数。此函数会修改这些值,并应将结果值传递给 vect_s32_clip()。
b_exp 是与输入尾数向量 关联的指数。
bound_exp 是与剪裁边界 lower_bound 和 upper_bound 相关联的指数。
b_hr 是输入尾数向量 的头空间。如果未知,可以使用 vect_s32_headroom() 获取。。或者,始终可以安全地使用值 0(但可能会导致精度降低)。
参数:
-
exponent_t* a_exp– [out] 与输出尾数向量 关联的指数 -
right_shift_t* b_shr– [out] 用于 的有符号算术右移位。由vect_s32_clip()使用 -
int32_t* lower_bound– [in/out] 剪裁范围的下限 -
int32_t* upper_bound– [in/out] 剪裁范围的上限 -
const exponent_t b_exp– [in] 与输入尾数向量 关联的指数 -
const exponent_t bound_exp– [in] 与剪裁边界lower_bound和upper_bound相关联的指数 -
const headroom_t b_hr– [in] 输入尾数向量 的头空间
void vect_s32_dot_prepare()
获取用于vect_s32_dot()的输出指数和输入移位参数。
该函数与vect_s32_dot()结合使用,用于计算两个32位BFP向量的内积。
该函数计算 a_exp、b_shr 和 c_shr。
-
a_exp是由vect_s32_dot()返回的64位尾数 的指数,当计算 时必须选择足够大的值以避免饱和。为了最大化精度,该函数选择a_exp为已知能避免饱和的最小指数(参见下面的异常)。此函数选择的a_exp是根据输入向量的指数和头空间计算得出的。 -
b_shr和c_shr是由vect_s32_dot()所需的移位参数,以实现选择的输出指数a_exp。 -
b_exp和c_exp分别是与输入尾数向量 和 相关联的指数。 -
b_hr和c_hr分别是 和 的头空间。如果其中任何一个未知,可以使用vect_s32_headroom()获取。或者,始终可以安全地使用值0(但可能会导致精度降低)。 -
length是输入尾数向量 和 中的元素数量。
调整输出指数
如果需要特定的输出指数 desired_exp(例如,用于模拟定点算术),可以根据以下方式调整由该函数产生的 b_shr 和 c_shr:
exponent_t desired_exp = ...; // 先验已知值
right_shift_t new_b_shr = b_shr + (desired_exp - a_exp);
right_shift_t new_c_shr = c_shr + (desired_exp - a_exp);
在应用上述调整时,应满足以下条件:
b_hr + b_shr >= 0c_hr + c_shr >= 0
请注意,使用比 b_shr 或 c_shr 实际需要的更小的值可能会导致饱和,而使用较大的值可能会导致不必要的下溢或精度损失。
参数:
-
exponent_t *a_exp– [out] 输出尾数 的指数 -
right_shift_t *b_shr– [out]vect_s32_dot()中用于 的带符号算术右移位 -
right_shift_t *c_shr– [out]vect_s32_dot()中用于 的带符号算术右移位 -
const exponent_t b_exp– [in] 输入尾数向量 的指数 -
const exponent_t c_exp– [in] 输入尾数向量 的指数 -
const headroom_t b_hr– [in] 输入尾数向量 的头空间 -
const headroom_t c_hr– [in] 输入尾数向量 的头空间 -
const unsigned length– [in] 向量 和 中的元素数量
void vect_s32_energy_prepare()
获取用于vect_s32_energy()的输出指数和输入移位参数。
该函数与vect_s32_energy()结合使用,用于计算32位BFP向量与自身的内积。
该函数计算 a_exp 和 b_shr。
-
a_exp是由vect_s32_energy()返回的64位尾数 的指数,当计算 时必须选择足够大的值以避免饱和。为了最大化精度,该函数选择a_exp为已知能避免饱和的最小指数(参见下面的异常)。此函数选择的a_exp是根据输入向量的指数和头空间计算得出的。 -
b_shr是由vect_s32_energy()所需的移位参数,以实现选择的输出指数a_exp。 -
b_exp是与输入尾数向量 相关联的指数。 -
b_hr是 的头空间。如果未知,可以使用vect_s32_headroom()获取。或者,始终可以安全地使用值0(但可能会导致精度降低)。 -
length是输入尾数向量 中的元素数量。
调整输出指数
如果需要特定的输出指数 desired_exp(例如,用于模拟定点算术),可以根据以下方式调整由该函数产生的 b_shr:
exponent_t desired_exp = ...; // 先验已知值
right_shift_t new_b_shr = b_shr + (desired_exp - a_exp);
在应用上述调整时,应满足以下条件:
b_hr + b_shr >= 0
请注意,使用比 b_shr 实际需要的更小的值可能会导致饱和,而使用较大的值可能会导致不必要的下溢或精度损失。
参数:
-
exponent_t *a_exp– [out]vect_s32_energy()的输出的指数 -
right_shift_t *b_shr– [out] 应用于 的右移位 -
const unsigned length– [in] 向量 中的元素数量 -
const exponent_t b_exp– [in] 向量 的指数 -
const headroom_t b_hr– [in] 向量 的头空间
void vect_s32_inverse_prepare()
获取vect_s32_inverse()函数使用的输出指数和缩放因子。
此函数与vect_s32_inverse()一起用于计算32位BFP向量元素的倒数。
此函数计算a_exp和scale。
-
a_exp是与输出尾数向量 关联的指数,必须选择以避免输入向量中最小元素的溢出,因为倒数后它成为最大的输出元素。为了最大化精度,此函数选择a_exp作为已知的最小指数,以避免饱和。此函数选择的a_exp由输入向量的指数和最小元素派生。 -
scale是vect_s32_inverse()使用的缩放参数,用于实现所选择的输出指数。 -
b[]是输入尾数向量 。 -
b_exp是与输入尾数向量 关联的指数。 -
length是向量 中的元素数量。
参数:
-
exponent_t *a_exp– [out] 输出向量 的指数 -
unsigned *scale– [out] 在计算倒数时应用的缩放因子 -
const int32_t b[]– [in] 输入向量 -
const exponent_t b_exp– [in] 的指数 -
const unsigned length– [in] 向量 中的元素数量
void vect_s32_macc_prepare()
获取vect_s32_macc()函数的输出指数和位移。
此函数与vect_s32_macc()一起 使用,用于对32位BFP向量进行逐元素乘积累加。
该函数计算new_acc_exp、acc_shr、b_shr和c_shr,这些值被选择为在不引起最终或中间值饱和的情况下,最大化累加器向量的精度。通常,调用者将把这些输出传递给vect_s32_macc()的相应输入参数。
acc_exp是操作前与累加器尾数向量 相关联的指数,而new_acc_exp是与更新后的累加器向量对应的指数。
b_exp和c_exp是与复数输入尾数向量 和 相关联的指数。
acc_hr、b_hr和c_hr分别是 、 和 的头空间。如果这些向量中任何一个的头空间未知,可以通过调用vect_s32_headroom()来获取。或者,总是可以安全地使用值0(但可能会导致降低精度)。
参数:
exponent_t* new_acc_exp– [out] 与输出尾数向量 (在macc之后)相关联的指数right_shift_t* acc_shr– [out]vect_s32_macc()中用于 的有符号算术右移位right_shift_t* b_shr– [out]vect_s32_macc()中用于 的有符号算术右移位right_shift_t* c_shr– [out]vect_s32_macc()中用于 的有符号算术右移位const exponent_t acc_exp– [in] 与输入尾数向量 (在macc之前)相关联的指数const exponent_t b_exp– [in] 与输入尾数向量 相关联的指数const exponent_t c_exp– [in] 与输入尾数向量 相关联的指数const headroom_t acc_hr– [in] 输入尾数向量 (在macc之前)的头空间const headroom_t b_hr– [in] 输入尾数向量 的头空间const headroom_t c_hr– [in] 输入尾数向量 的头空间
调整输出指数
如果需要特定的输出指数 desired_exp 用于结果(例如用于模拟定点算术),可以根据以下方式调整该函数产生的 acc_shr 和 bc_sat:
// 假设在某处设置了以下变量
exponent_t acc_exp, b_exp, c_exp;
headroom_t acc_hr, b_hr, c_hr;
exponent_t desired_exp;
...
// 调用 prepare
right_shift_t acc_shr, b_shr, c_shr;
vect_s32_macc_prepare(&acc_exp, &acc_shr, &b_shr, &c_shr,
acc_exp, b_exp, c_exp,
acc_hr, b_hr, c_hr);
// 修改结果
right_shift_t mant_shr = desired_exp - acc_exp;
acc_exp += mant_shr;
acc_shr += mant_shr;
b_shr += mant_shr;
c_shr += mant_shr;
// 现在可以使用 acc_shr、b_shr 和 c_shr 调用 vect_s32_macc()
在应用上述调整时,应保持以下条件:
acc_shr > -acc_hr(进一步左移可能会导致饱和)b_shr => -b_hr(进一步左移可能会导致饱和)c_shr => -c_hr(进一步左移可能会导致饱和)
用户需要确保任何此类修改不会导致饱和或无法接受的精度损失。
#define vect_s32_nmacc_prepare vect_s32_macc_prepare
获取调用 vect_s32_nmacc() 所需的输出指数和位移。
计算 vect_s32_nmacc() 的位移和指数的逻辑与 vect_s32_macc_prepare() 完全相同。
该宏提供给开发人员作为便利,并且使代码更具可读性。
void vect_s32_mul_prepare()
获取 vect_s32_mul() 使用的输出指数和输入位移。
此函数与 vect_s32_mul() 结合使用,对两个32位BFP向量进行逐元素乘法运算。
该函数计算 a_exp、b_shr 和 c_shr。
a_exp 是与尾数向量 相关联的指数,必须选择足够大的值,以避免计算 元素时的溢出。为了最大化精度,该函数选择 a_exp 作为已知的最小指数,以避免饱和(见下面的异常)。该函数选择的 a_exp 是根据输入向量的指数和头空间推导出来的。
b_shr 和 c_shr 是 vect_complex_s32_mul() 所需的位移参数,用于实现选择的输出指数 a_exp。
b_exp 和 c_exp 分别是与输入尾数向量 和 相关联的指数。
b_hr 和 c_hr 分别是 和 的头空间。如果 或 的头空间未知,可以调用vect_s32_headroom() 获取。或者,始终可以安全地使用值 0(但可能会导致降低精度)。
调整输出指数:
如果需要特定的输出指数 desired_exp(例如,用于模拟定点算术),可以根据以下方式调整由此函数生成的 b_shr 和 c_shr:
exponent_t desired_exp = ...; // 先验已知值
right_shift_t new_b_shr = b_shr + (desired_exp - a_exp);
right_shift_t new_c_shr = c_shr + (desired_exp - a_exp);
在应用上述调整时,应保持以下条件:
b_hr + b_shr >= 0c_hr + c_shr >= 0
请注意,使用比 b_shr 和 c_shr 严格需要的更小的值可能会导致饱和,而使用更大的值可能会导致不必要的下溢或精度损失。
注意事项:
- 使用此函数的输出,原本将为
INT32_MIN的输出尾数将饱和为-INT32_MAX。这是由VPU使用的对称饱和逻辑决定的硬件特性。这是一个通常不太可能发生的边界情况,当发生 时会产生1个LSb的误差。
参数:
-
exponent_t *a_exp– [out]vect_s32_mul()输出元素的指数 -
right_shift_t *b_shr– [out] 应用于 元素的右移量 -
right_shift_t *c_shr– [out] 应用于 元素的右移量 -
const exponent_t b_exp– [in] 的指数 -
const exponent_t c_exp– [in] 的指数 -
const headroom_t b_hr– [in] 的头空间 -
const headroom_t c_hr– [in] 的头空间
另请参阅: vect_s32_mul
#define vect_s32_scale_prepare vect_s32_mul_prepare
获取调用vect_s32_scale()所需的输出指数和位移。
计算vect_s32_scale()的位移和指数的逻辑与vect_s32_mul()相同。
这个宏的目的是为了方便开发人员,并使代码更易读。
有关更多详细信息,请参阅vect_s32_mul_prepare()。
void vect_s32_sqrt_prepare()
获取vect_s32_sqrt()使用的输出指数和位移参数。
此函数与vect_s32_sqrt()结合使用,用于计算32位BFP向量元素的平方根。
此函数计算a_exp和b_shr。
-
a_exp是与输出尾数向量 关联的指数,并且应该选择以最大化结果的精度。此函数选择a_exp作为已知的最小指数,以避免饱和结果尾数向量 。它是从输入BFP向量的指数和头空间派生的。 -
b_shr是vect_s32_sqrt()所需的位移参数,以实现所选择的输出指数a_exp。 -
b_exp是与输入尾数向量 关联的指数。 -
b_hr是 的头空间。如果未知,可以使用vect_s32_headroom()获取。或者,始终可以安全地使用值0(但可能会导致精度降低)。
调整输出指数
如果需要特定的输出指数desired_exp(例如,用于模拟定点算术),则可以根据以下方式调整此函数生成的b_shr:
exponent_t a_exp;
right_shift_t b_shr;
vect_s16_mul_prepare(&a_exp, &b_shr, b_exp, c_exp, b_hr, c_hr);
exponent_t desired_exp = ...; // a priori已知的值
b_shr = b_shr + (desired_exp - a_exp);
a_exp = desired_exp;
在应用上述调整时,应满足以下条件:
b_hr + b_shr >= 0
请注意,使用比b_shr严格要求的较小值可能会导致饱和,而使用较大值可能会导致不必要的下溢或精度损失。
此外,如果使用比所需更大的指数,则需要更大的depth参数(参见vect_s32_sqrt())以实现相同的精度, 因为结果是逐位计算的,从最高有效位开始。
参数:
-
exponent_t* a_exp– [out]vect_s32_sqrt()的输出指数 -
right_shift_t* b_shr– [out] 应用于 元素的右移位数 -
const exponent_t b_exp– [in] 的指数 -
const right_shift_t b_hr– [in] 的头空间
有关更多详细信息,请参阅vect_s32_sqrt。
#define vect_s32_sub_prepare vect_s32_add_prepare
获取调用vect_s32_sub()所需的输出指数和位移。
计算vect_s32_sub()的位移和指数的逻辑与vect_s32_add()完全相同。
提供此宏是为了方便开发人员,并使代码更可读。
另请参见: vect_s32_add_prepare()
void vect_2vec_prepare()
获取执行二进制加法类操作所需的输出指数和输入位移。
此函数计算执行二进制加法类操作所需的输出指数和输入位移。这些操作需要输入向量在使用其尾数执行操作之前共享一个指数。
在这里,“加法类”操作宽泛地定义为需要输入向量在其尾数可以有意义地用于执行该操作之前共享一个指数的操作。
例如,考虑 。如果 ,那么尾数可以直接相加得到有意义的结果 。但是,如果 ,则将尾数相加是没有意义的。在这种情况下,在执行尾数 相加之前,必须将一个或两个输入尾数进行位移,使表示相应指数的表示相符。类似的逻辑也适用于二进制比较。
这与“乘法类”操作相反,后者不具有相同的要求(例如,,无论 如何)。
对于如下的一般操作:
和 是具有指数 和 的输入尾数向量,它们被它们各自向量的每个元素共享。 是具有指数 的输出尾数向量。此函数还需要 和 的两个额外属性 和 ,它们分别是尾数向量 和 的头空间。
除了 之外,此函数还使用 和 来计算位移 和 ,这些位移是应用于尾数向量 和 的有符号算术右移,以便应用加法类 操作。
此函数选择 作为可以在不使尾数饱和的情况下同时表示 和 的最小指数,并且使 和 至少具有 extra_operand_hr 位的头空间。位移 和 是根据 使用 和 计算得出的。
参数:
-
exponent_t* a_exp– [out] 输出尾数向量 的关联指数 -
right_shift_t* b_shr– [out] 应用于 元素的有符号算术右移。用于计算输出尾数 的函数中使用 -
right_shift_t* c_shr– [out] 应用于 元素的有符号算术右移。用于计算输出尾数 的函数中使用 -
const exponent_t b_exp– [in] BFP向量 的指数 -
const exponent_t c_exp– [in] BFP向量 的指数 -
const headroom_t b_hr– [in] BFP向量 的头空间 -
const headroom_t c_hr– [in] BFP向量 的头空间 -
const headroom_t extra_operand_hr– [in] 执行操作所需的尾数向量中将保留的最小头空间量
调整输出指数:
如果结果需要特定的输出指数 desired_exp(例如,用于模拟定点算术),可以根据以下方式调整由此函数生成的 b_shr 和 c_shr:
exponent_t desired_exp = ...; // 先验已知值
right_shift_t new_b_shr = b_shr + (desired_exp - a_exp);
right_shift_t new_c_shr = c_shr + (desired_exp - a_exp);
在应用上述调整时,应满足以下条件:
b_hr + b_shr >= 0c_hr + c_shr >= 0
请注意,使用比严格必要的更小值来调整 b_shr 和 c_shr 可能会导致饱和,而使用较大的值可能会导致不必要的下溢或精度丢失。
备注:
- 如果 或 是未知的,可以使用适当的头空间函数(例如,vect_complex_s16_headroom() 用于复数16位向量)来计算 它们,或者始终安全地使用值
0(但可能会导致减少的精度)。