NumPy-源码解析-五十七-

114 阅读1小时+

NumPy 源码解析(五十七)

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

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

#ifndef _NPY_SIMD_SSE_MISC_H
#define _NPY_SIMD_SSE_MISC_H

// 定义一个函数宏,用于创建所有通道为零的128位整数向量
#define npyv_zero_u8  _mm_setzero_si128
#define npyv_zero_s8  _mm_setzero_si128
#define npyv_zero_u16 _mm_setzero_si128
#define npyv_zero_s16 _mm_setzero_si128
#define npyv_zero_u32 _mm_setzero_si128
#define npyv_zero_s32 _mm_setzero_si128
#define npyv_zero_u64 _mm_setzero_si128
#define npyv_zero_s64 _mm_setzero_si128
// 定义一个函数宏,用于创建所有通道为零的128位单精度浮点数向量
#define npyv_zero_f32 _mm_setzero_ps
#define npyv_zero_f64 _mm_setzero_pd

// 定义一个函数宏,用于创建所有通道为指定值的8位整数向量
#define npyv_setall_u8(VAL)  _mm_set1_epi8((char)(VAL))
#define npyv_setall_s8(VAL)  _mm_set1_epi8((char)(VAL))
#define npyv_setall_u16(VAL) _mm_set1_epi16((short)(VAL))
#define npyv_setall_s16(VAL) _mm_set1_epi16((short)(VAL))
#define npyv_setall_u32(VAL) _mm_set1_epi32((int)(VAL))
#define npyv_setall_s32(VAL) _mm_set1_epi32((int)(VAL))
// 定义一个函数宏,用于创建所有通道为指定值的单精度浮点数向量
#define npyv_setall_f32 _mm_set1_ps
#define npyv_setall_f64 _mm_set1_pd

// 定义一个内联函数,设置所有通道为指定64位无符号整数的向量
NPY_FINLINE __m128i npyv__setr_epi64(npy_int64 i0, npy_int64 i1);

// 定义一个函数,创建所有通道为指定64位无符号整数的向量
NPY_FINLINE npyv_u64 npyv_setall_u64(npy_uint64 a)
{
#if defined(_MSC_VER) && defined(_M_IX86)
    return npyv__setr_epi64((npy_int64)a, (npy_int64)a);
#else
    return _mm_set1_epi64x((npy_int64)a);
#endif
}

// 定义一个函数,创建所有通道为指定64位有符号整数的向量
NPY_FINLINE npyv_s64 npyv_setall_s64(npy_int64 a)
{
#if defined(_MSC_VER) && defined(_M_IX86)
    return npyv__setr_epi64(a, a);
#else
    return _mm_set1_epi64x((npy_int64)a);
#endif
}

/**
 * 创建具有特定值的每个通道的向量,并为其余通道设置特定值
 *
 * 由 NPYV__SET_FILL_* 生成的参数,如果 _mm_setr_* 被定义为宏,则不会展开。
 */
NPY_FINLINE __m128i npyv__setr_epi8(
    char i0, char i1, char i2,  char i3,  char i4,  char i5,  char i6,  char i7,
    char i8, char i9, char i10, char i11, char i12, char i13, char i14, char i15)
{
    return _mm_setr_epi8(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15);
}

// 定义一个内联函数,创建具有特定值的每个通道的16位有符号整数向量
NPY_FINLINE __m128i npyv__setr_epi16(short i0, short i1, short i2, short i3, short i4, short i5,
                                     short i6, short i7)
{
    return _mm_setr_epi16(i0, i1, i2, i3, i4, i5, i6, i7);
}

// 定义一个内联函数,创建具有特定值的每个通道的32位有符号整数向量
NPY_FINLINE __m128i npyv__setr_epi32(int i0, int i1, int i2, int i3)
{
    return _mm_setr_epi32(i0, i1, i2, i3);
}

// 定义一个内联函数,创建具有特定值的每个通道的64位有符号整数向量
NPY_FINLINE __m128i npyv__setr_epi64(npy_int64 i0, npy_int64 i1)
{
#if defined(_MSC_VER) && defined(_M_IX86)
    return _mm_setr_epi32((int)i0, (int)(i0 >> 32), (int)i1, (int)(i1 >> 32));
#else
    return _mm_set_epi64x(i1, i0);
#endif
}

// 定义一个内联函数,创建具有特定值的每个通道的32位单精度浮点数向量
NPY_FINLINE __m128 npyv__setr_ps(float i0, float i1, float i2, float i3)
{
    return _mm_setr_ps(i0, i1, i2, i3);
}

// 定义一个内联函数,创建具有特定值的每个通道的64位双精度浮点数向量
NPY_FINLINE __m128d npyv__setr_pd(double i0, double i1)
{
    return _mm_setr_pd(i0, i1);
}

// 定义一个函数宏,创建所有通道为指定填充值的8位整数向量
#define npyv_setf_u8(FILL, ...)  npyv__setr_epi8(NPYV__SET_FILL_16(char, FILL, __VA_ARGS__))
// 定义一个函数宏,创建所有通道为指定填充值的8位整数向量
#define npyv_setf_s8(FILL, ...)  npyv__setr_epi8(NPYV__SET_FILL_16(char, FILL, __VA_ARGS__))

#endif // _NPY_SIMD_SSE_MISC_H
// 定义宏以设置特定数据类型和填充值的向量,并生成适当的函数调用
#define npyv_setf_u16(FILL, ...) npyv__setr_epi16(NPYV__SET_FILL_8(short, FILL, __VA_ARGS__))
#define npyv_setf_s16(FILL, ...) npyv__setr_epi16(NPYV__SET_FILL_8(short, FILL, __VA_ARGS__))
#define npyv_setf_u32(FILL, ...) npyv__setr_epi32(NPYV__SET_FILL_4(int, FILL, __VA_ARGS__))
#define npyv_setf_s32(FILL, ...) npyv__setr_epi32(NPYV__SET_FILL_4(int, FILL, __VA_ARGS__))
#define npyv_setf_u64(FILL, ...) npyv__setr_epi64(NPYV__SET_FILL_2(npy_int64, FILL, __VA_ARGS__))
#define npyv_setf_s64(FILL, ...) npyv__setr_epi64(NPYV__SET_FILL_2(npy_int64, FILL, __VA_ARGS__))
#define npyv_setf_f32(FILL, ...) npyv__setr_ps(NPYV__SET_FILL_4(float, FILL, __VA_ARGS__))
#define npyv_setf_f64(FILL, ...) npyv__setr_pd(NPYV__SET_FILL_2(double, FILL, __VA_ARGS__))

// 定义宏以设置无符号8位整数向量的每个通道,未指定通道使用零填充
#define npyv_set_u8(...)  npyv_setf_u8(0,  __VA_ARGS__)
// 定义宏以设置有符号8位整数向量的每个通道,未指定通道使用零填充
#define npyv_set_s8(...)  npyv_setf_s8(0,  __VA_ARGS__)
// 定义宏以设置无符号16位整数向量的每个通道,未指定通道使用零填充
#define npyv_set_u16(...) npyv_setf_u16(0, __VA_ARGS__)
// 定义宏以设置有符号16位整数向量的每个通道,未指定通道使用零填充
#define npyv_set_s16(...) npyv_setf_s16(0, __VA_ARGS__)
// 定义宏以设置无符号32位整数向量的每个通道,未指定通道使用零填充
#define npyv_set_u32(...) npyv_setf_u32(0, __VA_ARGS__)
// 定义宏以设置有符号32位整数向量的每个通道,未指定通道使用零填充
#define npyv_set_s32(...) npyv_setf_s32(0, __VA_ARGS__)
// 定义宏以设置无符号64位整数向量的每个通道,未指定通道使用零填充
#define npyv_set_u64(...) npyv_setf_u64(0, __VA_ARGS__)
// 定义宏以设置有符号64位整数向量的每个通道,未指定通道使用零填充
#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__)

// 如果支持 SSE4.1 指令集,则使用 SSE4.1 的混合向量选择指令
#ifdef NPY_HAVE_SSE41
    #define npyv_select_u8(MASK, A, B)  _mm_blendv_epi8(B, A, MASK)
    #define npyv_select_f32(MASK, A, B) _mm_blendv_ps(B, A, _mm_castsi128_ps(MASK))
    #define npyv_select_f64(MASK, A, B) _mm_blendv_pd(B, A, _mm_castsi128_pd(MASK))
// 否则,定义非内联函数以实现无 SSE4.1 支持的混合向量选择
#else
    NPY_FINLINE __m128i npyv_select_u8(__m128i mask, __m128i a, __m128i b)
    { return _mm_xor_si128(b, _mm_and_si128(_mm_xor_si128(b, a), mask)); }
    NPY_FINLINE __m128 npyv_select_f32(__m128i mask, __m128 a, __m128 b)
    { return _mm_xor_ps(b, _mm_and_ps(_mm_xor_ps(b, a), _mm_castsi128_ps(mask))); }
    NPY_FINLINE __m128d npyv_select_f64(__m128i mask, __m128d a, __m128d b)
    { return _mm_xor_pd(b, _mm_and_pd(_mm_xor_pd(b, a), _mm_castsi128_pd(mask))); }
#endif

// 为不同数据类型的整数向量选择定义宏
#define npyv_select_s8  npyv_select_u8
#define npyv_select_u16 npyv_select_u8
#define npyv_select_s16 npyv_select_u8
#define npyv_select_u32 npyv_select_u8
#define npyv_select_s32 npyv_select_u8
#define npyv_select_u64 npyv_select_u8
#define npyv_select_s64 npyv_select_u8

// 提取向量的第一个通道数据并转换为指定的数据类型
#define npyv_extract0_u8(A) ((npy_uint8)_mm_cvtsi128_si32(A))
#define npyv_extract0_s8(A) ((npy_int8)_mm_cvtsi128_si32(A))
#define npyv_extract0_u16(A) ((npy_uint16)_mm_cvtsi128_si32(A))
#define npyv_extract0_s16(A) ((npy_int16)_mm_cvtsi128_si32(A))
#define npyv_extract0_u32(A) ((npy_uint32)_mm_cvtsi128_si32(A))
#define npyv_extract0_s32(A) ((npy_int32)_mm_cvtsi128_si32(A))
#define npyv_extract0_u64(A) ((npy_uint64)npyv128_cvtsi128_si64(A))
#define npyv_extract0_s64(A) ((npy_int64)npyv128_cvtsi128_si64(A))
// 定义宏,用于从 X 中提取 float32 的值,_mm_cvtss_f32 是 SSE 指令
#define npyv_extract0_f32 _mm_cvtss_f32
// 定义宏,用于从 X 中提取 float64 的值,_mm_cvtsd_f64 是 SSE2 指令
#define npyv_extract0_f64 _mm_cvtsd_f64

// 定义宏,用于将 X 重新解释为 uint8_t 类型
#define npyv_reinterpret_u8_u8(X)  X
// 定义宏,用于将 X 重新解释为 int8_t 类型
#define npyv_reinterpret_u8_s8(X)  X
#define npyv_reinterpret_u8_u16(X) X
#define npyv_reinterpret_u8_s16(X) X
#define npyv_reinterpret_u8_u32(X) X
#define npyv_reinterpret_u8_s32(X) X
#define npyv_reinterpret_u8_u64(X) X
#define npyv_reinterpret_u8_s64(X) X
// 定义宏,用于将 X 重新解释为 float32 类型,_mm_castps_si128 是 SSE 指令
#define npyv_reinterpret_u8_f32 _mm_castps_si128
// 定义宏,用于将 X 重新解释为 float64 类型,_mm_castpd_si128 是 SSE2 指令
#define npyv_reinterpret_u8_f64 _mm_castpd_si128

#define npyv_reinterpret_s8_s8(X)  X
#define npyv_reinterpret_s8_u8(X)  X
#define npyv_reinterpret_s8_u16(X) X
#define npyv_reinterpret_s8_s16(X) X
#define npyv_reinterpret_s8_u32(X) X
#define npyv_reinterpret_s8_s32(X) X
#define npyv_reinterpret_s8_u64(X) X
#define npyv_reinterpret_s8_s64(X) X
#define npyv_reinterpret_s8_f32 _mm_castps_si128
#define npyv_reinterpret_s8_f64 _mm_castpd_si128

#define npyv_reinterpret_u16_u16(X) X
#define npyv_reinterpret_u16_u8(X)  X
#define npyv_reinterpret_u16_s8(X)  X
#define npyv_reinterpret_u16_s16(X) X
#define npyv_reinterpret_u16_u32(X) X
#define npyv_reinterpret_u16_s32(X) X
#define npyv_reinterpret_u16_u64(X) X
#define npyv_reinterpret_u16_s64(X) X
#define npyv_reinterpret_u16_f32 _mm_castps_si128
#define npyv_reinterpret_u16_f64 _mm_castpd_si128

#define npyv_reinterpret_s16_s16(X) X
#define npyv_reinterpret_s16_u8(X)  X
#define npyv_reinterpret_s16_s8(X)  X
#define npyv_reinterpret_s16_u16(X) X
#define npyv_reinterpret_s16_u32(X) X
#define npyv_reinterpret_s16_s32(X) X
#define npyv_reinterpret_s16_u64(X) X
#define npyv_reinterpret_s16_s64(X) X
#define npyv_reinterpret_s16_f32 _mm_castps_si128
#define npyv_reinterpret_s16_f64 _mm_castpd_si128

#define npyv_reinterpret_u32_u32(X) X
#define npyv_reinterpret_u32_u8(X)  X
#define npyv_reinterpret_u32_s8(X)  X
#define npyv_reinterpret_u32_u16(X) X
#define npyv_reinterpret_u32_s16(X) X
#define npyv_reinterpret_u32_s32(X) X
#define npyv_reinterpret_u32_u64(X) X
#define npyv_reinterpret_u32_s64(X) X
#define npyv_reinterpret_u32_f32 _mm_castps_si128
#define npyv_reinterpret_u32_f64 _mm_castpd_si128

#define npyv_reinterpret_s32_s32(X) X
#define npyv_reinterpret_s32_u8(X)  X
#define npyv_reinterpret_s32_s8(X)  X
#define npyv_reinterpret_s32_u16(X) X
#define npyv_reinterpret_s32_s16(X) X
#define npyv_reinterpret_s32_u32(X) X
#define npyv_reinterpret_s32_u64(X) X
#define npyv_reinterpret_s32_s64(X) X
#define npyv_reinterpret_s32_f32 _mm_castps_si128
#define npyv_reinterpret_s32_f64 _mm_castpd_si128

#define npyv_reinterpret_u64_u64(X) X
#define npyv_reinterpret_u64_u8(X)  X
#define npyv_reinterpret_u64_s8(X)  X
#define npyv_reinterpret_u64_u16(X) X
#define npyv_reinterpret_u64_s16(X) X
#define npyv_reinterpret_u64_u32(X) X
#define npyv_reinterpret_u64_s32(X) X
#define npyv_reinterpret_u64_s64(X) X
#define npyv_reinterpret_u64_f32 _mm_castps_si128
#define npyv_reinterpret_u64_f64 _mm_castpd_si128

#define npyv_reinterpret_s64_s64(X) X
#define npyv_reinterpret_s64_u8(X)  X
// 定义了一系列宏,用于将不同类型数据重新解释为 64 位有符号整数或者浮点数,具体实现为直接返回传入的参数 X。
#define npyv_reinterpret_s64_s8(X)  X
#define npyv_reinterpret_s64_u16(X) X
#define npyv_reinterpret_s64_s16(X) X
#define npyv_reinterpret_s64_u32(X) X
#define npyv_reinterpret_s64_s32(X) X
#define npyv_reinterpret_s64_u64(X) X
#define npyv_reinterpret_s64_f32 _mm_castps_si128
#define npyv_reinterpret_s64_f64 _mm_castpd_si128

// 定义了一系列宏,用于将不同类型数据重新解释为 32 位浮点数,具体实现为使用 SSE 指令进行转换。
#define npyv_reinterpret_f32_f32(X) X
#define npyv_reinterpret_f32_u8  _mm_castsi128_ps
#define npyv_reinterpret_f32_s8  _mm_castsi128_ps
#define npyv_reinterpret_f32_u16 _mm_castsi128_ps
#define npyv_reinterpret_f32_s16 _mm_castsi128_ps
#define npyv_reinterpret_f32_u32 _mm_castsi128_ps
#define npyv_reinterpret_f32_s32 _mm_castsi128_ps
#define npyv_reinterpret_f32_u64 _mm_castsi128_ps
#define npyv_reinterpret_f32_s64 _mm_castsi128_ps
#define npyv_reinterpret_f32_f64 _mm_castpd_ps

// 定义了一系列宏,用于将不同类型数据重新解释为 64 位浮点数,具体实现为使用 SSE 指令进行转换。
#define npyv_reinterpret_f64_f64(X) X
#define npyv_reinterpret_f64_u8  _mm_castsi128_pd
#define npyv_reinterpret_f64_s8  _mm_castsi128_pd
#define npyv_reinterpret_f64_u16 _mm_castsi128_pd
#define npyv_reinterpret_f64_s16 _mm_castsi128_pd
#define npyv_reinterpret_f64_u32 _mm_castsi128_pd
#define npyv_reinterpret_f64_s32 _mm_castsi128_pd
#define npyv_reinterpret_f64_u64 _mm_castsi128_pd
#define npyv_reinterpret_f64_s64 _mm_castsi128_pd
#define npyv_reinterpret_f64_f32 _mm_castps_pd

// 仅在 AVX2/AVX512 环境下需要调用的宏,此处定义为空操作。
#define npyv_cleanup() ((void)0)

// 头文件结束的标记,用于防止头文件重复包含。
#endif // _NPY_SIMD_SSE_MISC_H

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

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

#ifndef _NPY_SIMD_SSE_OPERATORS_H
#define _NPY_SIMD_SSE_OPERATORS_H

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

// left
// 定义宏,将 SSE 寄存器 A 中的每个元素左移 C 位
#define npyv_shl_u16(A, C) _mm_sll_epi16(A, _mm_cvtsi32_si128(C))
#define npyv_shl_s16(A, C) _mm_sll_epi16(A, _mm_cvtsi32_si128(C))
#define npyv_shl_u32(A, C) _mm_sll_epi32(A, _mm_cvtsi32_si128(C))
#define npyv_shl_s32(A, C) _mm_sll_epi32(A, _mm_cvtsi32_si128(C))
#define npyv_shl_u64(A, C) _mm_sll_epi64(A, _mm_cvtsi32_si128(C))
#define npyv_shl_s64(A, C) _mm_sll_epi64(A, _mm_cvtsi32_si128(C))

// left by an immediate constant
// 定义宏,将 SSE 寄存器 A 中的每个元素左移常数 C 位
#define npyv_shli_u16 _mm_slli_epi16
#define npyv_shli_s16 _mm_slli_epi16
#define npyv_shli_u32 _mm_slli_epi32
#define npyv_shli_s32 _mm_slli_epi32
#define npyv_shli_u64 _mm_slli_epi64
#define npyv_shli_s64 _mm_slli_epi64

// right
// 定义宏,将 SSE 寄存器 A 中的每个元素右移 C 位(逻辑右移)
#define npyv_shr_u16(A, C) _mm_srl_epi16(A, _mm_cvtsi32_si128(C))
#define npyv_shr_s16(A, C) _mm_sra_epi16(A, _mm_cvtsi32_si128(C))
#define npyv_shr_u32(A, C) _mm_srl_epi32(A, _mm_cvtsi32_si128(C))
#define npyv_shr_s32(A, C) _mm_sra_epi32(A, _mm_cvtsi32_si128(C))
#define npyv_shr_u64(A, C) _mm_srl_epi64(A, _mm_cvtsi32_si128(C))

// 定义一个特化的右移宏,处理 64 位有符号整数的右移操作
NPY_FINLINE __m128i npyv_shr_s64(__m128i a, int c)
{
    const __m128i sbit = npyv_setall_s64(0x8000000000000000);
    const __m128i cv   = _mm_cvtsi32_si128(c);
    __m128i r = _mm_srl_epi64(_mm_add_epi64(a, sbit), cv);
    return _mm_sub_epi64(r, _mm_srl_epi64(sbit, cv));
}

// Right by an immediate constant
// 定义宏,将 SSE 寄存器 A 中的每个元素右移常数 C 位(逻辑右移)
#define npyv_shri_u16 _mm_srli_epi16
#define npyv_shri_s16 _mm_srai_epi16
#define npyv_shri_u32 _mm_srli_epi32
#define npyv_shri_s32 _mm_srai_epi32
#define npyv_shri_u64 _mm_srli_epi64
#define npyv_shri_s64  npyv_shr_s64

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

// AND
// 定义宏,将 SSE 寄存器 A 和 B 中的每个元素按位与
#define npyv_and_u8  _mm_and_si128
#define npyv_and_s8  _mm_and_si128
#define npyv_and_u16 _mm_and_si128
#define npyv_and_s16 _mm_and_si128
#define npyv_and_u32 _mm_and_si128
#define npyv_and_s32 _mm_and_si128
#define npyv_and_u64 _mm_and_si128
#define npyv_and_s64 _mm_and_si128
#define npyv_and_f32 _mm_and_ps
#define npyv_and_f64 _mm_and_pd
#define npyv_and_b8  _mm_and_si128
#define npyv_and_b16 _mm_and_si128
#define npyv_and_b32 _mm_and_si128
#define npyv_and_b64 _mm_and_si128

// OR
// 定义宏,将 SSE 寄存器 A 和 B 中的每个元素按位或
#define npyv_or_u8  _mm_or_si128
#define npyv_or_s8  _mm_or_si128
#define npyv_or_u16 _mm_or_si128
#define npyv_or_s16 _mm_or_si128
#define npyv_or_u32 _mm_or_si128
#define npyv_or_s32 _mm_or_si128
#define npyv_or_u64 _mm_or_si128
#define npyv_or_s64 _mm_or_si128
#define npyv_or_f32 _mm_or_ps
#define npyv_or_f64 _mm_or_pd
#define npyv_or_b8  _mm_or_si128
#define npyv_or_b16 _mm_or_si128
#define npyv_or_b32 _mm_or_si128
#define npyv_or_b64 _mm_or_si128

// XOR
// 定义宏,将 SSE 寄存器 A 和 B 中的每个元素按位异或
#define npyv_xor_u8  _mm_xor_si128
#define npyv_xor_s8  _mm_xor_si128
#define npyv_xor_u16 _mm_xor_si128
#define npyv_xor_s16 _mm_xor_si128
#define npyv_xor_u32 _mm_xor_si128
#define npyv_xor_s32 _mm_xor_si128



#define npyv_xor_u64 _mm_xor_si128
// 定义按位异或操作宏,对于各种数据类型使用对应的 SSE 指令进行操作
#define npyv_xor_u64 _mm_xor_si128
#define npyv_xor_s64 _mm_xor_si128
#define npyv_xor_f32 _mm_xor_ps
#define npyv_xor_f64 _mm_xor_pd
#define npyv_xor_b8  _mm_xor_si128
#define npyv_xor_b16 _mm_xor_si128
#define npyv_xor_b32 _mm_xor_si128
#define npyv_xor_b64 _mm_xor_si128

// 定义按位取反操作宏,根据数据类型使用对应的 SSE 指令进行操作
#define npyv_not_u8(A) _mm_xor_si128(A, _mm_set1_epi32(-1))
#define npyv_not_s8  npyv_not_u8
#define npyv_not_u16 npyv_not_u8
#define npyv_not_s16 npyv_not_u8
#define npyv_not_u32 npyv_not_u8
#define npyv_not_s32 npyv_not_u8
#define npyv_not_u64 npyv_not_u8
#define npyv_not_s64 npyv_not_u8
#define npyv_not_f32(A) _mm_xor_ps(A, _mm_castsi128_ps(_mm_set1_epi32(-1)))
#define npyv_not_f64(A) _mm_xor_pd(A, _mm_castsi128_pd(_mm_set1_epi32(-1)))
#define npyv_not_b8  npyv_not_u8
#define npyv_not_b16 npyv_not_u8
#define npyv_not_b32 npyv_not_u8
#define npyv_not_b64 npyv_not_u8

// 定义按位与非操作宏,根据数据类型使用对应的 SSE 指令进行操作
#define npyv_andc_u8(A, B) _mm_andnot_si128(B, A)
#define npyv_andc_b8(A, B) _mm_andnot_si128(B, A)
// 定义按位或非操作宏,使用按位非和按位或操作来实现
#define npyv_orc_b8(A, B) npyv_or_b8(npyv_not_b8(B), A)
// 定义按位异或非操作宏,使用比较相等操作和按位异或操作来实现
#define npyv_xnor_b8 _mm_cmpeq_epi8

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

// 定义整数相等比较操作宏,根据数据类型使用对应的 SSE 指令进行操作
#define npyv_cmpeq_u8  _mm_cmpeq_epi8
#define npyv_cmpeq_s8  _mm_cmpeq_epi8
#define npyv_cmpeq_u16 _mm_cmpeq_epi16
#define npyv_cmpeq_s16 _mm_cmpeq_epi16
#define npyv_cmpeq_u32 _mm_cmpeq_epi32
#define npyv_cmpeq_s32 _mm_cmpeq_epi32
#define npyv_cmpeq_s64  npyv_cmpeq_u64

#ifdef NPY_HAVE_SSE41
    // 如果支持 SSE4.1,定义整数相等比较操作宏使用 SSE 指令
    #define npyv_cmpeq_u64 _mm_cmpeq_epi64
#else
    // 否则,定义整数相等比较操作函数,使用基本的 SSE 指令来实现
    NPY_FINLINE __m128i npyv_cmpeq_u64(__m128i a, __m128i b)
    {
        __m128i cmpeq = _mm_cmpeq_epi32(a, b);
        __m128i cmpeq_h = _mm_srli_epi64(cmpeq, 32);
        __m128i test = _mm_and_si128(cmpeq, cmpeq_h);
        return _mm_shuffle_epi32(test, _MM_SHUFFLE(2, 2, 0, 0));
    }
#endif

// 定义整数不等比较操作宏,根据数据类型和支持的指令集使用对应的比较和非操作宏
#ifdef NPY_HAVE_XOP
    #define npyv_cmpneq_u8  _mm_comneq_epi8
    #define npyv_cmpneq_u16 _mm_comneq_epi16
    #define npyv_cmpneq_u32 _mm_comneq_epi32
    #define npyv_cmpneq_u64 _mm_comneq_epi64
#else
    #define npyv_cmpneq_u8(A, B)  npyv_not_u8(npyv_cmpeq_u8(A, B))
    #define npyv_cmpneq_u16(A, B) npyv_not_u16(npyv_cmpeq_u16(A, B))
    #define npyv_cmpneq_u32(A, B) npyv_not_u32(npyv_cmpeq_u32(A, B))
    #define npyv_cmpneq_u64(A, B) npyv_not_u64(npyv_cmpeq_u64(A, B))
#endif
#define npyv_cmpneq_s8  npyv_cmpneq_u8
#define npyv_cmpneq_s16 npyv_cmpneq_u16
#define npyv_cmpneq_s32 npyv_cmpneq_u32
#define npyv_cmpneq_s64 npyv_cmpneq_u64

// 定义有符号大于比较操作宏,根据数据类型和支持的指令集使用对应的 SSE 指令进行操作
#define npyv_cmpgt_s8  _mm_cmpgt_epi8
#define npyv_cmpgt_s16 _mm_cmpgt_epi16
#define npyv_cmpgt_s32 _mm_cmpgt_epi32

#ifdef NPY_HAVE_SSE42
    // 如果支持 SSE4.2,定义有符号大于比较操作宏使用 SSE 指令
    #define npyv_cmpgt_s64 _mm_cmpgt_epi64
#else
    // 否则,定义有符号大于比较操作函数,使用基本的 SSE 指令来实现
    NPY_FINLINE __m128i npyv_cmpgt_s64(__m128i a, __m128i b)
    {
        // 计算向量 b 减去向量 a 的结果
        __m128i sub = _mm_sub_epi64(b, a);
        // 计算 a 和 b 各位不同的比特位
        __m128i nsame_sbit = _mm_xor_si128(a, b);
        // 如果 nsame_sbit 不为零,则返回 b,否则返回 sub
        __m128i test = _mm_xor_si128(sub, _mm_and_si128(_mm_xor_si128(sub, b), nsame_sbit));
        // 扩展比特位,将 test 右移31位后的高位扩展到低位,并使用特定的顺序重新排列
        __m128i extend_sbit = _mm_shuffle_epi32(_mm_srai_epi32(test, 31), _MM_SHUFFLE(3, 3, 1, 1));
        // 返回最终结果 extend_sbit
        return extend_sbit;
    }
#endif

#ifdef NPY_HAVE_XOP
    #define npyv_cmpge_s8  _mm_comge_epi8
    #define npyv_cmpge_s16 _mm_comge_epi16
    #define npyv_cmpge_s32 _mm_comge_epi32
    #define npyv_cmpge_s64 _mm_comge_epi64
#else
    // 定义有符号整数比较大于等于操作,使用逻辑反操作得到
    #define npyv_cmpge_s8(A, B)  npyv_not_s8(_mm_cmpgt_epi8(B, A))
    #define npyv_cmpge_s16(A, B) npyv_not_s16(_mm_cmpgt_epi16(B, A))
    #define npyv_cmpge_s32(A, B) npyv_not_s32(_mm_cmpgt_epi32(B, A))
    #define npyv_cmpge_s64(A, B) npyv_not_s64(npyv_cmpgt_s64(B, A))
#endif

#ifdef NPY_HAVE_XOP
    #define npyv_cmpgt_u8  _mm_comgt_epu8
    #define npyv_cmpgt_u16 _mm_comgt_epu16
    #define npyv_cmpgt_u32 _mm_comgt_epu32
    #define npyv_cmpgt_u64 _mm_comgt_epu64
#else
    // 定义无符号整数大于操作,通过异或运算实现
    #define NPYV_IMPL_SSE_UNSIGNED_GT(LEN, SIGN)                     \
        NPY_FINLINE __m128i npyv_cmpgt_u##LEN(__m128i a, __m128i b)  \
        {                                                            \
            const __m128i sbit = _mm_set1_epi32(SIGN);               \
            return _mm_cmpgt_epi##LEN(                               \
                _mm_xor_si128(a, sbit), _mm_xor_si128(b, sbit)       \
            );                                                       \
        }

    NPYV_IMPL_SSE_UNSIGNED_GT(8,  0x80808080)
    NPYV_IMPL_SSE_UNSIGNED_GT(16, 0x80008000)
    NPYV_IMPL_SSE_UNSIGNED_GT(32, 0x80000000)

    // 定义64位无符号整数大于操作,通过异或运算实现
    NPY_FINLINE __m128i npyv_cmpgt_u64(__m128i a, __m128i b)
    {
        const __m128i sbit = npyv_setall_s64(0x8000000000000000);
        return npyv_cmpgt_s64(_mm_xor_si128(a, sbit), _mm_xor_si128(b, sbit));
    }
#endif

#ifdef NPY_HAVE_XOP
    #define npyv_cmpge_u8  _mm_comge_epu8
    #define npyv_cmpge_u16 _mm_comge_epu16
    #define npyv_cmpge_u32 _mm_comge_epu32
    #define npyv_cmpge_u64 _mm_comge_epu64
#else
    // 定义无符号整数大于等于操作,通过比较和最大值计算得到
    NPY_FINLINE __m128i npyv_cmpge_u8(__m128i a, __m128i b)
    { return _mm_cmpeq_epi8(a, _mm_max_epu8(a, b)); }
    
    // 在 SSE4.1 支持下,定义更高精度的无符号整数大于等于操作
    #ifdef NPY_HAVE_SSE41
        NPY_FINLINE __m128i npyv_cmpge_u16(__m128i a, __m128i b)
        { return _mm_cmpeq_epi16(a, _mm_max_epu16(a, b)); }
        NPY_FINLINE __m128i npyv_cmpge_u32(__m128i a, __m128i b)
        { return _mm_cmpeq_epi32(a, _mm_max_epu32(a, b)); }
    #else
        // 对于没有 SSE4.1 支持的情况,通过比较和逻辑非得到结果
        #define npyv_cmpge_u16(A, B) _mm_cmpeq_epi16(_mm_subs_epu16(B, A), _mm_setzero_si128())
        #define npyv_cmpge_u32(A, B) npyv_not_u32(npyv_cmpgt_u32(B, A))
    #endif
    // 定义64位无符号整数大于等于操作,通过逻辑非得到
    #define npyv_cmpge_u64(A, B) npyv_not_u64(npyv_cmpgt_u64(B, A))
#endif

