使用 Cythonized Python Wheels 指定精确的 CPU 指令集

2024-05-16

我有一个带有本机扩展的 Python 包,由Cython https://cython.org/。由于一些性能需要,编译是用-march=native, -mtune=native旗帜。这基本上使编译器能够使用任何可用的 ISA 扩展。

此外,我们保留了该包的非 cythonized、纯 python 版本。它应该用在对性能不太敏感的环境中。

因此,我们总共发布了两个版本:

  • Cythonized 轮是为非常特定的平台构建的
  • 纯蟒蛇轮。

其他一些包依赖于这个包,并且某些机器与编译该包的机器有点不同。自从我们使用-march=native,结果我们得到SIGILL,因为服务器上缺少某些 ISA 扩展。

所以,本质上,我想以某种方式使pip如果主机 CPU 与轮子不兼容,则忽略本机轮子。

原生轮子确实有cp37和平台名称,但我在这里没有看到定义更细粒度 ISA 要求的方法。我可以随时使用--implementationpip 的标志,但我想知道 pip 是否有更好的方法来区分不同的 ISA。

Thanks,


pip 基础设施不支持这种粒度。

我认为更好的方法是编译两个版本的 Cython 扩展:-march=native和不安装,安装两者并在运行时决定应加载哪一个。

这是一个概念证明。

