NumPy-源码解析-五十四-

176 阅读1小时+

NumPy 源码解析(五十四)

.\numpy\numpy\_core\src\common\npy_ctypes.h

/*
 * 检查一个 Python 类型是否是 ctypes 类型。
 *
 * 类似于 Py<type>_Check 函数,如果参数看起来像一个 ctypes 对象,则返回 true。
 *
 * 这个整个函数只是围绕同名的 Python 函数的一个包装器。
 */
static inline int
npy_ctypes_check(PyTypeObject *obj)
{
    PyObject *ret_obj;  // 用于存储函数调用的返回对象
    int ret;  // 存储最终的返回结果

    // 导入并缓存 numpy._core._internal 模块中的 npy_ctypes_check 函数
    npy_cache_import("numpy._core._internal", "npy_ctypes_check",
                     &npy_thread_unsafe_state.npy_ctypes_check);
    if (npy_thread_unsafe_state.npy_ctypes_check == NULL) {
        goto fail;  // 如果导入失败,则跳转到错误处理
    }

    // 调用 npy_ctypes_check 函数来检查是否是 ctypes 类型
    ret_obj = PyObject_CallFunctionObjArgs(npy_thread_unsafe_state.npy_ctypes_check,
                                           (PyObject *)obj, NULL);
    if (ret_obj == NULL) {
        goto fail;  // 如果调用失败,则跳转到错误处理
    }

    // 将返回对象转换为布尔值并赋给 ret
    ret = PyObject_IsTrue(ret_obj);
    Py_DECREF(ret_obj);  // 减少返回对象的引用计数
    if (ret == -1) {
        goto fail;  // 如果转换失败,则跳转到错误处理
    }

    return ret;  // 返回最终的检查结果

fail:
    /* 如果上述步骤失败,则假设该类型不是 ctypes 类型 */
    PyErr_Clear();  // 清除错误信息
    return 0;  // 返回 false
}

.\numpy\numpy\_core\src\common\npy_dlpack.h

// 引入 Python.h 头文件,用于与 Python 解释器交互
#include "Python.h"
// 引入 dlpack.h 头文件,这是 DLPack 库的头文件
#include "dlpack/dlpack.h"

#ifndef NPY_DLPACK_H
#define NPY_DLPACK_H

// Array API 规范的一部分,定义 DLPack Capsule 的名称
#define NPY_DLPACK_CAPSULE_NAME "dltensor"
#define NPY_DLPACK_VERSIONED_CAPSULE_NAME "dltensor_versioned"
#define NPY_DLPACK_USED_CAPSULE_NAME "used_dltensor"
#define NPY_DLPACK_VERSIONED_USED_CAPSULE_NAME "used_dltensor_versioned"

// NumPy 内部使用的 Capsule 名称,用于存储基本对象
// 因为需要释放对原始 Capsule 的引用
#define NPY_DLPACK_INTERNAL_CAPSULE_NAME "numpy_dltensor"
#define NPY_DLPACK_VERSIONED_INTERNAL_CAPSULE_NAME "numpy_dltensor_versioned"

// Array API 规范,导出函数,从 PyArrayObject 创建 DLPack 对象
NPY_NO_EXPORT PyObject *
array_dlpack(PyArrayObject *self, PyObject *const *args, Py_ssize_t len_args,
             PyObject *kwnames);

// Array API 规范,导出函数,返回与 PyArrayObject 相关的设备信息
NPY_NO_EXPORT PyObject *
array_dlpack_device(PyArrayObject *self, PyObject *NPY_UNUSED(args));

// 从 DLPack 对象创建 Python 对象,这是 Array API 规范的一部分
NPY_NO_EXPORT PyObject *
from_dlpack(PyObject *NPY_UNUSED(self),
        PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames);

#endif

.\numpy\numpy\_core\src\common\npy_extint128.h

/* 
   定义一个条件编译保护,防止多次包含本头文件
*/
#ifndef NUMPY_CORE_SRC_COMMON_NPY_EXTINT128_H_
#define NUMPY_CORE_SRC_COMMON_NPY_EXTINT128_H_

/* 
   定义一个结构体 npy_extint128_t,用于表示一个128位扩展整数,
   包括符号位和两个64位的无符号整数部分
*/
typedef struct {
    signed char sign;   // 符号位,1表示正数,-1表示负数
    npy_uint64 lo, hi;  // 低位和高位的64位无符号整数部分
} npy_extint128_t;

/* 
   定义一个静态内联函数,实现安全的64位整数加法,同时检查是否溢出
*/
static inline npy_int64
safe_add(npy_int64 a, npy_int64 b, char *overflow_flag)
{
    if (a > 0 && b > NPY_MAX_INT64 - a) {
        *overflow_flag = 1;  // 若加法溢出,则设置溢出标志
    }
    else if (a < 0 && b < NPY_MIN_INT64 - a) {
        *overflow_flag = 1;  // 若加法溢出,则设置溢出标志
    }
    return a + b;  // 返回加法结果
}

/* 
   定义一个静态内联函数,实现安全的64位整数减法,同时检查是否溢出
*/
static inline npy_int64
safe_sub(npy_int64 a, npy_int64 b, char *overflow_flag)
{
    if (a >= 0 && b < a - NPY_MAX_INT64) {
        *overflow_flag = 1;  // 若减法溢出,则设置溢出标志
    }
    else if (a < 0 && b > a - NPY_MIN_INT64) {
        *overflow_flag = 1;  // 若减法溢出,则设置溢出标志
    }
    return a - b;  // 返回减法结果
}

/* 
   定义一个静态内联函数,实现安全的64位整数乘法,同时检查是否溢出
*/
static inline npy_int64
safe_mul(npy_int64 a, npy_int64 b, char *overflow_flag)
{
    if (a > 0) {
        if (b > NPY_MAX_INT64 / a || b < NPY_MIN_INT64 / a) {
            *overflow_flag = 1;  // 若乘法溢出,则设置溢出标志
        }
    }
    else if (a < 0) {
        if (b > 0 && a < NPY_MIN_INT64 / b) {
            *overflow_flag = 1;  // 若乘法溢出,则设置溢出标志
        }
        else if (b < 0 && a < NPY_MAX_INT64 / b) {
            *overflow_flag = 1;  // 若乘法溢出,则设置溢出标志
        }
    }
    return a * b;  // 返回乘法结果
}

/* 
   定义一个静态内联函数,将64位有符号整数转换为128位扩展整数
*/
static inline npy_extint128_t
to_128(npy_int64 x)
{
    npy_extint128_t result;
    result.sign = (x >= 0 ? 1 : -1);  // 确定符号位
    if (x >= 0) {
        result.lo = x;  // 若为正数,直接赋值给低位部分
    }
    else {
        result.lo = (npy_uint64)(-(x + 1)) + 1;  // 若为负数,转换为补码形式
    }
    result.hi = 0;  // 高位部分清零
    return result;  // 返回128位扩展整数结果
}

/* 
   定义一个静态内联函数,将128位扩展整数转换为64位有符号整数
*/
static inline npy_int64
to_64(npy_extint128_t x, char *overflow)
{
    if (x.hi != 0 ||
        (x.sign > 0 && x.lo > NPY_MAX_INT64) ||
        (x.sign < 0 && x.lo != 0 && x.lo - 1 > -(NPY_MIN_INT64 + 1))) {
        *overflow = 1;  // 若转换溢出,则设置溢出标志
    }
    return x.lo * x.sign;  // 返回64位整数结果
}

/* 
   定义一个静态内联函数,实现两个64位整数的乘法,返回128位扩展整数结果
*/
static inline npy_extint128_t
mul_64_64(npy_int64 a, npy_int64 b)
{
    npy_extint128_t x, y, z;
    npy_uint64 x1, x2, y1, y2, r1, r2, prev;

    x = to_128(a);  // 将64位整数a转换为128位扩展整数
    y = to_128(b);  // 将64位整数b转换为128位扩展整数

    x1 = x.lo & 0xffffffff;  // 获取x的低32位
    x2 = x.lo >> 32;         // 获取x的高32位

    y1 = y.lo & 0xffffffff;  // 获取y的低32位
    y2 = y.lo >> 32;         // 获取y的高32位

    r1 = x1 * y2;            // 计算低32位乘积
    r2 = x2 * y1;            // 计算高32位乘积

    z.sign = x.sign * y.sign;  // 计算结果的符号位
    z.hi = x2 * y2 + (r1 >> 32) + (r2 >> 32);  // 计算结果的高64位
    z.lo = x1 * y1;           // 计算结果的低64位

    /* 进行加法运算,处理可能的进位 */
    prev = z.lo;
    z.lo += (r1 << 32);
    if (z.lo < prev) {
        ++z.hi;  // 若低位相加溢出,则高位加1
    }

    prev = z.lo;
    z.lo += (r2 << 32);
    if (z.lo < prev) {
        ++z.hi;  // 若低位相加溢出,则高位加1
    }

    return z;  // 返回128位扩展整数结果
}

/* 
   定义一个静态内联函数,实现两个128位扩展整数的加法,返回128位扩展整数结果
*/
static inline npy_extint128_t
add_128(npy_extint128_t x, npy_extint128_t y, char *overflow)
{
    npy_extint128_t z;

    if (x.sign == y.sign) {
        z.sign = x.sign;  // 若符号相同,则结果符号不变
        z.hi = x.hi + y.hi;  // 直接相加高位部分
        if (z.hi < x.hi) {
            *overflow = 1;  // 若高位相加溢出,则设置溢出标志
        }
        z.lo = x.lo + y.lo;  // 直接相加低位部分
        if (z.lo < x.lo) {
            if (z.hi == NPY_MAX_UINT64) {
                *overflow = 1;  // 若低位相加溢出,并且高位已经最大,则设置溢出标志
            }
            ++z.hi;  // 若低位相加溢出,则高位加1
        }
    }
    # 如果 x 的高位大于 y 的高位,或者当高位相等时 x 的低位大于等于 y 的低位,则执行以下代码块
    else if (x.hi > y.hi || (x.hi == y.hi && x.lo >= y.lo)) {
        # 结果 z 继承 x 的符号位
        z.sign = x.sign;
        # 计算 z 的高位,为 x 的高位减去 y 的高位
        z.hi = x.hi - y.hi;
        # 计算 z 的低位,为 x 的低位
        z.lo = x.lo;
        # 从 z 的低位中减去 y 的低位
        z.lo -= y.lo;
        # 如果 z 的低位结果大于 x 的低位,需要借位
        if (z.lo > x.lo) {
            # 减少 z 的高位
            --z.hi;
        }
    }
    # 如果上述条件不成立,则执行以下代码块
    else {
        # 结果 z 继承 y 的符号位
        z.sign = y.sign;
        # 计算 z 的高位,为 y 的高位减去 x 的高位
        z.hi = y.hi - x.hi;
        # 计算 z 的低位,为 y 的低位
        z.lo = y.lo;
        # 从 z 的低位中减去 x 的低位
        z.lo -= x.lo;
        # 如果 z 的低位结果大于 y 的低位,需要借位
        if (z.lo > y.lo) {
            # 减少 z 的高位
            --z.hi;
        }
    }

    # 返回计算结果 z
    return z;
/* 长整数取负操作 */
static inline npy_extint128_t
neg_128(npy_extint128_t x)
{
    // 复制输入的参数x到新变量z
    npy_extint128_t z = x;
    // 改变z的符号位
    z.sign *= -1;
    // 返回符号改变后的z
    return z;
}


/* 长整数减法操作 */
static inline npy_extint128_t
sub_128(npy_extint128_t x, npy_extint128_t y, char *overflow)
{
    // 调用add_128函数实现x - y操作,并返回结果
    return add_128(x, neg_128(y), overflow);
}


/* 长整数左移操作 */
static inline npy_extint128_t
shl_128(npy_extint128_t v)
{
    // 将输入的参数v赋值给新变量z
    npy_extint128_t z;
    z = v;
    // 高64位左移1位
    z.hi <<= 1;
    // 将低64位最高位移到高64位的最低位
    z.hi |= (z.lo & (((npy_uint64)1) << 63)) >> 63;
    // 低64位左移1位
    z.lo <<= 1;
    // 返回左移后的结果z
    return z;
}


/* 长整数右移操作 */
static inline npy_extint128_t
shr_128(npy_extint128_t v)
{
    // 将输入的参数v赋值给新变量z
    npy_extint128_t z;
    z = v;
    // 低64位右移1位
    z.lo >>= 1;
    // 将高64位的最低位移到低64位的最高位
    z.lo |= (z.hi & 0x1) << 63;
    // 高64位右移1位
    z.hi >>= 1;
    // 返回右移后的结果z
    return z;
}

/* 长整数比较操作,返回大于的判断结果 */
static inline int
gt_128(npy_extint128_t a, npy_extint128_t b)
{
    // 如果a和b的符号都为正数
    if (a.sign > 0 && b.sign > 0) {
        // 比较a和b的高64位和低64return (a.hi > b.hi) || (a.hi == b.hi && a.lo > b.lo);
    }
    // 如果a和b的符号都为负数
    else if (a.sign < 0 && b.sign < 0) {
        // 比较a和b的高64位和低64return (a.hi < b.hi) || (a.hi == b.hi && a.lo < b.lo);
    }
    // 如果a为正数,b为负数
    else if (a.sign > 0 && b.sign < 0) {
        // 判断a和b是否不同时为零
        return a.hi != 0 || a.lo != 0 || b.hi != 0 || b.lo != 0;
    }
    // 其他情况返回0
    else {
        return 0;
    }
}


/* 长整数除法操作 */
static inline npy_extint128_t
divmod_128_64(npy_extint128_t x, npy_int64 b, npy_int64 *mod)
{
    // 声明变量remainder, pointer, result, divisor,并初始化overflow为0
    npy_extint128_t remainder, pointer, result, divisor;
    char overflow = 0;

    // 断言b大于0
    assert(b > 0);

    // 如果b小于等于1或者x的高64位为0
    if (b <= 1 || x.hi == 0) {
        // 设置result的符号和低高64位
        result.sign = x.sign;
        result.lo = x.lo / b;
        result.hi = x.hi / b;
        // 计算余数并赋值给mod
        *mod = x.sign * (x.lo % b);
        // 返回计算结果result
        return result;
    }

    // 长除法计算,不是最有效率的选择
    // 将x赋值给remainder,并将其符号置为正数
    remainder = x;
    remainder.sign = 1;

    // 设置divisor为正数,低64位为b,高64位为0
    divisor.sign = 1;
    divisor.hi = 0;
    divisor.lo = b;

    // 设置result为正数,低高64位为0
    result.sign = 1;
    result.lo = 0;
    result.hi = 0;

    // 设置pointer为正数,低64位为1,高64位为0
    pointer.sign = 1;
    pointer.lo = 1;
    pointer.hi = 0;

    // 当divisor的高64位的最低位为0且remainder大于divisor时
    while ((divisor.hi & (((npy_uint64)1) << 63)) == 0 &&
           gt_128(remainder, divisor)) {
        // divisor和pointer分别左移一位
        divisor = shl_128(divisor);
        pointer = shl_128(pointer);
    }

    // 当pointer的低64位或高64位不为0while (pointer.lo || pointer.hi) {
        // 如果remainder不小于divisor
        if (!gt_128(divisor, remainder)) {
            // remainder减去divisor,并将结果加到result中
            remainder = sub_128(remainder, divisor, &overflow);
            result = add_128(result, pointer, &overflow);
        }
        // divisor右移一位,pointer右移一位
        divisor = shr_128(divisor);
        pointer = shr_128(pointer);
    }

    // 修正结果的符号并返回,不会溢出
    result.sign = x.sign;
    // 将remainder的低64位乘以x的符号并赋值给mod
    *mod = x.sign * remainder.lo;

    // 返回计算结果result
    return result;
}


/* 除法并向下取整(正数除数;不会溢出) */
static inline npy_extint128_t
floordiv_128_64(npy_extint128_t a, npy_int64 b)
{
    // 声明变量result, remainder,并初始化overflow为0
    npy_extint128_t result;
    npy_int64 remainder;
    char overflow = 0;
    // 断言b大于0
    assert(b > 0);
    // 调用divmod_128_64函数计算a除以b的商和余数,结果赋值给result
    result = divmod_128_64(a, b, &remainder);
    // 如果a为负数且余数不为0,将result减去1
    if (a.sign < 0 && remainder != 0) {
        result = sub_128(result, to_128(1), &overflow);
    }
    // 返回计算结果result
    return result;
}


/* 除法并向上取整(正数除数;不会溢出) */
static inline npy_extint128_t
ceildiv_128_64(npy_extint128_t a, npy_int64 b)
{
    // 声明变量result, remainder,并初始化overflow为0
    npy_extint128_t result;
    npy_int64 remainder;
    // 断言b大于0
    assert(b > 0);
    // 调用divmod_128_64函数计算a除以b的商和余数,结果赋值给result
    result = divmod_128_64(a, b, &remainder);
    // 如果余数不为0,将result加上1
    if (remainder != 0) {
        result = add_128(result, to_128(1), NULL);
    }
    // 返回计算结果result
    return result;
}
    # 声明一个字符型变量 overflow,并初始化为 0
    char overflow = 0;
    # 断言 b 大于 0,确保除数 b 是一个正数
    assert(b > 0);
    # 调用函数 divmod_128_64 对 a 和 b 进行128位和64位的除法运算,并将余数存入 remainder 指向的地址中,返回商 result
    result = divmod_128_64(a, b, &remainder);
    # 如果 a 的符号为正,并且余数 remainder 不等于 0,则执行下面的条件
    if (a.sign > 0 && remainder != 0) {
        # 调用函数 add_128 对 result 和一个表示整数1的128位数相加,将溢出标志存入 overflow 指向的地址中,并更新 result
        result = add_128(result, to_128(1), &overflow);
    }
    # 返回最终的 result 结果
    return result;
}
#endif  /* NUMPY_CORE_SRC_COMMON_NPY_EXTINT128_H_ */


// 结束if指令的条件编译块,关闭条件编译的头文件保护宏
}
#endif  /* NUMPY_CORE_SRC_COMMON_NPY_EXTINT128_H_ */

.\numpy\numpy\_core\src\common\npy_fpmath.h

#ifndef NUMPY_CORE_SRC_COMMON_NPY_NPY_FPMATH_H_
#define NUMPY_CORE_SRC_COMMON_NPY_NPY_FPMATH_H_

#include "npy_config.h"

#include "numpy/npy_os.h"
#include "numpy/npy_cpu.h"
#include "numpy/npy_common.h"

// 检查是否定义了某种 long double 的表示形式,如果没有则抛出错误
#if !(defined(HAVE_LDOUBLE_IEEE_QUAD_BE) || \
      defined(HAVE_LDOUBLE_IEEE_QUAD_LE) || \
      defined(HAVE_LDOUBLE_IEEE_DOUBLE_LE) || \
      defined(HAVE_LDOUBLE_IEEE_DOUBLE_BE) || \
      defined(HAVE_LDOUBLE_INTEL_EXTENDED_16_BYTES_LE) || \
      defined(HAVE_LDOUBLE_INTEL_EXTENDED_12_BYTES_LE) || \
      defined(HAVE_LDOUBLE_MOTOROLA_EXTENDED_12_BYTES_BE) || \
      defined(HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_BE) || \
      defined(HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_LE))
    #error No long double representation defined
#endif

// 为了向后兼容,保留双倍精度浮点数的旧名称
#ifdef HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_LE
    #define HAVE_LDOUBLE_DOUBLE_DOUBLE_LE
#endif
#ifdef HAVE_LDOUBLE_IBM_DOUBLE_DOUBLE_BE
    #define HAVE_LDOUBLE_DOUBLE_DOUBLE_BE
#endif

#endif  /* NUMPY_CORE_SRC_COMMON_NPY_NPY_FPMATH_H_ */

.\numpy\numpy\_core\src\common\npy_hashtable.c

/*
 * This functionality is designed specifically for the ufunc machinery to
 * dispatch based on multiple DTypes. Since this is designed to be used
 * as purely a cache, it currently does no reference counting.
 * Even though this is a cache, there is currently no maximum size. It may
 * make sense to limit the size, or count collisions: If too many collisions
 * occur, we could grow the cache, otherwise, just replace an old item that
 * was presumably not used for a long time.
 *
 * If a different part of NumPy requires a custom hashtable, the code should
 * be reused with care since specializing it more for the ufunc dispatching
 * case is likely desired.
 */

#include "templ_common.h"
#include "npy_hashtable.h"

#if SIZEOF_PY_UHASH_T > 4
#define _NpyHASH_XXPRIME_1 ((Py_uhash_t)11400714785074694791ULL)
#define _NpyHASH_XXPRIME_2 ((Py_uhash_t)14029467366897019727ULL)
#define _NpyHASH_XXPRIME_5 ((Py_uhash_t)2870177450012600261ULL)
#define _NpyHASH_XXROTATE(x) ((x << 31) | (x >> 33))  /* Rotate left 31 bits */
#else
#define _NpyHASH_XXPRIME_1 ((Py_uhash_t)2654435761UL)
#define _NpyHASH_XXPRIME_2 ((Py_uhash_t)2246822519UL)
#define _NpyHASH_XXPRIME_5 ((Py_uhash_t)374761393UL)
#define _NpyHASH_XXROTATE(x) ((x << 13) | (x >> 19))  /* Rotate left 13 bits */
#endif

#ifdef Py_GIL_DISABLED
// TODO: replace with PyMutex when it is public
#define LOCK_TABLE(tb)                                      \
    if (!PyThread_acquire_lock(tb->mutex, NOWAIT_LOCK)) {    \
        PyThread_acquire_lock(tb->mutex, WAIT_LOCK);         \
    }
#define UNLOCK_TABLE(tb) PyThread_release_lock(tb->mutex);
#define INITIALIZE_LOCK(tb)                     \
    tb->mutex = PyThread_allocate_lock();       \
    if (tb->mutex == NULL) {                    \
        PyErr_NoMemory();                       \
        PyMem_Free(res);                        \
        return NULL;                            \
    }
#define FREE_LOCK(tb)                           \
    if (tb->mutex != NULL) {                    \
        PyThread_free_lock(tb->mutex);          \
    }
#else
// the GIL serializes access to the table so no need
// for locking if it is enabled
#define LOCK_TABLE(tb)
#define UNLOCK_TABLE(tb)
#define INITIALIZE_LOCK(tb)
#define FREE_LOCK(tb)
#endif

/*
 * This hashing function is basically the Python tuple hash with the type
 * identity hash inlined. The tuple hash itself is a reduced version of xxHash.
 *
 * Users cannot control pointers, so we do not have to worry about DoS attacks?
 */
static inline Py_hash_t
identity_list_hash(PyObject *const *v, int len)
{
    Py_uhash_t acc = _NpyHASH_XXPRIME_5;
    for (int i = 0; i < len; i++) {
        /*
         * Lane is the single item hash, which for us is the rotated pointer.
         * Identical to the python type hash (pointers end with 0s normally).
         */
        // 从数组 v 中取出第 i 个元素,并转换为 size_t 类型
        size_t y = (size_t)v[i];
        // 根据 y 的值进行位操作,生成一个 Py_uhash_t 类型的 lane
        Py_uhash_t lane = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4));
        // 将 lane 乘以 _NpyHASH_XXPRIME_2 并加到 acc 上
        acc += lane * _NpyHASH_XXPRIME_2;
        // 使用 _NpyHASH_XXROTATE 函数对 acc 进行旋转操作
        acc = _NpyHASH_XXROTATE(acc);
        // 将 acc 乘以 _NpyHASH_XXPRIME_1
        acc *= _NpyHASH_XXPRIME_1;
    }
    // 返回最终的累加结果作为哈希值
    return acc;
}
#undef _NpyHASH_XXPRIME_1
#undef _NpyHASH_XXPRIME_2
#undef _NpyHASH_XXPRIME_5
#undef _NpyHASH_XXROTATE

/*
 * The following functions are internal utility functions for handling
 * hash table operations and memory management.
 */

static inline PyObject **
find_item(PyArrayIdentityHash const *tb, PyObject *const *key)
{
    // 计算给定键的哈希值
    Py_hash_t hash = identity_list_hash(key, tb->key_len);
    npy_uintp perturb = (npy_uintp)hash;
    npy_intp bucket;
    npy_intp mask = tb->size - 1 ;
    PyObject **item;

    // 计算哈希桶的索引位置
    bucket = (npy_intp)hash & mask;
    while (1) {
        // 获取当前桶的位置
        item = &(tb->buckets[bucket * (tb->key_len + 1)]);

        // 如果当前桶为空,则返回这个空桶
        if (item[0] == NULL) {
            /* The item is not in the cache; return the empty bucket */
            return item;
        }
        // 如果当前桶中的键与给定键相等,则返回这个桶
        if (memcmp(item+1, key, tb->key_len * sizeof(PyObject *)) == 0) {
            /* This is a match, so return the item/bucket */
            return item;
        }
        // 处理哈希冲突,按照 Python 的方式进行 perturb 操作
        perturb >>= 5;  /* Python uses the macro PERTURB_SHIFT == 5 */
        bucket = mask & (bucket * 5 + perturb + 1);
    }
}

/*
 * Allocate and initialize a new PyArrayIdentityHash object with a given key length.
 */
NPY_NO_EXPORT PyArrayIdentityHash *
PyArrayIdentityHash_New(int key_len)
{
    PyArrayIdentityHash *res = PyMem_Malloc(sizeof(PyArrayIdentityHash));
    if (res == NULL) {
        PyErr_NoMemory();
        return NULL;
    }

    assert(key_len > 0);
    res->key_len = key_len;
    res->size = 4;  /* Start with a size of 4 */
    res->nelem = 0;

    // 初始化锁(假设这里有一个初始化锁的宏或函数)
    INITIALIZE_LOCK(res);

    // 分配并初始化桶数组
    res->buckets = PyMem_Calloc(4 * (key_len + 1), sizeof(PyObject *));
    if (res->buckets == NULL) {
        PyErr_NoMemory();
        PyMem_Free(res);
        return NULL;
    }
    return res;
}

/*
 * Deallocate memory associated with a PyArrayIdentityHash object.
 */
NPY_NO_EXPORT void
PyArrayIdentityHash_Dealloc(PyArrayIdentityHash *tb)
{
    // 释放桶数组的内存
    PyMem_Free(tb->buckets);
    // 释放锁资源
    FREE_LOCK(tb);
    // 释放 PyArrayIdentityHash 结构体的内存
    PyMem_Free(tb);
}

/*
 * Resize the hash table if necessary based on its current usage.
 */