// 定义各种类型的小于操作,通过大于操作和参数位置调换得到
#define npyv_cmplt_u8(A, B)  npyv_cmpgt_u8(B, A)
#define npyv_cmplt_s8(A, B)  npyv_cmpgt_s8(B, A)
#define npyv_cmplt_u16(A, B) npyv_cmpgt_u16(B, A)
#define npyv_cmplt_s16(A, B) npyv_cmpgt_s16(B, A)
#define npyv_cmplt_u32(A, B) npyv_cmpgt_u32(B, A)
#define npyv_cmplt_s32(A, B) npyv_cmpgt_s32(B, A)
#define npyv_cmplt_u64(A, B) npyv_cmpgt_u64(B, A)
#define npyv_cmplt_s64(A, B) npyv_cmpgt_s64(B, A)

// 定义各种类型的小于等于操作,通过大于等于操作和参数位置调换得到
#define npyv_cmple_u8(A, B)  npyv_cmpge_u8(B, A)
// 小于等于比较,返回值为将 B 与 A 进行大于等于比较的结果
#define npyv_cmple_s8(A, B)  npyv_cmpge_s8(B, A)
// 无符号 16 位整数小于等于比较,返回值为将 B 与 A 进行大于等于比较的结果
#define npyv_cmple_u16(A, B) npyv_cmpge_u16(B, A)
// 有符号 16 位整数小于等于比较,返回值为将 B 与 A 进行大于等于比较的结果
#define npyv_cmple_s16(A, B) npyv_cmpge_s16(B, A)
// 无符号 32 位整数小于等于比较,返回值为将 B 与 A 进行大于等于比较的结果
#define npyv_cmple_u32(A, B) npyv_cmpge_u32(B, A)
// 有符号 32 位整数小于等于比较,返回值为将 B 与 A 进行大于等于比较的结果
#define npyv_cmple_s32(A, B) npyv_cmpge_s32(B, A)
// 无符号 64 位整数小于等于比较,返回值为将 B 与 A 进行大于等于比较的结果
#define npyv_cmple_u64(A, B) npyv_cmpge_u64(B, A)
// 有符号 64 位整数小于等于比较,返回值为将 B 与 A 进行大于等于比较的结果
#define npyv_cmple_s64(A, B) npyv_cmpge_s64(B, A)

// 单精度浮点数等于比较,返回值为将 a 与 b 进行等于比较的结果
#define npyv_cmpeq_f32(a, b)  _mm_castps_si128(_mm_cmpeq_ps(a, b))
// 双精度浮点数等于比较,返回值为将 a 与 b 进行等于比较的结果
#define npyv_cmpeq_f64(a, b)  _mm_castpd_si128(_mm_cmpeq_pd(a, b))
// 单精度浮点数非等于比较,返回值为将 a 与 b 进行非等于比较的结果
#define npyv_cmpneq_f32(a, b) _mm_castps_si128(_mm_cmpneq_ps(a, b))
// 双精度浮点数非等于比较,返回值为将 a 与 b 进行非等于比较的结果
#define npyv_cmpneq_f64(a, b) _mm_castpd_si128(_mm_cmpneq_pd(a, b))
// 单精度浮点数小于比较,返回值为将 a 与 b 进行小于比较的结果
#define npyv_cmplt_f32(a, b)  _mm_castps_si128(_mm_cmplt_ps(a, b))
// 双精度浮点数小于比较,返回值为将 a 与 b 进行小于比较的结果
#define npyv_cmplt_f64(a, b)  _mm_castpd_si128(_mm_cmplt_pd(a, b))
// 单精度浮点数小于等于比较,返回值为将 a 与 b 进行小于等于比较的结果
#define npyv_cmple_f32(a, b)  _mm_castps_si128(_mm_cmple_ps(a, b))
// 双精度浮点数小于等于比较,返回值为将 a 与 b 进行小于等于比较的结果
#define npyv_cmple_f64(a, b)  _mm_castpd_si128(_mm_cmple_pd(a, b))
// 单精度浮点数大于比较,返回值为将 a 与 b 进行大于比较的结果
#define npyv_cmpgt_f32(a, b)  _mm_castps_si128(_mm_cmpgt_ps(a, b))
// 双精度浮点数大于比较,返回值为将 a 与 b 进行大于比较的结果
#define npyv_cmpgt_f64(a, b)  _mm_castpd_si128(_mm_cmpgt_pd(a, b))
// 单精度浮点数大于等于比较,返回值为将 a 与 b 进行大于等于比较的结果
#define npyv_cmpge_f32(a, b)  _mm_castps_si128(_mm_cmpge_ps(a, b))
// 双精度浮点数大于等于比较,返回值为将 a 与 b 进行大于等于比较的结果
#define npyv_cmpge_f64(a, b)  _mm_castpd_si128(_mm_cmpge_pd(a, b))

// 检查特殊情况
// 检查单精度浮点数向量中是否有 NaN,返回值为将 a 与 a 进行非 NaN 比较的结果
NPY_FINLINE npyv_b32 npyv_notnan_f32(npyv_f32 a)
{ return _mm_castps_si128(_mm_cmpord_ps(a, a)); }
// 检查双精度浮点数向量中是否有 NaN,返回值为将 a 与 a 进行非 NaN 比较的结果
NPY_FINLINE npyv_b64 npyv_notnan_f64(npyv_f64 a)
{ return _mm_castpd_si128(_mm_cmpord_pd(a, a)); }

// 测试跨所有向量通道
// any: 如果任何元素不等于零,则返回 true
// all: 如果所有元素均不等于零,则返回 true
#define NPYV_IMPL_SSE_ANYALL(SFX, MSFX, TSFX, MASK)                 \
    NPY_FINLINE bool npyv_any_##SFX(npyv_##SFX a)                   \
    { return _mm_movemask_##MSFX(                                   \
        _mm_cmpeq_##TSFX(a, npyv_zero_##SFX())                      \
    ) != MASK; }                                                    \
    NPY_FINLINE bool npyv_all_##SFX(npyv_##SFX a)                   \
    { return _mm_movemask_##MSFX(                                   \
        _mm_cmpeq_##TSFX(a, npyv_zero_##SFX())                      \
    ) == 0; }
// 无符号 8 位整数的任意和全部比较实现
NPYV_IMPL_SSE_ANYALL(u8,  epi8, epi8, 0xffff)
// 有符号 8 位整数的任意和全部比较实现
NPYV_IMPL_SSE_ANYALL(s8,  epi8, epi8, 0xffff)
// 无符号 16 位整数的任意和全部比较实现
NPYV_IMPL_SSE_ANYALL(u16, epi8, epi16, 0xffff)
// 有符号 16 位整数的任意和全部比较实现
NPYV_IMPL_SSE_ANYALL(s16, epi8, epi16, 0xffff)
// 无符号 32 位整数的任意和全部比较实现
NPYV_IMPL_SSE_ANYALL(u32, epi8, epi32, 0xffff)
// 有符号 32 位整数的任意和全部比较实现
NPYV_IMPL_SSE_ANYALL(s32, epi8, epi32, 0xffff)
#ifdef NPY_HAVE_SSE41
    // 无符号 64 位整数的任意和全部比较实现(如果支持 SSE4.1)
    NPYV_IMPL_SSE_ANYALL(u64, epi8, epi64, 0xffff)
    NPYV_IMPL_SSE_ANYALL(s64, epi8, epi64, 0xffff)



# 使用 SSE 指令集实现向量操作,判断64位有符号整数中每个元素是否满足条件
NPYV_IMPL_SSE_ANYALL(s64, epi8, epi64, 0xffff)


这行代码调用了一个宏 `NPYV_IMPL_SSE_ANYALL`,利用 SSE 指令集对 64 位有符号整数向量进行操作,它的作用是判断每个元素是否满足特定条件(这里是检查每个元素的低位16位是否全部为1)。
#else
    // 定义函数 npyv_any_u64,检查是否存在非全零的无符号64位整数向量 a
    NPY_FINLINE bool npyv_any_u64(npyv_u64 a)
    {
        // 判断向量 a 中是否有元素等于全零向量 npyv_zero_u64(),返回结果的逻辑非为真
        return _mm_movemask_epi8(
            _mm_cmpeq_epi32(a, npyv_zero_u64())
        ) != 0xffff;
    }
    // 定义函数 npyv_all_u64,检查是否所有的无符号64位整数向量 a 中的元素都为全零
    NPY_FINLINE bool npyv_all_u64(npyv_u64 a)
    {
        // 将向量 a 中的每个元素与全零向量 npyv_zero_u64() 比较,得到结果向量 a
        a = _mm_cmpeq_epi32(a, npyv_zero_u64());
        // 将结果向量 a 与自身进行按位与,并使用特定的整数序列进行打乱
        a = _mm_and_si128(a, _mm_shuffle_epi32(a, _MM_SHUFFLE(2, 3, 0, 1)));
        // 检查向量 a 是否所有元素都为全零,返回结果的逻辑非为真
        return _mm_movemask_epi8(a) == 0;
    }
    // 定义宏 npyv_any_s64,使其与 npyv_any_u64 具有相同的定义
    #define npyv_any_s64 npyv_any_u64
    // 定义宏 npyv_all_s64,使其与 npyv_all_u64 具有相同的定义
    #define npyv_all_s64 npyv_all_u64
#endif

// 宏 NPYV_IMPL_SSE_ANYALL 的具体实现,用于实现 SSE 下的任意/所有功能
NPYV_IMPL_SSE_ANYALL(f32, ps, ps, 0xf)
NPYV_IMPL_SSE_ANYALL(f64, pd, pd, 0x3)
// 取消定义宏 NPYV_IMPL_SSE_ANYALL
#undef NPYV_IMPL_SSE_ANYALL

#endif // _NPY_SIMD_SSE_OPERATORS_H

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

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

#ifndef _NPY_SIMD_SSE_REORDER_H
#define _NPY_SIMD_SSE_REORDER_H

// 定义宏:将两个向量的低部分合并
#define npyv_combinel_u8  _mm_unpacklo_epi64
#define npyv_combinel_s8  _mm_unpacklo_epi64
#define npyv_combinel_u16 _mm_unpacklo_epi64
#define npyv_combinel_s16 _mm_unpacklo_epi64
#define npyv_combinel_u32 _mm_unpacklo_epi64
#define npyv_combinel_s32 _mm_unpacklo_epi64
#define npyv_combinel_u64 _mm_unpacklo_epi64
#define npyv_combinel_s64 _mm_unpacklo_epi64
// 将两个单精度浮点数向量的低部分合并
#define npyv_combinel_f32(A, B) _mm_castsi128_ps(_mm_unpacklo_epi64(_mm_castps_si128(A), _mm_castps_si128(B)))
// 将两个双精度浮点数向量的低部分合并
#define npyv_combinel_f64 _mm_unpacklo_pd

// 定义宏:将两个向量的高部分合并
#define npyv_combineh_u8  _mm_unpackhi_epi64
#define npyv_combineh_s8  _mm_unpackhi_epi64
#define npyv_combineh_u16 _mm_unpackhi_epi64
#define npyv_combineh_s16 _mm_unpackhi_epi64
#define npyv_combineh_u32 _mm_unpackhi_epi64
#define npyv_combineh_s32 _mm_unpackhi_epi64
#define npyv_combineh_u64 _mm_unpackhi_epi64
#define npyv_combineh_s64 _mm_unpackhi_epi64
// 将两个单精度浮点数向量的高部分合并
#define npyv_combineh_f32(A, B) _mm_castsi128_ps(_mm_unpackhi_epi64(_mm_castps_si128(A), _mm_castps_si128(B)))
// 将两个双精度浮点数向量的高部分合并
#define npyv_combineh_f64 _mm_unpackhi_pd

// 定义函数:从两个整型向量中提取低部分和高部分组成一个结构体
NPY_FINLINE npyv_m128ix2 npyv__combine(__m128i a, __m128i b)
{
    npyv_m128ix2 r;
    r.val[0] = npyv_combinel_u8(a, b); // 提取 a 和 b 的低部分组合成 r 的第一个值
    r.val[1] = npyv_combineh_u8(a, b); // 提取 a 和 b 的高部分组合成 r 的第二个值
    return r; // 返回包含低部分和高部分的结构体
}

// 定义函数:从两个单精度浮点数向量中提取低部分和高部分组成一个结构体
NPY_FINLINE npyv_f32x2 npyv_combine_f32(__m128 a, __m128 b)
{
    npyv_f32x2 r;
    r.val[0] = npyv_combinel_f32(a, b); // 提取 a 和 b 的低部分组合成 r 的第一个值
    r.val[1] = npyv_combineh_f32(a, b); // 提取 a 和 b 的高部分组合成 r 的第二个值
    return r; // 返回包含低部分和高部分的结构体
}

// 定义函数:从两个双精度浮点数向量中提取低部分和高部分组成一个结构体
NPY_FINLINE npyv_f64x2 npyv_combine_f64(__m128d a, __m128d b)
{
    npyv_f64x2 r;
    r.val[0] = npyv_combinel_f64(a, b); // 提取 a 和 b 的低部分组合成 r 的第一个值
    r.val[1] = npyv_combineh_f64(a, b); // 提取 a 和 b 的高部分组合成 r 的第二个值
    return r; // 返回包含低部分和高部分的结构体
}

// 定义宏:从两个向量中提取低部分和高部分组合成一个结构体的函数模板
#define NPYV_IMPL_SSE_ZIP(T_VEC, SFX, INTR_SFX)            \
    NPY_FINLINE T_VEC##x2 npyv_zip_##SFX(T_VEC a, T_VEC b) \
    {                                                      \
        T_VEC##x2 r;                                       \
        r.val[0] = _mm_unpacklo_##INTR_SFX(a, b);          // 提取 a 和 b 的低部分组合成 r 的第一个值
        r.val[1] = _mm_unpackhi_##INTR_SFX(a, b);          // 提取 a 和 b 的高部分组合成 r 的第二个值
        return r;                                          // 返回包含低部分和高部分的结构体
    }

// 实现各种数据类型的函数模板,用于从两个向量中提取低部分和高部分组合成一个结构体
NPYV_IMPL_SSE_ZIP(npyv_u8,  u8,  epi8)
NPYV_IMPL_SSE_ZIP(npyv_s8,  s8,  epi8)
NPYV_IMPL_SSE_ZIP(npyv_u16, u16, epi16)
NPYV_IMPL_SSE_ZIP(npyv_s16, s16, epi16)
NPYV_IMPL_SSE_ZIP(npyv_u32, u32, epi32)
NPYV_IMPL_SSE_ZIP(npyv_s32, s32, epi32)
NPYV_IMPL_SSE_ZIP(npyv_u64, u64, epi64)
NPYV_IMPL_SSE_ZIP(npyv_s64, s64, epi64)
NPYV_IMPL_SSE_ZIP(npyv_f32, f32, ps)
NPYV_IMPL_SSE_ZIP(npyv_f64, f64, pd)

#endif // _NPY_SIMD_SSE_REORDER_H
// 将两个向量解交错
NPY_FINLINE npyv_u8x2 npyv_unzip_u8(npyv_u8 ab0, npyv_u8 ab1)
{
#ifdef NPY_HAVE_SSSE3
    // 创建用于解交错的索引向量
    const __m128i idx = _mm_setr_epi8(
        0, 2, 4, 6, 8, 10, 12, 14, 1, 3, 5, 7, 9, 11, 13, 15
    );
    // 使用索引向量解交错第一个输入向量
    __m128i abl = _mm_shuffle_epi8(ab0, idx);
    // 使用索引向量解交错第二个输入向量
    __m128i abh = _mm_shuffle_epi8(ab1, idx);
    // 结合解交错后的两部分向量为一个新的向量
    return npyv_combine_u8(abl, abh);
#else
    // 如果没有 SSSE3 支持,则手动解交错
    __m128i ab_083b = _mm_unpacklo_epi8(ab0, ab1);
    __m128i ab_4c6e = _mm_unpackhi_epi8(ab0, ab1);
    __m128i ab_048c = _mm_unpacklo_epi8(ab_083b, ab_4c6e);
    __m128i ab_36be = _mm_unpackhi_epi8(ab_083b, ab_4c6e);
    __m128i ab_0346 = _mm_unpacklo_epi8(ab_048c, ab_36be);
    __m128i ab_8bc8 = _mm_unpackhi_epi8(ab_048c, ab_36be);
    // 创建结果向量结构体
    npyv_u8x2 r;
    r.val[0] = _mm_unpacklo_epi8(ab_0346, ab_8bc8);
    r.val[1] = _mm_unpackhi_epi8(ab_0346, ab_8bc8);
    return r;
#endif
}
#define npyv_unzip_s8 npyv_unzip_u8

// 解交错两个 uint16_t 向量
NPY_FINLINE npyv_u16x2 npyv_unzip_u16(npyv_u16 ab0, npyv_u16 ab1)
{
#ifdef NPY_HAVE_SSSE3
    // 创建用于解交错的索引向量
    const __m128i idx = _mm_setr_epi8(
        0, 1, 4, 5, 8, 9, 12, 13, 2, 3, 6, 7, 10, 11, 14, 15
    );
    // 使用索引向量解交错第一个输入向量
    __m128i abl = _mm_shuffle_epi8(ab0, idx);
    // 使用索引向量解交错第二个输入向量
    __m128i abh = _mm_shuffle_epi8(ab1, idx);
    // 结合解交错后的两部分向量为一个新的向量
    return npyv_combine_u16(abl, abh);
#else
    // 如果没有 SSSE3 支持,则手动解交错
    __m128i ab_0415 = _mm_unpacklo_epi16(ab0, ab1);
    __m128i ab_263f = _mm_unpackhi_epi16(ab0, ab1);
    __m128i ab_0246 = _mm_unpacklo_epi16(ab_0415, ab_263f);
    __m128i ab_135f = _mm_unpackhi_epi16(ab_0415, ab_263f);
    // 创建结果向量结构体
    npyv_u16x2 r;
    r.val[0] = _mm_unpacklo_epi16(ab_0246, ab_135f);
    r.val[1] = _mm_unpackhi_epi16(ab_0246, ab_135f);
    return r;
#endif
}
#define npyv_unzip_s16 npyv_unzip_u16

// 解交错两个 uint32_t 向量
NPY_FINLINE npyv_u32x2 npyv_unzip_u32(npyv_u32 ab0, npyv_u32 ab1)
{
    // 使用预定义的掩码进行解交错操作
    __m128i abl = _mm_shuffle_epi32(ab0, _MM_SHUFFLE(3, 1, 2, 0));
    __m128i abh = _mm_shuffle_epi32(ab1, _MM_SHUFFLE(3, 1, 2, 0));
    // 结合解交错后的两部分向量为一个新的向量
    return npyv_combine_u32(abl, abh);
}
#define npyv_unzip_s32 npyv_unzip_u32

// 直接将两个 uint64_t 向量结合成一个
NPY_FINLINE npyv_u64x2 npyv_unzip_u64(npyv_u64 ab0, npyv_u64 ab1)
{
    return npyv_combine_u64(ab0, ab1);
}
#define npyv_unzip_s64 npyv_unzip_u64

// 解交错两个 float 向量
NPY_FINLINE npyv_f32x2 npyv_unzip_f32(npyv_f32 ab0, npyv_f32 ab1)
{
    // 使用预定义的掩码进行解交错操作
    npyv_f32x2 r;
    r.val[0] = _mm_shuffle_ps(ab0, ab1, _MM_SHUFFLE(2, 0, 2, 0));
    r.val[1] = _mm_shuffle_ps(ab0, ab1, _MM_SHUFFLE(3, 1, 3, 1));
    return r;
}

// 直接将两个 double 向量结合成一个
NPY_FINLINE npyv_f64x2 npyv_unzip_f64(npyv_f64 ab0, npyv_f64 ab1)
{
    return npyv_combine_f64(ab0, ab1);
}

// 反转每个 64 位通道中的元素顺序
NPY_FINLINE npyv_u16 npyv_rev64_u16(npyv_u16 a)
{
#ifdef NPY_HAVE_SSSE3
    // 创建用于反转的索引向量
    const __m128i idx = _mm_setr_epi8(
        6, 7, 4, 5, 2, 3, 0, 1, 14, 15, 12, 13, 10, 11, 8, 9
    );
    // 使用索引向量反转输入向量
    return _mm_shuffle_epi8(a, idx);
#else
    // 如果没有 SSSE3 支持,则手动反转
    __m128i lo = _mm_shufflelo_epi16(a, _MM_SHUFFLE(0, 1, 2, 3));
    return _mm_shufflehi_epi16(lo, _MM_SHUFFLE(0, 1, 2, 3));
#endif
}
#define npyv_rev64_s16 npyv_rev64_u16

// 反转每个 64 位通道中的元素顺序
NPY_FINLINE npyv_u8 npyv_rev64_u8(npyv_u8 a)
{
#ifdef NPY_HAVE_SSSE3
    // 创建用于反转的索引向量
    const __m128i idx = _mm_setr_epi8(
        7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
    );
    // 使用索引向量反转输入向量
    return _mm_shuffle_epi8(a, idx);
#else
    // 如果没有 SSSE3 支持,则手动反转
    __m128i lo = _mm_shufflelo_epi16(a, _MM_SHUFFLE(0, 1, 2, 3));
    return _mm_shufflehi_epi16(lo, _MM_SHUFFLE(0, 1, 2, 3));
#endif
}
    );
    # 调用 SSE2 指令集中的 _mm_shuffle_epi8 函数,并传入参数 a 和 idx
    return _mm_shuffle_epi8(a, idx);
    # 返回 _mm_shuffle_epi8 函数的结果
#else
    __m128i rev16 = npyv_rev64_u16(a);
    // 使用 npyv_rev64_u16 函数对参数 a 进行逆序操作,返回结果存入 rev16 中
    // 交换 8 位的对
    return _mm_or_si128(_mm_slli_epi16(rev16, 8), _mm_srli_epi16(rev16, 8));
#endif
}
#define npyv_rev64_s8 npyv_rev64_u8

NPY_FINLINE npyv_u32 npyv_rev64_u32(npyv_u32 a)
{
    // 使用 SSE 指令对参数 a 进行 32 位元素的逆序操作
    return _mm_shuffle_epi32(a, _MM_SHUFFLE(2, 3, 0, 1));
}
#define npyv_rev64_s32 npyv_rev64_u32

NPY_FINLINE npyv_f32 npyv_rev64_f32(npyv_f32 a)
{
    // 使用 SSE 指令对参数 a 进行 32 位浮点数元素的逆序操作
    return _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 0, 1));
}

// 对每个 128 位 lane 的元素进行按照指定索引的置换操作
#define npyv_permi128_u32(A, E0, E1, E2, E3) \
    _mm_shuffle_epi32(A, _MM_SHUFFLE(E3, E2, E1, E0))

#define npyv_permi128_s32 npyv_permi128_u32

// 对每个 128 位 lane 的元素进行按照指定索引的置换操作,针对 64 位无符号整数
#define npyv_permi128_u64(A, E0, E1) \
    _mm_shuffle_epi32(A, _MM_SHUFFLE(((E1)<<1)+1, ((E1)<<1), ((E0)<<1)+1, ((E0)<<1)))

#define npyv_permi128_s64 npyv_permi128_u64

// 对每个 128 位 lane 的元素进行按照指定索引的置换操作,针对 32 位浮点数
#define npyv_permi128_f32(A, E0, E1, E2, E3) \
    _mm_shuffle_ps(A, A, _MM_SHUFFLE(E3, E2, E1, E0))

// 对每个 128 位 lane 的元素进行按照指定索引的置换操作,针对 64 位浮点数
#define npyv_permi128_f64(A, E0, E1) \
    _mm_shuffle_pd(A, A, _MM_SHUFFLE2(E1, E0))

#endif // _NPY_SIMD_SSE_REORDER_H


注释完成。

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

#ifndef _NPY_SIMD_H_
    #error "Not a standalone header"  // 如果没有包含在主头文件中,则报错
#endif

#define NPY_SIMD 128  // 定义 SIMD 宽度为 128 bits
#define NPY_SIMD_WIDTH 16  // SIMD 的宽度为 16 bytes
#define NPY_SIMD_F32 1  // 支持单精度浮点运算
#define NPY_SIMD_F64 1  // 支持双精度浮点运算
#if defined(NPY_HAVE_FMA3) || defined(NPY_HAVE_FMA4)
    #define NPY_SIMD_FMA3 1  // 使用原生的 FMA3 指令集支持
#else
    #define NPY_SIMD_FMA3 0  // 使用快速模拟的 FMA3
#endif
#define NPY_SIMD_BIGENDIAN 0  // SIMD 不支持大端模式
#define NPY_SIMD_CMPSIGNAL 1  // SIMD 支持比较信号处理

typedef __m128i npyv_u8;  // 定义无符号 8-bit 整数 SIMD 类型
typedef __m128i npyv_s8;  // 定义有符号 8-bit 整数 SIMD 类型
typedef __m128i npyv_u16;  // 定义无符号 16-bit 整数 SIMD 类型
typedef __m128i npyv_s16;  // 定义有符号 16-bit 整数 SIMD 类型
typedef __m128i npyv_u32;  // 定义无符号 32-bit 整数 SIMD 类型
typedef __m128i npyv_s32;  // 定义有符号 32-bit 整数 SIMD 类型
typedef __m128i npyv_u64;  // 定义无符号 64-bit 整数 SIMD 类型
typedef __m128i npyv_s64;  // 定义有符号 64-bit 整数 SIMD 类型
typedef __m128  npyv_f32;  // 定义单精度浮点数 SIMD 类型
typedef __m128d npyv_f64;  // 定义双精度浮点数 SIMD 类型

typedef __m128i npyv_b8;   // 定义 8-bit 布尔类型 SIMD 类型
typedef __m128i npyv_b16;  // 定义 16-bit 布尔类型 SIMD 类型
typedef __m128i npyv_b32;  // 定义 32-bit 布尔类型 SIMD 类型
typedef __m128i npyv_b64;  // 定义 64-bit 布尔类型 SIMD 类型

typedef struct { __m128i val[2]; } npyv_m128ix2;  // 定义包含两个 __m128i 的 SIMD 结构体
typedef npyv_m128ix2 npyv_u8x2;  // 定义两个 __m128i 的无符号 8-bit 整数 SIMD 结构体
typedef npyv_m128ix2 npyv_s8x2;  // 定义两个 __m128i 的有符号 8-bit 整数 SIMD 结构体
typedef npyv_m128ix2 npyv_u16x2;  // 定义两个 __m128i 的无符号 16-bit 整数 SIMD 结构体
typedef npyv_m128ix2 npyv_s16x2;  // 定义两个 __m128i 的有符号 16-bit 整数 SIMD 结构体
typedef npyv_m128ix2 npyv_u32x2;  // 定义两个 __m128i 的无符号 32-bit 整数 SIMD 结构体
typedef npyv_m128ix2 npyv_s32x2;  // 定义两个 __m128i 的有符号 32-bit 整数 SIMD 结构体
typedef npyv_m128ix2 npyv_u64x2;  // 定义两个 __m128i 的无符号 64-bit 整数 SIMD 结构体
typedef npyv_m128ix2 npyv_s64x2;  // 定义两个 __m128i 的有符号 64-bit 整数 SIMD 结构体

typedef struct { __m128i val[3]; } npyv_m128ix3;  // 定义包含三个 __m128i 的 SIMD 结构体
typedef npyv_m128ix3 npyv_u8x3;  // 定义三个 __m128i 的无符号 8-bit 整数 SIMD 结构体
typedef npyv_m128ix3 npyv_s8x3;  // 定义三个 __m128i 的有符号 8-bit 整数 SIMD 结构体
typedef npyv_m128ix3 npyv_u16x3;  // 定义三个 __m128i 的无符号 16-bit 整数 SIMD 结构体
typedef npyv_m128ix3 npyv_s16x3;  // 定义三个 __m128i 的有符号 16-bit 整数 SIMD 结构体
typedef npyv_m128ix3 npyv_u32x3;  // 定义三个 __m128i 的无符号 32-bit 整数 SIMD 结构体
typedef npyv_m128ix3 npyv_s32x3;  // 定义三个 __m128i 的有符号 32-bit 整数 SIMD 结构体
typedef npyv_m128ix3 npyv_u64x3;  // 定义三个 __m128i 的无符号 64-bit 整数 SIMD 结构体
typedef npyv_m128ix3 npyv_s64x3;  // 定义三个 __m128i 的有符号 64-bit 整数 SIMD 结构体

typedef struct { __m128  val[2]; } npyv_f32x2;  // 定义包含两个 __m128 的单精度浮点数 SIMD 结构体
typedef struct { __m128d val[2]; } npyv_f64x2;  // 定义包含两个 __m128d 的双精度浮点数 SIMD 结构体
typedef struct { __m128  val[3]; } npyv_f32x3;  // 定义包含三个 __m128 的单精度浮点数 SIMD 结构体
typedef struct { __m128d val[3]; } npyv_f64x3;  // 定义包含三个 __m128d 的双精度浮点数 SIMD 结构体

#define npyv_nlanes_u8  16  // 定义无符号 8-bit 整数 SIMD 向量的长度
#define npyv_nlanes_s8  16  // 定义有符号 8-bit 整数 SIMD 向量的长度
#define npyv_nlanes_u16 8   // 定义无符号 16-bit 整数 SIMD 向量的长度
#define npyv_nlanes_s16 8   // 定义有符号 16-bit 整数 SIMD 向量的长度
#define npyv_nlanes_u32 4   // 定义无符号 32-bit 整数 SIMD 向量的长度
#define npyv_nlanes_s32 4   // 定义有符号 32-bit 整数 SIMD 向量的长度
#define npyv_nlanes_u64 2   // 定义无符号 64-bit 整数 SIMD 向量的长度
#define npyv_nlanes_s64 2   // 定义有符号 64-bit 整数 SIMD 向量的长度
#define npyv_nlanes_f32 4   // 定义单精度浮点数 SIMD 向量的长度
#define npyv_nlanes_f64 2   // 定义双精度浮点数 SIMD 向量的长度

#include "utils.h"  // 包含实用工具函数的头文件
#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\sse\utils.h

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

#ifndef _NPY_SIMD_SSE_UTILS_H
#define _NPY_SIMD_SSE_UTILS_H

#if !defined(__x86_64__) && !defined(_M_X64)
// 如果不是 x86_64 架构,则定义 npyv128_cvtsi128_si64 函数
NPY_FINLINE npy_int64 npyv128_cvtsi128_si64(__m128i a)
{
    // 创建一个 16 字节对齐的整数数组 idx 来存储 __m128i a 的内容
    npy_int64 NPY_DECL_ALIGNED(16) idx[2];
    // 将 __m128i a 的内容存储到 idx 数组中
    _mm_store_si128((__m128i *)idx, a);
    // 返回 idx 数组的第一个元素
    return idx[0];
}
#else
    // 如果是 x86_64 架构,则直接使用 SSE 提供的 _mm_cvtsi128_si64 函数
    #define npyv128_cvtsi128_si64 _mm_cvtsi128_si64
#endif

#endif // _NPY_SIMD_SSE_UTILS_H

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

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

#ifndef _NPY_SIMD_VEC_ARITHMETIC_H
#define _NPY_SIMD_VEC_ARITHMETIC_H

/***************************
 * Addition
 ***************************/
// 定义不饱和加法操作宏
#define npyv_add_u8  vec_add
#define npyv_add_s8  vec_add
#define npyv_add_u16 vec_add
#define npyv_add_s16 vec_add
#define npyv_add_u32 vec_add
#define npyv_add_s32 vec_add
#define npyv_add_u64 vec_add
#define npyv_add_s64 vec_add
#if NPY_SIMD_F32
#define npyv_add_f32 vec_add
#endif
#define npyv_add_f64 vec_add

// 饱和加法的条件编译分支
#ifdef NPY_HAVE_VX
    // 定义使用 VX 扩展的饱和加法函数实现
    #define NPYV_IMPL_VX_ADDS(SFX, PSFX) \
        NPY_FINLINE npyv_##SFX npyv_adds_##SFX(npyv_##SFX a, npyv_##SFX b)\
        {                                                                 \
            return vec_pack##PSFX(                                        \
                vec_add(vec_unpackh(a), vec_unpackh(b)),                  \
                vec_add(vec_unpackl(a), vec_unpackl(b))                   \
            );                                                            \
        }

    // 各数据类型的饱和加法宏定义
    NPYV_IMPL_VX_ADDS(u8, su)
    NPYV_IMPL_VX_ADDS(s8, s)
    NPYV_IMPL_VX_ADDS(u16, su)
    NPYV_IMPL_VX_ADDS(s16, s)
#else // VSX
    // 如果没有 VX 扩展,则使用标准的饱和加法宏定义
    #define npyv_adds_u8  vec_adds
    #define npyv_adds_s8  vec_adds
    #define npyv_adds_u16 vec_adds
    #define npyv_adds_s16 vec_adds