第一个要跳的环节:如何在运行时检查 CPU/OS 组合支持哪些指令。为了简单起见,我们将检查 AVX(这SO-post https://stackoverflow.com/q/6121792/5769463有更多详细信息)并且我仅提供特定于 gcc 的(另请参阅this https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85100) 解决方案 - 称为impl_picker.pyx:

cdef extern from *:
    """
    int cpu_supports_avx(void){
        return __builtin_cpu_supports("avx");
    }
    """
    int cpu_supports_avx()

def cpu_has_avx_support():
    return cpu_supports_avx() != 0

第二个问题:pyx 文件和模块必须具有相同的名称。为了避免代码重复,实际代码位于 pxi 文件中:

# worker.pxi
cdef extern from *:
    """   
    int compiled_with_avx(void){
        #ifdef __AVX__
            return 1;
        #else
            return 0;
        #endif
    }
    """
    int compiled_with_avx()

def compiled_with_avx_support():
    return compiled_with_avx() != 0

正如我们所看到的,该函数compiled_with_avx_support will 产生不同的结果 https://stackoverflow.com/q/28939652/5769463,取决于它是否是用编译的-march=native or not.

现在我们只需包含 *.pxi 文件中的实际代码即可定义该模块的两个版本。一个模块称为worker_native.pyx:

# distutils: extra_compile_args=["-march=native"]

include "worker.pxi"

and worker_fallback.pyx:

include "worker.pxi"

构建一切,例如通过cythonize -i -3 *.pyx,可以按如下方式使用:

from impl_picker import cpu_has_avx_support

# overhead once when imported:
if cpu_has_avx_support():
    import worker_native as worker
else:
    print("using fallback worker")
    import worker_fallback as worker

print("compiled_with_avx_support:", worker.compiled_with_avx_support())

在我的机器上,上述内容会导致compiled_with_avx_support: True,在较旧的机器上“较慢”worker_fallback将被使用,结果将是compiled_with_avx_support: False.


这篇文章的目的不是提供一个可行的setup.py,但只是概述如何实现在运行时选择正确版本的目标的想法。显然,setup.py 可能会更加复杂:例如需要使用不同的编译器设置编译多个 c 文件(请参阅此SO-post https://stackoverflow.com/a/59364990/5769463,如何实现这一点)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Cythonized Python Wheels 指定精确的 CPU 指令集 的相关文章

随机推荐

  • 使用主题 css 文件需要页面上的标头控件。 (例如 )

    我正在开发 asp net 网络项目 当我运行该项目时 它工作正常 但在服务器中 我收到以下错误 如何解决这个问题呢 Using themed css files requires a header control on the page
  • 如何知道 Dart 中的复选框或单选按钮是否被选中?

    我有一个复选框和一个单选按钮组 我想知道是否选中了该复选框以及选择了哪个单选按钮 我如何在 Dart 中做到这一点 假设我们有这样的 HTML
  • 我可以将参数作为数组传递吗?

    例如 而不是 assert eq add 2 3 5 有什么方法可以调用类似的东西 let params u32 2 2 3 assert eq call add params 5 我发现这个功能对于测试非常有用 例如 如果我想为需要大量参
  • R 错误:无法更改锁定绑定的值

    我试图估计无限数字流的平均值和标准差 当我运行代码时 出现错误消息 无法更改锁定绑定的值 我做了一些研究 发现这个错误与我使用全局变量有关 但我无法弄清楚 任何帮助将非常感激 在此先感谢您的帮助 define global variable
  • [Regex]::Replace() 和 -replace 有什么区别?

    我明白了之间的区别 Replace and replace 但是什么是 replace and Regex Replace 我测试了以下两个代码 但对我来说结果完全相同 我还提到了 PowerShell Cookbook O reilly
  • 如何读取 R 中的每个 .csv 文件并将其导出到单个大文件中

    你好 我有以下格式的数据 101 20130826T155649 3 1 round 0 10552 180 yellow 12002 1 round 1 19502 150 yellow 22452 1 round 2 28957 130
  • Android中如何将文件写入raw文件夹?

    我认为这是一个非常基本的问题 我目前正在编写这样的文件 File output new File exampleout mid 现在 我想将文件写入 myproject res raw 我读到我可以通过将完整的网址放在 中来做到这一点 但
  • OpenCart 2.2.0.0中类别和产品页面的特定模板

    我正在使用 OpenCart 版本 2 2 0 0 并尝试为每个类别和产品页面设置不同的模板 网上搜索发现如下代码 if file exists DIR TEMPLATE this gt config gt get config templ
  • 使用 OpenCV 改进特征点匹配

    我想匹配立体图像中的特征点 我已经用不同的算法找到并提取了特征点 现在我需要一个良好的匹配 在本例中 我使用 FAST 算法进行检测和提取 BruteForceMatcher用于匹配特征点 匹配代码 vector lt vector
  • React router v6 和路由内页面的相关链接

    您好 我正在尝试使用 React Router 将项目更新到 v6 我了解了基础知识 但在相关链接方面遇到了困难 我们有一个页面 通过 id 呈现给定项目的参考文档 该文档可以使用同级 ID 链接到其他 同级 材料 换句话说 用户可以在文档
  • 处理双 NaN 和 Inf 时的 ILASM 问题

    我创建了一个简单的程序 并初始化了双精度类型值 var a double NaN 我使用 Visual Studio 2019 net Framework 4 5 构建项目 并使用 ILDASM exe 版本 4 0 30319 0 将其反
  • 导出 Maven 依赖项并维护存储库文件夹结构

    我想知道是否可以导出 复制使用 Maven 管理的项目的依赖项 同时维护本地存储库中采用的文件夹结构 我的需求的根源近十年来 我在本地存储库 8GB 中积累了很多工件 我不再处理以前分配的那些吸引了大部分工件的旧项目 现在 我需要将一个项目
  • PostgreSql“运行安装后步骤...数据库集群初始化失败”

    我是一名 Windows 用户 我花了几个小时不断地安装和卸载 然后才使其正常工作 前 10 次左右才看到标题中的错误消息 我将其作为一个自我回答的问题放在这里 以防止其他人在安装时可能遇到同样的问题 并为像我这样第一次使用 Postgre
  • 根据 row_number() 过滤 data.frame

    更新 自从提出这个问题以来 dplyr 已经更新 现在按照 OP 的要求执行 我正在尝试获取第二行到第七行data frame using dplyr 我正在这样做 require dplyr df lt data frame id 1 1
  • 为 npm install 添加本地项目依赖

    在 npm 中添加本地项目依赖项的正确语法是什么package json file 我本地有 git 项目C projects MyApp 我想得到这个项目npm install 我尝试以下 dependencies my app file
  • 为什么我不能将左大括号放在下一行?

    当我尝试编译以下代码时遇到奇怪的错误 package main import fmt fmt func main var arr 3 int for i 0 i lt 3 i fmt Printf d arr i 错误如下 unexpect
  • 如果目标上的消费者已关闭,则通知 ActiveMQ 生产者

    我正在使用 ActiveMQ 消息代理 并且我有一个要求 即生产者应用程序想要知道在特定目标上使用的消费者应用程序是否已启动 我怎样才能实现这个目标 Thanks 你应该结帐咨询信息 http activemq apache org adv
  • Laravel 5.6 - 注册表无法正常工作并且不显示任何错误

    在我最近的一个项目中 定制登记表不管用 当我单击注册按钮时 它会重新加载注册表单 不会打印任何错误 并且不会将数据插入数据库中 这是注册表的外观 这里是移民文件代码 public function up Schema create user
  • 将我的值类型转换为可空等效类型

    我有一个临时报告系统 我对查询的源类型或所需字段没有编译时知识 我可以使用在运行时编写表达式树System Linq Expressions Expression工厂方法 并使用反射调用 LINQ 方法 但动态 LINQ 是一个更简单的解决
  • 使用 Cythonized Python Wheels 指定精确的 CPU 指令集

    我有一个带有本机扩展的 Python 包 由Cython https cython org 由于一些性能需要 编译是用 march native mtune native旗帜 这基本上使编译器能够使用任何可用的 ISA 扩展 此外 我们保留