NumPy-源码解析-五十六-

135 阅读1小时+

NumPy 源码解析(五十六)

.\numpy\numpy\_core\src\common\simd\neon\conversion.h

#ifndef NPY_SIMD
    #error "Not a standalone header"
#endif

#ifndef _NPY_SIMD_NEON_CVT_H
#define _NPY_SIMD_NEON_CVT_H

// convert boolean vectors to integer vectors
#define npyv_cvt_u8_b8(A)   A
// reinterpret unsigned 8-bit vector as signed 8-bit vector
#define npyv_cvt_s8_b8   vreinterpretq_s8_u8
#define npyv_cvt_u16_b16(A) A
// reinterpret unsigned 16-bit vector as signed 16-bit vector
#define npyv_cvt_s16_b16 vreinterpretq_s16_u16
#define npyv_cvt_u32_b32(A) A
// reinterpret unsigned 32-bit vector as signed 32-bit vector
#define npyv_cvt_s32_b32 vreinterpretq_s32_u32
#define npyv_cvt_u64_b64(A) A
// reinterpret unsigned 64-bit vector as signed 64-bit vector
#define npyv_cvt_s64_b64 vreinterpretq_s64_u64
// reinterpret unsigned 32-bit vector as float 32-bit vector
#define npyv_cvt_f32_b32 vreinterpretq_f32_u32
// reinterpret unsigned 64-bit vector as float 64-bit vector
#define npyv_cvt_f64_b64 vreinterpretq_f64_u64

// convert integer vectors to boolean vectors
#define npyv_cvt_b8_u8(BL)   BL
// reinterpret unsigned 8-bit vector as signed 8-bit vector
#define npyv_cvt_b8_s8   vreinterpretq_u8_s8
#define npyv_cvt_b16_u16(BL) BL
// reinterpret unsigned 16-bit vector as signed 16-bit vector
#define npyv_cvt_b16_s16 vreinterpretq_u16_s16
#define npyv_cvt_b32_u32(BL) BL
// reinterpret unsigned 32-bit vector as signed 32-bit vector
#define npyv_cvt_b32_s32 vreinterpretq_u32_s32
#define npyv_cvt_b64_u64(BL) BL
// reinterpret unsigned 64-bit vector as signed 64-bit vector
#define npyv_cvt_b64_s64 vreinterpretq_u64_s64
// reinterpret unsigned 32-bit vector as float 32-bit vector
#define npyv_cvt_b32_f32 vreinterpretq_u32_f32
// reinterpret unsigned 64-bit vector as float 64-bit vector
#define npyv_cvt_b64_f64 vreinterpretq_u64_f64

// convert boolean vector to integer bitfield
NPY_FINLINE npy_uint64 npyv_tobits_b8(npyv_b8 a)
{
    // Define scaling factors for bits
    const npyv_u8 scale = npyv_set_u8(1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128);
    // Apply bitwise AND to extract scaled bits
    npyv_u8 seq_scale = vandq_u8(a, scale);
#if defined(__aarch64__)
    // Define byteOrder for AArch64 architecture
    const npyv_u8 byteOrder = {0,8,1,9,2,10,3,11,4,12,5,13,6,14,7,15};
    // Rearrange seq_scale according to byteOrder
    npyv_u8 v0 = vqtbl1q_u8(seq_scale, byteOrder);
    // Sum the values horizontally and return as 64-bit unsigned integer
    return vaddlvq_u16(vreinterpretq_u16_u8(v0));
#else
    // Sum seq_scale values horizontally and return as 64-bit unsigned integer
    npyv_u64 sumh = vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(seq_scale)));
    return vgetq_lane_u64(sumh, 0) + ((int)vgetq_lane_u64(sumh, 1) << 8);
#endif
}

NPY_FINLINE npy_uint64 npyv_tobits_b16(npyv_b16 a)
{
    // Define scaling factors for bits
    const npyv_u16 scale = npyv_set_u16(1, 2, 4, 8, 16, 32, 64, 128);
    // Apply bitwise AND to extract scaled bits
    npyv_u16 seq_scale = vandq_u16(a, scale);
#if NPY_SIMD_F64
    // Sum seq_scale values and return as 64-bit unsigned integer
    return vaddvq_u16(seq_scale);
#else
    // Sum seq_scale values horizontally and return as 64-bit unsigned integer
    npyv_u64 sumh = vpaddlq_u32(vpaddlq_u16(seq_scale));
    return vgetq_lane_u64(sumh, 0) + vgetq_lane_u64(sumh, 1);
#endif
}

NPY_FINLINE npy_uint64 npyv_tobits_b32(npyv_b32 a)
{
    // Define scaling factors for bits
    const npyv_u32 scale = npyv_set_u32(1, 2, 4, 8);
    // Apply bitwise AND to extract scaled bits
    npyv_u32 seq_scale = vandq_u32(a, scale);
#if NPY_SIMD_F64
    // Sum seq_scale values and return as 64-bit unsigned integer
    return vaddvq_u32(seq_scale);
#else
    // Sum seq_scale values horizontally and return as 64-bit unsigned integer
    npyv_u64 sumh = vpaddlq_u32(seq_scale);
    return vgetq_lane_u64(sumh, 0) + vgetq_lane_u64(sumh, 1);
#endif
}

NPY_FINLINE npy_uint64 npyv_tobits_b64(npyv_b64 a)
{
    // Extract and combine bits from a 64-bit vector into a 64-bit integer
    uint64_t lo = vgetq_lane_u64(a, 0);
    uint64_t hi = vgetq_lane_u64(a, 1);
    return ((hi & 0x2) | (lo & 0x1));
}

//expand
// Expand 8-bit unsigned integers to 16-bit unsigned integers
NPY_FINLINE npyv_u16x2 npyv_expand_u16_u8(npyv_u8 data) {
    npyv_u16x2 r;
    // Expand lower 8 bytes to 16 bytes
    r.val[0] = vmovl_u8(vget_low_u8(data));
    // Expand higher 8 bytes to 16 bytes
    r.val[1] = vmovl_u8(vget_high_u8(data));
    return r;
}

// Expand 16-bit unsigned integers to 32-bit unsigned integers
NPY_FINLINE npyv_u32x2 npyv_expand_u32_u16(npyv_u16 data) {
    npyv_u32x2 r;
    // Expand lower 16 bytes to 32 bytes
    r.val[0] = vmovl_u16(vget_low_u16(data));
    // Expand higher 16 bytes to 32 bytes
    r.val[1] = vmovl_u16(vget_high_u16(data));
    return r;
}

// pack two 16-bit boolean into one 8-bit boolean vector
NPY_FINLINE npyv_b8 npyv_pack_b8_b16(npyv_b16 a, npyv_b16 b) {
#if defined(__aarch64__)
    // 将参数 a 和 b 转换为 uint8x16_t 类型的向量,并执行无符号 8 位整数对齐加密(vuzp1q_u8)操作,
    // 返回结果向量。
    return vuzp1q_u8((uint8x16_t)a, (uint8x16_t)b);
// pack four 32-bit boolean vectors into one 8-bit boolean vector
NPY_FINLINE npyv_b8
npyv_pack_b8_b32(npyv_b32 a, npyv_b32 b, npyv_b32 c, npyv_b32 d) {
#if defined(__aarch64__)
    // Interleave the lower halves of vectors a and b, and c and d
    npyv_b16 ab = vuzp1q_u16((uint16x8_t)a, (uint16x8_t)b);
    npyv_b16 cd = vuzp1q_u16((uint16x8_t)c, (uint16x8_t)d);
#else
    // Combine and narrow the 32-bit vectors a, b, c, and d to 16-bit vectors ab and cd
    npyv_b16 ab = vcombine_u16(vmovn_u32(a), vmovn_u32(b));
    npyv_b16 cd = vcombine_u16(vmovn_u32(c), vmovn_u32(d));
#endif
    // Pack the 16-bit boolean vectors ab and cd into one 8-bit boolean vector
    return npyv_pack_b8_b16(ab, cd);
}

// pack eight 64-bit boolean vectors into one 8-bit boolean vector
NPY_FINLINE npyv_b8
npyv_pack_b8_b64(npyv_b64 a, npyv_b64 b, npyv_b64 c, npyv_b64 d,
                 npyv_b64 e, npyv_b64 f, npyv_b64 g, npyv_b64 h) {
#if defined(__aarch64__)
    // Interleave the lower halves of vectors a, b, c, d, e, f, g, and h
    npyv_b32 ab = vuzp1q_u32((uint32x4_t)a, (uint32x4_t)b);
    npyv_b32 cd = vuzp1q_u32((uint32x4_t)c, (uint32x4_t)d);
    npyv_b32 ef = vuzp1q_u32((uint32x4_t)e, (uint32x4_t)f);
    npyv_u32 gh = vuzp1q_u32((uint32x4_t)g, (uint32x4_t)h);
#else
    // Combine and narrow the 64-bit vectors a, b, c, d, e, f, g, and h to 32-bit vectors ab, cd, ef, and gh
    npyv_b32 ab = vcombine_u32(vmovn_u64(a), vmovn_u64(b));
    npyv_b32 cd = vcombine_u32(vmovn_u64(c), vmovn_u64(d));
    npyv_b32 ef = vcombine_u32(vmovn_u64(e), vmovn_u64(f));
    npyv_b32 gh = vcombine_u32(vmovn_u64(g), vmovn_u64(h));
#endif
    // Pack the 32-bit boolean vectors ab, cd, ef, and gh into one 8-bit boolean vector
    return npyv_pack_b8_b32(ab, cd, ef, gh);
}

// round to nearest integer
#if NPY_SIMD_F64
    #define npyv_round_s32_f32 vcvtnq_s32_f32
    // Round each element of vectors a and b to the nearest 32-bit signed integer
    NPY_FINLINE npyv_s32 npyv_round_s32_f64(npyv_f64 a, npyv_f64 b)
    {
        npyv_s64 lo = vcvtnq_s64_f64(a), hi = vcvtnq_s64_f64(b);
        // Combine the lower halves of vectors lo and hi into a 32-bit vector
        return vcombine_s32(vmovn_s64(lo), vmovn_s64(hi));
    }
#else
    // Round each element of vector a to the nearest 32-bit signed integer
    NPY_FINLINE npyv_s32 npyv_round_s32_f32(npyv_f32 a)
    {
        // Set the sign bit mask to 0x80000000
        const npyv_u32 sign = vdupq_n_u32(0x80000000);
        // Set the half value to 0.5
        const npyv_f32 half = vdupq_n_f32(0.5f);
        // Conditionally select the sign bit or half depending on the sign of a
        npyv_f32 sign_half = vbslq_f32(sign, a, half);
        // Round each element of vector a to the nearest 32-bit signed integer
        return vcvtq_s32_f32(vaddq_f32(a, sign_half));
    }
#endif

.\numpy\numpy\_core\src\common\simd\neon\math.h

#ifndef NPY_SIMD
    #error "Not a standalone header"
#endif

#ifndef _NPY_SIMD_NEON_MATH_H
#define _NPY_SIMD_NEON_MATH_H

/***************************
 * Elementary
 ***************************/

// Absolute
#define npyv_abs_f32 vabsq_f32
#define npyv_abs_f64 vabsq_f64

// Square
// 定义计算单精度浮点数向量平方的函数
NPY_FINLINE npyv_f32 npyv_square_f32(npyv_f32 a)
{ return vmulq_f32(a, a); }
#if NPY_SIMD_F64
    // 定义计算双精度浮点数向量平方的函数
    NPY_FINLINE npyv_f64 npyv_square_f64(npyv_f64 a)
    { return vmulq_f64(a, a); }
#endif

// Square root
#if NPY_SIMD_F64
    // 对双精度浮点数向量进行平方根计算
    #define npyv_sqrt_f32 vsqrtq_f32
    #define npyv_sqrt_f64 vsqrtq_f64
#else
    // 基于 ARM 文档,参考 https://developer.arm.com/documentation/dui0204/j/CIHDIACI
    // 定义计算单精度浮点数向量平方根的函数
    NPY_FINLINE npyv_f32 npyv_sqrt_f32(npyv_f32 a)
    {
        // 定义常量
        const npyv_f32 zero = vdupq_n_f32(0.0f);
        const npyv_u32 pinf = vdupq_n_u32(0x7f800000);
        // 检查是否为零或无穷大
        npyv_u32 is_zero = vceqq_f32(a, zero), is_inf = vceqq_u32(vreinterpretq_u32_f32(a), pinf);
        // 防止浮点数除零错误
        npyv_f32 guard_byz = vbslq_f32(is_zero, vreinterpretq_f32_u32(pinf), a);
        // 估算 (1/√a)
        npyv_f32 rsqrte = vrsqrteq_f32(guard_byz);
        /**
         * 牛顿-拉弗森迭代法:
         *  x[n+1] = x[n] * (3-d * (x[n]*x[n]) )/2)
         * 当 x0 是应用于 d 的 VRSQRTE 的结果时,收敛到 (1/√d)。
         *
         * 注意:至少需要 3 次迭代以提高精度
         */
        rsqrte = vmulq_f32(vrsqrtsq_f32(vmulq_f32(a, rsqrte), rsqrte), rsqrte);
        rsqrte = vmulq_f32(vrsqrtsq_f32(vmulq_f32(a, rsqrte), rsqrte), rsqrte);
        rsqrte = vmulq_f32(vrsqrtsq_f32(vmulq_f32(a, rsqrte), rsqrte), rsqrte);
        // a * (1/√a)
        npyv_f32 sqrt = vmulq_f32(a, rsqrte);
        // 如果 a 是零,则返回零;如果 a 是正无穷大,则返回正无穷大
        return vbslq_f32(vorrq_u32(is_zero, is_inf), a, sqrt);
    }
#endif // NPY_SIMD_F64

// Reciprocal
// 定义计算单精度浮点数向量倒数的函数
NPY_FINLINE npyv_f32 npyv_recip_f32(npyv_f32 a)
{
#if NPY_SIMD_F64
    // 定义计算双精度浮点数向量倒数的函数
    const npyv_f32 one = vdupq_n_f32(1.0f);
    return npyv_div_f32(one, a);
#else
    // 使用 VRECPE 应用于 d 的结果 x0,收敛到 (1/d) 的牛顿-拉弗森迭代法:
    npyv_f32 recipe = vrecpeq_f32(a);
    recipe = vmulq_f32(vrecpsq_f32(a, recipe), recipe);
    recipe = vmulq_f32(vrecpsq_f32(a, recipe), recipe);
    recipe = vmulq_f32(vrecpsq_f32(a, recipe), recipe);
    return recipe;
#endif
}
#if NPY_SIMD_F64
    // 定义计算双精度浮点数向量倒数的函数
    NPY_FINLINE npyv_f64 npyv_recip_f64(npyv_f64 a)
    {
        const npyv_f64 one = vdupq_n_f64(1.0);
        return npyv_div_f64(one, a);
    }
#endif // NPY_SIMD_F64

// Maximum, natively mapping with no guarantees to handle NaN.
// 定义计算单精度浮点数向量最大值的宏,无法保证处理 NaN
#define npyv_max_f32 vmaxq_f32
#define npyv_max_f64 vmaxq_f64
// Maximum, supports IEEE floating-point arithmetic (IEC 60559),
// 支持 IEEE 浮点数算术(IEC 60559#endif // _NPY_SIMD_NEON_MATH_H
#ifdef NPY_HAVE_ASIMD
    // 如果使用 ASIMD 指令集,定义 npyv_maxp_f32 为 vmaxnmq_f32 函数
    #define npyv_maxp_f32 vmaxnmq_f32
#else
    // 如果未使用 ASIMD 指令集,定义 npyv_maxp_f32 函数
    NPY_FINLINE npyv_f32 npyv_maxp_f32(npyv_f32 a, npyv_f32 b)
    {
        // 使用 vceqq_f32 函数比较 a 是否为 NaN,结果存储在 nn_a 中
        npyv_u32 nn_a = vceqq_f32(a, a);
        // 使用 vceqq_f32 函数比较 b 是否为 NaN,结果存储在 nn_b 中
        npyv_u32 nn_b = vceqq_f32(b, b);
        // 返回根据 nn_a 和 nn_b 条件选择的最大值向量
        return vmaxq_f32(vbslq_f32(nn_a, a, b), vbslq_f32(nn_b, b, a));
    }
#endif

// 定义 npyv_maxn_f32 函数为 vmaxq_f32 函数
// 最大化函数,传播 NaN
// 如果任意对应的元素是 NaN,则设置 NaN
#define npyv_maxn_f32 vmaxq_f32

#if NPY_SIMD_F64
    // 如果支持双精度 SIMD 计算
    // 定义 npyv_maxp_f64 函数为 vmaxnmq_f64 函数
    #define npyv_maxp_f64 vmaxnmq_f64
    // 定义 npyv_maxn_f64 函数为 vmaxq_f64 函数
    #define npyv_maxn_f64 vmaxq_f64
#endif // NPY_SIMD_F64

// 最大化函数,整数操作
#define npyv_max_u8 vmaxq_u8
#define npyv_max_s8 vmaxq_s8
#define npyv_max_u16 vmaxq_u16
#define npyv_max_s16 vmaxq_s16
#define npyv_max_u32 vmaxq_u32
#define npyv_max_s32 vmaxq_s32

// 定义 npyv_max_u64 函数
// 返回 a 和 b 中每个元素的最大值
NPY_FINLINE npyv_u64 npyv_max_u64(npyv_u64 a, npyv_u64 b)
{
    // 使用 vbslq_u64 函数根据 npyv_cmpgt_u64(a, b) 的结果选择 a 或 b 中的元素
    return vbslq_u64(npyv_cmpgt_u64(a, b), a, b);
}

// 定义 npyv_max_s64 函数
// 返回 a 和 b 中每个元素的最大值
NPY_FINLINE npyv_s64 npyv_max_s64(npyv_s64 a, npyv_s64 b)
{
    // 使用 vbslq_s64 函数根据 npyv_cmpgt_s64(a, b) 的结果选择 a 或 b 中的元素
    return vbslq_s64(npyv_cmpgt_s64(a, b), a, b);
}

// 最小化函数,本地映射,不保证处理 NaN
#define npyv_min_f32 vminq_f32
#define npyv_min_f64 vminq_f64

// 最小化函数,支持 IEEE 浮点运算 (IEC 60559)
// - 如果两个向量中的一个包含 NaN,则设置另一个向量中相应的元素
// - 只有当两个对应元素都是 NaN 时,才设置 NaN
#ifdef NPY_HAVE_ASIMD
    // 如果使用 ASIMD 指令集,定义 npyv_minp_f32 为 vminnmq_f32 函数
    #define npyv_minp_f32 vminnmq_f32
#else
    // 如果未使用 ASIMD 指令集,定义 npyv_minp_f32 函数
    NPY_FINLINE npyv_f32 npyv_minp_f32(npyv_f32 a, npyv_f32 b)
    {
        // 使用 vceqq_f32 函数比较 a 是否为 NaN,结果存储在 nn_a 中
        npyv_u32 nn_a = vceqq_f32(a, a);
        // 使用 vceqq_f32 函数比较 b 是否为 NaN,结果存储在 nn_b 中
        npyv_u32 nn_b = vceqq_f32(b, b);
        // 返回根据 nn_a 和 nn_b 条件选择的最小值向量
        return vminq_f32(vbslq_f32(nn_a, a, b), vbslq_f32(nn_b, b, a));
    }
#endif

// 定义 npyv_minn_f32 函数为 vminq_f32 函数
// 最小化函数,传播 NaN
// 如果任意对应的元素是 NaN,则设置 NaN
#define npyv_minn_f32 vminq_f32

#if NPY_SIMD_F64
    // 如果支持双精度 SIMD 计算
    // 定义 npyv_minp_f64 函数为 vminnmq_f64 函数
    #define npyv_minp_f64 vminnmq_f64
    // 定义 npyv_minn_f64 函数为 vminq_f64 函数
    #define npyv_minn_f64 vminq_f64
#endif // NPY_SIMD_F64

// 最小化函数,整数操作
#define npyv_min_u8 vminq_u8
#define npyv_min_s8 vminq_s8
#define npyv_min_u16 vminq_u16
#define npyv_min_s16 vminq_s16
#define npyv_min_u32 vminq_u32
#define npyv_min_s32 vminq_s32

// 定义 npyv_min_u64 函数
// 返回 a 和 b 中每个元素的最小值
NPY_FINLINE npyv_u64 npyv_min_u64(npyv_u64 a, npyv_u64 b)
{
    // 使用 vbslq_u64 函数根据 npyv_cmplt_u64(a, b) 的结果选择 a 或 b 中的元素
    return vbslq_u64(npyv_cmplt_u64(a, b), a, b);
}

// 定义 npyv_min_s64 函数
// 返回 a 和 b 中每个元素的最小值
NPY_FINLINE npyv_s64 npyv_min_s64(npyv_s64 a, npyv_s64 b)
{
    // 使用 vbslq_s64 函数根据 npyv_cmplt_s64(a, b) 的结果选择 a 或 b 中的元素
    return vbslq_s64(npyv_cmplt_s64(a, b), a, b);
}

// 减少所有数据类型的最小/最大值
#if NPY_SIMD_F64
    // 如果支持双精度 SIMD 计算
    #define npyv_reduce_max_u8 vmaxvq_u8
    #define npyv_reduce_max_s8 vmaxvq_s8
    #define npyv_reduce_max_u16 vmaxvq_u16
    #define npyv_reduce_max_s16 vmaxvq_s16
    #define npyv_reduce_max_u32 vmaxvq_u32
    #define npyv_reduce_max_s32 vmaxvq_s32

    #define npyv_reduce_max_f32 vmaxvq_f32
    #define npyv_reduce_max_f64 vmaxvq_f64
    #define npyv_reduce_maxn_f32 vmaxvq_f32
    #define npyv_reduce_maxn_f64 vmaxvq_f64
    #define npyv_reduce_maxp_f32 vmaxnmvq_f32
#endif
    #define npyv_reduce_maxp_f64 vmaxnmvq_f64
    
    定义了一个宏 `npyv_reduce_maxp_f64`,用于表示将向量中的浮点数类型的元素进行最大值约简。
    
    
    #define npyv_reduce_min_u8 vminvq_u8
    
    定义了一个宏 `npyv_reduce_min_u8`,用于表示将向量中的无符号8位整数类型的元素进行最小值约简。
    
    
    #define npyv_reduce_min_s8 vminvq_s8
    
    定义了一个宏 `npyv_reduce_min_s8`,用于表示将向量中的有符号8位整数类型的元素进行最小值约简。
    
    
    #define npyv_reduce_min_u16 vminvq_u16
    
    定义了一个宏 `npyv_reduce_min_u16`,用于表示将向量中的无符号16位整数类型的元素进行最小值约简。
    
    
    #define npyv_reduce_min_s16 vminvq_s16
    
    定义了一个宏 `npyv_reduce_min_s16`,用于表示将向量中的有符号16位整数类型的元素进行最小值约简。
    
    
    #define npyv_reduce_min_u32 vminvq_u32
    
    定义了一个宏 `npyv_reduce_min_u32`,用于表示将向量中的无符号32位整数类型的元素进行最小值约简。
    
    
    #define npyv_reduce_min_s32 vminvq_s32
    
    定义了一个宏 `npyv_reduce_min_s32`,用于表示将向量中的有符号32位整数类型的元素进行最小值约简。
    
    
    #define npyv_reduce_min_f32 vminvq_f32
    
    定义了一个宏 `npyv_reduce_min_f32`,用于表示将向量中的单精度浮点数类型的元素进行最小值约简。
    
    
    #define npyv_reduce_min_f64 vminvq_f64
    
    定义了一个宏 `npyv_reduce_min_f64`,用于表示将向量中的双精度浮点数类型的元素进行最小值约简。
    
    
    #define npyv_reduce_minn_f32 vminvq_f32
    
    定义了一个宏 `npyv_reduce_minn_f32`,用于表示将向量中的单精度浮点数类型的元素进行最小值约简。
    
    
    #define npyv_reduce_minn_f64 vminvq_f64
    
    定义了一个宏 `npyv_reduce_minn_f64`,用于表示将向量中的双精度浮点数类型的元素进行最小值约简。
    
    
    #define npyv_reduce_minp_f32 vminnmvq_f32
    
    定义了一个宏 `npyv_reduce_minp_f32`,用于表示将向量中的单精度浮点数类型的元素进行带负最小值约简。
    
    
    #define npyv_reduce_minp_f64 vminnmvq_f64
    
    定义了一个宏 `npyv_reduce_minp_f64`,用于表示将向量中的双精度浮点数类型的元素进行带负最小值约简。
#else
    // 定义 NEON 求最小值和最大值的宏函数
    #define NPY_IMPL_NEON_REDUCE_MINMAX(INTRIN, STYPE, SFX)                            \
        // 实现 NEON 向量的最小值或最大值求解函数
        NPY_FINLINE npy_##STYPE npyv_reduce_##INTRIN##_##SFX(npyv_##SFX a)             \
        {                                                                              \
            // 使用 NEON 指令求取向量的最小值或最大值
            STYPE##x8_t r = vp##INTRIN##_##SFX(vget_low_##SFX(a), vget_high_##SFX(a)); \
                        r = vp##INTRIN##_##SFX(r, r);                                  \
                        r = vp##INTRIN##_##SFX(r, r);                                  \
                        r = vp##INTRIN##_##SFX(r, r);                                  \
            // 返回结果向量中的第一个元素作为标量结果
            return (npy_##STYPE)vget_lane_##SFX(r, 0);                                 \
        }
    // 实例化 uint8 类型的最小值和最大值求解函数
    NPY_IMPL_NEON_REDUCE_MINMAX(min, uint8, u8)
    NPY_IMPL_NEON_REDUCE_MINMAX(max, uint8, u8)
    // 实例化 int8 类型的最小值和最大值求解函数
    NPY_IMPL_NEON_REDUCE_MINMAX(min, int8, s8)
    NPY_IMPL_NEON_REDUCE_MINMAX(max, int8, s8)
    // 取消宏定义 NPY_IMPL_NEON_REDUCE_MINMAX
    #undef NPY_IMPL_NEON_REDUCE_MINMAX

    // 定义 NEON 求最小值和最大值的宏函数
    #define NPY_IMPL_NEON_REDUCE_MINMAX(INTRIN, STYPE, SFX)                            \
        // 实现 NEON 向量的最小值或最大值求解函数
        NPY_FINLINE npy_##STYPE npyv_reduce_##INTRIN##_##SFX(npyv_##SFX a)             \
        {                                                                              \
            // 使用 NEON 指令求取向量的最小值或最大值
            STYPE##x4_t r = vp##INTRIN##_##SFX(vget_low_##SFX(a), vget_high_##SFX(a)); \
                        r = vp##INTRIN##_##SFX(r, r);                                  \
                        r = vp##INTRIN##_##SFX(r, r);                                  \
            // 返回结果向量中的第一个元素作为标量结果
            return (npy_##STYPE)vget_lane_##SFX(r, 0);                                 \
        }
    // 实例化 uint16 类型的最小值和最大值求解函数
    NPY_IMPL_NEON_REDUCE_MINMAX(min, uint16, u16)
    NPY_IMPL_NEON_REDUCE_MINMAX(max, uint16, u16)
    // 实例化 int16 类型的最小值和最大值求解函数
    NPY_IMPL_NEON_REDUCE_MINMAX(min, int16, s16)
    NPY_IMPL_NEON_REDUCE_MINMAX(max, int16, s16)
    // 取消宏定义 NPY_IMPL_NEON_REDUCE_MINMAX
    #undef NPY_IMPL_NEON_REDUCE_MINMAX

    // 定义 NEON 求最小值和最大值的宏函数
    #define NPY_IMPL_NEON_REDUCE_MINMAX(INTRIN, STYPE, SFX)                            \
        // 实现 NEON 向量的最小值或最大值求解函数
        NPY_FINLINE npy_##STYPE npyv_reduce_##INTRIN##_##SFX(npyv_##SFX a)             \
        {                                                                              \
            // 使用 NEON 指令求取向量的最小值或最大值
            STYPE##x2_t r = vp##INTRIN##_##SFX(vget_low_##SFX(a), vget_high_##SFX(a)); \
                        r = vp##INTRIN##_##SFX(r, r);                                  \
            // 返回结果向量中的第一个元素作为标量结果
            return (npy_##STYPE)vget_lane_##SFX(r, 0);                                 \
        }
    // 实例化 uint32 类型的最小值和最大值求解函数
    NPY_IMPL_NEON_REDUCE_MINMAX(min, uint32, u32)
    NPY_IMPL_NEON_REDUCE_MINMAX(max, uint32, u32)
    // 实例化 int32 类型的最小值和最大值求解函数
    NPY_IMPL_NEON_REDUCE_MINMAX(min, int32, s32)
    NPY_IMPL_NEON_REDUCE_MINMAX(max, int32, s32)
    // 取消宏定义 NPY_IMPL_NEON_REDUCE_MINMAX
    #undef NPY_IMPL_NEON_REDUCE_MINMAX
    // 定义宏 NPY_IMPL_NEON_REDUCE_MINMAX,用于实现 NEON 指令集的最小值和最大值归约函数
    #define NPY_IMPL_NEON_REDUCE_MINMAX(INTRIN, INF)                             \
        // 定义内联函数,用于将一个 npyv_f32 向量归约为一个 float 最小值或最大值                    \
        NPY_FINLINE float npyv_reduce_##INTRIN##_f32(npyv_f32 a)                 \
        {                                                                        \
            // 使用 NEON 指令将输入向量 a 的低位和高位部分合并,得到一个 float32x2_t 结果向量 \
            float32x2_t r = vp##INTRIN##_f32(vget_low_f32(a), vget_high_f32(a));\
            // 使用 NEON 指令再次对合并结果向量 r 进行 INTRIN 运算,得到最终归约结果向量       \
            r = vp##INTRIN##_f32(r, r);                                          \
            // 返回最终结果向量的第一个元素,即最小值或最大值                                 \
            return vget_lane_f32(r, 0);                                          \
        }                                                                        \
        // 定义内联函数,用于将一个 npyv_f32 向量归约为一个 float 最小值或最大值,忽略 NaN 值     \
        NPY_FINLINE float npyv_reduce_##INTRIN##p_f32(npyv_f32 a)                \
        {                                                                        \
            // 获取非 NaN 元素的掩码                                               \
            npyv_b32 notnan = npyv_notnan_f32(a);                                \
            // 如果向量中所有元素均为 NaN,则直接返回第一个元素的值                        \
            if (NPY_UNLIKELY(!npyv_any_b32(notnan))) {                           \
                return vgetq_lane_f32(a, 0);                                     \
            }                                                                    \
            // 使用掩码选择非 NaN 元素,将 NaN 元素替换为 INF (表示无穷大)              \
            a = npyv_select_f32(notnan, a,                                       \
                    npyv_reinterpret_f32_u32(npyv_setall_u32(INF)));             \
            // 调用相应的归约函数处理已处理过 NaN 的向量 a,返回最终的最小值或最大值             \
            return npyv_reduce_##INTRIN##_f32(a);                                \
        }                                                                        \
        // 定义内联函数,用于将一个 npyv_f32 向量归约为一个 float 最小值或最大值,无论是否有 NaN 值 \
        NPY_FINLINE float npyv_reduce_##INTRIN##n_f32(npyv_f32 a)                \
        {                                                                        \
            // 直接调用归约函数处理向量 a,返回最终的最小值或最大值                           \
            return npyv_reduce_##INTRIN##_f32(a);                                \
        }
    // 取消宏定义 NPY_IMPL_NEON_REDUCE_MINMAX 的定义
    #undef NPY_IMPL_NEON_REDUCE_MINMAX
#ifdef NPY_SIMD_F64
    #define NPY_IMPL_NEON_REDUCE_MINMAX(INTRIN, STYPE, SFX, OP)       \
        NPY_FINLINE STYPE npyv_reduce_##INTRIN##_##SFX(npyv_##SFX a)  \
        {                                                             \
            // 提取 NEON 向量 a 的低部分并将其转换为 STYPE 类型
            STYPE al = (STYPE)vget_low_##SFX(a);                      \
            // 提取 NEON 向量 a 的高部分并将其转换为 STYPE 类型
            STYPE ah = (STYPE)vget_high_##SFX(a);                     \
            // 返回 al 和 ah 中较大或较小的值,根据 OP 参数指定的比较操作符
            return al OP ah ? al : ah;                                \
        }
#endif // NPY_SIMD_F64

// 定义 NEON 实现的最大值和最小值归约函数
#define NPY_IMPL_NEON_REDUCE_MINMAX(INTRIN, STYPE, SFX, OP)       \
    NPY_FINLINE STYPE npyv_reduce_##INTRIN##_##SFX(npyv_##SFX a)  \
    {                                                             \
        // 提取 NEON 向量 a 的低部分并将其转换为 STYPE 类型
        STYPE al = (STYPE)vget_low_##SFX(a);                      \
        // 提取 NEON 向量 a 的高部分并将其转换为 STYPE 类型
        STYPE ah = (STYPE)vget_high_##SFX(a);                     \
        // 返回 al 和 ah 中较大或较小的值,根据 OP 参数指定的比较操作符
        return al OP ah ? al : ah;                                \
    }

// 调用宏定义来生成具体的函数实现,用于不同的数据类型和操作符
NPY_IMPL_NEON_REDUCE_MINMAX(max, npy_uint64, u64, >)
NPY_IMPL_NEON_REDUCE_MINMAX(max, npy_int64,  s64, >)
NPY_IMPL_NEON_REDUCE_MINMAX(min, npy_uint64, u64, <)
NPY_IMPL_NEON_REDUCE_MINMAX(min, npy_int64,  s64, <)
#undef NPY_IMPL_NEON_REDUCE_MINMAX

// round to nearest integer even
NPY_FINLINE npyv_f32 npyv_rint_f32(npyv_f32 a)
{
#ifdef NPY_HAVE_ASIMD
    // 使用 NEON 指令 vrndnq_f32 对向量 a 进行舍入到最近的偶数整数
    return vrndnq_f32(a);
#else
    // ARMv7 NEON 仅支持浮点数到整数的截断转换。
    // 使用一个魔术技巧,添加 1.5 * 2^23 来实现舍入到最近的偶数整数,
    // 然后减去这个魔术数以得到整数部分。

    // 创建一个常数向量,内容为 -0.0f 的无符号整数表示
    const npyv_u32 szero = vreinterpretq_u32_f32(vdupq_n_f32(-0.0f));
    // 计算向量 a 的符号位掩码
    const npyv_u32 sign_mask = vandq_u32(vreinterpretq_u32_f32(a), szero);
    // 创建一个常数向量,内容为 2^23 的浮点数表示
    const npyv_f32 two_power_23 = vdupq_n_f32(8388608.0); // 2^23
    // 创建一个常数向量,内容为 1.5 * 2^23 的浮点数表示
    const npyv_f32 two_power_23h = vdupq_n_f32(12582912.0f); // 1.5 * 2^23
    // 创建一个向量,用于消除 NaN 值,避免无效的浮点错误
    npyv_u32 nnan_mask = vceqq_f32(a, a);
    // 计算向量 a 的绝对值
    npyv_f32 abs_x = vabsq_f32(vreinterpretq_f32_u32(vandq_u32(nnan_mask, vreinterpretq_u32_f32(a))));
    // 执行舍入操作,通过添加魔术数 1.5 * 2^23
    npyv_f32 round = vsubq_f32(vaddq_f32(two_power_23h, abs_x), two_power_23h);
    // 使用符号掩码来进行符号位复制
    round = vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(round), sign_mask ));
    // 如果 |a| >= 2^23 或者 a 是 NaN,则返回 a;否则返回 round
    npyv_u32 mask = vcleq_f32(abs_x, two_power_23);
             mask = vandq_u32(mask, nnan_mask);
    return vbslq_f32(mask, round, a);
#endif
}

// 如果 NPY_SIMD_F64 定义了,则使用 vrndnq_f64 来定义 npyv_rint_f64 函数
#if NPY_SIMD_F64
    #define npyv_rint_f64 vrndnq_f64
#endif // NPY_SIMD_F64

// 如果 NPY_HAVE_ASIMD 定义了,则使用 vrndpq_f32 来定义 npyv_ceil_f32 函数
#ifdef NPY_HAVE_ASIMD
    #define npyv_ceil_f32 vrndpq_f32
#else
    // 否则,定义一个函数 npyv_ceil_f32,实现向上取整操作
    NPY_FINLINE npyv_f32 npyv_ceil_f32(npyv_f32 a)
    {
        // 创建常量 one,其值为单精度浮点数 1.0 的转换后的无符号整数表示
        const npyv_u32 one = vreinterpretq_u32_f32(vdupq_n_f32(1.0f));
        // 创建常量 szero,其值为单精度浮点数 -0.0 的转换后的无符号整数表示
        const npyv_u32 szero = vreinterpretq_u32_f32(vdupq_n_f32(-0.0f));
        // 创建 sign_mask,通过将浮点数 a 转换为无符号整数,并与 szero 相与得到
        const npyv_u32 sign_mask = vandq_u32(vreinterpretq_u32_f32(a), szero);
        // 创建常量 two_power_23,其值为单精度浮点数 8388608.0 的复制
        const npyv_f32 two_power_23 = vdupq_n_f32(8388608.0); // 2^23
        // 创建常量 two_power_23h,其值为单精度浮点数 12582912.0 的复制
        const npyv_f32 two_power_23h = vdupq_n_f32(12582912.0f); // 1.5 * 2^23
        
        // 创建 nnan_mask,检查 a 是否等于自身(排除 NaN 值)
        npyv_u32 nnan_mask = vceqq_f32(a, a);
        // 将 nnan_mask 与 a 进行位与操作,得到 x,用于消除 NaN 值以避免无效的浮点数错误
        npyv_f32 x = vreinterpretq_f32_u32(vandq_u32(nnan_mask, vreinterpretq_u32_f32(a)));
        
        // 计算 x 的绝对值 abs_x
        npyv_f32 abs_x = vabsq_f32(x);
        
        // 使用魔数 1.5 * 2^23 进行四舍五入
        npyv_f32 round = vsubq_f32(vaddq_f32(two_power_23h, abs_x), two_power_23h);
        
        // 将 round 的符号位设置为与 a 相同的符号
        round = vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(round), sign_mask));
        
        // 对 round 进行向上取整操作,考虑了有符号零值的情况
        npyv_f32 ceil = vaddq_f32(round, vreinterpretq_f32_u32(
            vandq_u32(vcltq_f32(round, x), one))
        );
        
        // 将 ceil 的符号位设置为与 a 相同的符号
        ceil = vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(ceil), sign_mask));
        
        // 如果 |a| >= 2^23 或者 a 为 NaN,则返回 a;否则返回 ceil
        npyv_u32 mask = vcleq_f32(abs_x, two_power_23);
        mask = vandq_u32(mask, nnan_mask);
        
        return vbslq_f32(mask, ceil, a);
    }