#endif

/***************************
 * Subtraction
 ***************************/
// 定义不饱和减法操作宏
#define npyv_sub_u8  vec_sub
#define npyv_sub_s8  vec_sub
#define npyv_sub_u16 vec_sub
#define npyv_sub_s16 vec_sub
#define npyv_sub_u32 vec_sub
#define npyv_sub_s32 vec_sub
#define npyv_sub_u64 vec_sub
#define npyv_sub_s64 vec_sub
#if NPY_SIMD_F32
#define npyv_sub_f32 vec_sub
#endif
#define npyv_sub_f64 vec_sub

// 饱和减法的条件编译分支
#ifdef NPY_HAVE_VX
    // 定义使用 VX 扩展的饱和减法函数实现
    #define NPYV_IMPL_VX_SUBS(SFX, PSFX)                                  \
        NPY_FINLINE npyv_##SFX npyv_subs_##SFX(npyv_##SFX a, npyv_##SFX b)\
        {                                                                 \
            return vec_pack##PSFX(                                        \
                vec_sub(vec_unpackh(a), vec_unpackh(b)),                  \
                vec_sub(vec_unpackl(a), vec_unpackl(b))                   \
            );                                                            \
        }

    // 各数据类型的饱和减法宏定义
    NPYV_IMPL_VX_SUBS(u8, su)
    NPYV_IMPL_VX_SUBS(s8, s)
    NPYV_IMPL_VX_SUBS(u16, su)
    NPYV_IMPL_VX_SUBS(s16, s)
#else // VSX
    // 如果没有 VX 扩展,则使用标准的饱和减法宏定义
    #define npyv_subs_u8  vec_subs
    #define npyv_subs_s8  vec_subs
    #define npyv_subs_u16 vec_subs
    #define npyv_subs_s16 vec_subs
#endif

/***************************
 * Multiplication
 ***************************/
// 定义不饱和乘法操作宏
// 在 GCC 6 及以下版本中,vec_mul 仅支持某些精度和长长整型
#if defined(NPY_HAVE_VSX) && defined(__GNUC__) && __GNUC__ < 7
    // 定义宏 NPYV_IMPL_VSX_MUL,生成用于乘法操作的函数
    #define NPYV_IMPL_VSX_MUL(T_VEC, SFX, ...)              \
        // 定义内联函数 npyv_mul_##SFX,用于向量类型 T_VEC,执行乘法操作
        NPY_FINLINE T_VEC npyv_mul_##SFX(T_VEC a, T_VEC b)  \
        {                                                   \
            // 创建一个常量向量 ev_od,包含给定位置的乘法结果索引
            const npyv_u8 ev_od = {__VA_ARGS__};            \
            // 使用 vec_perm 函数对乘法的偶数和奇数位置结果进行排列
            return vec_perm(                                \
                // 使用 vec_mule 执行乘法,生成偶数位置的结果
                (T_VEC)vec_mule(a, b),                      \
                // 使用 vec_mulo 执行乘法,生成奇数位置的结果,并根据 ev_od 排列
                (T_VEC)vec_mulo(a, b), ev_od                \
            );                                              \
        }

    // 使用宏定义的函数,生成不同类型的乘法函数并调用
    NPYV_IMPL_VSX_MUL(npyv_u8,  u8,  0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30)
    NPYV_IMPL_VSX_MUL(npyv_s8,  s8,  0, 16, 2, 18, 4, 20, 6, 22, 8, 24, 10, 26, 12, 28, 14, 30)
    NPYV_IMPL_VSX_MUL(npyv_u16, u16, 0, 1, 16, 17, 4, 5, 20, 21, 8, 9, 24, 25, 12, 13, 28, 29)
    NPYV_IMPL_VSX_MUL(npyv_s16, s16, 0, 1, 16, 17, 4, 5, 20, 21, 8, 9, 24, 25, 12, 13, 28, 29)

    // 宏 NPYV_IMPL_VSX_MUL_32,定义用于 32 位整数的乘法操作函数
    // 使用 asm 内联汇编执行 vmuluwm 指令,对无符号或有符号整数进行乘法操作
    #define NPYV_IMPL_VSX_MUL_32(T_VEC, SFX)                \
        NPY_FINLINE T_VEC npyv_mul_##SFX(T_VEC a, T_VEC b)  \
        {                                                   \
            T_VEC ret;                                      \
            __asm__ __volatile__(                           \
                // 使用 vmuluwm 指令,将 a 和 b 进行乘法,结果存储到 ret
                "vmuluwm %0,%1,%2" :                        \
                "=v" (ret) : "v" (a), "v" (b)               \
            );                                              \
            return ret;                                     \
        }

    // 生成不同类型的 32 位整数乘法函数并调用
    NPYV_IMPL_VSX_MUL_32(npyv_u32, u32)
    NPYV_IMPL_VSX_MUL_32(npyv_s32, s32)
#else
#define npyv_mul_u8  vec_mul
#define npyv_mul_s8  vec_mul
#define npyv_mul_u16 vec_mul
#define npyv_mul_s16 vec_mul
#define npyv_mul_u32 vec_mul
#define npyv_mul_s32 vec_mul
#endif
#if NPY_SIMD_F32
#define npyv_mul_f32 vec_mul
#endif
#define npyv_mul_f64 vec_mul


// 如果未定义 NPY_SIMD_F32,则定义以下整数类型的乘法宏为 vec_mul
// 这些宏分别用于无符号和有符号的 81632 位整数乘法
#else
#define npyv_mul_u8  vec_mul
#define npyv_mul_s8  vec_mul
#define npyv_mul_u16 vec_mul
#define npyv_mul_s16 vec_mul
#define npyv_mul_u32 vec_mul
#define npyv_mul_s32 vec_mul
#endif

// 如果定义了 NPY_SIMD_F32,则定义单精度浮点数乘法宏为 vec_mul
#if NPY_SIMD_F32
#define npyv_mul_f32 vec_mul
#endif

// 定义双精度浮点数乘法宏为 vec_mul
#define npyv_mul_f64 vec_mul

/***************************
 * Integer Division
 ***************************/

// 查看 simd/intdiv.h 以获取更多详细信息
// 对每个无符号 8 位元素进行除法,除数预先计算
NPY_FINLINE npyv_u8 npyv_divc_u8(npyv_u8 a, const npyv_u8x3 divisor)
{
#ifdef NPY_HAVE_VX
    // 使用向量化指令集 VX 执行无符号 8 位整数乘法高位计算
    npyv_u8  mulhi    = vec_mulh(a, divisor.val[0]);
#else // VSX
    // VSX 指令集下的替代实现
    const npyv_u8 mergeo_perm = {
        1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31
    };
    // 执行无符号 8 位整数乘法的高位部分
    npyv_u16 mul_even = vec_mule(a, divisor.val[0]);
    npyv_u16 mul_odd  = vec_mulo(a, divisor.val[0]);
    npyv_u8  mulhi    = (npyv_u8)vec_perm(mul_even, mul_odd, mergeo_perm);
#endif
    // 计算 floor(a/d) 的近似值
    // floor(a/d)     = (mulhi + ((a-mulhi) >> sh1)) >> sh2
    npyv_u8 q         = vec_sub(a, mulhi);
            q         = vec_sr(q, divisor.val[1]);
            q         = vec_add(mulhi, q);
            q         = vec_sr(q, divisor.val[2]);
    return  q;
}

// 对每个有符号 8 位元素进行除法,除数预先计算
NPY_FINLINE npyv_s8 npyv_divc_s8(npyv_s8 a, const npyv_s8x3 divisor)
{
#ifdef NPY_HAVE_VX
    // 使用向量化指令集 VX 执行有符号 8 位整数乘法高位计算
    npyv_s8  mulhi    = vec_mulh(a, divisor.val[0]);
#else
    // VSX 指令集下的替代实现
    const npyv_u8 mergeo_perm = {
        1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31
    };
    // 执行有符号 8 位整数乘法的高位部分
    npyv_s16 mul_even = vec_mule(a, divisor.val[0]);
    npyv_s16 mul_odd  = vec_mulo(a, divisor.val[0]);
    npyv_s8  mulhi    = (npyv_s8)vec_perm(mul_even, mul_odd, mergeo_perm);
#endif
    // 计算 trunc(a/d) 的近似值
    // q              = ((a + mulhi) >> sh1) - XSIGN(a)
    // trunc(a/d)     = (q ^ dsign) - dsign
    npyv_s8 q         = vec_sra_s8(vec_add(a, mulhi), (npyv_u8)divisor.val[1]);
            q         = vec_sub(q, vec_sra_s8(a, npyv_setall_u8(7)));
            q         = vec_sub(vec_xor(q, divisor.val[2]), divisor.val[2]);
    return  q;
}

// 对每个无符号 16 位元素进行除法,除数预先计算
NPY_FINLINE npyv_u16 npyv_divc_u16(npyv_u16 a, const npyv_u16x3 divisor)
{
#ifdef NPY_HAVE_VX
    // 使用向量化指令集 VX 执行无符号 16 位整数乘法高位计算
    npyv_u16 mulhi    = vec_mulh(a, divisor.val[0]);
#else // VSX
    // VSX 指令集下的替代实现
    const npyv_u8 mergeo_perm = {
        2, 3, 18, 19, 6, 7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31
    };
    // 执行无符号 16 位整数乘法的高位部分
    npyv_u32 mul_even = vec_mule(a, divisor.val[0]);
    npyv_u32 mul_odd  = vec_mulo(a, divisor.val[0]);
    npyv_u16 mulhi    = (npyv_u16)vec_perm(mul_even, mul_odd, mergeo_perm);
#endif
    // 计算 floor(a/d) 的近似值
    // floor(a/d)     = (mulhi + ((a-mulhi) >> sh1)) >> sh2
    npyv_u16 q        = vec_sub(a, mulhi);
             q        = vec_sr(q, divisor.val[1]);
             q        = vec_add(mulhi, q);
             q        = vec_sr(q, divisor.val[2]);
    return   q;
}
// divide each signed 16-bit element by a precomputed divisor (round towards zero)
NPY_FINLINE npyv_s16 npyv_divc_s16(npyv_s16 a, const npyv_s16x3 divisor)
{
#ifdef NPY_HAVE_VX
    // Perform vectorized high part of signed multiplication using VX instructions
    npyv_s16 mulhi    = vec_mulh(a, divisor.val[0]);
#else // VSX
    // Permutation pattern to merge high parts from vec_mule and vec_mulo results
    const npyv_u8 mergeo_perm = {
        2, 3, 18, 19, 6, 7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31
    };
    // Compute high parts of signed multiplication separately for even and odd lanes
    npyv_s32 mul_even = vec_mule(a, divisor.val[0]);
    npyv_s32 mul_odd  = vec_mulo(a, divisor.val[0]);
    // Combine high parts using permutation to get the result for each lane
    npyv_s16 mulhi    = (npyv_s16)vec_perm(mul_even, mul_odd, mergeo_perm);
#endif
    // Calculate quotient using divisor and shift parameters
    npyv_s16 q        = vec_sra_s16(vec_add(a, mulhi), (npyv_u16)divisor.val[1]);
    // Adjust quotient by subtracting the sign of the input (XOR with all 1s) and divisor
             q        = vec_sub(q, vec_sra_s16(a, npyv_setall_u16(15)));
             q        = vec_sub(vec_xor(q, divisor.val[2]), divisor.val[2]);
    return   q;
}

// divide each unsigned 32-bit element by a precomputed divisor
NPY_FINLINE npyv_u32 npyv_divc_u32(npyv_u32 a, const npyv_u32x3 divisor)
{
#if defined(NPY_HAVE_VSX4) || defined(NPY_HAVE_VX)
    // Perform vectorized high part of unsigned multiplication using VX or VSX4 instructions
    npyv_u32 mulhi    = vec_mulh(a, divisor.val[0]);
#else // VSX
    #if defined(__GNUC__) && __GNUC__ < 8
        // Doubleword integer wide multiplication using assembly for older GCC versions
        npyv_u64 mul_even, mul_odd;
        __asm__ ("vmulouw %0,%1,%2" : "=v" (mul_even) : "v" (a), "v" (divisor.val[0]));
        __asm__ ("vmuleuw %0,%1,%2" : "=v" (mul_odd)  : "v" (a), "v" (divisor.val[0]));
    #else
        // Doubleword integer wide multiplication using vec_mule and vec_mulo for GCC >= 8
        npyv_u64 mul_even = vec_mule(a, divisor.val[0]);
        npyv_u64 mul_odd  = vec_mulo(a, divisor.val[0]);
    #endif
    // Combine high parts of unsigned multiplication results into 32-bit lanes
    npyv_u32 mulhi    = vec_mergeo((npyv_u32)mul_even, (npyv_u32)mul_odd);
#endif
    // Calculate floor(x/d) using shifts and addition
    npyv_u32 q        = vec_sub(a, mulhi);
             q        = vec_sr(q, divisor.val[1]);
             q        = vec_add(mulhi, q);
             q        = vec_sr(q, divisor.val[2]);
    return   q;
}

// divide each signed 32-bit element by a precomputed divisor (round towards zero)
NPY_FINLINE npyv_s32 npyv_divc_s32(npyv_s32 a, const npyv_s32x3 divisor)
{
#if defined(NPY_HAVE_VSX4) || defined(NPY_HAVE_VX)
    // Perform vectorized high part of signed multiplication using VX or VSX4 instructions
    npyv_s32 mulhi    = vec_mulh(a, divisor.val[0]);
#else
    #if defined(__GNUC__) && __GNUC__ < 8
        // Doubleword integer wide multiplication using assembly for older GCC versions
        npyv_s64 mul_even, mul_odd;
        __asm__ ("vmulosw %0,%1,%2" : "=v" (mul_even) : "v" (a), "v" (divisor.val[0]));
        __asm__ ("vmulesw %0,%1,%2" : "=v" (mul_odd)  : "v" (a), "v" (divisor.val[0]));
    #else
        // Doubleword integer wide multiplication using vec_mule and vec_mulo for GCC >= 8
        npyv_s64 mul_even = vec_mule(a, divisor.val[0]);
        npyv_s64 mul_odd  = vec_mulo(a, divisor.val[0]);
    #endif
    // Combine high parts of signed multiplication results into 32-bit lanes
    npyv_s32 mulhi    = vec_mergeo((npyv_s32)mul_even, (npyv_s32)mul_odd);
#endif
    // Calculate quotient using divisor and shift parameters
    npyv_s32 q        = vec_sub(a, mulhi);
             q        = vec_sr(q, divisor.val[1]);
             q        = vec_add(mulhi, q);
             q        = vec_sr(q, divisor.val[2]);
    return   q;
}
    // 计算有符号乘法的高位结果
    npyv_s32 mulhi = vec_mergeo((npyv_s32)mul_even, (npyv_s32)mul_odd);
// q              = ((a + mulhi) >> sh1) - XSIGN(a)
// 对 a 加上 mulhi 后右移 sh1 位,再减去 XSIGN(a) 的结果赋值给 q
npyv_s32 q        = vec_sra_s32(vec_add(a, mulhi), (npyv_u32)divisor.val[1]);
         q        = vec_sub(q, vec_sra_s32(a, npyv_setall_u32(31)));
         q        = vec_sub(vec_xor(q, divisor.val[2]), divisor.val[2]);
// 返回 q
return   q;
}
// divide each unsigned 64-bit element by a precomputed divisor
NPY_FINLINE npyv_u64 npyv_divc_u64(npyv_u64 a, const npyv_u64x3 divisor)
{
#if defined(NPY_HAVE_VSX4)
// 如果定义了 NPY_HAVE_VSX4,则使用 vec_div 进行向量除法操作
return vec_div(a, divisor.val[0]);
#else
// 否则,从 divisor 中提取第一个元素 d,并将 a 的每个元素除以 d 得到结果向量
const npy_uint64 d = vec_extract(divisor.val[0], 0);
return npyv_set_u64(vec_extract(a, 0) / d, vec_extract(a, 1) / d);
#endif
}
// divide each signed 64-bit element by a precomputed divisor (round towards zero)
NPY_FINLINE npyv_s64 npyv_divc_s64(npyv_s64 a, const npyv_s64x3 divisor)
{
// 检查是否有可能溢出的条件,如果 a 是 -2^63 并且 divisor 的标志位为真,使用 divisor 的第一个元素作为除数 d
npyv_b64 overflow = npyv_and_b64(vec_cmpeq(a, npyv_setall_s64(-1LL << 63)), (npyv_b64)divisor.val[1]);
npyv_s64 d = vec_sel(divisor.val[0], npyv_setall_s64(1), overflow);
// 返回 a 向量中每个元素除以 d 的结果向量
return vec_div(a, d);
}
/***************************
 * Division
 ***************************/
#if NPY_SIMD_F32
#define npyv_div_f32 vec_div
#endif
#define npyv_div_f64 vec_div

/***************************
 * FUSED
 ***************************/
// multiply and add, a*b + c
#define npyv_muladd_f64 vec_madd
// multiply and subtract, a*b - c
#define npyv_mulsub_f64 vec_msub
#if NPY_SIMD_F32
#define npyv_muladd_f32 vec_madd
#define npyv_mulsub_f32 vec_msub
#endif
#if defined(NPY_HAVE_VXE) || defined(NPY_HAVE_VSX)
// negate multiply and add, -(a*b) + c
#define npyv_nmuladd_f32 vec_nmsub // 等同于 -(a*b - c)
#define npyv_nmuladd_f64 vec_nmsub
// negate multiply and subtract, -(a*b) - c
#define npyv_nmulsub_f64 vec_nmadd
#define npyv_nmulsub_f32 vec_nmadd // 等同于 -(a*b + c)
#else
NPY_FINLINE npyv_f64 npyv_nmuladd_f64(npyv_f64 a, npyv_f64 b, npyv_f64 c)
{ return vec_neg(vec_msub(a, b, c)); }
NPY_FINLINE npyv_f64 npyv_nmulsub_f64(npyv_f64 a, npyv_f64 b, npyv_f64 c)
{ return vec_neg(vec_madd(a, b, c)); }
#endif
// multiply, add for odd elements and subtract even elements.
// (a * b) -+ c
#if NPY_SIMD_F32
NPY_FINLINE npyv_f32 npyv_muladdsub_f32(npyv_f32 a, npyv_f32 b, npyv_f32 c)
{
// 使用 msign 进行乘法和减法,a*b - (msign ^ c)
const npyv_f32 msign = npyv_set_f32(-0.0f, 0.0f, -0.0f, 0.0f);
return npyv_muladd_f32(a, b, npyv_xor_f32(msign, c));
}
#endif
NPY_FINLINE npyv_f64 npyv_muladdsub_f64(npyv_f64 a, npyv_f64 b, npyv_f64 c)
{
// 使用 msign 进行乘法和减法,a*b - (msign ^ c)
const npyv_f64 msign = npyv_set_f64(-0.0, 0.0);
return npyv_muladd_f64(a, b, npyv_xor_f64(msign, c));
}
/***************************
 * Summation
 ***************************/
// reduce sum across vector
NPY_FINLINE npy_uint64 npyv_sum_u64(npyv_u64 a)
{
#ifdef NPY_HAVE_VX
// 如果定义了 NPY_HAVE_VX,则使用 vec_sum_u128 在零向量 zero 上对 a 进行求和并提取结果的第二部分
const npyv_u64 zero = npyv_zero_u64();
return vec_extract((npyv_u64)vec_sum_u128(a, zero), 1);
#else
// 否则,使用 vec_add 对 a 进行求和,并从结果中提取第一个元素作为最终的求和结果
return vec_extract(vec_add(a, vec_mergel(a, a)), 0);
#endif
}
// 定义一个内联函数,用于计算给定的 npyv_u32 向量的总和
NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
{
#ifdef NPY_HAVE_VX
    // 如果支持 VX 指令集,创建一个零向量 npyv_u32 zero,并使用 vec_sum_u128 计算向量 a 和 zero 的总和,然后提取第三个元素作为结果
    const npyv_u32 zero = npyv_zero_u32();
    return vec_extract((npyv_u32)vec_sum_u128(a, zero), 3);
#else
    // 如果不支持 VX 指令集,计算向量 a 的一系列操作,返回第一个元素作为结果
    const npyv_u32 rs = vec_add(a, vec_sld(a, a, 8));
    return vec_extract(vec_add(rs, vec_sld(rs, rs, 4)), 0);
#endif
}

#if NPY_SIMD_F32
// 如果支持单精度浮点数 SIMD 计算,定义一个内联函数计算 npyv_f32 向量的总和
NPY_FINLINE float npyv_sum_f32(npyv_f32 a)
{
    // 将向量 a 与其自身的高低部分相加得到 sum,然后返回 sum 的前两个元素相加的结果
    npyv_f32 sum = vec_add(a, npyv_combineh_f32(a, a));
    return vec_extract(sum, 0) + vec_extract(sum, 1);
    (void)sum; // 防止编译器警告
}
#endif

// 定义一个内联函数,计算 npyv_f64 向量的总和
NPY_FINLINE double npyv_sum_f64(npyv_f64 a)
{
    // 直接返回向量 a 的第一个和第二个元素相加的结果
    return vec_extract(a, 0) + vec_extract(a, 1);
}

// 扩展源向量并执行求和操作
NPY_FINLINE npy_uint16 npyv_sumup_u8(npyv_u8 a)
{
#ifdef NPY_HAVE_VX
    // 如果支持 VX 指令集,创建一个零向量 npyv_u8 zero,计算向量 a 和 zero 的四个元素的和,然后将结果作为 npyv_u32 传递给 npyv_sum_u32 函数,最后转换为 npy_uint16 类型返回
    const npyv_u8 zero = npyv_zero_u8();
    npyv_u32 sum4 = vec_sum4(a, zero);
    return (npy_uint16)npyv_sum_u32(sum4);
#else
    // 如果不支持 VX 指令集,使用向量 a 和 zero 的扩展值计算向量 a 的总和,最后提取第四个元素作为结果返回
    const npyv_u32 zero = npyv_zero_u32();
    npyv_u32 four = vec_sum4s(a, zero);
    npyv_s32 one  = vec_sums((npyv_s32)four, (npyv_s32)zero);
    return (npy_uint16)vec_extract(one, 3);
    (void)one; // 防止编译器警告
#endif
}

// 定义一个内联函数,计算 npyv_u16 向量的总和
NPY_FINLINE npy_uint32 npyv_sumup_u16(npyv_u16 a)
{
#ifdef NPY_HAVE_VX
    // 如果支持 VX 指令集,计算向量 a 的两个和,将结果作为 npyv_u64 传递给 npyv_sum_u64 函数,最后转换为 npy_uint32 类型返回
    npyv_u64 sum = vec_sum2(a, npyv_zero_u16());
    return (npy_uint32)npyv_sum_u64(sum);
#else // VSX
    // 如果不支持 VX 指令集,使用向量 a 的扩展值计算 a 的总和,最后提取第四个元素作为结果返回
    const npyv_s32 zero = npyv_zero_s32();
    npyv_u32x2 eight = npyv_expand_u32_u16(a);
    npyv_u32   four  = vec_add(eight.val[0], eight.val[1]);
    npyv_s32   one   = vec_sums((npyv_s32)four, zero);
    return (npy_uint32)vec_extract(one, 3);
    (void)one; // 防止编译器警告
#endif
}

#endif // _NPY_SIMD_VEC_ARITHMETIC_H

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

// 如果没有定义 NPY_SIMD,则输出错误提示信息
#ifndef NPY_SIMD
    #error "Not a standalone header"
#endif

// 如果没有定义 _NPY_SIMD_VEC_CVT_H,则定义它
#ifndef _NPY_SIMD_VEC_CVT_H
#define _NPY_SIMD_VEC_CVT_H

// 将布尔矢量转换为整数矢量
#define npyv_cvt_u8_b8(BL)   ((npyv_u8)  BL)
#define npyv_cvt_s8_b8(BL)   ((npyv_s8)  BL)
#define npyv_cvt_u16_b16(BL) ((npyv_u16) BL)
#define npyv_cvt_s16_b16(BL) ((npyv_s16) BL)
#define npyv_cvt_u32_b32(BL) ((npyv_u32) BL)
#define npyv_cvt_s32_b32(BL) ((npyv_s32) BL)
#define npyv_cvt_u64_b64(BL) ((npyv_u64) BL)
#define npyv_cvt_s64_b64(BL) ((npyv_s64) BL)
#if NPY_SIMD_F32
    #define npyv_cvt_f32_b32(BL) ((npyv_f32) BL)
#endif
#define npyv_cvt_f64_b64(BL) ((npyv_f64) BL)

// 将整数矢量转换为布尔矢量
#define npyv_cvt_b8_u8(A)   ((npyv_b8)  A)
#define npyv_cvt_b8_s8(A)   ((npyv_b8)  A)
#define npyv_cvt_b16_u16(A) ((npyv_b16) A)
#define npyv_cvt_b16_s16(A) ((npyv_b16) A)
#define npyv_cvt_b32_u32(A) ((npyv_b32) A)
#define npyv_cvt_b32_s32(A) ((npyv_b32) A)
#define npyv_cvt_b64_u64(A) ((npyv_b64) A)
#define npyv_cvt_b64_s64(A) ((npyv_b64) A)
#if NPY_SIMD_F32
    #define npyv_cvt_b32_f32(A) ((npyv_b32) A)
#endif
#define npyv_cvt_b64_f64(A) ((npyv_b64) A)

// 扩展
NPY_FINLINE npyv_u16x2 npyv_expand_u16_u8(npyv_u8 data)
{
    npyv_u16x2 r;
#ifdef NPY_HAVE_VX
    r.val[0] = vec_unpackh(data);
    r.val[1] = vec_unpackl(data);
#else
    npyv_u8 zero = npyv_zero_u8();
    r.val[0] = (npyv_u16)vec_mergeh(data, zero);
    r.val[1] = (npyv_u16)vec_mergel(data, zero);
#endif
    return r;
}

NPY_FINLINE npyv_u32x2 npyv_expand_u32_u16(npyv_u16 data)
{
    npyv_u32x2 r;
#ifdef NPY_HAVE_VX
    r.val[0] = vec_unpackh(data);
    r.val[1] = vec_unpackl(data);
#else
    npyv_u16 zero = npyv_zero_u16();
    r.val[0] = (npyv_u32)vec_mergeh(data, zero);
    r.val[1] = (npyv_u32)vec_mergel(data, zero);
#endif
    return r;
}