static int
_resize_if_necessary(PyArrayIdentityHash *tb)
{
    npy_intp new_size, prev_size = tb->size;
    PyObject **old_table = tb->buckets;
    assert(prev_size > 0);

    // 如果当前桶的使用超过了其容量的一半,则扩大容量为原来的两倍
    if ((tb->nelem + 1) * 2 > prev_size) {
        /* Double in size */
        new_size = prev_size * 2;
    }
    else {
        // 否则根据一定策略缩小容量,以避免频繁的扩展和收缩
        new_size = prev_size;
        while ((tb->nelem + 8) * 2 < new_size / 2) {
            /*
             * Should possibly be improved.  However, we assume that we
             * almost never shrink.  Still if we do, do not shrink as much
             * as possible to avoid growing right away.
             */
            new_size /= 2;
        }
        assert(new_size >= 4);
    }
    // 如果新的大小与之前的大小相同,则无需调整
    if (new_size == prev_size) {
        return 0;
    }

    npy_intp alloc_size;
    // 计算需要分配的新桶数组的大小
    if (npy_mul_sizes_with_overflow(&alloc_size, new_size, tb->key_len + 1)) {
        return -1;
    }
    // 分配新的桶数组内存空间
    tb->buckets = PyMem_Calloc(alloc_size, sizeof(PyObject *));
    if (tb->buckets == NULL) {
        // 如果分配失败,回滚操作,并报内存错误
        tb->buckets = old_table;
        PyErr_NoMemory();
        return -1;
    }

    // 更新哈希表的大小
    tb->size = new_size;


注释:
    // 遍历旧哈希表中的每一个槽位
    for (npy_intp i = 0; i < prev_size; i++) {
        // 获取当前槽位的指针,每个槽位存储了键值对的数组
        PyObject **item = &old_table[i * (tb->key_len + 1)];
        // 如果当前槽位不为空(即有键值对存在)
        if (item[0] != NULL) {
            // 在新哈希表中查找当前键的位置
            PyObject **tb_item = find_item(tb, item + 1);
            // 将旧哈希表中的键值对复制到新哈希表中对应位置
            tb_item[0] = item[0];  // 复制键
            memcpy(tb_item + 1, item + 1, tb->key_len * sizeof(PyObject *));  // 复制值
        }
    }
    // 释放旧哈希表的内存空间
    PyMem_Free(old_table);
    // 返回操作成功的标志
    return 0;
/**
 * Add an item to the identity cache. The storage location must not change
 * unless the cache is cleared.
 *
 * @param tb The mapping.
 * @param key The key, must be a C-array of pointers of the length
 *            corresponding to the mapping.
 * @param value Normally a Python object, no reference counting is done.
 *              Use NULL to clear an item. If the item does not exist, no
 *              action is performed for NULL.
 * @param replace If 1, allow replacements. If replace is 0 an error is raised
 *                if the stored value is different from the value to be cached.
 *                If the value to be cached is identical to the stored value,
 *                the value to be cached is ignored and no error is raised.
 * @returns 0 on success, -1 with a MemoryError or RuntimeError (if an item
 *          is added which is already in the cache and replace is 0). The
 *          caller should avoid the RuntimeError.
 */
NPY_NO_EXPORT int
PyArrayIdentityHash_SetItem(PyArrayIdentityHash *tb,
                            PyObject *const *key, PyObject *value, int replace)
{
    // 对表格进行加锁,确保线程安全
    LOCK_TABLE(tb);
    
    // 如果传入的 value 不为空,并且如果需要的话,进行必要时的表格调整(缩小)
    if (value != NULL && _resize_if_necessary(tb) < 0) {
        /* Shrink, only if a new value is added. */
        // 如果添加新值时需要收缩,则解锁表格并返回错误
        UNLOCK_TABLE(tb);
        return -1;
    }

    // 在表格中查找指定 key 对应的项目
    PyObject **tb_item = find_item(tb, key);

    // 如果 value 不为空
    if (value != NULL) {
        // 如果表格中已经存在相同 key 的项,并且不允许替换,则解锁表格并返回运行时错误
        if (tb_item[0] != NULL && tb_item[0] != value && !replace) {
            UNLOCK_TABLE(tb);
            PyErr_SetString(PyExc_RuntimeError,
                            "Identity cache already includes an item with this key.");
            return -1;
        }
        // 将 value 存储到表格中对应的位置
        tb_item[0] = value;
        // 将 key 复制到表格的后续位置
        memcpy(tb_item+1, key, tb->key_len * sizeof(PyObject *));
        // 增加表格中元素的数量计数
        tb->nelem += 1;
    }
    else {
        /* Clear the bucket -- just the value should be enough though. */
        // 清空存储桶,通常只清空值即可
        memset(tb_item, 0, (tb->key_len + 1) * sizeof(PyObject *));
    }

    // 解锁表格
    UNLOCK_TABLE(tb);
    return 0;
}

/**
 * Retrieve an item from the identity cache.
 *
 * @param tb The mapping.
 * @param key The key to look up, must be a C-array of pointers of the length
 *            corresponding to the mapping.
 * @returns The stored value associated with the key, or NULL if not found.
 */
NPY_NO_EXPORT PyObject *
PyArrayIdentityHash_GetItem(PyArrayIdentityHash const *tb, PyObject *const *key)
{
    // 对表格进行加锁,确保线程安全
    LOCK_TABLE(tb);
    // 查找并返回与指定 key 对应的存储值
    PyObject *res = find_item(tb, key)[0];
    // 解锁表格
    UNLOCK_TABLE(tb);
    return res;
}

.\numpy\numpy\_core\src\common\npy_hashtable.h

#ifndef NUMPY_CORE_SRC_COMMON_NPY_NPY_HASHTABLE_H_
#define NUMPY_CORE_SRC_COMMON_NPY_NPY_HASHTABLE_H_

#include <Python.h>

// 定义宏,指定使用当前版本的 NumPy API,禁止使用过时的 API
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
// 包含 NumPy 的 ndarraytypes.h 文件
#include "numpy/ndarraytypes.h"

// 定义一个结构体 PyArrayIdentityHash,用于实现身份哈希表
typedef struct {
    int key_len;  /* number of identities used */  // 关键字的长度,即使用的标识数目
    /* Buckets stores: val1, key1[0], key1[1], ..., val2, key2[0], ... */
    PyObject **buckets;  // 存储桶,按顺序存储值和对应的键
    npy_intp size;  /* current size */  // 当前大小
    npy_intp nelem;  /* number of elements */  // 元素的数量
#ifdef Py_GIL_DISABLED
    PyThread_type_lock *mutex;  // 线程锁,如果 GIL 被禁用
#endif
} PyArrayIdentityHash;  // PyArrayIdentityHash 结构体声明结束

// 以下为函数声明

// 向身份哈希表中设置元素,如果已存在则替换
NPY_NO_EXPORT int
PyArrayIdentityHash_SetItem(PyArrayIdentityHash *tb,
        PyObject *const *key, PyObject *value, int replace);

// 从身份哈希表中获取元素
NPY_NO_EXPORT PyObject *
PyArrayIdentityHash_GetItem(PyArrayIdentityHash const *tb, PyObject *const *key);

// 创建并返回一个新的身份哈希表
NPY_NO_EXPORT PyArrayIdentityHash *
PyArrayIdentityHash_New(int key_len);

// 释放身份哈希表及其资源
NPY_NO_EXPORT void
PyArrayIdentityHash_Dealloc(PyArrayIdentityHash *tb);

#endif  /* NUMPY_CORE_SRC_COMMON_NPY_NPY_HASHTABLE_H_ */

.\numpy\numpy\_core\src\common\npy_import.h

#ifndef NUMPY_CORE_SRC_COMMON_NPY_IMPORT_H_
#define NUMPY_CORE_SRC_COMMON_NPY_IMPORT_H_

#include <Python.h>

/*! \brief Fetch and cache Python function.
 *
 * Import a Python function and cache it for use. The function checks if
 * cache is NULL, and if not NULL imports the Python function specified by
 * \a module and \a function, increments its reference count, and stores
 * the result in \a cache. Usually \a cache will be a static variable and
 * should be initialized to NULL. On error \a cache will contain NULL on
 * exit,
 *
 * @param module Absolute module name.
 * @param attr module attribute to cache.
 * @param cache Storage location for imported function.
 */
static inline void
npy_cache_import(const char *module, const char *attr, PyObject **cache)
{
    // 检查缓存是否为空指针
    if (NPY_UNLIKELY(*cache == NULL)) {
        // 导入 Python 模块
        PyObject *mod = PyImport_ImportModule(module);

        // 如果成功导入模块
        if (mod != NULL) {
            // 获取模块中的指定属性
            *cache = PyObject_GetAttrString(mod, attr);
            // 减少模块的引用计数
            Py_DECREF(mod);
        }
    }
}

#endif  /* NUMPY_CORE_SRC_COMMON_NPY_IMPORT_H_ */

.\numpy\numpy\_core\src\common\npy_longdouble.c

/*
 * 定义宏,指定使用的 NumPy API 版本,禁用过时的 API
 */
#define NPY_NO_DEPRECATED_API NPY_API_VERSION

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

/*
 * 清理 PY_SSIZE_T 的定义,确保使用最新的 API
 */
#define PY_SSIZE_T_CLEAN

/*
 * 包含 Python.h 头文件,提供 Python C API 的基本功能
 */
#include <Python.h>

/*
 * 包含 NumPy 的数组类型定义头文件
 */
#include "numpy/ndarraytypes.h"

/*
 * 包含 NumPy 的数学函数头文件
 */
#include "numpy/npy_math.h"

/*
 * 包含 NumPy 的操作系统相关头文件
 */
#include "numpyos.h"

/*
 * 将 longdouble 转换为 Python 的长整型对象 PyLong 的函数。
 * 这个函数是基于 PyLong_FromDouble 修改的,由于不能直接设置数字的位数,
 * 因此必须进行位移和按位或操作。
 */
NPY_VISIBILITY_HIDDEN PyObject *
npy_longdouble_to_PyLong(npy_longdouble ldval)
{
    PyObject *v;
    PyObject *l_chunk_size;
    /*
     * 每次提取的比特位数。CPython 使用 30,但这是因为它与内部长整型表示相关
     */
    const int chunk_size = NPY_BITSOF_LONGLONG;
    npy_longdouble frac;
    int i, ndig, expo, neg;
    neg = 0;

    /*
     * 如果 ldval 是无穷大,则设置 OverflowError 异常
     */
    if (npy_isinf(ldval)) {
        PyErr_SetString(PyExc_OverflowError,
                        "cannot convert longdouble infinity to integer");
        return NULL;
    }
    /*
     * 如果 ldval 是 NaN,则设置 ValueError 异常
     */
    if (npy_isnan(ldval)) {
        PyErr_SetString(PyExc_ValueError,
                        "cannot convert longdouble NaN to integer");
        return NULL;
    }
    /*
     * 如果 ldval 是负数,则设置 neg 标志并取其绝对值
     */
    if (ldval < 0.0) {
        neg = 1;
        ldval = -ldval;
    }
    /*
     * 分解 ldval 为尾数 frac 和指数 expo,ldval = frac * 2**expo; 0.0 <= frac < 1.0
     */
    frac = npy_frexpl(ldval, &expo);
    v = PyLong_FromLong(0L);
    if (v == NULL)
        return NULL;
    /*
     * 如果指数 expo 小于等于 0,则直接返回 v
     */
    if (expo <= 0)
        return v;

    /*
     * 计算所需的位数 ndig
     */
    ndig = (expo - 1) / chunk_size + 1;

    /*
     * 创建长整型对象 l_chunk_size 以表示每次位移的比特位数
     */
    l_chunk_size = PyLong_FromLong(chunk_size);
    if (l_chunk_size == NULL) {
        Py_DECREF(v);
        return NULL;
    }

    /*
     * 获取浮点数的整数部分的最高有效位
     */
    frac = npy_ldexpl(frac, (expo - 1) % chunk_size + 1);
    for (i = ndig; --i >= 0;) {
        npy_ulonglong chunk = (npy_ulonglong) frac;
        PyObject *l_chunk;
        /*
         * v = v << chunk_size,将 v 左移 chunk_size 位
         */
        Py_SETREF(v, PyNumber_Lshift(v, l_chunk_size));
        if (v == NULL) {
            goto done;
        }
        /*
         * 创建表示 chunk 的长整型对象 l_chunk
         */
        l_chunk = PyLong_FromUnsignedLongLong(chunk);
        if (l_chunk == NULL) {
            Py_DECREF(v);
            v = NULL;
            goto done;
        }
        /*
         * v = v | chunk,将 chunk 或运算到 v 上
         */
        Py_SETREF(v, PyNumber_Or(v, l_chunk));
        Py_DECREF(l_chunk);
        if (v == NULL) {
            goto done;
        }

        /*
         * 去除最高位并重复
         */
        frac = frac - (npy_longdouble) chunk;
        frac = npy_ldexpl(frac, chunk_size);
    }

    /*
     * 如果是负数,取 v 的相反数
     */
    if (neg) {
        Py_SETREF(v, PyNumber_Negative(v));
        if (v == NULL) {
            goto done;
        }
    }

done:
    /*
     * 清理临时使用的 l_chunk_size 对象
     */
    Py_DECREF(l_chunk_size);
    return v;
}

/*
 * 辅助函数,用于将 PyLong 对象转换为 UTF-8 编码的字节串
 */
static PyObject *
_PyLong_Bytes(PyObject *long_obj) {
    PyObject *bytes;
    PyObject *unicode = PyObject_Str(long_obj);
    if (unicode == NULL) {
        return NULL;
    }
    bytes = PyUnicode_AsUTF8String(unicode);
    Py_DECREF(unicode);
    return bytes;
}
/**
 * 从 Python 的 long 对象转换为 npy_longdouble 类型的数值。
 * 
 * 使用一个字符串表示的 long 值进行转换,这种方法是正确的但速度较慢。
 * 另一种方法是通过数值方式转换,类似于 PyLong_AsDouble 的方式。
 * 然而,为了正确处理舍入模式,这需要知道尾数的大小,这是依赖于平台的。
 */
NPY_VISIBILITY_HIDDEN npy_longdouble
npy_longdouble_from_PyLong(PyObject *long_obj) {
    npy_longdouble result = 1234;  // 初始化结果为 1234
    char *end;  // 字符串结束位置指针
    char *cstr;  // 字符串指针
    PyObject *bytes;  // Python 字节对象

    /* convert the long to a string */
    bytes = _PyLong_Bytes(long_obj);  // 将 Python long 对象转换为字节对象
    if (bytes == NULL) {
        return -1;  // 转换失败,返回错误码 -1
    }

    cstr = PyBytes_AsString(bytes);  // 获取字节对象的字符串表示
    if (cstr == NULL) {
        goto fail;  // 如果转换为字符串失败,则跳转到失败处理
    }
    end = NULL;  // 初始化结束位置指针为 NULL

    /* convert the string to a long double and capture errors */
    errno = 0;  // 清空错误码
    result = NumPyOS_ascii_strtold(cstr, &end);  // 将字符串转换为长双精度浮点数,并捕获错误
    if (errno == ERANGE) {
        /* strtold 返回正确符号的无穷大。 */
        if (PyErr_Warn(PyExc_RuntimeWarning,
                "overflow encountered in conversion from python long") < 0) {
            goto fail;  // 发出溢出警告失败,跳转到失败处理
        }
    }
    else if (errno) {
        PyErr_Format(PyExc_RuntimeError,
                     "Could not parse python long as longdouble: %s (%s)",
                     cstr,
                     strerror(errno));
        goto fail;  // 其他错误情况,抛出运行时错误,跳转到失败处理
    }

    /* Extra characters at the end of the string, or nothing parsed */
    if (end == cstr || *end != '\0') {
        PyErr_Format(PyExc_RuntimeError,
                     "Could not parse long as longdouble: %s",
                     cstr);
        goto fail;  // 字符串末尾有额外字符或未解析任何内容,抛出运行时错误,跳转到失败处理
    }

    /* finally safe to decref now that we're done with `end` */
    Py_DECREF(bytes);  // 安全地释放字节对象的引用计数
    return result;  // 返回转换后的长双精度浮点数

fail:
    Py_DECREF(bytes);  // 失败处理:释放字节对象的引用计数
    return -1;  // 返回错误码 -1
}

.\numpy\numpy\_core\src\common\npy_longdouble.h

#ifndef NUMPY_CORE_SRC_COMMON_NPY_LONGDOUBLE_H_
#define NUMPY_CORE_SRC_COMMON_NPY_LONGDOUBLE_H_

#include "npy_config.h"  // 包含 numpy 配置信息的头文件
#include "numpy/ndarraytypes.h"  // 包含 numpy 数组类型相关的头文件

/* Convert a npy_longdouble to a python `long` integer.
 *
 * Results are rounded towards zero.
 *
 * This performs the same task as PyLong_FromDouble, but for long doubles
 * which have a greater range.
 */
NPY_VISIBILITY_HIDDEN PyObject *
npy_longdouble_to_PyLong(npy_longdouble ldval);  // 将 npy_longdouble 类型转换为 Python 的 long 整数对象

/* Convert a python `long` integer to a npy_longdouble
 *
 * This performs the same task as PyLong_AsDouble, but for long doubles
 * which have a greater range.
 *
 * Returns -1 if an error occurs.
 */
NPY_VISIBILITY_HIDDEN npy_longdouble
npy_longdouble_from_PyLong(PyObject *long_obj);  // 将 Python 的 long 整数对象转换为 npy_longdouble 类型

#endif  /* NUMPY_CORE_SRC_COMMON_NPY_LONGDOUBLE_H_ */

.\numpy\numpy\_core\src\common\npy_partition.h

#ifndef NUMPY_CORE_SRC_COMMON_PARTITION_H_
#define NUMPY_CORE_SRC_COMMON_PARTITION_H_

#include "npy_sort.h"

/* Python include is for future object sorts */
#include <Python.h>

#include <numpy/ndarraytypes.h>
#include <numpy/npy_common.h>

// 定义最大的递归分区栈深度为50
#define NPY_MAX_PIVOT_STACK 50

// 声明一个用于对数组进行分区的函数指针类型
typedef int (PyArray_PartitionFunc)(void *, npy_intp, npy_intp,
                                    npy_intp *, npy_intp *, npy_intp,
                                    void *);

// 声明一个用于对数组进行参数分区的函数指针类型
typedef int (PyArray_ArgPartitionFunc)(void *, npy_intp *, npy_intp, npy_intp,
                                       npy_intp *, npy_intp *, npy_intp,
                                       void *);

// 如果是 C++ 环境,则采用 extern "C" 包裹代码
#ifdef __cplusplus
extern "C" {
#endif

// 根据数据类型和选择类型获取对应的分区函数指针
NPY_NO_EXPORT PyArray_PartitionFunc *
get_partition_func(int type, NPY_SELECTKIND which);

// 根据数据类型和选择类型获取对应的参数分区函数指针
NPY_NO_EXPORT PyArray_ArgPartitionFunc *
get_argpartition_func(int type, NPY_SELECTKIND which);

// 如果是 C++ 环境,结束 extern "C" 区块
#ifdef __cplusplus
}
#endif

#endif

.\numpy\numpy\_core\src\common\npy_pycompat.h

#ifndef NUMPY_CORE_SRC_COMMON_NPY_PYCOMPAT_H_
// 如果未定义宏 NUMPY_CORE_SRC_COMMON_NPY_PYCOMPAT_H_,则开始条件编译
#define NUMPY_CORE_SRC_COMMON_NPY_PYCOMPAT_H_

// 包含 numpy/npy_3kcompat.h 头文件,用于兼容 Python 3k
#include "numpy/npy_3kcompat.h"

// 包含 pythoncapi-compat/pythoncapi_compat.h 头文件,用于兼容 Python C API
#include "pythoncapi-compat/pythoncapi_compat.h"

/*
 * 在 Python 3.10a7 (或 b1) 中,当值为 NaN 时,python 开始使用其自身的哈希值。
 * 参见 https://bugs.python.org/issue43475
 */
#if PY_VERSION_HEX > 0x030a00a6
// 如果 Python 版本大于 3.10a7,则定义 Npy_HashDouble 宏为 _Py_HashDouble
#define Npy_HashDouble _Py_HashDouble
#else
// 否则,定义静态内联函数 Npy_HashDouble
static inline Py_hash_t
Npy_HashDouble(PyObject *NPY_UNUSED(identity), double val)
{
    // 返回 _Py_HashDouble 函数对 val 的哈希值
    return _Py_HashDouble(val);
}
#endif

// 结束条件编译
#endif  /* NUMPY_CORE_SRC_COMMON_NPY_PYCOMPAT_H_ */

.\numpy\numpy\_core\src\common\npy_svml.h

// 如果 NPY_SIMD 为真,并且定义了 NPY_HAVE_AVX512_SPR 和 NPY_CAN_LINK_SVML,则声明下列函数
extern void __svml_exps32(const npy_half*, npy_half*, npy_intp);
extern void __svml_exp2s32(const npy_half*, npy_half*, npy_intp);
extern void __svml_logs32(const npy_half*, npy_half*, npy_intp);
extern void __svml_log2s32(const npy_half*, npy_half*, npy_intp);
extern void __svml_log10s32(const npy_half*, npy_half*, npy_intp);
extern void __svml_expm1s32(const npy_half*, npy_half*, npy_intp);
extern void __svml_log1ps32(const npy_half*, npy_half*, npy_intp);
extern void __svml_cbrts32(const npy_half*, npy_half*, npy_intp);
extern void __svml_sins32(const npy_half*, npy_half*, npy_intp);
extern void __svml_coss32(const npy_half*, npy_half*, npy_intp);
extern void __svml_tans32(const npy_half*, npy_half*, npy_intp);
extern void __svml_asins32(const npy_half*, npy_half*, npy_intp);
extern void __svml_acoss32(const npy_half*, npy_half*, npy_intp);
extern void __svml_atans32(const npy_half*, npy_half*, npy_intp);
extern void __svml_atan2s32(const npy_half*, npy_half*, npy_intp);
extern void __svml_sinhs32(const npy_half*, npy_half*, npy_intp);
extern void __svml_coshs32(const npy_half*, npy_half*, npy_intp);
extern void __svml_tanhs32(const npy_half*, npy_half*, npy_intp);
extern void __svml_asinhs32(const npy_half*, npy_half*, npy_intp);
extern void __svml_acoshs32(const npy_half*, npy_half*, npy_intp);
extern void __svml_atanhs32(const npy_half*, npy_half*, npy_intp);
#endif

// 如果 NPY_SIMD 为真,并且定义了 NPY_HAVE_AVX512_SKX 和 NPY_CAN_LINK_SVML,则声明下列函数
extern __m512 __svml_expf16(__m512 x);
extern __m512 __svml_exp2f16(__m512 x);
extern __m512 __svml_logf16(__m512 x);
extern __m512 __svml_log2f16(__m512 x);
extern __m512 __svml_log10f16(__m512 x);
extern __m512 __svml_expm1f16(__m512 x);
extern __m512 __svml_log1pf16(__m512 x);
extern __m512 __svml_cbrtf16(__m512 x);
extern __m512 __svml_sinf16(__m512 x);
extern __m512 __svml_cosf16(__m512 x);
extern __m512 __svml_tanf16(__m512 x);
extern __m512 __svml_asinf16(__m512 x);
extern __m512 __svml_acosf16(__m512 x);
extern __m512 __svml_atanf16(__m512 x);
extern __m512 __svml_atan2f16(__m512 x, __m512 y);
extern __m512 __svml_sinhf16(__m512 x);
extern __m512 __svml_coshf16(__m512 x);
extern __m512 __svml_tanhf16(__m512 x);
extern __m512 __svml_asinhf16(__m512 x);
extern __m512 __svml_acoshf16(__m512 x);
extern __m512 __svml_atanhf16(__m512 x);
extern __m512 __svml_powf16(__m512 x, __m512 y);

extern __m512d __svml_exp8_ha(__m512d x);
extern __m512d __svml_exp28_ha(__m512d x);
extern __m512d __svml_log8_ha(__m512d x);
extern __m512d __svml_log28_ha(__m512d x);
extern __m512d __svml_log108_ha(__m512d x);
extern __m512d __svml_expm18_ha(__m512d x);
extern __m512d __svml_log1p8_ha(__m512d x);
extern __m512d __svml_cbrt8_ha(__m512d x);
extern __m512d __svml_sin8_ha(__m512d x);
extern __m512d __svml_cos8_ha(__m512d x);
extern __m512d __svml_tan8_ha(__m512d x);
extern __m512d __svml_asin8_ha(__m512d x);
# 声明外部函数 __svml_acos8_ha,参数和返回类型为 __m512d
extern __m512d __svml_acos8_ha(__m512d x);
# 声明外部函数 __svml_atan8_ha,参数和返回类型为 __m512d
extern __m512d __svml_atan8_ha(__m512d x);
# 声明外部函数 __svml_atan28_ha,参数为 __m512d x 和 __m512d y,返回类型为 __m512d
extern __m512d __svml_atan28_ha(__m512d x, __m512d y);
# 声明外部函数 __svml_sinh8_ha,参数和返回类型为 __m512d
extern __m512d __svml_sinh8_ha(__m512d x);
# 声明外部函数 __svml_cosh8_ha,参数和返回类型为 __m512d
extern __m512d __svml_cosh8_ha(__m512d x);
# 声明外部函数 __svml_tanh8_ha,参数和返回类型为 __m512d
extern __m512d __svml_tanh8_ha(__m512d x);
# 声明外部函数 __svml_asinh8_ha,参数和返回类型为 __m512d
extern __m512d __svml_asinh8_ha(__m512d x);
# 声明外部函数 __svml_acosh8_ha,参数和返回类型为 __m512d
extern __m512d __svml_acosh8_ha(__m512d x);
# 声明外部函数 __svml_atanh8_ha,参数和返回类型为 __m512d
extern __m512d __svml_atanh8_ha(__m512d x);
# 声明外部函数 __svml_pow8_ha,参数为 __m512d x 和 __m512d y,返回类型为 __m512d
extern __m512d __svml_pow8_ha(__m512d x, __m512d y);
#endif

.\numpy\numpy\_core\src\common\numpyos.c

/*
 * 定义宏,确保使用最新的 NumPy API 版本
 */
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
/*
 * 定义宏,标识多维数组模块
 */
#define _MULTIARRAYMODULE

/*
 * 清除 Python.h 中的 PY_SSIZE_T,确保仅使用最新的大小类型 API
 */
#define PY_SSIZE_T_CLEAN
#include <Python.h>

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

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

/*
 * 如果支持 strtold_l 并且未定义 _GNU_SOURCE,则定义 _GNU_SOURCE
 */
#if defined(HAVE_STRTOLD_L) && !defined(_GNU_SOURCE)
# define _GNU_SOURCE
#endif

/*
 * 引入本地化设置头文件
 */
#include <locale.h>
/*
 * 引入标准输入输出头文件
 */
#include <stdio.h>

/*
 * 如果支持 strtold_l,则引入标准库头文件
 */
#ifdef HAVE_STRTOLD_L
#include <stdlib.h>
/*
 * 如果支持 X/Open locale,则引入 xlocale.h
 * 注意:xlocale 在 glibc 2.26 中被移除
 */
#ifdef HAVE_XLOCALE_H
#include <xlocale.h>  // xlocale 在 glibc 2.26 中被移除,请参考 gh-8367
#endif
#endif

/*
 * 从 C99 标准第 7.19.6 节:指数始终至少包含两位数字,
 * 可以包含足够表示指数所需的额外位数。
 */

/*
 * 定义最小指数位数为 2
 */
#define MIN_EXPONENT_DIGITS 2

/*
 * 确保任何存在的指数至少具有 MIN_EXPONENT_DIGITS 指定的长度。
 * 参数 buffer 是输入输出缓冲区,buf_size 是缓冲区大小。
 */
static void
ensure_minimum_exponent_length(char* buffer, size_t buf_size)
{
    /*
     * 在 buffer 中查找 'e''E' 字符,并返回该字符的指针位置。
     */
    char *p = strpbrk(buffer, "eE");
    // 检查指针 p 是否有效,并且下一个字符是 '-' 或者 '+'
    if (p && (*(p + 1) == '-' || *(p + 1) == '+')) {
        // 设置指针 start 指向 p 的后两个位置
        char *start = p + 2;
        // 指数数字的总数
        int exponent_digit_cnt = 0;
        // 领先的零的数量
        int leading_zero_cnt = 0;
        // 是否处于领先零状态的标志
        int in_leading_zeros = 1;
        // 有效数字的数量
        int significant_digit_cnt;

        /* 跳过指数和符号 */
        p += 2;

        /* 找到指数的结束位置,并跟踪前导零 */
        while (*p && isdigit(Py_CHARMASK(*p))) {
            if (in_leading_zeros && *p == '0') {
                ++leading_zero_cnt;
            }
            if (*p != '0') {
                in_leading_zeros = 0;
            }
            ++p;
            ++exponent_digit_cnt;
        }

        significant_digit_cnt = exponent_digit_cnt - leading_zero_cnt;

        // 如果指数数字的数量等于 MIN_EXPONENT_DIGITS
        if (exponent_digit_cnt == MIN_EXPONENT_DIGITS) {
            /*
             * 如果有 2 个确切的数字,我们完成了,
             * 不管它们包含什么
             */
        }
        else if (exponent_digit_cnt > MIN_EXPONENT_DIGITS) {
            int extra_zeros_cnt;

            /*
             * 指数中有超过 2 个数字。看看我们是否可以删除一些前导零
             */
            if (significant_digit_cnt < MIN_EXPONENT_DIGITS) {
                significant_digit_cnt = MIN_EXPONENT_DIGITS;
            }
            extra_zeros_cnt = exponent_digit_cnt - significant_digit_cnt;

            /*
             * 从指数的前端删除 extra_zeros_cnt 个字符
             */
            assert(extra_zeros_cnt >= 0);

            /*
             * 将 significant_digit_cnt 加一,以复制
             * 结尾的 0 字节,从而设置长度
             */
            memmove(start, start + extra_zeros_cnt, significant_digit_cnt + 1);
        }
        else {
            /*
             * 如果数字少于 2 个,则添加零
             * 直到达到 2 个,如果有足够的空间
             */
            int zeros = MIN_EXPONENT_DIGITS - exponent_digit_cnt;
            if (start + zeros + exponent_digit_cnt + 1 < buffer + buf_size) {
                memmove(start + zeros, start, exponent_digit_cnt + 1);
                memset(start, '0', zeros);
            }
        }
    }
/*
 * Ensure that buffer has a decimal point in it.  The decimal point
 * will not be in the current locale, it will always be '.'
 */
static void
ensure_decimal_point(char* buffer, size_t buf_size)
{
    int insert_count = 0;
    char* chars_to_insert;

    /* search for the first non-digit character */
    char *p = buffer;
    if (*p == '-' || *p == '+')
        /*
         * Skip leading sign, if present.  I think this could only
         * ever be '-', but it can't hurt to check for both.
         */
        ++p;
    while (*p && isdigit(Py_CHARMASK(*p))) {
        ++p;
    }
    if (*p == '.') {
        if (isdigit(Py_CHARMASK(*(p+1)))) {
            /*
             * Nothing to do, we already have a decimal
             * point and a digit after it.
             */
        }
        else {
            /*
             * We have a decimal point, but no following
             * digit.  Insert a zero after the decimal.
             */
            ++p;
            chars_to_insert = "0";
            insert_count = 1;
        }
    }
    else {
        chars_to_insert = ".0";
        insert_count = 2;
    }
    if (insert_count) {
        size_t buf_len = strlen(buffer);
        if (buf_len + insert_count + 1 >= buf_size) {
            /*
             * If there is not enough room in the buffer
             * for the additional text, just skip it.  It's
             * not worth generating an error over.
             */
        }
        else {
            memmove(p + insert_count, p, buffer + strlen(buffer) - p + 1);
            memcpy(p, chars_to_insert, insert_count);
        }
    }
}

/* see FORMATBUFLEN in unicodeobject.c */
#define FLOAT_FORMATBUFLEN 120

/*
 * Given a string that may have a decimal point in the current
 * locale, change it back to a dot.  Since the string cannot get
 * longer, no need for a maximum buffer size parameter.
 */
static void
change_decimal_from_locale_to_dot(char* buffer)
{
    struct lconv *locale_data = localeconv();
    const char *decimal_point = locale_data->decimal_point;

    if (decimal_point[0] != '.' || decimal_point[1] != 0) {
        size_t decimal_point_len = strlen(decimal_point);

        if (*buffer == '+' || *buffer == '-') {
            buffer++;
        }
        while (isdigit(Py_CHARMASK(*buffer))) {
            buffer++;
        }
        if (strncmp(buffer, decimal_point, decimal_point_len) == 0) {
            *buffer = '.';
            buffer++;
            if (decimal_point_len > 1) {
                /* buffer needs to get smaller */
                size_t rest_len = strlen(buffer + (decimal_point_len - 1));
                memmove(buffer, buffer + (decimal_point_len - 1), rest_len);
                buffer[rest_len] = 0;
            }
        }
    }
}

/*
 * Check that the format string is a valid one for NumPyOS_ascii_format*
 */
static int
check_ascii_format(const char *format)
{
    char format_char;
    size_t format_len = strlen(format);
    /* 获取格式字符串的最后一个字符作为格式字符 */
    format_char = format[format_len - 1];

    /* 如果格式字符串的第一个字符不是 '%',则返回错误 */
    if (format[0] != '%') {
        return -1;
    }

    /*
     * 我不确定为什么这个测试在这里。它确保格式字符串的第一个字符后面
     * 没有单引号、小写的 'l' 或百分号。这与大约 10 行前的注释掉的测试
     * 是相反的。
     */
    if (strpbrk(format + 1, "'l%")) {
        return -1;
    }

    /*
     * 同样让人好奇的是,这个函数接受像 "%xg" 这样对于浮点数无效的
     * 格式字符串。总体来说,这个函数的接口设计并不是很好,但由于它
     * 是一个公共 API,改变它很困难。
     */
    if (!(format_char == 'e' || format_char == 'E'
          || format_char == 'f' || format_char == 'F'
          || format_char == 'g' || format_char == 'G')) {
        return -1;
    }

    /* 如果所有的格式验证都通过,则返回成功 */
    return 0;
/*
 * Fix the generated string: make sure the decimal is ., that exponent has a
 * minimal number of digits, and that it has a decimal + one digit after that
 * decimal if decimal argument != 0 (Same effect that 'Z' format in
 * PyOS_ascii_formatd)
 */
static char*
fix_ascii_format(char* buf, size_t buflen, int decimal)
{
    /*
     * Get the current locale, and find the decimal point string.
     * Convert that string back to a dot.
     */
    change_decimal_from_locale_to_dot(buf);

    /*
     * If an exponent exists, ensure that the exponent is at least
     * MIN_EXPONENT_DIGITS digits, providing the buffer is large enough
     * for the extra zeros.  Also, if there are more than
     * MIN_EXPONENT_DIGITS, remove as many zeros as possible until we get
     * back to MIN_EXPONENT_DIGITS
     */
    ensure_minimum_exponent_length(buf, buflen);

    // 如果 decimal 参数不为 0,确保在 buf 中有小数点及至少一位小数
    if (decimal != 0) {
        ensure_decimal_point(buf, buflen);
    }

    // 返回修正后的 buf 字符串
    return buf;
}

/*
 * NumPyOS_ascii_format*:
 *      - buffer: A buffer to place the resulting string in
 *      - buf_size: The length of the buffer.
 *      - format: The printf()-style format to use for the code to use for
 *      converting.
 *      - value: The value to convert
 *      - decimal: if != 0, always has a decimal, and at leasat one digit after
 *      the decimal. This has the same effect as passing 'Z' in the original
 *      PyOS_ascii_formatd
 *
 * This is similar to PyOS_ascii_formatd in python > 2.6, except that it does
 * not handle 'n', and handles nan / inf.
 *
 * Converts a #gdouble to a string, using the '.' as decimal point. To format
 * the number you pass in a printf()-style format string. Allowed conversion
 * specifiers are 'e', 'E', 'f', 'F', 'g', 'G'.
 *
 * Return value: The pointer to the buffer with the converted string.
 */
#define ASCII_FORMAT(type, suffix, print_type)                          \
    NPY_NO_EXPORT char*                                                 \
    NumPyOS_ascii_format ## suffix(char *buffer, size_t buf_size,       \
                                   const char *format,                  \
                                   type val, int decimal)               \
    {                                                                   \
        // 检查浮点数是否有限,即不是NaN或无穷大
        if (npy_isfinite(val)) {                                        
            // 检查是否要求输出ASCII格式,如果是,则返回空指针
            if (check_ascii_format(format)) {                           
                return NULL;                                            
            }                                                           
            // 将浮点数按指定格式输出到缓冲区中
            PyOS_snprintf(buffer, buf_size, format, (print_type)val);   
            // 修正ASCII格式,确保输出正确格式的数据
            return fix_ascii_format(buffer, buf_size, decimal);         
        }                                                               
        // 如果浮点数是NaN
        else if (npy_isnan(val)){                                       
            // 如果缓冲区大小不足以容纳"nan",则返回空指针
            if (buf_size < 4) {                                         
                return NULL;                                            
            }                                                           
            // 将"nan"复制到缓冲区
            strcpy(buffer, "nan");                                      
        }                                                               
        // 如果浮点数是无穷大
        else {                                                          
            // 如果浮点数为负无穷且缓冲区大小不足以容纳"-inf",则返回空指针
            if (npy_signbit(val)) {                                     
                if (buf_size < 5) {                                     
                    return NULL;                                        
                }                                                       
                // 将"-inf"复制到缓冲区
                strcpy(buffer, "-inf");                                 
            }                                                           
            // 如果浮点数为正无穷且缓冲区大小不足以容纳"inf",则返回空指针
            else {                                                      
                if (buf_size < 4) {                                     
                    return NULL;                                        
                }                                                       
                // 将"inf"复制到缓冲区
                strcpy(buffer, "inf");                                  
            }                                                           
        }                                                               
        // 返回填充好数据的缓冲区
        return buffer;                                                  
    }
/*
 * ASCII_FORMAT(float, f, float)
 *
 * Macro definition for formatting float types with ASCII representation.
 */
ASCII_FORMAT(float, f, float)

/*
 * ASCII_FORMAT(double, d, double)
 *
 * Macro definition for formatting double types with ASCII representation.
 */
ASCII_FORMAT(double, d, double)

#ifndef FORCE_NO_LONG_DOUBLE_FORMATTING
/*
 * ASCII_FORMAT(long double, l, long double)
 *
 * Macro definition for formatting long double types with ASCII representation,
 * unless FORCE_NO_LONG_DOUBLE_FORMATTING is defined.
 */
ASCII_FORMAT(long double, l, long double)
#else
/*
 * ASCII_FORMAT(long double, l, double)
 *
 * Macro definition for formatting long double types with ASCII representation,
 * when FORCE_NO_LONG_DOUBLE_FORMATTING is defined.
 */
ASCII_FORMAT(long double, l, double)
#endif

/*
 * NumPyOS_ascii_isspace:
 *
 * Function to determine if the provided character is a whitespace character
 * in the ASCII character set.
 */
NPY_NO_EXPORT int
NumPyOS_ascii_isspace(int c)
{
    return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t'
                    || c == '\v';
}

/*
 * NumPyOS_ascii_isalpha:
 *
 * Function to determine if the provided character is an alphabetic character
 * (a-z or A-Z) in the ASCII character set.
 */
NPY_NO_EXPORT int
NumPyOS_ascii_isalpha(char c)
{
    return (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z');
}

/*
 * NumPyOS_ascii_isdigit:
 *
 * Function to determine if the provided character is a digit (0-9)
 * in the ASCII character set.
 */
NPY_NO_EXPORT int
NumPyOS_ascii_isdigit(char c)
{
    return (c >= '0' && c <= '9');
}

/*
 * NumPyOS_ascii_isalnum:
 *
 * Function to determine if the provided character is either a digit or
 * an alphabetic character (a-z, A-Z, or 0-9) in the ASCII character set.
 */
NPY_NO_EXPORT int
NumPyOS_ascii_isalnum(char c)
{
    return NumPyOS_ascii_isdigit(c) || NumPyOS_ascii_isalpha(c);
}

/*
 * NumPyOS_ascii_islower:
 *
 * Function to determine if the provided character is a lowercase alphabetic
 * character (a-z) in the ASCII character set.
 */
NPY_NO_EXPORT int
NumPyOS_ascii_islower(char c)
{
    return c >= 'a' && c <= 'z';
}

/*
 * NumPyOS_ascii_isupper:
 *
 * Function to determine if the provided character is an uppercase alphabetic
 * character (A-Z) in the ASCII character set.
 */
NPY_NO_EXPORT int
NumPyOS_ascii_isupper(char c)
{
    return c >= 'A' && c <= 'Z';
}

/*
 * NumPyOS_ascii_tolower:
 *
 * Function to convert the provided character to its lowercase equivalent
 * in the ASCII character set.
 */
NPY_NO_EXPORT int
NumPyOS_ascii_tolower(int c)
{
    if (c >= 'A' && c <= 'Z') {
        return c + ('a'-'A');
    }
    return c;
}

/*
 * NumPyOS_ascii_strncasecmp:
 *
 * Function to compare two strings case-insensitively up to a specified length,
 * considering ASCII character set rules.
 */
static int
NumPyOS_ascii_strncasecmp(const char* s1, const char* s2, size_t len)
{
    while (len > 0 && *s1 != '\0' && *s2 != '\0') {
        int diff = NumPyOS_ascii_tolower(*s1) - NumPyOS_ascii_tolower(*s2);
        if (diff != 0) {
            return diff;
        }
        ++s1;
        ++s2;
        --len;
    }
    if (len > 0) {
        return *s1 - *s2;
    }
    return 0;
}

/*
 * NumPyOS_ascii_strtod_plain:
 *
 * Function similar to PyOS_ascii_strtod, without enhanced features,
 * compatible with Python versions >= 2.7.
 */
static double
NumPyOS_ascii_strtod_plain(const char *s, char** endptr)
{
    double result;
    NPY_ALLOW_C_API_DEF;
    NPY_ALLOW_C_API;
    result = PyOS_string_to_double(s, endptr, NULL);
    if (PyErr_Occurred()) {
        if (endptr) {
            *endptr = (char*)s;
        }
        PyErr_Clear();
    }
    NPY_DISABLE_C_API;
    return result;
}

/*
 * NumPyOS_ascii_strtod:
 *
 * Function to convert a string to a double, addressing bugs in PyOS_ascii_strtod.
 */
NPY_NO_EXPORT double
NumPyOS_ascii_strtod(const char *s, char** endptr)
{
    const char *p;
    double result;

    while (NumPyOS_ascii_isspace(*s)) {
        ++s;
    }

    /*
     * Recognize POSIX inf/nan representations on all platforms.
     */
    p = s;
    result = 1.0;
    if (*p == '-') {
        result = -1.0;
        ++p;
    }
    else if (*p == '+') {
        ++p;
    }
    # 如果字符串以 "nan" 开头,表示遇到 NaN(Not a Number)情况
    if (NumPyOS_ascii_strncasecmp(p, "nan", 3) == 0) {
        # 将指针 p 向后移动 3 个字符,跳过 "nan"
        p += 3;
        # 如果接下来是 '(', 继续处理括号内的内容
        if (*p == '(') {
            ++p;
            # 处理括号内的字母数字和下划线,直到结束括号 ')'
            while (NumPyOS_ascii_isalnum(*p) || *p == '_') {
                ++p;
            }
            if (*p == ')') {
                ++p;
            }
        }
        # 如果有 endptr 参数,将指针 p 赋值给它
        if (endptr != NULL) {
            *endptr = (char*)p;
        }
        # 返回 NaN 常量
        return NPY_NAN;
    }
    # 如果字符串以 "inf" 开头,表示遇到正无穷(infinity)情况
    else if (NumPyOS_ascii_strncasecmp(p, "inf", 3) == 0) {
        # 将指针 p 向后移动 3 个字符,跳过 "inf"
        p += 3;
        # 如果接下来是 "inity", 继续处理完整的 "infinity"
        if (NumPyOS_ascii_strncasecmp(p, "inity", 5) == 0) {
            p += 5;
        }
        # 如果有 endptr 参数,将指针 p 赋值给它
        if (endptr != NULL) {
            *endptr = (char*)p;
        }
        # 返回正无穷常量
        return result * NPY_INFINITY;
    }
    /* End of ##1 */

    # 如果不是 NaN 或正无穷,则调用 NumPy 的字符串转换为 double 函数继续处理
    return NumPyOS_ascii_strtod_plain(s, endptr);
}



NPY_NO_EXPORT long double
NumPyOS_ascii_strtold(const char *s, char** endptr)
{
    const char *p;
    long double result;
#ifdef HAVE_STRTOLD_L
    locale_t clocale;
#endif

    // 跳过输入字符串开头的空白字符
    while (NumPyOS_ascii_isspace(*s)) {
        ++s;
    }

    /*
     * ##1
     *
     * Recognize POSIX inf/nan representations on all platforms.
     * 识别所有平台上的 POSIX inf/nan 表示形式。
     */
    p = s;
    result = 1.0;
    if (*p == '-') {
        result = -1.0;
        ++p;
    }
    else if (*p == '+') {
        ++p;
    }
    // 检查是否为 NaN
    if (NumPyOS_ascii_strncasecmp(p, "nan", 3) == 0) {
        p += 3;
        // 处理 NaN 可选的附加信息
        if (*p == '(') {
            ++p;
            // 跳过可能存在的附加标识符
            while (NumPyOS_ascii_isalnum(*p) || *p == '_') {
                ++p;
            }
            if (*p == ')') {
                ++p;
            }
        }
        // 如果有 endptr,将其设置为指向字符串结尾的指针
        if (endptr != NULL) {
            *endptr = (char*)p;
        }
        // 返回 NaN 常量
        return NPY_NAN;
    }
    // 检查是否为 Infinity
    else if (NumPyOS_ascii_strncasecmp(p, "inf", 3) == 0) {
        p += 3;
        // 检查是否为 "infinity" 的后缀
        if (NumPyOS_ascii_strncasecmp(p, "inity", 5) == 0) {
            p += 5;
        }
        // 如果有 endptr,将其设置为指向字符串结尾的指针
        if (endptr != NULL) {
            *endptr = (char*)p;
        }
        // 返回 ±Infinity
        return result * NPY_INFINITY;
    }
    /* End of ##1 */

#ifdef HAVE_STRTOLD_L
    // 使用本地化设置解析长双精度浮点数
    clocale = newlocale(LC_ALL_MASK, "C", NULL);
    if (clocale) {
        errno = 0;
        result = strtold_l(s, endptr, clocale);
        freelocale(clocale);
    }
    else {
        // 如果没有本地化支持,直接将 endptr 设置为 s,并返回 0
        if (endptr != NULL) {
            *endptr = (char*)s;
        }
        result = 0;
    }
    return result;
#else
    // 没有本地化支持时,使用标准 strtod 解析浮点数
    return NumPyOS_ascii_strtod(s, endptr);
#endif
}

/*
 * read_numberlike_string:
 *      * fp: FILE pointer
 *      * value: Place to store the value read
 *
 * Read what looks like valid numeric input and store it in a buffer
 * for later parsing as a number.
 *
 * Similarly to fscanf, this function always consumes leading whitespace,
 * and any text that could be the leading part in valid input.
 *
 * Return value: similar to fscanf.
 *      * 0 if no number read,
 *      * 1 if a number read,
 *      * EOF if end-of-file met before reading anything.
 */
static int
read_numberlike_string(FILE *fp, char *buffer, size_t buflen)
{

    char *endp;
    char *p;
    int c;
    int ok;

    /*
     * Fill buffer with the leftmost matching part in regexp
     *
     *     \s*[+-]? ( [0-9]*\.[0-9]+([eE][+-]?[0-9]+)
     *              | nan  (  \([:alphanum:_]*\) )?
     *              | inf(inity)?
     *              )
     *
     * case-insensitively.
     *
     * The "do { ... } while (0)" wrapping in macros ensures that they behave
     * properly eg. in "if ... else" structures.
     */
    
    // 宏定义:跳转到 buffer_filled 标签处
#define END_MATCH()                                                         \
        goto buffer_filled


注:以上是对给定代码的详细注释,按照要求进行了逐行解释。
    /* 定义宏:获取下一个字符,并将其放入缓冲区,处理 EOF 和缓冲区溢出 */
#define NEXT_CHAR()                                                         \
        do {                                                                \
            if (c == EOF || endp >= buffer + buflen - 1)            \
                END_MATCH();                                                \
            *endp++ = (char)c;                                              \
            c = getc(fp);                                                   \
        } while (0)

    /* 定义宏:匹配不区分大小写的字符串 */
#define MATCH_ALPHA_STRING_NOCASE(string)                                   \
        do {                                                                \
            for (p=(string); *p!='\0' && (c==*p || c+('a'-'A')==*p); ++p)   \
                NEXT_CHAR();                                                \
            if (*p != '\0') END_MATCH();                                    \
        } while (0)

    /* 定义宏:匹配零个或一个条件 */
#define MATCH_ONE_OR_NONE(condition)                                        \
        do { if (condition) NEXT_CHAR(); } while (0)

    /* 定义宏:匹配一个或多个条件 */
#define MATCH_ONE_OR_MORE(condition)                                        \
        do {                                                                \
            ok = 0;                                                         \
            while (condition) { NEXT_CHAR(); ok = 1; }                      \
            if (!ok) END_MATCH();                                           \
        } while (0)

    /* 定义宏:匹配零个或多个条件 */
#define MATCH_ZERO_OR_MORE(condition)                                       \
        while (condition) { NEXT_CHAR(); }

    /* 1. 模拟 fscanf 处理 EOF */
    c = getc(fp);
    if (c == EOF) {
        return EOF;
    }

    /* 2. 无条件消耗前导空白 */
    while (NumPyOS_ascii_isspace(c)) {
        c = getc(fp);
    }

    /* 3. 开始读取匹配输入到缓冲区 */
    endp = buffer;

    /* 4.1 符号部分(可选) */
    MATCH_ONE_OR_NONE(c == '+' || c == '-');

    /* 4.2 nan, inf, infinity;不区分大小写 */
    if (c == 'n' || c == 'N') {
        NEXT_CHAR();
        MATCH_ALPHA_STRING_NOCASE("an");

        /* 接受 nan([:alphanum:_]*),类似于 strtod */
        if (c == '(') {
            NEXT_CHAR();
            MATCH_ZERO_OR_MORE(NumPyOS_ascii_isalnum(c) || c == '_');
            if (c == ')') {
                NEXT_CHAR();
            }
        }
        END_MATCH();
    }
    else if (c == 'i' || c == 'I') {
        NEXT_CHAR();
        MATCH_ALPHA_STRING_NOCASE("nfinity");
        END_MATCH();
    }

    /* 4.3 小数部分 */
    MATCH_ZERO_OR_MORE(NumPyOS_ascii_isdigit(c));

    if (c == '.') {
        NEXT_CHAR();
        MATCH_ONE_OR_MORE(NumPyOS_ascii_isdigit(c));
    }

    /* 4.4 指数部分 */
    if (c == 'e' || c == 'E') {
        NEXT_CHAR();
        MATCH_ONE_OR_NONE(c == '+' || c == '-');
        MATCH_ONE_OR_MORE(NumPyOS_ascii_isdigit(c));
    }

    END_MATCH();

buffer_filled:

    ungetc(c, fp);
    *endp = '\0';

    /* 返回1表示有内容被读取,否则返回0 */
    # 如果 buffer 等于 endp,则返回 0;否则返回 1。
    return (buffer == endp) ? 0 : 1;
/*
 * NumPyOS_ascii_ftolf:
 *      * fp: FILE pointer
 *      * value: Place to store the value read
 *
 * Similar to PyOS_ascii_strtod, except that it reads input from a file.
 *
 * Similarly to fscanf, this function always consumes leading whitespace,
 * and any text that could be the leading part in valid input.
 *
 * Return value: similar to fscanf.
 *      * 0 if no number read,
 *      * 1 if a number read,
 *      * EOF if end-of-file met before reading anything.
 */
NPY_NO_EXPORT int
NumPyOS_ascii_ftolf(FILE *fp, double *value)
{
    // 缓冲区用于存储从文件中读取的数字字符串
    char buffer[FLOAT_FORMATBUFLEN + 1];
    char *p;
    int r;

    // 从文件中读取类似数字的字符串
    r = read_numberlike_string(fp, buffer, FLOAT_FORMATBUFLEN+1);

    // 如果成功读取数字字符串
    if (r != EOF && r != 0) {
        // 使用 NumPyOS_ascii_strtod 将字符串转换为双精度浮点数
        *value = NumPyOS_ascii_strtod(buffer, &p);
        // 如果转换后的指针与缓冲区指针相同,表明没有有效数字
        r = (p == buffer) ? 0 : 1;
    }
    // 返回读取操作的结果
    return r;
}

/*
 * NumPyOS_ascii_ftoLf:
 *      * fp: FILE pointer
 *      * value: Place to store the value read
 *
 * Similar to PyOS_ascii_strtod, except that it reads input from a file.
 *
 * Similarly to fscanf, this function always consumes leading whitespace,
 * and any text that could be the leading part in valid input.
 *
 * Return value: similar to fscanf.
 *      * 0 if no number read,
 *      * 1 if a number read,
 *      * EOF if end-of-file met before reading anything.
 */
NPY_NO_EXPORT int
NumPyOS_ascii_ftoLf(FILE *fp, long double *value)
{
    // 缓冲区用于存储从文件中读取的数字字符串
    char buffer[FLOAT_FORMATBUFLEN + 1];
    char *p;
    int r;

    // 从文件中读取类似数字的字符串
    r = read_numberlike_string(fp, buffer, FLOAT_FORMATBUFLEN+1);

    // 如果成功读取数字字符串
    if (r != EOF && r != 0) {
        // 使用 NumPyOS_ascii_strtold 将字符串转换为长双精度浮点数
        *value = NumPyOS_ascii_strtold(buffer, &p);
        // 如果转换后的指针与缓冲区指针相同,表明没有有效数字
        r = (p == buffer) ? 0 : 1;
    }
    // 返回读取操作的结果
    return r;
}

/*
 * NumPyOS_strtoll:
 *      * str: 要转换为长长整型的字符串
 *      * endptr: 如果提供,将返回第一个非数字字符的指针
 *      * base: 数字的进制,如 10 表示十进制
 *
 * 使用标准函数 strtoll 将字符串转换为长长整型数。
 */
NPY_NO_EXPORT npy_longlong
NumPyOS_strtoll(const char *str, char **endptr, int base)
{
    return strtoll(str, endptr, base);
}

/*
 * NumPyOS_strtoull:
 *      * str: 要转换为无符号长长整型的字符串
 *      * endptr: 如果提供,将返回第一个非数字字符的指针
 *      * base: 数字的进制,如 10 表示十进制
 *
 * 使用标准函数 strtoull 将字符串转换为无符号长长整型数。
 */
NPY_NO_EXPORT npy_ulonglong
NumPyOS_strtoull(const char *str, char **endptr, int base)
{
    return strtoull(str, endptr, base);
}

#ifdef _MSC_VER

#include <stdlib.h>

#if _MSC_VER >= 1900
/* npy3k_compat.h uses this function in the _Py_BEGIN/END_SUPPRESS_IPH
 * macros. It does not need to be defined when building using MSVC
 * earlier than 14.0 (_MSC_VER == 1900).
 */

// Microsoft Visual C++ 1900 及更高版本的静默无效参数处理器
static void __cdecl _silent_invalid_parameter_handler(
    wchar_t const* expression,
    wchar_t const* function,
    wchar_t const* file,
    unsigned int line,
    uintptr_t pReserved) { }

_invalid_parameter_handler _Py_silent_invalid_parameter_handler = _silent_invalid_parameter_handler;

#endif

#endif

.\numpy\numpy\_core\src\common\numpyos.h

#ifndef NUMPY_CORE_SRC_COMMON_NPY_NUMPYOS_H_
#define NUMPY_CORE_SRC_COMMON_NPY_NUMPYOS_H_

#ifdef __cplusplus
extern "C" {
#endif

// 定义了以下函数的声明,这些函数实现在 NumPy 源码中,用于处理 ASCII 字符串和数字转换

// 将 double 类型的 val 格式化成 ASCII 字符串,存储到 buffer 中,格式由 format 指定,decimal 是小数位数
NPY_NO_EXPORT char*
NumPyOS_ascii_formatd(char *buffer, size_t buf_size,
                      const char *format,
                      double val, int decimal);

// 将 float 类型的 val 格式化成 ASCII 字符串,存储到 buffer 中,格式由 format 指定,decimal 是小数位数
NPY_NO_EXPORT char*
NumPyOS_ascii_formatf(char *buffer, size_t buf_size,
                      const char *format,
                      float val, int decimal);

// 将 long double 类型的 val 格式化成 ASCII 字符串,存储到 buffer 中,格式由 format 指定,decimal 是小数位数
NPY_NO_EXPORT char*
NumPyOS_ascii_formatl(char *buffer, size_t buf_size,
                      const char *format,
                      long double val, int decimal);

// 将 ASCII 字符串 s 转换为 double 类型的数值
NPY_NO_EXPORT double
NumPyOS_ascii_strtod(const char *s, char** endptr);

// 将 ASCII 字符串 s 转换为 long double 类型的数值
NPY_NO_EXPORT long double
NumPyOS_ascii_strtold(const char *s, char** endptr);

// 从文件 fp 中读取 double 类型的数值,存储到 value 中,返回成功读取的标志
NPY_NO_EXPORT int
NumPyOS_ascii_ftolf(FILE *fp, double *value);

// 从文件 fp 中读取 long double 类型的数值,存储到 value 中,返回成功读取的标志
NPY_NO_EXPORT int
NumPyOS_ascii_ftoLf(FILE *fp, long double *value);

// 检查字符 c 是否为空白字符
NPY_NO_EXPORT int
NumPyOS_ascii_isspace(int c);

// 检查字符 c 是否为字母
NPY_NO_EXPORT int
NumPyOS_ascii_isalpha(char c);

// 检查字符 c 是否为数字
NPY_NO_EXPORT int
NumPyOS_ascii_isdigit(char c);

// 检查字符 c 是否为字母或数字
NPY_NO_EXPORT int
NumPyOS_ascii_isalnum(char c);

// 检查字符 c 是否为小写字母
NPY_NO_EXPORT int
NumPyOS_ascii_islower(char c);

// 检查字符 c 是否为大写字母
NPY_NO_EXPORT int
NumPyOS_ascii_isupper(char c);

// 将大写字母转换为小写字母
NPY_NO_EXPORT int
NumPyOS_ascii_tolower(char c);

/* 将字符串 str 转换为指定 base 进制的长长整型数值 */
NPY_NO_EXPORT npy_longlong
NumPyOS_strtoll(const char *str, char **endptr, int base);

/* 将字符串 str 转换为指定 base 进制的无符号长长整型数值 */
NPY_NO_EXPORT npy_ulonglong
NumPyOS_strtoull(const char *str, char **endptr, int base);

#ifdef __cplusplus
}
#endif

#endif  /* NUMPY_CORE_SRC_COMMON_NPY_NUMPYOS_H_ */

.\numpy\numpy\_core\src\common\numpy_tag.h

#ifndef _NPY_COMMON_TAG_H_
#define _NPY_COMMON_TAG_H_

#include "../npysort/npysort_common.h"

namespace npy {

// 定义一个模板结构体,用于存储多个标签类型,tags 是模板参数包
template<typename... tags>
struct taglist {
  // 计算标签数量的静态成员变量
  static constexpr unsigned size = sizeof...(tags);
};

// 各种标签类型的结构体定义

// 整数标签
struct integral_tag {
};

// 浮点数标签
struct floating_point_tag {
};

// 复数标签
struct complex_tag {
};

// 日期标签
struct date_tag {
};

// 布尔类型标签,继承自整数标签
struct bool_tag : integral_tag {
    // 使用 npy_bool 作为类型别名
    using type = npy_bool;
    // 标识这是布尔类型的 NPY_TYPES 值
    static constexpr NPY_TYPES type_value = NPY_BOOL;
    // 比较操作:小于
    static int less(type const& a, type const& b) {
      return BOOL_LT(a, b);
    }
    // 比较操作:小于等于
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

// 字节标签,继承自整数标签
struct byte_tag : integral_tag {
    // 使用 npy_byte 作为类型别名
    using type = npy_byte;
    // 标识这是字节类型的 NPY_TYPES 值
    static constexpr NPY_TYPES type_value = NPY_BYTE;
    // 比较操作:小于
    static int less(type const& a, type const& b) {
      return BYTE_LT(a, b);
    }
    // 比较操作:小于等于
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

// 无符号字节标签,继承自整数标签
struct ubyte_tag : integral_tag {
    // 使用 npy_ubyte 作为类型别名
    using type = npy_ubyte;
    // 标识这是无符号字节类型的 NPY_TYPES 值
    static constexpr NPY_TYPES type_value = NPY_UBYTE;
    // 比较操作:小于
    static int less(type const& a, type const& b) {
      return UBYTE_LT(a, b);
    }
    // 比较操作:小于等于
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

// 短整数标签,继承自整数标签
struct short_tag : integral_tag {
    // 使用 npy_short 作为类型别名
    using type = npy_short;
    // 标识这是短整数类型的 NPY_TYPES 值
    static constexpr NPY_TYPES type_value = NPY_SHORT;
    // 比较操作:小于
    static int less(type const& a, type const& b) {
      return SHORT_LT(a, b);
    }
    // 比较操作:小于等于
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

// 无符号短整数标签,继承自整数标签
struct ushort_tag : integral_tag {
    // 使用 npy_ushort 作为类型别名
    using type = npy_ushort;
    // 标识这是无符号短整数类型的 NPY_TYPES 值
    static constexpr NPY_TYPES type_value = NPY_USHORT;
    // 比较操作:小于
    static int less(type const& a, type const& b) {
      return USHORT_LT(a, b);
    }
    // 比较操作:小于等于
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

// 整数标签,继承自整数标签
struct int_tag : integral_tag {
    // 使用 npy_int 作为类型别名
    using type = npy_int;
    // 标识这是整数类型的 NPY_TYPES 值
    static constexpr NPY_TYPES type_value = NPY_INT;
    // 比较操作:小于
    static int less(type const& a, type const& b) {
      return INT_LT(a, b);
    }
    // 比较操作:小于等于
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

// 无符号整数标签,继承自整数标签
struct uint_tag : integral_tag {
    // 使用 npy_uint 作为类型别名
    using type = npy_uint;
    // 标识这是无符号整数类型的 NPY_TYPES 值
    static constexpr NPY_TYPES type_value = NPY_UINT;
    // 比较操作:小于
    static int less(type const& a, type const& b) {
      return UINT_LT(a, b);
    }
    // 比较操作:小于等于
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

// 长整数标签,继承自整数标签
struct long_tag : integral_tag {
    // 使用 npy_long 作为类型别名
    using type = npy_long;
    // 标识这是长整数类型的 NPY_TYPES 值
    static constexpr NPY_TYPES type_value = NPY_LONG;
    // 比较操作:小于
    static int less(type const& a, type const& b) {
      return LONG_LT(a, b);
    }
    // 比较操作:小于等于
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

// 无符号长整数标签,继承自整数标签
struct ulong_tag : integral_tag {
    // 使用 npy_ulong 作为类型别名
    using type = npy_ulong;
    // 标识这是无符号长整数类型的 NPY_TYPES 值
    static constexpr NPY_TYPES type_value = NPY_ULONG;
    // 比较操作:小于
    static int less(type const& a, type const& b) {
      return ULONG_LT(a, b);
    }
    // 比较操作:小于等于
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

#endif // _NPY_COMMON_TAG_H_
struct longlong_tag : integral_tag {
    // 定义类型为 npy_longlong 的别名 type
    using type = npy_longlong;
    // 设置 type_value 为 NPY_LONGLONG
    static constexpr NPY_TYPES type_value = NPY_LONGLONG;
    // 比较函数,比较 a 是否小于 b
    static int less(type const& a, type const& b) {
      return LONGLONG_LT(a, b);
    }
    // 小于等于函数,利用 less 函数实现
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

struct ulonglong_tag : integral_tag {
    // 定义类型为 npy_ulonglong 的别名 type
    using type = npy_ulonglong;
    // 设置 type_value 为 NPY_ULONGLONG
    static constexpr NPY_TYPES type_value = NPY_ULONGLONG;
    // 比较函数,比较 a 是否小于 b
    static int less(type const& a, type const& b) {
      return ULONGLONG_LT(a, b);
    }
    // 小于等于函数,利用 less 函数实现
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

struct half_tag {
    // 定义类型为 npy_half 的别名 type
    using type = npy_half;
    // 设置 type_value 为 NPY_HALF
    static constexpr NPY_TYPES type_value = NPY_HALF;
    // 比较函数,比较 a 是否小于 b
    static int less(type const& a, type const& b) {
      return HALF_LT(a, b);
    }
    // 小于等于函数,利用 less 函数实现
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

struct float_tag : floating_point_tag {
    // 定义类型为 npy_float 的别名 type
    using type = npy_float;
    // 设置 type_value 为 NPY_FLOAT
    static constexpr NPY_TYPES type_value = NPY_FLOAT;
    // 比较函数,比较 a 是否小于 b
    static int less(type const& a, type const& b) {
      return FLOAT_LT(a, b);
    }
    // 小于等于函数,利用 less 函数实现
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

struct double_tag : floating_point_tag {
    // 定义类型为 npy_double 的别名 type
    using type = npy_double;
    // 设置 type_value 为 NPY_DOUBLE
    static constexpr NPY_TYPES type_value = NPY_DOUBLE;
    // 比较函数,比较 a 是否小于 b
    static int less(type const& a, type const& b) {
      return DOUBLE_LT(a, b);
    }
    // 小于等于函数,利用 less 函数实现
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

struct longdouble_tag : floating_point_tag {
    // 定义类型为 npy_longdouble 的别名 type
    using type = npy_longdouble;
    // 设置 type_value 为 NPY_LONGDOUBLE
    static constexpr NPY_TYPES type_value = NPY_LONGDOUBLE;
    // 比较函数,比较 a 是否小于 b
    static int less(type const& a, type const& b) {
      return LONGDOUBLE_LT(a, b);
    }
    // 小于等于函数,利用 less 函数实现
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

struct cfloat_tag : complex_tag {
    // 定义类型为 npy_cfloat 的别名 type
    using type = npy_cfloat;
    // 设置 type_value 为 NPY_CFLOAT
    static constexpr NPY_TYPES type_value = NPY_CFLOAT;
    // 比较函数,比较 a 是否小于 b
    static int less(type const& a, type const& b) {
      return CFLOAT_LT(a, b);
    }
    // 小于等于函数,利用 less 函数实现
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

struct cdouble_tag : complex_tag {
    // 定义类型为 npy_cdouble 的别名 type
    using type = npy_cdouble;
    // 设置 type_value 为 NPY_CDOUBLE
    static constexpr NPY_TYPES type_value = NPY_CDOUBLE;
    // 比较函数,比较 a 是否小于 b
    static int less(type const& a, type const& b) {
      return CDOUBLE_LT(a, b);
    }
    // 小于等于函数,利用 less 函数实现
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

struct clongdouble_tag : complex_tag {
    // 定义类型为 npy_clongdouble 的别名 type
    using type = npy_clongdouble;
    // 设置 type_value 为 NPY_CLONGDOUBLE
    static constexpr NPY_TYPES type_value = NPY_CLONGDOUBLE;
    // 比较函数,比较 a 是否小于 b
    static int less(type const& a, type const& b) {
      return CLONGDOUBLE_LT(a, b);
    }
    // 小于等于函数,利用 less 函数实现
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

struct datetime_tag : date_tag {
    // 定义类型为 npy_datetime 的别名 type
    using type = npy_datetime;
    // 设置 type_value 为 NPY_DATETIME
    static constexpr NPY_TYPES type_value = NPY_DATETIME;
    // 比较函数,比较 a 是否小于 b
    static int less(type const& a, type const& b) {
      return DATETIME_LT(a, b);
    }
    // 定义静态函数 `less_equal`,用于比较两个常量引用类型 `a` 和 `b`,检查是否 `a` 不小于等于 `b`
    static int less_equal(type const& a, type const& b) {
      // 返回 `b` 不小于 `a` 的结果取反的布尔值(即 `a` 是否不小于等于 `b`)
      return !less(b, a);
    }
};
// 结构体定义:timedelta_tag,继承自date_tag
struct timedelta_tag : date_tag {
    // 使用npy_timedelta作为类型
    using type = npy_timedelta;
    // 定义类型值为NPY_TIMEDELTA
    static constexpr NPY_TYPES type_value = NPY_TIMEDELTA;
    // 比较函数:比较两个类型为type的对象a和b是否满足a < b
    static int less(type const& a, type const& b) {
      return TIMEDELTA_LT(a, b);
    }
    // 比较函数:比较两个类型为type的对象a和b是否满足a <= b
    static int less_equal(type const& a, type const& b) {
      return !less(b, a);
    }
};

// 结构体定义:string_tag
struct string_tag {
    // 使用npy_char作为类型
    using type = npy_char;
    // 定义类型值为NPY_STRING
    static constexpr NPY_TYPES type_value = NPY_STRING;
    // 比较函数:比较两个类型为type*的对象a和b(长度为len)是否满足a < b
    static int less(type const* a, type const* b, size_t len) {
      return STRING_LT(a, b, len);
    }
    // 比较函数:比较两个类型为type*的对象a和b(长度为len)是否满足a <= b
    static int less_equal(type const* a, type const* b, size_t len) {
      return !less(b, a, len);
    }
    // 交换函数:交换两个类型为type*的对象a和b(长度为len)
    static void swap(type* a, type* b, size_t len) {
      STRING_SWAP(a, b, len);
    }
    // 复制函数:将类型为type*的对象b(长度为len)复制到a
    static void copy(type * a, type const* b, size_t len) {
      STRING_COPY(a, b, len);
    }
};

// 结构体定义:unicode_tag
struct unicode_tag {
    // 使用npy_ucs4作为类型
    using type = npy_ucs4;
    // 定义类型值为NPY_UNICODE
    static constexpr NPY_TYPES type_value = NPY_UNICODE;
    // 比较函数:比较两个类型为type*的对象a和b(长度为len)是否满足a < b
    static int less(type const* a, type const* b, size_t len) {
      return UNICODE_LT(a, b, len);
    }
    // 比较函数:比较两个类型为type*的对象a和b(长度为len)是否满足a <= b
    static int less_equal(type const* a, type const* b, size_t len) {
      return !less(b, a, len);
    }
    // 交换函数:交换两个类型为type*的对象a和b(长度为len)
    static void swap(type* a, type* b, size_t len) {
      UNICODE_SWAP(a, b, len);
    }
    // 复制函数:将类型为type*的对象b(长度为len)复制到a
    static void copy(type * a, type const* b, size_t len) {
      UNICODE_COPY(a, b, len);
    }
};

}  // namespace npy

#endif

.\numpy\numpy\_core\src\common\python_xerbla.c

/*
  From the original manpage:
  --------------------------
  XERBLA is an error handler for the LAPACK routines.
  It is called by an LAPACK routine if an input parameter has an invalid value.
  A message is printed and execution stops.

  Instead of printing a message and stopping the execution, a
  ValueError is raised with the message.

  Parameters:
  -----------
  srname: Subroutine name to use in error message, maximum six characters.
          Spaces at the end are skipped.
  info: Number of the invalid parameter.
*/

// 定义函数 BLAS_FUNC(xerbla),用于处理 LAPACK 函数的错误
CBLAS_INT BLAS_FUNC(xerbla)(char *srname, CBLAS_INT *info)
{
        static const char format[] = "On entry to %.*s" \
                " parameter number %d had an illegal value";
        char buf[sizeof(format) + 6 + 4];   /* 6 for name, 4 for param. num. */

        int len = 0; /* subroutine name 的长度 */
        PyGILState_STATE save;

        // 计算 subroutine name 的实际长度,跳过末尾的空格
        while( len<6 && srname[len]!='\0' )
                len++;
        while( len && srname[len-1]==' ' )
                len--;

        // 确保全局解释器锁(GIL)已获取
        save = PyGILState_Ensure();
        // 格式化错误信息并设置为 ValueError 异常的内容
        PyOS_snprintf(buf, sizeof(buf), format, len, srname, (int)*info);
        PyErr_SetString(PyExc_ValueError, buf);
        // 释放全局解释器锁(GIL)
        PyGILState_Release(save);

        // 返回 0 表示处理完成,无返回值
        return 0;
}

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

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

#ifndef _NPY_SIMD_AVX2_ARITHMETIC_H
#define _NPY_SIMD_AVX2_ARITHMETIC_H

#include "../sse/utils.h"
/***************************
 * Addition
 ***************************/
// 定义 AVX2 指令集下的非饱和加法操作宏
#define npyv_add_u8  _mm256_add_epi8
#define npyv_add_s8  _mm256_add_epi8
#define npyv_add_u16 _mm256_add_epi16
#define npyv_add_s16 _mm256_add_epi16
#define npyv_add_u32 _mm256_add_epi32
#define npyv_add_s32 _mm256_add_epi32
#define npyv_add_u64 _mm256_add_epi64
#define npyv_add_s64 _mm256_add_epi64
#define npyv_add_f32 _mm256_add_ps
#define npyv_add_f64 _mm256_add_pd

// 定义 AVX2 指令集下的饱和加法操作宏
#define npyv_adds_u8  _mm256_adds_epu8
#define npyv_adds_s8  _mm256_adds_epi8
#define npyv_adds_u16 _mm256_adds_epu16
#define npyv_adds_s16 _mm256_adds_epi16
// TODO: 其他类型待实现 Packs intrins

/***************************
 * Subtraction
 ***************************/
// 定义 AVX2 指令集下的非饱和减法操作宏
#define npyv_sub_u8  _mm256_sub_epi8
#define npyv_sub_s8  _mm256_sub_epi8
#define npyv_sub_u16 _mm256_sub_epi16
#define npyv_sub_s16 _mm256_sub_epi16
#define npyv_sub_u32 _mm256_sub_epi32
#define npyv_sub_s32 _mm256_sub_epi32
#define npyv_sub_u64 _mm256_sub_epi64
#define npyv_sub_s64 _mm256_sub_epi64
#define npyv_sub_f32 _mm256_sub_ps
#define npyv_sub_f64 _mm256_sub_pd

// 定义 AVX2 指令集下的饱和减法操作宏
#define npyv_subs_u8  _mm256_subs_epu8
#define npyv_subs_s8  _mm256_subs_epi8
#define npyv_subs_u16 _mm256_subs_epu16
#define npyv_subs_s16 _mm256_subs_epi16
// TODO: 其他类型待实现 Packs intrins

/***************************
 * Multiplication
 ***************************/
// 定义 AVX2 指令集下的非饱和乘法操作宏
#define npyv_mul_u8  npyv256_mul_u8
#define npyv_mul_s8  npyv_mul_u8
#define npyv_mul_u16 _mm256_mullo_epi16
#define npyv_mul_s16 _mm256_mullo_epi16
#define npyv_mul_u32 _mm256_mullo_epi32
#define npyv_mul_s32 _mm256_mullo_epi32
#define npyv_mul_f32 _mm256_mul_ps
#define npyv_mul_f64 _mm256_mul_pd

// 饱和乘法操作宏待实现 Packs intrins

/***************************
 * Integer Division
 ***************************/
// 查看 simd/intdiv.h 以获取更多细节
// 对每个无符号 8 位元素进行预计算的除法运算
NPY_FINLINE npyv_u8 npyv_divc_u8(npyv_u8 a, const npyv_u8x3 divisor)
{
    const __m256i bmask = _mm256_set1_epi32(0x00FF00FF);
    const __m128i shf1  = _mm256_castsi256_si128(divisor.val[1]);
    const __m128i shf2  = _mm256_castsi256_si128(divisor.val[2]);
    const __m256i shf1b = _mm256_set1_epi8(0xFFU >> _mm_cvtsi128_si32(shf1));
    const __m256i shf2b = _mm256_set1_epi8(0xFFU >> _mm_cvtsi128_si32(shf2));
    // 高位无符号乘法
    __m256i mulhi_even  = _mm256_mullo_epi16(_mm256_and_si256(a, bmask), divisor.val[0]);
            mulhi_even  = _mm256_srli_epi16(mulhi_even, 8);
    __m256i mulhi_odd   = _mm256_mullo_epi16(_mm256_srli_epi16(a, 8), divisor.val[0]);
    __m256i mulhi       = _mm256_blendv_epi8(mulhi_odd, mulhi_even, bmask);
    // floor(a/d)       = (mulhi + ((a-mulhi) >> sh1)) >> sh2
    # 使用 AVX2 指令集中的 _mm256_sub_epi8 函数计算向量 a 减去向量 mulhi 的每个元素差,存储在向量 q 中
    __m256i q = _mm256_sub_epi8(a, mulhi);
    # 对向量 q 中的每个元素执行右移 16 位操作,然后与 shf1 按位与,结果存储回向量 q
    q = _mm256_and_si256(_mm256_srl_epi16(q, shf1), shf1b);
    # 将向量 mulhi 与向量 q 中的每个元素相加,结果存储回向量 q
    q = _mm256_add_epi8(mulhi, q);
    # 对向量 q 中的每个元素执行右移 16 位操作,然后与 shf2 按位与,结果存储回向量 q
    q = _mm256_and_si256(_mm256_srl_epi16(q, shf2), shf2b);
    # 返回计算结果的向量 q
    return q;
// 使用 SIMD 指令集进行有符号 8 位元素除法,以预先计算的除数为基准(向零舍入)
NPY_FINLINE npyv_s16 npyv_divc_s16(npyv_s16 a, const npyv_s16x3 divisor);
// 使用 SIMD 指令集进行有符号 8 位元素除法,以预先计算的除数为基准
NPY_FINLINE npyv_s8 npyv_divc_s8(npyv_s8 a, const npyv_s8x3 divisor)
{
    // 创建一个掩码,用于混合选择不同的结果
    const __m256i bmask = _mm256_set1_epi32(0x00FF00FF);
    // 以特定方法处理溢出,而不是使用 _mm256_cvtepi8_epi16/_mm256_packs_epi16
    __m256i divc_even = npyv_divc_s16(_mm256_srai_epi16(_mm256_slli_epi16(a, 8), 8), divisor);
    __m256i divc_odd  = npyv_divc_s16(_mm256_srai_epi16(a, 8), divisor);
            divc_odd  = _mm256_slli_epi16(divc_odd, 8);
    // 根据掩码混合偶数和奇数位置的结果,返回最终结果
    return _mm256_blendv_epi8(divc_odd, divc_even, bmask);
}

// 使用 SIMD 指令集进行无符号 16 位元素除法,以预先计算的除数为基准
NPY_FINLINE npyv_u16 npyv_divc_u16(npyv_u16 a, const npyv_u16x3 divisor)
{
    // 从 divisor 中提取所需的移位操作数
    const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]);
    const __m128i shf2 = _mm256_castsi256_si128(divisor.val[2]);
    // 高位部分的无符号乘法
    __m256i mulhi      = _mm256_mulhi_epu16(a, divisor.val[0]);
    // 计算 floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
    __m256i q          = _mm256_sub_epi16(a, mulhi);
            q          = _mm256_srl_epi16(q, shf1);
            q          = _mm256_add_epi16(mulhi, q);
            q          = _mm256_srl_epi16(q, shf2);
    // 返回计算结果
    return q;
}

// 使用 SIMD 指令集进行有符号 16 位元素除法,以预先计算的除数为基准(向零舍入)
NPY_FINLINE npyv_s16 npyv_divc_s16(npyv_s16 a, const npyv_s16x3 divisor)
{
    // 从 divisor 中提取所需的移位操作数
    const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]);
    // 高位部分的有符号乘法
    __m256i mulhi      = _mm256_mulhi_epi16(a, divisor.val[0]);
    // 计算 trunc(a/d) = ((a + mulhi) >> sh1) - XSIGN(a)
    // 其中 XSIGN(a) 表示 a 的符号位扩展
    __m256i q          = _mm256_sra_epi16(_mm256_add_epi16(a, mulhi), shf1);
            q          = _mm256_sub_epi16(q, _mm256_srai_epi16(a, 15));
            q          = _mm256_sub_epi16(_mm256_xor_si256(q, divisor.val[2]), divisor.val[2]);
    // 返回计算结果
    return q;
}

// 使用 SIMD 指令集进行无符号 32 位元素除法,以预先计算的除数为基准
NPY_FINLINE npyv_u32 npyv_divc_u32(npyv_u32 a, const npyv_u32x3 divisor)
{
    // 从 divisor 中提取所需的移位操作数
    const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]);
    const __m128i shf2 = _mm256_castsi256_si128(divisor.val[2]);
    // 高位部分的无符号乘法
    __m256i mulhi_even = _mm256_srli_epi64(_mm256_mul_epu32(a, divisor.val[0]), 32);
    __m256i mulhi_odd  = _mm256_mul_epu32(_mm256_srli_epi64(a, 32), divisor.val[0]);
    __m256i mulhi      = _mm256_blend_epi32(mulhi_even, mulhi_odd, 0xAA);
    // 计算 floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
    __m256i q          = _mm256_sub_epi32(a, mulhi);
            q          = _mm256_srl_epi32(q, shf1);
            q          = _mm256_add_epi32(mulhi, q);
            q          = _mm256_srl_epi32(q, shf2);
    // 返回计算结果
    return q;
}
NPY_FINLINE npyv_s32 npyv_divc_s32(npyv_s32 a, const npyv_s32x3 divisor)
{
    // 提取除数结构体中的第二个成员作为移位掩码
    const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]);
    // 计算偶数位置的乘法高位
    __m256i mulhi_even = _mm256_srli_epi64(_mm256_mul_epi32(a, divisor.val[0]), 32);
    // 计算奇数位置的乘法高位
    __m256i mulhi_odd  = _mm256_mul_epi32(_mm256_srli_epi64(a, 32), divisor.val[0]);
    // 合并偶数和奇数位置的乘法高位
    __m256i mulhi      = _mm256_blend_epi32(mulhi_even, mulhi_odd, 0xAA);
    // 计算商 q = ((a + mulhi) >> sh1) - XSIGN(a)
    // 其中 XSIGN(a) 是 a 的符号扩展
    __m256i q          = _mm256_sra_epi32(_mm256_add_epi32(a, mulhi), shf1);
            q          = _mm256_sub_epi32(q, _mm256_srai_epi32(a, 31));
            q          = _mm256_sub_epi32(_mm256_xor_si256(q, divisor.val[2]), divisor.val[2]);
    return q;
}

// 返回无符号 64 位乘法的高 64 位结果
// 参考 https://stackoverflow.com/a/28827013
NPY_FINLINE npyv_u64 npyv__mullhi_u64(npyv_u64 a, npyv_u64 b)
{
    // 定义一个掩码,用于提取低 32 位
    __m256i lomask = npyv_setall_s64(0xffffffff);
    // 将 a 向右移动 32 位,得到高位部分
    __m256i a_hi   = _mm256_srli_epi64(a, 32);        // a0l, a0h, a1l, a1h
    // 将 b 向右移动 32 位,得到高位部分
    __m256i b_hi   = _mm256_srli_epi64(b, 32);        // b0l, b0h, b1l, b1h
    // 计算部分乘积
    __m256i w0     = _mm256_mul_epu32(a, b);          // a0l*b0l, a1l*b1l
    __m256i w1     = _mm256_mul_epu32(a, b_hi);       // a0l*b0h, a1l*b1h
    __m256i w2     = _mm256_mul_epu32(a_hi, b);       // a0h*b0l, a1h*b0l
    __m256i w3     = _mm256_mul_epu32(a_hi, b_hi);    // a0h*b0h, a1h*b1h
    // 求和部分乘积
    __m256i w0h    = _mm256_srli_epi64(w0, 32);
    __m256i s1     = _mm256_add_epi64(w1, w0h);
    __m256i s1l    = _mm256_and_si256(s1, lomask);
    __m256i s1h    = _mm256_srli_epi64(s1, 32);

    __m256i s2     = _mm256_add_epi64(w2, s1l);
    __m256i s2h    = _mm256_srli_epi64(s2, 32);

    __m256i hi     = _mm256_add_epi64(w3, s1h);
            hi     = _mm256_add_epi64(hi, s2h);
    return hi;
}

// 按除数逐个除每个无符号 64 位元素
NPY_FINLINE npyv_u64 npyv_divc_u64(npyv_u64 a, const npyv_u64x3 divisor)
{
    // 提取除数结构体中的第二个和第三个成员作为移位掩码
    const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]);
    const __m128i shf2 = _mm256_castsi256_si128(divisor.val[2]);
    // 计算无符号乘法的高位
    __m256i mulhi      = npyv__mullhi_u64(a, divisor.val[0]);
    // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
    __m256i q          = _mm256_sub_epi64(a, mulhi);
            q          = _mm256_srl_epi64(q, shf1);
            q          = _mm256_add_epi64(mulhi, q);
            q          = _mm256_srl_epi64(q, shf2);
    return q;
}

// 按除数逐个除每个有符号 64 位元素(向零舍入)
NPY_FINLINE npyv_s64 npyv_divc_s64(npyv_s64 a, const npyv_s64x3 divisor)
{
    // 提取除数结构体中的第二个成员作为移位掩码
    const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]);
    // 计算无符号乘法的高位
    __m256i mulhi      = npyv__mullhi_u64(a, divisor.val[0]);
    // 将无符号乘法结果转换为有符号数的高位乘法
    // 计算符号位向量,标识 a 和 divisor 的符号情况
    __m256i asign      = _mm256_cmpgt_epi64(_mm256_setzero_si256(), a);
    __m256i msign      = _mm256_cmpgt_epi64(_mm256_setzero_si256(), divisor.val[0]);

    // 计算 m_asign 和 a_msign,用于减去 mulhi 中相应的值
    __m256i m_asign    = _mm256_and_si256(divisor.val[0], asign);
    __m256i a_msign    = _mm256_and_si256(a, msign);

    // 减去 mulhi 中需要的值,以计算正确的 mulhi 值
    mulhi              = _mm256_sub_epi64(mulhi, m_asign);
    mulhi              = _mm256_sub_epi64(mulhi, a_msign);

    // 计算商 q,先加上 mulhi,再进行右移操作
    __m256i q          = _mm256_add_epi64(a, mulhi);
    const __m256i sigb = npyv_setall_s64(1LL << 63);  // 创建一个符号位的掩码
    q                  = _mm256_srl_epi64(_mm256_add_epi64(q, sigb), shf1);  // 模拟算术右移操作
    q                  = _mm256_sub_epi64(q, _mm256_srl_epi64(sigb, shf1));

    // 调整 q,使其正确表示除法的结果
    q                  = _mm256_sub_epi64(q, asign);  // 减去 a 的符号位
    q                  = _mm256_sub_epi64(_mm256_xor_si256(q, divisor.val[2]), divisor.val[2]);

    // 返回计算得到的商 q
    return q;
/***************************
 * Division
 ***************************/
// 定义单精度浮点数和双精度浮点数的向量除法指令
#define npyv_div_f32 _mm256_div_ps
#define npyv_div_f64 _mm256_div_pd

/***************************
 * FUSED
 ***************************/
#ifdef NPY_HAVE_FMA3
    // 使用 FMA3 指令集的乘加操作,a*b + c
    #define npyv_muladd_f32 _mm256_fmadd_ps
    #define npyv_muladd_f64 _mm256_fmadd_pd
    // 使用 FMA3 指令集的乘减操作,a*b - c
    #define npyv_mulsub_f32 _mm256_fmsub_ps
    #define npyv_mulsub_f64 _mm256_fmsub_pd
    // 使用 FMA3 指令集的负乘加操作,-(a*b) + c
    #define npyv_nmuladd_f32 _mm256_fnmadd_ps
    #define npyv_nmuladd_f64 _mm256_fnmadd_pd
    // 使用 FMA3 指令集的负乘减操作,-(a*b) - c
    #define npyv_nmulsub_f32 _mm256_fnmsub_ps
    #define npyv_nmulsub_f64 _mm256_fnmsub_pd
    // 使用 FMA3 指令集的乘加减混合操作,(a * b) -+ c
    #define npyv_muladdsub_f32 _mm256_fmaddsub_ps
    #define npyv_muladdsub_f64 _mm256_fmaddsub_pd
#else
    // 如果没有 FMA3 指令集,定义纯粹的乘加、乘减、负乘加、负乘减、乘加减混合操作
    // multiply and add, a*b + c
    NPY_FINLINE npyv_f32 npyv_muladd_f32(npyv_f32 a, npyv_f32 b, npyv_f32 c)
    { return npyv_add_f32(npyv_mul_f32(a, b), c); }
    NPY_FINLINE npyv_f64 npyv_muladd_f64(npyv_f64 a, npyv_f64 b, npyv_f64 c)
    { return npyv_add_f64(npyv_mul_f64(a, b), c); }
    // multiply and subtract, a*b - c
    NPY_FINLINE npyv_f32 npyv_mulsub_f32(npyv_f32 a, npyv_f32 b, npyv_f32 c)
    { return npyv_sub_f32(npyv_mul_f32(a, b), c); }
    NPY_FINLINE npyv_f64 npyv_mulsub_f64(npyv_f64 a, npyv_f64 b, npyv_f64 c)
    { return npyv_sub_f64(npyv_mul_f64(a, b), c); }
    // negate multiply and add, -(a*b) + c
    NPY_FINLINE npyv_f32 npyv_nmuladd_f32(npyv_f32 a, npyv_f32 b, npyv_f32 c)
    { return npyv_sub_f32(c, npyv_mul_f32(a, b)); }
    NPY_FINLINE npyv_f64 npyv_nmuladd_f64(npyv_f64 a, npyv_f64 b, npyv_f64 c)
    { return npyv_sub_f64(c, npyv_mul_f64(a, b)); }
    // negate multiply and subtract, -(a*b) - c
    NPY_FINLINE npyv_f32 npyv_nmulsub_f32(npyv_f32 a, npyv_f32 b, npyv_f32 c)
    {
        // 使用 XOR 指令对 a 取反
        npyv_f32 neg_a = npyv_xor_f32(a, npyv_setall_f32(-0.0f));
        return npyv_sub_f32(npyv_mul_f32(neg_a, b), c);
    }
    NPY_FINLINE npyv_f64 npyv_nmulsub_f64(npyv_f64 a, npyv_f64 b, npyv_f64 c)
    {
        // 使用 XOR 指令对 a 取反
        npyv_f64 neg_a = npyv_xor_f64(a, npyv_setall_f64(-0.0));
        return npyv_sub_f64(npyv_mul_f64(neg_a, b), c);
    }
    // multiply, add for odd elements and subtract even elements.
    // (a * b) -+ c
    NPY_FINLINE npyv_f32 npyv_muladdsub_f32(npyv_f32 a, npyv_f32 b, npyv_f32 c)
    { return _mm256_addsub_ps(npyv_mul_f32(a, b), c); }
    NPY_FINLINE npyv_f64 npyv_muladdsub_f64(npyv_f64 a, npyv_f64 b, npyv_f64 c)
    { return _mm256_addsub_pd(npyv_mul_f64(a, b), c); }

#endif // !NPY_HAVE_FMA3

/***************************
 * Summation
 ***************************/
// 对向量进行求和操作
// reduce sum across vector
NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
{
    // 对向量 a 进行两次横向加法操作
    __m256i s0 = _mm256_hadd_epi32(a, a);
    s0 = _mm256_hadd_epi32(s0, s0);
    // 从一个 256 位的寄存器 s0 中提取第二个 128 位子寄存器 s1
    __m128i s1 = _mm256_extracti128_si256(s0, 1);
    // 将 s0 的低 128 位子寄存器与 s1 相加,并将结果存储回 s1
    s1 = _mm_add_epi32(_mm256_castsi256_si128(s0), s1);
    // 将 s1 转换为一个整数,并返回结果
    return _mm_cvtsi128_si32(s1);
// 定义一个内联函数,计算无符号64位整数向量的总和
NPY_FINLINE npy_uint64 npyv_sum_u64(npyv_u64 a)
{
    // 创建一个256位整数向量,将a和a的逆序排列相加
    __m256i two = _mm256_add_epi64(a, _mm256_shuffle_epi32(a, _MM_SHUFFLE(1, 0, 3, 2)));
    // 将256位整数向量two的低128位转换为128位整数向量one,并加上其高128位
    __m128i one = _mm_add_epi64(_mm256_castsi256_si128(two), _mm256_extracti128_si256(two, 1));
    // 将128位整数向量one转换为64位无符号整数并返回
    return (npy_uint64)npyv128_cvtsi128_si64(one);
}

// 定义一个内联函数,计算单精度浮点向量的总和
NPY_FINLINE float npyv_sum_f32(npyv_f32 a)
{
    // 对256位单精度浮点向量a进行水平加法
    __m256 sum_halves = _mm256_hadd_ps(a, a);
    sum_halves = _mm256_hadd_ps(sum_halves, sum_halves);
    // 将256位浮点向量sum_halves拆分为两个128位向量lo和hi,并将它们相加
    __m128 lo = _mm256_castps256_ps128(sum_halves);
    __m128 hi = _mm256_extractf128_ps(sum_halves, 1);
    __m128 sum = _mm_add_ps(lo, hi);
    // 返回128位向量sum中的单精度浮点数
    return _mm_cvtss_f32(sum);
}

// 定义一个内联函数,计算双精度浮点向量的总和
NPY_FINLINE double npyv_sum_f64(npyv_f64 a)
{
    // 对256位双精度浮点向量a进行水平加法
    __m256d sum_halves = _mm256_hadd_pd(a, a);
    // 将256位双精度向量sum_halves拆分为两个128位向量lo和hi,并将它们相加
    __m128d lo = _mm256_castpd256_pd128(sum_halves);
    __m128d hi = _mm256_extractf128_pd(sum_halves, 1);
    __m128d sum = _mm_add_pd(lo, hi);
    // 返回128位向量sum中的双精度浮点数
    return _mm_cvtsd_f64(sum);
}

// 定义一个内联函数,对无符号8位整数向量进行求和累加
// 使用256位整数向量a计算无符号16位整数的累加和
NPY_FINLINE npy_uint16 npyv_sumup_u8(npyv_u8 a)
{
    // 使用256位整数向量a计算无符号8位整数的累加和,存储到256位整数向量four
    __m256i four = _mm256_sad_epu8(a, _mm256_setzero_si256());
    // 将256位整数向量four拆分为两个128位整数向量,然后进行累加
    __m128i two  = _mm_add_epi16(_mm256_castsi256_si128(four), _mm256_extracti128_si256(four, 1));
    __m128i one  = _mm_add_epi16(two, _mm_unpackhi_epi64(two, two));
    // 将128位整数向量one转换为16位无符号整数并返回
    return (npy_uint16)_mm_cvtsi128_si32(one);
}

// 定义一个内联函数,对无符号16位整数向量进行求和累加
NPY_FINLINE npy_uint32 npyv_sumup_u16(npyv_u16 a)
{
    // 创建一个常量掩码,用于提取偶数位
    const npyv_u16 even_mask = _mm256_set1_epi32(0x0000FFFF);
    // 使用256位整数向量a按位与掩码,得到偶数位
    __m256i even  = _mm256_and_si256(a, even_mask);
    // 将256位整数向量a右移16位,得到奇数位
    __m256i odd   = _mm256_srli_epi32(a, 16);
    // 将偶数位和奇数位相加得到累加和,并返回
    __m256i eight = _mm256_add_epi32(even, odd);
    return npyv_sum_u32(eight);
}

#endif // _NPY_SIMD_AVX2_ARITHMETIC_H

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

#ifndef _NPY_SIMD_H_
    #error "Not a standalone header"
#endif
// 宏定义,确保本文件不会被直接包含,必须作为其他文件的一部分
#define NPY_SIMD 256
// SIMD 宽度为 256 比特
#define NPY_SIMD_WIDTH 32
// SIMD 支持单精度浮点数
#define NPY_SIMD_F32 1
// SIMD 支持双精度浮点数
#define NPY_SIMD_F64 1
#ifdef NPY_HAVE_FMA3
    #define NPY_SIMD_FMA3 1 // native support
#else
    #define NPY_SIMD_FMA3 0 // fast emulated
#endif
// SIMD 不使用大端序
#define NPY_SIMD_BIGENDIAN 0
// SIMD 不支持比较信号
#define NPY_SIMD_CMPSIGNAL 0
// 允许的最大加载步长,用于支持 _mm256_i32gather_*
// 这里的计算基于 32 字节步长的限制
#define NPY_SIMD_MAXLOAD_STRIDE32 (0x7fffffff / 8)

typedef __m256i npyv_u8;
typedef __m256i npyv_s8;
typedef __m256i npyv_u16;
typedef __m256i npyv_s16;
typedef __m256i npyv_u32;
typedef __m256i npyv_s32;
typedef __m256i npyv_u64;
typedef __m256i npyv_s64;
typedef __m256  npyv_f32;
typedef __m256d npyv_f64;

typedef __m256i npyv_b8;
typedef __m256i npyv_b16;
typedef __m256i npyv_b32;
typedef __m256i npyv_b64;

typedef struct { __m256i val[2]; } npyv_m256ix2;
typedef npyv_m256ix2 npyv_u8x2;
typedef npyv_m256ix2 npyv_s8x2;
typedef npyv_m256ix2 npyv_u16x2;
typedef npyv_m256ix2 npyv_s16x2;
typedef npyv_m256ix2 npyv_u32x2;
typedef npyv_m256ix2 npyv_s32x2;
typedef npyv_m256ix2 npyv_u64x2;
typedef npyv_m256ix2 npyv_s64x2;

typedef struct { __m256i val[3]; } npyv_m256ix3;
typedef npyv_m256ix3 npyv_u8x3;
typedef npyv_m256ix3 npyv_s8x3;
typedef npyv_m256ix3 npyv_u16x3;
typedef npyv_m256ix3 npyv_s16x3;
typedef npyv_m256ix3 npyv_u32x3;
typedef npyv_m256ix3 npyv_s32x3;
typedef npyv_m256ix3 npyv_u64x3;
typedef npyv_m256ix3 npyv_s64x3;

typedef struct { __m256  val[2]; } npyv_f32x2;
typedef struct { __m256d val[2]; } npyv_f64x2;
typedef struct { __m256  val[3]; } npyv_f32x3;
typedef struct { __m256d val[3]; } npyv_f64x3;

// 定义各类型的 SIMD 矢量的元素数
#define npyv_nlanes_u8  32
#define npyv_nlanes_s8  32
#define npyv_nlanes_u16 16
#define npyv_nlanes_s16 16
#define npyv_nlanes_u32 8
#define npyv_nlanes_s32 8
#define npyv_nlanes_u64 4
#define npyv_nlanes_s64 4
#define npyv_nlanes_f32 8
#define npyv_nlanes_f64 4

#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\avx2\conversion.h

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

#ifndef _NPY_SIMD_AVX2_CVT_H
#define _NPY_SIMD_AVX2_CVT_H

// 将掩码类型转换为整数类型
#define npyv_cvt_u8_b8(A)   A
#define npyv_cvt_s8_b8(A)   A
#define npyv_cvt_u16_b16(A) A
#define npyv_cvt_s16_b16(A) A
#define npyv_cvt_u32_b32(A) A
#define npyv_cvt_s32_b32(A) A
#define npyv_cvt_u64_b64(A) A
#define npyv_cvt_s64_b64(A) A
#define npyv_cvt_f32_b32 _mm256_castsi256_ps
#define npyv_cvt_f64_b64 _mm256_castsi256_pd

// 将整数类型转换为掩码类型
#define npyv_cvt_b8_u8(BL)   BL
#define npyv_cvt_b8_s8(BL)   BL
#define npyv_cvt_b16_u16(BL) BL
#define npyv_cvt_b16_s16(BL) BL
#define npyv_cvt_b32_u32(BL) BL
#define npyv_cvt_b32_s32(BL) BL
#define npyv_cvt_b64_u64(BL) BL
#define npyv_cvt_b64_s64(BL) BL
#define npyv_cvt_b32_f32 _mm256_castps_si256
#define npyv_cvt_b64_f64 _mm256_castpd_si256

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

NPY_FINLINE npy_uint64 npyv_tobits_b16(npyv_b16 a)
{
    // 将两个 16 位布尔向量打包成一个 8 位布尔向量
    __m128i pack = _mm_packs_epi16(_mm256_castsi256_si128(a), _mm256_extracti128_si256(a, 1));
    return (npy_uint16)_mm_movemask_epi8(pack);
}
NPY_FINLINE npy_uint64 npyv_tobits_b32(npyv_b32 a)
{ return (npy_uint8)_mm256_movemask_ps(_mm256_castsi256_ps(a)); }
NPY_FINLINE npy_uint64 npyv_tobits_b64(npyv_b64 a)
{ return (npy_uint8)_mm256_movemask_pd(_mm256_castsi256_pd(a)); }

// 将 8 位无符号整数向量扩展为两个 16 位无符号整数向量
NPY_FINLINE npyv_u16x2 npyv_expand_u16_u8(npyv_u8 data) {
    npyv_u16x2 r;
    r.val[0] = _mm256_cvtepu8_epi16(_mm256_castsi256_si128(data));
    r.val[1] = _mm256_cvtepu8_epi16(_mm256_extracti128_si256(data, 1));
    return r;
}

// 将 16 位无符号整数向量扩展为两个 32 位无符号整数向量
NPY_FINLINE npyv_u32x2 npyv_expand_u32_u16(npyv_u16 data) {
    npyv_u32x2 r;
    r.val[0] = _mm256_cvtepu16_epi32(_mm256_castsi256_si128(data));
    r.val[1] = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(data, 1));
    return r;
}

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

// 将四个 32 位布尔向量打包成一个 8 位布尔向量
NPY_FINLINE npyv_b8
npyv_pack_b8_b32(npyv_b32 a, npyv_b32 b, npyv_b32 c, npyv_b32 d) {
    __m256i ab = _mm256_packs_epi32(a, b);
    __m256i cd = _mm256_packs_epi32(c, d);
    __m256i abcd = npyv_pack_b8_b16(ab, cd);
    return _mm256_shuffle_epi32(abcd, _MM_SHUFFLE(3, 1, 2, 0));
}

// 将八个 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) {
    __m256i ab = _mm256_packs_epi32(a, b);
    __m256i cd = _mm256_packs_epi32(c, d);
    __m256i ef = _mm256_packs_epi32(e, f);
    __m256i gh = _mm256_packs_epi32(g, h);
    __m256i abcd = _mm256_packs_epi32(ab, cd);
    __m256i efgh = _mm256_packs_epi32(ef, gh);
    # 使用 npyv256_shuffle_odd 函数对 abcd 和 efgh 进行奇数位置元素的重新排列,并将结果打包为 16 位整数
    __m256i all  = npyv256_shuffle_odd(_mm256_packs_epi16(abcd, efgh));
    
    # 使用 _mm256_alignr_epi8 函数从 all 中提取后 128 位,并将其作为新的 all,实现向右移动 8 个字节
    __m256i rev128 = _mm256_alignr_epi8(all, all, 8);
    
    # 使用 _mm256_unpacklo_epi16 函数从 all 和 rev128 中解压低位的 16 位整数并返回结果
    return _mm256_unpacklo_epi16(all, rev128);
// 结束宏定义部分

// 定义将双精度浮点数向最接近的整数四舍五入(假设四舍六入五成双)的函数,返回整型向量
#define npyv_round_s32_f32 _mm256_cvtps_epi32

// 对双精度浮点数向量进行四舍五入转换为32位有符号整数向量的函数
NPY_FINLINE npyv_s32 npyv_round_s32_f64(npyv_f64 a, npyv_f64 b)
{
    // 将 a 和 b 各自转换为128位整数向量
    __m128i lo = _mm256_cvtpd_epi32(a), hi = _mm256_cvtpd_epi32(b);
    // 将 lo 和 hi 合并成256位整数向量,lo 在低128位,hi 在高128return _mm256_inserti128_si256(_mm256_castsi128_si256(lo), hi, 1);
}

// 结束条件编译指令
#endif // _NPY_SIMD_AVX2_CVT_H

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

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

#ifndef _NPY_SIMD_AVX2_MATH_H
#define _NPY_SIMD_AVX2_MATH_H
/***************************
 * Elementary
 ***************************/
// 平方根函数定义为 AVX2 指令集的平方根计算函数
#define npyv_sqrt_f32 _mm256_sqrt_ps
#define npyv_sqrt_f64 _mm256_sqrt_pd

// 倒数函数,对单精度浮点数向量进行定义
NPY_FINLINE npyv_f32 npyv_recip_f32(npyv_f32 a)
{ return _mm256_div_ps(_mm256_set1_ps(1.0f), a); }
// 倒数函数,对双精度浮点数向量进行定义
NPY_FINLINE npyv_f64 npyv_recip_f64(npyv_f64 a)
{ return _mm256_div_pd(_mm256_set1_pd(1.0), a); }

// 绝对值函数,对单精度浮点数向量进行定义
NPY_FINLINE npyv_f32 npyv_abs_f32(npyv_f32 a)
{
    return _mm256_and_ps(
        a, _mm256_castsi256_ps(_mm256_set1_epi32(0x7fffffff))
    );
}
// 绝对值函数,对双精度浮点数向量进行定义
NPY_FINLINE npyv_f64 npyv_abs_f64(npyv_f64 a)
{
    return _mm256_and_pd(
        a, _mm256_castsi256_pd(npyv_setall_s64(0x7fffffffffffffffLL))
    );
}

// 平方函数,对单精度浮点数向量进行定义
NPY_FINLINE npyv_f32 npyv_square_f32(npyv_f32 a)
{ return _mm256_mul_ps(a, a); }
// 平方函数,对双精度浮点数向量进行定义
NPY_FINLINE npyv_f64 npyv_square_f64(npyv_f64 a)
{ return _mm256_mul_pd(a, a); }

// 最大值函数,直接映射为 AVX2 指令集的最大值函数,不保证处理 NaN
#define npyv_max_f32 _mm256_max_ps
#define npyv_max_f64 _mm256_max_pd
// 最大值函数,支持 IEEE 浮点数算术(IEC 60559)
// - 如果其中一个向量包含 NaN,则将另一个向量对应元素设置为 NaN
// - 仅当对应的两个元素都是 NaN 时,才设置 NaN
NPY_FINLINE npyv_f32 npyv_maxp_f32(npyv_f32 a, npyv_f32 b)
{
    __m256 nn  = _mm256_cmp_ps(b, b, _CMP_ORD_Q);
    __m256 max = _mm256_max_ps(a, b);
    return _mm256_blendv_ps(a, max, nn);
}
NPY_FINLINE npyv_f64 npyv_maxp_f64(npyv_f64 a, npyv_f64 b)
{
    __m256d nn  = _mm256_cmp_pd(b, b, _CMP_ORD_Q);
    __m256d max = _mm256_max_pd(a, b);
    return _mm256_blendv_pd(a, max, nn);
}
// 最大值函数,传播 NaN
// 如果任何对应元素是 NaN,则设置 NaN
NPY_FINLINE npyv_f32 npyv_maxn_f32(npyv_f32 a, npyv_f32 b)
{
    __m256 nn  = _mm256_cmp_ps(a, a, _CMP_ORD_Q);
    __m256 max = _mm256_max_ps(a, b);
    return _mm256_blendv_ps(a, max, nn);
}
NPY_FINLINE npyv_f64 npyv_maxn_f64(npyv_f64 a, npyv_f64 b)
{
    __m256d nn  = _mm256_cmp_pd(a, a, _CMP_ORD_Q);
    __m256d max = _mm256_max_pd(a, b);
    return _mm256_blendv_pd(a, max, nn);
}

// 最大值函数,整数操作
#define npyv_max_u8 _mm256_max_epu8
#define npyv_max_s8 _mm256_max_epi8
#define npyv_max_u16 _mm256_max_epu16
#define npyv_max_s16 _mm256_max_epi16
#define npyv_max_u32 _mm256_max_epu32
#define npyv_max_s32 _mm256_max_epi32
// 对于无符号 64 位整数,定义最大值函数
NPY_FINLINE npyv_u64 npyv_max_u64(npyv_u64 a, npyv_u64 b)
{
    return _mm256_blendv_epi8(b, a, npyv_cmpgt_u64(a, b));
}
// 对于有符号 64 位整数,定义最大值函数
NPY_FINLINE npyv_s64 npyv_max_s64(npyv_s64 a, npyv_s64 b)
{
    return _mm256_blendv_epi8(b, a, _mm256_cmpgt_epi64(a, b));
}

// 最小值函数,直接映射为 AVX2 指令集的最小值函数,不保证处理 NaN
#define npyv_min_f32 _mm256_min_ps
#define npyv_min_f64 _mm256_min_pd
// 最小值函数,支持 IEEE 浮点数算术(IEC 60559)
// - 如果其中一个向量包含 NaN,则将另一个向量对应元素设置为 NaN
// 返回两个 __m256 向量中对应元素的最小值,如果元素对应位置其中一个为 NaN,则结果也是 NaN
NPY_FINLINE npyv_f32 npyv_minp_f32(npyv_f32 a, npyv_f32 b)
{
    // 检查向量 b 中的元素是否为有序(非 NaN)
    __m256 nn  = _mm256_cmp_ps(b, b, _CMP_ORD_Q);
    // 计算两个向量对应元素的最小值
    __m256 min = _mm256_min_ps(a, b);
    // 根据 nn 向量的结果进行选择,如果对应位置 b 的元素为 NaN,则选择 a 中的元素
    return _mm256_blendv_ps(a, min, nn);
}

// 返回两个 __m256d 向量中对应元素的最小值,如果元素对应位置其中一个为 NaN,则结果也是 NaN
NPY_FINLINE npyv_f64 npyv_minp_f64(npyv_f64 a, npyv_f64 b)
{
    // 检查向量 b 中的元素是否为有序(非 NaN)
    __m256d nn  = _mm256_cmp_pd(b, b, _CMP_ORD_Q);
    // 计算两个向量对应元素的最小值
    __m256d min = _mm256_min_pd(a, b);
    // 根据 nn 向量的结果进行选择,如果对应位置 b 的元素为 NaN,则选择 a 中的元素
    return _mm256_blendv_pd(a, min, nn);
}

// 返回两个 __m256 向量中对应元素的最小值,如果任一对应位置元素为 NaN,则结果也是 NaN
NPY_FINLINE npyv_f32 npyv_minn_f32(npyv_f32 a, npyv_f32 b)
{
    // 检查向量 a 中的元素是否为有序(非 NaN)
    __m256 nn  = _mm256_cmp_ps(a, a, _CMP_ORD_Q);
    // 计算两个向量对应元素的最小值
    __m256 min = _mm256_min_ps(a, b);
    // 根据 nn 向量的结果进行选择,如果对应位置 a 的元素为 NaN,则选择 b 中的元素
    return _mm256_blendv_ps(a, min, nn);
}

// 返回两个 __m256d 向量中对应元素的最小值,如果任一对应位置元素为 NaN,则结果也是 NaN
NPY_FINLINE npyv_f64 npyv_minn_f64(npyv_f64 a, npyv_f64 b)
{
    // 检查向量 a 中的元素是否为有序(非 NaN)
    __m256d nn  = _mm256_cmp_pd(a, a, _CMP_ORD_Q);
    // 计算两个向量对应元素的最小值
    __m256d min = _mm256_min_pd(a, b);
    // 根据 nn 向量的结果进行选择,如果对应位置 a 的元素为 NaN,则选择 b 中的元素
    return _mm256_blendv_pd(a, min, nn);
}

// 返回两个 __m256i 向量中对应元素的最小值,用于无符号 64 位整数
NPY_FINLINE npyv_u64 npyv_min_u64(npyv_u64 a, npyv_u64 b)
{
    // 使用 npyv_cmplt_u64 函数比较 a 和 b 的元素,生成选择向量,选择较小的元素
    return _mm256_blendv_epi8(b, a, npyv_cmplt_u64(a, b));
}

// 返回两个 __m256i 向量中对应元素的最小值,用于有符号 64 位整数
NPY_FINLINE npyv_s64 npyv_min_s64(npyv_s64 a, npyv_s64 b)
{
    // 使用 _mm256_cmpgt_epi64 函数比较 a 和 b 的元素,生成选择向量,选择较小的元素
    return _mm256_blendv_epi8(a, b, _mm256_cmpgt_epi64(a, b));
}

// 实现 AVX2 指令集下的最小值和最大值归约操作,用于 32 位和 64 位数据类型
#define NPY_IMPL_AVX2_REDUCE_MINMAX(STYPE, INTRIN, VINTRIN)                                              \
    NPY_FINLINE STYPE##32 npyv_reduce_##INTRIN##32(__m256i a)                                            \
    {                                                                                                    \
        // 将 __m256i 向量 a 转换为 __m128i 向量 v128,并且将两个 128 位块进行指定方式合并
        __m128i v128 = _mm_##VINTRIN##32(_mm256_castsi256_si128(a), _mm256_extracti128_si256(a, 1));     \
        // 继续归约到 64 位块
        __m128i v64 =  _mm_##VINTRIN##32(v128, _mm_shuffle_epi32(v128, _MM_SHUFFLE(0, 0, 3, 2)));        \
        // 继续归约到 32 位块
        __m128i v32 = _mm_##VINTRIN##32(v64, _mm_shuffle_epi32(v64, _MM_SHUFFLE(0, 0, 0, 1)));           \
        // 将结果转换为 32 位整数
        return (STYPE##32)_mm_cvtsi128_si32(v32);                                                        \
    }                                                                                                    \
    NPY_FINLINE STYPE##64 npyv_reduce_##INTRIN##64(__m256i a)                                            \
    {                                                                                                    \
        // 使用 npyv_##INTRIN##64 函数将 a 向量与自身进行指定方式合并
        __m256i v128 = npyv_##INTRIN##64(a, _mm256_permute2f128_si256(a, a, _MM_SHUFFLE(0, 0, 0, 1)));   \
        // 进行 64 位块的归约操作
        __m256i v64  = npyv_##INTRIN##64(v128, _mm256_shuffle_epi32(v128, _MM_SHUFFLE(0, 0, 3, 2)));     \
        // 提取归约结果中的第一个 64 位无符号整数
        return (STYPE##64)npyv_extract0_u64(v64);                                                        \
    }
// 定义 AVX2 指令集下的最小值归约操作宏,支持无符号和有符号 32 位整数
NPY_IMPL_AVX2_REDUCE_MINMAX(npy_uint, min_u, min_epu)
// 定义 AVX2 指令集下的最小值归约操作宏,支持无符号和有符号 64 位整数
NPY_IMPL_AVX2_REDUCE_MINMAX(npy_int,  min_s, min_epi)
# 定义 AVX2 指令集下的最小值和最大值归约操作宏,针对无符号整数类型
NPY_IMPL_AVX2_REDUCE_MINMAX(npy_uint, max_u, max_epu)

# 定义 AVX2 指令集下的最小值和最大值归约操作宏,针对有符号整数类型
NPY_IMPL_AVX2_REDUCE_MINMAX(npy_int, max_s, max_epi)

# 取消之前定义的 AVX2 指令集下的最小值和最大值归约操作宏
#undef NPY_IMPL_AVX2_REDUCE_MINMAX

# 定义 AVX2 指令集下的最小值和最大值归约操作宏,用于单精度浮点数和双精度浮点数
#define NPY_IMPL_AVX2_REDUCE_MINMAX(INTRIN, INF, INF64)                                              \
    # 定义单精度浮点数的归约函数,将 AVX2 矢量中的四个 float 值降维到一个 float 值
    NPY_FINLINE float npyv_reduce_##INTRIN##_f32(npyv_f32 a)                                         \
    {                                                                                                \
        # 提取 AVX2 矢量的低128位和高128位,执行指定的最小值或最大值归约操作
        __m128 v128 = _mm_##INTRIN##_ps(_mm256_castps256_ps128(a), _mm256_extractf128_ps(a, 1));     \
        # 对结果继续归约,取得最终的 float 值
        __m128 v64 =  _mm_##INTRIN##_ps(v128, _mm_shuffle_ps(v128, v128, _MM_SHUFFLE(0, 0, 3, 2)));  \
        __m128 v32 = _mm_##INTRIN##_ps(v64, _mm_shuffle_ps(v64, v64, _MM_SHUFFLE(0, 0, 0, 1)));      \
        return _mm_cvtss_f32(v32);                                                                   \
    }                                                                                                \
    # 定义双精度浮点数的归约函数,将 AVX2 矢量中的四个 double 值降维到一个 double 值
    NPY_FINLINE double npyv_reduce_##INTRIN##_f64(npyv_f64 a)                                        \
    {                                                                                                \
        # 提取 AVX2 矢量的低128位和高128位,执行指定的最小值或最大值归约操作
        __m128d v128 = _mm_##INTRIN##_pd(_mm256_castpd256_pd128(a), _mm256_extractf128_pd(a, 1));    \
        # 对结果继续归约,取得最终的 double 值
        __m128d v64 =  _mm_##INTRIN##_pd(v128, _mm_shuffle_pd(v128, v128, _MM_SHUFFLE(0, 0, 0, 1))); \
        return _mm_cvtsd_f64(v64);                                                                   \
    }                                                                                                \
    # 定义单精度浮点数的条件归约函数,处理 NaN 值的情况
    NPY_FINLINE float npyv_reduce_##INTRIN##p_f32(npyv_f32 a)                                        \
    {                                                                                                \
        # 判断是否存在非 NaN 的元素
        npyv_b32 notnan = npyv_notnan_f32(a);                                                        \
        if (NPY_UNLIKELY(!npyv_any_b32(notnan))) {                                                   \
            # 若不存在非 NaN 元素,则直接返回矢量的第一个 float 值
            return _mm_cvtss_f32(_mm256_castps256_ps128(a));                                         \
        }                                                                                            \
        # 选取非 NaN 元素,若不存在非 NaN 元素,则使用指定的 INF 值
        a = npyv_select_f32(notnan, a, npyv_reinterpret_f32_u32(npyv_setall_u32(INF)));              \
        # 对选取的值执行最小值或最大值归约操作
        return npyv_reduce_##INTRIN##_f32(a);                                                        \
    }                                                                                                \
    # 定义双精度浮点数的条件归约函数,处理 NaN 值的情况
    NPY_FINLINE double npyv_reduce_##INTRIN##p_f64(npyv_f64 a)                                       \
    {                                                                                                \
        npyv_b64 notnan = npyv_notnan_f64(a);                                                        \  // 检查双精度浮点向量a中的每个元素是否不是NaN
        if (NPY_UNLIKELY(!npyv_any_b64(notnan))) {                                                   \  // 如果向量a中没有任何元素不是NaN,则执行以下操作
            return _mm_cvtsd_f64(_mm256_castpd256_pd128(a));                                         \  // 将AVX双精度向量a转换为128位SIMD寄存器后取其低64位转换为标量返回
        }                                                                                            \
        a = npyv_select_f64(notnan, a, npyv_reinterpret_f64_u64(npyv_setall_u64(INF64)));            \  // 根据notnan向量选择a中不是NaN的元素,将NaN元素替换为正无穷大(INF64)
        return npyv_reduce_##INTRIN##_f64(a);                                                        \  // 调用指定指令集的双精度浮点向量a的规约函数,并返回结果
    }                                                                                                \
    NPY_FINLINE float npyv_reduce_##INTRIN##n_f32(npyv_f32 a)                                        \  // 使用指定指令集INTRIN对浮点向量a进行规约的函数定义
    {                                                                                                \
        npyv_b32 notnan = npyv_notnan_f32(a);                                                        \  // 检查单精度浮点向量a中的每个元素是否不是NaN
        if (NPY_UNLIKELY(!npyv_all_b32(notnan))) {                                                   \  // 如果向量a中存在任何NaN元素,则执行以下操作
            const union { npy_uint32 i; float f;} pnan = {0x7fc00000UL};                             \  // 创建一个union将NaN表示为单精度浮点数的结构
            return pnan.f;                                                                           \  // 返回NaN作为单精度浮点数
        }                                                                                            \
        return npyv_reduce_##INTRIN##_f32(a);                                                        \  // 调用指定指令集的单精度浮点向量a的规约函数,并返回结果
    }                                                                                                \
    NPY_FINLINE double npyv_reduce_##INTRIN##n_f64(npyv_f64 a)                                       \  // 使用指定指令集INTRIN对双精度浮点向量a进行规约的函数定义
    {                                                                                                \
        npyv_b64 notnan = npyv_notnan_f64(a);                                                        \  // 检查双精度浮点向量a中的每个元素是否不是NaN
        if (NPY_UNLIKELY(!npyv_all_b64(notnan))) {                                                   \  // 如果向量a中存在任何NaN元素,则执行以下操作
            const union { npy_uint64 i; double d;} pnan = {0x7ff8000000000000ull};                   \  // 创建一个union将NaN表示为双精度浮点数的结构
            return pnan.d;                                                                           \  // 返回NaN作为双精度浮点数
        }                                                                                            \
        return npyv_reduce_##INTRIN##_f64(a);                                                        \  // 调用指定指令集的双精度浮点向量a的规约函数,并返回结果
    }
// 定义 AVX2 指令集下的最小值和最大值函数,用于处理特定浮点数的边界值
NPY_IMPL_AVX2_REDUCE_MINMAX(min, 0x7f800000, 0x7ff0000000000000)
NPY_IMPL_AVX2_REDUCE_MINMAX(max, 0xff800000, 0xfff0000000000000)
// 取消定义 NPY_IMPL_AVX2_REDUCE_MINMAX 宏,结束对 AVX2 指令集下最小值和最大值函数的定义

// 定义 AVX256 指令集下的函数,用于对 8 位和 16 位整数执行最小值和最大值的归约操作
#define NPY_IMPL_AVX256_REDUCE_MINMAX(STYPE, INTRIN, VINTRIN)                                        \
    // 归约 16 位整数数组的最小值或最大值
    NPY_FINLINE STYPE##16 npyv_reduce_##INTRIN##16(__m256i a)                                        \
    {                                                                                                \
        __m128i v128 = _mm_##VINTRIN##16(_mm256_castsi256_si128(a), _mm256_extracti128_si256(a, 1)); \
        __m128i v64 =  _mm_##VINTRIN##16(v128, _mm_shuffle_epi32(v128, _MM_SHUFFLE(0, 0, 3, 2)));    \
        __m128i v32 = _mm_##VINTRIN##16(v64, _mm_shuffle_epi32(v64, _MM_SHUFFLE(0, 0, 0, 1)));       \
        __m128i v16 = _mm_##VINTRIN##16(v32, _mm_shufflelo_epi16(v32, _MM_SHUFFLE(0, 0, 0, 1)));     \
        return (STYPE##16)_mm_cvtsi128_si32(v16);                                                    \
    }                                                                                                \
    // 归约 8 位整数数组的最小值或最大值
    NPY_FINLINE STYPE##8 npyv_reduce_##INTRIN##8(__m256i a)                                          \
    {                                                                                                \
        __m128i v128 = _mm_##VINTRIN##8(_mm256_castsi256_si128(a), _mm256_extracti128_si256(a, 1));  \
        __m128i v64 =  _mm_##VINTRIN##8(v128, _mm_shuffle_epi32(v128, _MM_SHUFFLE(0, 0, 3, 2)));     \
        __m128i v32 = _mm_##VINTRIN##8(v64, _mm_shuffle_epi32(v64, _MM_SHUFFLE(0, 0, 0, 1)));        \
        __m128i v16 = _mm_##VINTRIN##8(v32, _mm_shufflelo_epi16(v32, _MM_SHUFFLE(0, 0, 0, 1)));      \
        __m128i v8 = _mm_##VINTRIN##8(v16, _mm_srli_epi16(v16, 8));                                  \
        return (STYPE##16)_mm_cvtsi128_si32(v8);                                                     \
    }
// 定义 AVX256 指令集下的最小值和最大值函数,针对无符号整数和有符号整数
NPY_IMPL_AVX256_REDUCE_MINMAX(npy_uint, min_u, min_epu)
NPY_IMPL_AVX256_REDUCE_MINMAX(npy_int,  min_s, min_epi)
NPY_IMPL_AVX256_REDUCE_MINMAX(npy_uint, max_u, max_epu)
NPY_IMPL_AVX256_REDUCE_MINMAX(npy_int,  max_s, max_epi)
// 取消定义 NPY_IMPL_AVX256_REDUCE_MINMAX 宏,结束对 AVX256 指令集下最小值和最大值函数的定义

// 定义对浮点数进行四舍五入到最近偶数的宏
#define npyv_rint_f32(A) _mm256_round_ps(A, _MM_FROUND_TO_NEAREST_INT)
#define npyv_rint_f64(A) _mm256_round_pd(A, _MM_FROUND_TO_NEAREST_INT)

// 定义对浮点数进行向上取整的宏
#define npyv_ceil_f32 _mm256_ceil_ps
#define npyv_ceil_f64 _mm256_ceil_pd

// 定义对浮点数进行截断取整的宏
#define npyv_trunc_f32(A) _mm256_round_ps(A, _MM_FROUND_TO_ZERO)
#define npyv_trunc_f64(A) _mm256_round_pd(A, _MM_FROUND_TO_ZERO)

// 定义对浮点数进行向下取整的宏
#define npyv_floor_f32 _mm256_floor_ps
#define npyv_floor_f64 _mm256_floor_pd

#endif // _NPY_SIMD_AVX2_MATH_H


这些宏和函数定义在一个 C/C++ 头文件中,主要用于处理 AVX2 和 AVX256 指令集下的向量化操作,包括整数的最小值和最大值归约,以及浮点数的四舍五入、向上取整、截断和向下取整操作。

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

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

#include "misc.h"

#ifndef _NPY_SIMD_AVX2_MEMORY_H
#define _NPY_SIMD_AVX2_MEMORY_H

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

// 定义 AVX2 模式下不同整数类型的加载和存储操作

#define NPYV_IMPL_AVX2_MEM_INT(CTYPE, SFX)                                   \
    // 加载未对齐的整型数据到 AVX2 向量
    NPY_FINLINE npyv_##SFX npyv_load_##SFX(const CTYPE *ptr)                 \
    { return _mm256_loadu_si256((const __m256i*)ptr); }                      \
    // 加载对齐的整型数据到 AVX2 向量
    NPY_FINLINE npyv_##SFX npyv_loada_##SFX(const CTYPE *ptr)                \
    { return _mm256_load_si256((const __m256i*)ptr); }                       \
    // 流式加载整型数据到 AVX2 向量
    NPY_FINLINE npyv_##SFX npyv_loads_##SFX(const CTYPE *ptr)                \
    { return _mm256_stream_load_si256((const __m256i*)ptr); }                \
    // 加载整型数据的低128位到 AVX2 向量
    NPY_FINLINE npyv_##SFX npyv_loadl_##SFX(const CTYPE *ptr)                \
    { return _mm256_castsi128_si256(_mm_loadu_si128((const __m128i*)ptr)); } \
    // 存储 AVX2 向量数据到未对齐的整型地址
    NPY_FINLINE void npyv_store_##SFX(CTYPE *ptr, npyv_##SFX vec)            \
    { _mm256_storeu_si256((__m256i*)ptr, vec); }                             \
    // 存储 AVX2 向量数据到对齐的整型地址
    NPY_FINLINE void npyv_storea_##SFX(CTYPE *ptr, npyv_##SFX vec)           \
    { _mm256_store_si256((__m256i*)ptr, vec); }                              \
    // 流式存储 AVX2 向量数据到整型地址
    NPY_FINLINE void npyv_stores_##SFX(CTYPE *ptr, npyv_##SFX vec)           \
    { _mm256_stream_si256((__m256i*)ptr, vec); }                             \
    // 存储 AVX2 向量低128位数据到未对齐的整型地址
    NPY_FINLINE void npyv_storel_##SFX(CTYPE *ptr, npyv_##SFX vec)           \
    { _mm_storeu_si128((__m128i*)(ptr), _mm256_castsi256_si128(vec)); }      \
    // 存储 AVX2 向量数据的高128位到未对齐的整型地址
    NPY_FINLINE void npyv_storeh_##SFX(CTYPE *ptr, npyv_##SFX vec)           \
    { _mm_storeu_si128((__m128i*)(ptr), _mm256_extracti128_si256(vec, 1)); }

// 使用宏定义来展开 AVX2 不同类型整数加载和存储函数
NPYV_IMPL_AVX2_MEM_INT(npy_uint8,  u8)
NPYV_IMPL_AVX2_MEM_INT(npy_int8,   s8)
NPYV_IMPL_AVX2_MEM_INT(npy_uint16, u16)
NPYV_IMPL_AVX2_MEM_INT(npy_int16,  s16)
NPYV_IMPL_AVX2_MEM_INT(npy_uint32, u32)
NPYV_IMPL_AVX2_MEM_INT(npy_int32,  s32)
NPYV_IMPL_AVX2_MEM_INT(npy_uint64, u64)
NPYV_IMPL_AVX2_MEM_INT(npy_int64,  s64)

// 未对齐加载单精度浮点数
#define npyv_load_f32 _mm256_loadu_ps
// 对齐加载单精度浮点数
#define npyv_loada_f32 _mm256_load_ps
// 流式加载单精度浮点数
#define npyv_loads_f32(PTR) \
    _mm256_castsi256_ps(_mm256_stream_load_si256((const __m256i*)(PTR)))
// 加载单精度浮点数低部分
#define npyv_loadl_f32(PTR) _mm256_castps128_ps256(_mm_loadu_ps(PTR))
// 未对齐存储单精度浮点数
#define npyv_store_f32 _mm256_storeu_ps
// 对齐存储单精度浮点数
#define npyv_storea_f32 _mm256_store_ps
// 流式存储单精度浮点数
#define npyv_stores_f32 _mm256_stream_ps
// 存储单精度浮点数低部分
#define npyv_storel_f32(PTR, VEC) _mm_storeu_ps(PTR, _mm256_castps256_ps128(VEC))

// 未对齐加载双精度浮点数
#define npyv_load_f64 _mm256_loadu_pd
// 对齐加载双精度浮点数
#define npyv_loada_f64 _mm256_load_pd
// 流式加载双精度浮点数
#define npyv_loads_f64(PTR) \
    _mm256_castsi256_pd(_mm256_stream_load_si256((const __m256i*)(PTR)))
// 加载双精度浮点数低部分
#define npyv_loadl_f64(PTR) _mm256_castpd128_pd256(_mm_loadu_pd(PTR))
// 未对齐存储双精度浮点数
#define npyv_store_f64 _mm256_storeu_pd
// 对齐存储双精度浮点数
#define npyv_storea_f64 _mm256_store_pd
// 流式存储双精度浮点数
#define npyv_stores_f64 _mm256_stream_pd
#define npyv_storel_f64(PTR, VEC) _mm_storeu_pd(PTR, _mm256_castpd256_pd128(VEC))
// 将 AVX2 双精度向量 VEC 的低128位存储到 PTR 指向的内存地址中

#define npyv_storeh_f32(PTR, VEC) _mm_storeu_ps(PTR, _mm256_extractf128_ps(VEC, 1))
// 将 AVX2 单精度向量 VEC 的高128位存储到 PTR 指向的内存地址中

#define npyv_storeh_f64(PTR, VEC) _mm_storeu_pd(PTR, _mm256_extractf128_pd(VEC, 1))
// 将 AVX2 双精度向量 VEC 的高128位存储到 PTR 指向的内存地址中

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

//// 32
NPY_FINLINE npyv_u32 npyv_loadn_u32(const npy_uint32 *ptr, npy_intp stride)
{
    assert(llabs(stride) <= NPY_SIMD_MAXLOAD_STRIDE32);
    // 设置步长为07的整数向量 steps
    const __m256i steps = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
    // 使用步长向量 steps 和给定的 stride 计算索引 idx
    const __m256i idx = _mm256_mullo_epi32(_mm256_set1_epi32((int)stride), steps);
    // 使用索引 idx 从内存地址 ptr 加载32位整数数据,并返回 AVX2 32位无符号整数向量
    return _mm256_i32gather_epi32((const int*)ptr, idx, 4);
}

NPY_FINLINE npyv_s32 npyv_loadn_s32(const npy_int32 *ptr, npy_intp stride)
{
    // 调用 npyv_loadn_u32 将结果强制转换为有符号整数向量
    return npyv_loadn_u32((const npy_uint32*)ptr, stride);
}

NPY_FINLINE npyv_f32 npyv_loadn_f32(const float *ptr, npy_intp stride)
{
    // 调用 npyv_loadn_u32 将结果强制转换为单精度浮点数向量
    return _mm256_castsi256_ps(npyv_loadn_u32((const npy_uint32*)ptr, stride));
}

//// 64
NPY_FINLINE npyv_f64 npyv_loadn_f64(const double *ptr, npy_intp stride)
{
    // 加载 ptr 指向的双精度数据到 a0 和 a2
    __m128d a0 = _mm_castsi128_pd(_mm_loadl_epi64((const __m128i*)ptr));
    __m128d a2 = _mm_castsi128_pd(_mm_loadl_epi64((const __m128i*)(ptr + stride*2)));
    // 加载 ptr + stride 和 ptr + stride*3 的双精度数据到 a01 和 a23
    __m128d a01 = _mm_loadh_pd(a0, ptr + stride);
    __m128d a23 = _mm_loadh_pd(a2, ptr + stride*3);
    // 将 a01 和 a23 合并成 AVX2 双精度向量并返回
    return _mm256_insertf128_pd(_mm256_castpd128_pd256(a01), a23, 1);
}

NPY_FINLINE npyv_u64 npyv_loadn_u64(const npy_uint64 *ptr, npy_intp stride)
{
    // 调用 npyv_loadn_f64 将结果强制转换为无符号64位整数向量
    return _mm256_castpd_si256(npyv_loadn_f64((const double*)ptr, stride));
}

NPY_FINLINE npyv_s64 npyv_loadn_s64(const npy_int64 *ptr, npy_intp stride)
{
    // 调用 npyv_loadn_f64 将结果强制转换为有符号64位整数向量
    return _mm256_castpd_si256(npyv_loadn_f64((const double*)ptr, stride));
}

//// 64-bit load over 32-bit stride
NPY_FINLINE npyv_f32 npyv_loadn2_f32(const float *ptr, npy_intp stride)
{
    // 加载 ptr 指向的单精度数据到 a0 和 a2
    __m128d a0 = _mm_castsi128_pd(_mm_loadl_epi64((const __m128i*)ptr));
    __m128d a2 = _mm_castsi128_pd(_mm_loadl_epi64((const __m128i*)(ptr + stride*2)));
    // 加载 ptr + stride 和 ptr + stride*3 的双精度数据到 a01 和 a23
    __m128d a01 = _mm_loadh_pd(a0, (const double*)(ptr + stride));
    __m128d a23 = _mm_loadh_pd(a2, (const double*)(ptr + stride*3));
    // 将 a01 和 a23 合并成 AVX2 单精度向量并返回
    return _mm256_castpd_ps(_mm256_insertf128_pd(_mm256_castpd128_pd256(a01), a23, 1));
}

NPY_FINLINE npyv_u32 npyv_loadn2_u32(const npy_uint32 *ptr, npy_intp stride)
{
    // 调用 npyv_loadn2_f32 将结果强制转换为无符号32位整数向量
    return _mm256_castps_si256(npyv_loadn2_f32((const float*)ptr, stride));
}

NPY_FINLINE npyv_s32 npyv_loadn2_s32(const npy_int32 *ptr, npy_intp stride)
{
    // 调用 npyv_loadn2_f32 将结果强制转换为有符号32位整数向量
    return _mm256_castps_si256(npyv_loadn2_f32((const float*)ptr, stride));
}

//// 128-bit load over 64-bit stride
NPY_FINLINE npyv_f64 npyv_loadn2_f64(const double *ptr, npy_intp stride)
{
    // 调用 npyv_loadl_f64 加载低64位数据到 AVX2 双精度向量 a
    __m256d a = npyv_loadl_f64(ptr);
    // 加载 ptr + stride 的双精度数据到 AVX 单精度向量并将其插入 a 的第二个128return _mm256_insertf128_pd(a, _mm_loadu_pd(ptr + stride), 1);
}

NPY_FINLINE npyv_u64 npyv_loadn2_u64(const npy_uint64 *ptr, npy_intp stride)
{
    // 调用 npyv_loadn2_f64 将结果强制转换为无符号64位整数向量
    return _mm256_castpd_si256(npyv_loadn2_f64((const double*)ptr, stride));
}

NPY_FINLINE npyv_s64 npyv_loadn2_s64(const npy_int64 *ptr, npy_intp stride)
{
    // 调用 npyv_loadn2_f64 将结果强制转换为有符号64位整数向量
    return _mm256_castpd_si256(npyv_loadn2_f64((const double*)ptr, stride));
}
/***************************
 * Non-contiguous Store
 ***************************/

//// 32
// 将 256 位整数向量 a 存储到 npy_int32 类型指针数组 ptr 中,按照指定的步长 stride 进行非连续存储
NPY_FINLINE void npyv_storen_s32(npy_int32 *ptr, npy_intp stride, npyv_s32 a)
{
    // 将 256 位整数向量 a 转换为两个 128 位整数向量 a0 和 a1
    __m128i a0 = _mm256_castsi256_si128(a);
    __m128i a1 = _mm256_extracti128_si256(a, 1);
    
    // 分别将 a0 的各分量存储到 ptr 中不同的位置,根据步长 stride 进行间隔存储
    ptr[stride * 0] = _mm_cvtsi128_si32(a0);
    ptr[stride * 1] = _mm_extract_epi32(a0, 1);
    ptr[stride * 2] = _mm_extract_epi32(a0, 2);
    ptr[stride * 3] = _mm_extract_epi32(a0, 3);
    // 同样地,将 a1 的各分量存储到 ptr 中不同的位置,根据步长 stride 进行间隔存储
    ptr[stride * 4] = _mm_cvtsi128_si32(a1);
    ptr[stride * 5] = _mm_extract_epi32(a1, 1);
    ptr[stride * 6] = _mm_extract_epi32(a1, 2);
    ptr[stride * 7] = _mm_extract_epi32(a1, 3);
}

// 将 256 位无符号整数向量 a 存储到 npy_uint32 类型指针数组 ptr 中,按照指定的步长 stride 进行非连续存储
NPY_FINLINE void npyv_storen_u32(npy_uint32 *ptr, npy_intp stride, npyv_u32 a)
{ 
    // 调用 npyv_storen_s32 函数,将 a 视为 npyv_s32 处理,转为 npy_int32* 类型存储
    npyv_storen_s32((npy_int32*)ptr, stride, a); 
}

// 将 256 位单精度浮点数向量 a 存储到 float 类型指针数组 ptr 中,按照指定的步长 stride 进行非连续存储
NPY_FINLINE void npyv_storen_f32(float *ptr, npy_intp stride, npyv_f32 a)
{ 
    // 调用 npyv_storen_s32 函数,将 a 转为 npyv_s32 处理后存储,转为 npy_int32* 类型存储
    npyv_storen_s32((npy_int32*)ptr, stride, _mm256_castps_si256(a)); 
}

//// 64
// 将 256 位双精度浮点数向量 a 存储到 double 类型指针数组 ptr 中,按照指定的步长 stride 进行非连续存储
NPY_FINLINE void npyv_storen_f64(double *ptr, npy_intp stride, npyv_f64 a)
{
    // 将 256 位双精度浮点数向量 a 转换为两个 128 位双精度浮点数向量 a0 和 a1
    __m128d a0 = _mm256_castpd256_pd128(a);
    __m128d a1 = _mm256_extractf128_pd(a, 1);
    
    // 将 a0 的低64位存储到 ptr 中的不同位置,根据步长 stride 进行间隔存储
    _mm_storel_pd(ptr + stride * 0, a0);
    _mm_storeh_pd(ptr + stride * 1, a0);
    // 将 a1 的低64位存储到 ptr 中的不同位置,根据步长 stride 进行间隔存储
    _mm_storel_pd(ptr + stride * 2, a1);
    _mm_storeh_pd(ptr + stride * 3, a1);
}

// 将 256 位无符号整数向量 a 存储到 npy_uint64 类型指针数组 ptr 中,按照指定的步长 stride 进行非连续存储
NPY_FINLINE void npyv_storen_u64(npy_uint64 *ptr, npy_intp stride, npyv_u64 a)
{ 
    // 调用 npyv_storen_f64 函数,将 a 视为 npyv_f64 处理,转为 double* 类型存储
    npyv_storen_f64((double*)ptr, stride, _mm256_castsi256_pd(a)); 
}

// 将 256 位有符号整数向量 a 存储到 npy_int64 类型指针数组 ptr 中,按照指定的步长 stride 进行非连续存储
NPY_FINLINE void npyv_storen_s64(npy_int64 *ptr, npy_intp stride, npyv_s64 a)
{ 
    // 调用 npyv_storen_f64 函数,将 a 视为 npyv_f64 处理,转为 double* 类型存储
    npyv_storen_f64((double*)ptr, stride, _mm256_castsi256_pd(a)); 
}

//// 64-bit store over 32-bit stride
// 将 256 位无符号整数向量 a 存储到 npy_uint32 类型指针数组 ptr 中,按照指定的 32 位步长 stride 进行非连续存储
NPY_FINLINE void npyv_storen2_u32(npy_uint32 *ptr, npy_intp stride, npyv_u32 a)
{
    // 将 256 位无符号整数向量 a 转换为两个 128 位双精度浮点数向量 a0 和 a1
    __m128d a0 = _mm256_castpd256_pd128(_mm256_castsi256_pd(a));
    __m128d a1 = _mm256_extractf128_pd(_mm256_castsi256_pd(a), 1);
    
    // 将 a0 的低64位存储到 ptr 中的不同位置,根据步长 stride 进行间隔存储
    _mm_storel_pd((double*)ptr, a0);
    _mm_storeh_pd((double*)(ptr + stride), a0);
    // 将 a1 的低64位存储到 ptr 中的不同位置,根据步长 stride 进行间隔存储
    _mm_storel_pd((double*)(ptr + stride*2), a1);
    _mm_storeh_pd((double*)(ptr + stride*3), a1);
}

// 将 256 位有符号整数向量 a 存储到 npy_int32 类型指针数组 ptr 中,按照指定的 32 位步长 stride 进行非连续存储
NPY_FINLINE void npyv_storen2_s32(npy_int32 *ptr, npy_intp stride, npyv_s32 a)
{ 
    // 调用 npyv_storen2_u32 函数,将 a 视为 npyv_u32 处理,转为 npy_uint32* 类型存储
    npyv_storen2_u32((npy_uint32*)ptr, stride, a); 
}

// 将 256 位单精度浮点数向量 a 存储到 float 类型指针数组 ptr 中,按照指定的 32 位步长 stride 进行非连续存储
NPY_FINLINE void npyv_storen2_f32(float *ptr, npy_intp stride, npyv_f32 a)
{ 
    // 调用 npyv_storen2_u32 函数,将 a 转为 npyv_u32 处理后存储,转为 npy_uint32* 类型存储
    npyv_storen2_u32((npy_uint32*)ptr, stride, _mm256_castps_si256(a)); 
}

//// 128-bit store over 64-bit stride
// 将 256 位无符号整数向量 a
//// 64
// 加载直到填充 64 位有符号整数向量
NPY_FINLINE npyv_s64 npyv_load_till_s64(const npy_int64 *ptr, npy_uintp nlane, npy_int64 fill)
{
    // 断言:向量长度大于 0
    assert(nlane > 0);
    // 设置一个包含 fill 值的 AVX 寄存器
    const __m256i vfill = npyv_setall_s64(fill);
    // 设置步长寄存器为 (0, 1, 2, 3)
    const __m256i steps = npyv_set_s64(0, 1, 2, 3);
    // 设置向量长度寄存器
    __m256i vnlane  = npyv_setall_s64(nlane > 4 ? 4 : (int)nlane);
    // 比较向量长度与步长,生成掩码
    __m256i mask    = _mm256_cmpgt_epi64(vnlane, steps);
    // 使用掩码从内存中加载数据到 AVX 寄存器
    __m256i payload = _mm256_maskload_epi64((const long long*)ptr, mask);
    // 根据掩码进行混合,用 fill 值填充未加载的部分
    __m256i ret     = _mm256_blendv_epi8(vfill, payload, mask);
#if NPY_SIMD_GUARD_PARTIAL_LOAD
    // 如果启用部分加载保护,使用 volatile 变量执行一个空操作
    volatile __m256i workaround = ret;
    // 或运算,确保在部分加载情况下返回正确的结果
    ret = _mm256_or_si256(workaround, ret);
#endif
    // 返回加载的 AVX 寄存器
    return ret;
}

// 填充零直到剩余的向量长度
NPY_FINLINE npyv_s64 npyv_load_tillz_s64(const npy_int64 *ptr, npy_uintp nlane)
{
    // 断言:向量长度大于 0
    assert(nlane > 0);
    // 设置步长寄存器为 (0, 1, 2, 3)
    const __m256i steps = npyv_set_s64(0, 1, 2, 3);
    // 设置向量长度寄存器
    __m256i vnlane  = npyv_setall_s64(nlane > 4 ? 4 : (int)nlane);
    // 比较向量长度与步长,生成掩码
    __m256i mask    = _mm256_cmpgt_epi64(vnlane, steps);
    // 使用掩码从内存中加载数据到 AVX 寄存器
    __m256i ret     = _mm256_maskload_epi64((const long long*)ptr, mask);
#if NPY_SIMD_GUARD_PARTIAL_LOAD
    // 如果启用部分加载保护,使用 volatile 变量执行一个空操作
    volatile __m256i workaround = ret;
    // 或运算,确保在部分加载情况下返回正确的结果
    ret = _mm256_or_si256(workaround, ret);
#endif
    // 返回加载的 AVX 寄存器
    return ret;
}

//// 64-bit nlane
// 加载直到填充 64 位整数向量,扩展为两倍的长度
NPY_FINLINE npyv_s32 npyv_load2_till_s32(const npy_int32 *ptr, npy_uintp nlane,
                                          npy_int32 fill_lo, npy_int32 fill_hi)
{
    // 断言:向量长度大于 0
    assert(nlane > 0);
    // 设置包含填充值的 AVX 寄存器
    const __m256i vfill = npyv_set_s32(
        fill_lo, fill_hi, fill_lo, fill_hi,
        fill_lo, fill_hi, fill_lo, fill_hi
    );
    // 设置步长寄存器为 (0, 1, 2, 3)
    const __m256i steps = npyv_set_s64(0, 1, 2, 3);
    // 设置向量长度寄存器
    __m256i vnlane  = npyv_setall_s64(nlane > 4 ? 4 : (int)nlane);
    // 比较向量长度与步长,生成掩码
    __m256i mask    = _mm256_cmpgt_epi64(vnlane, steps);
    // 使用掩码从内存中加载数据到 AVX 寄存器
    __m256i payload = _mm256_maskload_epi64((const long long*)ptr, mask);
    // 根据掩码进行混合,用填充值填充未加载的部分
    __m256i ret     = _mm256_blendv_epi8(vfill, payload, mask);
#if NPY_SIMD_GUARD_PARTIAL_LOAD
    // 如果定义了 NPY_SIMD_GUARD_PARTIAL_LOAD 宏,则执行以下操作
    volatile __m256i workaround = ret;
    // 使用 volatile 变量 workaround 来避免编译器优化,确保正确加载数据
    ret = _mm256_or_si256(workaround, ret);
    // 将 workaround 和 ret 进行按位或操作,可能是为了处理特定的加载问题
#endif
    // 返回加载的结果向量
    return ret;
}
// 填充零到剩余的通道
NPY_FINLINE npyv_s32 npyv_load2_tillz_s32(const npy_int32 *ptr, npy_uintp nlane)
{ return npyv_load_tillz_s64((const npy_int64*)ptr, nlane); }

/// 128-bit nlane
NPY_FINLINE npyv_u64 npyv_load2_tillz_s64(const npy_int64 *ptr, npy_uintp nlane)
{
    // 断言确保通道数大于0
    assert(nlane > 0);
    // 计算掩码 m,用于部分加载时控制处理的通道
    npy_int64 m  = -((npy_int64)(nlane > 1));
    // 设置一个掩码,根据 m 来选择加载的通道
    __m256i mask = npyv_set_s64(-1, -1, m, m);
    // 使用掩码加载数据到 ret 向量
    __m256i ret  = _mm256_maskload_epi64((const long long*)ptr, mask);
#if NPY_SIMD_GUARD_PARTIAL_LOAD
    // 如果定义了 NPY_SIMD_GUARD_PARTIAL_LOAD 宏,则执行以下操作
    volatile __m256i workaround = ret;
    // 使用 volatile 变量 workaround 来避免编译器优化,确保正确加载数据
    ret = _mm256_or_si256(workaround, ret);
    // 将 workaround 和 ret 进行按位或操作,可能是为了处理特定的加载问题
#endif
    // 返回加载的结果向量
    return ret;
}
// 填充指定值到剩余的通道
NPY_FINLINE npyv_u64 npyv_load2_till_s64(const npy_int64 *ptr, npy_uintp nlane,
                                           npy_int64 fill_lo, npy_int64 fill_hi)
{
    // 设置一个向量填充值 vfill
    const __m256i vfill = npyv_set_s64(0, 0, fill_lo, fill_hi);
    // 计算掩码 m,用于部分加载时控制处理的通道
    npy_int64 m     = -((npy_int64)(nlane > 1));
    // 设置一个掩码,根据 m 来选择加载的通道
    __m256i mask    = npyv_set_s64(-1, -1, m, m);
    // 使用掩码加载数据到 payload 向量
    __m256i payload = _mm256_maskload_epi64((const long long*)ptr, mask);
    // 将指定值和加载的数据根据掩码进行混合
    __m256i ret     = _mm256_blendv_epi8(vfill, payload, mask);
#if NPY_SIMD_GUARD_PARTIAL_LOAD
    // 如果定义了 NPY_SIMD_GUARD_PARTIAL_LOAD 宏,则执行以下操作
    volatile __m256i workaround = ret;
    // 使用 volatile 变量 workaround 来避免编译器优化,确保正确加载数据
    ret = _mm256_or_si256(workaround, ret);
    // 将 workaround 和 ret 进行按位或操作,可能是为了处理特定的加载问题
#endif
    // 返回加载的结果向量
    return ret;
}
/*********************************
 * Non-contiguous partial load
 *********************************/
//// 32
NPY_FINLINE npyv_s32
npyv_loadn_till_s32(const npy_int32 *ptr, npy_intp stride, npy_uintp nlane, npy_int32 fill)
{
    // 断言确保通道数大于0
    assert(nlane > 0);
    // 断言确保步长绝对值不超过最大加载步长
    assert(llabs(stride) <= NPY_SIMD_MAXLOAD_STRIDE32);
    // 设置一个向量填充值 vfill
    const __m256i vfill = _mm256_set1_epi32(fill);
    // 设置步长向量 steps
    const __m256i steps = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
    // 计算加载数据的索引
    const __m256i idx   = _mm256_mullo_epi32(_mm256_set1_epi32((int)stride), steps);
    // 设置一个通道数向量 vnlane,如果通道数大于8,则设置为8,否则设置为 nlane
    __m256i vnlane      = _mm256_set1_epi32(nlane > 8 ? 8 : (int)nlane);
    // 比较通道数和步长,生成掩码
    __m256i mask        = _mm256_cmpgt_epi32(vnlane, steps);
    // 使用掩码从指针 ptr 处加载数据到 ret 向量
    __m256i ret         = _mm256_mask_i32gather_epi32(vfill, (const int*)ptr, idx, mask, 4);
#if NPY_SIMD_GUARD_PARTIAL_LOAD
    // 如果定义了 NPY_SIMD_GUARD_PARTIAL_LOAD 宏,则执行以下操作
    volatile __m256i workaround = ret;
    // 使用 volatile 变量 workaround 来避免编译器优化,确保正确加载数据
    ret = _mm256_or_si256(workaround, ret);
    // 将 workaround 和 ret 进行按位或操作,可能是为了处理特定的加载问题
#endif
    // 返回加载的结果向量
    return ret;
}
// 填充零到剩余的通道
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
NPY_FINLINE npyv_s64
npyv_loadn_till_s64(const npy_int64 *ptr, npy_intp stride, npy_uintp nlane, npy_int64 fill)
{
    // 断言确保通道数大于0
    assert(nlane > 0);
    // 设置一个向量填充值 vfill
    const __m256i vfill = npyv_setall_s64(fill);
    // 设置加载数据的索引 idx
    const __m256i idx   = npyv_set_s64(0, 1*stride, 2*stride, 3*stride);
    // 设置步长向量 steps
    const __m256i steps = npyv_set_s64(0, 1, 2, 3);
    // 设置一个通道数向量 vnlane,如果通道数大于4,则设置为4,否则设置为 nlane
    __m256i vnlane = npyv_setall_s64(nlane > 4 ? 4 : (int)nlane);
    // 比较通道数和步长,生成掩码
    __m256i mask   = _mm256_cmpgt_epi64(vnlane, steps);
    // 使用掩码从指针 ptr 处加载数据到 ret 向量
    __m256i ret    = _mm256_mask_i64gather_epi64(vfill, (const long long*)ptr, idx, mask, 8);
#if NPY_SIMD_GUARD_PARTIAL_LOAD
    // 如果定义了 NPY_SIMD_GUARD_PARTIAL_LOAD 宏,则执行以下操作
    volatile __m256i workaround = ret;
    // 使用 volatile 变量 workaround 来避免编译器优化,确保正确加载数据
    ret = _mm256_or_si256(workaround, ret);
    // 将 workaround 和 ret 进行按位或操作,可能是为了处理特定的加载问题
#endif
    // 返回加载的结果向量
    return ret;
}
    // 创建一个 volatile 类型为 __m256i 的变量 workaround,并将 ret 的值赋给它
    volatile __m256i workaround = ret;
    // 使用 _mm256_or_si256 函数对 workaround 和 ret 进行按位或操作,并将结果赋给 ret
    ret = _mm256_or_si256(workaround, ret);
//// 64-bit load over 32-bit stride
NPY_FINLINE npyv_s64 npyv_loadn2_till_s32(const npy_int32 *ptr, npy_intp stride, npy_uintp nlane,
                                                 npy_int32 fill_lo, npy_int32 fill_hi)
{
    // 断言确保加载的向量长度大于0
    assert(nlane > 0);
    
    // 创建包含填充值的 AVX 寄存器
    const __m256i vfill = npyv_set_s32(
        fill_lo, fill_hi, fill_lo, fill_hi,
        fill_lo, fill_hi, fill_lo, fill_hi
    );
    
    // 创建包含步长的 AVX 寄存器
    const __m256i idx   = npyv_set_s64(0, 1*stride, 2*stride, 3*stride);
    
    // 创建包含步数的 AVX 寄存器
    const __m256i steps = npyv_set_s64(0, 1, 2, 3);
    
    // 设置加载的向量长度
    __m256i vnlane = npyv_setall_s64(nlane > 4 ? 4 : (int)nlane);
    
    // 创建用于掩码比较的 AVX 寄存器
    __m256i mask   = _mm256_cmpgt_epi64(vnlane, steps);
    
    // 使用掩码从指针 ptr 处加载数据到 AVX 寄存器 ret
    __m256i ret    = _mm256_mask_i64gather_epi64(vfill, (const long long*)ptr, idx, mask, 4);
    
#if NPY_SIMD_GUARD_PARTIAL_LOAD
    // 如果开启了部分加载保护,则进行一个额外的 volatile 操作
    volatile __m256i workaround = ret;
    ret = _mm256_or_si256(workaround, ret);
#endif
    
    // 返回加载的 AVX 寄存器 ret
    return ret;
}
// fill zero to rest lanes
NPY_FINLINE npyv_s32 npyv_loadn2_tillz_s32(const npy_int32 *ptr, npy_intp stride, npy_uintp nlane)
{ return npyv_loadn2_till_s32(ptr, stride, nlane, 0, 0); }

//// 128-bit load over 64-bit stride
NPY_FINLINE npyv_s64 npyv_loadn2_till_s64(const npy_int64 *ptr, npy_intp stride, npy_uintp nlane,
                                          npy_int64 fill_lo, npy_int64 fill_hi)
{
    // 断言确保加载的向量长度大于0
    assert(nlane > 0);
    
    // 加载低64位数据到 AVX 寄存器 a
    __m256i a = npyv_loadl_s64(ptr);
    
#if defined(_MSC_VER) && defined(_M_IX86)
    // 如果是 MSVC 编译器和 x86 平台,则按照 32int 大小设置填充值
    __m128i fill =_mm_setr_epi32(
        (int)fill_lo, (int)(fill_lo >> 32),
        (int)fill_hi, (int)(fill_hi >> 32)
    );
#else
    // 否则,按照 64int 大小设置填充值
    __m128i fill = _mm_set_epi64x(fill_hi, fill_lo);
#endif
    
    // 如果向量长度大于1,则从 ptr + stride 处加载数据到 AVX 寄存器 b;否则使用 fill 作为数据源
    __m128i b = nlane > 1 ? _mm_loadu_si128((const __m128i*)(ptr + stride)) : fill;
    
    // 将低128位从 b 插入到 a 的高128位,形成结果 ret
    __m256i ret = _mm256_inserti128_si256(a, b, 1);
    
#if NPY_SIMD_GUARD_PARTIAL_LOAD
    // 如果开启了部分加载保护,则进行一个额外的 volatile 操作
    volatile __m256i workaround = ret;
    ret = _mm256_or_si256(workaround, ret);
#endif
    
    // 返回加载的 AVX 寄存器 ret
    return ret;
}
// fill zero to rest lanes
NPY_FINLINE npyv_s64 npyv_loadn2_tillz_s64(const npy_int64 *ptr, npy_intp stride, npy_uintp nlane)
{ return npyv_loadn2_till_s64(ptr, stride, nlane, 0, 0); }

/*********************************
 * Partial store
 *********************************/
//// 32
NPY_FINLINE void npyv_store_till_s32(npy_int32 *ptr, npy_uintp nlane, npyv_s32 a)
{
    // 断言确保存储的向量长度大于0
    assert(nlane > 0);
    
    // 创建包含步长的 AVX 寄存器
    const __m256i steps = _mm256_setr_epi32(0, 1, 2, 3, 4, 5, 6, 7);
    
    // 设置存储的向量长度
    __m256i vnlane = _mm256_set1_epi32(nlane > 8 ? 8 : (int)nlane);
    
    // 创建用于掩码比较的 AVX 寄存器
    __m256i mask   = _mm256_cmpgt_epi32(vnlane, steps);
    
    // 使用掩码将 AVX 寄存器 a 中的数据存储到指针 ptr 处
    _mm256_maskstore_epi32((int*)ptr, mask, a);
}
//// 64
NPY_FINLINE void npyv_store_till_s64(npy_int64 *ptr, npy_uintp nlane, npyv_s64 a)
{
    // 断言确保存储的向量长度大于0
    assert(nlane > 0);
    
    // 创建包含步长的 AVX 寄存器
    const __m256i steps = npyv_set_s64(0, 1, 2, 3);
    
    // 设置存储的向量长度
    __m256i vnlane = npyv_setall_s64(nlane > 8 ? 8 : (int)nlane);
    
    // 创建用于掩码比较的 AVX 寄存器
    __m256i mask   = _mm256_cmpgt_epi64(vnlane, steps);
    # 使用 AVX2 指令集的 _mm256_maskstore_epi64 函数,将数据 a 根据掩码 mask 存储到内存地址 ptr 指向的位置
    _mm256_maskstore_epi64((long long*)ptr, mask, a);
/*********************************
 * Non-contiguous partial store
 *********************************/
//// 32
// 将长度为32位的向量部分存储到非连续地址的内存中
NPY_FINLINE void npyv_storen_till_s32(npy_int32 *ptr, npy_intp stride, npy_uintp nlane, npyv_s32 a)
{
    // 确保存储的长度大于0
    assert(nlane > 0);
    
    // 将256位整型向量a转换为两个128位整型向量a0和a1
    __m128i a0 = _mm256_castsi256_si128(a);
    __m128i a1 = _mm256_extracti128_si256(a, 1);

    // 根据nlane的不同值,选择不同数量的元素存储到内存中,间隔为stride
    ptr[stride*0] = _mm_extract_epi32(a0, 0);
    switch(nlane) {
    case 1:
        return;
    case 2:
        ptr[stride*1] = _mm_extract_epi32(a0, 1);
        return;
    case 3:
        ptr[stride*1] = _mm_extract_epi32(a0, 1);
        ptr[stride*2] = _mm_extract_epi32(a0, 2);
        return;
    case 4:
        ptr[stride*1] = _mm_extract_epi32(a0, 1);
        ptr[stride*2] = _mm_extract_epi32(a0, 2);
        ptr[stride*3] = _mm_extract_epi32(a0, 3);
        return;
    case 5:
        ptr[stride*1] = _mm_extract_epi32(a0, 1);
        ptr[stride*2] = _mm_extract_epi32(a0, 2);
        ptr[stride*3] = _mm_extract_epi32(a0, 3);
        ptr[stride*4] = _mm_extract_epi32(a1, 0);
        return;
    case 6:
        ptr[stride*1] = _mm_extract_epi32(a0, 1);
        ptr[stride*2] = _mm_extract_epi32(a0, 2);
        ptr[stride*3] = _mm_extract_epi32(a0, 3);
        ptr[stride*4] = _mm_extract_epi32(a1, 0);
        ptr[stride*5] = _mm_extract_epi32(a1, 1);
        return;
    case 7:
        ptr[stride*1] = _mm_extract_epi32(a0, 1);
        ptr[stride*2] = _mm_extract_epi32(a0, 2);
        ptr[stride*3] = _mm_extract_epi32(a0, 3);
        ptr[stride*4] = _mm_extract_epi32(a1, 0);
        ptr[stride*5] = _mm_extract_epi32(a1, 1);
        ptr[stride*6] = _mm_extract_epi32(a1, 2);
        return;
    }
}
    // 根据 switch 语句的默认情况执行以下操作
    default:
        // 将 a0 的第 132 位整数提取出来,并存入 ptr 数组的对应位置
        ptr[stride*1] = _mm_extract_epi32(a0, 1);
        // 将 a0 的第 232 位整数提取出来,并存入 ptr 数组的对应位置
        ptr[stride*2] = _mm_extract_epi32(a0, 2);
        // 将 a0 的第 332 位整数提取出来,并存入 ptr 数组的对应位置
        ptr[stride*3] = _mm_extract_epi32(a0, 3);
        // 将 a1 的第 032 位整数提取出来,并存入 ptr 数组的对应位置
        ptr[stride*4] = _mm_extract_epi32(a1, 0);
        // 将 a1 的第 132 位整数提取出来,并存入 ptr 数组的对应位置
        ptr[stride*5] = _mm_extract_epi32(a1, 1);
        // 将 a1 的第 232 位整数提取出来,并存入 ptr 数组的对应位置
        ptr[stride*6] = _mm_extract_epi32(a1, 2);
        // 将 a1 的第 332 位整数提取出来,并存入 ptr 数组的对应位置
        ptr[stride*7] = _mm_extract_epi32(a1, 3);
    }
//// 64
NPY_FINLINE void npyv_storen_till_s64(npy_int64 *ptr, npy_intp stride, npy_uintp nlane, npyv_s64 a)
{
    assert(nlane > 0);
    // 将 256 位整数向量 a 转换为两个 128 位双精度浮点向量
    __m128d a0 = _mm256_castpd256_pd128(_mm256_castsi256_pd(a));
    __m128d a1 = _mm256_extractf128_pd(_mm256_castsi256_pd(a), 1);

    // 将指针 ptr 强制转换为双精度浮点数指针
    double *dptr = (double*)ptr;
    // 存储 a0 的低位部分到 dptr
    _mm_storel_pd(dptr, a0);
    switch(nlane) {
    case 1:
        return;
    case 2:
        // 如果 nlane 为 2,则存储 a0 的高位部分到 dptr + stride * 1
        _mm_storeh_pd(dptr + stride * 1, a0);
        return;
    case 3:
        // 如果 nlane 为 3,则存储 a0 的高位部分到 dptr + stride * 1,
        // 存储 a1 的低位部分到 dptr + stride * 2
        _mm_storeh_pd(dptr + stride * 1, a0);
        _mm_storel_pd(dptr + stride * 2, a1);
        return;
    default:
        // 对于其他情况,存储 a0 的高位部分到 dptr + stride * 1,
        // 存储 a1 的低位部分到 dptr + stride * 2,
        // 存储 a1 的高位部分到 dptr + stride * 3
        _mm_storeh_pd(dptr + stride * 1, a0);
        _mm_storel_pd(dptr + stride * 2, a1);
        _mm_storeh_pd(dptr + stride * 3, a1);
    }
}

//// 64-bit store over 32-bit stride
NPY_FINLINE void npyv_storen2_till_s32(npy_int32 *ptr, npy_intp stride, npy_uintp nlane, npyv_s32 a)
{
    assert(nlane > 0);
    // 将 256 位整数向量 a 转换为两个 128 位双精度浮点向量
    __m128d a0 = _mm256_castpd256_pd128(_mm256_castsi256_pd(a));
    __m128d a1 = _mm256_extractf128_pd(_mm256_castsi256_pd(a), 1);

    // 存储 a0 的低位部分到双精度浮点数指针 ptr
    _mm_storel_pd((double*)ptr, a0);
    switch(nlane) {
    case 1:
        return;
    case 2:
        // 如果 nlane 为 2,则存储 a0 的高位部分到双精度浮点数指针 ptr + stride * 1
        _mm_storeh_pd((double*)(ptr + stride * 1), a0);
        return;
    case 3:
        // 如果 nlane 为 3,则存储 a0 的高位部分到双精度浮点数指针 ptr + stride * 1,
        // 存储 a1 的低位部分到双精度浮点数指针 ptr + stride * 2
        _mm_storeh_pd((double*)(ptr + stride * 1), a0);
        _mm_storel_pd((double*)(ptr + stride * 2), a1);
        return;
    default:
        // 对于其他情况,存储 a0 的高位部分到双精度浮点数指针 ptr + stride * 1,
        // 存储 a1 的低位部分到双精度浮点数指针 ptr + stride * 2,
        // 存储 a1 的高位部分到双精度浮点数指针 ptr + stride * 3
        _mm_storeh_pd((double*)(ptr + stride * 1), a0);
        _mm_storel_pd((double*)(ptr + stride * 2), a1);
        _mm_storeh_pd((double*)(ptr + stride * 3), a1);
    }
}

//// 128-bit store over 64-bit stride
NPY_FINLINE void npyv_storen2_till_s64(npy_int64 *ptr, npy_intp stride, npy_uintp nlane, npyv_s64 a)
{
    assert(nlane > 0);
    // 调用 npyv_storel_s64 存储 a 的低位部分到 ptr
    npyv_storel_s64(ptr, a);
    if (nlane > 1) {
        // 如果 nlane 大于 1,则调用 npyv_storeh_s64 存储 a 的高位部分到 ptr + stride
        npyv_storeh_s64(ptr + stride, a);
    }
}
    {                                                                                       \
        union {                                                                             \
            npyv_lanetype_##F_SFX from_##F_SFX;                                             \
            npyv_lanetype_##T_SFX to_##T_SFX;                                               \
        } pun;                                                                              \
        pun.from_##F_SFX = fill;                                                            \
        // 使用联合体 pun 将填充值 fill 转换为目标类型 T_SFX 的数据
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_load_till_##T_SFX(                   \
            (const npyv_lanetype_##T_SFX *)ptr, nlane, pun.to_##T_SFX                       \
        ));                                                                                 \
    }                                                                                       \
    // 加载并重新解释数据为类型为 T_SFX 的向量,并返回
    NPY_FINLINE npyv_##F_SFX npyv_loadn_till_##F_SFX                                        \
    (const npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane,                    \
     npyv_lanetype_##F_SFX fill)                                                            \
    {                                                                                       \
        union {                                                                             \
            npyv_lanetype_##F_SFX from_##F_SFX;                                             \
            npyv_lanetype_##T_SFX to_##T_SFX;                                               \
        } pun;                                                                              \
        pun.from_##F_SFX = fill;                                                            \
        // 使用联合体 pun 将填充值 fill 转换为目标类型 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               \
        ));                                                                                 \
    }                                                                                       \
    // 加载指定步长和数量的数据,并重新解释为类型为 T_SFX 的向量,并返回
    NPY_FINLINE npyv_##F_SFX npyv_load_tillz_##F_SFX                                        \
    (const npyv_lanetype_##F_SFX *ptr, npy_uintp nlane)                                     \
    {                                                                                       \
        // 加载指定数量的数据,并重新解释为类型为 T_SFX 的向量,并返回
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_load_tillz_##T_SFX(                  \
            (const npyv_lanetype_##T_SFX *)ptr, nlane                                       \
        ));                                                                                 \
    }                                                                                       \
    // 加载直到遇到零的数据,并重新解释为类型为 T_SFX 的向量,并返回
    NPY_FINLINE npyv_##F_SFX npyv_loadn_tillz_##F_SFX                                       \
    # 定义一个宏,用于将给定类型 F_SFX 的指针数组重新解释为类型 T_SFX 的向量数组,并加载直到遇到零元素的向量。
    (const npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane)
    {
        # 调用 npyv_loadn_tillz_##T_SFX 函数,加载从指针 ptr 开始,步长为 stride 的 nlane 个向量,直到遇到零元素。
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_loadn_tillz_##T_SFX(
            (const npyv_lanetype_##T_SFX *)ptr, stride, nlane
        ));
    }
    
    # 定义一个内联函数,将类型 F_SFX 的向量数组 a 存储到类型 F_SFX 的指针数组 ptr 中,存储直到达到 nlane 个向量。
    NPY_FINLINE void npyv_store_till_##F_SFX
    (npyv_lanetype_##F_SFX *ptr, npy_uintp nlane, npyv_##F_SFX a)
    {
        # 调用 npyv_reinterpret_##T_SFX##_##F_SFX 函数,将类型 F_SFX 的向量数组 a 重新解释为类型 T_SFX 的向量数组,然后存储到 ptr 中,存储直到达到 nlane 个向量。
        npyv_store_till_##T_SFX(
            (npyv_lanetype_##T_SFX *)ptr, nlane,
            npyv_reinterpret_##T_SFX##_##F_SFX(a)
        );
    }
    
    # 定义一个内联函数,将类型 F_SFX 的向量数组 a 存储到类型 F_SFX 的指针数组 ptr 中,使用步长 stride,存储直到达到 nlane 个向量。
    NPY_FINLINE void npyv_storen_till_##F_SFX
    (npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane, npyv_##F_SFX a)
    {
        # 调用 npyv_reinterpret_##T_SFX##_##F_SFX 函数,将类型 F_SFX 的向量数组 a 重新解释为类型 T_SFX 的向量数组,然后使用步长 stride 存储到 ptr 中,存储直到达到 nlane 个向量。
        npyv_storen_till_##T_SFX(
            (npyv_lanetype_##T_SFX *)ptr, stride, nlane,
            npyv_reinterpret_##T_SFX##_##F_SFX(a)
        );
    }
// 定义宏,用于生成一组加载和存储函数的实现,支持AVX2并处理部分数据类型

// 定义加载函数的宏
#define NPYV_IMPL_AVX2_REST_PARTIAL_TYPES(F_SFX, T_SFX)                                \
    // 定义加载函数,加载AVX2向量类型 F_SFX,处理数据类型为 T_SFX
    NPY_FINLINE npyv_##F_SFX npyv_load2_till_##F_SFX                                        \
    (const npyv_lanetype_##F_SFX *ptr, npy_uintp nlane,                                     \
     npyv_lanetype_##F_SFX fill_lo, npyv_lanetype_##F_SFX fill_hi)                          \
    {                                                                                       \
        // 定义联合体 pun,用于类型转换
        union pun {                                                                         \
            npyv_lanetype_##F_SFX from_##F_SFX;                                             \
            npyv_lanetype_##T_SFX to_##T_SFX;                                               \
        };                                                                                  \
        // 定义 pun_lo 和 pun_hi,用于分别存储 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_reinterpret_##F_SFX##_##T_SFX,将加载函数转换为 T_SFX 类型
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_load2_till_##T_SFX(                  \
            (const npyv_lanetype_##T_SFX *)ptr, nlane, pun_lo.to_##T_SFX, pun_hi.to_##T_SFX \
        ));                                                                                 \
    }                                                                                       \
    // 定义加载函数,加载 AVX2 向量类型 F_SFX 的一对值,处理数据类型为 T_SFX
    NPY_FINLINE npyv_##F_SFX npyv_loadn2_till_##F_SFX                                       \
    (const npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane,                    \
     npyv_lanetype_##F_SFX fill_lo, npyv_lanetype_##F_SFX fill_hi)                          \
    {                                                                                       \
        union pun {                                                                         \
            npyv_lanetype_##F_SFX from_##F_SFX;                                             \
            npyv_lanetype_##T_SFX to_##T_SFX;                                               \
        };                                                                                  \
        union pun pun_lo;                                                                   \
        union pun pun_hi;                                                                   \
        pun_lo.from_##F_SFX = fill_lo;                                                      \
        pun_hi.from_##F_SFX = fill_hi;                                                      \
        // 调用 reinterpret 函数将填充值重新解释为目标类型,并加载对应的向量数据
        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 npyv_load2_tillz_##F_SFX                                       \
    (const npyv_lanetype_##F_SFX *ptr, npy_uintp nlane)                                     \
    {                                                                                       \
        // 调用 reinterpret 函数将加载的数据重新解释为目标类型并返回
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_load2_tillz_##T_SFX(                 \
            (const npyv_lanetype_##T_SFX *)ptr, nlane                                       \
        ));                                                                                 \
    }                                                                                       \
    // 加载非零填充的前两个向量并将它们转换为目标类型
    NPY_FINLINE npyv_##F_SFX npyv_loadn2_tillz_##F_SFX                                      \
    (const npyv_lanetype_##F_SFX *ptr, npy_intp stride, npy_uintp nlane)                    \
    {                                                                                       \
        // 调用 reinterpret 函数将加载的数据重新解释为目标类型并返回
        return npyv_reinterpret_##F_SFX##_##T_SFX(npyv_loadn2_tillz_##T_SFX(                \
            (const npyv_lanetype_##T_SFX *)ptr, stride, nlane                               \
        ));                                                                                 \
    }                                                                                       \
    // 存储到目标类型的前两个向量数据
    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)                                           \
        );                                                                                  \
    }



{                                                                                       \
    npyv_store2_till_##T_SFX(                                                           \
        (npyv_lanetype_##T_SFX *)ptr, nlane,                                            \
        npyv_reinterpret_##T_SFX##_##F_SFX(a)                                           \
    );                                                                                  \
}


这段代码片段是一个宏定义和一个内联函数的实现。它们用于向特定类型的向量寄存器(vector register)存储数据。


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_##F_SFX` 是函数名的宏展开形式,根据 `F_SFX` 定义生成不同的函数名。
- `npyv_lanetype_##F_SFX` 是一个特定类型的向量元素的数据类型。
- `ptr` 是指向目标内存区域的指针。
- `stride` 是步长,表示内存中相邻元素之间的间隔。
- `nlane` 是要存储的向量元素数量。
- `npyv_##F_SFX a` 是要存储的向量数据。


    npyv_storen2_till_##T_SFX(                                                          \
        (npyv_lanetype_##T_SFX *)ptr, stride, nlane,                                    \
        npyv_reinterpret_##T_SFX##_##F_SFX(a)                                           \
    );                                                                                  \
}


这里是函数实现的具体内容,调用了另一个宏展开的函数 `npyv_storen2_till_##T_SFX`,这个函数实际上是将一个类型的向量 `a` 存储为另一种类型 `T_SFX` 的向量数据。

整体来说,这段代码片段通过宏定义和内联函数实现了向不同类型的向量寄存器存储数据的功能,利用了预处理宏的特性来生成不同类型的函数名和函数实现。
// 宏定义,用于生成AVX2指令集的加载/存储解交错函数对,操作的数据类型为u32和s32
#define NPYV_IMPL_AVX2_REST_PARTIAL_TYPES_PAIR(u32, s32) \
    // 省略部分实现细节,生成u32和s32类型对应的AVX2指令集函数

// 依据宏定义生成AVX2指令集的加载/存储解交错函数对,操作的数据类型为f32和s32
#define NPYV_IMPL_AVX2_REST_PARTIAL_TYPES_PAIR(f32, s32) \
    // 省略部分实现细节,生成f32和s32类型对应的AVX2指令集函数

// 依据宏定义生成AVX2指令集的加载/存储解交错函数对,操作的数据类型为u64和s64
#define NPYV_IMPL_AVX2_REST_PARTIAL_TYPES_PAIR(u64, s64) \
    // 省略部分实现细节,生成u64和s64类型对应的AVX2指令集函数

// 依据宏定义生成AVX2指令集的加载/存储解交错函数对,操作的数据类型为f64和s64
#define NPYV_IMPL_AVX2_REST_PARTIAL_TYPES_PAIR(f64, s64) \
    // 省略部分实现细节,生成f64和s64类型对应的AVX2指令集函数

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

// 定义AVX2指令集的加载/存储解交错函数宏,操作数据类型为SFX和ZSFX
#define NPYV_IMPL_AVX2_MEM_INTERLEAVE(SFX, ZSFX)                             \
    // 内联函数,将类型为npyv_ZSFX的向量解交错为类型为npyv_SFX的双通道向量
    NPY_FINLINE npyv_##ZSFX##x2 npyv_zip_##ZSFX(npyv_##SFX, npyv_##SFX);   \
    // 内联函数,将类型为npyv_SFX的双通道向量互连为类型为npyv_ZSFX的向量
    NPY_FINLINE npyv_##ZSFX##x2 npyv_unzip_##ZSFX(npyv_##SFX, npyv_##SFX); \
    // 内联函数,从内存中加载类型为npyv_lanetype_SFX的双通道向量
    NPY_FINLINE npyv_##SFX##x2 npyv_load_##SFX##x2(                          \
        const npyv_lanetype_##SFX *ptr                                       \
    ) {                                                                      \
        // 返回解交错后的双通道向量
        return npyv_unzip_##ZSFX(                                            \
            // 调用npyv_load_##SFX函数加载ptr和ptr+npyv_nlanes_##SFX位置的数据
            npyv_load_##SFX(ptr), npyv_load_##SFX(ptr+npyv_nlanes_##SFX)     \
        );                                                                   \
    }                                                                        \
    // 内联函数,将类型为npyv_SFX的双通道向量存储到内存中
    NPY_FINLINE void npyv_store_##SFX##x2(                                   \
        npyv_lanetype_##SFX *ptr, npyv_##SFX##x2 v                           \
    ) {                                                                      \
        // 将双通道向量v进行互连并存储到ptr和ptr+npyv_nlanes_##SFX位置
        npyv_##SFX##x2 zip = npyv_zip_##ZSFX(v.val[0], v.val[1]);            \
        npyv_store_##SFX(ptr, zip.val[0]);                                   \
        npyv_store_##SFX(ptr + npyv_nlanes_##SFX, zip.val[1]);               \
    }

// 使用宏定义生成AVX2指令集的加载/存储解交错函数对,操作数据类型为u8和u8
NPYV_IMPL_AVX2_MEM_INTERLEAVE(u8, u8)
// 使用宏定义生成AVX2指令集的加载/存储解交错函数对,操作数据类型为s8和u8
NPYV_IMPL_AVX2_MEM_INTERLEAVE(s8, u8)
// 使用宏定义生成AVX2指令集的加载/存储解交错函数对,操作数据类型为u16和u16
NPYV_IMPL_AVX2_MEM_INTERLEAVE(u16, u16)
// 使用宏定义生成AVX2指令集的加载/存储解交错函数对,操作数据类型为s16和u16
NPYV_IMPL_AVX2_MEM_INTERLEAVE(s16, u16)
// 使用宏定义生成AVX2指令集的加载/存储解交错函数对,操作数据类型为u32和u32
NPYV_IMPL_AVX2_MEM_INTERLEAVE(u32, u32)
// 使用宏定义生成AVX2指令集的加载/存储解交错函数对,操作数据类型为s32和u32
NPYV_IMPL_AVX2_MEM_INTERLEAVE(s32, u32)
// 使用宏定义生成AVX2指令集的加载/存储解交错函数对,操作数据类型为u64和u64
NPYV_IMPL_AVX2_MEM_INTERLEAVE(u64, u64)
// 使用宏定义生成AVX2指令集的加载/存储解交错函数对,操作数据类型为s64和u64
NPYV_IMPL_AVX2_MEM_INTERLEAVE(s64, u64)
// 使用宏定义生成AVX2指令集的加载/存储解交错函数对,操作数据类型为f32和f32
NPYV_IMPL_AVX2_MEM_INTERLEAVE(f32, f32)
// 使用宏定义生成AVX2指令集的加载/存储解交错函数对,操作数据类型为f64和f64
NPYV_IMPL_AVX2_MEM_INTERLEAVE(f64, f64)

/*********************************
 * Lookup tables
 *********************************/

// 使用向量作为索引,从包含32个float32元素的表中查找值
NPY_FINLINE npyv_f32 npyv_lut32_f32(const float *table, npyv_u32 idx)
{ return _mm256_i32gather_ps(table, idx, 4); }

// 使用向量作为索引,从包含32个uint32元素的表中查找值,并将结果重新解释为npyv_u32
NPY_FINLINE npyv_u32 npyv_lut32_u32(const npy_uint32 *table, npyv_u32 idx)
{ return npyv_reinterpret_u32_f32(npyv_lut32_f32((const float*)table, idx)); }

// 使用向量作为索引,从包含32个int32元素的表中查找值,并将结果重新解释为npyv_s32
NPY_FINLINE npyv_s32 npyv_lut32_s32(const npy_int32 *table, npyv_u32 idx)
{ return npyv_reinterpret_s32_f32(npyv_lut32_f32((const float*)table, idx)); }

// 使用向量作为索引,从包含16个float64元素的表中查找值
NPY_FINLINE npyv_f64 npyv_lut16_f64(const double *table, npyv_u64 idx)
{ return _mm256_i64gather_pd(table, idx, 8); }

// 使用向量作为索引,从包含16个uint64元素的表中查找值,并将结果重新解释为npyv_u64
NPY_FINLINE npyv_u64 npyv_lut16_u64(const npy_uint64 *table, npyv_u64 idx)
# 返回一个64位浮点数向量,其内容由表格中索引为idx的16个元素查找后重解释为64位浮点数得到
{ return npyv_reinterpret_u64_f64(npyv_lut16_f64((const double*)table, idx)); }
# 返回一个64位有符号整数向量,其内容由表格中索引为idx的16个元素查找后重解释为64位有符号整数得到
NPY_FINLINE npyv_s64 npyv_lut16_s64(const npy_int64 *table, npyv_u64 idx)
{ return npyv_reinterpret_s64_f64(npyv_lut16_f64((const double*)table, idx)); }

#endif // _NPY_SIMD_AVX2_MEMORY_H

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

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


#ifndef NPY_SIMD_AVX2_MISC_H
#define NPY_SIMD_AVX2_MISC_H


// vector with zero lanes
#define npyv_zero_u8  _mm256_setzero_si256
#define npyv_zero_s8  _mm256_setzero_si256
#define npyv_zero_u16 _mm256_setzero_si256
#define npyv_zero_s16 _mm256_setzero_si256
#define npyv_zero_u32 _mm256_setzero_si256
#define npyv_zero_s32 _mm256_setzero_si256
#define npyv_zero_u64 _mm256_setzero_si256
#define npyv_zero_s64 _mm256_setzero_si256
#define npyv_zero_f32 _mm256_setzero_ps
#define npyv_zero_f64 _mm256_setzero_pd


// vector with a specific value set to all lanes
#define npyv_setall_u8(VAL)  _mm256_set1_epi8((char)VAL)
#define npyv_setall_s8(VAL)  _mm256_set1_epi8((char)VAL)
#define npyv_setall_u16(VAL) _mm256_set1_epi16((short)VAL)
#define npyv_setall_s16(VAL) _mm256_set1_epi16((short)VAL)
#define npyv_setall_u32(VAL) _mm256_set1_epi32((int)VAL)
#define npyv_setall_s32(VAL) _mm256_set1_epi32(VAL)
#define npyv_setall_f32(VAL) _mm256_set1_ps(VAL)
#define npyv_setall_f64(VAL) _mm256_set1_pd(VAL)


NPY_FINLINE __m256i npyv__setr_epi64(npy_int64, npy_int64, npy_int64, npy_int64);
NPY_FINLINE npyv_u64 npyv_setall_u64(npy_uint64 a)
{
    npy_int64 ai = (npy_int64)a;
#if defined(_MSC_VER) && defined(_M_IX86)
    return npyv__setr_epi64(ai, ai, ai, ai);
#else
    return _mm256_set1_epi64x(ai);
#endif
}


NPY_FINLINE npyv_s64 npyv_setall_s64(npy_int64 a)
{
#if defined(_MSC_VER) && defined(_M_IX86)
    return npyv__setr_epi64(a, a, a, a);
#else
    return _mm256_set1_epi64x(a);
#endif
}


/*
 * vector with specific values set to each lane and
 * set a specific value to all remained lanes
 *
 * Args that generated by NPYV__SET_FILL_* not going to expand if
 * _mm256_setr_* are defined as macros.
*/
NPY_FINLINE __m256i 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,
    char i16, char i17, char i18, char i19, char i20, char i21, char i22, char i23,
    char i24, char i25, char i26, char i27, char i28, char i29, char i30, char i31)
{
    return _mm256_setr_epi8(
        i0,  i1,  i2,  i3,  i4,  i5,  i6,  i7,  i8,  i9,  i10, i11, i12, i13, i14, i15,
        i16, i17, i18, i19, i20, i21, i22, i23, i24, i25, i26, i27, i28, i29, i30, i31
    );
}


NPY_FINLINE __m256i npyv__setr_epi16(
    short i0,  short i1,  short i2,  short i3,  short i4,  short i5,  short i6,  short i7,
    short i8,  short i9,  short i10, short i11, short i12, short i13, short i14, short i15)
{
    return _mm256_setr_epi16(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, i12, i13, i14, i15);
}


NPY_FINLINE __m256i npyv__setr_epi32(int i0, int i1, int i2, int i3, int i4, int i5, int i6, int i7)
{
    return _mm256_setr_epi32(i0, i1, i2, i3, i4, i5, i6, i7);
}


NPY_FINLINE __m256i npyv__setr_epi64(npy_int64 i0, npy_int64 i1, npy_int64 i2, npy_int64 i3)
{
#if defined(_MSC_VER) && defined(_M_IX86)
    return npyv__setr_epi64(i0, i1, i2, i3);
#else
    return _mm256_setr_epi64x(i0, i1, i2, i3);
#endif
}
    # 使用 `_mm256_setr_epi32` 函数创建一个 AVX2 256 位整数向量,向量的每个元素为参数中对应的值,
    # 这些值被强制转换为整数 `(int)`,对于64位整数参数,通过 `(int)(i >> 32)` 获取高32位的整数部分。
    return _mm256_setr_epi32(
        (int)i0, (int)(i0 >> 32),  # 第一个元素由 i0 和 i0 的高32位构成
        (int)i1, (int)(i1 >> 32),  # 第二个元素由 i1 和 i1 的高32位构成
        (int)i2, (int)(i2 >> 32),  # 第三个元素由 i2 和 i2 的高32位构成
        (int)i3, (int)(i3 >> 32)   # 第四个元素由 i3 和 i3 的高32位构成
    );
#define npyv_select_u8(MASK, A, B)  _mm256_blendv_epi8(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
// 使用掩码MASK来选择每个通道中的值,然后将结果混合成新的256位整数型数据
#define npyv_select_f32(MASK, A, B) _mm256_blendv_ps(B, A, _mm256_castsi256_ps(MASK))
// 使用掩码MASK来选择每个通道中的值,然后将结果混合成新的256位双精度浮点数型数据
#define npyv_select_f64(MASK, A, B) _mm256_blendv_pd(B, A, _mm256_castsi256_pd(MASK))

// 提取第一个向量的第一个通道数据
#define npyv_extract0_u8(A) ((npy_uint8)_mm_cvtsi128_si32(_mm256_castsi256_si128(A)))
// 提取第一个向量的第一个通道数据,作为有符号8位整数
#define npyv_extract0_s8(A) ((npy_int8)_mm_cvtsi128_si32(_mm256_castsi256_si128(A)))
// 提取第一个向量的第一个通道数据,作为无符号16位整数
#define npyv_extract0_u16(A) ((npy_uint16)_mm_cvtsi128_si32(_mm256_castsi256_si128(A)))
// 提取第一个向量的第一个通道数据,作为有符号16位整数
#define npyv_extract0_s16(A) ((npy_int16)_mm_cvtsi128_si32(_mm256_castsi256_si128(A)))
// 提取第一个向量的第一个通道数据,作为无符号32位整数
#define npyv_extract0_u32(A) ((npy_uint32)_mm_cvtsi128_si32(_mm256_castsi256_si128(A)))
// 定义宏,用于从一个 256 位向量中提取特定类型和大小的元素
#define npyv_extract0_s32(A) ((npy_int32)_mm_cvtsi128_si32(_mm256_castsi256_si128(A)))
#define npyv_extract0_u64(A) ((npy_uint64)npyv128_cvtsi128_si64(_mm256_castsi256_si128(A)))
#define npyv_extract0_s64(A) ((npy_int64)npyv128_cvtsi128_si64(_mm256_castsi256_si128(A)))
#define npyv_extract0_f32(A) _mm_cvtss_f32(_mm256_castps256_ps128(A))
#define npyv_extract0_f64(A) _mm_cvtsd_f64(_mm256_castpd256_pd128(A))

// 定义宏,用于重新解释数据的类型
#define npyv_reinterpret_u8_u8(X)  X
#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
#define npyv_reinterpret_u8_f32 _mm256_castps_si256 // 将 256 位浮点向量重新解释为 256 位整数向量
#define npyv_reinterpret_u8_f64 _mm256_castpd_si256 // 将 256 位双精度浮点向量重新解释为 256 位整数向量

#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 _mm256_castps_si256 // 将 256 位浮点向量重新解释为 256 位整数向量
#define npyv_reinterpret_s8_f64 _mm256_castpd_si256 // 将 256 位双精度浮点向量重新解释为 256 位整数向量

#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 _mm256_castps_si256 // 将 256 位浮点向量重新解释为 256 位整数向量
#define npyv_reinterpret_u16_f64 _mm256_castpd_si256 // 将 256 位双精度浮点向量重新解释为 256 位整数向量

#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 _mm256_castps_si256 // 将 256 位浮点向量重新解释为 256 位整数向量
#define npyv_reinterpret_s16_f64 _mm256_castpd_si256 // 将 256 位双精度浮点向量重新解释为 256 位整数向量

#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 _mm256_castps_si256 // 将 256 位浮点向量重新解释为 256 位整数向量
#define npyv_reinterpret_u32_f64 _mm256_castpd_si256 // 将 256 位双精度浮点向量重新解释为 256 位整数向量

#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 _mm256_castps_si256 // 将 256 位浮点向量重新解释为 256 位整数向量
#define npyv_reinterpret_s32_f64 _mm256_castpd_si256 // 将 256 位双精度浮点向量重新解释为 256 位整数向量

#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
// 宏:将 64 位无符号整数重新解释为 16 位无符号整数,直接返回输入参数

#define npyv_reinterpret_u64_s16(X) X
// 宏:将 64 位无符号整数重新解释为 16 位有符号整数,直接返回输入参数

#define npyv_reinterpret_u64_u32(X) X
// 宏:将 64 位无符号整数重新解释为 32 位无符号整数,直接返回输入参数

#define npyv_reinterpret_u64_s32(X) X
// 宏:将 64 位无符号整数重新解释为 32 位有符号整数,直接返回输入参数

#define npyv_reinterpret_u64_s64(X) X
// 宏:将 64 位无符号整数重新解释为 64 位有符号整数,直接返回输入参数

#define npyv_reinterpret_u64_f32 _mm256_castps_si256
// 宏:将 64 位无符号整数重新解释为 32 位浮点数,使用 SSE 指令将输入参数转换为 __m256i 类型

#define npyv_reinterpret_u64_f64 _mm256_castpd_si256
// 宏:将 64 位无符号整数重新解释为 64 位双精度浮点数,使用 SSE 指令将输入参数转换为 __m256i 类型

#define npyv_reinterpret_s64_s64(X) X
// 宏:将 64 位有符号整数重新解释为 64 位有符号整数,直接返回输入参数

#define npyv_reinterpret_s64_u8(X)  X
// 宏:将 64 位有符号整数重新解释为 8 位无符号整数,直接返回输入参数

#define npyv_reinterpret_s64_s8(X)  X
// 宏:将 64 位有符号整数重新解释为 8 位有符号整数,直接返回输入参数

#define npyv_reinterpret_s64_u16(X) X
// 宏:将 64 位有符号整数重新解释为 16 位无符号整数,直接返回输入参数

#define npyv_reinterpret_s64_s16(X) X
// 宏:将 64 位有符号整数重新解释为 16 位有符号整数,直接返回输入参数

#define npyv_reinterpret_s64_u32(X) X
// 宏:将 64 位有符号整数重新解释为 32 位无符号整数,直接返回输入参数

#define npyv_reinterpret_s64_s32(X) X
// 宏:将 64 位有符号整数重新解释为 32 位有符号整数,直接返回输入参数

#define npyv_reinterpret_s64_u64(X) X
// 宏:将 64 位有符号整数重新解释为 64 位无符号整数,直接返回输入参数

#define npyv_reinterpret_s64_f32 _mm256_castps_si256
// 宏:将 64 位有符号整数重新解释为 32 位浮点数,使用 SSE 指令将输入参数转换为 __m256i 类型

#define npyv_reinterpret_s64_f64 _mm256_castpd_si256
// 宏:将 64 位有符号整数重新解释为 64 位双精度浮点数,使用 SSE 指令将输入参数转换为 __m256i 类型

#define npyv_reinterpret_f32_f32(X) X
// 宏:将 32 位浮点数重新解释为 32 位浮点数,直接返回输入参数

#define npyv_reinterpret_f32_u8  _mm256_castsi256_ps
// 宏:将 32 位浮点数重新解释为 8 位无符号整数,使用 SSE 指令将输入参数转换为 __m256 类型

#define npyv_reinterpret_f32_s8  _mm256_castsi256_ps
// 宏:将 32 位浮点数重新解释为 8 位有符号整数,使用 SSE 指令将输入参数转换为 __m256 类型

#define npyv_reinterpret_f32_u16 _mm256_castsi256_ps
// 宏:将 32 位浮点数重新解释为 16 位无符号整数,使用 SSE 指令将输入参数转换为 __m256 类型

#define npyv_reinterpret_f32_s16 _mm256_castsi256_ps
// 宏:将 32 位浮点数重新解释为 16 位有符号整数,使用 SSE 指令将输入参数转换为 __m256 类型

#define npyv_reinterpret_f32_u32 _mm256_castsi256_ps
// 宏:将 32 位浮点数重新解释为 32 位无符号整数,使用 SSE 指令将输入参数转换为 __m256 类型

#define npyv_reinterpret_f32_s32 _mm256_castsi256_ps
// 宏:将 32 位浮点数重新解释为 32 位有符号整数,使用 SSE 指令将输入参数转换为 __m256 类型

#define npyv_reinterpret_f32_u64 _mm256_castsi256_ps
// 宏:将 32 位浮点数重新解释为 64 位无符号整数,使用 SSE 指令将输入参数转换为 __m256 类型

#define npyv_reinterpret_f32_s64 _mm256_castsi256_ps
// 宏:将 32 位浮点数重新解释为 64 位有符号整数,使用 SSE 指令将输入参数转换为 __m256 类型

#define npyv_reinterpret_f32_f64 _mm256_castpd_ps
// 宏:将 32 位浮点数重新解释为 64 位双精度浮点数,使用 SSE 指令将输入参数转换为 __m256 类型

#define npyv_reinterpret_f64_f64(X) X
// 宏:将 64 位双精度浮点数重新解释为 64 位双精度浮点数,直接返回输入参数

#define npyv_reinterpret_f64_u8  _mm256_castsi256_pd
// 宏:将 64 位双精度浮点数重新解释为 8 位无符号整数,使用 SSE 指令将输入参数转换为 __m256d 类型

#define npyv_reinterpret_f64_s8  _mm256_castsi256_pd
// 宏:将 64 位双精度浮点数重新解释为 8 位有符号整数,使用 SSE 指令将输入参数转换为 __m256d 类型

#define npyv_reinterpret_f64_u16 _mm256_castsi256_pd
// 宏:将 64 位双精度浮点数重新解释为 16 位无符号整数,使用 SSE 指令将输入参数转换为 __m256d 类型

#define npyv_reinterpret_f64_s16 _mm256_castsi256_pd
// 宏:将 64 位双精度浮点数重新解释为 16 位有符号整数,使用 SSE 指令将输入参数转换为 __m256d 类型

#define npyv_reinterpret_f64_u32 _mm256_castsi256_pd
// 宏:将 64 位双精度浮点数重新解释为 32 位无符号整数,使用 SSE 指令将输入参数转换为 __m256d 类型

#define npyv_reinterpret_f64_s32 _mm256_castsi256_pd
// 宏:将 64 位双精度浮点数重新解释为 32 位有符号整数,使用 SSE 指令将输入参数转换为 __m256d 类型

#define npyv_reinterpret_f64_u64 _mm256_castsi256_pd
// 宏:将 64 位双精度浮点数重新解释为 64