#endif
#if NPY_SIMD_F64
    #define npyv_ceil_f64 vrndpq_f64
#endif // NPY_SIMD_F64

// trunc
#ifdef NPY_HAVE_ASIMD
    #define npyv_trunc_f32 vrndq_f32
#else
    // 定义在没有 ASIMD 支持时,用于截断操作的函数 npyv_trunc_f32
    NPY_FINLINE npyv_f32 npyv_trunc_f32(npyv_f32 a)
    {
        // 定义常量 max_int 为 0x7fffffff
        const npyv_s32 max_int = vdupq_n_s32(0x7fffffff);
        // 定义常量 exp_mask 为 0xff000000
        const npyv_u32 exp_mask = vdupq_n_u32(0xff000000);
        // 定义常量 szero 为 -0.0f 的整数表示
        const npyv_s32 szero = vreinterpretq_s32_f32(vdupq_n_f32(-0.0f));
        // 创建 sign_mask,用于提取输入参数 a 的符号位
        const npyv_u32 sign_mask = vandq_u32(
            vreinterpretq_u32_f32(a), vreinterpretq_u32_s32(szero));

        // 创建 nfinite_mask,用于检测 a 是否为有限值
        npyv_u32 nfinite_mask = vshlq_n_u32(vreinterpretq_u32_f32(a), 1);
                 nfinite_mask = vandq_u32(nfinite_mask, exp_mask);
                 nfinite_mask = vceqq_u32(nfinite_mask, exp_mask);
        // 消除 NaN 和 inf,避免无效的浮点错误
        npyv_f32 x = vreinterpretq_f32_u32(
            veorq_u32(nfinite_mask, vreinterpretq_u32_f32(a)));
        /**
         * 在 armv7 上,vcvtq.f32 处理特殊情况如下:
         *  NaN 返回 0
         * +inf 或超出范围 返回 0x80000000(-0.0f)
         * -inf 或超出范围 返回 0x7fffffff(nan)
         */
        // 将 x 转为整数类型
        npyv_s32 trunci = vcvtq_s32_f32(x);
        // 将整数类型再转回浮点数类型
        npyv_f32 trunc = vcvtq_f32_s32(trunci);
        // 根据符号位,保留有符号零,例如 -0.5 -> -0.0
        trunc = vreinterpretq_f32_u32(
            vorrq_u32(vreinterpretq_u32_f32(trunc), sign_mask));
        // 如果溢出,则返回原始参数 a
        npyv_u32 overflow_mask = vorrq_u32(
            vceqq_s32(trunci, szero), vceqq_s32(trunci, max_int)
        );
        // 如果溢出或非有限值,则返回原始参数 a,否则返回截断后的值
        return vbslq_f32(vorrq_u32(nfinite_mask, overflow_mask), a, trunc);
   }
#endif
#if NPY_SIMD_F64
    #define npyv_trunc_f64 vrndq_f64
#endif // NPY_SIMD_F64

// floor
#ifdef NPY_HAVE_ASIMD
    #define npyv_floor_f32 vrndmq_f32
#else
    // 在没有 ASIMD 支持时,定义用于向下取整操作的函数 npyv_floor_f32
    NPY_FINLINE npyv_f32 npyv_floor_f32(npyv_f32 a)
    {
        // 创建一个常量,其值为单精度浮点数 1.0 对应的无符号整数形式
        const npyv_u32 one = vreinterpretq_u32_f32(vdupq_n_f32(1.0f));
        // 创建一个常量,其值为单精度浮点数 -0.0 对应的无符号整数形式
        const npyv_u32 szero = vreinterpretq_u32_f32(vdupq_n_f32(-0.0f));
        // 通过按位与操作,生成一个用于标记符号位的掩码
        const npyv_u32 sign_mask = vandq_u32(vreinterpretq_u32_f32(a), szero);
        // 创建一个常量,其值为单精度浮点数 2^23 对应的向量形式
        const npyv_f32 two_power_23 = vdupq_n_f32(8388608.0); // 2^23
        // 创建一个常量,其值为单精度浮点数 1.5 * 2^23 对应的向量形式
        const npyv_f32 two_power_23h = vdupq_n_f32(12582912.0f); // 1.5 * 2^23
    
        // 创建一个掩码,用于消除 NaN 值,以避免无效的浮点错误
        npyv_u32 nnan_mask = vceqq_f32(a, a);
        // 通过按位与操作,提取绝对值形式的浮点数向量
        npyv_f32 x = vreinterpretq_f32_u32(vandq_u32(nnan_mask, vreinterpretq_u32_f32(a)));
    
        // 计算绝对值的浮点数向量
        npyv_f32 abs_x = vabsq_f32(x);
        // 通过加上魔数 1.5 * 2^23 来进行四舍五入
        npyv_f32 round = vsubq_f32(vaddq_f32(two_power_23h, abs_x), two_power_23h);
    
        // 执行拷贝符号操作
        round = vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(round), sign_mask));
    
        // 计算向下取整的浮点数向量
        npyv_f32 floor = vsubq_f32(round, vreinterpretq_f32_u32(
            vandq_u32(vcgtq_f32(round, x), one)
        ));
    
        // 尊重带符号零的特性
        floor = vreinterpretq_f32_u32(vorrq_u32(vreinterpretq_u32_f32(floor), sign_mask));
    
        // 如果 |a| >= 2^23 或者 a 是 NaN,则返回 a;否则返回 floor
        npyv_u32 mask = vcleq_f32(abs_x, two_power_23);
                 mask = vandq_u32(mask, nnan_mask);
        return vbslq_f32(mask, floor, a);
    }
#if defined(NPY_HAVE_ASIMD)
    // 如果定义了 NPY_HAVE_ASIMD 宏,则执行以下代码块
    #if NPY_SIMD_F64
        // 如果定义了 NPY_SIMD_F64 宏,则定义 npyv_floor_f64 宏为 vrndmq_f64
        #define npyv_floor_f64 vrndmq_f64
    #endif // NPY_SIMD_F64
#endif // NPY_HAVE_ASIMD
// 结束对 NPY_HAVE_ASIMD 宏的条件编译

#endif // _NPY_SIMD_NEON_MATH_H
// 结束对 _NPY_SIMD_NEON_MATH_H 头文件的条件编译

.\numpy\numpy\_core\src\common\simd\neon\memory.h

#ifndef NPY_SIMD
    // 如果未定义 NPY_SIMD 宏,则报错,此头文件不是独立可用的
    #error "Not a standalone header"
#endif

#ifndef _NPY_SIMD_NEON_MEMORY_H
#define _NPY_SIMD_NEON_MEMORY_H

#include "misc.h"

/***************************
 * load/store
 ***************************/