// 将两个16位布尔值打包成一个8位布尔矢量
NPY_FINLINE npyv_b8 npyv_pack_b8_b16(npyv_b16 a, npyv_b16 b) {
    return vec_pack(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 = vec_pack(a, b);
    npyv_b16 cd = vec_pack(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 = vec_pack(a, b);
    npyv_b32 cd = vec_pack(c, d);
    npyv_b32 ef = vec_pack(e, f);
    npyv_b32 gh = vec_pack(g, h);
    return npyv_pack_b8_b32(ab, cd, ef, gh);
}

// 将布尔矢量转换为整数位域
#if defined(NPY_HAVE_VXE) || defined(NPY_HAVE_VSX2)
    NPY_FINLINE npy_uint64 npyv_tobits_b8(npyv_b8 a)
    {
        const npyv_u8 qperm = npyv_set_u8(120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0);
        npyv_u16 r = (npyv_u16)vec_vbpermq((npyv_u8)a, qperm);
    #ifdef NPY_HAVE_VXE
        // 如果定义了 NPY_HAVE_VXE 宏,则使用 vec_extract(r, 3)
        return vec_extract(r, 3);
    #else
        // 如果未定义 NPY_HAVE_VXE 宏,则使用 vec_extract(r, 4)
        return vec_extract(r, 4);
    #endif
        // 用于消除模糊警告:变量 `r` 被设置但未使用 [-Wunused-but-set-variable]
    (void)r;
    }
    
    // 将 16 位整数向量转换为位表示的64位整数
    NPY_FINLINE npy_uint64 npyv_tobits_b16(npyv_b16 a)
    {
        // 定义一个字节向量 qperm
        const npyv_u8 qperm = npyv_setf_u8(128, 112, 96, 80, 64, 48, 32, 16, 0);
        // 对输入向量 a 执行 qperm 排列并将结果转换为 8 位无符号整数向量 r
        npyv_u8 r = (npyv_u8)vec_vbpermq((npyv_u8)a, qperm);
    #ifdef NPY_HAVE_VXE
        // 如果定义了 NPY_HAVE_VXE 宏,则使用 vec_extract(r, 6)
        return vec_extract(r, 6);
    #else
        // 如果未定义 NPY_HAVE_VXE 宏,则使用 vec_extract(r, 8)
        return vec_extract(r, 8);
    #endif
    // 用于消除模糊警告:变量 `r` 被设置但未使用 [-Wunused-but-set-variable]
    (void)r;
    }
    
    // 将 32 位整数向量转换为位表示的64位整数
    NPY_FINLINE npy_uint64 npyv_tobits_b32(npyv_b32 a)
    {
    #ifdef NPY_HAVE_VXE
        // 如果定义了 NPY_HAVE_VXE 宏,则定义一个特定的 qperm 字节向量
        const npyv_u8 qperm = npyv_setf_u8(128, 128, 128, 128, 128, 96, 64, 32, 0);
    #else
        // 如果未定义 NPY_HAVE_VXE 宏,则定义一个不同的 qperm 字节向量
        const npyv_u8 qperm = npyv_setf_u8(128, 96, 64, 32, 0);
    #endif
        // 对输入向量 a 执行 qperm 排列并将结果转换为 8 位无符号整数向量 r
        npyv_u8 r = (npyv_u8)vec_vbpermq((npyv_u8)a, qperm);
    #ifdef NPY_HAVE_VXE
        // 如果定义了 NPY_HAVE_VXE 宏,则使用 vec_extract(r, 6)
        return vec_extract(r, 6);
    #else
        // 如果未定义 NPY_HAVE_VXE 宏,则使用 vec_extract(r, 8)
        return vec_extract(r, 8);
    #endif
    // 用于消除模糊警告:变量 `r` 被设置但未使用 [-Wunused-but-set-variable]
    (void)r;
    }
    
    // 将 64 位整数向量转换为位表示的64位整数
    NPY_FINLINE npy_uint64 npyv_tobits_b64(npyv_b64 a)
    {
    #ifdef NPY_HAVE_VXE
        // 如果定义了 NPY_HAVE_VXE 宏,则定义一个特定的 qperm 字节向量
        const npyv_u8 qperm = npyv_setf_u8(128, 128, 128, 128, 128, 128, 128, 64, 0);
    #else
        // 如果未定义 NPY_HAVE_VXE 宏,则定义一个不同的 qperm 字节向量
        const npyv_u8 qperm = npyv_setf_u8(128, 64, 0);
    #endif
        // 对输入向量 a 执行 qperm 排列并将结果转换为 8 位无符号整数向量 r
        npyv_u8 r = (npyv_u8)vec_vbpermq((npyv_u8)a, qperm);
    #ifdef NPY_HAVE_VXE
        // 如果定义了 NPY_HAVE_VXE 宏,则使用 vec_extract(r, 6)
        return vec_extract(r, 6);
    #else
        // 如果未定义 NPY_HAVE_VXE 宏,则使用 vec_extract(r, 8)
        return vec_extract(r, 8);
    #endif
    // 用于消除模糊警告:变量 `r` 被设置但未使用 [-Wunused-but-set-variable]
    (void)r;
    }
NPY_FINLINE npyv_s32 npyv__trunc_s32_f64(npyv_f64 a, npyv_f64 b)
{
#ifdef NPY_HAVE_VX
    // 如果平台支持 VX 指令集,则使用向量打包将两个双精度向量 a 和 b 转换为带符号整数向量并返回
    return vec_packs(vec_signed(a), vec_signed(b));
// VSX
#elif defined(__IBMC__)
    // 如果使用 IBM XL C/C++ 编译器,则执行以下操作
    // 创建一个字节向量,指定低位和高位对应的位置
    const npyv_u8 seq_even = npyv_set_u8(0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27);
    // 将双精度向量 a 和 b 分别转换为带符号整数向量 lo_even 和 hi_even
    npyv_s32 lo_even = vec_cts(a, 0);
    npyv_s32 hi_even = vec_cts(b, 0);
    // 使用 seq_even 的顺序重新排列 lo_even 和 hi_even 向量,返回结果向量
    return vec_perm(lo_even, hi_even, seq_even);
#else
    // 否则,执行以下操作(适用于大多数情况,如 GCC 编译器)
    // 创建一个字节向量,指定奇数位置的序列
    const npyv_u8 seq_odd = npyv_set_u8(4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31);
    #ifdef __clang__
        // 如果编译器是 Clang
    
        // __builtin_convertvector 在许多版本上不支持这种转换
        // 幸运的是,几乎所有版本都有直接的内建函数 'xvcvdpsxws'
        // 使用内建函数 'xvcvdpsxws' 将向量 a 转换为 s32 类型的 lo_odd
        npyv_s32 lo_odd = __builtin_vsx_xvcvdpsxws(a);
        // 使用内建函数 'xvcvdpsxws' 将向量 b 转换为 s32 类型的 hi_odd
        npyv_s32 hi_odd = __builtin_vsx_xvcvdpsxws(b);
    #else // gcc
        // 如果编译器是 GCC
    
        // 声明两个 s32 类型的变量 lo_odd 和 hi_odd,稍后将通过内联汇编进行赋值
        npyv_s32 lo_odd, hi_odd;
        // 使用内联汇编执行 'xvcvdpsxws' 指令,将向量 a 转换为 s32 类型的 lo_odd
        __asm__ ("xvcvdpsxws %x0,%x1" : "=wa" (lo_odd) : "wa" (a));
        // 使用内联汇编执行 'xvcvdpsxws' 指令,将向量 b 转换为 s32 类型的 hi_odd
        __asm__ ("xvcvdpsxws %x0,%x1" : "=wa" (hi_odd) : "wa" (b));
    #endif
    
    // 使用 vec_perm 函数对 lo_odd 和 hi_odd 进行向量的混合操作,使用 seq_odd 作为混合顺序
    return vec_perm(lo_odd, hi_odd, seq_odd);
#endif
}

// 结束一个条件编译块,对应于前面的 #if NPY_SIMD_F32
#if NPY_SIMD_F32
    // 定义一个内联函数,将 npyv_f32 类型的向量 a 四舍五入为 npyv_s32 类型的向量
    NPY_FINLINE npyv_s32 npyv_round_s32_f32(npyv_f32 a)
    { return npyv__trunc_s32_f32(vec_rint(a)); }
#endif

// 定义一个内联函数,将 npyv_f64 类型的向量 a 和 b 各自四舍五入为 npyv_s32 类型的向量,并返回 a 的结果
NPY_FINLINE npyv_s32 npyv_round_s32_f64(npyv_f64 a, npyv_f64 b)
{ return npyv__trunc_s32_f64(vec_rint(a), vec_rint(b)); }

// 结束当前头文件中的条件编译块,对应于前面的 #if NPY_SIMD_F32
#endif // _NPY_SIMD_VEC_CVT_H

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

#ifndef NPY_SIMD
    // 如果未定义 NPY_SIMD 宏,则输出错误消息并终止编译
    #error "Not a standalone header"
#endif

#ifndef _NPY_SIMD_VEC_MATH_H
#define _NPY_SIMD_VEC_MATH_H
/***************************
 * Elementary
 ***************************/
// 平方根函数定义
#if NPY_SIMD_F32
    // 如果支持单精度浮点运算,则使用向量化平方根函数 vec_sqrt
    #define npyv_sqrt_f32 vec_sqrt
#endif
// 双精度浮点数平方根函数定义
#define npyv_sqrt_f64 vec_sqrt

// 倒数函数定义
#if NPY_SIMD_F32
    // 如果支持单精度浮点运算,则定义单精度浮点数的倒数函数 npyv_recip_f32
    NPY_FINLINE npyv_f32 npyv_recip_f32(npyv_f32 a)
    {
        // 定义常量 one 为所有元素为 1.0f 的向量
        const npyv_f32 one = npyv_setall_f32(1.0f);
        // 返回 one 与 a 的逐元素除法结果
        return vec_div(one, a);
    }
#endif
// 双精度浮点数的倒数函数定义
NPY_FINLINE npyv_f64 npyv_recip_f64(npyv_f64 a)
{
    // 定义常量 one 为所有元素为 1.0 的向量
    const npyv_f64 one = npyv_setall_f64(1.0);
    // 返回 one 与 a 的逐元素除法结果
    return vec_div(one, a);
}

// 绝对值函数定义
#if NPY_SIMD_F32
    // 如果支持单精度浮点运算,则使用向量化绝对值函数 vec_abs
    #define npyv_abs_f32 vec_abs
#endif
// 双精度浮点数绝对值函数定义
#define npyv_abs_f64 vec_abs

// 平方函数定义
#if NPY_SIMD_F32
    // 如果支持单精度浮点运算,则定义单精度浮点数的平方函数 npyv_square_f32
    NPY_FINLINE npyv_f32 npyv_square_f32(npyv_f32 a)
    { return vec_mul(a, a); } // 返回 a 与自身逐元素相乘的结果,即平方
#endif
// 双精度浮点数的平方函数定义
NPY_FINLINE npyv_f64 npyv_square_f64(npyv_f64 a)
{ return vec_mul(a, a); } // 返回 a 与自身逐元素相乘的结果,即平方

// 最大值函数定义,不保证处理 NaN
#if NPY_SIMD_F32
    // 如果支持单精度浮点运算,则使用向量化最大值函数 vec_max
    #define npyv_max_f32 vec_max
#endif
// 双精度浮点数最大值函数定义,不保证处理 NaN
#define npyv_max_f64 vec_max
// 最大值函数定义,支持 IEEE 浮点算术 (IEC 60559)
#if NPY_SIMD_F32
    // 如果支持单精度浮点运算,则定义单精度浮点数的最大值函数 npyv_maxp_f32
    #define npyv_maxp_f32 vec_max
#endif
// 对于不同架构,选择是否使用向量化最大值函数,如 vfmindb & vfmaxdb appears in zarch12
#if defined(NPY_HAVE_VXE) || defined(NPY_HAVE_VSX)
    // 如果定义了 NPY_HAVE_VXE 或 NPY_HAVE_VSX,使用向量化最大值函数 vec_max
    #define npyv_maxp_f64 vec_max
#else
    // 否则,在没有特定支持的架构下,使用自定义最大值函数 npyv_maxp_f64
    NPY_FINLINE npyv_f64 npyv_maxp_f64(npyv_f64 a, npyv_f64 b)
    {
        // 定义非 NaN 掩码
        npyv_b64 nn_a = npyv_notnan_f64(a);
        npyv_b64 nn_b = npyv_notnan_f64(b);
        // 返回根据非 NaN 掩码选择的最大值
        return vec_max(vec_sel(b, a, nn_a), vec_sel(a, b, nn_b));
    }
#endif
#if NPY_SIMD_F32
    // 如果支持单精度浮点运算,则定义单精度浮点数的非 NaN 最大值函数 npyv_maxn_f32
    NPY_FINLINE npyv_f32 npyv_maxn_f32(npyv_f32 a, npyv_f32 b)
    {
        // 定义非 NaN 掩码
        npyv_b32 nn_a = npyv_notnan_f32(a);
        npyv_b32 nn_b = npyv_notnan_f32(b);
        // 计算最大值并根据非 NaN 掩码选择
        npyv_f32 max = vec_max(a, b);
        return vec_sel(b, vec_sel(a, max, nn_a), nn_b);
    }
#endif
// 双精度浮点数的非 NaN 最大值函数定义
NPY_FINLINE npyv_f64 npyv_maxn_f64(npyv_f64 a, npyv_f64 b)
{
    // 定义非 NaN 掩码
    npyv_b64 nn_a = npyv_notnan_f64(a);
    npyv_b64 nn_b = npyv_notnan_f64(b);
    // 计算最大值并根据非 NaN 掩码选择
    npyv_f64 max = vec_max(a, b);
    return vec_sel(b, vec_sel(a, max, nn_a), nn_b);
}

// 最大值函数定义,整数运算
#define npyv_max_u8 vec_max
#define npyv_max_s8 vec_max
#define npyv_max_u16 vec_max
#define npyv_max_s16 vec_max
#define npyv_max_u32 vec_max
#define npyv_max_s32 vec_max
#define npyv_max_u64 vec_max
#define npyv_max_s64 vec_max

// 最小值函数定义,不保证处理 NaN
#if NPY_SIMD_F32
    // 如果支持单精度浮点运算,则使用向量化最小值函数 vec_min
    #define npyv_min_f32 vec_min
#endif
// 双精度浮点数最小值函数定义,不保证处理 NaN
#define npyv_min_f64 vec_min
// 最小值函数定义,支持 IEEE 浮点算术 (IEC 60559)
#if NPY_SIMD_F32
    // 如果支持单精度浮点运算,则定义单精度浮点数的最小值函数 npyv_minp_f32
    #define npyv_minp_f32 vec_min
#endif
#if defined(NPY_HAVE_VXE) || defined(NPY_HAVE_VSX)
    // 如果定义了 NPY_HAVE_VXE 或 NPY_HAVE_VSX,使用向量化最小值函数 vec_min
    #define npyv_minp_f64 vec_min
#else
    // 定义一个内联函数 npyv_minp_f64,用于计算两个 npyv_f64 类型向量 a 和 b 的最小值
    NPY_FINLINE npyv_f64 npyv_minp_f64(npyv_f64 a, npyv_f64 b)
    {
        // 获取向量 a 中非 NaN 元素的掩码
        npyv_b64 nn_a = npyv_notnan_f64(a);
        // 获取向量 b 中非 NaN 元素的掩码
        npyv_b64 nn_b = npyv_notnan_f64(b);
        // 使用掩码 nn_a 和 nn_b,选择 a 和 b 中的对应元素形成新的向量,以确保不考虑 NaN 值
        return vec_min(vec_sel(b, a, nn_a), vec_sel(a, b, nn_b));
    }
#ifdef
#if NPY_SIMD_F32
    // 如果编译器支持单精度 SIMD 指令集,则定义以下函数
    NPY_FINLINE npyv_f32 npyv_minn_f32(npyv_f32 a, npyv_f32 b)
    {
        // 获取非 NaN 的元素掩码
        npyv_b32 nn_a = npyv_notnan_f32(a);
        npyv_b32 nn_b = npyv_notnan_f32(b);
        // 计算向量 a 和 b 的最小值
        npyv_f32 min = vec_min(a, b);
        // 根据 nn_b 选择 b 或者 a 的最小值
        return vec_sel(b, vec_sel(a, min, nn_a), nn_b);
    }
#endif

// 定义双精度版本的最小值函数
NPY_FINLINE npyv_f64 npyv_minn_f64(npyv_f64 a, npyv_f64 b)
{
    // 获取双精度向量 a 和 b 中非 NaN 的掩码
    npyv_b64 nn_a = npyv_notnan_f64(a);
    npyv_b64 nn_b = npyv_notnan_f64(b);
    // 计算向量 a 和 b 的最小值
    npyv_f64 min = vec_min(a, b);
    // 根据 nn_b 选择 b 或者 a 的最小值
    return vec_sel(b, vec_sel(a, min, nn_a), nn_b);
}

// Minimum, integer operations
// 定义各整数类型的最小值宏
#define npyv_min_u8 vec_min
#define npyv_min_s8 vec_min
#define npyv_min_u16 vec_min
#define npyv_min_s16 vec_min
#define npyv_min_u32 vec_min
#define npyv_min_s32 vec_min
#define npyv_min_u64 vec_min
#define npyv_min_s64 vec_min

// 定义通用的向量减少操作宏,用于计算最小值和最大值
#define NPY_IMPL_VEC_REDUCE_MINMAX(INTRIN, STYPE, SFX)                  \
    NPY_FINLINE npy_##STYPE npyv_reduce_##INTRIN##_##SFX(npyv_##SFX a)  \
    {                                                                   \
        // 使用 SIMD 指令实现向量的最小/最大值减少操作
        npyv_##SFX r = vec_##INTRIN(a, vec_sld(a, a, 8));               \
                   r = vec_##INTRIN(r, vec_sld(r, r, 4));               \
                   r = vec_##INTRIN(r, vec_sld(r, r, 2));               \
                   r = vec_##INTRIN(r, vec_sld(r, r, 1));               \
        // 提取结果向量中的第一个元素作为最终的减少结果
        return (npy_##STYPE)vec_extract(r, 0);                          \
    }

// 定义各种整数类型和操作的最小值和最大值向量减少操作
NPY_IMPL_VEC_REDUCE_MINMAX(min, uint8, u8)
NPY_IMPL_VEC_REDUCE_MINMAX(max, uint8, u8)
NPY_IMPL_VEC_REDUCE_MINMAX(min, int8, s8)
NPY_IMPL_VEC_REDUCE_MINMAX(max, int8, s8)
#undef NPY_IMPL_VEC_REDUCE_MINMAX

NPY_IMPL_VEC_REDUCE_MINMAX(min, uint16, u16)
NPY_IMPL_VEC_REDUCE_MINMAX(max, uint16, u16)
NPY_IMPL_VEC_REDUCE_MINMAX(min, int16, s16)
NPY_IMPL_VEC_REDUCE_MINMAX(max, int16, s16)
#undef NPY_IMPL_VEC_REDUCE_MINMAX

NPY_IMPL_VEC_REDUCE_MINMAX(min, uint32, u32)
NPY_IMPL_VEC_REDUCE_MINMAX(max, uint32, u32)
NPY_IMPL_VEC_REDUCE_MINMAX(min, int32, s32)
NPY_IMPL_VEC_REDUCE_MINMAX(max, int32, s32)
#undef NPY_IMPL_VEC_REDUCE_MINMAX
#define NPY_IMPL_VEC_REDUCE_MINMAX(INTRIN, STYPE, SFX)                  \
    NPY_FINLINE npy_##STYPE npyv_reduce_##INTRIN##_##SFX(npyv_##SFX a)  \  // 定义一个模板宏,用于生成特定类型和后缀的向量归约函数
    {                                                                   \
        npyv_##SFX r = vec_##INTRIN(a, vec_sld(a, a, 8));               \  // 使用指定的向量指令进行归约操作
        return (npy_##STYPE)vec_extract(r, 0);                          \  // 从归约结果向量中提取第一个元素作为结果并返回
        (void)r;                                                         \  // 使用 void 来避免编译器警告未使用变量的提示
    }

NPY_IMPL_VEC_REDUCE_MINMAX(min, uint64, u64)   // 实例化模板宏,生成 unsigned 64 位整数的最小值归约函数
NPY_IMPL_VEC_REDUCE_MINMAX(max, uint64, u64)   // 实例化模板宏,生成 unsigned 64 位整数的最大值归约函数
NPY_IMPL_VEC_REDUCE_MINMAX(min, int64, s64)    // 实例化模板宏,生成 signed 64 位整数的最小值归约函数
NPY_IMPL_VEC_REDUCE_MINMAX(max, int64, s64)    // 实例化模板宏,生成 signed 64 位整数的最大值归约函数

#undef NPY_IMPL_VEC_REDUCE_MINMAX  // 取消宏定义,清理预处理器环境

#if NPY_SIMD_F32
    #define NPY_IMPL_VEC_REDUCE_MINMAX(INTRIN, INF)                   \  // 定义一个模板宏,用于生成特定浮点数类型的向量归约函数
        NPY_FINLINE float npyv_reduce_##INTRIN##_f32(npyv_f32 a)      \  // 内联函数,生成 float 类型的向量归约函数
        {                                                             \
            npyv_f32 r = vec_##INTRIN(a, vec_sld(a, a, 8));           \  // 使用指定的向量指令进行归约操作
                     r = vec_##INTRIN(r, vec_sld(r, r, 4));           \  // 进行额外的归约操作
            return vec_extract(r, 0);                                 \  // 从归约结果向量中提取第一个元素作为结果并返回
        }                                                             \
        NPY_FINLINE float npyv_reduce_##INTRIN##p_f32(npyv_f32 a)     \  // 内联函数,用于处理特殊情况下的浮点数归约
        {                                                             \
            return npyv_reduce_##INTRIN##_f32(a);                     \  // 直接调用上面定义的 float 归约函数
        }                                                             \
        NPY_FINLINE float npyv_reduce_##INTRIN##n_f32(npyv_f32 a)     \  // 内联函数,用于处理特殊情况下的浮点数归约
        {                                                             \
            npyv_b32 notnan = npyv_notnan_f32(a);                     \  // 检查是否有 NaN 值
            if (NPY_UNLIKELY(!npyv_all_b32(notnan))) {                \  // 如果有 NaN 值,则处理特殊情况
                const union { npy_uint32 i; float f;}                 \  // 定义联合体以便直接使用位操作
                pnan = {0x7fc00000UL};                                \  // 定义 NaN 值的位表示
                return pnan.f;                                        \  // 返回 NaN 值
            }                                                         \
            return npyv_reduce_##INTRIN##_f32(a);                     \  // 否则,调用上面定义的 float 归约函数
        }
    NPY_IMPL_VEC_REDUCE_MINMAX(min, 0x7f800000)  // 实例化模板宏,生成 float 类型的最小值归约函数
    NPY_IMPL_VEC_REDUCE_MINMAX(max, 0xff800000)  // 实例化模板宏,生成 float 类型的最大值归约函数
    #undef NPY_IMPL_VEC_REDUCE_MINMAX  // 取消宏定义,清理预处理器环境
#endif // NPY_SIMD_F32

#define NPY_IMPL_VEC_REDUCE_MINMAX(INTRIN, INF)                   \
    NPY_FINLINE double npyv_reduce_##INTRIN##_f64(npyv_f64 a)     \  // 定义一个模板宏,用于生成 double 类型的向量归约函数
    {                                                             \
        npyv_f64 r = vec_##INTRIN(a, vec_sld(a, a, 8));           \  // 使用指定的向量指令进行归约操作
        return vec_extract(r, 0);                                 \  // 从归约结果向量中提取第一个元素作为结果并返回
        (void)r;                                                  \  // 使用 void 来避免编译器警告未使用变量的提示
    }                                                             \
    NPY_FINLINE double npyv_reduce_##INTRIN##n_f64(npyv_f64 a)    \  // 内联函数,用于处理特殊情况下的 double 归约
    {                                                             \
        npyv_b64 notnan = npyv_notnan_f64(a);                     \
        // 使用 SIMD 指令检查向量中每个元素是否为非 NaN 的浮点数
        if (NPY_UNLIKELY(!npyv_all_b64(notnan))) {                \
            // 如果向量中存在 NaN 值,则返回一个预定义的 NaN 值
            const union { npy_uint64 i; double f;}                \
            pnan = {0x7ff8000000000000ull};                       \
            return pnan.f;                                        \
        }                                                         \
        // 对向量中的浮点数进行约简操作,使用给定的 INTRIN 指令集
        return npyv_reduce_##INTRIN##_f64(a);                     \
    }
// 定义一个宏,实现向量化操作以计算最小值和最大值,使用 IEEE 754 double 标准的值
NPY_IMPL_VEC_REDUCE_MINMAX(min, 0x7ff0000000000000)
// 定义一个宏,实现向量化操作以计算最小值和最大值,使用 IEEE 754 double 标准的值
NPY_IMPL_VEC_REDUCE_MINMAX(max, 0xfff0000000000000)
// 取消前面定义的 NPY_IMPL_VEC_REDUCE_MINMAX 宏
#undef NPY_IMPL_VEC_REDUCE_MINMAX

// 如果定义了 NPY_HAVE_VXE 或者 NPY_HAVE_VSX,则使用相同的向量化操作来实现最小值和最大值的降维
#define npyv_reduce_minp_f64 npyv_reduce_min_f64
#define npyv_reduce_maxp_f64 npyv_reduce_max_f64
#else
// 如果没有定义 NPY_HAVE_VXE 和 NPY_HAVE_VSX,则定义以下两个函数
NPY_FINLINE double npyv_reduce_minp_f64(npyv_f64 a)
{
    // 检查向量 a 中非 NaN 元素,若不存在,返回向量中的第一个元素
    npyv_b64 notnan = npyv_notnan_f64(a);
    if (NPY_UNLIKELY(!npyv_any_b64(notnan))) {
        return vec_extract(a, 0);
    }
    // 将 NaN 元素替换为 IEEE 754 double 标准中的最小值,并继续进行最小值的降维操作
    a = npyv_select_f64(notnan, a, npyv_reinterpret_f64_u64(
                npyv_setall_u64(0x7ff0000000000000)));
    return npyv_reduce_min_f64(a);
}
// 类似于上面的函数,但是用于计算最大值的降维操作
NPY_FINLINE double npyv_reduce_maxp_f64(npyv_f64 a)
{
    npyv_b64 notnan = npyv_notnan_f64(a);
    if (NPY_UNLIKELY(!npyv_any_b64(notnan))) {
        return vec_extract(a, 0);
    }
    a = npyv_select_f64(notnan, a, npyv_reinterpret_f64_u64(
                npyv_setall_u64(0xfff0000000000000)));
    return npyv_reduce_max_f64(a);
}
#endif

// 定义一个宏,实现向量化操作以进行向最近偶数的整数舍入
#define npyv_rint_f64 vec_rint
// 定义一个宏,实现向量化操作以进行向正无穷大的舍入
#define npyv_ceil_f64 vec_ceil
// 定义一个宏,实现向量化操作以进行向零的舍入
#define npyv_trunc_f64 vec_trunc
// 定义一个宏,实现向量化操作以进行向负无穷大的舍入
#define npyv_floor_f64 vec_floor

// 如果定义了 NPY_SIMD_F32,则同时定义以下几个宏,使用单精度浮点数操作
#if NPY_SIMD_F32
    #define npyv_rint_f32 vec_rint
    #define npyv_ceil_f32 vec_ceil
    #define npyv_trunc_f32 vec_trunc
    #define npyv_floor_f32 vec_floor
#endif

#endif // _NPY_SIMD_VEC_MATH_H

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

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

#ifndef _NPY_SIMD_VEC_MEMORY_H
#define _NPY_SIMD_VEC_MEMORY_H

#include "misc.h"

/****************************
 * Private utilities
 ****************************/

// TODO: test load by cast
// 定义是否使用类型转换加载数据的宏,如果为真则使用类型转换加载
#define VSX__CAST_lOAD 0
#if VSX__CAST_lOAD
    // 使用类型转换加载数据
    #define npyv__load(T_VEC, PTR) (*((T_VEC*)(PTR)))
#else
    /**
     * CLANG fails to load unaligned addresses via vec_xl, vec_xst
     * so we failback to vec_vsx_ld, vec_vsx_st
     */
    // 在 CLANG 中无法通过 vec_xl、vec_xst 加载非对齐地址,因此回退到 vec_vsx_ld、vec_vsx_st
    #if defined (NPY_HAVE_VSX2) && ( \
        (defined(__GNUC__) && !defined(vec_xl)) || (defined(__clang__) && !defined(__IBMC__)) \
    )
        #define npyv__load(T_VEC, PTR) vec_vsx_ld(0, PTR)
    #else // VX
        #define npyv__load(T_VEC, PTR) vec_xl(0, PTR)
    #endif
#endif

// unaligned store
// 非对齐存储宏定义
#if defined (NPY_HAVE_VSX2) && ( \
    (defined(__GNUC__) && !defined(vec_xl)) || (defined(__clang__) && !defined(__IBMC__)) \
)
    #define npyv__store(PTR, VEC) vec_vsx_st(VEC, 0, PTR)
#else // VX
    #define npyv__store(PTR, VEC) vec_xst(VEC, 0, PTR)
#endif

// aligned load/store
// 对齐加载/存储宏定义
#if defined (NPY_HAVE_VSX)
    #define npyv__loada(PTR) vec_ld(0, PTR)
    #define npyv__storea(PTR, VEC) vec_st(VEC, 0, PTR)
#else // VX
    #define npyv__loada(PTR) vec_xl(0, PTR)
    #define npyv__storea(PTR, VEC) vec_xst(VEC, 0, PTR)
#endif

// avoid aliasing rules
// 避免别名规则,将指针转换为 64 位无符号整数指针
NPY_FINLINE npy_uint64 *npyv__ptr2u64(const void *ptr)
{ npy_uint64 *ptr64 = (npy_uint64*)ptr; return ptr64; }

// load lower part
// 加载低部分宏定义
NPY_FINLINE npyv_u64 npyv__loadl(const void *ptr)
{
#ifdef NPY_HAVE_VSX
    #if defined(__clang__) && !defined(__IBMC__)
        // vec_promote doesn't support doubleword on clang
        // 在 clang 中,vec_promote 不支持双字
        return npyv_setall_u64(*npyv__ptr2u64(ptr));
    #else
        return vec_promote(*npyv__ptr2u64(ptr), 0);
    #endif
#else // VX
    return vec_load_len((const unsigned long long*)ptr, 7);
#endif
}

// store lower part
// 存储低部分宏定义
#define npyv__storel(PTR, VEC) \
    *npyv__ptr2u64(PTR) = vec_extract(((npyv_u64)VEC), 0)

#define npyv__storeh(PTR, VEC) \
    *npyv__ptr2u64(PTR) = vec_extract(((npyv_u64)VEC), 1)

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

// 实现向量内存加载/存储的宏定义,包含不同数据宽度的加载函数
#define NPYV_IMPL_VEC_MEM(SFX, DW_CAST)                                                 \
    NPY_FINLINE npyv_##SFX npyv_load_##SFX(const npyv_lanetype_##SFX *ptr)              \
    { return (npyv_##SFX)npyv__load(npyv_##SFX, (const npyv_lanetype_##DW_CAST*)ptr); } \
    NPY_FINLINE npyv_##SFX npyv_loada_##SFX(const npyv_lanetype_##SFX *ptr)             \
    { return (npyv_##SFX)npyv__loada((const npyv_lanetype_u32*)ptr); }                  \
    NPY_FINLINE npyv_##SFX npyv_loads_##SFX(const npyv_lanetype_##SFX *ptr)             \
    { return npyv_loada_##SFX(ptr); }                                                   \
    NPY_FINLINE npyv_##SFX npyv_loadl_##SFX(const npyv_lanetype_##SFX *ptr)             \
    { return (npyv_##SFX)npyv__loadl(ptr); }

#endif // _NPY_SIMD_VEC_MEMORY_H
    # 存储函数定义,将向量数据存储到指定地址
    
    NPY_FINLINE void npyv_store_##SFX(npyv_lanetype_##SFX *ptr, npyv_##SFX vec)
    { npyv__store((npyv_lanetype_##DW_CAST*)ptr, (npyv_##DW_CAST)vec); }
    
    # 存储对齐函数定义,将向量数据按对齐方式存储到指定地址
    
    NPY_FINLINE void npyv_storea_##SFX(npyv_lanetype_##SFX *ptr, npyv_##SFX vec)
    { npyv__storea((npyv_lanetype_u32*)ptr, (npyv_u32)vec); }
    
    # 存储对齐函数的简写定义,将向量数据按对齐方式存储到指定地址
    
    NPY_FINLINE void npyv_stores_##SFX(npyv_lanetype_##SFX *ptr, npyv_##SFX vec)
    { npyv_storea_##SFX(ptr, vec); }
    
    # 低位存储函数定义,将向量低位数据存储到指定地址
    
    NPY_FINLINE void npyv_storel_##SFX(npyv_lanetype_##SFX *ptr, npyv_##SFX vec)
    { npyv__storel(ptr, vec); }
    
    # 高位存储函数定义,将向量高位数据存储到指定地址
    
    NPY_FINLINE void npyv_storeh_##SFX(npyv_lanetype_##SFX *ptr, npyv_##SFX vec)
    { npyv__storeh(ptr, vec); }
//// 定义宏以实现不连续加载

NPYV_IMPL_VEC_MEM(u8,  u8)  // 宏定义,生成用于加载/存储无符号8位整数向量的函数
NPYV_IMPL_VEC_MEM(s8,  s8)  // 宏定义,生成用于加载/存储有符号8位整数向量的函数
NPYV_IMPL_VEC_MEM(u16, u16) // 宏定义,生成用于加载/存储无符号16位整数向量的函数
NPYV_IMPL_VEC_MEM(s16, s16) // 宏定义,生成用于加载/存储有符号16位整数向量的函数
NPYV_IMPL_VEC_MEM(u32, u32) // 宏定义,生成用于加载/存储无符号32位整数向量的函数
NPYV_IMPL_VEC_MEM(s32, s32) // 宏定义,生成用于加载/存储有符号32位整数向量的函数
NPYV_IMPL_VEC_MEM(u64, f64) // 宏定义,生成用于加载/存储无符号64位整数向量的函数(实际是使用双精度浮点向量)
NPYV_IMPL_VEC_MEM(s64, f64) // 宏定义,生成用于加载/存储有符号64位整数向量的函数(实际是使用双精度浮点向量)
#if NPY_SIMD_F32
NPYV_IMPL_VEC_MEM(f32, f32) // 如果支持单精度浮点数SIMD,则生成用于加载/存储单精度浮点数向量的函数
#endif
NPYV_IMPL_VEC_MEM(f64, f64) // 宏定义,生成用于加载/存储双精度浮点数向量的函数

/***************************
 * Non-contiguous Load
 ***************************/

//// 32
// 以32位整数步长从内存加载向量
NPY_FINLINE npyv_u32 npyv_loadn_u32(const npy_uint32 *ptr, npy_intp stride)
{
    return npyv_set_u32(
        ptr[stride * 0], ptr[stride * 1],
        ptr[stride * 2], ptr[stride * 3]
    );
}

// 以32位整数步长从内存加载有符号32位整数向量
NPY_FINLINE npyv_s32 npyv_loadn_s32(const npy_int32 *ptr, npy_intp stride)
{ return (npyv_s32)npyv_loadn_u32((const npy_uint32*)ptr, stride); }

#if NPY_SIMD_F32
// 如果支持单精度浮点SIMD,则以32位整数步长从内存加载单精度浮点数向量
NPY_FINLINE npyv_f32 npyv_loadn_f32(const float *ptr, npy_intp stride)
{ return (npyv_f32)npyv_loadn_u32((const npy_uint32*)ptr, stride); }
#endif

//// 64
// 以64位整数步长从内存加载无符号64位整数向量
NPY_FINLINE npyv_u64 npyv_loadn_u64(const npy_uint64 *ptr, npy_intp stride)
{ return npyv_set_u64(ptr[0], ptr[stride]); }

// 以64位整数步长从内存加载有符号64位整数向量
NPY_FINLINE npyv_s64 npyv_loadn_s64(const npy_int64 *ptr, npy_intp stride)
{ return npyv_set_s64(ptr[0], ptr[stride]); }

// 以64位整数步长从内存加载双精度浮点数向量
NPY_FINLINE npyv_f64 npyv_loadn_f64(const double *ptr, npy_intp stride)
{ return npyv_set_f64(ptr[0], ptr[stride]); }

//// 64-bit load over 32-bit stride
// 以64位整数步长(使用32位整数指针)从内存加载无符号32位整数向量
NPY_FINLINE npyv_u32 npyv_loadn2_u32(const npy_uint32 *ptr, npy_intp stride)
{ return (npyv_u32)npyv_set_u64(*(npy_uint64*)ptr, *(npy_uint64*)(ptr + stride)); }

// 以64位整数步长(使用32位整数指针)从内存加载有符号32位整数向量
NPY_FINLINE npyv_s32 npyv_loadn2_s32(const npy_int32 *ptr, npy_intp stride)
{ return (npyv_s32)npyv_set_u64(*(npy_uint64*)ptr, *(npy_uint64*)(ptr + stride)); }

#if NPY_SIMD_F32
// 如果支持单精度浮点SIMD,则以64位整数步长(使用单精度浮点数指针)从内存加载单精度浮点数向量
NPY_FINLINE npyv_f32 npyv_loadn2_f32(const float *ptr, npy_intp stride)
{ return (npyv_f32)npyv_set_u64(*(npy_uint64*)ptr, *(npy_uint64*)(ptr + stride)); }
#endif

//// 128-bit load over 64-bit stride
// 以64位整数步长从内存加载无符号64位整数向量
NPY_FINLINE npyv_u64 npyv_loadn2_u64(const npy_uint64 *ptr, npy_intp stride)
{ (void)stride; return npyv_load_u64(ptr); }

// 以64位整数步长从内存加载有符号64位整数向量
NPY_FINLINE npyv_s64 npyv_loadn2_s64(const npy_int64 *ptr, npy_intp stride)
{ (void)stride; return npyv_load_s64(ptr); }

// 以64位整数步长从内存加载双精度浮点数向量
NPY_FINLINE npyv_f64 npyv_loadn2_f64(const double *ptr, npy_intp stride)
{ (void)stride; return npyv_load_f64(ptr); }

/***************************
 * Non-contiguous Store
 ***************************/

//// 32
// 以32位整数步长将向量存储到内存
NPY_FINLINE void npyv_storen_u32(npy_uint32 *ptr, npy_intp stride, npyv_u32 a)
{
    ptr[stride * 0] = vec_extract(a, 0);
    ptr[stride * 1] = vec_extract(a, 1);
    ptr[stride * 2] = vec_extract(a, 2);
    ptr[stride * 3] = vec_extract(a, 3);
}

// 以32位整数步长将有符号32位整数向量存储到内存
NPY_FINLINE void npyv_storen_s32(npy_int32 *ptr, npy_intp stride, npyv_s32 a)
{ npyv_storen_u32((npy_uint32*)ptr, stride, (npyv_u32)a); }

#if NPY_SIMD_F32
// 如果支持单精度浮点SIMD,则以32位整数步长将单精度浮点数向量存储到内存
NPY_FINLINE void npyv_storen_f32(float *ptr, npy_intp stride, npyv_f32 a)
{ npyv_storen_u32((npy_uint32*)ptr, stride, (npyv_u32)a); }
#endif

//// 64
// 以64位整数步长将无符号64位整数向量存储到内存
NPY_FINLINE void npyv_storen_u64(npy_uint64 *ptr, npy_intp stride, npyv_u64 a)
{
    ptr[stride * 0] = vec_extract(a, 0);
}
    # 将向量 a 中索引为 1 的元素提取出来,并存入 ptr 数组的第 stride 个位置
    ptr[stride * 1] = vec_extract(a, 1);
//// 64-bit store over 32-bit stride
NPY_FINLINE void npyv_storen2_u32(npy_uint32 *ptr, npy_intp stride, npyv_u32 a)
{
    // 将向量a中的第一个64位元素存储到ptr指向的位置
    *(npy_uint64*)ptr = vec_extract((npyv_u64)a, 0);
    // 将向量a中的第二个64位元素存储到ptr指向的位置加上stride的位置
    *(npy_uint64*)(ptr + stride) = vec_extract((npyv_u64)a, 1);
}

NPY_FINLINE void npyv_storen2_s32(npy_int32 *ptr, npy_intp stride, npyv_s32 a)
{ 
    // 调用npyv_storen2_u32函数将向量a转换为无符号32位整数向量,并存储到ptr指向的位置
    npyv_storen2_u32((npy_uint32*)ptr, stride, (npyv_u32)a); 
}

#if NPY_SIMD_F32
NPY_FINLINE void npyv_storen2_f32(float *ptr, npy_intp stride, npyv_f32 a)
{ 
    // 调用npyv_storen2_u32函数将向量a转换为无符号32位整数向量,并存储到ptr指向的位置
    npyv_storen2_u32((npy_uint32*)ptr, stride, (npyv_u32)a); 
}
#endif

//// 128-bit store over 64-bit stride
NPY_FINLINE void npyv_storen2_u64(npy_uint64 *ptr, npy_intp stride, npyv_u64 a)
{ 
    // 忽略stride,直接调用npyv_store_u64函数将向量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,直接调用npyv_store_s64函数将向量a存储到ptr指向的位置
    (void)stride; npyv_store_s64(ptr, a); 
}

NPY_FINLINE void npyv_storen2_f64(double *ptr, npy_intp stride, npyv_f64 a)
{ 
    // 忽略stride,直接调用npyv_store_f64函数将向量a存储到ptr指向的位置
    (void)stride; npyv_store_f64(ptr, a); 
}

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

//// 32
NPY_FINLINE npyv_s32 npyv_load_till_s32(const npy_int32 *ptr, npy_uintp nlane, npy_int32 fill)
{
    // 确保nlane大于0
    assert(nlane > 0);
    // 使用fill值创建32位整数向量vfill
    npyv_s32 vfill = npyv_setall_s32(fill);

#ifdef NPY_HAVE_VX
    // 如果支持VX指令集,根据nlane的大小加载数据
    const unsigned blane = (nlane > 4) ? 4 : nlane;
    const npyv_u32 steps = npyv_set_u32(0, 1, 2, 3);
    const npyv_u32 vlane = npyv_setall_u32(blane);
    const npyv_b32 mask  = vec_cmpgt(vlane, steps);
    npyv_s32 a = vec_load_len(ptr, blane*4-1);
    a = vec_sel(vfill, a, mask);
#else
    // 如果不支持VX指令集,根据nlane的大小选择不同的加载方式
    npyv_s32 a;
    switch(nlane) {
    case 1:
        a = vec_insert(ptr[0], vfill, 0);
        break;
    case 2:
        a = (npyv_s32)vec_insert(
            *npyv__ptr2u64(ptr), (npyv_u64)vfill, 0
        );
        break;
    case 3:
        vfill = vec_insert(ptr[2], vfill, 2);
        a = (npyv_s32)vec_insert(
            *npyv__ptr2u64(ptr), (npyv_u64)vfill, 0
        );
        break;
    default:
        return npyv_load_s32(ptr);
    }
#endif

#if NPY_SIMD_GUARD_PARTIAL_LOAD
    // 在支持SIMD保护部分加载时,执行一个volatile操作
    volatile npyv_s32 workaround = a;
    a = vec_or(workaround, a);
#endif

    return a;
}

// 填充剩余的通道为零
NPY_FINLINE npyv_s32 npyv_load_tillz_s32(const npy_int32 *ptr, npy_uintp nlane)
{
#ifdef NPY_HAVE_VX
    // 如果支持VX指令集,根据nlane的大小加载数据,剩余通道填充为零
    unsigned blane = (nlane > 4) ? 4 : nlane;
    return vec_load_len(ptr, blane*4-1);
#else
    // 如果不支持VX指令集,调用npv_load_till_s32函数加载数据,剩余通道填充为零
    return npyv_load_till_s32(ptr, nlane, 0);
#endif
}

//// 64
NPY_FINLINE npyv_s64 npyv_load_till_s64(const npy_int64 *ptr, npy_uintp nlane, npy_int64 fill)
{
    // 确保nlane大于0
    assert(nlane > 0);
    if (nlane == 1) {
        // 当nlane为1时,使用ptr[0]和fill值创建64位整数向量r
        npyv_s64 r = npyv_set_s64(ptr[0], fill);
    #if NPY_SIMD_GUARD_PARTIAL_LOAD
        // 在支持SIMD保护部分加载时,执行一个volatile操作
        volatile npyv_s64 workaround = r;
        r = vec_or(workaround, r);
    #endif
        return r;
    }
}
    // 调用 npyv_load_s64 函数,传入指针 ptr,并返回其结果
    return npyv_load_s64(ptr);
// 以内联方式加载直到指定数量的64位整数,如果启用了VX指令集,则使用SIMD指令进行加载
NPY_FINLINE npyv_s64 npyv_load_tillz_s64(const npy_int64 *ptr, npy_uintp nlane)
{
#ifdef NPY_HAVE_VX
    // 如果请求的元素数量大于2,则限制为2个
    unsigned blane = (nlane > 2) ? 2 : nlane;
    // 使用SIMD指令加载长度为 blane*8-1 的数据
    return vec_load_len((const signed long long*)ptr, blane*8-1);
#else
    // 否则,调用非零填充版本的加载函数
    return npyv_load_till_s64(ptr, nlane, 0);
#endif
}

//// 64-bit nlane
// 以内联方式加载直到指定数量的32位整数,可以指定填充值来填充剩余的数据
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);
    if (nlane == 1) {
        // 如果只有一个元素,使用指定的填充值创建32位整数向量
        npyv_s32 r = npyv_set_s32(ptr[0], ptr[1], fill_lo, fill_hi);
    #if NPY_SIMD_GUARD_PARTIAL_LOAD
        // 在需要保护部分加载的情况下,使用volatile变量执行一个操作以避免编译器优化
        volatile npyv_s32 workaround = r;
        r = vec_or(workaround, r);
    #endif
        return r;
    }
    // 否则,调用普通的加载函数来加载数据
    return npyv_load_s32(ptr);
}

// fill zero to rest lanes
// 以内联方式加载直到指定数量的32位整数,并填充剩余的数据为零
NPY_FINLINE npyv_s32 npyv_load2_tillz_s32(const npy_int32 *ptr, npy_uintp nlane)
{ return (npyv_s32)npyv_load_tillz_s64((const npy_int64*)ptr, nlane); }

//// 128-bit nlane
// 以内联方式加载直到指定数量的64位整数,无条件返回64位整数向量
NPY_FINLINE npyv_s64 npyv_load2_till_s64(const npy_int64 *ptr, npy_uintp nlane,
                                           npy_int64 fill_lo, npy_int64 fill_hi)
{ (void)nlane; (void)fill_lo; (void)fill_hi; return npyv_load_s64(ptr); }

// fill zero to rest lanes
// 以内联方式加载直到指定数量的64位整数,并填充剩余的数据为零
NPY_FINLINE npyv_s64 npyv_load2_tillz_s64(const npy_int64 *ptr, npy_uintp nlane)
{ (void)nlane; return npyv_load_s64(ptr); }

/*********************************
 * Non-contiguous partial load
 *********************************/

//// 32
// 以内联方式加载非连续的32位整数向量,可以指定填充值来填充剩余的数据
NPY_FINLINE npyv_s32
npyv_loadn_till_s32(const npy_int32 *ptr, npy_intp stride, npy_uintp nlane, npy_int32 fill)
{
    assert(nlane > 0);
    // 使用指定的填充值创建一个32位整数向量
    npyv_s32 vfill = npyv_setall_s32(fill);
    switch(nlane) {
    case 3:
        // 如果请求的元素数量为3,则插入第三个元素并更新vfill
        vfill = vec_insert(ptr[stride*2], vfill, 2);
    case 2:
        // 如果请求的元素数量为2,则插入第二个元素并更新vfill
        vfill = vec_insert(ptr[stride], vfill, 1);
    case 1:
        // 插入第一个元素并更新vfill
        vfill = vec_insert(*ptr, vfill, 0);
        break;
    default:
        // 否则,调用非连续加载函数来加载数据
        return npyv_loadn_s32(ptr, stride);
    } // switch
#if NPY_SIMD_GUARD_PARTIAL_LOAD
    // 在需要保护部分加载的情况下,使用volatile变量执行一个操作以避免编译器优化
    volatile npyv_s32 workaround = vfill;
    vfill = vec_or(workaround, vfill);
#endif
    return vfill;
}

// fill zero to rest lanes
// 以内联方式加载非连续的32位整数向量,并填充剩余的数据为零
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); }

//// 64
// 以内联方式加载非连续的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);
    if (nlane == 1) {
        // 如果请求的元素数量为1,则调用带填充参数的加载函数
        return npyv_load_till_s64(ptr, nlane, fill);
    }
    // 否则,调用非连续加载函数来加载数据
    return npyv_loadn_s64(ptr, stride);
}

// fill zero to rest lanes
// 以内联方式加载非连续的64位整数向量,并填充剩余的数据为零
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); }

//// 64-bit load over 32-bit stride
// 以内联方式加载非连续的32位整数向量,可以指定填充值来填充剩余的数据
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) {
        # 如果只有一个通道,使用给定的指针和填充值创建一个 SIMD 向量
        npyv_s32 r = npyv_set_s32(ptr[0], ptr[1], fill_lo, fill_hi);
        
        # 如果定义了 NPY_SIMD_GUARD_PARTIAL_LOAD,执行以下代码段
        # 将结果存储在 volatile 变量 workaround 中,然后使用逻辑或操作符合并 r 和 workaround
        # 这段代码可能用于某些 SIMD 指令集下的部分加载情况的处理
    #if NPY_SIMD_GUARD_PARTIAL_LOAD
        volatile npyv_s32 workaround = r;
        r = vec_or(workaround, r);
    #endif
        
        # 返回创建的 SIMD 向量 r
        return r;
    }
    
    # 如果不止一个通道,使用给定的指针和步长来加载 SIMD 向量
    return npyv_loadn2_s32(ptr, stride);
/*********************************
 * Partial store
 *********************************/
//// 32
NPY_FINLINE void npyv_store_till_s32(npy_int32 *ptr, npy_uintp nlane, npyv_s32 a)
{
    // 确保待存储的元素个数大于零
    assert(nlane > 0);
#ifdef NPY_HAVE_VX
    // 如果支持向量化指令,计算实际需要存储的元素个数
    unsigned blane = (nlane > 4) ? 4 : nlane;
    // 使用向量化指令部分存储数据到ptr中
    vec_store_len(a, ptr, blane*4-1);
#else
    // 如果不支持向量化指令,根据元素个数执行不同的存储方式
    switch(nlane) {
    case 1:
        // 存储第一个元素到ptr中
        *ptr = vec_extract(a, 0);
        break;
    case 2:
        // 存储前两个元素到ptr中
        npyv_storel_s32(ptr, a);
        break;
    case 3:
        // 存储前两个元素到ptr中,再存储第三个元素到ptr[2]中
        npyv_storel_s32(ptr, a);
        ptr[2] = vec_extract(a, 2);
        break;
    default:
        // 存储所有元素到ptr中
        npyv_store_s32(ptr, a);
    }
#endif
}

//// 64
NPY_FINLINE void npyv_store_till_s64(npy_int64 *ptr, npy_uintp nlane, npyv_s64 a)
{
    // 确保待存储的元素个数大于零
    assert(nlane > 0);
#ifdef NPY_HAVE_VX
    // 如果支持向量化指令,计算实际需要存储的元素个数
    unsigned blane = (nlane > 2) ? 2 : nlane;
    // 使用向量化指令部分存储数据到ptr中
    vec_store_len(a, (signed long long*)ptr, blane*8-1);
#else
    if (nlane == 1) {
        // 如果只有一个元素,直接存储到ptr中
        npyv_storel_s64(ptr, a);
        return;
    }
    // 否则,存储所有元素到ptr中
    npyv_store_s64(ptr, a);
#endif
}

//// 64-bit nlane
NPY_FINLINE void npyv_store2_till_s32(npy_int32 *ptr, npy_uintp nlane, npyv_s32 a)
{ 
    // 调用64位存储函数,将32位向量a的数据存储到64位ptr中
    npyv_store_till_s64((npy_int64*)ptr, nlane, (npyv_s64)a); 
}

//// 128-bit nlane
NPY_FINLINE void npyv_store2_till_s64(npy_int64 *ptr, npy_uintp nlane, npyv_s64 a)
{
    // 确保待存储的元素个数大于零
    assert(nlane > 0); 
    // 直接存储所有元素到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)
{
    // 确保待存储的元素个数大于零
    assert(nlane > 0);
    // 将向量a中的第一个元素存储到ptr中的第一个位置
    ptr[stride*0] = vec_extract(a, 0);
    // 根据元素个数执行不同的存储方式
    switch(nlane) {
    case 1:
        // 如果只有一个元素,直接返回
        return;
    case 2:
        // 存储第二个元素到ptr中的第二个位置
        ptr[stride*1] = vec_extract(a, 1);
        return;
    case 3:
        // 存储第二个元素到ptr中的第二个位置,存储第三个元素到ptr中的第三个位置
        ptr[stride*1] = vec_extract(a, 1);
        ptr[stride*2] = vec_extract(a, 2);
        return;
    default:
         // 存储第二到第四个元素到ptr中对应位置
         ptr[stride*1] = vec_extract(a, 1);
         ptr[stride*2] = vec_extract(a, 2);
         ptr[stride*3] = vec_extract(a, 3);
    }
}
//// 64
NPY_FINLINE void npyv_storen_till_s64(npy_int64 *ptr, npy_intp stride, npy_uintp nlane, npyv_s64 a)
{
    # 断言确保 nlane 大于 0,如果不是则触发 AssertionError
    assert(nlane > 0);
    # 如果 nlane 等于 1,则使用 npyv_storel_s64 函数将 a 存储到 ptr 指向的内存中,并返回
    if (nlane == 1) {
        npyv_storel_s64(ptr, a);
        return;
    }
    # 如果 nlane 大于 1,则使用 npyv_storen_s64 函数将长度为 nlane 的向量 a 存储到 ptr 指向的内存中,
    # 并按照指定的步长 stride 进行存储
    npyv_storen_s64(ptr, stride, a);
// Store 64-bit integer vector `a` into memory `ptr` with a 32-bit stride for `nlane` elements
NPY_FINLINE void npyv_storen2_till_s32(npy_int32 *ptr, npy_intp stride, npy_uintp nlane, npyv_s32 a)
{
    // 断言确保要存储的元素数量大于0
    assert(nlane > 0);
    // 将低32位元素存储到内存地址ptr处
    npyv_storel_s32(ptr, a);
    // 如果元素数量大于1,则将高32位元素存储到内存地址ptr + stride处
    if (nlane > 1) {
        npyv_storeh_s32(ptr + stride, a);
    }
}

// Store 128-bit integer vector `a` into memory `ptr` with a 64-bit stride for `nlane` elements
NPY_FINLINE void npyv_storen2_till_s64(npy_int64 *ptr, npy_intp stride, npy_uintp nlane, npyv_s64 a)
{ 
    // 断言确保要存储的元素数量大于0
    assert(nlane > 0);
    // 调用存储128位整数向量的函数,存储到内存地址ptr处
    npyv_store_s64(ptr, a); 
}

/*****************************************************************
 * Implement partial load/store for u32/f32/u64/f64... via casting
 *****************************************************************/
// 宏定义,用于生成多种类型的部分加载/存储函数
#define NPYV_IMPL_VEC_REST_PARTIAL_TYPES(F_SFX, T_SFX)                                      \
    // 部分加载函数,将类型为`F_SFX`的向量部分加载到`npyv_##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)         \
    {                                                                                       \
        union {                                                                             \
            npyv_lanetype_##F_SFX from_##F_SFX;                                             \
            npyv_lanetype_##T_SFX to_##T_SFX;                                               \
        } pun;                                                                              \
        // 利用联合体进行类型转换,填充为`T_SFX`类型,用于部分加载函数调用
        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                       \
        ));                                                                                 \
    }                                                                                       \
    // 部分加载函数,带有步长`stride`,将类型为`F_SFX`的向量部分加载到`npyv_##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;                                                            \
        // 返回重新解释类型后的加载数据,将类型 F_SFX 转换为类型 T_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 向量
    NPY_FINLINE npyv_##F_SFX npyv_load_tillz_##F_SFX                                        \
    (const npyv_lanetype_##F_SFX *ptr, npy_uintp nlane)                                     \
    {                                                                                       \
        // 返回重新解释类型后的加载直到末尾为空的类型 F_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)                    \
    {                                                                                       \
        // 返回重新解释类型后的加载带步长直到末尾为空的类型 F_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 向量
        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)          \
    {                                                                                       \
        npyv_storen_till_##T_SFX(                                                           \
            (npyv_lanetype_##T_SFX *)ptr, stride, nlane,                                    \
            npyv_reinterpret_##T_SFX##_##F_SFX(a)                                           \
        );                                                                                  \
    }



    }                                                                                       \

这是一个 C 语言中的预处理器宏定义的结尾部分。


    NPY_FINLINE void npyv_storen_till_##F_SFX                                               \

定义了一个内联函数 `npyv_storen_till_##F_SFX`,其返回类型为 `void`,接受四个参数:指向 `npyv_lanetype_##F_SFX` 类型的指针 `ptr`,一个整数 `stride`,一个无符号整数 `nlane`,以及一个 `npyv_##F_SFX` 类型的参数 `a`。


    (npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane, npyv_##F_SFX a)          \

这一行是函数参数列表的起始部分。


        npyv_storen_till_##T_SFX(                                                           \

调用了另一个内联函数 `npyv_storen_till_##T_SFX`,其返回类型为 `void`,并传入参数:将 `ptr` 强制类型转换为 `npyv_lanetype_##T_SFX *`,`stride`,`nlane`,以及将 `a` 强制类型转换为 `npyv_reinterpret_##T_SFX##_##F_SFX(a)`。


            (npyv_lanetype_##T_SFX *)ptr, stride, nlane,                                    \

传递给 `npyv_storen_till_##T_SFX` 函数的参数列表的起始部分。


            npyv_reinterpret_##T_SFX##_##F_SFX(a)                                           \

调用 `npyv_reinterpret_##T_SFX##_##F_SFX` 宏,用于重新解释参数 `a` 的类型为 `T_SFX` 对应的类型。


        );                                                                                  \

`npyv_storen_till_##T_SFX` 函数调用的结尾。


    }

函数 `npyv_storen_till_##F_SFX` 的定义结尾。
// 定义宏,用于生成一系列的向量加载函数,处理不完整类型对 (F_SFX, T_SFX)
#define NPYV_IMPL_VEC_REST_PARTIAL_TYPES(F_SFX, T_SFX)                                 \
    // 定义内联函数 npyv_load2_till_##F_SFX,加载 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,用于转换 F_SFX 类型数据到 T_SFX 类型
        union pun {                                                                     \
            npyv_lanetype_##F_SFX from_##F_SFX;                                         \
            npyv_lanetype_##T_SFX to_##T_SFX;                                           \
        };                                                                              \
        // 定义联合变量 pun_lo 和 pun_hi,分别存储 fill_lo 和 fill_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 函数加载 T_SFX 类型数据,利用 reinterpret 转换为 F_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,直至指定数量
    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 进行类型转换,将 fill_lo 赋值给 from_##F_SFX
        pun_lo.from_##F_SFX = fill_lo;                                                      \
        // 使用联合体 pun 进行类型转换,将 fill_hi 赋值给 from_##F_SFX
        pun_hi.from_##F_SFX = fill_hi;                                                      \
        // 调用 npyv_loadn2_till_##T_SFX 函数加载数据,以 pun_lo.to_##T_SFX 和 pun_hi.to_##T_SFX 为参数
        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                                                               \
        ));                                                                                 \
    }                                                                                       \
    // 定义 NPY_FINLINE 内联函数,加载指定长度的数据并返回转换后的 npyv_##F_SFX 结果
    NPY_FINLINE npyv_##F_SFX npyv_load2_tillz_##F_SFX                                       \
    (const npyv_lanetype_##F_SFX *ptr, npy_uintp nlane)                                     \
    {                                                                                       \
        // 调用 npyv_load2_tillz_##T_SFX 函数加载数据,将 ptr 强制类型转换为 const npyv_lanetype_##T_SFX 指针
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_load2_tillz_##T_SFX(                 \
            (const npyv_lanetype_##T_SFX *)ptr, nlane                                       \
        ));                                                                                 \
    }                                                                                       \
    // 定义 NPY_FINLINE 内联函数,加载带步长的指定长度数据并返回转换后的 npyv_##F_SFX 结果
    NPY_FINLINE npyv_##F_SFX npyv_loadn2_tillz_##F_SFX                                      \
    (const npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane)                    \
    {                                                                                       \
        // 调用 npyv_loadn2_tillz_##T_SFX 函数加载数据,将 ptr 强制类型转换为 const npyv_lanetype_##T_SFX 指针,传递 stride 和 nlane 作为参数
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_loadn2_tillz_##T_SFX(                \
            (const npyv_lanetype_##T_SFX *)ptr, stride, nlane                               \
        ));                                                                                 \
    }                                                                                       \
    // 定义 NPY_FINLINE 内联函数,存储指定长度的 npyv_##F_SFX 数据到 ptr
    NPY_FINLINE void npyv_store2_till_##F_SFX                                               \
    (npyv_lanetype_##F_SFX *ptr, npy_uintp nlane, npyv_##F_SFX a)                           \
    {                                                                                       \
        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)          \
    {                                                                                       \
        npyv_storen2_till_##T_SFX(                                                          \
            (npyv_lanetype_##T_SFX *)ptr, stride, nlane,                                    \
            npyv_reinterpret_##T_SFX##_##F_SFX(a)                                           \
        );                                                                                  \
    }



    {                                                                                       \
        // 调用特定类型 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,存储 F_SFX 类型的向量 a 到 ptr 指向的内存中,处理直到 nlane
    NPY_FINLINE void npyv_storen2_till_##F_SFX                                              \
    (npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane, npyv_##F_SFX a)          \
    {                                                                                       \
        // 调用特定类型 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)                                           \
        );                                                                                  \
    }
// 宏定义,生成多种类型的向量操作函数
NPYV_IMPL_VEC_REST_PARTIAL_TYPES_PAIR(u32, s32)
#if NPY_SIMD_F32
// 如果支持单精度浮点型 SIMD,则生成相应类型的向量操作函数
NPYV_IMPL_VEC_REST_PARTIAL_TYPES_PAIR(f32, s32)
#endif
// 生成多种类型的向量操作函数
NPYV_IMPL_VEC_REST_PARTIAL_TYPES_PAIR(u64, s64)
NPYV_IMPL_VEC_REST_PARTIAL_TYPES_PAIR(f64, s64)

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

// 定义向量内存交织操作的宏
#define NPYV_IMPL_VEC_MEM_INTERLEAVE(SFX)                                \
    // 对两个同类型向量执行交织操作
    NPY_FINLINE npyv_##SFX##x2 npyv_zip_##SFX(npyv_##SFX, npyv_##SFX);   \
    // 对两个同类型向量执行反交织操作
    NPY_FINLINE npyv_##SFX##x2 npyv_unzip_##SFX(npyv_##SFX, npyv_##SFX); \
    // 加载两个连续内存位置的向量并进行反交织
    NPY_FINLINE npyv_##SFX##x2 npyv_load_##SFX##x2(                      \
        const npyv_lanetype_##SFX *ptr                                   \
    ) {                                                                  \
        return npyv_unzip_##SFX(                                         \
            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_##SFX(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_VEC_MEM_INTERLEAVE(u8)
NPYV_IMPL_VEC_MEM_INTERLEAVE(s8)
NPYV_IMPL_VEC_MEM_INTERLEAVE(u16)
NPYV_IMPL_VEC_MEM_INTERLEAVE(s16)
NPYV_IMPL_VEC_MEM_INTERLEAVE(u32)
NPYV_IMPL_VEC_MEM_INTERLEAVE(s32)
NPYV_IMPL_VEC_MEM_INTERLEAVE(u64)
NPYV_IMPL_VEC_MEM_INTERLEAVE(s64)
#if NPY_SIMD_F32
// 如果支持单精度浮点型 SIMD,则生成单精度向量内存交织操作函数
NPYV_IMPL_VEC_MEM_INTERLEAVE(f32)
#endif
// 生成双精度向量内存交织操作函数
NPYV_IMPL_VEC_MEM_INTERLEAVE(f64)

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

// 使用向量作为索引来查找包含32个float32元素的表
NPY_FINLINE npyv_u32 npyv_lut32_u32(const npy_uint32 *table, npyv_u32 idx)
{
    // 提取向量中的每个索引值
    const unsigned i0 = vec_extract(idx, 0);
    const unsigned i1 = vec_extract(idx, 1);
    const unsigned i2 = vec_extract(idx, 2);
    const unsigned i3 = vec_extract(idx, 3);
    // 使用表中的值来填充向量,并返回结果向量
    npyv_u32 r = vec_promote(table[i0], 0);
             r = vec_insert(table[i1], r, 1);
             r = vec_insert(table[i2], r, 2);
             r = vec_insert(table[i3], r, 3);
    return r;
}

// 使用向量作为索引来查找包含32个int32元素的表
NPY_FINLINE npyv_s32 npyv_lut32_s32(const npy_int32 *table, npyv_u32 idx)
{ return (npyv_s32)npyv_lut32_u32((const npy_uint32*)table, idx); }

#if NPY_SIMD_F32
// 如果支持单精度浮点型 SIMD,则使用向量作为索引来查找包含32个float元素的表
NPY_FINLINE npyv_f32 npyv_lut32_f32(const float *table, npyv_u32 idx)
{ return (npyv_f32)npyv_lut32_u32((const npy_uint32*)table, idx); }
#endif
// 使用向量作为索引来查找包含16个float64元素的表
#ifdef NPY_HAVE_VX
    // 如果定义了 NPY_HAVE_VX 宏,则使用 vec_extract 提取 idx 的第二个和第四个元素作为索引
    const unsigned i0 = vec_extract((npyv_u32)idx, 1);
    const unsigned i1 = vec_extract((npyv_u32)idx, 3);
#else
    // 否则,使用 vec_extract 提取 idx 的第一个和第三个元素作为索引
    const unsigned i0 = vec_extract((npyv_u32)idx, 0);
    const unsigned i1 = vec_extract((npyv_u32)idx, 2);
#endif

    // 使用 i0 索引从 table 数组中读取一个 double 值,并将其扩展为 npyv_f64 类型的向量 r
    npyv_f64 r = vec_promote(table[i0], 0);
    // 使用 i1 索引从 table 数组中读取一个 double 值,并将其插入到向量 r 的第二个位置
    r = vec_insert(table[i1], r, 1);
    
    // 返回构造好的向量 r,作为 lut16_f64 函数的结果
    return r;
}

// npyv_lut16_u64 函数,将 npy_uint64 类型的表格和索引传递给 lut16_f64 函数,并将结果转换为 npyv_u64 类型
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));
}

// npyv_lut16_s64 函数,将 npy_int64 类型的表格和索引传递给 lut16_f64 函数,并将结果转换为 npyv_s64 类型
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));
}

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

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

#ifndef _NPY_SIMD_VEC_MISC_H
#define _NPY_SIMD_VEC_MISC_H
// 如果 _NPY_SIMD_VEC_MISC_H 宏未定义,则定义它,防止头文件重复包含

// 定义各种数据类型的零向量宏
#define npyv_zero_u8()  ((npyv_u8)   npyv_setall_s32(0))
#define npyv_zero_s8()  ((npyv_s8)   npyv_setall_s32(0))
#define npyv_zero_u16() ((npyv_u16)  npyv_setall_s32(0))
#define npyv_zero_s16() ((npyv_s16)  npyv_setall_s32(0))
#define npyv_zero_u32() npyv_setall_u32(0)
#define npyv_zero_s32() npyv_setall_s32(0)
#define npyv_zero_u64() ((npyv_u64) npyv_setall_s32(0))
#define npyv_zero_s64() ((npyv_s64) npyv_setall_s32(0))
#if NPY_SIMD_F32
    #define npyv_zero_f32() npyv_setall_f32(0.0f)
#endif
#define npyv_zero_f64() npyv_setall_f64(0.0)
// 定义了返回各种数据类型的零向量的宏,分别使用相应的 npyv_setall_* 函数设置全零值

// 定义设置全向量相同值的宏,使用了不同数据类型的向量宏
#define npyv_setall_u8(VAL)  NPYV_IMPL_VEC_SPLTB(npyv_u8,  (unsigned char)(VAL))
#define npyv_setall_s8(VAL)  NPYV_IMPL_VEC_SPLTB(npyv_s8,  (signed char)(VAL))
#define npyv_setall_u16(VAL) NPYV_IMPL_VEC_SPLTH(npyv_u16, (unsigned short)(VAL))
#define npyv_setall_s16(VAL) NPYV_IMPL_VEC_SPLTH(npyv_s16, (short)(VAL))
#define npyv_setall_u32(VAL) NPYV_IMPL_VEC_SPLTW(npyv_u32, (unsigned int)(VAL))
#define npyv_setall_s32(VAL) NPYV_IMPL_VEC_SPLTW(npyv_s32, (int)(VAL))
#if NPY_SIMD_F32
    #define npyv_setall_f32(VAL) NPYV_IMPL_VEC_SPLTW(npyv_f32, (VAL))
#endif
#define npyv_setall_u64(VAL) NPYV_IMPL_VEC_SPLTD(npyv_u64, (npy_uint64)(VAL))
#define npyv_setall_s64(VAL) NPYV_IMPL_VEC_SPLTD(npyv_s64, (npy_int64)(VAL))
#define npyv_setall_f64(VAL) NPYV_IMPL_VEC_SPLTD(npyv_f64, VAL)
// 定义了设置全向量为相同值的宏,使用了 NPYV_IMPL_VEC_SPLTB、NPYV_IMPL_VEC_SPLTH、NPYV_IMPL_VEC_SPLTW、NPYV_IMPL_VEC_SPLTD 宏

// 定义设置向量中各个通道的值的宏
#define npyv_setf_u8(FILL, ...)  ((npyv_u8){NPYV__SET_FILL_16(unsigned char, FILL, __VA_ARGS__)})
#define npyv_setf_s8(FILL, ...)  ((npyv_s8){NPYV__SET_FILL_16(signed char, FILL, __VA_ARGS__)})
#define npyv_setf_u16(FILL, ...) ((npyv_u16){NPYV__SET_FILL_8(unsigned short, FILL, __VA_ARGS__)})
#define npyv_setf_s16(FILL, ...) ((npyv_s16){NPYV__SET_FILL_8(short, FILL, __VA_ARGS__)})
#define npyv_setf_u32(FILL, ...) ((npyv_u32){NPYV__SET_FILL_4(unsigned int, FILL, __VA_ARGS__)})
#define npyv_setf_s32(FILL, ...) ((npyv_s32){NPYV__SET_FILL_4(int, FILL, __VA_ARGS__)})
#define npyv_setf_u64(FILL, ...) ((npyv_u64){NPYV__SET_FILL_2(npy_uint64, FILL, __VA_ARGS__)})
#define npyv_setf_s64(FILL, ...) ((npyv_s64){NPYV__SET_FILL_2(npy_int64, FILL, __VA_ARGS__)})
#if NPY_SIMD_F32
    #define npyv_setf_f32(FILL, ...) ((npyv_f32){NPYV__SET_FILL_4(float, FILL, __VA_ARGS__)})