// GCC 需要对指针类型进行明确的字面类型定义,否则会导致模棱两可的错误
#define NPYV_IMPL_NEON_MEM(SFX, CTYPE)                                           \
    // 加载操作,从 ptr 指向的地址加载数据到向量 npyv_##SFX 中
    NPY_FINLINE npyv_##SFX npyv_load_##SFX(const npyv_lanetype_##SFX *ptr)       \
    { return vld1q_##SFX((const CTYPE*)ptr); }                                   \
    // 加载操作,从 ptr 指向的地址加载数据到向量 npyv_##SFX 中
    NPY_FINLINE npyv_##SFX npyv_loada_##SFX(const npyv_lanetype_##SFX *ptr)      \
    { return vld1q_##SFX((const CTYPE*)ptr); }                                   \
    // 加载操作,从 ptr 指向的地址加载数据到向量 npyv_##SFX 中
    NPY_FINLINE npyv_##SFX npyv_loads_##SFX(const npyv_lanetype_##SFX *ptr)      \
    { return vld1q_##SFX((const CTYPE*)ptr); }                                   \
    // 加载操作,从 ptr 指向的地址加载数据到向量 npyv_##SFX 中,低位补零
    NPY_FINLINE npyv_##SFX npyv_loadl_##SFX(const npyv_lanetype_##SFX *ptr)      \
    {                                                                            \
        return vcombine_##SFX(                                                   \
            vld1_##SFX((const CTYPE*)ptr), vdup_n_##SFX(0)                       \
        );                                                                       \
    }                                                                            \
    // 存储操作,将向量 vec 的数据存储到 ptr 指向的地址
    NPY_FINLINE void npyv_store_##SFX(npyv_lanetype_##SFX *ptr, npyv_##SFX vec)  \
    { vst1q_##SFX((CTYPE*)ptr, vec); }                                           \
    // 存储操作,将向量 vec 的数据存储到 ptr 指向的地址
    NPY_FINLINE void npyv_storea_##SFX(npyv_lanetype_##SFX *ptr, npyv_##SFX vec) \
    { vst1q_##SFX((CTYPE*)ptr, vec); }                                           \
    // 存储操作,将向量 vec 的数据存储到 ptr 指向的地址
    NPY_FINLINE void npyv_stores_##SFX(npyv_lanetype_##SFX *ptr, npyv_##SFX vec) \
    { vst1q_##SFX((CTYPE*)ptr, vec); }                                           \
    // 存储操作,将向量 vec 的低位数据存储到 ptr 指向的地址
    NPY_FINLINE void npyv_storel_##SFX(npyv_lanetype_##SFX *ptr, npyv_##SFX vec) \
    { vst1_##SFX((CTYPE*)ptr, vget_low_##SFX(vec)); }                            \
    // 存储操作,将向量 vec 的高位数据存储到 ptr 指向的地址
    NPY_FINLINE void npyv_storeh_##SFX(npyv_lanetype_##SFX *ptr, npyv_##SFX vec) \
    { vst1_##SFX((CTYPE*)ptr, vget_high_##SFX(vec)); }

// 定义各种数据类型的 NEON 内存操作宏
NPYV_IMPL_NEON_MEM(u8,  uint8_t)
NPYV_IMPL_NEON_MEM(s8,  int8_t)
NPYV_IMPL_NEON_MEM(u16, uint16_t)
NPYV_IMPL_NEON_MEM(s16, int16_t)
NPYV_IMPL_NEON_MEM(u32, uint32_t)
NPYV_IMPL_NEON_MEM(s32, int32_t)
NPYV_IMPL_NEON_MEM(u64, uint64_t)
NPYV_IMPL_NEON_MEM(s64, int64_t)
NPYV_IMPL_NEON_MEM(f32, float)
#if NPY_SIMD_F64
NPYV_IMPL_NEON_MEM(f64, double)
#endif

/***************************
 * Non-contiguous Load
 ***************************/
// 非连续加载操作,从 ptr 指向的地址开始,按照给定的步长 stride 加载数据到向量 npyv_s32 中
NPY_FINLINE npyv_s32 npyv_loadn_s32(const npy_int32 *ptr, npy_intp stride)
{
    // 创建一个全为 0128 位整型 NEON 向量
    int32x4_t a = vdupq_n_s32(0);
    // 分别从不同地址加载数据到向量的不同通道
    a = vld1q_lane_s32((const int32_t*)ptr,            a, 0);
    a = vld1q_lane_s32((const int32_t*)ptr + stride,   a, 1);
    a = vld1q_lane_s32((const int32_t*)ptr + stride*2, a, 2);
    a = vld1q_lane_s32((const int32_t*)ptr + stride*3, a, 3);


这段代码主要是 NEON SIMD 操作的宏定义和函数实现,用于在 ARM 架构下进行内存的加载和存储操作,支持不同数据类型和非连续加载。
    # 返回变量 a 的值作为函数的输出结果
    return a;
//// 64
NPY_FINLINE npyv_s64 npyv_loadn_s64(const npy_int64 *ptr, npy_intp stride)
{
    // 使用 Neon 指令加载两个 int64_t 元素到一个 128 位寄存器中
    return vcombine_s64(
        vld1_s64((const int64_t*)ptr), vld1_s64((const int64_t*)ptr + stride)
    );
}
NPY_FINLINE npyv_u64 npyv_loadn_u64(const npy_uint64 *ptr, npy_intp stride)
{
    // 将加载的 int64_t 数据重新解释为 uint64_t 数据
    return npyv_reinterpret_u64_s64(
        npyv_loadn_s64((const npy_int64*)ptr, stride)
    );
}
#if NPY_SIMD_F64
NPY_FINLINE npyv_f64 npyv_loadn_f64(const double *ptr, npy_intp stride)
{
    // 将加载的 int64_t 数据重新解释为 double 数据
    return npyv_reinterpret_f64_s64(
        npyv_loadn_s64((const npy_int64*)ptr, stride)
    );
}
#endif

//// 64-bit load over 32-bit stride
NPY_FINLINE npyv_u32 npyv_loadn2_u32(const npy_uint32 *ptr, npy_intp stride)
{
    // 使用 Neon 指令加载两个 uint32_t 元素到一个 64 位寄存器中
    return vcombine_u32(
        vld1_u32((const uint32_t*)ptr), vld1_u32((const uint32_t*)ptr + stride)
    );
}
NPY_FINLINE npyv_s32 npyv_loadn2_s32(const npy_int32 *ptr, npy_intp stride)
{ 
    // 将加载的 uint32_t 数据重新解释为 int32_t 数据
    return npyv_reinterpret_s32_u32(npyv_loadn2_u32((const npy_uint32*)ptr, stride));
}
NPY_FINLINE npyv_f32 npyv_loadn2_f32(const float *ptr, npy_intp stride)
{ 
    // 将加载的 uint32_t 数据重新解释为 float 数据
    return npyv_reinterpret_f32_u32(npyv_loadn2_u32((const npy_uint32*)ptr, stride));
}

//// 128-bit load over 64-bit stride
NPY_FINLINE npyv_u64 npyv_loadn2_u64(const npy_uint64 *ptr, npy_intp stride)
{ 
    // 无需考虑 stride,直接加载 uint64_t 数据
    (void)stride; return npyv_load_u64(ptr); 
}
NPY_FINLINE npyv_s64 npyv_loadn2_s64(const npy_int64 *ptr, npy_intp stride)
{ 
    // 无需考虑 stride,直接加载 int64_t 数据
    (void)stride; return npyv_load_s64(ptr); 
}
#if NPY_SIMD_F64
NPY_FINLINE npyv_f64 npyv_loadn2_f64(const double *ptr, npy_intp stride)
{ 
    // 无需考虑 stride,直接加载 double 数据
    (void)stride; return npyv_load_f64(ptr); 
}
#endif

/***************************
 * Non-contiguous Store
 ***************************/
//// 32
NPY_FINLINE void npyv_storen_s32(npy_int32 *ptr, npy_intp stride, npyv_s32 a)
{
    // 分别存储 4 个 int32_t 元素到指定位置,考虑 stride
    vst1q_lane_s32((int32_t*)ptr, a, 0);
    vst1q_lane_s32((int32_t*)ptr + stride, a, 1);
    vst1q_lane_s32((int32_t*)ptr + stride*2, a, 2);
    vst1q_lane_s32((int32_t*)ptr + stride*3, a, 3);
}
NPY_FINLINE void npyv_storen_u32(npy_uint32 *ptr, npy_intp stride, npyv_u32 a)
{ 
    // 将存储的 int32_t 数据重新解释为 uint32_t 数据
    npyv_storen_s32((npy_int32*)ptr, stride, npyv_reinterpret_s32_u32(a)); 
}
NPY_FINLINE void npyv_storen_f32(float *ptr, npy_intp stride, npyv_f32 a)
{ 
    // 将存储的 int32_t 数据重新解释为 float 数据
    npyv_storen_s32((npy_int32*)ptr, stride, npyv_reinterpret_s32_f32(a)); 
}

//// 64
NPY_FINLINE void npyv_storen_s64(npy_int64 *ptr, npy_intp stride, npyv_s64 a)
{
    // 分别存储 2 个 int64_t 元素到指定位置,考虑 stride
    vst1q_lane_s64((int64_t*)ptr, a, 0);
    vst1q_lane_s64((int64_t*)ptr + stride, a, 1);
}
NPY_FINLINE void npyv_storen_u64(npy_uint64 *ptr, npy_intp stride, npyv_u64 a)
{ 
    // 将存储的 int64_t 数据重新解释为 uint64_t 数据
    npyv_storen_s64((npy_int64*)ptr, stride, npyv_reinterpret_s64_u64(a)); 
}

#if NPY_SIMD_F64
NPY_FINLINE void npyv_storen_f64(double *ptr, npy_intp stride, npyv_f64 a)
//// 64-bit store over 32-bit stride
NPY_FINLINE void npyv_storen2_u32(npy_uint32 *ptr, npy_intp stride, npyv_u32 a)
{
#if NPY_SIMD_F64
    // 使用 SIMD 指令将第一个 64 位数据存储到 ptr,a 被重新解释为 64 位数据
    vst1q_lane_u64((uint64_t*)ptr, npyv_reinterpret_u64_u32(a), 0);
    // 使用 SIMD 指令将第二个 64 位数据存储到 ptr + stride,a 被重新解释为 64 位数据
    vst1q_lane_u64((uint64_t*)(ptr + stride), npyv_reinterpret_u64_u32(a), 1);
#else
    // 在 armhf 环境中,要求对齐存储,将 a 的低 32 位存储到 ptr
    vst1_u32((uint32_t*)ptr, vget_low_u32(a));
    // 在 armhf 环境中,将 a 的高 32 位存储到 ptr + stride
    vst1_u32((uint32_t*)ptr + stride, vget_high_u32(a));
#endif
}

NPY_FINLINE void npyv_storen2_s32(npy_int32 *ptr, npy_intp stride, npyv_s32 a)
{
    // 将 npyv_s32 类型数据 a 重新解释为 npyv_u32 并进行存储
    npyv_storen2_u32((npy_uint32*)ptr, stride, npyv_reinterpret_u32_s32(a));
}

NPY_FINLINE void npyv_storen2_f32(float *ptr, npy_intp stride, npyv_f32 a)
{
    // 将 npyv_f32 类型数据 a 重新解释为 npyv_u32 并进行存储
    npyv_storen2_u32((npy_uint32*)ptr, stride, npyv_reinterpret_u32_f32(a));
}

//// 128-bit store over 64-bit stride
NPY_FINLINE void npyv_storen2_u64(npy_uint64 *ptr, npy_intp stride, npyv_u64 a)
{
    // 忽略 stride 参数,直接存储 a 的数据到 ptr
    (void)stride;
    npyv_store_u64(ptr, a);
}

NPY_FINLINE void npyv_storen2_s64(npy_int64 *ptr, npy_intp stride, npyv_s64 a)
{
    // 忽略 stride 参数,直接存储 a 的数据到 ptr
    (void)stride;
    npyv_store_s64(ptr, a);
}

#if NPY_SIMD_F64
NPY_FINLINE void npyv_storen2_f64(double *ptr, npy_intp stride, npyv_f64 a)
{
    // 忽略 stride 参数,直接存储 a 的数据到 ptr
    (void)stride;
    npyv_store_f64(ptr, a);
}
#endif

/*********************************
 * Partial Load
 *********************************/

//// 32
NPY_FINLINE npyv_s32 npyv_load_till_s32(const npy_int32 *ptr, npy_uintp nlane, npy_int32 fill)
{
    assert(nlane > 0);
    npyv_s32 a;
    switch(nlane) {
    case 1:
        // 加载单个 32 位数据到 a,使用 fill 填充剩余的 SIMD 矢量
        a = vld1q_lane_s32((const int32_t*)ptr, vdupq_n_s32(fill), 0);
        break;
    case 2:
        // 组合两个 32 位数据到 a,并使用 fill 填充剩余的 SIMD 矢量
        a = vcombine_s32(vld1_s32((const int32_t*)ptr), vdup_n_s32(fill));
        break;
    case 3:
        // 组合前两个 32 位数据到 a,第三个数据使用 fill 填充剩余的 SIMD 矢量
        a = vcombine_s32(
            vld1_s32((const int32_t*)ptr),
            vld1_lane_s32((const int32_t*)ptr + 2, vdup_n_s32(fill), 0)
        );
        break;
    default:
        // 加载所有的 32 位数据到 a
        return npyv_load_s32(ptr);
    }
#if NPY_SIMD_GUARD_PARTIAL_LOAD
    // 如果定义了 NPY_SIMD_GUARD_PARTIAL_LOAD,执行一个 workaround 操作
    volatile npyv_s32 workaround = a;
    a = vorrq_s32(workaround, a);
#endif
    return a;
}

// 使用 0 填充剩余的 SIMD 矢量
NPY_FINLINE npyv_s32 npyv_load_tillz_s32(const npy_int32 *ptr, npy_uintp nlane)
{
    return npyv_load_till_s32(ptr, nlane, 0);
}

//// 64
NPY_FINLINE npyv_s64 npyv_load_till_s64(const npy_int64 *ptr, npy_uintp nlane, npy_int64 fill)
{
    assert(nlane > 0);
    if (nlane == 1) {
        // 加载单个 64 位数据到 a,并使用 fill 填充剩余的 SIMD 矢量
        npyv_s64 a = vcombine_s64(vld1_s64((const int64_t*)ptr), vdup_n_s64(fill));
    #if NPY_SIMD_GUARD_PARTIAL_LOAD
        // 如果定义了 NPY_SIMD_GUARD_PARTIAL_LOAD,执行一个 workaround 操作
        volatile npyv_s64 workaround = a;
        a = vorrq_s64(workaround, a);
    #endif
        return a;
    }
    // 加载所有的 64 位数据到 a
    return npyv_load_s64(ptr);
}

// 使用 0 填充剩余的 SIMD 矢量
NPY_FINLINE npyv_s64 npyv_load_tillz_s64(const npy_int64 *ptr, npy_uintp nlane)
{
    return npyv_load_till_s64(ptr, nlane, 0);
}

//// 64-bit nlane
NPY_FINLINE npyv_s32 npyv_load2_till_s32(const npy_int32 *ptr, npy_uintp nlane,
                                          npy_int32 fill_lo, npy_int32 fill_hi)
{
    assert(nlane > 0);
    // 加载 nlane 个 32 位数据到 a,同时使用 fill_lo 和 fill_hi 填充剩余的 SIMD 矢量

    // 确保 nlane 大于 0
    assert(nlane > 0);

    npyv_s32 a;
    switch(nlane) {
    case 1:
        // 加载一个 32 位数据到 a,并用 fill_lo 和 fill_hi 填充剩余的 SIMD 矢量
        a = vld1q_lane_s32((const int32_t*)ptr, vcombine_s32(vdup_n_s32(fill_lo), vdup_n_s32(fill_hi)), 0);
        break;
    case 2:
        // 加载两个 32 位数据到 a,并用 fill_hi 填充剩余的 SIMD 矢量
        a = vcombine_s32(vld1_s32((const int32_t*)ptr), vdup_n_s32(fill_hi));
        break;
    case 3:
        // 加载前两个 32 位数据到 a,第三个数据使用 fill_hi 填充剩余的 SIMD 矢量
        a = vcombine_s32(
            vld1_s32((const int32_t*)ptr),
            vld1_lane_s32((const int32_t*)ptr + 2, vdup_n_s32(fill_hi), 0)
        );
        break;
    default:
        // 加载所有的 32 位数据到 a
        return npyv_load_s32(ptr);
    }
#if NPY_SIMD_GUARD_PARTIAL_LOAD
    // 如果定义了 NPY_SIMD_GUARD_PARTIAL_LOAD,执行一个 workaround 操作
    volatile npyv_s32 workaround = a;
    a = vorrq_s32(workaround, a);
#endif
    return a;
}
    # 如果 nlane 等于 1,执行以下操作
    if (nlane == 1) {
        # 声明并初始化一个 16 字节对齐的整型数组 fill,包含两个元素 fill_lo 和 fill_hi
        const int32_t NPY_DECL_ALIGNED(16) fill[2] = {fill_lo, fill_hi};
        # 从指针 ptr 处加载两个 int32_t 类型的值,并将它们组合成一个 npyv_s32 向量 a
        npyv_s32 a = vcombine_s32(vld1_s32((const int32_t*)ptr), vld1_s32(fill));
    #if NPY_SIMD_GUARD_PARTIAL_LOAD
        # 如果定义了 NPY_SIMD_GUARD_PARTIAL_LOAD 宏,则使用 volatile 变量 workaround 来保证正确的部分加载
        volatile npyv_s32 workaround = a;
        # 使用或运算将 workaround 和 a 合并,以确保正确性
        a = vorrq_s32(workaround, a);
    #endif
        # 返回向量 a
        return a;
    }
    # 如果 nlane 不等于 1,加载 ptr 指针处的 int32_t 数据并返回
    return npyv_load_s32(ptr);
//// 128-bit nlane
// 加载指定长度的 int64 数据到 SIMD 寄存器中,并在剩余的位置填充零值
NPY_FINLINE npyv_s64 npyv_load2_till_s64(const npy_int64 *ptr, npy_uintp nlane,
                                         npy_int64 fill_lo, npy_int64 fill_hi)
{ 
    // 忽略未使用的参数 fill_lo 和 fill_hi,直接加载所有数据到寄存器中
    (void)nlane; (void)fill_lo; (void)fill_hi; 
    return npyv_load_s64(ptr); // 调用加载 int64 数据的函数并返回结果
}

NPY_FINLINE npyv_s64 npyv_load2_tillz_s64(const npy_int64 *ptr, npy_uintp nlane)
{ 
    // 忽略未使用的参数 nlane,加载指定长度的 int64 数据到 SIMD 寄存器中,并在剩余的位置填充零值
    (void)nlane; 
    return npyv_load_s64(ptr); // 调用加载 int64 数据的函数并返回结果
}

/*********************************
 * Non-contiguous partial load
 *********************************/
//// 32
// 加载不连续的部分 int32 数据到 SIMD 寄存器中
NPY_FINLINE npyv_s32
npyv_loadn_till_s32(const npy_int32 *ptr, npy_intp stride, npy_uintp nlane, npy_int32 fill)
{
    assert(nlane > 0); // 断言加载长度大于零
    int32x4_t vfill = vdupq_n_s32(fill); // 使用 fill 参数创建一个 int32x4_t 类型的常量向量
    switch(nlane) {
    case 3:
        vfill = vld1q_lane_s32((const int32_t*)ptr + stride*2, vfill, 2); // 加载第三个元素到向量中的第二个位置
    case 2:
        vfill = vld1q_lane_s32((const int32_t*)ptr + stride, vfill, 1); // 加载第二个元素到向量中的第一个位置
    case 1:
        vfill = vld1q_lane_s32((const int32_t*)ptr, vfill, 0); // 加载第一个元素到向量中的第零个位置
        break;
    default:
        return npyv_loadn_s32(ptr, stride); // 加载连续的 int32 数据到 SIMD 寄存器中
    }
#if NPY_SIMD_GUARD_PARTIAL_LOAD
    volatile npyv_s32 workaround = vfill; // 如果定义了 NPY_SIMD_GUARD_PARTIAL_LOAD,则执行的虚拟访问以避免优化
    vfill = vorrq_s32(workaround, vfill); // 使用或运算以确保加载数据到 vfill 向量中
#endif
    return vfill; // 返回加载后的向量
}

// 加载指定长度的 int32 数据到 SIMD 寄存器中,并在剩余的位置填充零值
NPY_FINLINE npyv_s32
npyv_loadn_tillz_s32(const npy_int32 *ptr, npy_intp stride, npy_uintp nlane)
{ 
    return npyv_loadn_till_s32(ptr, stride, nlane, 0); // 调用加载不连续部分 int32 数据的函数,填充零值并返回结果
}

// 加载指定长度的 int64 数据到 SIMD 寄存器中,并在剩余的位置填充指定的值
NPY_FINLINE npyv_s64
npyv_loadn_till_s64(const npy_int64 *ptr, npy_intp stride, npy_uintp nlane, npy_int64 fill)
{
    assert(nlane > 0); // 断言加载长度大于零
    if (nlane == 1) {
        return npyv_load_till_s64(ptr, 1, fill); // 如果加载长度为 1,则加载到 SIMD 寄存器中并填充指定的值
    }
    return npyv_loadn_s64(ptr, stride); // 否则加载连续的 int64 数据到 SIMD 寄存器中
}

// 加载指定长度的 int64 数据到 SIMD 寄存器中,并在剩余的位置填充零值
NPY_FINLINE npyv_s64 npyv_loadn_tillz_s64(const npy_int64 *ptr, npy_intp stride, npy_uintp nlane)
{ 
    return npyv_loadn_till_s64(ptr, stride, nlane, 0); // 调用加载不连续部分 int64 数据的函数,填充零值并返回结果
}

//// 64-bit load over 32-bit stride
// 使用 32 位步长加载指定长度的 int32 数据到 SIMD 寄存器中
NPY_FINLINE npyv_s32 npyv_loadn2_till_s32(const npy_int32 *ptr, npy_intp stride, npy_uintp nlane,
                                          npy_int32 fill_lo, npy_int32 fill_hi)
{
    assert(nlane > 0); // 断言加载长度大于零
    if (nlane == 1) {
        const int32_t NPY_DECL_ALIGNED(16) fill[2] = {fill_lo, fill_hi}; // 声明一个填充数组,确保对齐到 16 字节边界
        npyv_s32 a = vcombine_s32(vld1_s32((const int32_t*)ptr), vld1_s32(fill)); // 使用填充值创建一个 int32x2_t 向量并与原始数据合并
    #if NPY_SIMD_GUARD_PARTIAL_LOAD
        volatile npyv_s32 workaround = a; // 如果定义了 NPY_SIMD_GUARD_PARTIAL_LOAD,则执行的虚拟访问以避免优化
        a = vorrq_s32(workaround, a); // 使用或运算以确保加载数据到 a 向量中
    #endif
        return a; // 返回加载后的向量
    }
    return npyv_loadn2_s32(ptr, stride); // 加载连续的 int32 数据到 SIMD 寄存器中
}

// 使用 32 位步长加载指定长度的 int32 数据到 SIMD 寄存器中,并在剩余的位置填充零值
NPY_FINLINE npyv_s32 npyv_loadn2_tillz_s32(const npy_int32 *ptr, npy_intp stride, npy_uintp nlane)
{
    assert(nlane > 0); // 断言加载长度大于零
    if (nlane == 1) {
        npyv_s32 a = vcombine_s32(vld1_s32((const int32_t*)ptr), vdup_n_s32(0)); // 使用零值创建一个 int32x2_t 向量并与原始数据合并
    #if NPY_SIMD_GUARD_PARTIAL_LOAD
        volatile npyv_s32 workaround = a; // 如果定义了 NPY_SIMD_GUARD_PARTIAL_LOAD,则执行的虚拟访问以避免优化
        a = vorrq_s32(workaround, a); // 使用或运算以确保加载数据到 a 向量中
    #endif
        return a; // 返回加载后的向量
    }
    return npyv_loadn2_s32(ptr, stride); // 加载连续的 int32 数据到 SIMD 寄存器中
}
/*********************************
 * Non-contiguous partial store
 *********************************/
//// 64-bit store over 32-bit stride
NPY_FINLINE void npyv_storen2_till_s32(npy_int32 *ptr, npy_intp stride, npy_uintp nlane, npyv_s32 a)
{
    assert(nlane > 0);  // 断言确保 nlane 大于 0

    // 将第一个 lane 的值存储到 ptr 指向的地址
    vst1q_lane_s32((int32_t*)ptr, a, 0);

    switch(nlane) {
    case 1:
        return;  // 如果 nlane 为 1,直接返回,只存储了一个元素
    case 2:
        // 将第二个 lane 的值存储到 ptr + stride 指向的地址
        vst1q_lane_s32((int32_t*)ptr + stride, a, 1);
        return;
    case 3:
        // 将第二个 lane 的值存储到 ptr + stride 指向的地址
        vst1q_lane_s32((int32_t*)ptr + stride, a, 1);
        // 将第三个 lane 的值存储到 ptr + stride*2 指向的地址
        vst1q_lane_s32((int32_t*)ptr + stride*2, a, 2);
        return;
    default:
        // 默认情况下,存储所有的 lanes 的值到 ptr + stride*i 指向的地址
        vst1q_lane_s32((int32_t*)ptr + stride, a, 1);
        vst1q_lane_s32((int32_t*)ptr + stride*2, a, 2);
        vst1q_lane_s32((int32_t*)ptr + stride*3, a, 3);
    }
}
    # 断言语句,用于确保条件 nlane > 0 成立,否则程序会抛出 AssertionError 异常。
    assert(nlane > 0);
#if NPY_SIMD_F64
    // 如果定义了 NPY_SIMD_F64,使用 Neon 指令将 s32 类型向量 a 转换为 s64 类型后存储到内存 ptr
    vst1q_lane_s64((int64_t*)ptr, npyv_reinterpret_s64_s32(a), 0);
    // 如果向量长度 nlane 大于 1,继续将向量 a 的第一个 64 位元素存储到 ptr + stride 处
    if (nlane > 1) {
        vst1q_lane_s64((int64_t*)(ptr + stride), npyv_reinterpret_s64_s32(a), 1);
    }
#else
    // 如果未定义 NPY_SIMD_F64,将 s32 类型向量 a 的低 32 位元素存储到 ptr 处
    npyv_storel_s32(ptr, a);
    // 如果向量长度 nlane 大于 1,将向量 a 的高 32 位元素存储到 ptr + stride 处
    if (nlane > 1) {
        npyv_storeh_s32(ptr + stride, a);
    }
#endif
}

//// 128-bit store over 64-bit stride
// 将长度为 nlane 的 s64 类型向量 a 存储到内存 ptr,步长为 stride
NPY_FINLINE void npyv_storen2_till_s64(npy_int64 *ptr, npy_intp stride, npy_uintp nlane, npyv_s64 a)
{ assert(nlane > 0); (void)stride; (void)nlane; npyv_store_s64(ptr, a); }

/*****************************************************************
 * Implement partial load/store for u32/f32/u64/f64... via casting
 *****************************************************************/
// 定义宏 NPYV_IMPL_NEON_REST_PARTIAL_TYPES,用于实现通过类型转换实现部分加载/存储操作
#define NPYV_IMPL_NEON_REST_PARTIAL_TYPES(F_SFX, T_SFX)                                     \
    // 部分加载函数:从 ptr 处加载长度为 nlane 的 F_SFX 类型向量,用 fill 填充空缺部分
    NPY_FINLINE npyv_##F_SFX npyv_load_till_##F_SFX                                         \
    (const npyv_lanetype_##F_SFX *ptr, npy_uintp nlane, npyv_lanetype_##F_SFX fill)         \
    {                                                                                       \
        // 联合体 pun,将 fill 转换为对应的 T_SFX 类型后再转换为 F_SFX 类型向量返回
        union {                                                                             \
            npyv_lanetype_##F_SFX from_##F_SFX;                                             \
            npyv_lanetype_##T_SFX to_##T_SFX;                                               \
        } pun;                                                                              \
        pun.from_##F_SFX = fill;                                                            \
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_load_till_##T_SFX(                   \
            (const npyv_lanetype_##T_SFX *)ptr, nlane, pun.to_##T_SFX                       \
        ));                                                                                 \
    }                                                                                       \
    // 部分加载函数,带步长版本:从 ptr 处以 stride 步长加载长度为 nlane 的 F_SFX 类型向量
    NPY_FINLINE npyv_##F_SFX npyv_loadn_till_##F_SFX                                        \
    (const npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane,                    \
     npyv_lanetype_##F_SFX fill)                                                            \
    {                                                                                       \
        union {                                                                             \
            npyv_lanetype_##F_SFX from_##F_SFX;                                             \
            npyv_lanetype_##T_SFX to_##T_SFX;                                               \
        } pun;                                                                              \
        pun.from_##F_SFX = fill;                                                            \
        // 使用联合体 pun 将 fill 转换为对应的类型 from_##F_SFX
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_loadn_till_##T_SFX(                  \
            (const npyv_lanetype_##T_SFX *)ptr, stride, nlane, pun.to_##T_SFX               \
        ));                                                                                 \
    }                                                                                       \
    // 以填充值 fill 加载数据直到最后的函数定义,将 F_SFX 类型指针 ptr 转换为 T_SFX 类型
    NPY_FINLINE npyv_##F_SFX npyv_load_tillz_##F_SFX                                        \
    (const npyv_lanetype_##F_SFX *ptr, npy_uintp nlane)                                     \
    {                                                                                       \
        // 调用 load_tillz_##T_SFX 将指针 ptr 解释为 T_SFX 类型,直到 nlane 长度
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_load_tillz_##T_SFX(                  \
            (const npyv_lanetype_##T_SFX *)ptr, nlane                                       \
        ));                                                                                 \
    }                                                                                       \
    // 以填充值为零加载数据直到最后的函数定义,将 F_SFX 类型指针 ptr 转换为 T_SFX 类型
    NPY_FINLINE npyv_##F_SFX npyv_loadn_tillz_##F_SFX                                       \
    (const npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane)                    \
    {                                                                                       \
        // 调用 loadn_tillz_##T_SFX 将指针 ptr 解释为 T_SFX 类型,步长为 stride,直到 nlane 长度
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_loadn_tillz_##T_SFX(                 \
            (const npyv_lanetype_##T_SFX *)ptr, stride, nlane                               \
        ));                                                                                 \
    }                                                                                       \
    // 将数据存储直到最后的函数定义,将 F_SFX 类型指针 ptr 中的数据存储为 T_SFX 类型
    NPY_FINLINE void npyv_store_till_##F_SFX                                                \
    (npyv_lanetype_##F_SFX *ptr, npy_uintp nlane, npyv_##F_SFX a)                           \
    {                                                                                       \
        // 调用 store_till_##T_SFX 将类型为 F_SFX 的向量 a 存储到类型为 T_SFX 的指针 ptr 中,直到 nlane 长度
        npyv_store_till_##T_SFX(                                                            \
            (npyv_lanetype_##T_SFX *)ptr, nlane,                                            \
            npyv_reinterpret_##T_SFX##_##F_SFX(a)                                           \
        );                                                                                  \
    }                                                                                       \
    NPY_FINLINE void npyv_storen_till_##F_SFX                                               \
    (npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane, npyv_##F_SFX a)          \
    {                                                                                       \
        // 定义一个内联函数,用于将长度为 nlane 的 npyv_##F_SFX 类型向量 a 存储到 ptr 指向的内存中,步长为 stride
        npyv_storen_till_##T_SFX(                                                           \
            // 将 npyv_##F_SFX 类型的向量 a 重新解释为 npyv_##T_SFX##_##F_SFX 类型的向量,并存储到 ptr 中
            (npyv_lanetype_##T_SFX *)ptr, stride, nlane,                                    \
            npyv_reinterpret_##T_SFX##_##F_SFX(a)                                           \
        );                                                                                  \
    }
// 定义宏 NPYV_IMPL_NEON_REST_PARTIAL_TYPES_PAIR,用于生成两个函数:
// - npyv_load2_till_##F_SFX:加载并转换两个连续的元素到指定类型 F_SFX 的向量,直到满足 nlane 的数量要求,
//   使用 fill_lo 和 fill_hi 分别填充未加载的元素
// - npyv_loadn2_till_##F_SFX:加载并转换两个连续的元素到指定类型 F_SFX 的向量,根据 stride 和 nlane 的需求,
//   使用 fill_lo 和 fill_hi 填充未加载的元素
#define NPYV_IMPL_NEON_REST_PARTIAL_TYPES_PAIR(F_SFX, T_SFX)                                \
    // 内联函数 npyv_load2_till_##F_SFX,加载指定类型 F_SFX 的向量,直到 nlane 个元素,
    // 使用 fill_lo 和 fill_hi 分别填充未加载的元素
    NPY_FINLINE npyv_##F_SFX npyv_load2_till_##F_SFX                                        \
    (const npyv_lanetype_##F_SFX *ptr, npy_uintp nlane,                                     \
     npyv_lanetype_##F_SFX fill_lo, npyv_lanetype_##F_SFX fill_hi)                          \
    {                                                                                       \
        // 联合 pun 用于类型转换
        union pun {                                                                         \
            npyv_lanetype_##F_SFX from_##F_SFX;                                             \
            npyv_lanetype_##T_SFX to_##T_SFX;                                               \
        };                                                                                  \
        union pun pun_lo;                                                                   \
        union pun pun_hi;                                                                   \
        pun_lo.from_##F_SFX = fill_lo;                                                      \
        pun_hi.from_##F_SFX = fill_hi;                                                      \
        // 调用 npyv_load2_till_##T_SFX 函数加载类型为 T_SFX 的向量,转换为类型 F_SFX 的向量
        // 这里将指针 ptr 强制转换为指向类型为 T_SFX 的元素的指针,并传入填充值 pun_lo.to_##T_SFX 和 pun_hi.to_##T_SFX
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_load2_till_##T_SFX(                  \
            (const npyv_lanetype_##T_SFX *)ptr, nlane, pun_lo.to_##T_SFX, pun_hi.to_##T_SFX \
        ));                                                                                 \
    }                                                                                       \
    // 内联函数 npyv_loadn2_till_##F_SFX,加载指定类型 F_SFX 的向量,根据 stride 和 nlane 的需求,
    // 使用 fill_lo 和 fill_hi 填充未加载的元素
    NPY_FINLINE npyv_##F_SFX npyv_loadn2_till_##F_SFX                                       \
    (const npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane,                    \
     npyv_lanetype_##F_SFX fill_lo, npyv_lanetype_##F_SFX fill_hi)                          \
    {                                                                                       \
        union pun {                                                                         \  // 定义一个联合体 pun,用于类型 F_SFX 和 T_SFX 的转换
            npyv_lanetype_##F_SFX from_##F_SFX;                                             \  // 联合体成员 from_F_SFX,用于类型 F_SFX
            npyv_lanetype_##T_SFX to_##T_SFX;                                               \  // 联合体成员 to_T_SFX,用于类型 T_SFX
        };                                                                                  \
        union pun pun_lo;                                                                   \  // 声明 pun 结构体变量 pun_lo
        union pun pun_hi;                                                                   \  // 声明 pun 结构体变量 pun_hi
        pun_lo.from_##F_SFX = fill_lo;                                                      \  // 将 fill_lo 赋值给 pun_lo 的 from_F_SFX 成员
        pun_hi.from_##F_SFX = fill_hi;                                                      \  // 将 fill_hi 赋值给 pun_hi 的 from_F_SFX 成员
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_loadn2_till_##T_SFX(                 \  // 调用类型 F_SFX 到类型 T_SFX 的重新解释加载函数
            (const npyv_lanetype_##T_SFX *)ptr, stride, nlane, pun_lo.to_##T_SFX,           \  // 使用 ptr 所指向的数据加载类型 T_SFX
            pun_hi.to_##T_SFX                                                               \  // 使用 pun_lo.to_T_SFX 和 pun_hi.to_T_SFX 进行加载
        ));                                                                                 \
    }                                                                                       \  // 函数结束
    NPY_FINLINE npyv_##F_SFX npyv_load2_tillz_##F_SFX                                       \  // 内联函数定义,加载类型 F_SFX 数据,直到遇到零
    (const npyv_lanetype_##F_SFX *ptr, npy_uintp nlane)                                     \  // 参数:指向类型 F_SFX 数据的指针 ptr,加载的数量 nlane
    {                                                                                       \
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_load2_tillz_##T_SFX(                 \  // 调用类型 F_SFX 到类型 T_SFX 的重新解释加载函数,加载直到遇到零
            (const npyv_lanetype_##T_SFX *)ptr, nlane                                       \  // 使用 ptr 所指向的数据加载类型 T_SFX
        ));                                                                                 \
    }                                                                                       \  // 函数结束
    NPY_FINLINE npyv_##F_SFX npyv_loadn2_tillz_##F_SFX                                      \  // 内联函数定义,加载类型 F_SFX 数据,直到遇到零,支持步长
    (const npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane)                    \  // 参数:指向类型 F_SFX 数据的指针 ptr,步长 stride,加载的数量 nlane
    {                                                                                       \
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_loadn2_tillz_##T_SFX(                \  // 调用类型 F_SFX 到类型 T_SFX 的重新解释加载函数,加载直到遇到零,支持步长
            (const npyv_lanetype_##T_SFX *)ptr, stride, nlane                               \  // 使用 ptr 所指向的数据加载类型 T_SFX
        ));                                                                                 \
    }                                                                                       \  // 函数结束
    NPY_FINLINE void npyv_store2_till_##F_SFX                                               \  // 内联函数定义,存储类型 F_SFX 数据,直到遇到零
    (npyv_lanetype_##F_SFX *ptr, npy_uintp nlane, npyv_##F_SFX a)                           \  // 参数:指向类型 F_SFX 数据的指针 ptr,存储的数量 nlane,数据 a
    {
        # 将向量 `a` 重新解释为 `T_SFX` 类型,并将其存储到指针 `ptr` 所指向的内存中,
        # 存储的个数由 `nlane` 指定
        npyv_store2_till_##T_SFX(
            (npyv_lanetype_##T_SFX *)ptr, nlane,
            npyv_reinterpret_##T_SFX##_##F_SFX(a)
        );
    }
    NPY_FINLINE void npyv_storen2_till_##F_SFX
    (
        npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane, npyv_##F_SFX a
    )
    {
        # 将向量 `a` 重新解释为 `T_SFX` 类型,并将其存储到以 `ptr` 指向为起点、
        # 步长为 `stride` 的内存中,存储的个数由 `nlane` 指定
        npyv_storen2_till_##T_SFX(
            (npyv_lanetype_##T_SFX *)ptr, stride, nlane,
            npyv_reinterpret_##T_SFX##_##F_SFX(a)
        );
    }
// 定义一个宏,用于实现 NEON SIMD 操作的加载和存储,用于两个通道的情况

#define NPYV_IMPL_NEON_MEM_INTERLEAVE(SFX, T_PTR)                        \
    // 定义一个内联函数,用于加载两个通道的 NEON 数据
    NPY_FINLINE npyv_##SFX##x2 npyv_load_##SFX##x2(                      \
        const npyv_lanetype_##SFX *ptr                                   \
    ) {                                                                  \
        // 使用 NEON 指令 vld2q_##SFX 加载指针 ptr 所指向的数据
        return vld2q_##SFX((const T_PTR*)ptr);                           \
    }                                                                    \
    // 定义一个内联函数,用于存储两个通道的 NEON 数据
    NPY_FINLINE void npyv_store_##SFX##x2(                               \
        npyv_lanetype_##SFX *ptr, npyv_##SFX##x2 v                       \
    ) {                                                                  \
        // 使用 NEON 指令 vst2q_##SFX 存储数据 v 到指针 ptr 所指向的位置
        vst2q_##SFX((T_PTR*)ptr, v);                                     \
    }
    #define NPYV_IMPL_NEON_MEM_INTERLEAVE_64(SFX)                               \
        // 定义 NEON SIMD 操作的函数模板,用于加载和存储 64 位数据的双向交错操作
        NPY_FINLINE npyv_##SFX##x2 npyv_load_##SFX##x2(                         \
            const npyv_lanetype_##SFX *ptr)                                     \
        {                                                                       \
            // 加载指针指向的前两个数据作为第一组向量 a 和第二组向量 b
            npyv_##SFX a = npyv_load_##SFX(ptr);                                \
            npyv_##SFX b = npyv_load_##SFX(ptr + 2);                            \
            // 创建存储两个向量的结构体 r
            npyv_##SFX##x2 r;                                                   \
            // 将向量 a 和 b 的低位和高位组合成 r 的两个元素
            r.val[0] = vcombine_##SFX(vget_low_##SFX(a),  vget_low_##SFX(b));   \
            r.val[1] = vcombine_##SFX(vget_high_##SFX(a), vget_high_##SFX(b));  \
            // 返回结构体 r,包含了交错后的数据
            return r;                                                           \
        }                                                                       \
        // 定义存储函数,将交错后的数据存储回内存中
        NPY_FINLINE void npyv_store_##SFX##x2(                                  \
            npyv_lanetype_##SFX *ptr, npyv_##SFX##x2 v)                         \
        {                                                                       \
            // 将结构体 v 的第一组和第二组数据分别存储到指针指向的地址和下一个地址
            npyv_store_##SFX(ptr, vcombine_##SFX(                               \
                vget_low_##SFX(v.val[0]),  vget_low_##SFX(v.val[1])));          \
            npyv_store_##SFX(ptr + 2, vcombine_##SFX(                           \
                vget_high_##SFX(v.val[0]),  vget_high_##SFX(v.val[1])));        \
        }
        // 实例化宏,生成具体的函数定义和实现
        NPYV_IMPL_NEON_MEM_INTERLEAVE_64(u64)
        NPYV_IMPL_NEON_MEM_INTERLEAVE_64(s64)
#endif // 结束预处理指令

/*********************************
 * Lookup table
 *********************************/
// 使用矢量作为表中的索引
// 该表包含32个uint32元素。
NPY_FINLINE npyv_u32 npyv_lut32_u32(const npy_uint32 *table, npyv_u32 idx)
{
    // 提取索引中的第一个值
    const unsigned i0 = vgetq_lane_u32(idx, 0);
    // 提取索引中的第二个值
    const unsigned i1 = vgetq_lane_u32(idx, 1);
    // 提取索引中的第三个值
    const unsigned i2 = vgetq_lane_u32(idx, 2);
    // 提取索引中的第四个值
    const unsigned i3 = vgetq_lane_u32(idx, 3);

    // 创建一个包含table[i0]的低位uint32x2_t值
    uint32x2_t low = vcreate_u32(table[i0]);
               // 从table中以i1为索引读取一个uint32_t值并将它加载到low的第二个位置
               low = vld1_lane_u32((const uint32_t*)table + i1, low, 1);
    // 创建一个包含table[i2]的高位uint32x2_t值
    uint32x2_t high = vcreate_u32(table[i2]);
               // 从table中以i3为索引读取一个uint32_t值并将它加载到high的第二个位置
               high = vld1_lane_u32((const uint32_t*)table + i3, high, 1);
    return vcombine_u32(low, high); // 组合低位和高位,返回结果
}
// 对npy_int32类型的表进行32位查找
NPY_FINLINE npyv_s32 npyv_lut32_s32(const npy_int32 *table, npyv_u32 idx)
{ return npyv_reinterpret_s32_u32(npyv_lut32_u32((const npy_uint32*)table, idx)); }
// 对float类型的表进行32位查找
NPY_FINLINE npyv_f32 npyv_lut32_f32(const float *table, npyv_u32 idx)
{ return npyv_reinterpret_f32_u32(npyv_lut32_u32((const npy_uint32*)table, idx)); }

// 使用矢量作为索引的表
// 该表包含16个uint64元素。
NPY_FINLINE npyv_u64 npyv_lut16_u64(const npy_uint64 *table, npyv_u64 idx)
{
    // 从索引中提取低位值
    const unsigned i0 = vgetq_lane_u32(vreinterpretq_u32_u64(idx), 0);
    // 从索引中提取高位值
    const unsigned i1 = vgetq_lane_u32(vreinterpretq_u32_u64(idx), 2);
    return vcombine_u64(
        vld1_u64((const uint64_t*)table + i0), // 从table中以i0为索引读取uint64_t值
        vld1_u64((const uint64_t*)table + i1)  // 从table中以i1为索引读取uint64_t值
    );
}
// 对npy_int64类型的表进行64位查找
NPY_FINLINE npyv_s64 npyv_lut16_s64(const npy_int64 *table, npyv_u64 idx)
{ return npyv_reinterpret_s64_u64(npyv_lut16_u64((const npy_uint64*)table, idx)); }
// 当NPY_SIMD_F64宏被定义时,对double类型的表进行64位查找
#if NPY_SIMD_F64
NPY_FINLINE npyv_f64 npyv_lut16_f64(const double *table, npyv_u64 idx)
{ return npyv_reinterpret_f64_u64(npyv_lut16_u64((const npy_uint64*)table, idx)); }
#endif

#endif // 结束预处理指令

.\numpy\numpy\_core\src\common\simd\neon\misc.h

#ifndef NPY_SIMD
    // 如果未定义 NPY_SIMD 宏,则报错,因为此文件不可作为独立头文件使用
    #error "Not a standalone header"
#endif

#ifndef _NPY_SIMD_NEON_MISC_H
#define _NPY_SIMD_NEON_MISC_H

// 定义一个函数-like 宏,用于返回所有通道为零的 uint8x16_t 向量
#define npyv_zero_u8()  vreinterpretq_u8_s32(npyv_zero_s32())
// 定义一个函数-like 宏,用于返回所有通道为零的 int8x16_t 向量
#define npyv_zero_s8()  vreinterpretq_s8_s32(npyv_zero_s32())
// 定义一个函数-like 宏,用于返回所有通道为零的 uint16x8_t 向量
#define npyv_zero_u16() vreinterpretq_u16_s32(npyv_zero_s32())
// 定义一个函数-like 宏,用于返回所有通道为零的 int16x8_t 向量
#define npyv_zero_s16() vreinterpretq_s16_s32(npyv_zero_s32())
// 定义一个函数-like 宏,用于返回所有通道为零的 uint32x4_t 向量
#define npyv_zero_u32() vdupq_n_u32((unsigned)0)
// 定义一个函数-like 宏,用于返回所有通道为零的 int32x4_t 向量
#define npyv_zero_s32() vdupq_n_s32((int)0)
// 定义一个函数-like 宏,用于返回所有通道为零的 uint64x2_t 向量
#define npyv_zero_u64() vreinterpretq_u64_s32(npyv_zero_s32())
// 定义一个函数-like 宏,用于返回所有通道为零的 int64x2_t 向量
#define npyv_zero_s64() vreinterpretq_s64_s32(npyv_zero_s32())
// 定义一个函数-like 宏,用于返回所有通道为零的 float32x4_t 向量
#define npyv_zero_f32() vdupq_n_f32(0.0f)
// 定义一个函数-like 宏,用于返回所有通道为零的 float64x2_t 向量
#define npyv_zero_f64() vdupq_n_f64(0.0)

// 定义一个函数-like 宏,用于返回所有通道设置为指定值的 uint8x16_t 向量
#define npyv_setall_u8  vdupq_n_u8
// 定义一个函数-like 宏,用于返回所有通道设置为指定值的 int8x16_t 向量
#define npyv_setall_s8  vdupq_n_s8
// 定义一个函数-like 宏,用于返回所有通道设置为指定值的 uint16x8_t 向量
#define npyv_setall_u16 vdupq_n_u16
// 定义一个函数-like 宏,用于返回所有通道设置为指定值的 int16x8_t 向量
#define npyv_setall_s16 vdupq_n_s16
// 定义一个函数-like 宏,用于返回所有通道设置为指定值的 uint32x4_t 向量
#define npyv_setall_u32 vdupq_n_u32
// 定义一个函数-like 宏,用于返回所有通道设置为指定值的 int32x4_t 向量
#define npyv_setall_s32 vdupq_n_s32
// 定义一个函数-like 宏,用于返回所有通道设置为指定值的 uint64x2_t 向量
#define npyv_setall_u64 vdupq_n_u64
// 定义一个函数-like 宏,用于返回所有通道设置为指定值的 int64x2_t 向量
#define npyv_setall_s64 vdupq_n_s64
// 定义一个函数-like 宏,用于返回所有通道设置为指定值的 float32x4_t 向量
#define npyv_setall_f32 vdupq_n_f32
// 定义一个函数-like 宏,用于返回所有通道设置为指定值的 float64x2_t 向量
#define npyv_setall_f64 vdupq_n_f64

// 定义一个函数-like 宏,根据填充值 FILL 和其他参数,返回指定类型和值的向量
// 这些宏适用于不同大小的数据类型,并且具有变长参数列表
#if defined(__clang__) || defined(__GNUC__)
    #define npyv_setf_u8(FILL, ...)  ((uint8x16_t){NPYV__SET_FILL_16(uint8_t, FILL, __VA_ARGS__)})
    #define npyv_setf_s8(FILL, ...)  ((int8x16_t){NPYV__SET_FILL_16(int8_t, FILL, __VA_ARGS__)})
    #define npyv_setf_u16(FILL, ...) ((uint16x8_t){NPYV__SET_FILL_8(uint16_t, FILL, __VA_ARGS__)})
    #define npyv_setf_s16(FILL, ...) ((int16x8_t){NPYV__SET_FILL_8(int16_t, FILL, __VA_ARGS__)})
    #define npyv_setf_u32(FILL, ...) ((uint32x4_t){NPYV__SET_FILL_4(uint32_t, FILL, __VA_ARGS__)})
    #define npyv_setf_s32(FILL, ...) ((int32x4_t){NPYV__SET_FILL_4(int32_t, FILL, __VA_ARGS__)})
    #define npyv_setf_u64(FILL, ...) ((uint64x2_t){NPYV__SET_FILL_2(uint64_t, FILL, __VA_ARGS__)})
    #define npyv_setf_s64(FILL, ...) ((int64x2_t){NPYV__SET_FILL_2(int64_t, FILL, __VA_ARGS__)})
    #define npyv_setf_f32(FILL, ...) ((float32x4_t){NPYV__SET_FILL_4(float, FILL, __VA_ARGS__)})
    #if NPY_SIMD_F64
        #define npyv_setf_f64(FILL, ...) ((float64x2_t){NPYV__SET_FILL_2(double, FILL, __VA_ARGS__)})
    #endif
#else
    // 对于不支持变长参数的编译器,定义一个函数,手动设置向量的每个通道值,并返回向量
    NPY_FINLINE uint8x16_t npyv__set_u8(npy_uint8 i0, npy_uint8 i1, npy_uint8 i2, npy_uint8 i3,
        npy_uint8 i4, npy_uint8 i5, npy_uint8 i6, npy_uint8 i7, npy_uint8 i8, npy_uint8 i9,
        npy_uint8 i10, npy_uint8 i11, npy_uint8 i12, npy_uint8 i13, npy_uint8 i14, npy_uint8 i15)
    {
        // 创建一个数据数组,存储指定的每个通道的值
        const uint8_t NPY_DECL_ALIGNED(16) data[16] = {
            i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15
        };
        // 使用 vld1q_u8 函数加载数据数组,返回一个 uint8x16_t 向量
        return vld1q_u8(data);
    }
#endif

#endif // _NPY_SIMD_NEON_MISC_H
    # 定义一个内联函数,用于创建一个包含8个int8_t元素的向量
    NPY_FINLINE int8x16_t npyv__set_s8(npy_int8 i0, npy_int8 i1, npy_int8 i2, npy_int8 i3,
        npy_int8 i4, npy_int8 i5, npy_int8 i6, npy_int8 i7, npy_int8 i8, npy_int8 i9,
        npy_int8 i10, npy_int8 i11, npy_int8 i12, npy_int8 i13, npy_int8 i14, npy_int8 i15)
    {
        # 创建一个包含16个int8_t元素的常量数组
        const int8_t NPY_DECL_ALIGNED(16) data[16] = {
            i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15
        };
        # 使用ARM NEON指令加载16字节对齐的数据并返回一个int8x16_t类型的向量
        return vld1q_s8(data);
    }
    
    # 定义一个内联函数,用于创建一个包含8个uint16_t元素的向量
    NPY_FINLINE uint16x8_t npyv__set_u16(npy_uint16 i0, npy_uint16 i1, npy_uint16 i2, npy_uint16 i3,
        npy_uint16 i4, npy_uint16 i5, npy_uint16 i6, npy_uint16 i7)
    {
        # 创建一个包含8个uint16_t元素的常量数组
        const uint16_t NPY_DECL_ALIGNED(16) data[8] = {i0, i1, i2, i3, i4, i5, i6, i7};
        # 使用ARM NEON指令加载16字节对齐的数据并返回一个uint16x8_t类型的向量
        return vld1q_u16(data);
    }
    
    # 定义一个内联函数,用于创建一个包含8个int16_t元素的向量
    NPY_FINLINE int16x8_t npyv__set_s16(npy_int16 i0, npy_int16 i1, npy_int16 i2, npy_int16 i3,
        npy_int16 i4, npy_int16 i5, npy_int16 i6, npy_int16 i7)
    {
        # 创建一个包含8个int16_t元素的常量数组
        const int16_t NPY_DECL_ALIGNED(16) data[8] = {i0, i1, i2, i3, i4, i5, i6, i7};
        # 使用ARM NEON指令加载16字节对齐的数据并返回一个int16x8_t类型的向量
        return vld1q_s16(data);
    }
    
    # 定义一个内联函数,用于创建一个包含4个uint32_t元素的向量
    NPY_FINLINE uint32x4_t npyv__set_u32(npy_uint32 i0, npy_uint32 i1, npy_uint32 i2, npy_uint32 i3)
    {
        # 创建一个包含4个uint32_t元素的常量数组
        const uint32_t NPY_DECL_ALIGNED(16) data[4] = {i0, i1, i2, i3};
        # 使用ARM NEON指令加载16字节对齐的数据并返回一个uint32x4_t类型的向量
        return vld1q_u32(data);
    }
    
    # 定义一个内联函数,用于创建一个包含4个int32_t元素的向量
    NPY_FINLINE int32x4_t npyv__set_s32(npy_int32 i0, npy_int32 i1, npy_int32 i2, npy_int32 i3)
    {
        # 创建一个包含4个int32_t元素的常量数组
        const int32_t NPY_DECL_ALIGNED(16) data[4] = {i0, i1, i2, i3};
        # 使用ARM NEON指令加载16字节对齐的数据并返回一个int32x4_t类型的向量
        return vld1q_s32(data);
    }
    
    # 定义一个内联函数,用于创建一个包含2个uint64_t元素的向量
    NPY_FINLINE uint64x2_t npyv__set_u64(npy_uint64 i0, npy_uint64 i1)
    {
        # 创建一个包含2个uint64_t元素的常量数组
        const uint64_t NPY_DECL_ALIGNED(16) data[2] = {i0, i1};
        # 使用ARM NEON指令加载16字节对齐的数据并返回一个uint64x2_t类型的向量
        return vld1q_u64(data);
    }
    
    # 定义一个内联函数,用于创建一个包含2个int64_t元素的向量
    NPY_FINLINE int64x2_t npyv__set_s64(npy_int64 i0, npy_int64 i1)
    {
        # 创建一个包含2个int64_t元素的常量数组
        const int64_t NPY_DECL_ALIGNED(16) data[2] = {i0, i1};
        # 使用ARM NEON指令加载16字节对齐的数据并返回一个int64x2_t类型的向量
        return vld1q_s64(data);
    }
    
    # 定义一个内联函数,用于创建一个包含4个float元素的向量
    NPY_FINLINE float32x4_t npyv__set_f32(float i0, float i1, float i2, float i3)
    {
        # 创建一个包含4个float元素的常量数组
        const float NPY_DECL_ALIGNED(16) data[4] = {i0, i1, i2, i3};
        # 使用ARM NEON指令加载16字节对齐的数据并返回一个float32x4_t类型的向量
        return vld1q_f32(data);
    }
    
    # 如果支持双精度浮点运算(NPY_SIMD_F64宏定义为真),定义一个内联函数,用于创建一个包含2个double元素的向量
    #if NPY_SIMD_F64
        NPY_FINLINE float64x2_t npyv__set_f64(double i0, double i1)
        {
            # 创建一个包含2个double元素的常量数组
            const double NPY_DECL_ALIGNED(16) data[2] = {i0, i1};
            # 使用ARM NEON指令加载16字节对齐的数据并返回一个float64x2_t类型的向量
            return vld1q_f64(data);
        }
    #endif
    
    # 定义一个宏,用于创建一个包含8个uint8_t元素的向量,通过调用npyv__set_u8函数
    #define npyv_setf_u8(FILL, ...)  npyv__set_u8(NPYV__SET_FILL_16(npy_uint8, FILL, __VA_ARGS__))
    # 定义一个宏,用于创建一个包含8个int8_t元素的向量,通过调用npyv__set_s8函数
    #define npyv_setf_s8(FILL, ...)  npyv__set_s8(NPYV__SET_FILL_16(npy_int8, FILL, __VA_ARGS__))
    # 定义一个宏,用于创建一个包含8个uint16_t元素的向量,通过调用npyv__set_u16函数
    #define npyv_setf_u16(FILL, ...) npyv__set_u16(NPYV__SET_FILL_8(npy_uint16, FILL, __VA_ARGS__))
    # 定义一个宏,用于创建一个包含8个int16_t元素的向量,通过调用npyv__set_s16函数
    #define npyv_setf_s16(FILL, ...) npyv__set_s16(NPYV__SET_FILL_8(npy_int16, FILL, __VA_ARGS__))
    # 定义一个宏,用于创建一个包含4个uint32_t元素的向量,通过调用npyv__set_u32函数
    #define npyv_setf_u32(FILL, ...) npyv__set_u32(NPYV__SET_FILL_4(npy_uint32, FILL, __VA_ARGS__))
    # 定义一个宏,用于创建一个包含4个int32_t元素的向量,通过调用npyv__set_s32函数
    #define npyv_set
    #define npyv_setf_s64(FILL, ...) npyv__set_s64(NPYV__SET_FILL_2(npy_int64, FILL, __VA_ARGS__))
    # 定义一个宏,用于设置长度为2的npy_int64类型向量,填充值为FILL和可变参数列表
    
    #define npyv_setf_f32(FILL, ...) npyv__set_f32(NPYV__SET_FILL_4(float, FILL, __VA_ARGS__))
    # 定义一个宏,用于设置长度为4的float类型向量,填充值为FILL和可变参数列表
    
    #if NPY_SIMD_F64
        #define npyv_setf_f64(FILL, ...) npyv__set_f64(NPYV__SET_FILL_2(double, FILL, __VA_ARGS__))
    #endif
    # 如果NPY_SIMD_F64为真(即双精度浮点数支持可用),则定义一个宏,用于设置长度为2的double类型向量,填充值为FILL和可变参数列表
// 宏定义:设置每个向量的特定值,并将其余的所有向量设为零
#define npyv_set_u8(...)  npyv_setf_u8(0,  __VA_ARGS__)
#define npyv_set_s8(...)  npyv_setf_s8(0,  __VA_ARGS__)
#define npyv_set_u16(...) npyv_setf_u16(0, __VA_ARGS__)
#define npyv_set_s16(...) npyv_setf_s16(0, __VA_ARGS__)
#define npyv_set_u32(...) npyv_setf_u32(0, __VA_ARGS__)
#define npyv_set_s32(...) npyv_setf_s32(0, __VA_ARGS__)
#define npyv_set_u64(...) npyv_setf_u64(0, __VA_ARGS__)
#define npyv_set_s64(...) npyv_setf_s64(0, __VA_ARGS__)
#define npyv_set_f32(...) npyv_setf_f32(0, __VA_ARGS__)
#define npyv_set_f64(...) npyv_setf_f64(0, __VA_ARGS__)

// 宏定义:按每个向量的每个元素选择
#define npyv_select_u8  vbslq_u8
#define npyv_select_s8  vbslq_s8
#define npyv_select_u16 vbslq_u16
#define npyv_select_s16 vbslq_s16
#define npyv_select_u32 vbslq_u32
#define npyv_select_s32 vbslq_s32
#define npyv_select_u64 vbslq_u64
#define npyv_select_s64 vbslq_s64
#define npyv_select_f32 vbslq_f32
#define npyv_select_f64 vbslq_f64

// 宏定义:提取第一个向量的第一个元素
#define npyv_extract0_u8(A) ((npy_uint8)vgetq_lane_u8(A, 0))
#define npyv_extract0_s8(A) ((npy_int8)vgetq_lane_s8(A, 0))
#define npyv_extract0_u16(A) ((npy_uint16)vgetq_lane_u16(A, 0))
#define npyv_extract0_s16(A) ((npy_int16)vgetq_lane_s16(A, 0))
#define npyv_extract0_u32(A) ((npy_uint32)vgetq_lane_u32(A, 0))
#define npyv_extract0_s32(A) ((npy_int32)vgetq_lane_s32(A, 0))
#define npyv_extract0_u64(A) ((npy_uint64)vgetq_lane_u64(A, 0))
#define npyv_extract0_s64(A) ((npy_int64)vgetq_lane_s64(A, 0))
#define npyv_extract0_f32(A) vgetq_lane_f32(A, 0)
#define npyv_extract0_f64(A) vgetq_lane_f64(A, 0)

// 宏定义:重新解释数据类型为另一种数据类型
#define npyv_reinterpret_u8_u8(X) X
#define npyv_reinterpret_u8_s8  vreinterpretq_u8_s8
#define npyv_reinterpret_u8_u16 vreinterpretq_u8_u16
#define npyv_reinterpret_u8_s16 vreinterpretq_u8_s16
#define npyv_reinterpret_u8_u32 vreinterpretq_u8_u32
#define npyv_reinterpret_u8_s32 vreinterpretq_u8_s32
#define npyv_reinterpret_u8_u64 vreinterpretq_u8_u64
#define npyv_reinterpret_u8_s64 vreinterpretq_u8_s64
#define npyv_reinterpret_u8_f32 vreinterpretq_u8_f32
#define npyv_reinterpret_u8_f64 vreinterpretq_u8_f64

#define npyv_reinterpret_s8_s8(X) X
#define npyv_reinterpret_s8_u8  vreinterpretq_s8_u8
#define npyv_reinterpret_s8_u16 vreinterpretq_s8_u16
#define npyv_reinterpret_s8_s16 vreinterpretq_s8_s16
#define npyv_reinterpret_s8_u32 vreinterpretq_s8_u32
#define npyv_reinterpret_s8_s32 vreinterpretq_s8_s32
#define npyv_reinterpret_s8_u64 vreinterpretq_s8_u64
#define npyv_reinterpret_s8_s64 vreinterpretq_s8_s64
#define npyv_reinterpret_s8_f32 vreinterpretq_s8_f32
#define npyv_reinterpret_s8_f64 vreinterpretq_s8_f64

#define npyv_reinterpret_u16_u16(X) X
#define npyv_reinterpret_u16_u8  vreinterpretq_u16_u8
#define npyv_reinterpret_u16_s8  vreinterpretq_u16_s8
#define npyv_reinterpret_u16_s16 vreinterpretq_u16_s16
#define npyv_reinterpret_u16_u32 vreinterpretq_u16_u32
# 定义宏 npyv_reinterpret_u16_s32,用于将 16 位无符号整数向量重新解释为 32 位有符号整数向量
#define npyv_reinterpret_u16_s32 vreinterpretq_u16_s32
# 定义宏 npyv_reinterpret_u16_u64,用于将 16 位无符号整数向量重新解释为 64 位无符号整数向量
#define npyv_reinterpret_u16_u64 vreinterpretq_u16_u64
# 定义宏 npyv_reinterpret_u16_s64,用于将 16 位无符号整数向量重新解释为 64 位有符号整数向量
#define npyv_reinterpret_u16_s64 vreinterpretq_u16_s64
# 定义宏 npyv_reinterpret_u16_f32,用于将 16 位无符号整数向量重新解释为 32 位浮点数向量
#define npyv_reinterpret_u16_f32 vreinterpretq_u16_f32
# 定义宏 npyv_reinterpret_u16_f64,用于将 16 位无符号整数向量重新解释为 64 位浮点数向量
#define npyv_reinterpret_u16_f64 vreinterpretq_u16_f64

# 定义宏 npyv_reinterpret_s16_s16,用于将 16 位有符号整数向量重新解释为 16 位有符号整数向量(无需重新解释)
#define npyv_reinterpret_s16_s16(X) X
# 定义宏 npyv_reinterpret_s16_u8,用于将 16 位有符号整数向量重新解释为 8 位无符号整数向量
#define npyv_reinterpret_s16_u8  vreinterpretq_s16_u8
# 定义宏 npyv_reinterpret_s16_s8,用于将 16 位有符号整数向量重新解释为 8 位有符号整数向量
#define npyv_reinterpret_s16_s8  vreinterpretq_s16_s8
# 定义宏 npyv_reinterpret_s16_u16,用于将 16 位有符号整数向量重新解释为 16 位无符号整数向量
#define npyv_reinterpret_s16_u16 vreinterpretq_s16_u16
# 定义宏 npyv_reinterpret_s16_u32,用于将 16 位有符号整数向量重新解释为 32 位无符号整数向量
#define npyv_reinterpret_s16_u32 vreinterpretq_s16_u32
# 定义宏 npyv_reinterpret_s16_s32,用于将 16 位有符号整数向量重新解释为 32 位有符号整数向量
#define npyv_reinterpret_s16_s32 vreinterpretq_s16_s32
# 定义宏 npyv_reinterpret_s16_u64,用于将 16 位有符号整数向量重新解释为 64 位无符号整数向量
#define npyv_reinterpret_s16_u64 vreinterpretq_s16_u64
# 定义宏 npyv_reinterpret_s16_s64,用于将 16 位有符号整数向量重新解释为 64 位有符号整数向量
#define npyv_reinterpret_s16_s64 vreinterpretq_s16_s64
# 定义宏 npyv_reinterpret_s16_f32,用于将 16 位有符号整数向量重新解释为 32 位浮点数向量
#define npyv_reinterpret_s16_f32 vreinterpretq_s16_f32
# 定义宏 npyv_reinterpret_s16_f64,用于将 16 位有符号整数向量重新解释为 64 位浮点数向量
#define npyv_reinterpret_s16_f64 vreinterpretq_s16_f64

# 定义宏 npyv_reinterpret_u32_u32,用于将 32 位无符号整数向量重新解释为 32 位无符号整数向量(无需重新解释)
#define npyv_reinterpret_u32_u32(X) X
# 定义宏 npyv_reinterpret_u32_u8,用于将 32 位无符号整数向量重新解释为 8 位无符号整数向量
#define npyv_reinterpret_u32_u8  vreinterpretq_u32_u8
# 定义宏 npyv_reinterpret_u32_s8,用于将 32 位无符号整数向量重新解释为 8 位有符号整数向量
#define npyv_reinterpret_u32_s8  vreinterpretq_u32_s8
# 定义宏 npyv_reinterpret_u32_u16,用于将 32 位无符号整数向量重新解释为 16 位无符号整数向量
#define npyv_reinterpret_u32_u16 vreinterpretq_u32_u16
# 定义宏 npyv_reinterpret_u32_s16,用于将 32 位无符号整数向量重新解释为 16 位有符号整数向量
#define npyv_reinterpret_u32_s16 vreinterpretq_u32_s16
# 定义宏 npyv_reinterpret_u32_s32,用于将 32 位无符号整数向量重新解释为 32 位有符号整数向量
#define npyv_reinterpret_u32_s32 vreinterpretq_u32_s32
# 定义宏 npyv_reinterpret_u32_u64,用于将 32 位无符号整数向量重新解释为 64 位无符号整数向量
#define npyv_reinterpret_u32_u64 vreinterpretq_u32_u64
# 定义宏 npyv_reinterpret_u32_s64,用于将 32 位无符号整数向量重新解释为 64 位有符号整数向量
#define npyv_reinterpret_u32_s64 vreinterpretq_u32_s64
# 定义宏 npyv_reinterpret_u32_f32,用于将 32 位无符号整数向量重新解释为 32 位浮点数向量
#define npyv_reinterpret_u32_f32 vreinterpretq_u32_f32
# 定义宏 npyv_reinterpret_u32_f64,用于将 32 位无符号整数向量重新解释为 64 位浮点数向量
#define npyv_reinterpret_u32_f64 vreinterpretq_u32_f64

# 定义宏 npyv_reinterpret_s32_s32,用于将 32 位有符号整数向量重新解释为 32 位有符号整数向量(无需重新解释)
#define npyv_reinterpret_s32_s32(X) X
# 定义宏 npyv_reinterpret_s32_u8,用于将 32 位有符号整数向量重新解释为 8 位无符号整数向量
#define npyv_reinterpret_s32_u8  vreinterpretq_s32_u8
# 定义宏 npyv_reinterpret_s32_s8,用于将 32 位有符号整数向量重新解释为 8 位有符号整数向量
#define npyv_reinterpret_s32_s8  vreinterpretq_s32_s8
# 定义宏 npyv_reinterpret_s32_u16,用于将 32 位有符号整数向量重新解释为 16 位无符号整数向量
#define npyv_reinterpret_s32_u16 vreinterpretq_s32_u16
# 定义宏 npyv_reinterpret_s32_s16,用于将 32 位有符号整数向量重新解释为 16 位有符号整数向量
#define npyv_reinterpret_s32_s16 vreinterpretq_s32_s16
# 定义宏 npyv_reinterpret_s32_u32,用于将 32 位有符号整数向量重新解释为 32 位无符号整数向量
#define npyv_reinterpret_s32_u32 vreinterpretq_s32_u32
# 定义宏 npyv_reinterpret_s32_u64,用于将 32 位有符号整数向量重新解释为 64 位无符号整数向量
#define npyv_reinterpret_s32
// 定义一系列宏,用于将不同类型的数据重新解释为 float32 向量
#define npyv_reinterpret_f32_u8  vreinterpretq_f32_u8
#define npyv_reinterpret_f32_s8  vreinterpretq_f32_s8
#define npyv_reinterpret_f32_u16 vreinterpretq_f32_u16
#define npyv_reinterpret_f32_s16 vreinterpretq_f32_s16
#define npyv_reinterpret_f32_u32 vreinterpretq_f32_u32
#define npyv_reinterpret_f32_s32 vreinterpretq_f32_s32
#define npyv_reinterpret_f32_u64 vreinterpretq_f32_u64
#define npyv_reinterpret_f32_s64 vreinterpretq_f32_s64
#define npyv_reinterpret_f32_f64 vreinterpretq_f32_f64

// 定义一个宏,用于将相同类型的 float64 数据重新解释为 float64 向量
#define npyv_reinterpret_f64_f64(X) X
#define npyv_reinterpret_f64_u8  vreinterpretq_f64_u8
#define npyv_reinterpret_f64_s8  vreinterpretq_f64_s8
#define npyv_reinterpret_f64_u16 vreinterpretq_f64_u16
#define npyv_reinterpret_f64_s16 vreinterpretq_f64_s16
#define npyv_reinterpret_f64_u32 vreinterpretq_f64_u32
#define npyv_reinterpret_f64_s32 vreinterpretq_f64_s32
#define npyv_reinterpret_f64_u64 vreinterpretq_f64_u64
#define npyv_reinterpret_f64_s64 vreinterpretq_f64_s64
#define npyv_reinterpret_f64_f32 vreinterpretq_f64_f32

// AVX2/AVX512 架构下才需要执行的清理操作宏
#define npyv_cleanup() ((void)0)

#endif // _NPY_SIMD_NEON_MISC_H

.\numpy\numpy\_core\src\common\simd\neon\neon.h

#ifndef _NPY_SIMD_H_
    #error "Not a standalone header"
#endif

// 定义 SIMD 宽度为 128 bits
#define NPY_SIMD 128
// 定义 SIMD 宽度为 16 bytes
#define NPY_SIMD_WIDTH 16
// 定义支持单精度浮点数操作
#define NPY_SIMD_F32 1

#ifdef __aarch64__
    // 如果是 ARM64 架构,定义支持双精度浮点数操作
    #define NPY_SIMD_F64 1
#else
    // 否则,不支持双精度浮点数操作
    #define NPY_SIMD_F64 0
#endif

#ifdef NPY_HAVE_NEON_VFPV4
    // 如果支持 NEON 指令集的 FMA3 指令,设置为原生支持
    #define NPY_SIMD_FMA3 1  // native support
#else
    // 否则,使用硬件模拟的方式支持 FMA3 指令
    #define NPY_SIMD_FMA3 0  // HW emulated
#endif

// 定义 SIMD 架构为小端模式
#define NPY_SIMD_BIGENDIAN 0
// 定义 SIMD 比较信号的支持
#define NPY_SIMD_CMPSIGNAL 1

// 下面是各种数据类型的 SIMD 向量定义
typedef uint8x16_t  npyv_u8;
typedef int8x16_t   npyv_s8;
typedef uint16x8_t  npyv_u16;
typedef int16x8_t   npyv_s16;
typedef uint32x4_t  npyv_u32;
typedef int32x4_t   npyv_s32;
typedef uint64x2_t  npyv_u64;
typedef int64x2_t   npyv_s64;
typedef float32x4_t npyv_f32;

#if NPY_SIMD_F64
typedef float64x2_t npyv_f64;
#endif

typedef uint8x16_t  npyv_b8;
typedef uint16x8_t  npyv_b16;
typedef uint32x4_t  npyv_b32;
typedef uint64x2_t  npyv_b64;

// 各种 SIMD 向量的多重结构定义
typedef uint8x16x2_t  npyv_u8x2;
typedef int8x16x2_t   npyv_s8x2;
typedef uint16x8x2_t  npyv_u16x2;
typedef int16x8x2_t   npyv_s16x2;
typedef uint32x4x2_t  npyv_u32x2;
typedef int32x4x2_t   npyv_s32x2;
typedef uint64x2x2_t  npyv_u64x2;
typedef int64x2x2_t   npyv_s64x2;
typedef float32x4x2_t npyv_f32x2;

#if NPY_SIMD_F64
typedef float64x2x2_t npyv_f64x2;
#endif

typedef uint8x16x3_t  npyv_u8x3;
typedef int8x16x3_t   npyv_s8x3;
typedef uint16x8x3_t  npyv_u16x3;
typedef int16x8x3_t   npyv_s16x3;
typedef uint32x4x3_t  npyv_u32x3;
typedef int32x4x3_t   npyv_s32x3;
typedef uint64x2x3_t  npyv_u64x3;
typedef int64x2x3_t   npyv_s64x3;
typedef float32x4x3_t npyv_f32x3;

#if NPY_SIMD_F64
typedef float64x2x3_t npyv_f64x3;
#endif

// 各种数据类型 SIMD 向量的通道数定义
#define npyv_nlanes_u8  16
#define npyv_nlanes_s8  16
#define npyv_nlanes_u16 8
#define npyv_nlanes_s16 8
#define npyv_nlanes_u32 4
#define npyv_nlanes_s32 4
#define npyv_nlanes_u64 2
#define npyv_nlanes_s64 2
#define npyv_nlanes_f32 4
#define npyv_nlanes_f64 2

// 包含 SIMD 相关的头文件
#include "memory.h"
#include "misc.h"
#include "reorder.h"
#include "operators.h"
#include "conversion.h"
#include "arithmetic.h"
#include "math.h"

.\numpy\numpy\_core\src\common\simd\neon\operators.h

#ifndef NPY_SIMD
    #error "Not a standalone header"
#endif

#ifndef _NPY_SIMD_NEON_OPERATORS_H
#define _NPY_SIMD_NEON_OPERATORS_H

/***************************
 * Shifting
 ***************************/

// left shift operations for various data types
#define npyv_shl_u16(A, C) vshlq_u16(A, npyv_setall_s16(C))
#define npyv_shl_s16(A, C) vshlq_s16(A, npyv_setall_s16(C))
#define npyv_shl_u32(A, C) vshlq_u32(A, npyv_setall_s32(C))
#define npyv_shl_s32(A, C) vshlq_s32(A, npyv_setall_s32(C))
#define npyv_shl_u64(A, C) vshlq_u64(A, npyv_setall_s64(C))
#define npyv_shl_s64(A, C) vshlq_s64(A, npyv_setall_s64(C))

// left shift operations by an immediate constant for various data types
#define npyv_shli_u16 vshlq_n_u16
#define npyv_shli_s16 vshlq_n_s16
#define npyv_shli_u32 vshlq_n_u32
#define npyv_shli_s32 vshlq_n_s32
#define npyv_shli_u64 vshlq_n_u64
#define npyv_shli_s64 vshlq_n_s64

// right shift operations for various data types
#define npyv_shr_u16(A, C) vshlq_u16(A, npyv_setall_s16(-(C)))
#define npyv_shr_s16(A, C) vshlq_s16(A, npyv_setall_s16(-(C)))
#define npyv_shr_u32(A, C) vshlq_u32(A, npyv_setall_s32(-(C)))
#define npyv_shr_s32(A, C) vshlq_s32(A, npyv_setall_s32(-(C)))
#define npyv_shr_u64(A, C) vshlq_u64(A, npyv_setall_s64(-(C)))
#define npyv_shr_s64(A, C) vshlq_s64(A, npyv_setall_s64(-(C)))

// right shift operations by an immediate constant for various data types
#define npyv_shri_u16 vshrq_n_u16
#define npyv_shri_s16 vshrq_n_s16
#define npyv_shri_u32 vshrq_n_u32
#define npyv_shri_s32 vshrq_n_s32
#define npyv_shri_u64 vshrq_n_u64
#define npyv_shri_s64 vshrq_n_s64

/***************************
 * Logical
 ***************************/

// AND operations for various data types
#define npyv_and_u8  vandq_u8
#define npyv_and_s8  vandq_s8
#define npyv_and_u16 vandq_u16
#define npyv_and_s16 vandq_s16
#define npyv_and_u32 vandq_u32
#define npyv_and_s32 vandq_s32
#define npyv_and_u64 vandq_u64
#define npyv_and_s64 vandq_s64
#define npyv_and_f32(A, B) \
    vreinterpretq_f32_u8(vandq_u8(vreinterpretq_u8_f32(A), vreinterpretq_u8_f32(B)))
#define npyv_and_f64(A, B) \
    vreinterpretq_f64_u8(vandq_u8(vreinterpretq_u8_f64(A), vreinterpretq_u8_f64(B)))
#define npyv_and_b8   vandq_u8
#define npyv_and_b16  vandq_u16
#define npyv_and_b32  vandq_u32
#define npyv_and_b64  vandq_u64

// OR operations for various data types
#define npyv_or_u8  vorrq_u8
#define npyv_or_s8  vorrq_s8
#define npyv_or_u16 vorrq_u16
#define npyv_or_s16 vorrq_s16
#define npyv_or_u32 vorrq_u32
#define npyv_or_s32 vorrq_s32
#define npyv_or_u64 vorrq_u64
#define npyv_or_s64 vorrq_s64
#define npyv_or_f32(A, B) \
    vreinterpretq_f32_u8(vorrq_u8(vreinterpretq_u8_f32(A), vreinterpretq_u8_f32(B)))
#define npyv_or_f64(A, B) \
    vreinterpretq_f64_u8(vorrq_u8(vreinterpretq_u8_f64(A), vreinterpretq_u8_f64(B)))
#define npyv_or_b8   vorrq_u8
#define npyv_or_b16  vorrq_u16
#define npyv_or_b32  vorrq_u32
#define npyv_or_b64  vorrq_u64

// XOR operations for various data types
#define npyv_xor_u8  veorq_u8
#define npyv_xor_s8  veorq_s8
#define npyv_xor_u16 veorq_u16
#define npyv_xor_s16 veorq_s16
#define npyv_xor_u32 veorq_u32
#define npyv_xor_s32 veorq_s32
#define npyv_xor_u64 veorq_u64
#define npyv_xor_s64 veorq_s64
#define npyv_xor_f32(A, B) \
    vreinterpretq_f32_u8(veorq_u8(vreinterpretq_u8_f32(A), vreinterpretq_u8_f32(B)))
#define npyv_xor_f64(A, B) \
    vreinterpretq_f64_u8(veorq_u8(vreinterpretq_u8_f64(A), vreinterpretq_u8_f64(B)))
    # 将输入的两个向量 A 和 B 进行类型转换,使其分别被视为无符号 8 位整数向量和单精度浮点数向量,
    # 然后执行按位异或运算,并将结果重新转换为单精度浮点数向量返回。
    vreinterpretq_f32_u8(veorq_u8(vreinterpretq_u8_f32(A), vreinterpretq_u8_f32(B)))
// 定义宏 npyv_xor_f64,实现两个双精度浮点向量的按位异或操作
#define npyv_xor_f64(A, B) \
    vreinterpretq_f64_u8(veorq_u8(vreinterpretq_u8_f64(A), vreinterpretq_u8_f64(B)))

// 定义宏 npyv_xor_b8 到 npyv_xor_b64,分别实现8位、16位、32位和64位整数向量的按位异或操作
#define npyv_xor_b8   veorq_u8
#define npyv_xor_b16  veorq_u16
#define npyv_xor_b32  veorq_u32
#define npyv_xor_b64  veorq_u64

// 定义宏 npyv_not_u8 到 npyv_not_b64,分别实现8位、16位、32位和64位的按位取反操作
#define npyv_not_u8  vmvnq_u8
#define npyv_not_s8  vmvnq_s8
#define npyv_not_u16 vmvnq_u16
#define npyv_not_s16 vmvnq_s16
#define npyv_not_u32 vmvnq_u32
#define npyv_not_s32 vmvnq_s32
#define npyv_not_u64(A) vreinterpretq_u64_u8(vmvnq_u8(vreinterpretq_u8_u64(A)))
#define npyv_not_s64(A) vreinterpretq_s64_u8(vmvnq_u8(vreinterpretq_u8_s64(A)))
#define npyv_not_f32(A) vreinterpretq_f32_u8(vmvnq_u8(vreinterpretq_u8_f32(A)))
#define npyv_not_f64(A) vreinterpretq_f64_u8(vmvnq_u8(vreinterpretq_u8_f64(A)))
#define npyv_not_b8   vmvnq_u8
#define npyv_not_b16  vmvnq_u16
#define npyv_not_b32  vmvnq_u32
#define npyv_not_b64  npyv_not_u64

// 定义宏 npyv_andc_u8 和 npyv_andc_b8,实现8位整数向量的按位与补操作
#define npyv_andc_u8 vbicq_u8
#define npyv_andc_b8 vbicq_u8

// 定义宏 npyv_orc_b8,实现8位整数向量的按位或补操作
#define npyv_orc_b8 vornq_u8

// 定义宏 npyv_xnor_b8,实现8位整数向量的按位异或非操作
#define npyv_xnor_b8 vceqq_u8

/***************************
 * Comparison
 ***************************/

// 定义宏 npyv_cmpeq_u8 到 npyv_cmpeq_f64,分别实现相等比较操作
#define npyv_cmpeq_u8  vceqq_u8
#define npyv_cmpeq_s8  vceqq_s8
#define npyv_cmpeq_u16 vceqq_u16
#define npyv_cmpeq_s16 vceqq_s16
#define npyv_cmpeq_u32 vceqq_u32
#define npyv_cmpeq_s32 vceqq_s32
#define npyv_cmpeq_f32 vceqq_f32
#define npyv_cmpeq_f64 vceqq_f64

#ifdef __aarch64__
    // 在 ARM 64位 架构下定义宏 npyv_cmpeq_u64 和 npyv_cmpeq_s64,实现64位整数向量的相等比较操作
    #define npyv_cmpeq_u64 vceqq_u64
    #define npyv_cmpeq_s64 vceqq_s64
#else
    // 在其他架构下定义函数 npyv_cmpeq_u64,实现64位整数向量的相等比较操作
    NPY_FINLINE uint64x2_t npyv_cmpeq_u64(uint64x2_t a, uint64x2_t b)
    {
        // 将64位整数向量转换为32位整数向量进行比较,再将结果转换回64位整数向量
        uint64x2_t cmpeq = vreinterpretq_u64_u32(vceqq_u32(
            vreinterpretq_u32_u64(a), vreinterpretq_u32_u64(b)
        ));
        uint64x2_t cmpeq_h = vshlq_n_u64(cmpeq, 32); // 左移32位
        uint64x2_t test = vandq_u64(cmpeq, cmpeq_h); // 与操作
        return vreinterpretq_u64_s64(vshrq_n_s64(vreinterpretq_s64_u64(test), 32)); // 右移32位
    }
    #define npyv_cmpeq_s64(A, B) \
        npyv_cmpeq_u64(vreinterpretq_u64_s64(A), vreinterpretq_u64_s64(B)) // 实现64位有符号整数向量的相等比较操作
#endif

// 定义宏 npyv_cmpneq_u8 到 npyv_cmpneq_f64,分别实现不等比较操作
#define npyv_cmpneq_u8(A, B)  vmvnq_u8(vceqq_u8(A, B))
#define npyv_cmpneq_s8(A, B)  vmvnq_u8(vceqq_s8(A, B))
#define npyv_cmpneq_u16(A, B) vmvnq_u16(vceqq_u16(A, B))
#define npyv_cmpneq_s16(A, B) vmvnq_u16(vceqq_s16(A, B))
#define npyv_cmpneq_u32(A, B) vmvnq_u32(vceqq_u32(A, B))
#define npyv_cmpneq_s32(A, B) vmvnq_u32(vceqq_s32(A, B))
#define npyv_cmpneq_u64(A, B) npyv_not_u64(npyv_cmpeq_u64(A, B))
#define npyv_cmpneq_s64(A, B) npyv_not_u64(npyv_cmpeq_s64(A, B))
#define npyv_cmpneq_f32(A, B) vmvnq_u32(vceqq_f32(A, B))
#define npyv_cmpneq_f64(A, B) npyv_not_u64(vceqq_f64(A, B))

// 定义宏 npyv_cmpgt_u8 到 npyv_cmpgt_f64,分别实现大于比较操作
#define npyv_cmpgt_u8  vcgtq_u8
#define npyv_cmpgt_s8  vcgtq_s8
#define npyv_cmpgt_u16 vcgtq_u16
#define npyv_cmpgt_s16 vcgtq_s16
#define npyv_cmpgt_u32 vcgtq_u32
#define npyv_cmpgt_s32 vcgtq_s32
#define npyv_cmpgt_f32 vcgtq_f32
#define npyv_cmpgt_f64 vcgtq_f64

#ifdef __aarch64__
    // 在 ARM 64位 架构下定义宏 npyv_cmpgt_u64 和 npyv_cmpgt_s64,实现64位整数向量的大于比较操作
    #define npyv_cmpgt_u64 vcgtq_u64
    #define npyv_cmpgt_s64 vcgtq_s64
#else
    # 比较两个 int64x2_t 向量 a 和 b 中的元素,返回一个 uint64x2_t 向量
    NPY_FINLINE uint64x2_t npyv_cmpgt_s64(int64x2_t a, int64x2_t b)
    {
        # 计算 b - a 的结果
        int64x2_t sub = vsubq_s64(b, a);
        # 反转 a 和 b 的比特位,得到一个相同位为 0 的 uint64x2_t 向量
        uint64x2_t nsame_sbit = vreinterpretq_u64_s64(veorq_s64(a, b));
        # 使用 nsame_sbit 对 b 和 sub 进行条件选择,得到一个条件选择的结果向量
        int64x2_t test = vbslq_s64(nsame_sbit, b, sub);
        # 对 test 进行右移 63 位,以获得符号位的扩展
        int64x2_t extend_sbit = vshrq_n_s64(test, 63);
        # 将 extend_sbit 转换为 uint64x2_t 向量并返回
        return vreinterpretq_u64_s64(extend_sbit);
    }
    
    # 比较两个 uint64x2_t 向量 a 和 b 中的元素,返回一个 uint64x2_t 向量
    NPY_FINLINE uint64x2_t npyv_cmpgt_u64(uint64x2_t a, uint64x2_t b)
    {
        # 定义一个常量向量 sbit,所有比特位为 0x8000000000000000
        const uint64x2_t sbit = npyv_setall_u64(0x8000000000000000);
        # 对 a 和 b 的比特位进行反转
        a = npyv_xor_u64(a, sbit);
        b = npyv_xor_u64(b, sbit);
        # 调用 npyv_cmpgt_s64 函数,将 a 和 b 转换为 int64x2_t 向量进行比较,并返回结果
        return npyv_cmpgt_s64(vreinterpretq_s64_u64(a), vreinterpretq_s64_u64(b));
    }
#endif

// 定义比较操作:大于等于
#define npyv_cmpge_u8  vcgeq_u8     // 比较无符号8位整数是否大于等于
#define npyv_cmpge_s8  vcgeq_s8     // 比较有符号8位整数是否大于等于
#define npyv_cmpge_u16 vcgeq_u16    // 比较无符号16位整数是否大于等于
#define npyv_cmpge_s16 vcgeq_s16    // 比较有符号16位整数是否大于等于
#define npyv_cmpge_u32 vcgeq_u32    // 比较无符号32位整数是否大于等于
#define npyv_cmpge_s32 vcgeq_s32    // 比较有符号32位整数是否大于等于
#define npyv_cmpge_f32 vcgeq_f32    // 比较单精度浮点数是否大于等于
#define npyv_cmpge_f64 vcgeq_f64    // 比较双精度浮点数是否大于等于

#ifdef __aarch64__
    #define npyv_cmpge_u64 vcgeq_u64    // 比较无符号64位整数是否大于等于
    #define npyv_cmpge_s64 vcgeq_s64    // 比较有符号64位整数是否大于等于
#else
    #define npyv_cmpge_u64(A, B) npyv_not_u64(npyv_cmpgt_u64(B, A))   // 比较无符号64位整数是否大于等于(兼容性处理)
    #define npyv_cmpge_s64(A, B) npyv_not_u64(npyv_cmpgt_s64(B, A))   // 比较有符号64位整数是否大于等于(兼容性处理)
#endif

// 小于比较
#define npyv_cmplt_u8(A, B)  npyv_cmpgt_u8(B, A)     // 比较无符号8位整数是否小于
#define npyv_cmplt_s8(A, B)  npyv_cmpgt_s8(B, A)     // 比较有符号8位整数是否小于
#define npyv_cmplt_u16(A, B) npyv_cmpgt_u16(B, A)    // 比较无符号16位整数是否小于
#define npyv_cmplt_s16(A, B) npyv_cmpgt_s16(B, A)    // 比较有符号16位整数是否小于
#define npyv_cmplt_u32(A, B) npyv_cmpgt_u32(B, A)    // 比较无符号32位整数是否小于
#define npyv_cmplt_s32(A, B) npyv_cmpgt_s32(B, A)    // 比较有符号32位整数是否小于
#define npyv_cmplt_u64(A, B) npyv_cmpgt_u64(B, A)    // 比较无符号64位整数是否小于
#define npyv_cmplt_s64(A, B) npyv_cmpgt_s64(B, A)    // 比较有符号64位整数是否小于
#define npyv_cmplt_f32(A, B) npyv_cmpgt_f32(B, A)    // 比较单精度浮点数是否小于
#define npyv_cmplt_f64(A, B) npyv_cmpgt_f64(B, A)    // 比较双精度浮点数是否小于

// 小于等于比较
#define npyv_cmple_u8(A, B)  npyv_cmpge_u8(B, A)     // 比较无符号8位整数是否小于等于
#define npyv_cmple_s8(A, B)  npyv_cmpge_s8(B, A)     // 比较有符号8位整数是否小于等于
#define npyv_cmple_u16(A, B) npyv_cmpge_u16(B, A)    // 比较无符号16位整数是否小于等于
#define npyv_cmple_s16(A, B) npyv_cmpge_s16(B, A)    // 比较有符号16位整数是否小于等于
#define npyv_cmple_u32(A, B) npyv_cmpge_u32(B, A)    // 比较无符号32位整数是否小于等于
#define npyv_cmple_s32(A, B) npyv_cmpge_s32(B, A)    // 比较有符号32位整数是否小于等于
#define npyv_cmple_u64(A, B) npyv_cmpge_u64(B, A)    // 比较无符号64位整数是否小于等于
#define npyv_cmple_s64(A, B) npyv_cmpge_s64(B, A)    // 比较有符号64位整数是否小于等于
#define npyv_cmple_f32(A, B) npyv_cmpge_f32(B, A)    // 比较单精度浮点数是否小于等于
#define npyv_cmple_f64(A, B) npyv_cmpge_f64(B, A)    // 比较双精度浮点数是否小于等于

// 检查特殊情况
NPY_FINLINE npyv_b32 npyv_notnan_f32(npyv_f32 a)
{
#if defined(__clang__)
/**
 * 为了避免信号qNaN,对于clang对称输入的错误
 * 检查 https://github.com/numpy/numpy/issues/22933,
 * 以获取更多的解释
 */
    npyv_b32 ret;
    #if NPY_SIMD_F64
        __asm("fcmeq %0.4s, %1.4s, %1.4s" : "=w" (ret) : "w" (a));
    #else
        __asm("vceq.f32 %q0, %q1, %q1" : "=w" (ret) : "w" (a));
    #endif
    return ret;
#else
    return vceqq_f32(a, a);
#endif
}

#if NPY_SIMD_F64
    NPY_FINLINE npyv_b64 npyv_notnan_f64(npyv_f64 a)
    {
    #if defined(__clang__)
        npyv_b64 ret;
        __asm("fcmeq %0.2d, %1.2d, %1.2d" : "=w" (ret) : "w" (a));
        return ret;
    #else
        return vceqq_f64(a, a);
    #endif
    }
#endif

// 测试跨所有向量通道
// any: 如果任何元素不等于零则返回true
// all: 如果所有元素都不等于零则返回true
#if NPY_SIMD_F64
    #define NPYV_IMPL_NEON_ANYALL(LEN)                  \
        NPY_FINLINE bool npyv_any_b##LEN(npyv_b##LEN a) \
        { return vmaxvq_u##LEN(a) != 0; }               \
        NPY_FINLINE bool npyv_all_b##LEN(npyv_b##LEN a) \
        { return vminvq_u##LEN(a) != 0; }
    NPYV_IMPL_NEON_ANYALL(8)    // 检查8个元素中是否有任何一个不等于零
    NPYV_IMPL_NEON_ANYALL(16)   // 检查16个元素中是否有任何一个不等于零
    NPYV_IMPL_NEON_ANYALL(32)   // 检查32个元素中是否有任何一个不等于零
    #undef NPYV_IMPL_NEON_ANYALL
    #define NPYV_IMPL_NEON_ANYALL(SFX, USFX, BSFX)                      \
        // 定义 NEON SIMD 操作的任意元素和所有元素的宏函数
        NPY_FINLINE bool npyv_any_##SFX(npyv_##SFX a)                   \
        // 实现检查 NEON SIMD 向量是否存在非零元素的函数
        { return npyv_any_##BSFX(npyv_reinterpret_##USFX##_##SFX(a)); } \
        NPY_FINLINE bool npyv_all_##SFX(npyv_##SFX a)                   \
        // 实现检查 NEON SIMD 向量是否所有元素都非零的函数
        { return npyv_all_##BSFX(npyv_reinterpret_##USFX##_##SFX(a)); }
    
    NPYV_IMPL_NEON_ANYALL(u8,  u8,  b8)
    NPYV_IMPL_NEON_ANYALL(s8,  u8,  b8)
    NPYV_IMPL_NEON_ANYALL(u16, u16, b16)
    NPYV_IMPL_NEON_ANYALL(s16, u16, b16)
    NPYV_IMPL_NEON_ANYALL(u32, u32, b32)
    NPYV_IMPL_NEON_ANYALL(s32, u32, b32)
    #undef NPYV_IMPL_NEON_ANYALL
    
    NPY_FINLINE bool npyv_any_b64(npyv_b64 a)
    // 实现检查 NEON SIMD 向量是否存在非零 64 位元素的函数
    { return vmaxvq_u32(vreinterpretq_u32_u64(a)) != 0; }
    NPY_FINLINE bool npyv_all_b64(npyv_b64 a)
    // 实现检查 NEON SIMD 向量是否所有 64 位元素都非零的函数
    { return vminvq_u32(vreinterpretq_u32_u64(a)) != 0; }
    #define npyv_any_u64 npyv_any_b64
    NPY_FINLINE bool npyv_all_u64(npyv_u64 a)
    {
        uint32x4_t a32 = vreinterpretq_u32_u64(a);
                   a32 = vorrq_u32(a32, vrev64q_u32(a32));
        // 使用 NEON 指令将向量的 64 位数据转换为 32 位并反转,以便检查是否所有元素非零
        return vminvq_u32(a32) != 0;
    }
    NPY_FINLINE bool npyv_any_s64(npyv_s64 a)
    // 实现检查 NEON SIMD 向量是否存在非零 64 位有符号整数元素的函数
    { return npyv_any_u64(vreinterpretq_u64_s64(a)); }
    NPY_FINLINE bool npyv_all_s64(npyv_s64 a)
    // 实现检查 NEON SIMD 向量是否所有 64 位有符号整数元素都非零的函数
    { return npyv_all_u64(vreinterpretq_u64_s64(a)); }
    
    #define NPYV_IMPL_NEON_ANYALL(SFX, BSFX)                                 \
        // 定义 NEON SIMD 操作的任意元素和所有元素的宏函数,特定于浮点类型
        NPY_FINLINE bool npyv_any_##SFX(npyv_##SFX a)                        \
        // 实现检查 NEON SIMD 向量是否存在非零元素的函数,特定于浮点类型
        { return !npyv_all_##BSFX(npyv_cmpeq_##SFX(a, npyv_zero_##SFX())); } \
        NPY_FINLINE bool npyv_all_##SFX(npyv_##SFX a)                        \
        // 实现检查 NEON SIMD 向量是否所有元素都非零的函数,特定于浮点类型
        { return !npyv_any_##BSFX(npyv_cmpeq_##SFX(a, npyv_zero_##SFX())); }
    NPYV_IMPL_NEON_ANYALL(f32, b32)
    NPYV_IMPL_NEON_ANYALL(f64, b64)
    #undef NPYV_IMPL_NEON_ANYALL
#else
    #define NPYV_IMPL_NEON_ANYALL(LEN)                    \
        NPY_FINLINE bool npyv_any_b##LEN(npyv_b##LEN a)   \
        {                                                 \
            // 将布尔型向量转换为64位整型向量
            int64x2_t a64 = vreinterpretq_s64_u##LEN(a);  \
            // 检查向量中是否有任何一个元素为真
            return (                                      \
                vgetq_lane_s64(a64, 0) |                  \
                vgetq_lane_s64(a64, 1)                    \
            ) != 0;                                       \
        }                                                 \
        NPY_FINLINE bool npyv_all_b##LEN(npyv_b##LEN a)   \
        {                                                 \
            // 将布尔型向量转换为64位整型向量
            int64x2_t a64 = vreinterpretq_s64_u##LEN(a);  \
            // 检查向量中所有元素是否都为真
            return (                                      \
                vgetq_lane_s64(a64, 0) &                  \
                vgetq_lane_s64(a64, 1)                    \
            ) == -1;                                      \
        }
    // 实现NEON指令集的任意/全部操作,针对不同长度的布尔型向量
    NPYV_IMPL_NEON_ANYALL(8)
    NPYV_IMPL_NEON_ANYALL(16)
    NPYV_IMPL_NEON_ANYALL(32)
    NPYV_IMPL_NEON_ANYALL(64)
    #undef NPYV_IMPL_NEON_ANYALL

    #define NPYV_IMPL_NEON_ANYALL(SFX, USFX)              \
        NPY_FINLINE bool npyv_any_##SFX(npyv_##SFX a)     \
        {                                                 \
            // 将SFX类型向量转换为64位整型向量
            int64x2_t a64 = vreinterpretq_s64_##SFX(a);   \
            // 检查向量中是否有任何一个元素为真
            return (                                      \
                vgetq_lane_s64(a64, 0) |                  \
                vgetq_lane_s64(a64, 1)                    \
            ) != 0;                                       \
        }                                                 \
        NPY_FINLINE bool npyv_all_##SFX(npyv_##SFX a)     \
        {                                                 \
            // 比较SFX类型向量与零向量,检查是否所有元素都为零
            npyv_##USFX tz = npyv_cmpeq_##SFX(            \
                a, npyv_zero_##SFX()                      \
            );                                            \
            // 将USFX类型向量转换为64位整型向量
            int64x2_t a64 = vreinterpretq_s64_##USFX(tz); \
            // 检查向量中所有元素是否都为真
            return (                                      \
                vgetq_lane_s64(a64, 0) &                  \
                vgetq_lane_s64(a64, 1)                    \
            ) == 0;                                       \
        }
    // 实现NEON指令集的任意/全部操作,包括无符号和有符号不同类型
    NPYV_IMPL_NEON_ANYALL(u8,  u8)
    NPYV_IMPL_NEON_ANYALL(s8,  u8)
    NPYV_IMPL_NEON_ANYALL(u16, u16)
    NPYV_IMPL_NEON_ANYALL(s16, u16)
    NPYV_IMPL_NEON_ANYALL(u32, u32)
    NPYV_IMPL_NEON_ANYALL(s32, u32)
    #undef NPYV_IMPL_NEON_ANYALL

    // 检查32位浮点型向量中是否有任何一个元素为真
    NPY_FINLINE bool npyv_any_f32(npyv_f32 a)
    {
        uint32x4_t tz = npyv_cmpeq_f32(a, npyv_zero_f32());
        // 将32位浮点型向量转换为64位整型向量,并检查是否有任何一个元素为真
        int64x2_t a64 = vreinterpretq_s64_u32(tz);
        return (vgetq_lane_s64(a64, 0) & vgetq_lane_s64(a64, 1)) != -1ll;
    }
    // 检查32位浮点型向量中是否所有元素都为真
    NPY_FINLINE bool npyv_all_f32(npyv_f32 a)
    {
        // 将浮点向量 a 中每个元素与零进行比较,生成一个比较结果向量 tz
        uint32x4_t tz = npyv_cmpeq_f32(a, npyv_zero_f32());
        // 将结果向量 tz 转换为含有两个 64 位有符号整数的向量 a64
        int64x2_t a64 = vreinterpretq_s64_u32(tz);
        // 检查 a64 中的两个元素是否都为零,返回检查结果
        return (vgetq_lane_s64(a64, 0) | vgetq_lane_s64(a64, 1)) == 0;
    }
    NPY_FINLINE bool npyv_any_s64(npyv_s64 a)
    {
        // 检查输入向量 a 中的两个 64 位有符号整数元素是否有任意一个非零,返回检查结果
        return (vgetq_lane_s64(a, 0) | vgetq_lane_s64(a, 1)) != 0;
    }
    NPY_FINLINE bool npyv_all_s64(npyv_s64 a)
    {
        // 检查输入向量 a 中的两个 64 位有符号整数元素是否都非零,返回检查结果
        return vgetq_lane_s64(a, 0) && vgetq_lane_s64(a, 1);
    }
    NPY_FINLINE bool npyv_any_u64(npyv_u64 a)
    {
        // 检查输入向量 a 中的两个 64 位无符号整数元素是否有任意一个非零,返回检查结果
        return (vgetq_lane_u64(a, 0) | vgetq_lane_u64(a, 1)) != 0;
    }
    NPY_FINLINE bool npyv_all_u64(npyv_u64 a)
    {
        // 检查输入向量 a 中的两个 64 位无符号整数元素是否都非零,返回检查结果
        return vgetq_lane_u64(a, 0) && vgetq_lane_u64(a, 1);
    }
#endif // NPY_SIMD_F64



// 如果定义了 NPY_SIMD_F64 宏,则结束当前的条件编译段落
#endif // NPY_SIMD_F64



#endif // _NPY_SIMD_NEON_OPERATORS_H



// 结束当前的条件编译段落,该段落由 _NPY_SIMD_NEON_OPERATORS_H 宏控制
#endif // _NPY_SIMD_NEON_OPERATORS_H

.\numpy\numpy\_core\src\common\simd\neon\reorder.h

#ifndef NPY_SIMD
    #error "Not a standalone header"
#endif

#ifndef _NPY_SIMD_NEON_REORDER_H
#define _NPY_SIMD_NEON_REORDER_H

// 定义 __aarch64__ 情况下的向量操作宏,用于合并两个向量的低部分元素
#ifdef __aarch64__
    #define npyv_combinel_u8(A, B)  vreinterpretq_u8_u64(vzip1q_u64(vreinterpretq_u64_u8(A), vreinterpretq_u64_u8(B)))
    #define npyv_combinel_s8(A, B)  vreinterpretq_s8_u64(vzip1q_u64(vreinterpretq_u64_s8(A), vreinterpretq_u64_s8(B)))
    #define npyv_combinel_u16(A, B) vreinterpretq_u16_u64(vzip1q_u64(vreinterpretq_u64_u16(A), vreinterpretq_u64_u16(B)))
    #define npyv_combinel_s16(A, B) vreinterpretq_s16_u64(vzip1q_u64(vreinterpretq_u64_s16(A), vreinterpretq_u64_s16(B)))
    #define npyv_combinel_u32(A, B) vreinterpretq_u32_u64(vzip1q_u64(vreinterpretq_u64_u32(A), vreinterpretq_u64_u32(B)))
    #define npyv_combinel_s32(A, B) vreinterpretq_s32_u64(vzip1q_u64(vreinterpretq_u64_s32(A), vreinterpretq_u64_s32(B)))
    #define npyv_combinel_u64       vzip1q_u64
    #define npyv_combinel_s64       vzip1q_s64
    #define npyv_combinel_f32(A, B) vreinterpretq_f32_u64(vzip1q_u64(vreinterpretq_u64_f32(A), vreinterpretq_u64_f32(B)))
    #define npyv_combinel_f64       vzip1q_f64
#else
    // 定义非 __aarch64__ 情况下的向量操作宏,用于合并两个向量的低部分元素
    #define npyv_combinel_u8(A, B)  vcombine_u8(vget_low_u8(A), vget_low_u8(B))
    #define npyv_combinel_s8(A, B)  vcombine_s8(vget_low_s8(A), vget_low_s8(B))
    #define npyv_combinel_u16(A, B) vcombine_u16(vget_low_u16(A), vget_low_u16(B))
    #define npyv_combinel_s16(A, B) vcombine_s16(vget_low_s16(A), vget_low_s16(B))
    #define npyv_combinel_u32(A, B) vcombine_u32(vget_low_u32(A), vget_low_u32(B))
    #define npyv_combinel_s32(A, B) vcombine_s32(vget_low_s32(A), vget_low_s32(B))
    #define npyv_combinel_u64(A, B) vcombine_u64(vget_low_u64(A), vget_low_u64(B))
    #define npyv_combinel_s64(A, B) vcombine_s64(vget_low_s64(A), vget_low_s64(B))
    #define npyv_combinel_f32(A, B) vcombine_f32(vget_low_f32(A), vget_low_f32(B))
#endif

// 定义 __aarch64__ 情况下的向量操作宏,用于合并两个向量的高部分元素
#ifdef __aarch64__
    #define npyv_combineh_u8(A, B)  vreinterpretq_u8_u64(vzip2q_u64(vreinterpretq_u64_u8(A), vreinterpretq_u64_u8(B)))
    #define npyv_combineh_s8(A, B)  vreinterpretq_s8_u64(vzip2q_u64(vreinterpretq_u64_s8(A), vreinterpretq_u64_s8(B)))
    #define npyv_combineh_u16(A, B) vreinterpretq_u16_u64(vzip2q_u64(vreinterpretq_u64_u16(A), vreinterpretq_u64_u16(B)))
    #define npyv_combineh_s16(A, B) vreinterpretq_s16_u64(vzip2q_u64(vreinterpretq_u64_s16(A), vreinterpretq_u64_s16(B)))
    #define npyv_combineh_u32(A, B) vreinterpretq_u32_u64(vzip2q_u64(vreinterpretq_u64_u32(A), vreinterpretq_u64_u32(B)))
    #define npyv_combineh_s32(A, B) vreinterpretq_s32_u64(vzip2q_u64(vreinterpretq_u64_s32(A), vreinterpretq_u64_s32(B)))
    #define npyv_combineh_u64       vzip2q_u64
    #define npyv_combineh_s64       vzip2q_s64
    #define npyv_combineh_f32(A, B) vreinterpretq_f32_u64(vzip2q_u64(vreinterpretq_u64_f32(A), vreinterpretq_u64_f32(B)))
    #define npyv_combineh_f64       vzip2q_f64
#else
    // 定义非 __aarch64__ 情况下的向量操作宏,用于合并两个向量的高部分元素
#endif

#endif
    # 定义宏函数 `npyv_combineh_u8(A, B)`,将两个 uint8x8_t 类型的寄存器 A 和 B 的高位元素组合成一个新的寄存器
    #define npyv_combineh_u8(A, B)  vcombine_u8(vget_high_u8(A), vget_high_u8(B))
    
    # 定义宏函数 `npyv_combineh_s8(A, B)`,将两个 int8x8_t 类型的寄存器 A 和 B 的高位元素组合成一个新的寄存器
    #define npyv_combineh_s8(A, B)  vcombine_s8(vget_high_s8(A), vget_high_s8(B))
    
    # 定义宏函数 `npyv_combineh_u16(A, B)`,将两个 uint16x4_t 类型的寄存器 A 和 B 的高位元素组合成一个新的寄存器
    #define npyv_combineh_u16(A, B) vcombine_u16(vget_high_u16(A), vget_high_u16(B))
    
    # 定义宏函数 `npyv_combineh_s16(A, B)`,将两个 int16x4_t 类型的寄存器 A 和 B 的高位元素组合成一个新的寄存器
    #define npyv_combineh_s16(A, B) vcombine_s16(vget_high_s16(A), vget_high_s16(B))
    
    # 定义宏函数 `npyv_combineh_u32(A, B)`,将两个 uint32x2_t 类型的寄存器 A 和 B 的高位元素组合成一个新的寄存器
    #define npyv_combineh_u32(A, B) vcombine_u32(vget_high_u32(A), vget_high_u32(B))
    
    # 定义宏函数 `npyv_combineh_s32(A, B)`,将两个 int32x2_t 类型的寄存器 A 和 B 的高位元素组合成一个新的寄存器
    #define npyv_combineh_s32(A, B) vcombine_s32(vget_high_s32(A), vget_high_s32(B))
    
    # 定义宏函数 `npyv_combineh_u64(A, B)`,将两个 uint64x1_t 类型的寄存器 A 和 B 的高位元素组合成一个新的寄存器
    #define npyv_combineh_u64(A, B) vcombine_u64(vget_high_u64(A), vget_high_u64(B))
    
    # 定义宏函数 `npyv_combineh_s64(A, B)`,将两个 int64x1_t 类型的寄存器 A 和 B 的高位元素组合成一个新的寄存器
    #define npyv_combineh_s64(A, B) vcombine_s64(vget_high_s64(A), vget_high_s64(B))
    
    # 定义宏函数 `npyv_combineh_f32(A, B)`,将两个 float32x2_t 类型的寄存器 A 和 B 的高位元素组合成一个新的寄存器
    #define npyv_combineh_f32(A, B) vcombine_f32(vget_high_f32(A), vget_high_f32(B))
// 定义宏函数 NPYV_IMPL_NEON_COMBINE,用于将两个给定类型 T_VEC 的向量合并成一个类型为 T_VEC##x2 的结构体
#define NPYV_IMPL_NEON_COMBINE(T_VEC, SFX)                     \
    // 内联函数,将两个类型为 T_VEC 的向量 a 和 b 合并
    NPY_FINLINE T_VEC##x2 npyv_combine_##SFX(T_VEC a, T_VEC b) \
    {                                                          \
        // 创建类型为 T_VEC##x2 的变量 r,其中 val[0] 是通过 npyv_combinel_SFX 函数合并 a 和 b 的结果
        r.val[0] = NPY_CAT(npyv_combinel_, SFX)(a, b);         \
        // val[1] 是通过 npyv_combineh_SFX 函数合并 a 和 b 的结果
        r.val[1] = NPY_CAT(npyv_combineh_, SFX)(a, b);         \
        // 返回合并后的结果结构体 r
        return r;                                              \
    }

// 根据给定类型和后缀 SFX 实例化 NPYV_IMPL_NEON_COMBINE 宏
NPYV_IMPL_NEON_COMBINE(npyv_u8,  u8)
NPYV_IMPL_NEON_COMBINE(npyv_s8,  s8)
NPYV_IMPL_NEON_COMBINE(npyv_u16, u16)
NPYV_IMPL_NEON_COMBINE(npyv_s16, s16)
NPYV_IMPL_NEON_COMBINE(npyv_u32, u32)
NPYV_IMPL_NEON_COMBINE(npyv_s32, s32)
NPYV_IMPL_NEON_COMBINE(npyv_u64, u64)
NPYV_IMPL_NEON_COMBINE(npyv_s64, s64)
NPYV_IMPL_NEON_COMBINE(npyv_f32, f32)

// 根据宏 __aarch64__ 的定义条件编译以下部分代码块
#ifdef __aarch64__
    // 定义宏函数 NPYV_IMPL_NEON_ZIP,用于对给定类型 T_VEC 的向量执行交织(interleave)和解交织(deinterleave)操作
    #define NPYV_IMPL_NEON_ZIP(T_VEC, SFX)                       \
        // 内联函数,将两个类型为 T_VEC 的向量 a 和 b 进行交织操作
        NPY_FINLINE T_VEC##x2 npyv_zip_##SFX(T_VEC a, T_VEC b)   \
        {                                                        \
            // 创建类型为 T_VEC##x2 的变量 r,其中 val[0] 是通过 vzip1q_SFX(a, b) 进行的交织操作
            r.val[0] = vzip1q_##SFX(a, b);                       \
            // val[1] 是通过 vzip2q_SFX(a, b) 进行的交织操作
            r.val[1] = vzip2q_##SFX(a, b);                       \
            // 返回交织后的结果结构体 r
            return r;                                            \
        }                                                        \
        // 内联函数,将两个类型为 T_VEC 的向量 a 和 b 进行解交织操作
        NPY_FINLINE T_VEC##x2 npyv_unzip_##SFX(T_VEC a, T_VEC b) \
        {                                                        \
            // 创建类型为 T_VEC##x2 的变量 r,其中 val[0] 是通过 vuzp1q_SFX(a, b) 进行的解交织操作
            r.val[0] = vuzp1q_##SFX(a, b);                       \
            // val[1] 是通过 vuzp2q_SFX(a, b) 进行的解交织操作
            r.val[1] = vuzp2q_##SFX(a, b);                       \
            // 返回解交织后的结果结构体 r
            return r;                                            \
        }
// 若未定义 __aarch64__ 宏,则编译以下代码块
#else
    // 定义宏函数 NPYV_IMPL_NEON_ZIP,用于对给定类型 T_VEC 的向量执行交织(interleave)和解交织(deinterleave)操作
    #define NPYV_IMPL_NEON_ZIP(T_VEC, SFX)                       \
        // 内联函数,将两个类型为 T_VEC 的向量 a 和 b 进行交织操作
        NPY_FINLINE T_VEC##x2 npyv_zip_##SFX(T_VEC a, T_VEC b)   \
        { return vzipq_##SFX(a, b); }                            \
        // 内联函数,将两个类型为 T_VEC 的向量 a 和 b 进行解交织操作
        NPY_FINLINE T_VEC##x2 npyv_unzip_##SFX(T_VEC a, T_VEC b) \
        { return vuzpq_##SFX(a, b); }
#endif

// 根据给定类型和后缀 SFX 实例化 NPYV_IMPL_NEON_ZIP 宏
NPYV_IMPL_NEON_ZIP(npyv_u8,  u8)
NPYV_IMPL_NEON_ZIP(npyv_s8,  s8)
NPYV_IMPL_NEON_ZIP(npyv_u16, u16)
NPYV_IMPL_NEON_ZIP(npyv_s16, s16)
NPYV_IMPL_NEON_ZIP(npyv_u32, u32)
NPYV_IMPL_NEON_ZIP(npyv_s32, s32)
NPYV_IMPL_NEON_ZIP(npyv_f32, f32)

// 定义一系列宏函数,将不同类型的向量直接映射到其对应的合并和解交织函数
#define npyv_zip_u64 npyv_combine_u64
#define npyv_zip_s64 npyv_combine_s64
#define npyv_zip_f64 npyv_combine_f64
#define npyv_unzip_u64 npyv_combine_u64
#define npyv_unzip_s64 npyv_combine_s64
#define npyv_unzip_f64 npyv_combine_f64

// 定义一系列宏函数,用于反转每个 64 位通道中的元素顺序
#define npyv_rev64_u8  vrev64q_u8
#define npyv_rev64_s8  vrev64q_s8
#define npyv_rev64_u16 vrev64q_u16
#define npyv_rev64_s16 vrev64q_s16
#define npyv_rev64_u32 vrev64q_u32
#define npyv_rev64_s32 vrev64q_s32
#define npyv_rev64_f32 vrev64q_f32
// 定义宏 npyv_rev64_f32 用于反转 NEON 寄存器中 64 位浮点数元素的顺序

// 根据不同的编译器预处理指令,定义宏 npyv_permi128_u32,用于对 NEON 寄存器中的 128 位整数型数据进行按指定索引重新排列
#ifdef __clang__
    #define npyv_permi128_u32(A, E0, E1, E2, E3) \
        __builtin_shufflevector(A, A, E0, E1, E2, E3)
// 对于 Clang 编译器,使用 __builtin_shufflevector 进行元素重新排列
#elif defined(__GNUC__)
    #define npyv_permi128_u32(A, E0, E1, E2, E3) \
        __builtin_shuffle(A, npyv_set_u32(E0, E1, E2, E3))
// 对于 GCC 编译器,使用 __builtin_shuffle 结合 npyv_set_u32 宏进行元素重新排列
#else
    #define npyv_permi128_u32(A, E0, E1, E2, E3)          \
        npyv_set_u32(                                     \
            vgetq_lane_u32(A, E0), vgetq_lane_u32(A, E1), \
            vgetq_lane_u32(A, E2), vgetq_lane_u32(A, E3)  \
        )
// 对于其他编译器,使用 vgetq_lane_u32 获取指定索引处的 32 位整数,并通过 npyv_set_u32 宏进行元素重新排列
    #define npyv_permi128_s32(A, E0, E1, E2, E3)          \
        npyv_set_s32(                                     \
            vgetq_lane_s32(A, E0), vgetq_lane_s32(A, E1), \
            vgetq_lane_s32(A, E2), vgetq_lane_s32(A, E3)  \
        )
    #define npyv_permi128_f32(A, E0, E1, E2, E3)          \
        npyv_set_f32(                                     \
            vgetq_lane_f32(A, E0), vgetq_lane_f32(A, E1), \
            vgetq_lane_f32(A, E2), vgetq_lane_f32(A, E3)  \
        )
#endif

#if defined(__clang__) || defined(__GNUC__)
    // 对于 Clang 和 GCC 编译器,定义整数和浮点数的 128 位元素重排宏
    #define npyv_permi128_s32 npyv_permi128_u32
    #define npyv_permi128_f32 npyv_permi128_u32
#endif

// 根据不同的编译器预处理指令,定义宏 npyv_permi128_u64,用于对 NEON 寄存器中的 128 位无符号长整型数据进行按指定索引重新排列
#ifdef __clang__
    #define npyv_permi128_u64(A, E0, E1) \
        __builtin_shufflevector(A, A, E0, E1)
// 对于 Clang 编译器,使用 __builtin_shufflevector 进行元素重新排列
#elif defined(__GNUC__)
    #define npyv_permi128_u64(A, E0, E1) \
        __builtin_shuffle(A, npyv_set_u64(E0, E1))
// 对于 GCC 编译器,使用 __builtin_shuffle 结合 npyv_set_u64 宏进行元素重新排列
#else
    #define npyv_permi128_u64(A, E0, E1)                  \
        npyv_set_u64(                                     \
            vgetq_lane_u64(A, E0), vgetq_lane_u64(A, E1)  \
        )
    #define npyv_permi128_s64(A, E0, E1)                  \
        npyv_set_s64(                                     \
            vgetq_lane_s64(A, E0), vgetq_lane_s64(A, E1)  \
        )
    #define npyv_permi128_f64(A, E0, E1)                  \
        npyv_set_f64(                                     \
            vgetq_lane_f64(A, E0), vgetq_lane_f64(A, E1)  \
        )
#endif

#if defined(__clang__) || defined(__GNUC__)
    // 对于 Clang 和 GCC 编译器,定义整数和浮点数的 128 位元素重排宏
    #define npyv_permi128_s64 npyv_permi128_u64
    #define npyv_permi128_f64 npyv_permi128_u64
#endif

#if !NPY_SIMD_F64
    // 如果不支持双精度浮点数 SIMD 操作,则取消定义 npyv_permi128_f64 宏
    #undef npyv_permi128_f64
#endif

#endif // _NPY_SIMD_NEON_REORDER_H
// 结束 _NPY_SIMD_NEON_REORDER_H 文件的条件编译

.\numpy\numpy\_core\src\common\simd\simd.h

#ifndef _NPY_SIMD_H_
#define _NPY_SIMD_H_
/**
 * the NumPy C SIMD vectorization interface "NPYV" are types and functions intended
 * to simplify vectorization of code on different platforms, currently supports
 * the following SIMD extensions SSE, AVX2, AVX512, VSX and NEON.
 *
 * TODO: Add an independent sphinx doc.
*/

#include "numpy/npy_common.h"
#ifndef __cplusplus
    #include <stdbool.h>
#endif

#include "npy_cpu_dispatch.h"
#include "simd_utils.h"

#ifdef __cplusplus
extern "C" {
#endif
/*
 * clang commit an aggressive optimization behaviour when flag `-ftrapping-math`
 * isn't fully supported that's present at -O1 or greater. When partially loading a
 * vector register for a operations that requires to fill up the remaining lanes
 * with certain value for example divide operation needs to fill the remaining value
 * with non-zero integer to avoid fp exception divide-by-zero.
 * clang optimizer notices that the entire register is not needed for the store
 * and optimizes out the fill of non-zero integer to the remaining
 * elements. As workaround we mark the returned register with `volatile`
 * followed by symmetric operand operation e.g. `or`
 * to convince the compiler that the entire vector is needed.
 */
#if defined(__clang__) && !defined(NPY_HAVE_CLANG_FPSTRICT)
    #define NPY_SIMD_GUARD_PARTIAL_LOAD 1
#else
    #define NPY_SIMD_GUARD_PARTIAL_LOAD 0
#endif

#if defined(_MSC_VER) && defined(_M_IX86)
/*
 * Avoid using any of the following intrinsics with MSVC 32-bit,
 * even if they are apparently work on newer versions.
 * They had bad impact on the generated instructions,
 * sometimes the compiler deal with them without the respect
 * of 32-bit mode which lead to crush due to execute 64-bit
 * instructions and other times generate bad emulated instructions.
 */
    #undef _mm512_set1_epi64
    #undef _mm256_set1_epi64x
    #undef _mm_set1_epi64x
    #undef _mm512_setr_epi64x
    #undef _mm256_setr_epi64x
    #undef _mm_setr_epi64x
    #undef _mm512_set_epi64x
    #undef _mm256_set_epi64x
    #undef _mm_set_epi64x
#endif

// lane type by intrin suffix
typedef npy_uint8  npyv_lanetype_u8;    // 定义无符号 8 位整数的 SIMD 向量元素类型
typedef npy_int8   npyv_lanetype_s8;    // 定义有符号 8 位整数的 SIMD 向量元素类型
typedef npy_uint16 npyv_lanetype_u16;   // 定义无符号 16 位整数的 SIMD 向量元素类型
typedef npy_int16  npyv_lanetype_s16;   // 定义有符号 16 位整数的 SIMD 向量元素类型
typedef npy_uint32 npyv_lanetype_u32;   // 定义无符号 32 位整数的 SIMD 向量元素类型
typedef npy_int32  npyv_lanetype_s32;   // 定义有符号 32 位整数的 SIMD 向量元素类型
typedef npy_uint64 npyv_lanetype_u64;   // 定义无符号 64 位整数的 SIMD 向量元素类型
typedef npy_int64  npyv_lanetype_s64;   // 定义有符号 64 位整数的 SIMD 向量元素类型
typedef float      npyv_lanetype_f32;   // 定义单精度浮点数的 SIMD 向量元素类型
typedef double     npyv_lanetype_f64;   // 定义双精度浮点数的 SIMD 向量元素类型

#if defined(NPY_HAVE_AVX512F) && !defined(NPY_SIMD_FORCE_256) && !defined(NPY_SIMD_FORCE_128)
    #include "avx512/avx512.h"
#elif defined(NPY_HAVE_AVX2) && !defined(NPY_SIMD_FORCE_128)
    #include "avx2/avx2.h"
#elif defined(NPY_HAVE_SSE2)
    #include "sse/sse.h"
#endif

// TODO: Add support for VSX(2.06) and BE Mode for VSX
#if defined(NPY_HAVE_VX) || (defined(NPY_HAVE_VSX2) && defined(__LITTLE_ENDIAN__))
    #include "vec/vec.h"
#endif

#ifdef NPY_HAVE_NEON
    #include "neon/neon.h"
#endif

#ifndef NPY_SIMD
    /// 定义:如果没有可用的SIMD扩展,NPY_SIMD为0,否则为SIMD的位宽(以比特为单位)。
    #define NPY_SIMD 0
    /// 定义:如果没有可用的SIMD扩展,NPY_SIMD_WIDTH为0,否则为SIMD的位宽(以字节为单位)。
    #define NPY_SIMD_WIDTH 0
    /// 定义:如果启用的SIMD扩展支持单精度浮点数,则为1,否则为0#define NPY_SIMD_F32 0
    /// 定义:如果启用的SIMD扩展支持双精度浮点数,则为1,否则为0#define NPY_SIMD_F64 0
    /// 定义:如果启用的SIMD扩展支持本地FMA(Fused Multiply-Add)操作,则为1,否则为0。
    /// 注意:即使不支持FMA指令集,仍然会模拟(快速)FMA操作,但在精度要求高时不应使用。
    #define NPY_SIMD_FMA3 0
    /// 定义:如果启用的SIMD扩展在大端模式下运行,则为1,否则为0#define NPY_SIMD_BIGENDIAN 0
    /// 定义:如果支持的比较指令集(lt, le, gt, ge)在处理静默NaN时引发浮点无效异常,则为1,否则为0#define NPY_SIMD_CMPSIGNAL 0
#ifndef _NPY_SIMD_H_

// 如果 _NPY_SIMD_H_ 未定义,则执行以下代码,防止头文件重复包含


#endif

// 结束条件,确保头文件在多次包含时不会被重复定义


#if !defined(NPY_HAVE_AVX512F) && NPY_SIMD && NPY_SIMD < 512
    #include "emulate_maskop.h"
#endif

// 如果未定义 NPY_HAVE_AVX512F 并且 NPY_SIMD 为真且小于 512,则包含 emulate_maskop.h 头文件


#if NPY_SIMD
    #include "intdiv.h"
#endif

// 如果 NPY_SIMD 为真,则包含 intdiv.h 头文件


/**
 * Some SIMD extensions currently(AVX2, AVX512F) require (de facto)
 * a maximum number of strides sizes when dealing with non-contiguous memory access.
 *
 * Therefore the following functions must be used to check the maximum
 * acceptable limit of strides before using any of non-contiguous load/store intrinsics.
 *
 * For instance:
 *  npy_intp ld_stride = step[0] / sizeof(float);
 *  npy_intp st_stride = step[1] / sizeof(float);
 *
 *  if (npyv_loadable_stride_f32(ld_stride) && npyv_storable_stride_f32(st_stride)) {
 *      for (;;)
 *          npyv_f32 a = npyv_loadn_f32(ld_pointer, ld_stride);
 *          // ...
 *          npyv_storen_f32(st_pointer, st_stride, a);
 *  }
 *  else {
 *      for (;;)
 *          // C scalars
 *  }
 */

// 以下是一段注释,描述了一些 SIMD 扩展(如 AVX2, AVX512F)在处理非连续内存访问时的最大步长限制,以及使用非连续加载/存储指令前必须使用的函数。


#ifndef NPY_SIMD_MAXLOAD_STRIDE32
    #define NPY_SIMD_MAXLOAD_STRIDE32 0
#endif
#ifndef NPY_SIMD_MAXSTORE_STRIDE32
    #define NPY_SIMD_MAXSTORE_STRIDE32 0
#endif
#ifndef NPY_SIMD_MAXLOAD_STRIDE64
    #define NPY_SIMD_MAXLOAD_STRIDE64 0
#endif
#ifndef NPY_SIMD_MAXSTORE_STRIDE64
    #define NPY_SIMD_MAXSTORE_STRIDE64 0
#endif

// 如果未定义这些宏,则定义它们并初始化为 0,用于限制 SIMD 加载和存储的最大步长


#define NPYV_IMPL_MAXSTRIDE(SFX, MAXLOAD, MAXSTORE) \
    NPY_FINLINE int npyv_loadable_stride_##SFX(npy_intp stride) \
    { return MAXLOAD > 0 ? llabs(stride) <= MAXLOAD : 1; } \
    NPY_FINLINE int npyv_storable_stride_##SFX(npy_intp stride) \
    { return MAXSTORE > 0 ? llabs(stride) <= MAXSTORE : 1; }

// 定义一个宏,生成两个内联函数,用于检查给定步长是否在指定的最大加载或存储步长范围内


#if NPY_SIMD
    NPYV_IMPL_MAXSTRIDE(u32, NPY_SIMD_MAXLOAD_STRIDE32, NPY_SIMD_MAXSTORE_STRIDE32)
    NPYV_IMPL_MAXSTRIDE(s32, NPY_SIMD_MAXLOAD_STRIDE32, NPY_SIMD_MAXSTORE_STRIDE32)
    NPYV_IMPL_MAXSTRIDE(f32, NPY_SIMD_MAXLOAD_STRIDE32, NPY_SIMD_MAXSTORE_STRIDE32)
    NPYV_IMPL_MAXSTRIDE(u64, NPY_SIMD_MAXLOAD_STRIDE64, NPY_SIMD_MAXSTORE_STRIDE64)
    NPYV_IMPL_MAXSTRIDE(s64, NPY_SIMD_MAXLOAD_STRIDE64, NPY_SIMD_MAXSTORE_STRIDE64)
#endif

// 如果 NPY_SIMD 为真,则实例化各种数据类型(u32, s32, f32, u64, s64)的加载和存储步长检查函数


#if NPY_SIMD_F64
    NPYV_IMPL_MAXSTRIDE(f64, NPY_SIMD_MAXLOAD_STRIDE64, NPY_SIMD_MAXSTORE_STRIDE64)
#endif

// 如果支持双精度 SIMD(NPY_SIMD_F64 为真),则实例化 f64 类型的加载和存储步长检查函数


#ifdef __cplusplus
}
#endif
#endif // _NPY_SIMD_H_

// 如果是 C++ 环境,则关闭外部 C 链接,并结束头文件保护符 `#ifndef _NPY_SIMD_H_`

.\numpy\numpy\_core\src\common\simd\simd_utils.h

#ifndef _NPY_SIMD_UTILS_H
#define _NPY_SIMD_UTILS_H

// 定义用于创建长度为2的向量的宏,CAST是类型转换宏,I0和I1是初始值,__VA_ARGS__是可变参数列表
#define NPYV__SET_2(CAST, I0, I1, ...) (CAST)(I0), (CAST)(I1)

// 定义用于创建长度为4的向量的宏,CAST是类型转换宏,I0到I3是初始值,__VA_ARGS__是可变参数列表
#define NPYV__SET_4(CAST, I0, I1, I2, I3, ...) \
    (CAST)(I0), (CAST)(I1), (CAST)(I2), (CAST)(I3)

// 定义用于创建长度为8的向量的宏,CAST是类型转换宏,I0到I7是初始值,__VA_ARGS__是可变参数列表
#define NPYV__SET_8(CAST, I0, I1, I2, I3, I4, I5, I6, I7, ...) \
    (CAST)(I0), (CAST)(I1), (CAST)(I2), (CAST)(I3), (CAST)(I4), (CAST)(I5), (CAST)(I6), (CAST)(I7)

// 定义用于创建长度为16的向量的宏,CAST是类型转换宏,I0到I15是初始值,__VA_ARGS__是可变参数列表
#define NPYV__SET_16(CAST, I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, ...) \
    NPYV__SET_8(CAST, I0, I1, I2, I3, I4, I5, I6, I7), \
    NPYV__SET_8(CAST, I8, I9, I10, I11, I12, I13, I14, I15)

// 定义用于创建长度为32的向量的宏,CAST是类型转换宏,I0到I31是初始值,__VA_ARGS__是可变参数列表
#define NPYV__SET_32(CAST, I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, \
    I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31, ...) \
    \
    NPYV__SET_16(CAST, I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15), \
    NPYV__SET_16(CAST, I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31)

// 定义用于创建长度为64的向量的宏,CAST是类型转换宏,I0到I63是初始值,__VA_ARGS__是可变参数列表
#define NPYV__SET_64(CAST, I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, \
    I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31, \
    I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47, \
    I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63, ...) \
    \
    NPYV__SET_32(CAST, I0, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, \
    I16, I17, I18, I19, I20, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31), \
    NPYV__SET_32(CAST, I32, I33, I34, I35, I36, I37, I38, I39, I40, I41, I42, I43, I44, I45, I46, I47, \
    I48, I49, I50, I51, I52, I53, I54, I55, I56, I57, I58, I59, I60, I61, I62, I63)

// 定义用于创建长度为2的向量的宏,CAST是类型转换宏,F是填充值,__VA_ARGS__是可变参数列表
#define NPYV__SET_FILL_2(CAST, F, ...) NPY_EXPAND(NPYV__SET_2(CAST, __VA_ARGS__, F, F))

// 定义用于创建长度为4的向量的宏,CAST是类型转换宏,F是填充值,__VA_ARGS__是可变参数列表
#define NPYV__SET_FILL_4(CAST, F, ...) NPY_EXPAND(NPYV__SET_4(CAST, __VA_ARGS__, F, F, F, F))

// 定义用于创建长度为8的向量的宏,CAST是类型转换宏,F是填充值,__VA_ARGS__是可变参数列表
#define NPYV__SET_FILL_8(CAST, F, ...) NPY_EXPAND(NPYV__SET_8(CAST, __VA_ARGS__, F, F, F, F, F, F, F, F))

// 定义用于创建长度为16的向量的宏,CAST是类型转换宏,F是填充值,__VA_ARGS__是可变参数列表
#define NPYV__SET_FILL_16(CAST, F, ...) NPY_EXPAND(NPYV__SET_16(CAST, __VA_ARGS__, \
    F, F, F, F, F, F, F, F, F, F, F, F, F, F, F))

// 定义用于创建长度为32的向量的宏,CAST是类型转换宏,F是填充值,__VA_ARGS__是可变参数列表
#define NPYV__SET_FILL_32(CAST, F, ...) NPY_EXPAND(NPYV__SET_32(CAST, __VA_ARGS__, \
    F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F))

// 定义用于创建长度为64的向量的宏,CAST是类型转换宏,F是填充值,__VA_ARGS__是可变参数列表
#define NPYV__SET_FILL_64(CAST, F, ...) NPY_EXPAND(NPYV__SET_64(CAST, __VA_ARGS__, \
    F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, \
    F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F, F))

#endif // _NPY_SIMD_UTILS_H

.\numpy\numpy\_core\src\common\simd\sse\arithmetic.h

#ifndef NPY_SIMD
    #error "Not a standalone header"
#endif

#ifndef _NPY_SIMD_SSE_ARITHMETIC_H
#define _NPY_SIMD_SSE_ARITHMETIC_H

/***************************
 * Addition
 ***************************/
// 非饱和加法
#define npyv_add_u8  _mm_add_epi8
#define npyv_add_s8  _mm_add_epi8
#define npyv_add_u16 _mm_add_epi16
#define npyv_add_s16 _mm_add_epi16
#define npyv_add_u32 _mm_add_epi32
#define npyv_add_s32 _mm_add_epi32
#define npyv_add_u64 _mm_add_epi64
#define npyv_add_s64 _mm_add_epi64
#define npyv_add_f32 _mm_add_ps
#define npyv_add_f64 _mm_add_pd

// 饱和加法
#define npyv_adds_u8  _mm_adds_epu8
#define npyv_adds_s8  _mm_adds_epi8
#define npyv_adds_u16 _mm_adds_epu16
#define npyv_adds_s16 _mm_adds_epi16
// TODO: 实现 Packs intrins 后继续添加

/***************************
 * Subtraction
 ***************************/
// 非饱和减法
#define npyv_sub_u8  _mm_sub_epi8
#define npyv_sub_s8  _mm_sub_epi8
#define npyv_sub_u16 _mm_sub_epi16
#define npyv_sub_s16 _mm_sub_epi16
#define npyv_sub_u32 _mm_sub_epi32
#define npyv_sub_s32 _mm_sub_epi32
#define npyv_sub_u64 _mm_sub_epi64
#define npyv_sub_s64 _mm_sub_epi64
#define npyv_sub_f32 _mm_sub_ps
#define npyv_sub_f64 _mm_sub_pd

// 饱和减法
#define npyv_subs_u8  _mm_subs_epu8
#define npyv_subs_s8  _mm_subs_epi8
#define npyv_subs_u16 _mm_subs_epu16
#define npyv_subs_s16 _mm_subs_epi16
// TODO: 实现 Packs intrins 后继续添加

/***************************
 * Multiplication
 ***************************/
// 非饱和乘法(8位无符号整数特化)
NPY_FINLINE __m128i npyv_mul_u8(__m128i a, __m128i b)
{
    // 构造掩码,用于选择乘法结果的偶数位置字节
    const __m128i mask = _mm_set1_epi32(0xFF00FF00);
    // 偶数位置乘法结果
    __m128i even = _mm_mullo_epi16(a, b);
    // 奇数位置乘法结果
    __m128i odd  = _mm_mullo_epi16(_mm_srai_epi16(a, 8), _mm_srai_epi16(b, 8));
            odd  = _mm_slli_epi16(odd, 8);
    // 选择最终结果
    return npyv_select_u8(mask, odd, even);
}
#define npyv_mul_s8  npyv_mul_u8
#define npyv_mul_u16 _mm_mullo_epi16
#define npyv_mul_s16 _mm_mullo_epi16

#ifdef NPY_HAVE_SSE41
    #define npyv_mul_u32 _mm_mullo_epi32
#else
    // 32位无符号整数乘法(未实现 SSE4.1 的情况下)
    NPY_FINLINE __m128i npyv_mul_u32(__m128i a, __m128i b)
    {
        // 偶数位置乘法结果
        __m128i even = _mm_mul_epu32(a, b);
        // 奇数位置乘法结果
        __m128i odd  = _mm_mul_epu32(_mm_srli_epi64(a, 32), _mm_srli_epi64(b, 32));
        // 合并低32位和高32位结果
        __m128i low  = _mm_unpacklo_epi32(even, odd);
        __m128i high = _mm_unpackhi_epi32(even, odd);
        return _mm_unpacklo_epi64(low, high);
    }
#endif // NPY_HAVE_SSE41
#define npyv_mul_s32 npyv_mul_u32
// TODO: 模拟64位整数乘法

#define npyv_mul_f32 _mm_mul_ps
#define npyv_mul_f64 _mm_mul_pd

// 饱和乘法
// TODO: 实现 Packs intrins 后继续添加

/***************************
 * Integer Division
 ***************************/
// 参见 simd/intdiv.h 以获取更多说明
// 将每个无符号8位元素除以预计算的除数
NPY_FINLINE npyv_u8 npyv_divc_u8(npyv_u8 a, const npyv_u8x3 divisor)
{
    // 构造掩码,用于选择除法结果的低位字节
    const __m128i bmask = _mm_set1_epi32(0x00FF00FF);
    // 根据除数的第二个元素设置移位量
    const __m128i shf1b = _mm_set1_epi8(0xFFU >> _mm_cvtsi128_si32(divisor.val[1]));
    // 设置 shf2b 为一个包含 divisor.val[2] 的低 8 位的掩码
    const __m128i shf2b = _mm_set1_epi8(0xFFU >> _mm_cvtsi128_si32(divisor.val[2]));

    // 计算偶数位置的高位乘积:a 与 bmask 按位与,再与 divisor.val[0] 相乘
    __m128i mulhi_even  = _mm_mullo_epi16(_mm_and_si128(a, bmask), divisor.val[0]);

    // 计算奇数位置的高位乘积:a 右移 8 位,再与 divisor.val[0] 相乘
    __m128i mulhi_odd   = _mm_mullo_epi16(_mm_srli_epi16(a, 8), divisor.val[0]);

    // 将偶数和奇数位置的高位乘积结果右移 8 位
    mulhi_even  = _mm_srli_epi16(mulhi_even, 8);

    // 使用 bmask 选择偶数位置或奇数位置的高位乘积结果
    __m128i mulhi       = npyv_select_u8(bmask, mulhi_even, mulhi_odd);

    // 计算 floor(a/d) = (mulhi + ((a - mulhi) >> sh1)) >> sh2
    __m128i q           = _mm_sub_epi8(a, mulhi);  // a - mulhi
    q           = _mm_and_si128(_mm_srl_epi16(q, divisor.val[1]), shf1b);  // (a - mulhi) >> sh1
    q           = _mm_add_epi8(mulhi, q);  // mulhi + ((a - mulhi) >> sh1)
    q           = _mm_and_si128(_mm_srl_epi16(q, divisor.val[2]), shf2b);  // ((mulhi + ((a - mulhi) >> sh1)) >> sh2)

    // 返回计算结果 q
    return q;
// 结束 numpPy 内联函数 npyv_divc_s8,将每个有符号 8 位元素除以预先计算的除数(向零舍入)
NPY_FINLINE npyv_s8 npyv_divc_s8(npyv_s8 a, const npyv_s8x3 divisor)
{
    // 创建一个掩码,用于选择每个 8 位元素的低位部分
    const __m128i bmask = _mm_set1_epi32(0x00FF00FF);
    // 使用 npyv_divc_s16 函数分别计算偶数和奇数位元素的除法
    __m128i divc_even = npyv_divc_s16(_mm_srai_epi16(_mm_slli_epi16(a, 8), 8), divisor);
    __m128i divc_odd  = npyv_divc_s16(_mm_srai_epi16(a, 8), divisor);
    // 将奇数位元素左移 8 位,再与偶数位元素结合,形成结果
    divc_odd  = _mm_slli_epi16(divc_odd, 8);
    return npyv_select_u8(bmask, divc_even, divc_odd);
}

// 按照预先计算的除数,将每个无符号 16 位元素进行除法
NPY_FINLINE npyv_u16 npyv_divc_u16(npyv_u16 a, const npyv_u16x3 divisor)
{
    // 使用无符号乘法的高位部分
    __m128i mulhi = _mm_mulhi_epu16(a, divisor.val[0]);
    // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
    __m128i q     = _mm_sub_epi16(a, mulhi);
            q     = _mm_srl_epi16(q, divisor.val[1]);
            q     = _mm_add_epi16(mulhi, q);
            q     = _mm_srl_epi16(q, divisor.val[2]);
    return  q;
}

// 按照预先计算的除数,将每个有符号 16 位元素进行除法(向零舍入)
NPY_FINLINE npyv_s16 npyv_divc_s16(npyv_s16 a, const npyv_s16x3 divisor)
{
    // 使用有符号乘法的高位部分
    __m128i mulhi = _mm_mulhi_epi16(a, divisor.val[0]);
    // q = ((a + mulhi) >> sh1) - XSIGN(a)
    // trunc(a/d) = (q ^ dsign) - dsign
    __m128i q     = _mm_sra_epi16(_mm_add_epi16(a, mulhi), divisor.val[1]);
            q     = _mm_sub_epi16(q, _mm_srai_epi16(a, 15));
            q     = _mm_sub_epi16(_mm_xor_si128(q, divisor.val[2]), divisor.val[2]);
    return  q;
}

// 按照预先计算的除数,将每个无符号 32 位元素进行除法
NPY_FINLINE npyv_u32 npyv_divc_u32(npyv_u32 a, const npyv_u32x3 divisor)
{
    // 使用无符号乘法的高位部分,分别计算偶数和奇数位元素的乘积
    __m128i mulhi_even = _mm_srli_epi64(_mm_mul_epu32(a, divisor.val[0]), 32);
    __m128i mulhi_odd  = _mm_mul_epu32(_mm_srli_epi64(a, 32), divisor.val[0]);
#ifdef NPY_HAVE_SSE41
    // 使用 SSE4.1 提供的指令混合偶数和奇数位元素的乘积
    __m128i mulhi      = _mm_blend_epi16(mulhi_even, mulhi_odd, 0xCC);
#else
    // 使用非 SSE4.1 的方式混合偶数和奇数位元素的乘积
    __m128i mask_13    = _mm_setr_epi32(0, -1, 0, -1);
           mulhi_odd   = _mm_and_si128(mulhi_odd, mask_13);
    __m128i mulhi      = _mm_or_si128(mulhi_even, mulhi_odd);
#endif
    // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
    __m128i q          = _mm_sub_epi32(a, mulhi);
            q          = _mm_srl_epi32(q, divisor.val[1]);
            q          = _mm_add_epi32(mulhi, q);
            q          = _mm_srl_epi32(q, divisor.val[2]);
    return  q;
}

// 按照预先计算的除数,将每个有符号 32 位元素进行除法(向零舍入)
NPY_FINLINE npyv_s32 npyv_divc_s32(npyv_s32 a, const npyv_s32x3 divisor)
{
    // 取每个有符号 32 位元素的符号
    __m128i asign      = _mm_srai_epi32(a, 31);
#ifdef NPY_HAVE_SSE41
    // 使用 SSE4.1 提供的指令,计算有符号乘法的高位部分
    __m128i mulhi_even = _mm_srli_epi64(_mm_mul_epi32(a, divisor.val[0]), 32);
    # 使用 SSE2 指令集中的 `_mm_srli_epi64` 对寄存器 `a` 进行 64 位向右移位操作,然后使用 `_mm_mul_epi32` 计算结果与寄存器 `divisor.val[0]` 的乘积。
    __m128i mulhi_odd  = _mm_mul_epi32(_mm_srli_epi64(a, 32), divisor.val[0]);
    
    # 使用 SSE2 指令集中的 `_mm_blend_epi16` 将 `mulhi_even` 和 `mulhi_odd` 的结果根据掩码 `0xCC` 进行混合,生成 `mulhi` 寄存器。
    __m128i mulhi      = _mm_blend_epi16(mulhi_even, mulhi_odd, 0xCC);
#else  // not SSE4.1
    // 如果不支持 SSE4.1,执行以下代码段

    // 计算无符号乘法的高位部分
    __m128i mulhi_even = _mm_srli_epi64(_mm_mul_epu32(a, divisor.val[0]), 32);
    // 计算偶数索引位置的乘法高位
    __m128i mulhi_odd  = _mm_mul_epu32(_mm_srli_epi64(a, 32), divisor.val[0]);
    // 创建掩码以选择奇数索引位置的乘法高位结果
    __m128i mask_13    = _mm_setr_epi32(0, -1, 0, -1);
            mulhi_odd  = _mm_and_si128(mulhi_odd, mask_13);
    // 合并偶数和奇数索引位置的乘法高位结果
    __m128i mulhi      = _mm_or_si128(mulhi_even, mulhi_odd);
    // 将无符号乘法结果转换为带符号的高位乘法
    // mulhi - ((a < 0) ? m : 0) - ((m < 0) ? a : 0);
    const __m128i msign= _mm_srai_epi32(divisor.val[0], 31);
    // 对 msign 和 a 进行按位与操作
    __m128i m_asign    = _mm_and_si128(divisor.val[0], asign);
    __m128i a_msign    = _mm_and_si128(a, msign);
            mulhi      = _mm_sub_epi32(mulhi, m_asign);
            mulhi      = _mm_sub_epi32(mulhi, a_msign);
#endif
    // 计算商 q = ((a + mulhi) >> sh1) - XSIGN(a)
    __m128i q          = _mm_sra_epi32(_mm_add_epi32(a, mulhi), divisor.val[1]);
            q          = _mm_sub_epi32(q, asign);
            q          = _mm_sub_epi32(_mm_xor_si128(q, divisor.val[2]), divisor.val[2]);
    return  q;
}
// 返回无符号 64 位乘法的高 64 位结果
// 参考:https://stackoverflow.com/a/28827013
NPY_FINLINE npyv_u64 npyv__mullhi_u64(npyv_u64 a, npyv_u64 b)
{
    __m128i lomask = npyv_setall_s64(0xffffffff);
    // 将 a 向右移动 32 位,得到高位部分
    __m128i a_hi   = _mm_srli_epi64(a, 32);        // a0l, a0h, a1l, a1h
    // 将 b 向右移动 32 位,得到高位部分
    __m128i b_hi   = _mm_srli_epi64(b, 32);        // b0l, b0h, b1l, b1h
    // 计算部分乘积
    __m128i w0     = _mm_mul_epu32(a, b);          // a0l*b0l, a1l*b1l
    __m128i w1     = _mm_mul_epu32(a, b_hi);       // a0l*b0h, a1l*b1h
    __m128i w2     = _mm_mul_epu32(a_hi, b);       // a0h*b0l, a1h*b0l
    __m128i w3     = _mm_mul_epu32(a_hi, b_hi);    // a0h*b0h, a1h*b1h
    // 求和部分乘积
    __m128i w0h    = _mm_srli_epi64(w0, 32);
    __m128i s1     = _mm_add_epi64(w1, w0h);
    __m128i s1l    = _mm_and_si128(s1, lomask);
    __m128i s1h    = _mm_srli_epi64(s1, 32);

    __m128i s2     = _mm_add_epi64(w2, s1l);
    __m128i s2h    = _mm_srli_epi64(s2, 32);

    __m128i hi     = _mm_add_epi64(w3, s1h);
            hi     = _mm_add_epi64(hi, s2h);
    return hi;
}
// 每个无符号 64 位元素除以预先计算的除数
NPY_FINLINE npyv_u64 npyv_divc_u64(npyv_u64 a, const npyv_u64x3 divisor)
{
    // 计算无符号乘法的高位部分
    __m128i mulhi = npyv__mullhi_u64(a, divisor.val[0]);
    // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
    __m128i q     = _mm_sub_epi64(a, mulhi);
            q     = _mm_srl_epi64(q, divisor.val[1]);
            q     = _mm_add_epi64(mulhi, q);
            q     = _mm_srl_epi64(q, divisor.val[2]);
    return  q;
}
// 每个有符号 64 位元素除以预先计算的除数(向零舍入)
NPY_FINLINE npyv_s64 npyv_divc_s64(npyv_s64 a, const npyv_s64x3 divisor)
{
    // 计算无符号乘法的高位部分
    __m128i mulhi      = npyv__mullhi_u64(a, divisor.val[0]);
    // 使用函数 npyv__mullhi_u64 对 a 和 divisor.val[0] 进行无符号64位乘法,并将结果存储在 mulhi 中
    // 这一步计算得到的是 a 与 divisor.val[0] 的乘积的高64位部分
    
    // convert unsigned to signed high multiplication
    // 将无符号乘法转换为有符号乘法的高位运算
    
    // mulhi - ((a < 0) ? m : 0) - ((m < 0) ? a : 0);
    // 如果 a 小于 0,则将 m 加到 mulhi 上;如果 m 小于 0,则将 a 加到 mulhi 上。
    // 这段代码可能用于在无符号乘法的基础上进行有符号调整,确保乘法结果在有符号整数环境下的正确性。
#ifdef NPY_HAVE_SSE42
    // 如果支持 SSE4.2,则使用比较运算寄存器来设置除数的符号位
    const __m128i msign= _mm_cmpgt_epi64(_mm_setzero_si128(), divisor.val[0]);
    // 使用比较运算寄存器来设置被除数 a 的符号位
    __m128i asign      = _mm_cmpgt_epi64(_mm_setzero_si128(), a);
#else
    // 如果不支持 SSE4.2,则通过移位和 shuffle 操作设置除数的符号位
    const __m128i msign= _mm_srai_epi32(_mm_shuffle_epi32(divisor.val[0], _MM_SHUFFLE(3, 3, 1, 1)), 31);
    // 通过移位和 shuffle 操作设置被除数 a 的符号位
    __m128i asign      = _mm_srai_epi32(_mm_shuffle_epi32(a, _MM_SHUFFLE(3, 3, 1, 1)), 31);
#endif
    // 计算除数和被除数符号位的按位与结果
    __m128i m_asign    = _mm_and_si128(divisor.val[0], asign);
    // 计算被除数和除数符号位的按位与结果
    __m128i a_msign    = _mm_and_si128(a, msign);
    // 对 mulhi 执行符号位修正
    mulhi              = _mm_sub_epi64(mulhi, m_asign);
    mulhi              = _mm_sub_epi64(mulhi, a_msign);
    // 计算商 q,即 (a + mulhi) >> sh,其中 sh 是移位参数
    __m128i q          = _mm_add_epi64(a, mulhi);
    // 模拟算术右移操作
    const __m128i sigb = npyv_setall_s64(1LL << 63);
    q                  = _mm_srl_epi64(_mm_add_epi64(q, sigb), divisor.val[1]);
    q                  = _mm_sub_epi64(q, _mm_srl_epi64(sigb, divisor.val[1]));
    // 修正商 q,即 q = q - XSIGN(a)
    q                  = _mm_sub_epi64(q, asign);
    // 执行截断操作,即 trunc(a/d) = (q ^ dsign) - dsign
    q                  = _mm_sub_epi64(_mm_xor_si128(q, divisor.val[2]), divisor.val[2]);
    return q;
}
/***************************
 * Division
 ***************************/
// TODO: emulate integer division
#define npyv_div_f32 _mm_div_ps
#define npyv_div_f64 _mm_div_pd
/***************************
 * FUSED
 ***************************/
#ifdef NPY_HAVE_FMA3
    // multiply and add, a*b + c
    #define npyv_muladd_f32 _mm_fmadd_ps
    #define npyv_muladd_f64 _mm_fmadd_pd
    // multiply and subtract, a*b - c
    #define npyv_mulsub_f32 _mm_fmsub_ps
    #define npyv_mulsub_f64 _mm_fmsub_pd
    // negate multiply and add, -(a*b) + c
    #define npyv_nmuladd_f32 _mm_fnmadd_ps
    #define npyv_nmuladd_f64 _mm_fnmadd_pd
    // negate multiply and subtract, -(a*b) - c
    #define npyv_nmulsub_f32 _mm_fnmsub_ps
    #define npyv_nmulsub_f64 _mm_fnmsub_pd
    // multiply, add for odd elements and subtract even elements.
    // (a * b) -+ c
    #define npyv_muladdsub_f32 _mm_fmaddsub_ps
    #define npyv_muladdsub_f64 _mm_fmaddsub_pd
#elif defined(NPY_HAVE_FMA4)
    // multiply and add, a*b + c
    #define npyv_muladd_f32 _mm_macc_ps
    #define npyv_muladd_f64 _mm_macc_pd
    // multiply and subtract, a*b - c
    #define npyv_mulsub_f32 _mm_msub_ps
    #define npyv_mulsub_f64 _mm_msub_pd
    // negate multiply and add, -(a*b) + c
    #define npyv_nmuladd_f32 _mm_nmacc_ps
    #define npyv_nmuladd_f64 _mm_nmacc_pd
    // multiply, add for odd elements and subtract even elements.
    // (a * b) -+ c
    #define npyv_muladdsub_f32 _mm_maddsub_ps
    #define npyv_muladdsub_f64 _mm_maddsub_pd
#else
    // 如果不支持 FMA 指令集,则定义一些函数来模拟乘加和乘减操作
    // multiply and add, a*b + c
    NPY_FINLINE npyv_f32 npyv_muladd_f32(npyv_f32 a, npyv_f32 b, npyv_f32 c)
    { return npyv_add_f32(npyv_mul_f32(a, b), c); }
    NPY_FINLINE npyv_f64 npyv_muladd_f64(npyv_f64 a, npyv_f64 b, npyv_f64 c)
    { return npyv_add_f64(npyv_mul_f64(a, b), c); }
#endif
    // 定义一个内联函数,实现浮点数向量 a 和 b 的乘法,再减去向量 c 的结果
    NPY_FINLINE npyv_f32 npyv_mulsub_f32(npyv_f32 a, npyv_f32 b, npyv_f32 c)
    { return npyv_sub_f32(npyv_mul_f32(a, b), c); }
    
    // 定义一个内联函数,实现双精度浮点数向量 a 和 b 的乘法,再减去向量 c 的结果
    NPY_FINLINE npyv_f64 npyv_mulsub_f64(npyv_f64 a, npyv_f64 b, npyv_f64 c)
    { return npyv_sub_f64(npyv_mul_f64(a, b), c); }
    
    // 定义一个内联函数,实现浮点数向量 a 和 b 的乘法的相反数,再加上向量 c 的结果
    NPY_FINLINE npyv_f32 npyv_nmuladd_f32(npyv_f32 a, npyv_f32 b, npyv_f32 c)
    { return npyv_sub_f32(c, npyv_mul_f32(a, b)); }
    
    // 定义一个内联函数,实现双精度浮点数向量 a 和 b 的乘法的相反数,再加上向量 c 的结果
    NPY_FINLINE npyv_f64 npyv_nmuladd_f64(npyv_f64 a, npyv_f64 b, npyv_f64 c)
    { return npyv_sub_f64(c, npyv_mul_f64(a, b)); }
    
    // 定义一个内联函数,实现浮点数向量 a 和 b 的乘法结果加上向量 c 的结果(奇数元素加,偶数元素减)
    // (a * b) -+ c
    NPY_FINLINE npyv_f32 npyv_muladdsub_f32(npyv_f32 a, npyv_f32 b, npyv_f32 c)
    {
        // 计算 a 和 b 的乘积
        npyv_f32 m = npyv_mul_f32(a, b);
    #ifdef NPY_HAVE_SSE3
        // 如果支持 SSE3 指令集,则使用 SSE3 中的加减操作
        return _mm_addsub_ps(m, c);
    #else
        // 如果不支持 SSE3,则手动实现加减操作
        const npyv_f32 msign = npyv_set_f32(-0.0f, 0.0f, -0.0f, 0.0f);
        return npyv_add_f32(m, npyv_xor_f32(msign, c));
    #endif
    }
    
    // 定义一个内联函数,实现双精度浮点数向量 a 和 b 的乘法结果加上向量 c 的结果(奇数元素加,偶数元素减)
    NPY_FINLINE npyv_f64 npyv_muladdsub_f64(npyv_f64 a, npyv_f64 b, npyv_f64 c)
    {
        // 计算 a 和 b 的乘积
        npyv_f64 m = npyv_mul_f64(a, b);
    #ifdef NPY_HAVE_SSE3
        // 如果支持 SSE3 指令集,则使用 SSE3 中的加减操作
        return _mm_addsub_pd(m, c);
    #else
        // 如果不支持 SSE3,则手动实现加减操作
        const npyv_f64 msign = npyv_set_f64(-0.0, 0.0);
        return npyv_add_f64(m, npyv_xor_f64(msign, c));
    #endif
    }
#endif // NPY_HAVE_FMA3
#ifndef NPY_HAVE_FMA3 // for FMA4 and NON-FMA3
    // negate multiply and subtract, -(a*b) - c
    // 定义一个内联函数,用于实现 -(a*b) - c 的操作
    NPY_FINLINE npyv_f32 npyv_nmulsub_f32(npyv_f32 a, npyv_f32 b, npyv_f32 c)
    {
        // 计算 a 的负数
        npyv_f32 neg_a = npyv_xor_f32(a, npyv_setall_f32(-0.0f));
        // 返回 -(a*b) - c 的结果
        return npyv_sub_f32(npyv_mul_f32(neg_a, b), c);
    }
    // 定义一个内联函数,用于实现 -(a*b) - c 的操作,针对双精度浮点数
    NPY_FINLINE npyv_f64 npyv_nmulsub_f64(npyv_f64 a, npyv_f64 b, npyv_f64 c)
    {
        // 计算 a 的负数
        npyv_f64 neg_a = npyv_xor_f64(a, npyv_setall_f64(-0.0));
        // 返回 -(a*b) - c 的结果
        return npyv_sub_f64(npyv_mul_f64(neg_a, b), c);
    }
#endif // !NPY_HAVE_FMA3

/***************************
 * Summation
 ***************************/
// reduce sum across vector
// 对无符号 32 位整数向量进行求和
NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
{
    // 将向量 a 按元素相加,并将结果保存在临时变量 t 中
    __m128i t = _mm_add_epi32(a, _mm_srli_si128(a, 8));
    t = _mm_add_epi32(t, _mm_srli_si128(t, 4));
    // 将临时变量 t 的最低元素转换为 unsigned int 类型并返回
    return (unsigned)_mm_cvtsi128_si32(t);
}

// 对无符号 64 位整数向量进行求和
NPY_FINLINE npy_uint64 npyv_sum_u64(npyv_u64 a)
{
    // 将向量 a 的前后两个元素按位相加,并将结果保存在临时变量 one 中
    __m128i one = _mm_add_epi64(a, _mm_unpackhi_epi64(a, a));
    // 将临时变量 one 的元素转换为 unsigned long long 类型并返回
    return (npy_uint64)npyv128_cvtsi128_si64(one);
}

// 对单精度浮点数向量进行求和
NPY_FINLINE float npyv_sum_f32(npyv_f32 a)
{
#ifdef NPY_HAVE_SSE3
    // 使用 SSE3 指令集实现单精度浮点数向量的求和
    __m128 sum_halves = _mm_hadd_ps(a, a);
    return _mm_cvtss_f32(_mm_hadd_ps(sum_halves, sum_halves));
#else
    // 使用传统 SSE 指令集实现单精度浮点数向量的求和
    __m128 t1 = _mm_movehl_ps(a, a);
    __m128 t2 = _mm_add_ps(a, t1);
    __m128 t3 = _mm_shuffle_ps(t2, t2, 1);
    __m128 t4 = _mm_add_ss(t2, t3);
    return _mm_cvtss_f32(t4);
#endif
}

// 对双精度浮点数向量进行求和
NPY_FINLINE double npyv_sum_f64(npyv_f64 a)
{
#ifdef NPY_HAVE_SSE3
    // 使用 SSE3 指令集实现双精度浮点数向量的求和
    return _mm_cvtsd_f64(_mm_hadd_pd(a, a));
#else
    // 使用传统 SSE 指令集实现双精度浮点数向量的求和
    return _mm_cvtsd_f64(_mm_add_pd(a, _mm_unpackhi_pd(a, a)));
#endif
}

// expand the source vector and performs sum reduce
// 对无符号 8 位整数向量进行求和
NPY_FINLINE npy_uint16 npyv_sumup_u8(npyv_u8 a)
{
    // 将向量 a 的所有元素累加到一个 16 位整数向量 two 中
    __m128i two = _mm_sad_epu8(a, _mm_setzero_si128());
    // 将向量 two 的前后两个元素按位相加,并将结果保存在临时变量 one 中
    __m128i one = _mm_add_epi16(two, _mm_unpackhi_epi64(two, two));
    // 将临时变量 one 的元素转换为 unsigned short 类型并返回
    return (npy_uint16)_mm_cvtsi128_si32(one);
}

// 对无符号 16 位整数向量进行求和
NPY_FINLINE npy_uint32 npyv_sumup_u16(npyv_u16 a)
{
    // 创建一个掩码,用于提取 a 中的偶数位元素
    const __m128i even_mask = _mm_set1_epi32(0x0000FFFF);
    // 将 a 中的偶数位元素提取到向量 even 中
    __m128i even = _mm_and_si128(a, even_mask);
    // 将 a 中的奇数位元素向右移动 16 位,并与 even 相加得到 four
    __m128i odd  = _mm_srli_epi32(a, 16);
    __m128i four = _mm_add_epi32(even, odd);
    // 调用 npyv_sum_u32 函数对 four 进行求和,并返回结果
    return npyv_sum_u32(four);
}

#endif // _NPY_SIMD_SSE_ARITHMETIC_H

.\numpy\numpy\_core\src\common\simd\sse\conversion.h

#ifndef NPY_SIMD
    #error "Not a standalone header"
#endif

#ifndef _NPY_SIMD_SSE_CVT_H
#define _NPY_SIMD_SSE_CVT_H

// 将掩码类型转换为整数类型
#define npyv_cvt_u8_b8(BL)   BL
#define npyv_cvt_s8_b8(BL)   BL
#define npyv_cvt_u16_b16(BL) BL
#define npyv_cvt_s16_b16(BL) BL
#define npyv_cvt_u32_b32(BL) BL
#define npyv_cvt_s32_b32(BL) BL
#define npyv_cvt_u64_b64(BL) BL
#define npyv_cvt_s64_b64(BL) BL
#define npyv_cvt_f32_b32 _mm_castsi128_ps   // 将整数类型转换为单精度浮点数向量
#define npyv_cvt_f64_b64 _mm_castsi128_pd   // 将整数类型转换为双精度浮点数向量

// 将整数类型转换为掩码类型
#define npyv_cvt_b8_u8(A)   A
#define npyv_cvt_b8_s8(A)   A
#define npyv_cvt_b16_u16(A) A
#define npyv_cvt_b16_s16(A) A
#define npyv_cvt_b32_u32(A) A
#define npyv_cvt_b32_s32(A) A
#define npyv_cvt_b64_u64(A) A
#define npyv_cvt_b64_s64(A) A
#define npyv_cvt_b32_f32 _mm_castps_si128    // 将单精度浮点数向量转换为整数类型
#define npyv_cvt_b64_f64 _mm_castpd_si128    // 将双精度浮点数向量转换为整数类型

// 将布尔向量转换为整数位字段
NPY_FINLINE npy_uint64 npyv_tobits_b8(npyv_b8 a)
{ return (npy_uint16)_mm_movemask_epi8(a); }

NPY_FINLINE npy_uint64 npyv_tobits_b16(npyv_b16 a)
{
    __m128i pack = _mm_packs_epi16(a, a);
    return (npy_uint8)_mm_movemask_epi8(pack);
}

NPY_FINLINE npy_uint64 npyv_tobits_b32(npyv_b32 a)
{ return (npy_uint8)_mm_movemask_ps(_mm_castsi128_ps(a)); }

NPY_FINLINE npy_uint64 npyv_tobits_b64(npyv_b64 a)
{ return (npy_uint8)_mm_movemask_pd(_mm_castsi128_pd(a)); }

// 扩展操作
NPY_FINLINE npyv_u16x2 npyv_expand_u16_u8(npyv_u8 data) {
    npyv_u16x2 r;
    const __m128i z = _mm_setzero_si128();
    r.val[0] = _mm_unpacklo_epi8(data, z);
    r.val[1] = _mm_unpackhi_epi8(data, z);
    return r;
}

NPY_FINLINE npyv_u32x2 npyv_expand_u32_u16(npyv_u16 data) {
    npyv_u32x2 r;
    const __m128i z = _mm_setzero_si128();
    r.val[0]  = _mm_unpacklo_epi16(data, z);
    r.val[1]  = _mm_unpackhi_epi16(data, z);
    return r;
}

// 将两个16位布尔向量打包成一个8位布尔向量
NPY_FINLINE npyv_b8 npyv_pack_b8_b16(npyv_b16 a, npyv_b16 b) {
    return _mm_packs_epi16(a, b);
}

// 将四个32位布尔向量打包成一个8位布尔向量
NPY_FINLINE npyv_b8
npyv_pack_b8_b32(npyv_b32 a, npyv_b32 b, npyv_b32 c, npyv_b32 d) {
    npyv_b16 ab = _mm_packs_epi32(a, b);
    npyv_b16 cd = _mm_packs_epi32(c, d);
    return npyv_pack_b8_b16(ab, cd);
}

// 将八个64位布尔向量打包成一个8位布尔向量
NPY_FINLINE npyv_b8
npyv_pack_b8_b64(npyv_b64 a, npyv_b64 b, npyv_b64 c, npyv_b64 d,
                 npyv_b64 e, npyv_b64 f, npyv_b64 g, npyv_b64 h) {
    npyv_b32 ab = _mm_packs_epi32(a, b);
    npyv_b32 cd = _mm_packs_epi32(c, d);
    npyv_b32 ef = _mm_packs_epi32(e, f);
    npyv_b32 gh = _mm_packs_epi32(g, h);
    return npyv_pack_b8_b32(ab, cd, ef, gh);
}

// 将单精度浮点数向量四舍五入到最近的整数(假设偶数)
#define npyv_round_s32_f32 _mm_cvtps_epi32
NPY_FINLINE npyv_s32 npyv_round_s32_f64(npyv_f64 a, npyv_f64 b)
{
    __m128i lo = _mm_cvtpd_epi32(a), hi = _mm_cvtpd_epi32(b);
    return _mm_unpacklo_epi64(lo, hi);
}

#endif // _NPY_SIMD_SSE_CVT_H

.\numpy\numpy\_core\src\common\simd\sse\math.h

#ifndef NPY_SIMD
    #error "Not a standalone header"
#endif

#ifndef _NPY_SIMD_SSE_MATH_H
#define _NPY_SIMD_SSE_MATH_H
/***************************
 * Elementary
 ***************************/
// 平方根函数定义
#define npyv_sqrt_f32 _mm_sqrt_ps
#define npyv_sqrt_f64 _mm_sqrt_pd

// 倒数函数定义
NPY_FINLINE npyv_f32 npyv_recip_f32(npyv_f32 a)
{ return _mm_div_ps(_mm_set1_ps(1.0f), a); }
NPY_FINLINE npyv_f64 npyv_recip_f64(npyv_f64 a)
{ return _mm_div_pd(_mm_set1_pd(1.0), a); }

// 绝对值函数定义
NPY_FINLINE npyv_f32 npyv_abs_f32(npyv_f32 a)
{
    return _mm_and_ps(
        a, _mm_castsi128_ps(_mm_set1_epi32(0x7fffffff))
    );
}
NPY_FINLINE npyv_f64 npyv_abs_f64(npyv_f64 a)
{
    return _mm_and_pd(
        a, _mm_castsi128_pd(npyv_setall_s64(0x7fffffffffffffffLL))
    );
}

// 平方函数定义
NPY_FINLINE npyv_f32 npyv_square_f32(npyv_f32 a)
{ return _mm_mul_ps(a, a); }
NPY_FINLINE npyv_f64 npyv_square_f64(npyv_f64 a)
{ return _mm_mul_pd(a, a); }

// 最大值函数定义,直接映射,不保证处理 NaN
#define npyv_max_f32 _mm_max_ps
#define npyv_max_f64 _mm_max_pd

// 最大值函数,支持 IEEE 浮点算术(IEC 60559)
// - 如果其中一个向量包含 NaN,则设置另一个向量对应元素
// - 只有当两个对应元素都是 NaN 时,才设置 NaN
NPY_FINLINE npyv_f32 npyv_maxp_f32(npyv_f32 a, npyv_f32 b)
{
    __m128i nn = npyv_notnan_f32(b);
    __m128 max = _mm_max_ps(a, b);
    return npyv_select_f32(nn, max, a);
}
NPY_FINLINE npyv_f64 npyv_maxp_f64(npyv_f64 a, npyv_f64 b)
{
    __m128i nn  = npyv_notnan_f64(b);
    __m128d max = _mm_max_pd(a, b);
    return npyv_select_f64(nn, max, a);
}
NPY_FINLINE npyv_f32 npyv_maxn_f32(npyv_f32 a, npyv_f32 b)
{
    __m128i nn = npyv_notnan_f32(a);
    __m128 max = _mm_max_ps(a, b);
    return npyv_select_f32(nn, max, a);
}
NPY_FINLINE npyv_f64 npyv_maxn_f64(npyv_f64 a, npyv_f64 b)
{
    __m128i nn  = npyv_notnan_f64(a);
    __m128d max = _mm_max_pd(a, b);
    return npyv_select_f64(nn, max, a);
}

// 最大值函数,整数操作
#ifdef NPY_HAVE_SSE41
    #define npyv_max_s8 _mm_max_epi8
    #define npyv_max_u16 _mm_max_epu16
    #define npyv_max_u32 _mm_max_epu32
    #define npyv_max_s32 _mm_max_epi32
#else
    NPY_FINLINE npyv_s8 npyv_max_s8(npyv_s8 a, npyv_s8 b)
    {
        return npyv_select_s8(npyv_cmpgt_s8(a, b), a, b);
    }
    NPY_FINLINE npyv_u16 npyv_max_u16(npyv_u16 a, npyv_u16 b)
    {
        return npyv_select_u16(npyv_cmpgt_u16(a, b), a, b);
    }
    NPY_FINLINE npyv_u32 npyv_max_u32(npyv_u32 a, npyv_u32 b)
    {
        return npyv_select_u32(npyv_cmpgt_u32(a, b), a, b);
    }
    NPY_FINLINE npyv_s32 npyv_max_s32(npyv_s32 a, npyv_s32 b)
    {
        return npyv_select_s32(npyv_cmpgt_s32(a, b), a, b);
    }
#endif
#define npyv_max_u8 _mm_max_epu8
#define npyv_max_s16 _mm_max_epi16
NPY_FINLINE npyv_u64 npyv_max_u64(npyv_u64 a, npyv_u64 b)
{
    return npyv_select_u64(npyv_cmpgt_u64(a, b), a, b);
}
NPY_FINLINE npyv_s64 npyv_max_s64(npyv_s64 a, npyv_s64 b)
{
    # 使用 SIMD 指令进行比较,选取 a 和 b 中对应元素中的大值
    return npyv_select_s64(npyv_cmpgt_s64(a, b), a, b);
// Minimum, natively mapping with no guarantees to handle NaN.
// 定义了几个宏用于执行单精度和双精度浮点数的最小值操作
#define npyv_min_f32 _mm_min_ps
#define npyv_min_f64 _mm_min_pd

// Minimum, supports IEEE floating-point arithmetic (IEC 60559),
// - If one of the two vectors contains NaN, the equivalent element of the other vector is set
// - Only if both corresponded elements are NaN, NaN is set.
// 实现了对单精度浮点数向量的最小值操作,支持 IEEE 浮点算术(IEC 60559),
// - 如果两个向量中的一个包含 NaN,则设置另一个向量对应元素的值
// - 只有当两个对应的元素都是 NaN 时,才会设置为 NaN
NPY_FINLINE npyv_f32 npyv_minp_f32(npyv_f32 a, npyv_f32 b)
{
    // 使用 nopyv_notnan_f32 函数获取非 NaN 的掩码
    __m128i nn = npyv_notnan_f32(b);
    // 使用 SSE 指令计算 a 和 b 向量中的最小值
    __m128 min = _mm_min_ps(a, b);
    // 根据非 NaN 的掩码选择最小值或原始值来创建新的向量
    return npyv_select_f32(nn, min, a);
}

// 类似于上述函数,实现了对双精度浮点数向量的最小值操作
NPY_FINLINE npyv_f64 npyv_minp_f64(npyv_f64 a, npyv_f64 b)
{
    __m128i nn  = npyv_notnan_f64(b);
    __m128d min = _mm_min_pd(a, b);
    return npyv_select_f64(nn, min, a);
}

// 实现了对单精度浮点数向量的最小值操作
NPY_FINLINE npyv_f32 npyv_minn_f32(npyv_f32 a, npyv_f32 b)
{
    __m128i nn = npyv_notnan_f32(a);
    __m128 min = _mm_min_ps(a, b);
    return npyv_select_f32(nn, min, a);
}

// 实现了对双精度浮点数向量的最小值操作
NPY_FINLINE npyv_f64 npyv_minn_f64(npyv_f64 a, npyv_f64 b)
{
    __m128i nn  = npyv_notnan_f64(a);
    __m128d min = _mm_min_pd(a, b);
    return npyv_select_f64(nn, min, a);
}

// Minimum, integer operations
#ifdef NPY_HAVE_SSE41
    // 使用 SSE4.1 指令集提供的最小值操作宏
    #define npyv_min_s8 _mm_min_epi8
    #define npyv_min_u16 _mm_min_epu16
    #define npyv_min_u32 _mm_min_epu32
    #define npyv_min_s32 _mm_min_epi32
#else
    // 对于不支持 SSE4.1 的平台,实现了对应整数类型的最小值操作
    NPY_FINLINE npyv_s8 npyv_min_s8(npyv_s8 a, npyv_s8 b)
    {
        // 使用条件选择函数实现 s8 类型向量的最小值操作
        return npyv_select_s8(npyv_cmplt_s8(a, b), a, b);
    }

    NPY_FINLINE npyv_u16 npyv_min_u16(npyv_u16 a, npyv_u16 b)
    {
        // 使用条件选择函数实现 u16 类型向量的最小值操作
        return npyv_select_u16(npyv_cmplt_u16(a, b), a, b);
    }

    NPY_FINLINE npyv_u32 npyv_min_u32(npyv_u32 a, npyv_u32 b)
    {
        // 使用条件选择函数实现 u32 类型向量的最小值操作
        return npyv_select_u32(npyv_cmplt_u32(a, b), a, b);
    }

    NPY_FINLINE npyv_s32 npyv_min_s32(npyv_s32 a, npyv_s32 b)
    {
        // 使用条件选择函数实现 s32 类型向量的最小值操作
        return npyv_select_s32(npyv_cmplt_s32(a, b), a, b);
    }
#endif

// 使用 SSE2 指令集提供的最小值操作宏
#define npyv_min_u8 _mm_min_epu8
#define npyv_min_s16 _mm_min_epi16

// 实现了对 u64 类型向量的最小值操作
NPY_FINLINE npyv_u64 npyv_min_u64(npyv_u64 a, npyv_u64 b)
{
    // 使用条件选择函数实现 u64 类型向量的最小值操作
    return npyv_select_u64(npyv_cmplt_u64(a, b), a, b);
}

// 实现了对 s64 类型向量的最小值操作
NPY_FINLINE npyv_s64 npyv_min_s64(npyv_s64 a, npyv_s64 b)
{
    // 使用条件选择函数实现 s64 类型向量的最小值操作
    return npyv_select_s64(npyv_cmplt_s64(a, b), a, b);
}

// reduce min&max for 32&64-bits
// 定义了宏用于实现对 32 位和 64 位数据类型的最小和最大值缩减操作
#define NPY_IMPL_SSE_REDUCE_MINMAX(STYPE, INTRIN, VINTRIN)                                     \
    NPY_FINLINE STYPE##32 npyv_reduce_##INTRIN##32(__m128i a)                                  \
    {                                                                                          \
        // 使用 SSE 指令集进行数据重排和比较,得到最小值
        __m128i v64 =  npyv_##INTRIN##32(a, _mm_shuffle_epi32(a, _MM_SHUFFLE(0, 0, 3, 2)));    \
        // 再次重排和比较,得到最小值
        __m128i v32 = npyv_##INTRIN##32(v64, _mm_shuffle_epi32(v64, _MM_SHUFFLE(0, 0, 0, 1))); \
        // 将结果转换为对应的 32 位整数并返回
        return (STYPE##32)_mm_cvtsi128_si32(v32);                                              \
    }                                                                                          \
    NPY_FINLINE STYPE##64 npyv_reduce_##INTRIN##64(__m128i a)                                  \
    {
        # 创建一个名为 v64 的变量,使用 npyv_##INTRIN##64 函数生成一个 64 位的数据向量,
        # 这个函数以 a 作为输入,通过对 a 进行特定的位操作和洗牌生成结果。
        __m128i v64  = npyv_##INTRIN##64(a, _mm_shuffle_epi32(a, _MM_SHUFFLE(0, 0, 3, 2)));

        # 将 v64 中的数据提取出来,并转换成 STYPE##64 类型的值,然后作为函数的返回值返回。
        return (STYPE##64)npyv_extract0_u64(v64);
    }


这段代码中,使用了一些宏定义和 SIMD(单指令多数据流)指令,用于处理数据向量化操作,具体的 INTRIN 和 STYPE 是根据具体的上下文和宏定义来确定的。
// 定义宏 NPY_IMPL_SSE_REDUCE_MINMAX,用于生成不同类型和函数的 SSE 指令实现
NPY_IMPL_SSE_REDUCE_MINMAX(npy_uint, min_u, min_epu)
NPY_IMPL_SSE_REDUCE_MINMAX(npy_int,  min_s, min_epi)
NPY_IMPL_SSE_REDUCE_MINMAX(npy_uint, max_u, max_epu)
NPY_IMPL_SSE_REDUCE_MINMAX(npy_int,  max_s, max_epi)
// 取消宏定义 NPY_IMPL_SSE_REDUCE_MINMAX

// 宏重新定义 NPY_IMPL_SSE_REDUCE_MINMAX,用于生成 SSE 指令实现
#define NPY_IMPL_SSE_REDUCE_MINMAX(INTRIN, INF, INF64)                                          \
    // 定义单精度浮点数的 SSE 指令实现,用于计算最小值或最大值
    NPY_FINLINE float npyv_reduce_##INTRIN##_f32(npyv_f32 a)                                    \
    {                                                                                           \
        // 将向量 a 按指定方式重新排列,得到 64 位浮点数向量 v64
        __m128 v64 =  _mm_##INTRIN##_ps(a, _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 3, 2)));      \
        // 将 v64 按指定方式重新排列,得到 32 位浮点数向量 v32
        __m128 v32 = _mm_##INTRIN##_ps(v64, _mm_shuffle_ps(v64, v64, _MM_SHUFFLE(0, 0, 0, 1))); \
        // 返回 v32 的第一个元素作为浮点数结果
        return _mm_cvtss_f32(v32);                                                              \
    }                                                                                           \
    // 定义双精度浮点数的 SSE 指令实现,用于计算最小值或最大值
    NPY_FINLINE double npyv_reduce_##INTRIN##_f64(npyv_f64 a)                                   \
    {                                                                                           \
        // 将向量 a 按指定方式重新排列,得到 64 位双精度浮点数向量 v64
        __m128d v64 = _mm_##INTRIN##_pd(a, _mm_shuffle_pd(a, a, _MM_SHUFFLE(0, 0, 0, 1)));      \
        // 返回 v64 的第一个元素作为双精度浮点数结果
        return _mm_cvtsd_f64(v64);                                                              \
    }                                                                                           \
    // 定义单精度浮点数的 SSE 指令实现,用于计算带有处理 NaN 的最小值或最大值
    NPY_FINLINE float npyv_reduce_##INTRIN##p_f32(npyv_f32 a)                                   \
    {                                                                                           \
        // 获取 a 中非 NaN 的掩码
        npyv_b32 notnan = npyv_notnan_f32(a);                                                   \
        // 如果所有元素都是 NaN,则返回 a 的第一个元素
        if (NPY_UNLIKELY(!npyv_any_b32(notnan))) {                                              \
            return _mm_cvtss_f32(a);                                                            \
        }                                                                                       \
        // 选取非 NaN 的元素或者用 INF 替换 NaN 的元素
        a = npyv_select_f32(notnan, a, npyv_reinterpret_f32_u32(npyv_setall_u32(INF)));         \
        // 调用 npyv_reduce_##INTRIN##_f32 计算最终结果
        return npyv_reduce_##INTRIN##_f32(a);                                                   \
    }                                                                                           \
    // 定义双精度浮点数的 SSE 指令实现,用于计算带有处理 NaN 的最小值或最大值
    NPY_FINLINE double npyv_reduce_##INTRIN##p_f64(npyv_f64 a)                                  \
    {
        # 使用 SIMD 向量操作,检查双精度浮点向量 a 中的非 NaN 元素
        npyv_b64 notnan = npyv_notnan_f64(a);
        # 如果向量 a 中没有非 NaN 元素,则返回向量中的第一个元素作为结果
        if (NPY_UNLIKELY(!npyv_any_b64(notnan))) {
            return _mm_cvtsd_f64(a);
        }
        # 将向量 a 中非 NaN 元素保留,将 NaN 元素替换为正无穷,并重新解释为双精度浮点数向量
        a = npyv_select_f64(notnan, a, npyv_reinterpret_f64_u64(npyv_setall_u64(INF64)));
        # 对非 NaN 元素进行指定的归约操作 INTRIN,并返回结果
        return npyv_reduce_##INTRIN##_f64(a);
    }
    NPY_FINLINE float npyv_reduce_##INTRIN##n_f32(npyv_f32 a)
    {
        # 使用 SIMD 向量操作,检查单精度浮点向量 a 中的非 NaN 元素
        npyv_b32 notnan = npyv_notnan_f32(a);
        # 如果向量 a 中有 NaN 元素,则返回特定的 NaN 值
        if (NPY_UNLIKELY(!npyv_all_b32(notnan))) {
            const union { npy_uint32 i; float f;} pnan = {0x7fc00000UL};
            return pnan.f;
        }
        # 对非 NaN 元素进行指定的归约操作 INTRIN,并返回结果
        return npyv_reduce_##INTRIN##_f32(a);
    }
    NPY_FINLINE double npyv_reduce_##INTRIN##n_f64(npyv_f64 a)
    {
        # 使用 SIMD 向量操作,检查双精度浮点向量 a 中的非 NaN 元素
        npyv_b64 notnan = npyv_notnan_f64(a);
        # 如果向量 a 中有 NaN 元素,则返回特定的 NaN 值
        if (NPY_UNLIKELY(!npyv_all_b64(notnan))) {
            const union { npy_uint64 i; double d;} pnan = {0x7ff8000000000000ull};
            return pnan.d;
        }
        # 对非 NaN 元素进行指定的归约操作 INTRIN,并返回结果
        return npyv_reduce_##INTRIN##_f64(a);
    }
// 定义 SSE 指令的宏,用于实现最小值和最大值的规约操作
#define NPY_IMPL_SSE_REDUCE_MINMAX(STYPE, INTRIN)                                                    \
    // 定义内联函数,用于减少 SSE 寄存器中 16 位数据的最小值或最大值
    NPY_FINLINE STYPE##16 npyv_reduce_##INTRIN##16(__m128i a)                                        \
    {                                                                                                \
        // 将输入的 128 位整数按指定方式重组成 64 位整数
        __m128i v64 =  npyv_##INTRIN##16(a, _mm_shuffle_epi32(a, _MM_SHUFFLE(0, 0, 3, 2)));          \
        // 进一步重组以得到 32 位整数
        __m128i v32 = npyv_##INTRIN##16(v64, _mm_shuffle_epi32(v64, _MM_SHUFFLE(0, 0, 0, 1)));       \
        // 最后得到 16 位整数,返回其结果
        __m128i v16 = npyv_##INTRIN##16(v32, _mm_shufflelo_epi16(v32, _MM_SHUFFLE(0, 0, 0, 1)));     \
        return (STYPE##16)_mm_cvtsi128_si32(v16);                                                    \
    }                                                                                                \
    // 定义内联函数,用于减少 SSE 寄存器中 8 位数据的最小值或最大值
    NPY_FINLINE STYPE##8 npyv_reduce_##INTRIN##8(__m128i a)                                          \
    {                                                                                                \
        // 将输入的 128 位整数按指定方式重组成 64 位整数
        __m128i v64 =  npyv_##INTRIN##8(a, _mm_shuffle_epi32(a, _MM_SHUFFLE(0, 0, 3, 2)));           \
        // 进一步重组以得到 32 位整数
        __m128i v32 = npyv_##INTRIN##8(v64, _mm_shuffle_epi32(v64, _MM_SHUFFLE(0, 0, 0, 1)));        \
        // 再得到 16 位整数
        __m128i v16 = npyv_##INTRIN##8(v32, _mm_shufflelo_epi16(v32, _MM_SHUFFLE(0, 0, 0, 1)));      \
        // 最后得到 8 位整数,通过逻辑右移实现除以 2
        __m128i v8 = npyv_##INTRIN##8(v16, _mm_srli_epi16(v16, 8));                                  \
        return (STYPE##16)_mm_cvtsi128_si32(v8);                                                     \
    }

// 使用宏定义实现不同数据类型的最小值和最大值规约操作
NPY_IMPL_SSE_REDUCE_MINMAX(npy_uint, min_u)
NPY_IMPL_SSE_REDUCE_MINMAX(npy_int,  min_s)
NPY_IMPL_SSE_REDUCE_MINMAX(npy_uint, max_u)
NPY_IMPL_SSE_REDUCE_MINMAX(npy_int,  max_s)
#undef NPY_IMPL_SSE_REDUCE_MINMAX

// 如果支持 SSE4.1 指令集,则使用 SSE4.1 的指令执行浮点数四舍五入到最近偶数
NPY_FINLINE npyv_f32 npyv_rint_f32(npyv_f32 a)
{
#ifdef NPY_HAVE_SSE41
    // 使用 SSE4.1 的指令实现浮点数的四舍五入到最近偶数
    return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT);
#else
    // 如果不支持 SSE4.1 指令集,则使用以下代码实现浮点数的四舍五入到最近偶数
    // 设置一个 32 位浮点数全为 -0.0f 的向量
    const __m128 szero = _mm_set1_ps(-0.0f);
    // 设置一个 32 位整数表示指数掩码为 0xff000000
    const __m128i exp_mask = _mm_set1_epi32(0xff000000);

    // 生成一个掩码,用于检测非无限值
    __m128i nfinite_mask = _mm_slli_epi32(_mm_castps_si128(a), 1);
    nfinite_mask = _mm_and_si128(nfinite_mask, exp_mask);
    nfinite_mask = _mm_cmpeq_epi32(nfinite_mask, exp_mask);

    // 消除 NaN 和 Inf,以避免无效的浮点错误
    __m128 x = _mm_xor_ps(a, _mm_castsi128_ps(nfinite_mask));
    // 将浮点数转换为整数进行四舍五入
    __m128i roundi = _mm_cvtps_epi32(x);
    // 将整数转换回浮点数
    __m128 round = _mm_cvtepi32_ps(roundi);
    // 处理带符号的零
    round = _mm_or_ps(round, _mm_and_ps(a, szero));
    // 如果溢出则返回原始值
    __m128i overflow_mask = _mm_cmpeq_epi32(roundi, _mm_castps_si128(szero));
    // 如果溢出或者非有限值,则返回原始值,否则返回四舍五入后的结果
    return npyv_select_f32(_mm_or_si128(nfinite_mask, overflow_mask), a, round);
#endif
}
NPY_FINLINE npyv_f64 npyv_rint_f64(npyv_f64 a)
{
#ifdef NPY_HAVE_SSE41
    // 如果支持 SSE4.1 指令集,则使用 SSE 指令进行向最近整数舍入并返回结果
    return _mm_round_pd(a, _MM_FROUND_TO_NEAREST_INT);
#else
    // 如果不支持 SSE4.1 指令集,则进行手动实现舍入操作

    // 设置常量 -0.0 的向量
    const __m128d szero = _mm_set1_pd(-0.0);
    // 设置常量 2^52 的向量
    const __m128d two_power_52 = _mm_set1_pd(0x10000000000000);

    // 计算出 NaN 掩码,用于排除 NaN 值,避免在比较操作中出现无效的浮点错误
    __m128d nan_mask = _mm_cmpunord_pd(a, a);

    // 计算绝对值向量,并处理 NaN 值
    __m128d abs_x = npyv_abs_f64(_mm_xor_pd(nan_mask, a));

    // 执行舍入操作,加上魔法数 2^52
    __m128d round = _mm_sub_pd(_mm_add_pd(two_power_52, abs_x), two_power_52);

    // 复制原始值的符号到舍入结果中
    round = _mm_or_pd(round, _mm_and_pd(a, szero));

    // 如果 |a| >= 2^52 或者 a 是 NaN,则返回原始值 a;否则返回舍入结果 round
    __m128d mask = _mm_cmpge_pd(abs_x, two_power_52);
    mask = _mm_or_pd(mask, nan_mask);
    return npyv_select_f64(_mm_castpd_si128(mask), a, round);
#endif
}

// ceil
#ifdef NPY_HAVE_SSE41
    // 如果支持 SSE4.1 指令集,则使用 SSE 指令进行向上取整并返回结果
    #define npyv_ceil_f32 _mm_ceil_ps
    #define npyv_ceil_f64 _mm_ceil_pd
#else
    // 如果不支持 SSE4.1 指令集,则手动实现单精度浮点数向上取整操作
    NPY_FINLINE npyv_f32 npyv_ceil_f32(npyv_f32 a)
    {
        const __m128 one = _mm_set1_ps(1.0f);
        const __m128 szero = _mm_set1_ps(-0.0f);
        const __m128i exp_mask = _mm_set1_epi32(0xff000000);

        // 计算非无穷大的掩码,用于排除 NaN 和 Inf 值,避免在比较操作中出现无效的浮点错误
        __m128i nfinite_mask = _mm_slli_epi32(_mm_castps_si128(a), 1);
        nfinite_mask = _mm_and_si128(nfinite_mask, exp_mask);
        nfinite_mask = _mm_cmpeq_epi32(nfinite_mask, exp_mask);

        // 处理 NaN 和 Inf 值,将它们的位反转,并与原始值异或,以排除这些值
        __m128 x = _mm_xor_ps(a, _mm_castsi128_ps(nfinite_mask));

        // 执行舍入操作,并将结果转换为整数
        __m128i roundi = _mm_cvtps_epi32(x);

        // 将整数结果转换回单精度浮点数
        __m128 round = _mm_cvtepi32_ps(roundi);

        // 执行向上取整操作
        __m128 ceil = _mm_add_ps(round, _mm_and_ps(_mm_cmplt_ps(round, x), one));

        // 将符号位从原始值复制到向上取整结果中
        ceil = _mm_or_ps(ceil, _mm_and_ps(a, szero));

        // 如果溢出,返回原始值 a;否则返回向上取整结果 ceil
        __m128i overflow_mask = _mm_cmpeq_epi32(roundi, _mm_castps_si128(szero));
        return npyv_select_f32(_mm_or_si128(nfinite_mask, overflow_mask), a, ceil);
    }

    // 手动实现双精度浮点数向上取整操作
    NPY_FINLINE npyv_f64 npyv_ceil_f64(npyv_f64 a)
    {
        // 创建一个包含值为1.0的双精度浮点数向量
        const __m128d one = _mm_set1_pd(1.0);
        // 创建一个包含值为-0.0的双精度浮点数向量
        const __m128d szero = _mm_set1_pd(-0.0);
        // 创建一个包含值为2^52的双精度浮点数向量
        const __m128d two_power_52 = _mm_set1_pd(0x10000000000000);
        
        // 创建一个向量,其元素为a中的NaN的掩码
        __m128d nan_mask = _mm_cmpunord_pd(a, a);
        
        // 通过异或操作去除NaN,以避免在后续的比较操作中出现无效的浮点数错误
        __m128d x = _mm_xor_pd(nan_mask, a);
        
        // 计算x的绝对值向量
        __m128d abs_x = npyv_abs_f64(x);
        
        // 计算x的符号向量
        __m128d sign_x = _mm_and_pd(x, szero);
        
        // 使用魔术数2^52进行四舍五入
        // 假设MXCSR寄存器已设置为四舍五入模式
        __m128d round = _mm_sub_pd(_mm_add_pd(two_power_52, abs_x), two_power_52);
        
        // 根据x的符号向量进行符号位的设置
        round = _mm_or_pd(round, sign_x);
        
        // 执行向上取整操作
        __m128d ceil = _mm_add_pd(round, _mm_and_pd(_mm_cmplt_pd(round, x), one));
        
        // 保持0.0的符号
        ceil = _mm_or_pd(ceil, sign_x);
        
        // 如果|a| >= 2^52 或 a == NaN,则返回a,否则返回ceil
        __m128d mask = _mm_cmpge_pd(abs_x, two_power_52);
        mask = _mm_or_pd(mask, nan_mask);
        
        // 根据掩码选择返回a或ceil的元素
        return npyv_select_f64(_mm_castpd_si128(mask), a, ceil);
    }
// 如果定义了 NPY_HAVE_SSE41,则定义宏 npyv_floor_f32 为 _mm_floor_ps,即使用 SSE 指令集的单精度浮点数向下取整操作
// 如果定义了 NPY_HAVE_SSE41,则定义宏 npyv_floor_f64 为 _mm_floor_pd,即使用 SSE 指令集的双精度浮点数向下取整操作
#ifdef NPY_HAVE_SSE41
    #define npyv_floor_f32 _mm_floor_ps
    #define npyv_floor_f64 _mm_floor_pd
#else
    // 否则,定义 npyv_floor_f32 函数,对单精度浮点数 a 进行向下取整操作
    NPY_FINLINE npyv_f32 npyv_floor_f32(npyv_f32 a)
    {
        // 设置一个单精度浮点数 -0.0 的向量
        const __m128 szero = _mm_set1_ps(-0.0f);
        // 设置一个整型向量,其高位字节为 0xff000000
        const __m128i exp_mask = _mm_set1_epi32(0xff000000);

        // 创建一个掩码,用于标识 a 中有限数字部分的位置
        __m128i nfinite_mask = _mm_slli_epi32(_mm_castps_si128(a), 1);
        nfinite_mask = _mm_and_si128(nfinite_mask, exp_mask);
        nfinite_mask = _mm_cmpeq_epi32(nfinite_mask, exp_mask);

        // 消除 NaN 和无穷大,以避免无效的浮点数错误
        __m128 x = _mm_xor_ps(a, _mm_castsi128_ps(nfinite_mask));
        // 将浮点数 x 向下取整到最接近的整数,得到整型向量
        __m128i trunci = _mm_cvttps_epi32(x);
        // 将整型向量转换回单精度浮点数向量
        __m128 trunc = _mm_cvtepi32_ps(trunci);
        // 将负零保留为负零,例如 -0.5 变为 -0.0
        trunc = _mm_or_ps(trunc, _mm_and_ps(a, szero));
        // 如果溢出则返回原始值 a
        __m128i overflow_mask = _mm_cmpeq_epi32(trunci, _mm_castps_si128(szero));
        // 如果 a 溢出或不是有限数字,则返回 a;否则返回向下取整后的值
        return npyv_select_f32(_mm_or_si128(nfinite_mask, overflow_mask), a, trunc);
    }

    // 否则,定义 npyv_floor_f64 函数,对双精度浮点数 a 进行向下取整操作
    NPY_FINLINE npyv_f64 npyv_floor_f64(npyv_f64 a)
    {
        // 设置一个双精度浮点数 1.0 的向量
        const __m128d one = _mm_set1_pd(1.0);
        // 设置一个双精度浮点数 -0.0 的向量
        const __m128d szero = _mm_set1_pd(-0.0);
        // 设置一个双精度浮点数 2^52 的向量
        const __m128d two_power_52 = _mm_set1_pd(0x10000000000000);
        // 创建一个掩码,用于标识 a 中 NaN 的位置
        __m128d nan_mask = _mm_cmpunord_pd(a, a);
        // 消除 NaN,以避免无效的浮点数错误在 cmpge 内
        __m128d abs_x = npyv_abs_f64(_mm_xor_pd(nan_mask, a));
        // 将 abs_x 向下取整,通过加上 2^52 的魔数来实现
        // 假设 MXCSR 寄存器已设置为舍入
        __m128d abs_round = _mm_sub_pd(_mm_add_pd(two_power_52, abs_x), two_power_52);
        // 计算需要减去的值,以确保正确的向下取整
        __m128d subtrahend = _mm_and_pd(_mm_cmpgt_pd(abs_round, abs_x), one);
        // 进行向下取整操作
        __m128d trunc = _mm_sub_pd(abs_round, subtrahend);
        // 赋予结果相同的符号
        trunc = _mm_or_pd(trunc, _mm_and_pd(a, szero));
        // 如果 |a| >= 2^52 或者 a 是 NaN,则返回 a;否则返回向下取整后的值
        __m128d mask = _mm_cmpge_pd(abs_x, two_power_52);
        mask = _mm_or_pd(mask, nan_mask);
        return npyv_select_f64(_mm_castpd_si128(mask), a, trunc);
    }
#endif
#endif
    {
        // 定义一个包含单精度浮点数 1.0 的 SSE 寄存器
        const __m128 one = _mm_set1_ps(1.0f);
        // 定义一个包含单精度浮点数 -0.0 的 SSE 寄存器
        const __m128 szero = _mm_set1_ps(-0.0f);
        // 定义一个包含 0xff000000 的 SSE 寄存器,用于提取指数部分
        const __m128i exp_mask = _mm_set1_epi32(0xff000000);
    
        // 创建一个掩码,用于标识非无穷的浮点数(finite)
        __m128i nfinite_mask = _mm_slli_epi32(_mm_castps_si128(a), 1);
                nfinite_mask = _mm_and_si128(nfinite_mask, exp_mask);
                nfinite_mask = _mm_cmpeq_epi32(nfinite_mask, exp_mask);
    
        // 消除 NaN 和无穷大,以避免无效的浮点数错误
        __m128 x = _mm_xor_ps(a, _mm_castsi128_ps(nfinite_mask));
        // 将浮点数转换为整数并进行舍入
        __m128i roundi = _mm_cvtps_epi32(x);
        // 将整数舍入结果转换回浮点数
        __m128 round = _mm_cvtepi32_ps(roundi);
        // 计算向下取整结果
        __m128 floor = _mm_sub_ps(round, _mm_and_ps(_mm_cmpgt_ps(round, x), one));
        // 考虑到带符号的零
        floor = _mm_or_ps(floor, _mm_and_ps(a, szero));
        // 如果发生溢出,则返回原始值 a
        __m128i overflow_mask = _mm_cmpeq_epi32(roundi, _mm_castps_si128(szero));
        // 如果数值溢出或者是非有限浮点数,则返回 a,否则返回 floor 的结果
        return npyv_select_f32(_mm_or_si128(nfinite_mask, overflow_mask), a, floor);
    }
    NPY_FINLINE npyv_f64 npyv_floor_f64(npyv_f64 a)
    {
        // 定义一个包含双精度浮点数 1.0 的 SSE 寄存器
        const __m128d one = _mm_set1_pd(1.0);
        // 定义一个包含双精度浮点数 -0.0 的 SSE 寄存器
        const __m128d szero = _mm_set1_pd(-0.0);
        // 定义一个包含 2^52 的双精度浮点数的 SSE 寄存器
        const __m128d two_power_52 = _mm_set1_pd(0x10000000000000);
        // 创建一个 NaN 掩码,用于标识 NaN 值
        __m128d nan_mask = _mm_cmpunord_pd(a, a);
        // 消除 NaN 以避免在 cmpge 内部出现无效的浮点数错误
        __m128d x = _mm_xor_pd(nan_mask, a);
        // 计算绝对值
        __m128d abs_x = npyv_abs_f64(x);
        // 提取符号位
        __m128d sign_x = _mm_and_pd(x, szero);
        // 通过加上魔法数 2^52 进行舍入
        // 假设 MXCSR 寄存器已设置为四舍五入
        __m128d round = _mm_sub_pd(_mm_add_pd(two_power_52, abs_x), two_power_52);
        // 复制符号位
        round = _mm_or_pd(round, sign_x);
        // 计算向下取整结果
        __m128d floor = _mm_sub_pd(round, _mm_and_pd(_mm_cmpgt_pd(round, x), one));
        // 如果 |a| >= 2^52 或者 a 是 NaN,则返回 a;否则返回 floor 的结果
        __m128d mask = _mm_cmpge_pd(abs_x, two_power_52);
               mask = _mm_or_pd(mask, nan_mask);
        return npyv_select_f64(_mm_castpd_si128(mask), a, floor);
    }
#endif // NPY_HAVE_SSE41



// 结束条件:如果定义了 NPY_HAVE_SSE41 宏,则结束当前代码块
#endif // _NPY_SIMD_SSE_MATH_H



// 结束条件:结束 _NPY_SIMD_SSE_MATH_H 头文件的条件编译块

.\numpy\numpy\_core\src\common\simd\sse\memory.h

#ifndef NPY_SIMD
    #error "Not a standalone header"
#endif

#ifndef _NPY_SIMD_SSE_MEMORY_H
#define _NPY_SIMD_SSE_MEMORY_H

#include "misc.h"

/***************************
 * load/store
 ***************************/

// stream load
#ifdef NPY_HAVE_SSE41
    #define npyv__loads(PTR) _mm_stream_load_si128((__m128i *)(PTR))
#else
    #define npyv__loads(PTR) _mm_load_si128((const __m128i *)(PTR))
#endif

// 定义 SSE 内存操作的模板宏,参数为数据类型 CTYPE 和后缀 SFX
#define NPYV_IMPL_SSE_MEM_INT(CTYPE, SFX)                                    \
    // 加载未对齐的数据并转换为 SSE 寄存器格式
    NPY_FINLINE npyv_##SFX npyv_load_##SFX(const CTYPE *ptr)                 \
    { return _mm_loadu_si128((const __m128i*)ptr); }                         \
    // 加载对齐的数据并转换为 SSE 寄存器格式
    NPY_FINLINE npyv_##SFX npyv_loada_##SFX(const CTYPE *ptr)                \
    { return _mm_load_si128((const __m128i*)ptr); }                          \
    // 使用 stream 方式加载数据,根据是否支持 SSE4.1 决定具体实现
    NPY_FINLINE npyv_##SFX npyv_loads_##SFX(const CTYPE *ptr)                \
    { return npyv__loads(ptr); }                                             \
    // 加载 64 位数据的低位部分并转换为 SSE 寄存器格式
    NPY_FINLINE npyv_##SFX npyv_loadl_##SFX(const CTYPE *ptr)                \
    { return _mm_loadl_epi64((const __m128i*)ptr); }                         \
    // 存储 SSE 寄存器数据到未对齐的内存位置
    NPY_FINLINE void npyv_store_##SFX(CTYPE *ptr, npyv_##SFX vec)            \
    { _mm_storeu_si128((__m128i*)ptr, vec); }                                \
    // 存储 SSE 寄存器数据到对齐的内存位置
    NPY_FINLINE void npyv_storea_##SFX(CTYPE *ptr, npyv_##SFX vec)           \
    { _mm_store_si128((__m128i*)ptr, vec); }                                 \
    // 使用 stream 方式存储 SSE 寄存器数据到内存位置
    NPY_FINLINE void npyv_stores_##SFX(CTYPE *ptr, npyv_##SFX vec)           \
    { _mm_stream_si128((__m128i*)ptr, vec); }                                \
    // 存储 SSE 寄存器数据的低位部分到内存位置
    NPY_FINLINE void npyv_storel_##SFX(CTYPE *ptr, npyv_##SFX vec)           \
    { _mm_storel_epi64((__m128i *)ptr, vec); }                               \
    // 存储 SSE 寄存器数据的高位部分到内存位置,使用 _mm_unpackhi_epi64 实现
    NPY_FINLINE void npyv_storeh_##SFX(CTYPE *ptr, npyv_##SFX vec)           \
    { _mm_storel_epi64((__m128i *)ptr, _mm_unpackhi_epi64(vec, vec)); }

// 各种数据类型的 SSE 内存操作宏的具体实现
NPYV_IMPL_SSE_MEM_INT(npy_uint8,  u8)
NPYV_IMPL_SSE_MEM_INT(npy_int8,   s8)
NPYV_IMPL_SSE_MEM_INT(npy_uint16, u16)
NPYV_IMPL_SSE_MEM_INT(npy_int16,  s16)
NPYV_IMPL_SSE_MEM_INT(npy_uint32, u32)
NPYV_IMPL_SSE_MEM_INT(npy_int32,  s32)
NPYV_IMPL_SSE_MEM_INT(npy_uint64, u64)
NPYV_IMPL_SSE_MEM_INT(npy_int64,  s64)

// unaligned load
#define npyv_load_f32 _mm_loadu_ps
#define npyv_load_f64 _mm_loadu_pd
// aligned load
#define npyv_loada_f32 _mm_load_ps
#define npyv_loada_f64 _mm_load_pd
// load lower part
// 加载浮点数低位部分并转换为 SSE 寄存器格式,使用 _mm_castsi128_ps 转换为 __m128 类型
#define npyv_loadl_f32(PTR) _mm_castsi128_ps(npyv_loadl_u32((const npy_uint32*)(PTR)))
#define npyv_loadl_f64(PTR) _mm_castsi128_pd(npyv_loadl_u32((const npy_uint32*)(PTR)))
// stream load
// 使用 stream 方式加载浮点数并转换为 SSE 寄存器格式,使用 _mm_castsi128_ps 转换为 __m128 类型
#define npyv_loads_f32(PTR) _mm_castsi128_ps(npyv__loads(PTR))
#define npyv_loads_f64(PTR) _mm_castsi128_pd(npyv__loads(PTR))
// unaligned store
#define npyv_store_f32 _mm_storeu_ps
#define npyv_store_f64 _mm_storeu_pd
// aligned store
#define npyv_storea_f32 _mm_store_ps
#define npyv_storea_f64 _mm_store_pd
// stream store
#define npyv_stores_f32 _mm_stream_ps
#define npyv_stores_f64 _mm_stream_pd

#endif // _NPY_SIMD_SSE_MEMORY_H
// 存储向量低部分为 32 位整数
#define npyv_storel_f32(PTR, VEC) _mm_storel_epi64((__m128i*)(PTR), _mm_castps_si128(VEC));

// 存储向量低部分为 64 位双精度浮点数
#define npyv_storel_f64(PTR, VEC) _mm_storel_epi64((__m128i*)(PTR), _mm_castpd_si128(VEC));

// 存储向量高部分为 32 位单精度浮点数
#define npyv_storeh_f32(PTR, VEC) npyv_storeh_u32((npy_uint32*)(PTR), _mm_castps_si128(VEC))

// 存储向量高部分为 64 位双精度浮点数
#define npyv_storeh_f64(PTR, VEC) npyv_storeh_u32((npy_uint32*)(PTR), _mm_castpd_si128(VEC))

/***************************
 * 非连续加载
 ***************************/

//// 32 位整数加载
NPY_FINLINE npyv_s32 npyv_loadn_s32(const npy_int32 *ptr, npy_intp stride)
{
    // 将首地址的整数加载到 xmm 寄存器中
    __m128i a = _mm_cvtsi32_si128(*ptr);
#ifdef NPY_HAVE_SSE41
    // 使用 SSE4.1 插入指令加载后续整数到 xmm 寄存器
    a = _mm_insert_epi32(a, ptr[stride],   1);
    a = _mm_insert_epi32(a, ptr[stride*2], 2);
    a = _mm_insert_epi32(a, ptr[stride*3], 3);
#else
    // 使用非 SSE4.1 插入方法加载后续整数到 xmm 寄存器
    __m128i a1 = _mm_cvtsi32_si128(ptr[stride]);
    __m128i a2 = _mm_cvtsi32_si128(ptr[stride*2]);
    __m128i a3 = _mm_cvtsi32_si128(ptr[stride*3]);
    a = _mm_unpacklo_epi32(a, a1);
    a = _mm_unpacklo_epi64(a, _mm_unpacklo_epi32(a2, a3));
#endif
    return a;
}

// 无符号 32 位整数加载,实际调用有符号加载函数
NPY_FINLINE npyv_u32 npyv_loadn_u32(const npy_uint32 *ptr, npy_intp stride)
{ return npyv_loadn_s32((const npy_int32*)ptr, stride); }

// 单精度浮点数加载,转换整数加载函数返回结果为浮点数
NPY_FINLINE npyv_f32 npyv_loadn_f32(const float *ptr, npy_intp stride)
{ return _mm_castsi128_ps(npyv_loadn_s32((const npy_int32*)ptr, stride)); }

//// 64 位双精度浮点数加载
NPY_FINLINE npyv_f64 npyv_loadn_f64(const double *ptr, npy_intp stride)
{ return _mm_loadh_pd(npyv_loadl_f64(ptr), ptr + stride); }

// 无符号 64 位整数加载,实际调用双精度加载函数
NPY_FINLINE npyv_u64 npyv_loadn_u64(const npy_uint64 *ptr, npy_intp stride)
{ return _mm_castpd_si128(npyv_loadn_f64((const double*)ptr, stride)); }

// 有符号 64 位整数加载,实际调用双精度加载函数
NPY_FINLINE npyv_s64 npyv_loadn_s64(const npy_int64 *ptr, npy_intp stride)
{ return _mm_castpd_si128(npyv_loadn_f64((const double*)ptr, stride)); }

//// 64 位加载,步长为 32 位整数
NPY_FINLINE npyv_f32 npyv_loadn2_f32(const float *ptr, npy_intp stride)
{
    // 加载低部分双精度浮点数到 xmm 寄存器
    __m128d r = _mm_loadh_pd(
        npyv_loadl_f64((const double*)ptr), (const double*)(ptr + stride)
    );
    return _mm_castpd_ps(r);  // 转换为单精度浮点数返回
}

// 无符号 32 位整数加载,实际调用单精度加载函数
NPY_FINLINE npyv_u32 npyv_loadn2_u32(const npy_uint32 *ptr, npy_intp stride)
{ return _mm_castps_si128(npyv_loadn2_f32((const float*)ptr, stride)); }

// 有符号 32 位整数加载,实际调用单精度加载函数
NPY_FINLINE npyv_s32 npyv_loadn2_s32(const npy_int32 *ptr, npy_intp stride)
{ return _mm_castps_si128(npyv_loadn2_f32((const float*)ptr, stride)); }

//// 128 位加载,步长为 64 位双精度浮点数
NPY_FINLINE npyv_f64 npyv_loadn2_f64(const double *ptr, npy_intp stride)
{ (void)stride; return npyv_load_f64(ptr); }  // 直接加载双精度浮点数

// 无符号 64 位整数加载,实际调用双精度加载函数
NPY_FINLINE npyv_u64 npyv_loadn2_u64(const npy_uint64 *ptr, npy_intp stride)
{ (void)stride; return npyv_load_u64(ptr); }

// 有符号 64 位整数加载,实际调用双精度加载函数
NPY_FINLINE npyv_s64 npyv_loadn2_s64(const npy_int64 *ptr, npy_intp stride)
{ (void)stride; return npyv_load_s64(ptr); }

/***************************
 * 非连续存储
 ***************************/

//// 32 位整数存储
NPY_FINLINE void npyv_storen_s32(npy_int32 *ptr, npy_intp stride, npyv_s32 a)
{
    // 存储 xmm 寄存器中整数的低部分到目标地址
    ptr[stride * 0] = _mm_cvtsi128_si32(a);
#ifdef NPY_HAVE_SSE41
    # 将寄存器 `a` 中的第 1 个整数提取并存储到指针数组 `ptr` 的指定位置
    ptr[stride * 1] = _mm_extract_epi32(a, 1);
    # 将寄存器 `a` 中的第 2 个整数提取并存储到指针数组 `ptr` 的指定位置
    ptr[stride * 2] = _mm_extract_epi32(a, 2);
    # 将寄存器 `a` 中的第 3 个整数提取并存储到指针数组 `ptr` 的指定位置
    ptr[stride * 3] = _mm_extract_epi32(a, 3);
//// 64
NPY_FINLINE void npyv_storen_f64(double *ptr, npy_intp stride, npyv_f64 a)
{
    // 使用 SSE2 指令将双精度浮点数向量 a 存储到 ptr 和 ptr + stride 处
    _mm_storel_pd(ptr, a);  // 将向量 a 的低64位存储到 ptr
    _mm_storeh_pd(ptr + stride, a);  // 将向量 a 的高64位存储到 ptr + stride
}

//// 64-bit store over 32-bit stride
NPY_FINLINE void npyv_storen2_u32(npy_uint32 *ptr, npy_intp stride, npyv_u32 a)
{
    // 使用 SSE2 指令将32位无符号整数向量 a 存储到 ptr 和 ptr + stride 处
    _mm_storel_pd((double*)ptr, _mm_castsi128_pd(a));  // 将向量 a 转换为双精度浮点数后存储到 ptr
    _mm_storeh_pd((double*)(ptr + stride), _mm_castsi128_pd(a));  // 将向量 a 转换为双精度浮点数后存储到 ptr + stride
}

/*********************************
 * Partial Load
 *********************************/
//// 32
NPY_FINLINE npyv_s32 npyv_load_till_s32(const npy_int32 *ptr, npy_uintp nlane, npy_int32 fill)
{
    assert(nlane > 0);  // 断言 nlane 大于 0,确保加载的长度有效
    #ifndef NPY_HAVE_SSE41
        const short *wptr = (const short*)ptr;  // 如果没有 SSE4.1 支持,将 ptr 视为 short 指针
    #endif
    const __m128i vfill = npyv_setall_s32(fill);  // 使用 SSE2 指令生成填充值 fill 的向量 vfill
    __m128i a;
    switch(nlane) {
        case 2:
            a = _mm_castpd_si128(
                _mm_loadl_pd(_mm_castsi128_pd(vfill), (double*)ptr)
            );
            break;
    #ifdef NPY_HAVE_SSE41
        case 1:
            a = _mm_insert_epi32(vfill, ptr[0], 0);  // 使用 SSE4.1 指令在 vfill 中插入第一个整数值
            break;
        case 3:
            a = _mm_loadl_epi64((const __m128i*)ptr);  // 使用 SSE2 指令加载 ptr 所指向的64位数据到向量 a
            a = _mm_insert_epi32(a, ptr[2], 2);  // 在向量 a 中的第2个位置插入 ptr[2] 的值
            a = _mm_insert_epi32(a, fill, 3);  // 在向量 a 中的第3个位置插入 fill 的值
            break;
    #else
        case 1:
            a = _mm_insert_epi16(vfill, wptr[0], 0);  // 使用 SSE2 指令在 vfill 中插入第一个短整数值
    a = _mm_insert_epi16(a, wptr[1], 1);
    # 在__m128i类型变量a中的索引1位置插入wptr数组的第2个元素,返回结果赋给a

    break;
    # 跳出当前循环或者switch语句的执行,结束当前的case分支

    case 3:
        a = _mm_loadl_epi64((const __m128i*)ptr);
        # 将ptr指向的内存中的64位数据加载到a中的低64位,高位填充为0
        a = _mm_unpacklo_epi64(a, vfill);
        # 将a中的64位数据与vfill中的数据进行交错组合,返回结果赋给a
        a = _mm_insert_epi16(a, wptr[4], 4);
        # 在a中的索引4位置插入wptr数组的第5个元素,返回结果赋给a
        a = _mm_insert_epi16(a, wptr[5], 5);
        # 在a中的索引5位置插入wptr数组的第6个元素,返回结果赋给a
        break;
    # 结束当前case分支的执行

#endif // NPY_HAVE_SSE41
    default:
        return npyv_load_s32(ptr);
    # 如果没有满足case条件的情况,返回调用npyv_load_s32(ptr)的结果,作为默认操作

#if NPY_SIMD_GUARD_PARTIAL_LOAD
    // We use a variable marked 'volatile' to convince the compiler that
    // the entire vector is needed.
    volatile __m128i workaround = a;
    # 使用一个标记为'volatile'的变量workaround来告知编译器整个向量a是必需的
    // avoid optimizing it out
    a = _mm_or_si128(workaround, a);
    # 将workaround和a进行按位或操作,结果存储回a,以确保a不被优化掉
#endif
    return a;
    # 返回变量a作为函数的结果
// 在非常量数组指针ptr指向的地址上,根据整型元素读取数据,直到填充nlane数量的32位整型数据
NPY_FINLINE npyv_s32
npyv_loadn_till_s32(const npy_int32 *ptr, npy_intp stride, npy_uintp nlane, npy_int32 fill)
{
    // 断言保证加载的元素数量大于0
    assert(nlane > 0);
    // 使用指定的32位整数填充创建一个__m128i类型的向量vfill
    __m128i vfill = npyv_setall_s32(fill);
    // 如果不支持SSE4.1指令集
    #ifndef NPY_HAVE_SSE41
        // 将ptr转换为short型指针wptr
        const short *wptr = (const short*)ptr;
    #endif
    // 根据nlane的数量进行switch选择
    switch(nlane) {


这段代码的主要作用是根据传入的指针和参数,加载一定数量的32位整数数据到SSE向量中,支持非连续的部分加载。
    #ifdef NPY_HAVE_SSE41
        // 如果定义了 NPY_HAVE_SSE41 宏,则执行以下代码块
        case 3:
            // 将 ptr[stride*2] 插入到 vfill 的第 2 个位置
            vfill = _mm_insert_epi32(vfill, ptr[stride*2], 2);
        case 2:
            // 将 ptr[stride] 插入到 vfill 的第 1 个位置
            vfill = _mm_insert_epi32(vfill, ptr[stride], 1);
        case 1:
            // 将 ptr[0] 插入到 vfill 的第 0 个位置
            vfill = _mm_insert_epi32(vfill, ptr[0], 0);
            // 跳出 switch 语句
            break;
    #else
        // 如果未定义 NPY_HAVE_SSE41 宏,则执行以下代码块
        case 3:
            // 将 ptr[stride*2] 和 vfill 进行低位展开,组成新的 vfill
            vfill = _mm_unpacklo_epi32(_mm_cvtsi32_si128(ptr[stride*2]), vfill);
        case 2:
            // 将 ptr[0] 和 ptr[stride] 以及当前的 vfill 进行展开操作,组成新的 vfill
            vfill = _mm_unpacklo_epi64(_mm_unpacklo_epi32(
                _mm_cvtsi32_si128(*ptr), _mm_cvtsi32_si128(ptr[stride])
            ), vfill);
            // 跳出 switch 语句
            break;
        case 1:
            // 将 wptr[0] 插入到 vfill 的第 0 个位置
            vfill = _mm_insert_epi16(vfill, wptr[0], 0);
            // 将 wptr[1] 插入到 vfill 的第 1 个位置
            vfill = _mm_insert_epi16(vfill, wptr[1], 1);
            // 跳出 switch 语句
            break;
    #endif // NPY_HAVE_SSE41
    // 如果不匹配上述任何 case,执行默认情况
    default:
        // 调用 npyv_loadn_s32 函数加载 ptr 和 stride 所指示的数据
        return npyv_loadn_s32(ptr, stride);
    } // switch 结束
#if NPY_SIMD_GUARD_PARTIAL_LOAD
    // 如果定义了 NPY_SIMD_GUARD_PARTIAL_LOAD 宏,则执行以下代码块
    volatile __m128i workaround = vfill;
    // 创建一个 volatile 的 __m128i 变量 workaround,用 vfill 初始化它
    vfill = _mm_or_si128(workaround, vfill);
    // 使用逻辑或操作符将 workaround 和 vfill 合并,并将结果赋给 vfill
#endif
    // 返回 vfill 变量的值
    return vfill;
}
// 填充剩余的通道为零
NPY_FINLINE npyv_s32
npyv_loadn_tillz_s32(const npy_int32 *ptr, npy_intp stride, npy_uintp nlane)
{
    assert(nlane > 0);
    // 断言 nlane 大于 0
    switch(nlane) {
    case 1:
        // 当 nlane 为 1 时执行以下代码块
        return _mm_cvtsi32_si128(ptr[0]);
        // 使用 ptr[0] 创建一个 __m128i 类型的变量并返回
    case 2:;
        // 当 nlane 为 2 时执行以下代码块
        {
            // 创建一个局部的 npyv_s32 类型变量 a,并用 ptr[0] 初始化它
            npyv_s32 a = _mm_cvtsi32_si128(ptr[0]);
    #ifdef NPY_HAVE_SSE41
            // 如果定义了 NPY_HAVE_SSE41 宏,则执行以下代码块
            return _mm_insert_epi32(a, ptr[stride], 1);
            // 使用 _mm_insert_epi32 在 a 的第二个位置插入 ptr[stride],并返回结果
    #else
            // 如果未定义 NPY_HAVE_SSE41 宏,则执行以下代码块
            return _mm_unpacklo_epi32(a, _mm_cvtsi32_si128(ptr[stride]));
            // 使用 _mm_unpacklo_epi32 将 a 和 ptr[stride] 的数据组合,并返回结果
    #endif // NPY_HAVE_SSE41
        }
    case 3:
        // 当 nlane 为 3 时执行以下代码块
        {
            // 创建一个局部的 npyv_s32 类型变量 a,并用 ptr[0] 初始化它
            npyv_s32 a = _mm_cvtsi32_si128(ptr[0]);
    #ifdef NPY_HAVE_SSE41
            // 如果定义了 NPY_HAVE_SSE41 宏,则执行以下代码块
            a = _mm_insert_epi32(a, ptr[stride], 1);
            // 使用 _mm_insert_epi32 在 a 的第二个位置插入 ptr[stride]
            a = _mm_insert_epi32(a, ptr[stride*2], 2);
            // 使用 _mm_insert_epi32 在 a 的第三个位置插入 ptr[stride*2]
            return a;
            // 返回已经填充好数据的 a
    #else
            // 如果未定义 NPY_HAVE_SSE41 宏,则执行以下代码块
            a = _mm_unpacklo_epi32(a, _mm_cvtsi32_si128(ptr[stride]));
            // 使用 _mm_unpacklo_epi32 将 a 和 ptr[stride] 的数据组合
            a = _mm_unpacklo_epi64(a, _mm_cvtsi32_si128(ptr[stride*2]));
            // 使用 _mm_unpacklo_epi64 将 a 和 ptr[stride*2] 的数据组合
            return a;
            // 返回已经填充好数据的 a
    #endif // NPY_HAVE_SSE41
        }
    default:
        // 默认情况下
        return npyv_loadn_s32(ptr, stride);
        // 调用 npyv_loadn_s32 函数并返回结果
    }
}

//// 64
NPY_FINLINE npyv_s64
npyv_loadn_till_s64(const npy_int64 *ptr, npy_intp stride, npy_uintp nlane, npy_int64 fill)
{
    assert(nlane > 0);
    // 断言 nlane 大于 0
    if (nlane == 1) {
        // 如果 nlane 等于 1,则执行以下代码块
        return npyv_load_till_s64(ptr, 1, fill);
        // 调用 npyv_load_till_s64 函数并返回结果
    }
    return npyv_loadn_s64(ptr, stride);
    // 调用 npyv_loadn_s64 函数并返回结果
}
// 填充剩余的通道为零
NPY_FINLINE npyv_s64 npyv_loadn_tillz_s64(const npy_int64 *ptr, npy_intp stride, npy_uintp nlane)
{
    assert(nlane > 0);
    // 断言 nlane 大于 0
    if (nlane == 1) {
        // 如果 nlane 等于 1,则执行以下代码块
        return _mm_loadl_epi64((const __m128i*)ptr);
        // 使用 _mm_loadl_epi64 加载 ptr 所指向的数据,并返回结果
    }
    return npyv_loadn_s64(ptr, stride);
    // 调用 npyv_loadn_s64 函数并返回结果
}

//// 64-bit load over 32-bit stride
NPY_FINLINE npyv_s32 npyv_loadn2_till_s32(const npy_int32 *ptr, npy_intp stride, npy_uintp nlane,
                                                 npy_int32 fill_lo, npy_int32 fill_hi)
{
    assert(nlane > 0);
    // 断言 nlane 大于 0
    if (nlane == 1) {
        // 如果 nlane 等于 1,则执行以下代码块
        const __m128i vfill = npyv_set_s32(0, 0, fill_lo, fill_hi);
        // 使用 npyv_set_s32 函数创建一个 __m128i 类型的 vfill 变量
        __m128i a = _mm_castpd_si128(
            _mm_loadl_pd(_mm_castsi128_pd(vfill), (double*)ptr)
        );
        // 使用 _mm_loadl_pd 和 _mm_castpd_si128 加载数据到 a 变量
    #if NPY_SIMD_GUARD_PARTIAL_LOAD
        // 如果定义了 NPY_SIMD_GUARD_PARTIAL_LOAD 宏,则执行以下代码块
        volatile __m128i workaround = a;
        // 创建一个 volatile 的 __m128i 变量 workaround,用 a 初始化它
        a = _mm_or_si128(workaround, a);
        // 使用逻辑或操作符将 workaround 和 a 合并,并将结果赋给 a
    #endif
        // 返回 a 变量的值
        return a;
    }
    return npyv_loadn2_s32(ptr, stride);
    // 调用 npyv_loadn2_s32 函数并返回结果
}
NPY_FINLINE npyv_s32 npyv_loadn2_tillz_s32(const npy_int32 *ptr, npy_intp stride, npy_uintp nlane)
{
    assert(nlane > 0);
    // 断言 nlane 大于 0
    if (nlane == 1) {
        // 如果 nlane 等于 1,则执行以下代码块
        return _mm_loadl_epi64((const __m128i*)ptr);
        // 使用 _mm_loadl_epi64 加载 ptr 所指向的数据,并返回结果
    }
    return npyv_loadn2_s32(ptr, stride);
    // 调用 npyv_loadn2_s32 函数并返回结果
}

//// 128-bit load over 64-bit stride
NPY_FINLINE npyv_s64 npyv_loadn2_till_s64(const npy_int64 *ptr, npy_intp stride, npy_uintp nlane,
                                                  npy_int64 fill_lo, npy_int64 fill_hi)
{ assert(nlane > 0); (void)stride; (void)nlane; (void)fill_lo; (void)fill_hi; return npyv_load_s64(ptr); }
// 断言 nlane 大于 0,并调用 npyv_load_s64 函数并返回结果
//// 32
NPY_FINLINE void npyv_store_till_s32(npy_int32 *ptr, npy_uintp nlane, npyv_s32 a)
{
    // 确保 nlane 大于 0,即至少有一个元素需要存储
    assert(nlane > 0);
    
    // 根据 nlane 的值选择不同的存储方式
    switch(nlane) {
    case 1:
        // 当 nlane 为 1 时,将 a 的低位 32 位存储到 ptr 指向的位置
        *ptr = _mm_cvtsi128_si32(a);
        break;
    case 2:
        // 当 nlane 为 2 时,将 a 的低位 64 位存储到 ptr 指向的位置
        _mm_storel_epi64((__m128i *)ptr, a);
        break;
    case 3:
        // 当 nlane 为 3 时,将 a 的低位 64 位存储到 ptr 指向的位置
        _mm_storel_epi64((__m128i *)ptr, a);
    #ifdef NPY_HAVE_SSE41
        // 如果支持 SSE4.1,则额外将 a 的第三个 32 位整数存储到 ptr 指向的位置
        ptr[2] = _mm_extract_epi32(a, 2);
    #else
        // 如果不支持 SSE4.1,则通过重新排列获取第三个 32 位整数并存储到 ptr 指向的位置
        ptr[2] = _mm_cvtsi128_si32(_mm_shuffle_epi32(a, _MM_SHUFFLE(0, 0, 0, 2)));
    #endif
        break;
    default:
        // 对于其他情况,调用通用的存储函数 npyv_store_s32 将 a 中的所有数据存储到 ptr 指向的位置
        npyv_store_s32(ptr, a);
    }
}

//// 64
NPY_FINLINE void npyv_store_till_s64(npy_int64 *ptr, npy_uintp nlane, npyv_s64 a)
{
    // 确保 nlane 大于 0,即至少有一个元素需要存储
    assert(nlane > 0);
    
    // 当 nlane 为 1 时,将 a 的低位 64 位存储到 ptr 指向的位置
    if (nlane == 1) {
        _mm_storel_epi64((__m128i *)ptr, a);
        return;
    }
    
    // 对于其他情况,调用通用的存储函数 npyv_store_s64 将 a 中的所有数据存储到 ptr 指向的位置
    npyv_store_s64(ptr, a);
}

//// 64-bit nlane
NPY_FINLINE void npyv_store2_till_s32(npy_int32 *ptr, npy_uintp nlane, npyv_s32 a)
{
    // 确保 nlane 大于 0,即至少有一个元素需要存储
    assert(nlane > 0);
    // 调用 npyv_store_till_s64 将 a 中的数据存储到 ptr 指向的位置
    npyv_store_till_s64((npy_int64*)ptr, nlane, a);
}

//// 128-bit nlane
NPY_FINLINE void npyv_store2_till_s64(npy_int64 *ptr, npy_uintp nlane, npyv_s64 a)
{
    // 确保 nlane 大于 0,即至少有一个元素需要存储
    assert(nlane > 0);
    // 调用通用的存储函数 npyv_store_s64 将 a 中的所有数据存储到 ptr 指向的位置
    npyv_store_s64(ptr, a);
}

/*********************************
 * Non-contiguous partial store
 *********************************/
//// 32
NPY_FINLINE void npyv_storen_till_s32(npy_int32 *ptr, npy_intp stride, npy_uintp nlane, npyv_s32 a)
{
    // 确保 nlane 大于 0,即至少有一个元素需要存储
    assert(nlane > 0);
    
    // 将 a 的低位 32 位整数存储到 ptr 指向的位置(根据 stride 和索引计算存储位置)
    ptr[stride*0] = _mm_cvtsi128_si32(a);
    
    // 根据 nlane 的值选择不同的存储方式
    switch(nlane) {
    case 1:
        return;
#ifdef NPY_HAVE_SSE41
    case 2:
        // 如果支持 SSE4.1,则将 a 的第二个 32 位整数存储到 ptr 指向的位置
        ptr[stride*1] = _mm_extract_epi32(a, 1);
        return;
    case 3:
        // 如果支持 SSE4.1,则将 a 的第二和第三个 32 位整数存储到 ptr 指向的位置
        ptr[stride*1] = _mm_extract_epi32(a, 1);
        ptr[stride*2] = _mm_extract_epi32(a, 2);
        return;
    default:
        // 如果支持 SSE4.1,则将 a 的第二到第四个 32 位整数存储到 ptr 指向的位置
        ptr[stride*1] = _mm_extract_epi32(a, 1);
        ptr[stride*2] = _mm_extract_epi32(a, 2);
        ptr[stride*3] = _mm_extract_epi32(a, 3);
#else
    case 2:
        // 如果不支持 SSE4.1,则通过重新排列获取第二个 32 位整数并存储到 ptr 指向的位置
        ptr[stride*1] = _mm_cvtsi128_si32(_mm_shuffle_epi32(a, _MM_SHUFFLE(0, 0, 0, 1)));
        return;
    case 3:
        // 如果不支持 SSE4.1,则通过重新排列获取第二和第三个 32 位整数并存储到 ptr 指向的位置
        ptr[stride*1] = _mm_cvtsi128_si32(_mm_shuffle_epi32(a, _MM_SHUFFLE(0, 0, 0, 1)));
        ptr[stride*2] = _mm_cvtsi128_si32(_mm_shuffle_epi32(a, _MM_SHUFFLE(0, 0, 0, 2)));
        return;
    default:
        // 如果不支持 SSE4.1,则通过重新排列获取第二到第四个 32 位整数并存储到 ptr 指向的位置
        ptr[stride*1] = _mm_cvtsi128_si32(_mm_shuffle_epi32(a, _MM_SHUFFLE(0, 0, 0, 1)));
        ptr[stride*2] = _mm_cvtsi128_si32(_mm_shuffle_epi32(a, _MM_SHUFFLE(0, 0, 0, 2)));
        ptr[stride*3] = _mm_cvtsi128_si32(_mm_shuffle_epi32(a, _MM_SHUFFLE(0, 0, 0, 3)));
#endif
    }
}

//// 64
NPY_FINLINE void npyv_storen_till_s64(npy_int64 *ptr, npy_intp stride, npy_uintp nlane, npyv_s64 a)
{
    // 确保 nlane 大于 0,即至少有一个元素需要存储
    assert(nlane > 0);
    
    // 当 nlane 为 1 时,将 a 的低位 64 位存储到 ptr 指向的位置
    if (nlane == 1) {
        _mm_storel_epi64((__m128i *)ptr, a);
        return;
    }
    
    // 调用通用的存储函数 npyv_storen_s64 将 a 中的所有数据按照指定的 stride 存储到 ptr 指向的位置
    npyv_storen_s64(ptr, stride, a);
}
//// 64-bit store over 32-bit stride
// 定义了一个函数 npyv_storen2_till_s32,用于将 64 位整数存储到 32 位步长位置
NPY_FINLINE void npyv_storen2_till_s32(npy_int32 *ptr, npy_intp stride, npy_uintp nlane, npyv_s32 a)
{
    // 断言确保 nlane 大于 0
    assert(nlane > 0);
    // 将向量 a 的低位存储到 ptr 指向的位置
    npyv_storel_s32(ptr, a);
    // 如果 nlane 大于 1,则将向量 a 的高位存储到 ptr + stride 指向的位置
    if (nlane > 1) {
        npyv_storeh_s32(ptr + stride, a);
    }
}

//// 128-bit store over 64-bit stride
// 定义了一个函数 npyv_storen2_till_s64,用于将 128 位整数存储到 64 位步长位置
NPY_FINLINE void npyv_storen2_till_s64(npy_int64 *ptr, npy_intp stride, npy_uintp nlane, npyv_s64 a)
{
    // 断言确保 nlane 大于 0
    assert(nlane > 0);
    // 忽略 stride 和 nlane 的值,将向量 a 存储到 ptr 指向的位置
    (void)stride; (void)nlane; npyv_store_s64(ptr, a);
}

/*****************************************************************
 * Implement partial load/store for u32/f32/u64/f64... via casting
 *****************************************************************/
// 定义了一系列宏,实现了通过类型转换来进行部分加载/存储操作,支持 u32/f32/u64/f64 等类型

#define NPYV_IMPL_SSE_REST_PARTIAL_TYPES(F_SFX, T_SFX)                                      \
    // 实现了加载函数 npyv_load_till_##F_SFX,用于部分加载 F_SFX 类型数据
    NPY_FINLINE npyv_##F_SFX npyv_load_till_##F_SFX                                         \
    (const npyv_lanetype_##F_SFX *ptr, npy_uintp nlane, npyv_lanetype_##F_SFX fill)         \
    {                                                                                       \
        // 定义一个联合体 pun,用于将 fill 转换成目标类型 T_SFX
        union {                                                                             \
            npyv_lanetype_##F_SFX from_##F_SFX;                                             \
            npyv_lanetype_##T_SFX to_##T_SFX;                                               \
        } pun;                                                                              \
        pun.from_##F_SFX = fill;                                                            \
        // 返回将转换后的填充值 pun.to_##T_SFX 传递给 npyv_load_till_##T_SFX 函数的结果
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_load_till_##T_SFX(                   \
            (const npyv_lanetype_##T_SFX *)ptr, nlane, pun.to_##T_SFX                       \
        ));                                                                                 \
    }                                                                                       \
    // 实现了加载函数 npyv_loadn_till_##F_SFX,用于部分加载 F_SFX 类型数据,支持步长操作
    NPY_FINLINE npyv_##F_SFX npyv_loadn_till_##F_SFX                                        \
    (const npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane,                    \
     npyv_lanetype_##F_SFX fill)                                                            \
    {                                                                                       \
        union {                                                                             \
            npyv_lanetype_##F_SFX from_##F_SFX;                                             \
            npyv_lanetype_##T_SFX to_##T_SFX;                                               \
        } pun;                                                                              \
        pun.from_##F_SFX = fill;                                                            \
        // 使用联合体 pun 将 fill 转换为 from_##F_SFX 类型的数据
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_loadn_till_##T_SFX(                  \
            (const npyv_lanetype_##T_SFX *)ptr, stride, nlane, pun.to_##T_SFX               \
        ));                                                                                 \
    }                                                                                       \
    // 以非常规方式加载 F_SFX 类型的向量,直接从指针 ptr 中读取 nlane 个元素
    NPY_FINLINE npyv_##F_SFX npyv_load_tillz_##F_SFX                                        \
    (const npyv_lanetype_##F_SFX *ptr, npy_uintp nlane)                                     \
    {                                                                                       \
        // 将加载到的数据重新解释为 T_SFX 类型的向量
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_load_tillz_##T_SFX(                  \
            (const npyv_lanetype_##T_SFX *)ptr, nlane                                       \
        ));                                                                                 \
    }                                                                                       \
    // 以非常规方式加载 F_SFX 类型的向量,并且在末尾填充零值
    NPY_FINLINE npyv_##F_SFX npyv_loadn_tillz_##F_SFX                                       \
    (const npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane)                    \
    {                                                                                       \
        // 将加载到的数据重新解释为 T_SFX 类型的向量
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_loadn_tillz_##T_SFX(                 \
            (const npyv_lanetype_##T_SFX *)ptr, stride, nlane                               \
        ));                                                                                 \
    }                                                                                       \
    // 以非常规方式存储 F_SFX 类型的向量数据
    NPY_FINLINE void npyv_store_till_##F_SFX                                                \
    (npyv_lanetype_##F_SFX *ptr, npy_uintp nlane, npyv_##F_SFX a)                           \
    {                                                                                       \
        // 将 F_SFX 类型的向量 a 重新解释为 T_SFX 类型后存储到 ptr 指向的内存中
        npyv_store_till_##T_SFX(                                                            \
            (npyv_lanetype_##T_SFX *)ptr, nlane,                                            \
            npyv_reinterpret_##T_SFX##_##F_SFX(a)                                           \
        );                                                                                  \

        npyv_store_till_##F_SFX  函数的说明如上ultimate
    }                                                                                       \
    // 定义 NPY_FINLINE 宏展开后的函数 npyv_storen_till_##F_SFX
    NPY_FINLINE void npyv_storen_till_##F_SFX                                               \
    // 函数签名:将 npyv_lanetype_##F_SFX 类型的向量 a 存储到 ptr 指向的内存中,步长为 stride,处理的向量数为 nlane
    (npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane, npyv_##F_SFX a)          \
    {                                                                                       \
        // 调用宏 npyv_storen_till_##T_SFX 将 a 向量重新解释为 npyv_##T_SFX 类型,然后存储到 ptr 中
        npyv_storen_till_##T_SFX(                                                           \
            (npyv_lanetype_##T_SFX *)ptr, stride, nlane,                                    \
            npyv_reinterpret_##T_SFX##_##F_SFX(a)                                           \
        );                                                                                  \
    }
// 定义宏 NPYV_IMPL_SSE_REST_PARTIAL_TYPES,用于生成特定数据类型和操作类型的函数实现
NPYV_IMPL_SSE_REST_PARTIAL_TYPES(u32, s32)
// 生成 npyv_u32 类型的 SSE 函数实现,处理 s32 类型操作
NPYV_IMPL_SSE_REST_PARTIAL_TYPES(f32, s32)
// 生成 npyv_f32 类型的 SSE 函数实现,处理 s32 类型操作
NPYV_IMPL_SSE_REST_PARTIAL_TYPES(u64, s64)
// 生成 npyv_u64 类型的 SSE 函数实现,处理 s64 类型操作
NPYV_IMPL_SSE_REST_PARTIAL_TYPES(f64, s64)
// 生成 npyv_f64 类型的 SSE 函数实现,处理 s64 类型操作

// 定义宏 NPYV_IMPL_SSE_REST_PARTIAL_TYPES_PAIR,用于生成两种数据类型组合的函数实现
#define NPYV_IMPL_SSE_REST_PARTIAL_TYPES_PAIR(F_SFX, T_SFX)                                 \
    // 声明 npyv_load2_till_##F_SFX 函数,加载指定类型的数据直到指定数量,并填充指定的低位和高位值
    NPY_FINLINE npyv_##F_SFX npyv_load2_till_##F_SFX                                        \
    (const npyv_lanetype_##F_SFX *ptr, npy_uintp nlane,                                     \
     npyv_lanetype_##F_SFX fill_lo, npyv_lanetype_##F_SFX fill_hi)                          \
    {                                                                                       \
        // 定义联合体 pun 用于类型转换
        union pun {                                                                         \
            npyv_lanetype_##F_SFX from_##F_SFX;                                             \
            npyv_lanetype_##T_SFX to_##T_SFX;                                               \
        };                                                                                  \
        // 定义联合体变量 pun_lo 和 pun_hi,分别填充低位和高位的值
        union pun pun_lo;                                                                   \
        union pun pun_hi;                                                                   \
        pun_lo.from_##F_SFX = fill_lo;                                                      \
        pun_hi.from_##F_SFX = fill_hi;                                                      \
        // 返回根据填充值转换后的结果,使用 npyv_load2_till_##T_SFX 函数加载数据
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_load2_till_##T_SFX(                  \
            (const npyv_lanetype_##T_SFX *)ptr, nlane, pun_lo.to_##T_SFX, pun_hi.to_##T_SFX \
        ));                                                                                 \
    }                                                                                       \
    // 声明 npyv_loadn2_till_##F_SFX 函数,加载指定类型的数据直到指定数量,带有步长,并填充指定的低位和高位值
    NPY_FINLINE npyv_##F_SFX npyv_loadn2_till_##F_SFX                                       \
    (const npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane,                    \
     npyv_lanetype_##F_SFX fill_lo, npyv_lanetype_##F_SFX fill_hi)                          \
    {                                                                                       \
        union pun {                                                                         \
            npyv_lanetype_##F_SFX from_##F_SFX;                                             \
            npyv_lanetype_##T_SFX to_##T_SFX;                                               \
        };                                                                                  \
        union pun pun_lo;                                                                   \
        union pun pun_hi;                                                                   \
        pun_lo.from_##F_SFX = fill_lo;                                                      \
        pun_hi.from_##F_SFX = fill_hi;                                                      \
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_loadn2_till_##T_SFX(                 \
            (const npyv_lanetype_##T_SFX *)ptr, stride, nlane, pun_lo.to_##T_SFX,           \
            pun_hi.to_##T_SFX                                                               \
        ));                                                                                 \
    }                                                                                       \

这段代码定义了一个函数,用于加载并重新解释 SIMD 向量数据类型。根据不同的输入类型转换加载,以及指定的填充值。


    NPY_FINLINE npyv_##F_SFX npyv_load2_tillz_##F_SFX                                       \
    (const npyv_lanetype_##F_SFX *ptr, npy_uintp nlane)                                     \
    {                                                                                       \
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_load2_tillz_##T_SFX(                 \
            (const npyv_lanetype_##T_SFX *)ptr, nlane                                       \
        ));                                                                                 \
    }                                                                                       \

这段代码定义了一个函数,用于加载指定数量的 SIMD 向量数据类型并清零剩余部分。


    NPY_FINLINE npyv_##F_SFX npyv_loadn2_tillz_##F_SFX                                      \
    (const npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane)                    \
    {                                                                                       \
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_loadn2_tillz_##T_SFX(                \
            (const npyv_lanetype_##T_SFX *)ptr, stride, nlane                               \
        ));                                                                                 \
    }                                                                                       \

这段代码定义了一个函数,用于加载带有步长的 SIMD 向量数据类型,并清零剩余部分。


    NPY_FINLINE void npyv_store2_till_##F_SFX                                               \
    (npyv_lanetype_##F_SFX *ptr, npy_uintp nlane, npyv_##F_SFX a)                           \

这段代码定义了一个函数,用于存储指定数量的 SIMD 向量数据类型。
    {
        # 调用宏 npyv_store2_till_##T_SFX,用于将向量 a 的数据按类型 T_SFX 解释后存储到指针 ptr 所指向的内存中,处理 nlane 个元素
        npyv_store2_till_##T_SFX(
            (npyv_lanetype_##T_SFX *)ptr, nlane,
            npyv_reinterpret_##T_SFX##_##F_SFX(a)
        );
    
        # 定义内联函数 npyv_storen2_till_##F_SFX,用于将向量 a 的数据按类型 F_SFX 解释后存储到 ptr 指向的内存中,处理步长为 stride,nlane 个元素
        NPY_FINLINE void npyv_storen2_till_##F_SFX
        (npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane, npyv_##F_SFX a)
        {
            # 调用宏 npyv_storen2_till_##T_SFX,将向量 a 的数据按类型 T_SFX 解释后存储到 ptr 指向的内存中,处理步长为 stride,nlane 个元素
            npyv_storen2_till_##T_SFX(
                (npyv_lanetype_##T_SFX *)ptr, stride, nlane,
                npyv_reinterpret_##T_SFX##_##F_SFX(a)
            );
        }
    }
// 定义一个宏,用于生成特定类型的 SIMD 操作函数,实现加载和存储的互相关联
#define NPYV_IMPL_SSE_REST_PARTIAL_TYPES_PAIR(TYPE1, TYPE2) \
    // 实现类型为 TYPE1 和 TYPE2 的 SSE 操作的特定函数

/************************************************************
 *  de-interlave load / interleave contiguous store
 ************************************************************/

// 两个通道的内存交织加载和连续存储

// 定义一个宏,用于实现给定类型的内存交织加载和存储操作
#define NPYV_IMPL_SSE_MEM_INTERLEAVE(SFX, ZSFX) \
    // 内存交织加载操作,将连续存储的数据分别加载到两个向量中
    NPY_FINLINE npyv_##ZSFX##x2 npyv_zip_##ZSFX(npyv_##SFX, npyv_##SFX); \
    // 内存解交织操作,将两个向量的数据合并为一个向量
    NPY_FINLINE npyv_##ZSFX##x2 npyv_unzip_##ZSFX(npyv_##SFX, npyv_##SFX); \
    // 加载两个连续存储的数据块,分别存储到两个向量中
    NPY_FINLINE npyv_##SFX##x2 npyv_load_##SFX##x2( \
        const npyv_lanetype_##SFX *ptr \
    ) { \
        return npyv_unzip_##ZSFX( \
            npyv_load_##SFX(ptr), npyv_load_##SFX(ptr+npyv_nlanes_##SFX) \
        ); \
    } \
    // 将两个向量的数据分别存储到连续存储块中
    NPY_FINLINE void npyv_store_##SFX##x2( \
        npyv_lanetype_##SFX *ptr, npyv_##SFX##x2 v \
    ) { \
        npyv_##SFX##x2 zip = npyv_zip_##ZSFX(v.val[0], v.val[1]); \
        npyv_store_##SFX(ptr, zip.val[0]); \
        npyv_store_##SFX(ptr + npyv_nlanes_##SFX, zip.val[1]); \
    }

// 以下是根据上述宏定义生成的具体类型的内存交织加载和存储操作函数

NPYV_IMPL_SSE_MEM_INTERLEAVE(u8, u8)
NPYV_IMPL_SSE_MEM_INTERLEAVE(s8, u8)
NPYV_IMPL_SSE_MEM_INTERLEAVE(u16, u16)
NPYV_IMPL_SSE_MEM_INTERLEAVE(s16, u16)
NPYV_IMPL_SSE_MEM_INTERLEAVE(u32, u32)
NPYV_IMPL_SSE_MEM_INTERLEAVE(s32, u32)
NPYV_IMPL_SSE_MEM_INTERLEAVE(u64, u64)
NPYV_IMPL_SSE_MEM_INTERLEAVE(s64, u64)
NPYV_IMPL_SSE_MEM_INTERLEAVE(f32, f32)
NPYV_IMPL_SSE_MEM_INTERLEAVE(f64, f64)

/*********************************
 * Lookup table
 *********************************/

// 使用向量作为索引查找包含 32 个 float32 元素的表格

// 返回根据索引 idx 查找的 float32 类型的表格中的值组成的向量
NPY_FINLINE npyv_f32 npyv_lut32_f32(const float *table, npyv_u32 idx)
{
    // 提取 idx 向量的第一个元素作为整数索引 i0
    const int i0 = _mm_cvtsi128_si32(idx);
#ifdef NPY_HAVE_SSE41
    // 使用 SSE4.1 的函数从 idx 向量中提取其他整数索引 i1, i2, i3
    const int i1 = _mm_extract_epi32(idx, 1);
    const int i2 = _mm_extract_epi32(idx, 2);
    const int i3 = _mm_extract_epi32(idx, 3);
#else
    // 使用 SSE2 的函数从 idx 向量中提取其他整数索引 i1, i2, i3
    const int i1 = _mm_extract_epi16(idx, 2);
    const int i2 = _mm_extract_epi16(idx, 4);
    const int i3 = _mm_extract_epi16(idx, 6);
#endif
    // 返回根据索引从表格中取出的四个 float32 值组成的向量
    return npyv_set_f32(table[i0], table[i1], table[i2], table[i3]);
}

// 返回根据索引 idx 查找的 uint32 类型的表格中的值组成的向量
NPY_FINLINE npyv_u32 npyv_lut32_u32(const npy_uint32 *table, npyv_u32 idx)
{ return npyv_reinterpret_u32_f32(npyv_lut32_f32((const float*)table, idx)); }

// 返回根据索引 idx 查找的 int32 类型的表格中的值组成的向量
NPY_FINLINE npyv_s32 npyv_lut32_s32(const npy_int32 *table, npyv_u32 idx)
// 使用给定的索引向表中查找对应的双精度浮点数,返回一个双精度向量
NPY_FINLINE npyv_f64 npyv_lut16_f64(const double *table, npyv_u64 idx)
{
    // 从 idx 中提取第一个索引 i0,并转换为整数
    const int i0 = _mm_cvtsi128_si32(idx);
#ifdef NPY_HAVE_SSE41
    // 如果支持 SSE4.1,则从 idx 中提取第二个索引 i1(32位),否则从 idx 中提取第二个索引 i1(16位)
    const int i1 = _mm_extract_epi32(idx, 2);
#else
    const int i1 = _mm_extract_epi16(idx, 4);
#endif
    // 使用 i0 和 i1 作为索引,从表中获取两个双精度浮点数,并将它们组合成一个双精度向量返回
    return npyv_set_f64(table[i0], table[i1]);
}

// 使用给定的表和索引查找表中的64位无符号整数,并将结果重新解释为双精度浮点数向量返回
NPY_FINLINE npyv_u64 npyv_lut16_u64(const npy_uint64 *table, npyv_u64 idx)
{ return npyv_reinterpret_u64_f64(npyv_lut16_f64((const double*)table, idx)); }

// 使用给定的表和索引查找表中的64位有符号整数,并将结果重新解释为双精度浮点数向量返回
NPY_FINLINE npyv_s64 npyv_lut16_s64(const npy_int64 *table, npyv_u64 idx)
{ return npyv_reinterpret_s64_f64(npyv_lut16_f64((const double*)table, idx)); }