#endif
#define npyv_setf_f64(FILL, ...) ((npyv_f64){NPYV__SET_FILL_2(double, FILL, __VA_ARGS__)})
// 定义了设置向量中各个通道值的宏,分别使用 NPYV__SET_FILL_16、NPYV__SET_FILL_8、NPYV__SET_FILL_4 宏

#endif
// 结束 _NPY_SIMD_VEC_MISC_H 宏的定义
// 将所有剩余的向量通道设置为零
#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__)
#if NPY_SIMD_F32
    #define npyv_set_f32(...) npyv_setf_f32(0, __VA_ARGS__)
#endif
#define npyv_set_f64(...) npyv_setf_f64(0, __VA_ARGS__)

// 按通道选择
#define npyv_select_u8(MASK, A, B) vec_sel(B, A, MASK)
#define npyv_select_s8  npyv_select_u8
#define npyv_select_u16 npyv_select_u8
#define npyv_select_s16 npyv_select_u8
#define npyv_select_u32 npyv_select_u8
#define npyv_select_s32 npyv_select_u8
#define npyv_select_u64 npyv_select_u8
#define npyv_select_s64 npyv_select_u8
#if NPY_SIMD_F32
    #define npyv_select_f32 npyv_select_u8
#endif
#define npyv_select_f64 npyv_select_u8

// 提取第一个向量通道的值
#define npyv_extract0_u8(A) ((npy_uint8)vec_extract(A, 0))
#define npyv_extract0_s8(A) ((npy_int8)vec_extract(A, 0))
#define npyv_extract0_u16(A) ((npy_uint16)vec_extract(A, 0))
#define npyv_extract0_s16(A) ((npy_int16)vec_extract(A, 0))
#define npyv_extract0_u32(A) ((npy_uint32)vec_extract(A, 0))
#define npyv_extract0_s32(A) ((npy_int32)vec_extract(A, 0))
#define npyv_extract0_u64(A) ((npy_uint64)vec_extract(A, 0))
#define npyv_extract0_s64(A) ((npy_int64)vec_extract(A, 0))
#if NPY_SIMD_F32
    #define npyv_extract0_f32(A) vec_extract(A, 0)
#endif
#define npyv_extract0_f64(A) vec_extract(A, 0)

// 重新解释类型
#define npyv_reinterpret_u8_u8(X) X
#define npyv_reinterpret_u8_s8(X) ((npyv_u8)X)
#define npyv_reinterpret_u8_u16 npyv_reinterpret_u8_s8
#define npyv_reinterpret_u8_s16 npyv_reinterpret_u8_s8
#define npyv_reinterpret_u8_u32 npyv_reinterpret_u8_s8
#define npyv_reinterpret_u8_s32 npyv_reinterpret_u8_s8
#define npyv_reinterpret_u8_u64 npyv_reinterpret_u8_s8
#define npyv_reinterpret_u8_s64 npyv_reinterpret_u8_s8
#if NPY_SIMD_F32
    #define npyv_reinterpret_u8_f32 npyv_reinterpret_u8_s8
#endif
#define npyv_reinterpret_u8_f64 npyv_reinterpret_u8_s8

#define npyv_reinterpret_s8_s8(X) X
#define npyv_reinterpret_s8_u8(X) ((npyv_s8)X)
#define npyv_reinterpret_s8_u16 npyv_reinterpret_s8_u8
#define npyv_reinterpret_s8_s16 npyv_reinterpret_s8_u8
#define npyv_reinterpret_s8_u32 npyv_reinterpret_s8_u8
#define npyv_reinterpret_s8_s32 npyv_reinterpret_s8_u8
#define npyv_reinterpret_s8_u64 npyv_reinterpret_s8_u8
#define npyv_reinterpret_s8_s64 npyv_reinterpret_s8_u8
#if NPY_SIMD_F32
    #define npyv_reinterpret_s8_f32 npyv_reinterpret_s8_u8
#endif
#define npyv_reinterpret_s8_f64 npyv_reinterpret_s8_u8

#define npyv_reinterpret_u16_u16(X) X
#define npyv_reinterpret_u16_u8(X) ((npyv_u16)X)
#define npyv_reinterpret_u16_s8  npyv_reinterpret_u16_u8
#define npyv_reinterpret_u16_s16 npyv_reinterpret_u16_u8
// 定义将 unsigned 16 位整数重新解释为 signed 16 位整数的宏,实际上使用 unsigned 8 位整数宏
#define npyv_reinterpret_u16_u32 npyv_reinterpret_u16_u8
// 定义将 unsigned 16 位整数重新解释为 unsigned 32 位整数的宏,实际上使用 unsigned 8 位整数宏
#define npyv_reinterpret_u16_s32 npyv_reinterpret_u16_u8
// 定义将 unsigned 16 位整数重新解释为 signed 32 位整数的宏,实际上使用 unsigned 8 位整数宏
#define npyv_reinterpret_u16_u64 npyv_reinterpret_u16_u8
// 定义将 unsigned 16 位整数重新解释为 unsigned 64 位整数的宏,实际上使用 unsigned 8 位整数宏
#define npyv_reinterpret_u16_s64 npyv_reinterpret_u16_u8
// 定义将 unsigned 16 位整数重新解释为 signed 64 位整数的宏,实际上使用 unsigned 8 位整数宏
#if NPY_SIMD_F32
    #define npyv_reinterpret_u16_f32 npyv_reinterpret_u16_u8
#endif
// 如果支持单精度浮点运算,定义将 unsigned 16 位整数重新解释为单精度浮点数的宏,实际上使用 unsigned 8 位整数宏
#define npyv_reinterpret_u16_f64 npyv_reinterpret_u16_u8

#define npyv_reinterpret_s16_s16(X) X
// 定义将 signed 16 位整数重新解释为 signed 16 位整数的宏,直接返回参数 X
#define npyv_reinterpret_s16_u8(X) ((npyv_s16)X)
// 定义将 signed 16 位整数重新解释为 unsigned 8 位整数的宏,进行类型转换为 signed 16 位整数
#define npyv_reinterpret_s16_s8  npyv_reinterpret_s16_u8
// 定义将 signed 16 位整数重新解释为 signed 8 位整数的宏,实际上使用 signed 16 位整数转为 unsigned 8 位整数宏
#define npyv_reinterpret_s16_u16 npyv_reinterpret_s16_u8
// 定义将 signed 16 位整数重新解释为 unsigned 16 位整数的宏,实际上使用 signed 16 位整数转为 unsigned 8 位整数宏
#define npyv_reinterpret_s16_u32 npyv_reinterpret_s16_u8
// 定义将 signed 16 位整数重新解释为 unsigned 32 位整数的宏,实际上使用 signed 16 位整数转为 unsigned 8 位整数宏
#define npyv_reinterpret_s16_s32 npyv_reinterpret_s16_u8
// 定义将 signed 16 位整数重新解释为 signed 32 位整数的宏,实际上使用 signed 16 位整数转为 unsigned 8 位整数宏
#define npyv_reinterpret_s16_u64 npyv_reinterpret_s16_u8
// 定义将 signed 16 位整数重新解释为 unsigned 64 位整数的宏,实际上使用 signed 16 位整数转为 unsigned 8 位整数宏
#define npyv_reinterpret_s16_s64 npyv_reinterpret_s16_u8
// 定义将 signed 16 位整数重新解释为 signed 64 位整数的宏,实际上使用 signed 16 位整数转为 unsigned 8 位整数宏
#if NPY_SIMD_F32
    #define npyv_reinterpret_s16_f32 npyv_reinterpret_s16_u8
#endif
// 如果支持单精度浮点运算,定义将 signed 16 位整数重新解释为单精度浮点数的宏,实际上使用 signed 16 位整数转为 unsigned 8 位整数宏
#define npyv_reinterpret_s16_f64 npyv_reinterpret_s16_u8

#define npyv_reinterpret_u32_u32(X) X
// 定义将 unsigned 32 位整数重新解释为 unsigned 32 位整数的宏,直接返回参数 X
#define npyv_reinterpret_u32_u8(X) ((npyv_u32)X)
// 定义将 unsigned 32 位整数重新解释为 unsigned 8 位整数的宏,进行类型转换为 unsigned 32 位整数
#define npyv_reinterpret_u32_s8  npyv_reinterpret_u32_u8
// 定义将 unsigned 32 位整数重新解释为 signed 8 位整数的宏,实际上使用 unsigned 32 位整数转为 unsigned 8 位整数宏
#define npyv_reinterpret_u32_u16 npyv_reinterpret_u32_u8
// 定义将 unsigned 32 位整数重新解释为 unsigned 16 位整数的宏,实际上使用 unsigned 32 位整数转为 unsigned 8 位整数宏
#define npyv_reinterpret_u32_s16 npyv_reinterpret_u32_u8
// 定义将 unsigned 32 位整数重新解释为 signed 16 位整数的宏,实际上使用 unsigned 32 位整数转为 unsigned 8 位整数宏
#define npyv_reinterpret_u32_s32 npyv_reinterpret_u32_u8
// 定义将 unsigned 32 位整数重新解释为 signed 32 位整数的宏,实际上使用 unsigned 32 位整数转为 unsigned 8 位整数宏
#define npyv_reinterpret_u32_u64 npyv_reinterpret_u32_u8
// 定义将 unsigned 32 位整数重新解释为 unsigned 64 位整数的宏,实际上使用 unsigned 32 位整数转为 unsigned 8 位整数宏
#define npyv_reinterpret_u32_s64 npyv_reinterpret_u32_u8
// 定义将 unsigned 32 位整数重新解释为 signed 64 位整数的宏,实际上使用 unsigned 32 位整数转为 unsigned 8 位整数宏
#if NPY_SIMD_F32
    #define npyv_reinterpret_u32_f32 npyv_reinterpret_u32_u8
#endif
// 如果支持单精度浮点运算,定义将 unsigned 32 位整数重新解释为单精度浮点数的宏,实际上使用 unsigned 32 位整数转为 unsigned 8 位整数宏
#define npyv_reinterpret_u32_f64 npyv_reinterpret_u32_u8

#define npyv_reinterpret_s32_s32(X) X
// 定义将 signed 32 位整数重新解释为 signed 32 位整数的宏,直接返回参数 X
#define npyv_reinterpret_s32_u8(X) ((npyv_s32)X)
// 定义将 signed 32 位整数重新解释为 unsigned 8 位整数的宏,进行类型转换为 signed 32 位整数
#define npyv_reinterpret_s32_s8  npyv_reinterpret_s32_u8
// 定义将 signed 32 位整数重新解释为 signed 8 位整数的宏,实际上使用 signed 32 位整数转为 unsigned 8 位整数宏
#define npyv_reinterpret_s32_u16 npyv_reinterpret_s32_u8
// 定义将 signed 32 位整数重新解释为 unsigned 16 位整数的宏,实际上使用 signed 32 位整数转为 unsigned 8 位整数宏
#define npyv_reinterpret_s32_s16 npyv_reinterpret_s32_u8
// 定义将 signed 32 位整数重新解释为 signed 16 位整数的宏,实际上使用 signed 32 位整数转为 unsigned 8 位整数宏
#define npyv_reinterpret
#define npyv_reinterpret_s64_u32 npyv_reinterpret_s64_u8
#define npyv_reinterpret_s64_s32 npyv_reinterpret_s64_u8
#define npyv_reinterpret_s64_u64 npyv_reinterpret_s64_u8
#if NPY_SIMD_F32
    #define npyv_reinterpret_s64_f32 npyv_reinterpret_s64_u8
#endif
#define npyv_reinterpret_s64_f64 npyv_reinterpret_s64_u8

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

#ifndef NPY_SIMD
    #error "Not a standalone header"
#endif
// 如果未定义 NPY_SIMD 宏,则产生错误消息 "Not a standalone header"

#ifndef _NPY_SIMD_VEC_OPERATORS_H
#define _NPY_SIMD_VEC_OPERATORS_H
// 如果未定义 _NPY_SIMD_VEC_OPERATORS_H 宏,则定义该宏,避免重复包含

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

// Left
#define npyv_shl_u16(A, C) vec_sl(A, npyv_setall_u16(C))
// 定义无符号 16 位整数向左移位操作的宏,使用 vec_sl 函数

#define npyv_shl_s16(A, C) vec_sl_s16(A, npyv_setall_u16(C))
// 定义有符号 16 位整数向左移位操作的宏,使用 vec_sl_s16 函数

#define npyv_shl_u32(A, C) vec_sl(A, npyv_setall_u32(C))
// 定义无符号 32 位整数向左移位操作的宏,使用 vec_sl 函数

#define npyv_shl_s32(A, C) vec_sl_s32(A, npyv_setall_u32(C))
// 定义有符号 32 位整数向左移位操作的宏,使用 vec_sl_s32 函数

#define npyv_shl_u64(A, C) vec_sl(A, npyv_setall_u64(C))
// 定义无符号 64 位整数向左移位操作的宏,使用 vec_sl 函数

#define npyv_shl_s64(A, C) vec_sl_s64(A, npyv_setall_u64(C))
// 定义有符号 64 位整数向左移位操作的宏,使用 vec_sl_s64 函数

// Left by an immediate constant
#define npyv_shli_u16 npyv_shl_u16
// 定义无符号 16 位整数按立即常数向左移位操作的宏,与 npyv_shl_u16 相同

#define npyv_shli_s16 npyv_shl_s16
// 定义有符号 16 位整数按立即常数向左移位操作的宏,与 npyv_shl_s16 相同

#define npyv_shli_u32 npyv_shl_u32
// 定义无符号 32 位整数按立即常数向左移位操作的宏,与 npyv_shl_u32 相同

#define npyv_shli_s32 npyv_shl_s32
// 定义有符号 32 位整数按立即常数向左移位操作的宏,与 npyv_shl_s32 相同

#define npyv_shli_u64 npyv_shl_u64
// 定义无符号 64 位整数按立即常数向左移位操作的宏,与 npyv_shl_u64 相同

#define npyv_shli_s64 npyv_shl_s64
// 定义有符号 64 位整数按立即常数向左移位操作的宏,与 npyv_shl_s64 相同

// Right
#define npyv_shr_u16(A, C) vec_sr(A,  npyv_setall_u16(C))
// 定义无符号 16 位整数向右移位操作的宏,使用 vec_sr 函数

#define npyv_shr_s16(A, C) vec_sra_s16(A, npyv_setall_u16(C))
// 定义有符号 16 位整数向右移位操作的宏,使用 vec_sra_s16 函数

#define npyv_shr_u32(A, C) vec_sr(A,  npyv_setall_u32(C))
// 定义无符号 32 位整数向右移位操作的宏,使用 vec_sr 函数

#define npyv_shr_s32(A, C) vec_sra_s32(A, npyv_setall_u32(C))
// 定义有符号 32 位整数向右移位操作的宏,使用 vec_sra_s32 函数

#define npyv_shr_u64(A, C) vec_sr(A,  npyv_setall_u64(C))
// 定义无符号 64 位整数向右移位操作的宏,使用 vec_sr 函数

#define npyv_shr_s64(A, C) vec_sra_s64(A, npyv_setall_u64(C))
// 定义有符号 64 位整数向右移位操作的宏,使用 vec_sra_s64 函数

// Right by an immediate constant
#define npyv_shri_u16 npyv_shr_u16
// 定义无符号 16 位整数按立即常数向右移位操作的宏,与 npyv_shr_u16 相同

#define npyv_shri_s16 npyv_shr_s16
// 定义有符号 16 位整数按立即常数向右移位操作的宏,与 npyv_shr_s16 相同

#define npyv_shri_u32 npyv_shr_u32
// 定义无符号 32 位整数按立即常数向右移位操作的宏,与 npyv_shr_u32 相同

#define npyv_shri_s32 npyv_shr_s32
// 定义有符号 32 位整数按立即常数向右移位操作的宏,与 npyv_shr_s32 相同

#define npyv_shri_u64 npyv_shr_u64
// 定义无符号 64 位整数按立即常数向右移位操作的宏,与 npyv_shr_u64 相同

#define npyv_shri_s64 npyv_shr_s64
// 定义有符号 64 位整数按立即常数向右移位操作的宏,与 npyv_shr_s64 相同

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

#define NPYV_IMPL_VEC_BIN_CAST(INTRIN, SFX, CAST) \
    NPY_FINLINE npyv_##SFX npyv_##INTRIN##_##SFX(npyv_##SFX a, npyv_##SFX b) \
    { return (npyv_##SFX)vec_##INTRIN((CAST)a, (CAST)b); }
// 定义通用的二元逻辑运算的模板宏,使用 NPY_FINLINE 进行内联优化

// Up to GCC 6 logical intrinsics don't support bool long long
#if defined(__GNUC__) && __GNUC__ <= 6
    #define NPYV_IMPL_VEC_BIN_B64(INTRIN) NPYV_IMPL_VEC_BIN_CAST(INTRIN, b64, npyv_u64)
#else
    #define NPYV_IMPL_VEC_BIN_B64(INTRIN) NPYV_IMPL_VEC_BIN_CAST(INTRIN, b64, npyv_b64)
#endif
// 根据 GCC 编译器版本,选择适当的 64 位整数类型,避免布尔和长长整数支持问题

// AND
#define npyv_and_u8  vec_and
// 定义无符号 8 位整数按位与操作的宏,使用 vec_and 函数

#define npyv_and_s8  vec_and
// 定义有符号 8 位整数按位与操作的宏,使用 vec_and 函数

#define npyv_and_u16 vec_and
// 定义无符号 16 位整数按位与操作的宏,使用 vec_and 函数

#define npyv_and_s16 vec_and
// 定义有符号 16 位整数按位与操作的宏,使用 vec_and 函数

#define npyv_and_u32 vec_and
// 定义无符号 32 位整数按位与操作的宏,使用 vec_and 函数

#define npyv_and_s32 vec_and
// 定义有符号 32 位整数按位与操作的宏,使用 vec_and 函数

#define npyv_and_u64 vec_and
// 定义无符号 64 位整数按位与操作的宏,使用 vec_and 函数

#define npyv_and_s64 vec_and
// 定义有符号 64 位整数按位与操作的宏,使用 vec_and 函数

#if NPY_SIMD_F32
    #define npyv_and_f32 vec_and
#endif
// 如果支持单精度浮点
#define npyv_xor_s32 vec_xor
#define npyv_xor_u64 vec_xor
#define npyv_xor_s64 vec_xor
#if NPY_SIMD_F32
    #define npyv_xor_f32 vec_xor
#endif
#define npyv_xor_f64 vec_xor
#define npyv_xor_b8  vec_xor
#define npyv_xor_b16 vec_xor
#define npyv_xor_b32 vec_xor
NPYV_IMPL_VEC_BIN_B64(xor)


// 定义了多个宏,用于执行不同类型数据的按位异或操作,具体操作由 vec_xor 完成
#define npyv_xor_s32 vec_xor      // 32位有符号整数按位异或
#define npyv_xor_u64 vec_xor      // 64位无符号整数按位异或
#define npyv_xor_s64 vec_xor      // 64位有符号整数按位异或
#if NPY_SIMD_F32
    #define npyv_xor_f32 vec_xor  // 单精度浮点数按位异或(条件编译)
#endif
#define npyv_xor_f64 vec_xor      // 双精度浮点数按位异或
#define npyv_xor_b8  vec_xor      // 8位布尔型按位异或
#define npyv_xor_b16 vec_xor      // 16位布尔型按位异或
#define npyv_xor_b32 vec_xor      // 32位布尔型按位异或
NPYV_IMPL_VEC_BIN_B64(xor)      // 使用 vec_xor 实现64位布尔型按位异或


// NOT
// 注意:我们实现 npyv_not_b*(布尔类型) 供内部使用
#define NPYV_IMPL_VEC_NOT_INT(VEC_LEN)                                 \
    NPY_FINLINE npyv_u##VEC_LEN npyv_not_u##VEC_LEN(npyv_u##VEC_LEN a) \
    { return vec_nor(a, a); }                                          \
    NPY_FINLINE npyv_s##VEC_LEN npyv_not_s##VEC_LEN(npyv_s##VEC_LEN a) \
    { return vec_nor(a, a); }                                          \
    NPY_FINLINE npyv_b##VEC_LEN npyv_not_b##VEC_LEN(npyv_b##VEC_LEN a) \
    { return vec_nor(a, a); }


// 定义了一个宏 NPYV_IMPL_VEC_NOT_INT,用于实现多个整型和布尔型数据的按位非操作,具体操作由 vec_nor 完成
#define NPYV_IMPL_VEC_NOT_INT(VEC_LEN)                                 \
    NPY_FINLINE npyv_u##VEC_LEN npyv_not_u##VEC_LEN(npyv_u##VEC_LEN a) \
    { return vec_nor(a, a); }                                          \
    NPY_FINLINE npyv_s##VEC_LEN npyv_not_s##VEC_LEN(npyv_s##VEC_LEN a) \
    { return vec_nor(a, a); }                                          \
    NPY_FINLINE npyv_b##VEC_LEN npyv_not_b##VEC_LEN(npyv_b##VEC_LEN a) \
    { return vec_nor(a, a); }


NPYV_IMPL_VEC_NOT_INT(8)
NPYV_IMPL_VEC_NOT_INT(16)
NPYV_IMPL_VEC_NOT_INT(32)


// 使用宏 NPYV_IMPL_VEC_NOT_INT 分别实现8位、16位和32位整型和布尔型数据的按位非操作
NPYV_IMPL_VEC_NOT_INT(8)
NPYV_IMPL_VEC_NOT_INT(16)
NPYV_IMPL_VEC_NOT_INT(32)


// 在 ppc64 上,直到 gcc5,vec_nor 不支持布尔型长长整数
#if defined(NPY_HAVE_VSX) && defined(__GNUC__) && __GNUC__ > 5
    NPYV_IMPL_VEC_NOT_INT(64)
#else
    NPY_FINLINE npyv_u64 npyv_not_u64(npyv_u64 a)
    { return vec_nor(a, a); }
    NPY_FINLINE npyv_s64 npyv_not_s64(npyv_s64 a)
    { return vec_nor(a, a); }
    NPY_FINLINE npyv_b64 npyv_not_b64(npyv_b64 a)
    { return (npyv_b64)vec_nor((npyv_u64)a, (npyv_u64)a); }
#endif


// 根据条件,分别实现64位整型和布尔型数据的按位非操作
#if defined(NPY_HAVE_VSX) && defined(__GNUC__) && __GNUC__ > 5
    NPYV_IMPL_VEC_NOT_INT(64)  // 使用 NPYV_IMPL_VEC_NOT_INT 宏实现
#else
    NPY_FINLINE npyv_u64 npyv_not_u64(npyv_u64 a)
    { return vec_nor(a, a); }   // 64位无符号整数按位非
    NPY_FINLINE npyv_s64 npyv_not_s64(npyv_s64 a)
    { return vec_nor(a, a); }   // 64位有符号整数按位非
    NPY_FINLINE npyv_b64 npyv_not_b64(npyv_b64 a)
    { return (npyv_b64)vec_nor((npyv_u64)a, (npyv_u64)a); }  // 64位布尔型按位非
#endif


#if NPY_SIMD_F32
    NPY_FINLINE npyv_f32 npyv_not_f32(npyv_f32 a)
    { return vec_nor(a, a); }
#endif
NPY_FINLINE npyv_f64 npyv_not_f64(npyv_f64 a)
{ return vec_nor(a, a); }


// 如果支持单精度浮点数SIMD,实现单精度浮点数的按位非操作,否则忽略
#if NPY_SIMD_F32
    NPY_FINLINE npyv_f32 npyv_not_f32(npyv_f32 a)
    { return vec_nor(a, a); }  // 单精度浮点数按位非
#endif
NPY_FINLINE npyv_f64 npyv_not_f64(npyv_f64 a)
{ return vec_nor(a, a); }        // 双精度浮点数按位非


// ANDC, ORC and XNOR
#define npyv_andc_u8 vec_andc
#define npyv_andc_b8 vec_andc
#if defined(NPY_HAVE_VXE) || defined(NPY_HAVE_VSX)
    #define npyv_orc_b8 vec_orc
    #define npyv_xnor_b8 vec_eqv
#else
    #define npyv_orc_b8(A, B) npyv_or_b8(npyv_not_b8(B), A)
    #define npyv_xnor_b8(A, B) npyv_not_b8(npyv_xor_b8(B, A))
#endif


// 定义了多个宏,用于执行不同类型数据的按位ANDC、ORC和XNOR操作,具体操作由 vec_andc、vec_orc 和 vec_eqv 完成
#define npyv_andc_u8 vec_andc      // 8位无符号整数按位ANDC
#define npyv_andc_b8 vec_andc      // 8位布尔型按位ANDC
#if defined(NPY_HAVE_VXE) || defined(NPY_HAVE_VSX)
    #define npyv_orc_b8 vec_orc    // 如果支持 VXE 或 VSX,8位布尔型按位ORC
    #define npyv_xnor_b8 vec_eqv   // 如果支持 VXE 或 VSX,8位布尔型按位XNOR
#else
    #define npyv_orc_b8(A, B) npyv_or_b8(npyv_not_b8(B), A)     // 否则,通过按位OR和按位NOT实现8位布尔型按位ORC
    #define npyv_xnor_b8(A, B) npyv_not_b8(npyv_xor_b8(B, A))   // 否则,通过按位XOR和按位NOT实现8位布尔型按位XNOR
#endif


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

// Int Equal
#define npyv_cmpeq_u8  vec_cmpeq
#define npyv_cmpeq_s8  vec_cmpeq
#define npyv_cmpeq_u16 vec_cmpeq
#define npyv_cmpeq_s16 vec_cmpeq
#define npyv_cmpeq_u32 vec_cmpeq
#define npyv
    #define npyv_cmpneq_u16(A, B) npyv_not_b16(vec_cmpeq(A, B))
    // 定义一个宏,用于比较两个无符号16位整数向量A和B的元素是否不相等,返回结果取反
    
    #define npyv_cmpneq_s16(A, B) npyv_not_b16(vec_cmpeq(A, B))
    // 定义一个宏,用于比较两个有符号16位整数向量A和B的元素是否不相等,返回结果取反
    
    #define npyv_cmpneq_u32(A, B) npyv_not_b32(vec_cmpeq(A, B))
    // 定义一个宏,用于比较两个无符号32位整数向量A和B的元素是否不相等,返回结果取反
    
    #define npyv_cmpneq_s32(A, B) npyv_not_b32(vec_cmpeq(A, B))
    // 定义一个宏,用于比较两个有符号32位整数向量A和B的元素是否不相等,返回结果取反
    
    #define npyv_cmpneq_u64(A, B) npyv_not_b64(vec_cmpeq(A, B))
    // 定义一个宏,用于比较两个无符号64位整数向量A和B的元素是否不相等,返回结果取反
    
    #define npyv_cmpneq_s64(A, B) npyv_not_b64(vec_cmpeq(A, B))
    // 定义一个宏,用于比较两个有符号64位整数向量A和B的元素是否不相等,返回结果取反
    
    #if NPY_SIMD_F32
        #define npyv_cmpneq_f32(A, B) npyv_not_b32(vec_cmpeq(A, B))
    #endif
    // 如果支持32位单精度浮点数SIMD指令,则定义一个宏,用于比较两个单精度浮点数向量A和B的元素是否不相等,返回结果取反
    
    #define npyv_cmpneq_f64(A, B) npyv_not_b64(vec_cmpeq(A, B))
    // 定义一个宏,用于比较两个双精度浮点数向量A和B的元素是否不相等,返回结果取反
#endif

// Greater than
// 定义无符号8位整数向量的大于比较操作宏
#define npyv_cmpgt_u8  vec_cmpgt
// 定义有符号8位整数向量的大于比较操作宏
#define npyv_cmpgt_s8  vec_cmpgt
// 定义无符号16位整数向量的大于比较操作宏
#define npyv_cmpgt_u16 vec_cmpgt
// 定义有符号16位整数向量的大于比较操作宏
#define npyv_cmpgt_s16 vec_cmpgt
// 定义无符号32位整数向量的大于比较操作宏
#define npyv_cmpgt_u32 vec_cmpgt
// 定义有符号32位整数向量的大于比较操作宏
#define npyv_cmpgt_s32 vec_cmpgt
// 定义无符号64位整数向量的大于比较操作宏
#define npyv_cmpgt_u64 vec_cmpgt
// 定义有符号64位整数向量的大于比较操作宏
#define npyv_cmpgt_s64 vec_cmpgt
// 如果支持单精度浮点数向量,则定义单精度浮点数向量的大于比较操作宏
#if NPY_SIMD_F32
    #define npyv_cmpgt_f32 vec_cmpgt
#endif
// 定义双精度浮点数向量的大于比较操作宏
#define npyv_cmpgt_f64 vec_cmpgt

// Greater than or equal
// 如果支持向量扩展(VX)或者GCC版本大于5,则定义各类型向量的大于等于比较操作宏
#if defined(NPY_HAVE_VX) || (defined(__GNUC__) && __GNUC__ > 5)
    #define npyv_cmpge_u8  vec_cmpge
    #define npyv_cmpge_s8  vec_cmpge
    #define npyv_cmpge_u16 vec_cmpge
    #define npyv_cmpge_s16 vec_cmpge
    #define npyv_cmpge_u32 vec_cmpge
    #define npyv_cmpge_s32 vec_cmpge
    #define npyv_cmpge_u64 vec_cmpge
    #define npyv_cmpge_s64 vec_cmpge
// 否则,使用大于比较操作宏来实现各类型向量的大于等于比较操作宏
#else
    #define npyv_cmpge_u8(A, B)  npyv_not_b8(vec_cmpgt(B, A))
    #define npyv_cmpge_s8(A, B)  npyv_not_b8(vec_cmpgt(B, A))
    #define npyv_cmpge_u16(A, B) npyv_not_b16(vec_cmpgt(B, A))
    #define npyv_cmpge_s16(A, B) npyv_not_b16(vec_cmpgt(B, A))
    #define npyv_cmpge_u32(A, B) npyv_not_b32(vec_cmpgt(B, A))
    #define npyv_cmpge_s32(A, B) npyv_not_b32(vec_cmpgt(B, A))
    #define npyv_cmpge_u64(A, B) npyv_not_b64(vec_cmpgt(B, A))
    #define npyv_cmpge_s64(A, B) npyv_not_b64(vec_cmpgt(B, A))
#endif
// 如果支持单精度浮点数向量,则定义单精度浮点数向量的大于等于比较操作宏
#if NPY_SIMD_F32
    #define npyv_cmpge_f32 vec_cmpge
#endif
// 定义双精度浮点数向量的大于等于比较操作宏
#define npyv_cmpge_f64 vec_cmpge

// Less than
// 定义无符号8位整数向量的小于比较操作宏
#define npyv_cmplt_u8(A, B)  npyv_cmpgt_u8(B, A)
// 定义有符号8位整数向量的小于比较操作宏
#define npyv_cmplt_s8(A, B)  npyv_cmpgt_s8(B, A)
// 定义无符号16位整数向量的小于比较操作宏
#define npyv_cmplt_u16(A, B) npyv_cmpgt_u16(B, A)
// 定义有符号16位整数向量的小于比较操作宏
#define npyv_cmplt_s16(A, B) npyv_cmpgt_s16(B, A)
// 定义无符号32位整数向量的小于比较操作宏
#define npyv_cmplt_u32(A, B) npyv_cmpgt_u32(B, A)
// 定义有符号32位整数向量的小于比较操作宏
#define npyv_cmplt_s32(A, B) npyv_cmpgt_s32(B, A)
// 定义无符号64位整数向量的小于比较操作宏
#define npyv_cmplt_u64(A, B) npyv_cmpgt_u64(B, A)
// 定义有符号64位整数向量的小于比较操作宏
#define npyv_cmplt_s64(A, B) npyv_cmpgt_s64(B, A)
// 如果支持单精度浮点数向量,则定义单精度浮点数向量的小于比较操作宏
#if NPY_SIMD_F32
    #define npyv_cmplt_f32(A, B) npyv_cmpgt_f32(B, A)
#endif
// 定义双精度浮点数向量的小于比较操作宏
#define npyv_cmplt_f64(A, B) npyv_cmpgt_f64(B, A)

// Less than or equal
// 定义无符号8位整数向量的小于等于比较操作宏
#define npyv_cmple_u8(A, B)  npyv_cmpge_u8(B, A)
// 定义有符号8位整数向量的小于等于比较操作宏
#define npyv_cmple_s8(A, B)  npyv_cmpge_s8(B, A)
// 定义无符号16位整数向量的小于等于比较操作宏
#define npyv_cmple_u16(A, B) npyv_cmpge_u16(B, A)
// 定义有符号16位整数向量的小于等于比较操作宏
#define npyv_cmple_s16(A, B) npyv_cmpge_s16(B, A)
// 定义无符号32位整数向量的小于等于比较操作宏
#define npyv_cmple_u32(A, B) npyv_cmpge_u32(B, A)
// 定义有符号32位整数向量的小于等于比较操作宏
#define npyv_cmple_s32(A, B) npyv_cmpge_s32(B, A)
// 定义无符号64位整数向量的小于等于比较操作宏
#define npyv_cmple_u64(A, B) npyv_cmpge_u64(B, A)
// 定义有符号64位整数向量的小于等于比较操作宏
#define npyv_cmple_s64(A, B) npyv_cmpge_s64(B, A)
// 如果支持单精度浮点数向量,则定义单精度浮点数向量的小于等于比较操作宏
#if NPY_SIMD_F32
    #define npyv_cmple_f32(A, B) npyv_cmpge_f32(B, A)
#endif
// 定义双精度浮点数向量的小于等于比较操作宏
#define npyv_cmple_f64(A, B) npyv_cmpge_f64(B, A)

// check special cases
// 如果支持单精度浮点数向量,则定义检查单精度浮点数向量中非NaN值的宏
#if NPY_SIMD_F32
    NPY_FINLINE npyv_b32 npyv_notnan_f32(npyv_f32 a)
    { return vec_cmpeq(a, a); }
#endif
// 定义检查双精度浮点数向量中非NaN值的宏
NPY_FIN
    # 定义一个内联函数,检查向量中是否存在非零元素
    NPY_FINLINE bool npyv_any_##SFX(npyv_##SFX a)             \
    { return vec_any_ne(a, (npyv_##SFX)npyv_zero_##SFX2()); }
    # 定义一个内联函数,检查向量中是否所有元素都是非零的
    NPY_FINLINE bool npyv_all_##SFX(npyv_##SFX a)             \
    { return vec_all_ne(a, (npyv_##SFX)npyv_zero_##SFX2()); }
# 定义宏 NPYV_IMPL_VEC_ANYALL,用于生成各种类型的 SIMD 向量操作函数,处理布尔型(b8, b16, b32, b64)或整数型(u8, s8, u16, s16, u32, s32, u64, s64)数据
NPYV_IMPL_VEC_ANYALL(b8,  u8)    // 生成处理布尔型 b8 和无符号整数型 u8 的 SIMD 向量操作函数
NPYV_IMPL_VEC_ANYALL(b16, u16)   // 生成处理布尔型 b16 和无符号整数型 u16 的 SIMD 向量操作函数
NPYV_IMPL_VEC_ANYALL(b32, u32)   // 生成处理布尔型 b32 和无符号整数型 u32 的 SIMD 向量操作函数
NPYV_IMPL_VEC_ANYALL(b64, u64)   // 生成处理布尔型 b64 和无符号整数型 u64 的 SIMD 向量操作函数
NPYV_IMPL_VEC_ANYALL(u8,  u8)    // 生成处理无符号整数型 u8 的 SIMD 向量操作函数
NPYV_IMPL_VEC_ANYALL(s8,  s8)    // 生成处理有符号整数型 s8 的 SIMD 向量操作函数
NPYV_IMPL_VEC_ANYALL(u16, u16)   // 生成处理无符号整数型 u16 的 SIMD 向量操作函数
NPYV_IMPL_VEC_ANYALL(s16, s16)   // 生成处理有符号整数型 s16 的 SIMD 向量操作函数
NPYV_IMPL_VEC_ANYALL(u32, u32)   // 生成处理无符号整数型 u32 的 SIMD 向量操作函数
NPYV_IMPL_VEC_ANYALL(s32, s32)   // 生成处理有符号整数型 s32 的 SIMD 向量操作函数
NPYV_IMPL_VEC_ANYALL(u64, u64)   // 生成处理无符号整数型 u64 的 SIMD 向量操作函数
NPYV_IMPL_VEC_ANYALL(s64, s64)   // 生成处理有符号整数型 s64 的 SIMD 向量操作函数
#if NPY_SIMD_F32
    NPYV_IMPL_VEC_ANYALL(f32, f32)   // 生成处理单精度浮点数型 f32 的 SIMD 向量操作函数(条件编译)
#endif
NPYV_IMPL_VEC_ANYALL(f64, f64)   // 生成处理双精度浮点数型 f64 的 SIMD 向量操作函数
#undef NPYV_IMPL_VEC_ANYALL         // 取消定义宏 NPYV_IMPL_VEC_ANYALL,结束对 SIMD 向量操作函数的定义

#endif // _NPY_SIMD_VEC_OPERATORS_H   // 结束 SIMD 向量操作函数头文件的条件编译部分

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

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

#ifndef _NPY_SIMD_VEC_REORDER_H
#define _NPY_SIMD_VEC_REORDER_H

// combine lower part of two vectors
#define npyv__combinel(A, B) vec_mergeh((npyv_u64)(A), (npyv_u64)(B))
// Define macros to combine lower part of vectors for different types
#define npyv_combinel_u8(A, B)  ((npyv_u8) npyv__combinel(A, B))
#define npyv_combinel_s8(A, B)  ((npyv_s8) npyv__combinel(A, B))
#define npyv_combinel_u16(A, B) ((npyv_u16)npyv__combinel(A, B))
#define npyv_combinel_s16(A, B) ((npyv_s16)npyv__combinel(A, B))
#define npyv_combinel_u32(A, B) ((npyv_u32)npyv__combinel(A, B))
#define npyv_combinel_s32(A, B) ((npyv_s32)npyv__combinel(A, B))
#define npyv_combinel_u64       vec_mergeh
#define npyv_combinel_s64       vec_mergeh
#if NPY_SIMD_F32
    #define npyv_combinel_f32(A, B) ((npyv_f32)npyv__combinel(A, B))
#endif
#define npyv_combinel_f64       vec_mergeh

// combine higher part of two vectors
#define npyv__combineh(A, B) vec_mergel((npyv_u64)(A), (npyv_u64)(B))
// Define macros to combine higher part of vectors for different types
#define npyv_combineh_u8(A, B)  ((npyv_u8) npyv__combineh(A, B))
#define npyv_combineh_s8(A, B)  ((npyv_s8) npyv__combineh(A, B))
#define npyv_combineh_u16(A, B) ((npyv_u16)npyv__combineh(A, B))
#define npyv_combineh_s16(A, B) ((npyv_s16)npyv__combineh(A, B))
#define npyv_combineh_u32(A, B) ((npyv_u32)npyv__combineh(A, B))
#define npyv_combineh_s32(A, B) ((npyv_s32)npyv__combineh(A, B))
#define npyv_combineh_u64       vec_mergel
#define npyv_combineh_s64       vec_mergel
#if NPY_SIMD_F32
    #define npyv_combineh_f32(A, B) ((npyv_f32)npyv__combineh(A, B))
#endif
#define npyv_combineh_f64       vec_mergel

/*
 * combine: combine two vectors from lower and higher parts of two other vectors
 * zip: interleave two vectors
*/
#define NPYV_IMPL_VEC_COMBINE_ZIP(T_VEC, SFX)                  \
    NPY_FINLINE T_VEC##x2 npyv_combine_##SFX(T_VEC a, T_VEC b) \
    {                                                          \
        T_VEC##x2 r;                                           \
        r.val[0] = NPY_CAT(npyv_combinel_, SFX)(a, b);         \
        r.val[1] = NPY_CAT(npyv_combineh_, SFX)(a, b);         \
        return r;                                              \
    }                                                          \
    NPY_FINLINE T_VEC##x2 npyv_zip_##SFX(T_VEC a, T_VEC b)     \
    {                                                          \
        T_VEC##x2 r;                                           \
        r.val[0] = vec_mergeh(a, b);                           \
        r.val[1] = vec_mergel(a, b);                           \
        return r;                                              \
    }

// Define combine and zip operations for different vector types and sizes
NPYV_IMPL_VEC_COMBINE_ZIP(npyv_u8,  u8)
NPYV_IMPL_VEC_COMBINE_ZIP(npyv_s8,  s8)
NPYV_IMPL_VEC_COMBINE_ZIP(npyv_u16, u16)
NPYV_IMPL_VEC_COMBINE_ZIP(npyv_s16, s16)
NPYV_IMPL_VEC_COMBINE_ZIP(npyv_u32, u32)
NPYV_IMPL_VEC_COMBINE_ZIP(npyv_s32, s32)
NPYV_IMPL_VEC_COMBINE_ZIP(npyv_u64, u64)
NPYV_IMPL_VEC_COMBINE_ZIP(npyv_s64, s64)
#if NPY_SIMD_F32
    NPYV_IMPL_VEC_COMBINE_ZIP(npyv_f32, f32)
#endif

#endif  // _NPY_SIMD_VEC_REORDER_H
// 合并两个名为 npyv_f64 的向量
NPYV_IMPL_VEC_COMBINE_ZIP(npyv_f64, f64)

// 解交错两个向量
NPY_FINLINE npyv_u8x2 npyv_unzip_u8(npyv_u8 ab0, npyv_u8 ab1)
{
    // 定义偶数索引顺序的向量
    const npyv_u8 idx_even = npyv_set_u8(
        0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30
    );
    // 定义奇数索引顺序的向量
    const npyv_u8 idx_odd = npyv_set_u8(
        1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31
    );
    // 定义返回结果的变量
    npyv_u8x2 r;
    // 使用 vec_perm 函数根据偶数索引重新排列 ab0 和 ab1,并存储到 r 的第一个元素
    r.val[0] = vec_perm(ab0, ab1, idx_even);
    // 使用 vec_perm 函数根据奇数索引重新排列 ab0 和 ab1,并存储到 r 的第二个元素
    r.val[1] = vec_perm(ab0, ab1, idx_odd);
    return r;  // 返回重新排列后的向量
}

// 同样的功能,但用于有符号的 8 位整数向量
NPY_FINLINE npyv_s8x2 npyv_unzip_s8(npyv_s8 ab0, npyv_s8 ab1)
{
    // 调用无符号 8 位整数的解交错函数,并将结果转换为有符号 8 位整数向量
    npyv_u8x2 ru = npyv_unzip_u8((npyv_u8)ab0, (npyv_u8)ab1);
    // 定义返回结果的变量
    npyv_s8x2 r;
    // 将 ru 的第一个元素转换为有符号 8 位整数并存储到 r 的第一个元素
    r.val[0] = (npyv_s8)ru.val[0];
    // 将 ru 的第二个元素转换为有符号 8 位整数并存储到 r 的第二个元素
    r.val[1] = (npyv_s8)ru.val[1];
    return r;  // 返回重新排列后的向量
}

// 类似的函数,用于无符号 16 位整数向量
NPY_FINLINE npyv_u16x2 npyv_unzip_u16(npyv_u16 ab0, npyv_u16 ab1)
{
    // 定义偶数索引顺序的向量
    const npyv_u8 idx_even = npyv_set_u8(
        0, 1, 4, 5, 8, 9, 12, 13, 16, 17, 20, 21, 24, 25, 28, 29
    );
    // 定义奇数索引顺序的向量
    const npyv_u8 idx_odd = npyv_set_u8(
        2, 3, 6, 7, 10, 11, 14, 15, 18, 19, 22, 23, 26, 27, 30, 31
    );
    // 定义返回结果的变量
    npyv_u16x2 r;
    // 使用 vec_perm 函数根据偶数索引重新排列 ab0 和 ab1,并存储到 r 的第一个元素
    r.val[0] = vec_perm(ab0, ab1, idx_even);
    // 使用 vec_perm 函数根据奇数索引重新排列 ab0 和 ab1,并存储到 r 的第二个元素
    r.val[1] = vec_perm(ab0, ab1, idx_odd);
    return r;  // 返回重新排列后的向量
}

// 类似的函数,用于有符号 16 位整数向量
NPY_FINLINE npyv_s16x2 npyv_unzip_s16(npyv_s16 ab0, npyv_s16 ab1)
{
    // 调用无符号 16 位整数的解交错函数,并将结果转换为有符号 16 位整数向量
    npyv_u16x2 ru = npyv_unzip_u16((npyv_u16)ab0, (npyv_u16)ab1);
    // 定义返回结果的变量
    npyv_s16x2 r;
    // 将 ru 的第一个元素转换为有符号 16 位整数并存储到 r 的第一个元素
    r.val[0] = (npyv_s16)ru.val[0];
    // 将 ru 的第二个元素转换为有符号 16 位整数并存储到 r 的第二个元素
    r.val[1] = (npyv_s16)ru.val[1];
    return r;  // 返回重新排列后的向量
}

// 类似的函数,用于无符号 32 位整数向量
NPY_FINLINE npyv_u32x2 npyv_unzip_u32(npyv_u32 ab0, npyv_u32 ab1)
{
    // 合并 ab0 和 ab1 的高位和低位部分,得到两个新的 32 位整数向量
    npyv_u32 m0 = vec_mergeh(ab0, ab1);
    npyv_u32 m1 = vec_mergel(ab0, ab1);
    // 再次合并 m0 和 m1 的高位和低位部分,得到两个重新排列的 32 位整数向量
    npyv_u32 r0 = vec_mergeh(m0, m1);
    npyv_u32 r1 = vec_mergel(m0, m1);
    // 定义返回结果的变量
    npyv_u32x2 r;
    // 将重新排列后的向量存储到返回结果中
    r.val[0] = r0;
    r.val[1] = r1;
    return r;  // 返回重新排列后的向量
}

// 类似的函数,用于有符号 32 位整数向量
NPY_FINLINE npyv_s32x2 npyv_unzip_s32(npyv_s32 ab0, npyv_s32 ab1)
{
    // 调用无符号 32 位整数的解交错函数,并将结果转换为有符号 32 位整数向量
    npyv_u32x2 ru = npyv_unzip_u32((npyv_u32)ab0, (npyv_u32)ab1);
    // 定义返回结果的变量
    npyv_s32x2 r;
    // 将 ru 的第一个元素转换为有符号 32 位整数并存储到 r 的第一个元素
    r.val[0] = (npyv_s32)ru.val[0];
    // 将 ru 的第二个元素转换为有符号 32 位整数并存储到 r 的第二个元素
    r.val[1] = (npyv_s32)ru.val[1];
    return r;  // 返回重新排列后的向量
}

// 如果支持单精度浮点数 SIMD 计算,则定义解交错函数,用于单精度浮点数向量
#if NPY_SIMD_F32
    NPY_FINLINE npyv_f32x2 npyv_unzip_f32(npyv_f32 ab0, npyv_f32 ab1)
    {
        // 调用无符号 32 位整数的解交错函数,并将结果转换为单精度浮点数向量
        npyv_u32x2 ru = npyv_unzip_u32((npyv_u32)ab0, (npyv_u32)ab1);
        // 定义返回结果的变量
        npyv
    );
    // 使用给定的索引向量 idx 对向量 a 进行排列操作,并返回结果
    return vec_perm(a, a, idx);
#endif
}

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

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

#ifndef _NPY_SIMD_VEC_UTILS_H
#define _NPY_SIMD_VEC_UTILS_H

// the following intrinsics may not some|all by zvector API on gcc/clang
#ifdef NPY_HAVE_VX
    #ifndef vec_neg
        #define vec_neg(a) (-(a)) // Vector Negate
    #endif
    #ifndef vec_add
        #define vec_add(a, b) ((a) + (b)) // Vector Add
    #endif
    #ifndef vec_sub
        #define vec_sub(a, b) ((a) - (b)) // Vector Subtract
    #endif
    #ifndef vec_mul
        #define vec_mul(a, b) ((a) * (b)) // Vector Multiply
    #endif
    #ifndef vec_div
        #define vec_div(a, b) ((a) / (b)) // Vector Divide
    #endif
    #ifndef vec_neg
        #define vec_neg(a) (-(a)) // Vector Negate
    #endif
    #ifndef vec_and
        #define vec_and(a, b) ((a) & (b)) // Vector AND
    #endif
    #ifndef vec_or
        #define vec_or(a, b) ((a) | (b)) // Vector OR
    #endif
    #ifndef vec_xor
        #define vec_xor(a, b) ((a) ^ (b)) // Vector XOR
    #endif
    #ifndef vec_sl
        #define vec_sl(a, b) ((a) << (b)) // Vector Shift Left
    #endif
    #ifndef vec_sra
        #define vec_sra(a, b) ((a) >> (b)) // Vector Shift Right Arithmetic
    #endif
    #ifndef vec_sr
        #define vec_sr(a, b) ((a) >> (b)) // Vector Shift Right Algebraic
    #endif
    #ifndef vec_slo
        #define vec_slo(a, b) vec_slb(a, (b) << 64) // Vector Shift Left by Octet
    #endif
    #ifndef vec_sro
        #define vec_sro(a, b) vec_srb(a, (b) << 64) // Vector Shift Right by Octet
    #endif
    // vec_doublee maps to wrong intrin "vfll".
    // see https://gcc.gnu.org/bugzilla/show_bug.cgi?id=100871
    #if defined(__GNUC__) && !defined(__clang__)
        #define npyv_doublee __builtin_s390_vflls
    #else
        #define npyv_doublee vec_doublee
    #endif
    // compatibility with vsx
    #ifndef vec_vbpermq
        #define vec_vbpermq vec_bperm_u128
    #endif
    // zvector requires second operand to signed while vsx api expected to be
    // unsigned, the following macros are set to remove this conflict
    #define vec_sl_s8(a, b)   vec_sl(a, (npyv_s8)(b)) // Vector Shift Left by 8-bit
    #define vec_sl_s16(a, b)  vec_sl(a, (npyv_s16)(b)) // Vector Shift Left by 16-bit
    #define vec_sl_s32(a, b)  vec_sl(a, (npyv_s32)(b)) // Vector Shift Left by 32-bit
    #define vec_sl_s64(a, b)  vec_sl(a, (npyv_s64)(b)) // Vector Shift Left by 64-bit
    #define vec_sra_s8(a, b)  vec_sra(a, (npyv_s8)(b)) // Vector Shift Right Arithmetic by 8-bit
    #define vec_sra_s16(a, b) vec_sra(a, (npyv_s16)(b)) // Vector Shift Right Arithmetic by 16-bit
    #define vec_sra_s32(a, b) vec_sra(a, (npyv_s32)(b)) // Vector Shift Right Arithmetic by 32-bit
    #define vec_sra_s64(a, b) vec_sra(a, (npyv_s64)(b)) // Vector Shift Right Arithmetic by 64-bit
#else
    // Define fallback macros for platforms without NPY_HAVE_VX support
    #define vec_sl_s8 vec_sl // Vector Shift Left by 8-bit
    #define vec_sl_s16 vec_sl // Vector Shift Left by 16-bit
    #define vec_sl_s32 vec_sl // Vector Shift Left by 32-bit
    #define vec_sl_s64 vec_sl // Vector Shift Left by 64-bit
    #define vec_sra_s8 vec_sra // Vector Shift Right Arithmetic by 8-bit
    #define vec_sra_s16 vec_sra // Vector Shift Right Arithmetic by 16-bit
    #define vec_sra_s32 vec_sra // Vector Shift Right Arithmetic by 32-bit
    #define vec_sra_s64 vec_sra // Vector Shift Right Arithmetic by 64-bit
#endif

#endif // _NPY_SIMD_VEC_UTILS_H

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

/**
 * This block of code defines SIMD (Single Instruction, Multiple Data) types and macros
 * tailored for different SIMD architectures and compilers.
 */

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

// Check if either VX(zarch11) or VSX2(Power8/ISA2.07) support is required
#if !defined(NPY_HAVE_VX) && !defined(NPY_HAVE_VSX2)
    #error "require minimum support VX(zarch11) or VSX2(Power8/ISA2.07)"
#endif

// Check for VSX support and ensure it's only used in little-endian mode
#if defined(NPY_HAVE_VSX) && !defined(__LITTLE_ENDIAN__)
    #error "VSX support doesn't cover big-endian mode yet, only zarch."
#endif

// Check for VX(zarch) support and restrict usage to big-endian mode
#if defined(NPY_HAVE_VX) && defined(__LITTLE_ENDIAN__)
    #error "VX(zarch) support doesn't cover little-endian mode."
#endif

// Suppress certain GCC warnings for older versions (<= 7) that might affect SIMD intrinsics
#if defined(__GNUC__) && __GNUC__ <= 7
    /**
      * GCC <= 7 produces ambiguous warning caused by -Werror=maybe-uninitialized,
      * when certain intrinsics involved. `vec_ld` is one of them but it seemed to work fine,
      * and suppressing the warning wouldn't affect its functionality.
      */
    #pragma GCC diagnostic ignored "-Wuninitialized"
    #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
#endif

// Define SIMD configuration constants
#define NPY_SIMD 128
#define NPY_SIMD_WIDTH 16
#define NPY_SIMD_F64 1

// Define NPY_SIMD_F32 based on whether NPY_HAVE_VXE or NPY_HAVE_VSX is defined
#if defined(NPY_HAVE_VXE) || defined(NPY_HAVE_VSX)
    #define NPY_SIMD_F32 1
#else
    #define NPY_SIMD_F32 0
#endif

// Enable native FMA3 support
#define NPY_SIMD_FMA3 1 // native support

// Define endianness and comparison signal macros based on architecture support
#ifdef NPY_HAVE_VX
    #define NPY_SIMD_BIGENDIAN 1
    #define NPY_SIMD_CMPSIGNAL 0
#else
    #define NPY_SIMD_BIGENDIAN 0
    #define NPY_SIMD_CMPSIGNAL 1
#endif

// Define SIMD vector types for various data types
typedef __vector unsigned char      npyv_u8;
typedef __vector signed char        npyv_s8;
typedef __vector unsigned short     npyv_u16;
typedef __vector signed short       npyv_s16;
typedef __vector unsigned int       npyv_u32;
typedef __vector signed int         npyv_s32;
typedef __vector unsigned long long npyv_u64;
typedef __vector signed long long   npyv_s64;
#if NPY_SIMD_F32
typedef __vector float              npyv_f32;
#endif
typedef __vector double             npyv_f64;

// Define SIMD vector types for 2-element structures
typedef struct { npyv_u8  val[2]; } npyv_u8x2;
typedef struct { npyv_s8  val[2]; } npyv_s8x2;
typedef struct { npyv_u16 val[2]; } npyv_u16x2;
typedef struct { npyv_s16 val[2]; } npyv_s16x2;
typedef struct { npyv_u32 val[2]; } npyv_u32x2;
typedef struct { npyv_s32 val[2]; } npyv_s32x2;
typedef struct { npyv_u64 val[2]; } npyv_u64x2;
typedef struct { npyv_s64 val[2]; } npyv_s64x2;
#if NPY_SIMD_F32
typedef struct { npyv_f32 val[2]; } npyv_f32x2;
#endif
typedef struct { npyv_f64 val[2]; } npyv_f64x2;

// Define SIMD vector types for 3-element structures
typedef struct { npyv_u8  val[3]; } npyv_u8x3;
typedef struct { npyv_s8  val[3]; } npyv_s8x3;
typedef struct { npyv_u16 val[3]; } npyv_u16x3;
typedef struct { npyv_s16 val[3]; } npyv_s16x3;
typedef struct { npyv_u32 val[3]; } npyv_u32x3;
typedef struct { npyv_s32 val[3]; } npyv_s32x3;
typedef struct { npyv_u64 val[3]; } npyv_u64x3;
typedef struct { npyv_s64 val[3]; } npyv_s64x3;
#if NPY_SIMD_F32
typedef struct { npyv_f32 val[3]; } npyv_f32x3;
#endif
typedef struct { npyv_f64 val[3]; } npyv_f64x3;

// Define number of lanes for each SIMD vector type
#define npyv_nlanes_u8  16
#define npyv_nlanes_s8  16
#define npyv_nlanes_u16 8
#define npyv_nlanes_s16 8
// 定义不同类型的 SIMD 向量的长度
#define npyv_nlanes_u32 4  // 无符号整数型向量长度为 4
#define npyv_nlanes_s32 4  // 有符号整数型向量长度为 4
#define npyv_nlanes_u64 2  // 无符号长整型向量长度为 2
#define npyv_nlanes_s64 2  // 有符号长整型向量长度为 2
#define npyv_nlanes_f32 4  // 单精度浮点数型向量长度为 4
#define npyv_nlanes_f64 2  // 双精度浮点数型向量长度为 2

// 使用 __vector __bool 与 typedef 结合会导致模糊错误,此处进行定义以避免
#define npyv_b8  __vector __bool char    // 8 位布尔型向量
#define npyv_b16 __vector __bool short   // 16 位布尔型向量
#define npyv_b32 __vector __bool int     // 32 位布尔型向量
#define npyv_b64 __vector __bool long long  // 64 位布尔型向量

// 包含各种工具、内存、杂项、重新排序、操作符、类型转换、算术运算和数学函数的头文件
#include "utils.h"
#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\ucsnarrow.c

/*
 * 定义宏,禁用已弃用的 NumPy API,并设置为当前 API 版本
 */
#define NPY_NO_DEPRECATED_API NPY_API_VERSION

/*
 * 定义宏,指示该文件属于 MultiArray 模块
 */
#define _MULTIARRAYMODULE

/*
 * 引入 Python 头文件
 */
#define PY_SSIZE_T_CLEAN
#include <Python.h>

/*
 * 引入 NumPy 数组对象头文件
 */
#include "numpy/arrayobject.h"

/*
 * 引入 NumPy 的数学函数和宏定义头文件
 */
#include "numpy/npy_math.h"

/*
 * 引入 NumPy 的配置头文件
 */
#include "npy_config.h"

/*
 * 引入自定义的 ctors.h 头文件
 */
#include "ctors.h"

/*
 * 以下部分的代码原本包含在窄版 Python 构建中,用于在 NumPy Unicode 数据类型(总是 4 字节)和 Python Unicode 标量(在窄版中为 2 字节)之间进行转换。
 * 这个 "narrow" 接口现在在 Python 中已被弃用,并且在 NumPy 中未被使用。
 */

/*
 * 从包含 UCS4 Unicode 的缓冲区初始化 PyUnicodeObject 对象。
 *
 * Parameters
 * ----------
 *  src: char *
 *      指向包含 UCS4 Unicode 的缓冲区的指针。
 *  size: Py_ssize_t
 *      缓冲区的字节大小。
 *  swap: int
 *      如果为真,则对数据进行交换。
 *  align: int
 *      如果为真,则对数据进行对齐。
 *
 * Returns
 * -------
 * new_reference: PyUnicodeObject
 *      初始化后的 PyUnicodeObject 对象。
 */
NPY_NO_EXPORT PyUnicodeObject *
PyUnicode_FromUCS4(char const *src_char, Py_ssize_t size, int swap, int align)
{
    Py_ssize_t ucs4len = size / sizeof(npy_ucs4);
    npy_ucs4 const *src = (npy_ucs4 const *)src_char;
    npy_ucs4 *buf = NULL;

    /* 如果需要,进行数据交换和对齐 */
    if (swap || align) {
        buf = (npy_ucs4 *)malloc(size);
        if (buf == NULL) {
            PyErr_NoMemory();
            return NULL;
        }
        memcpy(buf, src, size);
        if (swap) {
            byte_swap_vector(buf, ucs4len, sizeof(npy_ucs4));
        }
        src = buf;
    }

    /* 去除尾部的零 */
    while (ucs4len > 0 && src[ucs4len - 1] == 0) {
        ucs4len--;
    }

    /* 使用 PyUnicode_FromKindAndData 函数创建 PyUnicodeObject 对象 */
    PyUnicodeObject *ret = (PyUnicodeObject *)PyUnicode_FromKindAndData(
        PyUnicode_4BYTE_KIND, src, ucs4len);
    
    /* 释放申请的内存 */
    free(buf);

    /* 返回创建的 PyUnicodeObject 对象 */
    return ret;
}

.\numpy\numpy\_core\src\common\ucsnarrow.h

#ifndef NUMPY_CORE_SRC_COMMON_NPY_UCSNARROW_H_
// 如果未定义 NUMPY_CORE_SRC_COMMON_NPY_UCSNARROW_H_ 宏,则执行以下内容
#define NUMPY_CORE_SRC_COMMON_NPY_UCSNARROW_H_
// 定义 NUMPY_CORE_SRC_COMMON_NPY_UCSNARROW_H_ 宏

// 声明一个不导出的函数 PyUnicode_FromUCS4,返回一个 PyUnicodeObject 对象指针
NPY_NO_EXPORT PyUnicodeObject *
PyUnicode_FromUCS4(char const *src, Py_ssize_t size, int swap, int align);

// 结束条件,关闭 NUMPY_CORE_SRC_COMMON_NPY_UCSNARROW_H_ 宏定义
#endif  /* NUMPY_CORE_SRC_COMMON_NPY_UCSNARROW_H_ */
// 结束条件,关闭条件编译指令

.\numpy\numpy\_core\src\common\ufunc_override.c

/*
 * 定义宏,禁用所有已弃用的 NumPy API,使用当前版本的 API
 */
#define NPY_NO_DEPRECATED_API NPY_API_VERSION

/*
 * 定义宏,启用多维数组模块
 */
#define _MULTIARRAYMODULE

/*
 * 包含必要的头文件,用于 NumPy 的数组类型定义
 */
#include "numpy/ndarraytypes.h"
#include "npy_pycompat.h"
#include "get_attr_string.h"
#include "npy_import.h"
#include "ufunc_override.h"
#include "scalartypes.h"
#include "npy_static_data.h"

/*
 * 检查对象是否在其类上定义了 __array_ufunc__ 方法,并且它不是默认的情况下,
 * 即对象不是 ndarray,并且其 __array_ufunc__ 与 ndarray 的不同。
 *
 * 如果存在并且不同于 ndarray 的 __array_ufunc__,返回类型(obj).__array_ufunc__ 的新引用;
 * 否则返回 NULL。
 */
NPY_NO_EXPORT PyObject *
PyUFuncOverride_GetNonDefaultArrayUfunc(PyObject *obj)
{
    PyObject *cls_array_ufunc;

    /* 快速返回 ndarray */
    if (PyArray_CheckExact(obj)) {
        return NULL;
    }
    
    /* 快速返回 numpy 标量类型 */
    if (is_anyscalar_exact(obj)) {
        return NULL;
    }

    /*
     * 类是否定义了 __array_ufunc__?(注意,LookupSpecial 对基本的 Python 类型有快速返回,所以这里不必担心)
     */
    cls_array_ufunc = PyArray_LookupSpecial(obj, npy_interned_str.array_ufunc);
    if (cls_array_ufunc == NULL) {
        if (PyErr_Occurred()) {
            PyErr_Clear(); /* TODO[gh-14801]: 在属性访问期间传播崩溃? */
        }
        return NULL;
    }

    /* 如果与 ndarray.__array_ufunc__ 相同,则忽略 */
    if (cls_array_ufunc == npy_static_pydata.ndarray_array_ufunc) {
        Py_DECREF(cls_array_ufunc);
        return NULL;
    }

    return cls_array_ufunc;
}

/*
 * 检查对象是否在其类上定义了 __array_ufunc__ 方法,并且它不是默认的情况下,
 * 即对象不是 ndarray,并且其 __array_ufunc__ 与 ndarray 的不同。
 *
 * 如果是,返回 1;否则返回 0。
 */
NPY_NO_EXPORT int
PyUFunc_HasOverride(PyObject * obj)
{
    PyObject *method = PyUFuncOverride_GetNonDefaultArrayUfunc(obj);
    if (method) {
        Py_DECREF(method);
        return 1;
    }
    else {
        return 0;
    }
}

/*
 * 从 kwds 中获取可能的 out 参数,并返回其中包含的输出数量:
 * 如果是一个元组,则返回其中元素的数量,否则返回 1。
 * out 参数本身作为 out_kwd_obj 返回,并且输出作为 out_objs 数组(作为借用引用)返回。
 *
 * 如果没有找到输出,则返回 0;如果 kwds 不是字典,则返回 -1(并设置错误)。
 */
NPY_NO_EXPORT int
PyUFuncOverride_GetOutObjects(PyObject *kwds, PyObject **out_kwd_obj, PyObject ***out_objs)
{
    if (kwds == NULL) {
        Py_INCREF(Py_None);
        *out_kwd_obj = Py_None;
        return 0;
    }

    if (!PyDict_CheckExact(kwds)) {
        PyErr_SetString(PyExc_TypeError,
                        "Internal Numpy error: call to PyUFuncOverride_GetOutObjects "
                        "with non-dict kwds");
        *out_kwd_obj = NULL;
        return -1;
    }

    int result = PyDict_GetItemStringRef(kwds, "out", out_kwd_obj);
    // 如果结果为 -1,则返回 -1
    if (result == -1) {
        return -1;
    }
    // 如果结果为 0,则增加 Py_None 的引用计数,将其赋给 out_kwd_obj,然后返回 0
    else if (result == 0) {
        Py_INCREF(Py_None);
        *out_kwd_obj = Py_None;
        return 0;
    }
    // 如果 out_kwd_obj 是 PyTuple 类型的对象
    if (PyTuple_CheckExact(*out_kwd_obj)) {
        /*
         * C-API 建议在调用任何 PySequence_Fast* 函数之前调用 PySequence_Fast。
         * 这对于 PyPy 是必需的。
         */
        // 声明 PyObject 指针 seq,用 PySequence_Fast 快速转换 *out_kwd_obj
        PyObject *seq;
        seq = PySequence_Fast(*out_kwd_obj,
                              "Could not convert object to sequence");
        // 如果转换失败,清除 *out_kwd_obj,并返回 -1
        if (seq == NULL) {
            Py_CLEAR(*out_kwd_obj);
            return -1;
        }
        // 获取 PySequence_Fast 转换后的对象数组指针,并赋给 *out_objs
        *out_objs = PySequence_Fast_ITEMS(seq);
        // 将 seq 的引用计数设置给 *out_kwd_obj,并返回 seq 的大小
        Py_SETREF(*out_kwd_obj, seq);
        return PySequence_Fast_GET_SIZE(seq);
    }
    // 如果 out_kwd_obj 不是 PyTuple 类型的对象
    else {
        // 将 out_kwd_obj 的地址赋给 *out_objs,并返回 1
        *out_objs = out_kwd_obj;
        return 1;
    }
}


注释:

# 这是一个单独的右花括号,用于结束某个代码块或函数定义的主体部分

.\numpy\numpy\_core\src\common\ufunc_override.h

#ifndef NUMPY_CORE_SRC_COMMON_UFUNC_OVERRIDE_H_
#define NUMPY_CORE_SRC_COMMON_UFUNC_OVERRIDE_H_

#include "npy_config.h"

/*
 * Check whether an object has __array_ufunc__ defined on its class and it
 * is not the default, i.e., the object is not an ndarray, and its
 * __array_ufunc__ is not the same as that of ndarray.
 *
 * Returns a new reference, the value of type(obj).__array_ufunc__ if it
 * exists and is different from that of ndarray, and NULL otherwise.
 */
// 声明 PyUFuncOverride_GetNonDefaultArrayUfunc 函数,检查对象是否定义了非默认的 __array_ufunc__
NPY_NO_EXPORT PyObject *
PyUFuncOverride_GetNonDefaultArrayUfunc(PyObject *obj);

/*
 * Check whether an object has __array_ufunc__ defined on its class and it
 * is not the default, i.e., the object is not an ndarray, and its
 * __array_ufunc__ is not the same as that of ndarray.
 *
 * Returns 1 if this is the case, 0 if not.
 */
// 声明 PyUFunc_HasOverride 函数,检查对象是否具有 __array_ufunc__ 的重写
NPY_NO_EXPORT int
PyUFunc_HasOverride(PyObject *obj);

/*
 * Get possible out argument from kwds, and returns the number of outputs
 * contained within it: if a tuple, the number of elements in it, 1 otherwise.
 * The out argument itself is returned in out_kwd_obj, and the outputs
 * in the out_obj array (as borrowed references).
 *
 * Returns 0 if no outputs found, -1 if kwds is not a dict (with an error set).
 */
// 声明 PyUFuncOverride_GetOutObjects 函数,从关键字参数中获取可能的输出参数,并返回输出的数量
NPY_NO_EXPORT int
PyUFuncOverride_GetOutObjects(PyObject *kwds, PyObject **out_kwd_obj, PyObject ***out_objs);

#endif  /* NUMPY_CORE_SRC_COMMON_UFUNC_OVERRIDE_H_ */

.\numpy\numpy\_core\src\common\umathmodule.h

#ifndef NUMPY_CORE_SRC_COMMON_UMATHMODULE_H_
#define NUMPY_CORE_SRC_COMMON_UMATHMODULE_H_

// 包含以下头文件,这些头文件定义了ufunc对象、ufunc类型解析和Python侧的扩展对象的设置/获取
#include "ufunc_object.h"
#include "ufunc_type_resolution.h"
#include "extobj.h"  /* for the python side extobj set/get */

// NPY_NO_EXPORT表示这个函数不会被导出到模块外部
NPY_NO_EXPORT PyObject *
get_sfloat_dtype(PyObject *NPY_UNUSED(mod), PyObject *NPY_UNUSED(args));

// 添加新的文档字符串到ufunc对象中
PyObject * add_newdoc_ufunc(PyObject *NPY_UNUSED(dummy), PyObject *args);

// 根据给定的Python函数创建一个ufunc对象
PyObject * ufunc_frompyfunc(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *NPY_UNUSED(kwds));

// 初始化umath模块,返回一个整数作为初始化的结果
int initumath(PyObject *m);

#endif  /* NUMPY_CORE_SRC_COMMON_UMATHMODULE_H_ */

.\numpy\numpy\_core\src\common\utils.hpp

#ifndef NUMPY_CORE_SRC_COMMON_UTILS_HPP
#define NUMPY_CORE_SRC_COMMON_UTILS_HPP

#include "npdef.hpp"

#if NP_HAS_CPP20
    #include <bit>
#endif

#include <type_traits>
#include <string.h>
#include <cstdint>
#include <cassert>

namespace np {

using std::uint32_t;
using std::uint64_t;

/** Create a value of type `To` from the bits of `from`.
 *
 * similar to `std::bit_cast` but compatible with C++17,
 * should perform similar to `*reinterpret_cast<To*>(&from)`
 * or through punning without expecting any undefined behaviors.
 */
template<typename To, typename From>
#if NP_HAS_BUILTIN(__builtin_bit_cast) || NP_HAS_CPP20
[[nodiscard]] constexpr
#else
inline
#endif
To BitCast(const From &from) noexcept
{
    // 静态断言:确保目标类型和源类型具有相同的大小
    static_assert(
        sizeof(To) == sizeof(From),
        "both data types must have the same size");

    // 静态断言:确保目标类型和源类型都是平凡可复制的
    static_assert(
        std::is_trivially_copyable_v<To> &&
        std::is_trivially_copyable_v<From>,
        "both data types must be trivially copyable");

    // 根据编译器支持情况选择实现方式
#if NP_HAS_CPP20
    return std::bit_cast<To>(from);
#elif NP_HAS_BUILTIN(__builtin_bit_cast)
    return __builtin_bit_cast(To, from);
#else
    // 使用 memcpy 进行位拷贝
    To to;
    memcpy(&to, &from, sizeof(from));
    return to;
#endif
}

/// Bit-scan reverse for non-zeros.
/// Returns the index of the highest set bit. Equivalent to floor(log2(a))
template <typename T>
inline int BitScanReverse(uint32_t a)
{
    // 根据编译器支持情况选择实现方式
#if NP_HAS_CPP20
    return std::countl_one(a);
#else
    // 如果 a 为 0,返回 0
    if (a == 0) {
        // 由于使用了 __builtin_clz,可能导致未定义行为
        return 0;
    }
    int r;
    // 根据编译器选择特定的实现方式
    #ifdef _MSC_VER
    unsigned long rl;
    (void)_BitScanReverse(&rl, (unsigned long)a);
    r = static_cast<int>(rl);
    #elif (defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER)) \
        &&  (defined(NPY_CPU_X86) || defined(NPY_CPU_AMD64))
    __asm__("bsr %1, %0" : "=r" (r) : "r"(a));
    #elif defined(__GNUC__) || defined(__clang__)
    r = 31 - __builtin_clz(a); // 执行于 arm -> clz, ppc -> cntlzw
    #else
    r = 0;
    while (a >>= 1) {
        r++;
    }
    #endif
    return r;
#endif
}

/// Bit-scan reverse for non-zeros.
/// Returns the index of the highest set bit. Equivalent to floor(log2(a))
inline int BitScanReverse(uint64_t a)
{
    // 根据编译器支持情况选择实现方式
#if NP_HAS_CPP20
    return std::countl_one(a);
#else
    // 如果 a 为 0,返回 0
    if (a == 0) {
        // 由于使用了 __builtin_clzll,可能导致未定义行为
        return 0;
    }
    // 根据平台和编译器选择特定的实现方式
    #if defined(_M_AMD64) && defined(_MSC_VER)
    unsigned long rl;
    (void)_BitScanReverse64(&rl, a);
    return static_cast<int>(rl);
    #elif defined(__x86_64__) && (defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER))
    uint64_t r;
    __asm__("bsrq %1, %0" : "=r"(r) : "r"(a));
    return static_cast<int>(r);
    #elif defined(__GNUC__) || defined(__clang__)
    return 63 - __builtin_clzll(a);
    #else
    uint64_t a_hi = a >> 32;
    if (a_hi == 0) {
        return BitScanReverse(static_cast<uint32_t>(a));
    }
    return 32 + BitScanReverse(static_cast<uint32_t>(a_hi));
    #endif
#endif
}
    #endif
#endif

这行代码是预处理器指令,用于结束一个条件编译指令块。在这里,`#endif` 结束了之前由 `#ifndef` 或 `#if` 开始的条件编译块。


}

这是 C++ 中的闭合花括号 `}`,用于结束 `namespace np` 命名空间的定义。


} // namespace np

这行代码注释结束了 `namespace np` 命名空间的定义,提供了命名空间结束的说明性注释。


#endif // NUMPY_CORE_SRC_COMMON_UTILS_HPP

这是条件编译指令的结尾,`#endif` 用于结束条件编译块,后面的 `// NUMPY_CORE_SRC_COMMON_UTILS_HPP` 是注释,指出这个 `#endif` 是为了匹配开始于 `NUMPY_CORE_SRC_COMMON_UTILS_HPP` 的条件编译指令。

.\numpy\numpy\_core\src\dummymodule.c

/*
 * -*- c -*-
 */

/*
 * This is a dummy module whose purpose is to get distutils to generate the
 * configuration files before the libraries are made.
 */

/* Define to prevent including deprecated API and use the current API version */
#define NPY_NO_DEPRECATED_API NPY_API_VERSION

/* Define to prevent importing array when not needed */
#define NO_IMPORT_ARRAY

/* Include Python.h header file for Python C API */
#include <Python.h>

/* Define the structure for methods (functions) in this module */
static struct PyMethodDef methods[] = {
    {NULL, NULL, 0, NULL}  /* Sentinel entry indicating end of method definitions */
};

/* Define the structure for the module itself */
static struct PyModuleDef moduledef = {
    PyModuleDef_HEAD_INIT,  /* Indicates initialization of PyModuleDef structure */
    "dummy",                /* Module name */
    NULL,                   /* Module documentation, unused in this case */
    -1,                     /* Size of per-interpreter state of the module, -1 indicates global variables */
    methods,                /* Array of module-level functions */
    NULL,                   /* Optional slot for module-level traverse function */
    NULL,                   /* Optional slot for module-level clear function */
    NULL,                   /* Optional slot for module-level free function */
    NULL                    /* Optional slot for module-level traversal context */
};

/* Initialization function for the module */
PyMODINIT_FUNC PyInit__dummy(void) {
    PyObject *m;

    /* Create the module object */
    m = PyModule_Create(&moduledef);
    if (!m) {
        return NULL;  /* Return NULL on failure to create module */
    }

    return m;  /* Return the created module object */
}

.\numpy\numpy\_core\src\multiarray\abstractdtypes.c

/*
 * 定义宏以避免使用已弃用的 NumPy API 版本,并指定多维数组模块。
 */
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
#define _MULTIARRAYMODULE

/*
 * 引入必要的头文件和库文件,包括 Python 标准库、结构成员定义、NumPy 的相关头文件、
 * 以及自定义的数据类型元信息、抽象数据类型、数组强制转换和通用函数。
 */
#include <Python.h>
#include <structmember.h>

#include "numpy/ndarraytypes.h"
#include "numpy/arrayobject.h"

#include "dtypemeta.h"
#include "abstractdtypes.h"
#include "array_coercion.h"
#include "common.h"


/*
 * 定义静态内联函数 int_default_descriptor,用于返回整数类型的数组描述符。
 */
static inline PyArray_Descr *
int_default_descriptor(PyArray_DTypeMeta* NPY_UNUSED(cls))
{
    return PyArray_DescrFromType(NPY_INTP);
}

/*
 * 根据 Python 的 long 对象发现合适的数据类型描述符。
 * 如果长整型不足以表示,会依次检查长长整型、无符号长整型,最后返回对象类型。
 */
static PyArray_Descr *
discover_descriptor_from_pylong(
        PyArray_DTypeMeta *NPY_UNUSED(cls), PyObject *obj)
{
    assert(PyLong_Check(obj));
    
    long long value = PyLong_AsLongLong(obj);
    if (error_converting(value)) {
        PyErr_Clear();
    }
    else {
        if (NPY_MIN_INTP <= value && value <= NPY_MAX_INTP) {
            return PyArray_DescrFromType(NPY_INTP);
        }
        return PyArray_DescrFromType(NPY_LONGLONG);
    }

    unsigned long long uvalue = PyLong_AsUnsignedLongLong(obj);
    if (uvalue == (unsigned long long)-1 && PyErr_Occurred()){
        PyErr_Clear();
    }
    else {
        return PyArray_DescrFromType(NPY_ULONGLONG);
    }

    return PyArray_DescrFromType(NPY_OBJECT);
}

/*
 * 定义静态内联函数 float_default_descriptor,用于返回双精度浮点数类型的数组描述符。
 */
static inline PyArray_Descr *
float_default_descriptor(PyArray_DTypeMeta* NPY_UNUSED(cls))
{
    return PyArray_DescrFromType(NPY_DOUBLE);
}

/*
 * 根据 Python 的 float 对象发现合适的数据类型描述符,总是返回双精度浮点数类型。
 */
static PyArray_Descr*
discover_descriptor_from_pyfloat(
        PyArray_DTypeMeta* NPY_UNUSED(cls), PyObject *obj)
{
    assert(PyFloat_CheckExact(obj));
    return PyArray_DescrFromType(NPY_DOUBLE);
}

/*
 * 定义静态内联函数 complex_default_descriptor,用于返回双精度复数类型的数组描述符。
 */
static inline PyArray_Descr *
complex_default_descriptor(PyArray_DTypeMeta* NPY_UNUSED(cls))
{
    return PyArray_DescrFromType(NPY_CDOUBLE);
}

/*
 * 根据 Python 的 complex 对象发现合适的数据类型描述符,总是返回复数128位类型。
 */
static PyArray_Descr*
discover_descriptor_from_pycomplex(
        PyArray_DTypeMeta* NPY_UNUSED(cls), PyObject *obj)
{
    assert(PyComplex_CheckExact(obj));
    return PyArray_DescrFromType(NPY_COMPLEX128);
}

/*
 * 初始化并映射 Python 类型到 NumPy 的数据类型。
 * 如果初始化任何一个抽象数据类型失败,则返回 -1。
 * 延迟赋值以避免在 Windows 编译器中出现 "error C2099: initializer is not a constant"。
 */
NPY_NO_EXPORT int
initialize_and_map_pytypes_to_dtypes()
{
    if (PyType_Ready((PyTypeObject *)&PyArray_IntAbstractDType) < 0) {
        return -1;
    }
    if (PyType_Ready((PyTypeObject *)&PyArray_FloatAbstractDType) < 0) {
        return -1;
    }
    if (PyType_Ready((PyTypeObject *)&PyArray_ComplexAbstractDType) < 0) {
        return -1;
    }

    /*
     * 延迟赋值以避免在 Windows 编译器中出现 "error C2099: initializer is not a constant"。
     * 期望将来能够在结构体中完成这些赋值。
     */
    ((PyTypeObject *)&PyArray_PyLongDType)->tp_base =
        (PyTypeObject *)&PyArray_IntAbstractDType;
    PyArray_PyLongDType.scalar_type = &PyLong_Type;
    if (PyType_Ready((PyTypeObject *)&PyArray_PyLongDType) < 0) {
        return -1;
    }

    ((PyTypeObject *)&PyArray_PyFloatDType)->tp_base =
        (PyTypeObject *)&PyArray_FloatAbstractDType;
    PyArray_PyFloatDType.scalar_type = &PyFloat_Type;
    
    /* 省略部分代码,根据上下文可能还有其他内容 */

    return 0;
}
    // 如果 PyArray_PyFloatDType 类型未准备好,返回错误码 -1
    if (PyType_Ready((PyTypeObject *)&PyArray_PyFloatDType) < 0) {
        return -1;
    }
    // 将 PyArray_PyComplexDType 的基类设置为 PyArray_ComplexAbstractDType
    ((PyTypeObject *)&PyArray_PyComplexDType)->tp_base =
        (PyTypeObject *)&PyArray_ComplexAbstractDType;
    // 将 PyArray_PyComplexDType 的标量类型设置为 PyComplex_Type
    PyArray_PyComplexDType.scalar_type = &PyComplex_Type;
    // 如果 PyArray_PyComplexDType 类型未准备好,返回错误码 -1
    if (PyType_Ready((PyTypeObject *)&PyArray_PyComplexDType) < 0) {
        return -1;
    }

    /* 注册新的数据类型以便发现 */
    // 将 PyLong_Type 映射为 PyArray_PyLongDType 数据类型
    if (_PyArray_MapPyTypeToDType(
            &PyArray_PyLongDType, &PyLong_Type, NPY_FALSE) < 0) {
        return -1;
    }
    // 将 PyFloat_Type 映射为 PyArray_PyFloatDType 数据类型
    if (_PyArray_MapPyTypeToDType(
            &PyArray_PyFloatDType, &PyFloat_Type, NPY_FALSE) < 0) {
        return -1;
    }
    // 将 PyComplex_Type 映射为 PyArray_PyComplexDType 数据类型
    if (_PyArray_MapPyTypeToDType(
            &PyArray_PyComplexDType, &PyComplex_Type, NPY_FALSE) < 0) {
        return -1;
    }

    /*
     * 将 strbytesbool 映射为 NumPy 的数据类型。
     * 这里使用 `is_known_scalar_type` 函数来完成。
     * 注意:`is_known_scalar_type` 函数目前被视为初步版本,
     *       可能会通过额外的抽象数据类型来实现相同的功能。
     */
    // 将 PyUnicode_Type 映射为 Unicode 字符串类型
    PyArray_DTypeMeta *dtype;
    dtype = NPY_DTYPE(PyArray_DescrFromType(NPY_UNICODE));
    if (_PyArray_MapPyTypeToDType(dtype, &PyUnicode_Type, NPY_FALSE) < 0) {
        return -1;
    }
    // 将 PyBytes_Type 映射为字节串类型
    dtype = NPY_DTYPE(PyArray_DescrFromType(NPY_STRING));
    if (_PyArray_MapPyTypeToDType(dtype, &PyBytes_Type, NPY_FALSE) < 0) {
        return -1;
    }
    // 将 PyBool_Type 映射为布尔类型
    dtype = NPY_DTYPE(PyArray_DescrFromType(NPY_BOOL));
    if (_PyArray_MapPyTypeToDType(dtype, &PyBool_Type, NPY_FALSE) < 0) {
        return -1;
    }

    // 成功执行,返回成功码 0
    return 0;
/*
 * The following functions define the "common DType" for the abstract dtypes.
 *
 * Note that the logic with respect to the "higher" dtypes such as floats
 * could likely be more logically defined for them, but since NumPy dtypes
 * largely "know" each other, that is not necessary.
 */

static PyArray_DTypeMeta *
int_common_dtype(PyArray_DTypeMeta *NPY_UNUSED(cls), PyArray_DTypeMeta *other)
{
    // 如果传入的数据类型是遗留类型且类型编号小于遗留类型数量
    if (NPY_DT_is_legacy(other) && other->type_num < NPY_NTYPES_LEGACY) {
        // 如果传入的类型是布尔类型
        if (other->type_num == NPY_BOOL) {
            /* Use the default integer for bools: */
            // 返回默认整数类型(PyArray_IntpDType)的新引用
            return NPY_DT_NewRef(&PyArray_IntpDType);
        }
    }
    // 如果传入的数据类型是遗留类型
    else if (NPY_DT_is_legacy(other)) {
        /* This is a back-compat fallback to usually do the right thing... */
        // 创建一个指向PyArray_UInt8DType的指针
        PyArray_DTypeMeta *uint8_dt = &PyArray_UInt8DType;
        // 调用传入类型和uint8_dt的共同数据类型函数
        PyArray_DTypeMeta *res = NPY_DT_CALL_common_dtype(other, uint8_dt);
        // 释放uint8_dt的引用
        Py_DECREF(uint8_dt);
        // 如果返回为空
        if (res == NULL) {
            // 清除错误
            PyErr_Clear();
        }
        // 如果返回为Py_NotImplemented
        else if (res == (PyArray_DTypeMeta *)Py_NotImplemented) {
            // 释放res的引用
            Py_DECREF(res);
        }
        // 否则
        else {
            // 返回res
            return res;
        }
        /* Try again with `int8`, an error may have been set, though */
        // 创建一个指向PyArray_Int8DType的指针
        PyArray_DTypeMeta *int8_dt = &PyArray_Int8DType;
        // 调用传入类型和int8_dt的共同数据类型函数
        res = NPY_DT_CALL_common_dtype(other, int8_dt);
        // 如果返回为空
        if (res == NULL) {
            // 清除错误
            PyErr_Clear();
        }
        // 如果返回为Py_NotImplemented
        else if (res == (PyArray_DTypeMeta *)Py_NotImplemented) {
            // 释放res的引用
            Py_DECREF(res);
        }
        // 否则
        else {
            // 返回res
            return res;
        }
        /* And finally, we will try the default integer, just for sports... */
        // 创建一个指向PyArray_IntpDType的指针
        PyArray_DTypeMeta *default_int = &PyArray_IntpDType;
        // 调用传入类型和default_int的共同数据类型函数
        res = NPY_DT_CALL_common_dtype(other, default_int);
        // 如果返回为空
        if (res == NULL) {
            // 清除错误
            PyErr_Clear();
        }
        // 返回res
        return res;
    }
    // 增加Py_NotImplemented的引用计数
    Py_INCREF(Py_NotImplemented);
    // 返回Py_NotImplemented
    return (PyArray_DTypeMeta *)Py_NotImplemented;
}


static PyArray_DTypeMeta *
float_common_dtype(PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
{
    // 如果传入的数据类型是遗留类型且类型编号小于遗留类型数量
    if (NPY_DT_is_legacy(other) && other->type_num < NPY_NTYPES_LEGACY) {
        // 如果传入的类型是布尔类型或者整数类型
        if (other->type_num == NPY_BOOL || PyTypeNum_ISINTEGER(other->type_num)) {
            /* Use the default integer for bools and ints: */
            // 返回默认双精度浮点类型(PyArray_DoubleDType)的新引用
            return NPY_DT_NewRef(&PyArray_DoubleDType);
        }
    }
    // 如果传入的类型是PyArray_PyLongDType
    else if (other == &PyArray_PyLongDType) {
        // 增加cls的引用计数并返回cls
        Py_INCREF(cls);
        return cls;
    }
    // 返回Py_NotImplemented
    return (PyArray_DTypeMeta *)Py_NotImplemented;
}
    else if (NPY_DT_is_legacy(other)) {
        /* 如果 'other' 是遗留数据类型,执行以下操作 */
        /* 这是向后兼容的回退,通常会执行正确的操作... */
        
        // 指向半精度数据类型的指针
        PyArray_DTypeMeta *half_dt = &PyArray_HalfDType;
        
        // 查找 'other' 和半精度数据类型的公共数据类型
        PyArray_DTypeMeta *res = NPY_DT_CALL_common_dtype(other, half_dt);
        
        // 如果未找到公共数据类型,清除错误状态
        if (res == NULL) {
            PyErr_Clear();
        }
        // 如果返回结果是 Py_NotImplemented,则释放 'res'
        else if (res == (PyArray_DTypeMeta *)Py_NotImplemented) {
            Py_DECREF(res);
        }
        // 否则返回找到的公共数据类型
        else {
            return res;
        }
        
        // 使用双精度(默认的浮点数)再次尝试
        // 指向双精度数据类型的指针
        PyArray_DTypeMeta *double_dt = &PyArray_DoubleDType;
        
        // 查找 'other' 和双精度数据类型的公共数据类型
        res = NPY_DT_CALL_common_dtype(other, double_dt);
        
        // 返回找到的公共数据类型
        return res;
    }
    
    // 增加对 Py_NotImplemented 的引用计数
    Py_INCREF(Py_NotImplemented);
    
    // 返回 Py_NotImplemented,表示未找到合适的数据类型
    return (PyArray_DTypeMeta *)Py_NotImplemented;
}



/*
 * 返回两个数据类型的共同复合数据类型。
 * 如果 `other` 是遗留类型并且类型编号小于 `NPY_NTYPES_LEGACY`,
 * 对于布尔和整数类型,使用默认的复合数据类型 PyArray_CDoubleDType。
 * 否则,如果 `other` 是遗留类型,则使用通常情况下正确的复合数据类型(fallback)。
 * 如果使用 PyArray_CFloatDType 没有得到结果,清除异常,并尝试使用 PyArray_CDoubleDType。
 * 如果 `other` 是 PyArray_PyLongDType 或 PyArray_PyFloatDType,返回 `cls`。
 * 否则,返回 Py_NotImplemented 表示未实现。
 */
static PyArray_DTypeMeta *
complex_common_dtype(PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
{
    if (NPY_DT_is_legacy(other) && other->type_num < NPY_NTYPES_LEGACY) {
        if (other->type_num == NPY_BOOL ||
                PyTypeNum_ISINTEGER(other->type_num)) {
            /* Use the default integer for bools and ints: */
            return NPY_DT_NewRef(&PyArray_CDoubleDType);
        }
    }
    else if (NPY_DT_is_legacy(other)) {
        /* This is a back-compat fallback to usually do the right thing... */
        PyArray_DTypeMeta *cfloat_dt = &PyArray_CFloatDType;
        PyArray_DTypeMeta *res = NPY_DT_CALL_common_dtype(other, cfloat_dt);
        if (res == NULL) {
            PyErr_Clear();
        }
        else if (res == (PyArray_DTypeMeta *)Py_NotImplemented) {
            Py_DECREF(res);
        }
        else {
            return res;
        }
        /* Retry with cdouble (the default complex) */
        PyArray_DTypeMeta *cdouble_dt = &PyArray_CDoubleDType;
        res = NPY_DT_CALL_common_dtype(other, cdouble_dt);
        return res;
    }
    else if (other == &PyArray_PyLongDType ||
             other == &PyArray_PyFloatDType) {
        Py_INCREF(cls);
        return cls;
    }
    Py_INCREF(Py_NotImplemented);
    return (PyArray_DTypeMeta *)Py_NotImplemented;
}



/*
 * 在 arraytypes.c.src 中定义所有常规数据类型可以继承的抽象数值数据类型。
 * 在此还定义与 Python 标量对应的数据类型。
 */
NPY_NO_EXPORT PyArray_DTypeMeta PyArray_IntAbstractDType = {{{
        PyVarObject_HEAD_INIT(&PyArrayDTypeMeta_Type, 0)
        .tp_name = "numpy.dtypes._IntegerAbstractDType",
        .tp_base = &PyArrayDescr_Type,
        .tp_basicsize = sizeof(PyArray_Descr),
        .tp_flags = Py_TPFLAGS_DEFAULT,
    },},
    .type_num = -1,
    .flags = NPY_DT_ABSTRACT,
};

/*
 * 定义与 PyLong 对象对应的数据类型结构 PyArray_PyLongDType。
 * 其中,discover_descr_from_pyobject 使用 discover_descriptor_from_pylong 函数,
 * default_descr 使用 int_default_descriptor 函数,
 * common_dtype 使用 int_common_dtype 函数。
 */
NPY_DType_Slots pylongdtype_slots = {
    .discover_descr_from_pyobject = discover_descriptor_from_pylong,
    .default_descr = int_default_descriptor,
    .common_dtype = int_common_dtype,
};

NPY_NO_EXPORT PyArray_DTypeMeta PyArray_PyLongDType = {{{
        PyVarObject_HEAD_INIT(&PyArrayDTypeMeta_Type, 0)
        .tp_name = "numpy.dtypes._PyLongDType",
        .tp_base = NULL,  /* set in initialize_and_map_pytypes_to_dtypes */
        .tp_basicsize = sizeof(PyArray_Descr),
        .tp_flags = Py_TPFLAGS_DEFAULT,
    },},
    .type_num = -1,
    .dt_slots = &pylongdtype_slots,
    .scalar_type = NULL,  /* set in initialize_and_map_pytypes_to_dtypes */
};

/*
 * 定义所有常规数据类型可以继承的抽象浮点数数据类型 PyArray_FloatAbstractDType。
 */
NPY_NO_EXPORT PyArray_DTypeMeta PyArray_FloatAbstractDType = {{{
        PyVarObject_HEAD_INIT(&PyArrayDTypeMeta_Type, 0)
        .tp_name = "numpy.dtypes._FloatAbstractDType",
        .tp_base = &PyArrayDescr_Type,
        .tp_basicsize = sizeof(PyArray_Descr),
       .tp_flags = Py_TPFLAGS_DEFAULT,
    },},
    .type_num = -1,
    .flags = NPY_DT_ABSTRACT,
};

/*
 * 定义与 PyFloat 对象对应的数据类型结构 PyArray_PyFloatDType。
 * 其中,discover_descr_from_pyobject 使用 discover_descriptor_from_pyfloat 函数。
 */
NPY_DType_Slots pyfloatdtype_slots = {
    .discover_descr_from_pyobject = discover_descriptor_from_pyfloat,
    .default_descr = float_default_descriptor,
    # 设置默认描述器为浮点数的默认描述器
    .common_dtype = float_common_dtype,
    # 设置常见数据类型为浮点数的常见数据类型
# 定义 PyArray_PyFloatDType 类型的全局变量,表示 numpy 中的浮点数数据类型
NPY_NO_EXPORT PyArray_DTypeMeta PyArray_PyFloatDType = {{
        PyVarObject_HEAD_INIT(&PyArrayDTypeMeta_Type, 0)
        .tp_name = "numpy.dtypes._PyFloatDType",
        .tp_base = NULL,  /* 在 initialize_and_map_pytypes_to_dtypes 中设置 */
        .tp_basicsize = sizeof(PyArray_Descr),
       .tp_flags = Py_TPFLAGS_DEFAULT,
    },},
    .type_num = -1,  # 数据类型编号设为 -1
    .dt_slots = &pyfloatdtype_slots,  # 使用 pyfloatdtype_slots 描述符槽
    .scalar_type = NULL,  /* 在 initialize_and_map_pytypes_to_dtypes 中设置 */
};

# 定义 PyArray_ComplexAbstractDType 类型的全局变量,表示 numpy 中的复数抽象数据类型
NPY_NO_EXPORT PyArray_DTypeMeta PyArray_ComplexAbstractDType = {{
        PyVarObject_HEAD_INIT(&PyArrayDTypeMeta_Type, 0)
        .tp_name = "numpy.dtypes._ComplexAbstractDType",
        .tp_base = &PyArrayDescr_Type,  # 基类设为 PyArrayDescr_Type
        .tp_basicsize = sizeof(PyArray_Descr),
         .tp_flags = Py_TPFLAGS_DEFAULT,
    },},
    .type_num = -1,  # 数据类型编号设为 -1
    .flags = NPY_DT_ABSTRACT,  # 设置抽象标志
};

# 定义 pycomplexdtype_slots 结构体,包含复数类型的描述符槽函数
NPY_DType_Slots pycomplexdtype_slots = {
    .discover_descr_from_pyobject = discover_descriptor_from_pycomplex,
    .default_descr = complex_default_descriptor,
    .common_dtype = complex_common_dtype,
};

# 定义 PyArray_PyComplexDType 类型的全局变量,表示 numpy 中的复数数据类型
NPY_NO_EXPORT PyArray_DTypeMeta PyArray_PyComplexDType = {{
        PyVarObject_HEAD_INIT(&PyArrayDTypeMeta_Type, 0)
        .tp_name = "numpy.dtypes._PyComplexDType",
        .tp_base = NULL,  /* 在 initialize_and_map_pytypes_to_dtypes 中设置 */
        .tp_basicsize = sizeof(PyArray_Descr),
         .tp_flags = Py_TPFLAGS_DEFAULT,
    },},
    .type_num = -1,  # 数据类型编号设为 -1
    .dt_slots = &pycomplexdtype_slots,  # 使用 pycomplexdtype_slots 描述符槽
    .scalar_type = NULL,  /* 在 initialize_and_map_pytypes_to_dtypes 中设置 */
};