工具鏈路線圖#

SciPy 函式庫的使用需要(或可選地依賴於)幾個其他的函式庫才能運作,主要的依賴項是 Python 和 NumPy。它需要更大量的函式庫和工具才能建置函式庫或建置文件。

當然,工具和函式庫本身並非靜態。本文旨在提供一個指南,說明 SciPy 如何隨著時間的推移使用這些動態依賴項。

SciPy 的目標是與多個版本的相依函式庫和工具相容。強迫使用者群每次發行版本都升級其他組件會大大降低 SciPy 的價值。然而,維持與非常舊的工具/函式庫的回溯相容性會限制可以納入哪些較新的功能和特性。SciPy 採取相對保守的方法,在主要平台上維持與多個主要 Python 和 NumPy 發行版本的相容性。(這本身可能會施加進一步的限制。請參閱 C 編譯器章節以取得範例。)

  • 首先也是最重要的,SciPy 是一個 Python 專案,因此它需要 Python 環境。

  • 需要安裝 BLAS 和 LAPACK 數值函式庫。

  • 需要 C、C++、Fortran 程式碼的編譯器,以及 Cython 和 Pythran 的編譯器(後者目前可以選擇不使用)

  • Python 環境需要安裝 numpy 套件。

  • 測試需要 pytesthypothesis Python 套件。

  • 建置文件需要 matplotlib、Sphinx 和 MyST-NB 套件以及 PyData 主題。

用於建置 CPython 的工具對用於建置 SciPy 的工具產生了一些影響。它也對文件中使用的範例(例如,函式的 docstring)產生了影響,因為這些範例只能使用所有支援的配置中都存在的功能。

建置 SciPy#

Python 版本#

SciPy 與多個 Python 版本相容。在停止支援舊版 Python 時,SciPy 遵循 [NEP29] 的指導。通常,對最舊 Python 版本的支援會在原始發行版本的 42 個月後停止。根據 PEP 602 的接受,這通常發生在四月,並在 SciPy 的年中發行版本中被採用。

Python 版本支援隨時間的變化

從 SciPy 1.3 開始,已停止支援 Python 2.7。

日期

支援的 Python 版本

2024

Py3.10+

2023

Py3.9+

2022

Py3.8+

2021

Py3.7+

2020

Py3.6+

2019

Py3.5+

2018

Py2.7, Py3.4+

NumPy#

SciPy 依賴於 NumPy,但 SciPy 的發行版本與 NumPy 的發行版本無關。SciPy 嘗試與至少前 4 個 NumPy 發行版本相容。特別是,SciPy 不能僅依賴最新 NumPy 的功能,而是需要使用所有這 4 個 NumPy 發行版本 中通用的功能編寫。

每個 SciPy 版本的 Python 和 NumPy 版本支援

該表格顯示了適用於每個主要 Python 版本的 NumPy 版本。此表格未區分 SciPy 修補程式版本(例如,當發行新的 Python 版本時,SciPy 通常會發行相容的修補程式版本)。

SciPy 版本

Python 版本

NumPy 版本

1.13

>=3.9, <3.13

>=1.22.4, <2.3.0

1.12

>=3.9, <3.13

>=1.22.4, <2.0.0

1.11

>=3.9, <3.13

>=1.21.6, <1.27.0

1.10

>=3.8, <3.12

>=1.19.5, <1.26.0

1.9

>=3.8, <3.12

>=1.18.5, <1.26.0

1.8

>=3.8, <3.11

>=1.17.3, <1.24.0

1.7

>=3.7, <3.11

>=1.16.5, <1.23.0

1.6

>=3.7, <3.10

>=1.16.5, <1.21.0

1.5

>=3.6, <3.10

>=1.14.5, <1.20.0

1.4

>=3.5, <3.9

>=1.13.3, <1.18.0

1.2

2.7, >=3.4, <3.8

>=1.8.2, <1.17.0

在特定情況下,例如特定架構,這些需求可能會有所不同。請查看發行說明和 meta-package oldest-supported-numpy 以取得更多資訊 [OSN]

編譯器#

建置 SciPy 需要 C、C++、Fortran 的編譯器,以及 python 轉譯器 Cython 和 Pythran(後者是從 1.7.0 版本開始可以選擇不使用的依賴項)。

為了維持與大量平台和設定的相容性,特別是在無法使用官方 wheels(或其他發行管道,如 Anaconda 或 conda-forge)的情況下,SciPy 嘗試在尚未達到官方終止生命週期的平台上,保持與舊版編譯器的相容性。

如下面更詳細的解釋,目前最低編譯器版本是

編譯器

預設平台(已測試)

次要平台(未測試)

最低版本

GCC

Linux

AIX, Alpine Linux, OSX

GCC 9.x

LLVM

OSX

Linux, FreeBSD, Windows

LLVM 12.x

MSVC

Windows

Visual Studio 2019 (vc142)

請注意,目前沒有專門的 CI 作業來測試最低支援的 LLVM/Clang 版本。只要它們支援核心(非 stdlib)C++17,比 SciPy CI 中使用的版本更舊的版本應該也可以運作。如果您在編譯期間遇到問題,請提交 issue。

官方建置版本#

目前,SciPy wheels 的建置方式如下

平台

CI 基礎 映像檔

編譯器

註解

Linux x86

ubuntu-22.04

GCC 10.2.1

cibuildwheel

Linux arm

docker-builder-arm64

GCC 11.3.0

cibuildwheel

OSX x86_64 (OpenBLAS)

macos-12

Apple clang 13.1.6/gfortran 11.3.0

cibuildwheel

OSX x86_64 (Accelerate)

macos-13

Apple clang 15.0.0/gfortran 13.2.0

cibuildwheel

OSX arm64 (OpenBLAS)

macos-14

Apple clang 15.0.0/gfortran 12.1.0

cibuildwheel

OSX arm64 (Accelerate)

macos-14

Apple clang 15.0.0/gfortran 13.2.0

cibuildwheel

Windows

windows-2019

GCC 10.3.0 (rtools)

cibuildwheel

請注意,OSX wheels 額外供應了 gfortran 11.3.0 用於 x86_64,以及 gfortran 12.1.0 用於 arm64。請參閱 tools/wheels/cibw_before_build_macos.sh

C 編譯器#

SciPy 與大多數現代 C 編譯器(特別是 clang)相容。如今,所有相關編譯器都對最新的 C 語言標準有合理的支援,儘管這與過去的情況大相逕庭。以下段落主要討論這些約束條件的演變;不關心歷史背景的讀者可以跳到最後的表格。

關於 ABI 與編譯器支援與 C 標準的歷史背景

過去,在 C 支援方面,相關平台上最嚴格的編譯器是 Microsoft Visual C++ 編譯器和工具組(統稱為 MSVC;它有一個複雜的版本方案[MSVC]。直到 Visual Studio 2013,每個 MSVC 版本都帶有一個更新的 C Runtime (CRT) 函式庫,該函式庫與之前的版本不相容。

這種應用程式二進位介面 (ABI) 的不相容性意味著,所有想要跨此介面進行通訊的專案(例如,從共享函式庫呼叫函式)都需要使用相同的 MSVC 版本進行(重新)編譯。長期支援 CPython 2.7 意味著 python 本身長期受限於 VS 2008(為了不在修補程式版本中破壞 ABI),因此 SciPy 也受限於該版本。

使用 VS 2008(它不支援 C99)來編譯 CPython 2.7 的建置版本,長期以來意味著 SciPy 中的 C 程式碼必須符合語言和標準函式庫的早期 C90 標準。在 SciPy 1.3.x 中停止支援 CPython 2.7 後,該限制最終被解除(儘管最初只是逐漸解除)。

隨著自 Visual Studio 2015 發行以來引入的 “Universal C Runtime” [UCRT],C Runtime 的 ABI 已經穩定,這意味著 SciPy 不再需要像底層 CPython 版本那樣使用相同的編譯器版本。然而,這種穩定性並非無限期:Microsoft 一直在計劃一個 ABI 破壞性的發行版本 - 跨編譯器 resp. C/C++ 標準函式庫 - (暫定名為 “vNext”),但到目前為止,尚不清楚它何時會到來。一旦發生這種情況,SciPy 將再次最多只能使用最後一個 ABI 相容的 Visual Studio 發行版本(目前為 VS 2022),直到根據 NEP29 支援的所有 CPython 版本都已使用 vNext 相容的編譯器在 upstream 建置。

更具體地說,Microsoft Visual Studio 版本和目標 “工具組” 的版本之間存在區別,後者定義為 “The Microsoft C++ compiler, linker, standard libraries, and related utilities”(Microsoft C++ 編譯器、連結器、標準函式庫和相關工具)。每個版本的 Visual Studio 都帶有一個預設版本的 MSVC 工具組(例如,VS2017 帶有 vc141,VS2019 帶有 vc142),但即使在較新版本的 Visual Studio 中,也可以以較舊的工具組為目標。由於編譯器的性質(即,分為前端和後端),因此支援給定功能(例如,在 C 中)的限制因素是 Visual Studio 的版本還是工具組,但通常後者是更難的障礙,因此是有效的下限。

這是由於以下事實:雖然 ABI 在工具組版本之間保持相容(直到 vNext),但所有連結操作都必須使用至少與用於建置任何涉及的工件的工具組一樣新的工具組,這意味著工具組版本提升往往具有 “傳染性”,例如:要求所有使用的函式庫也提升其工具組(以及可能的編譯器)版本。這對於 NumPy 來說比 SciPy 更是一個問題,因為後者只有一個小的 C API,並且與 NumPy 相比,被更少的專案編譯。此外,使用較新的工具組意味著編譯 C++ 程式碼的函式庫(如 SciPy)的使用者可能還需要較新的 Microsoft Visual C++ Redistributable,這可能必須分發給他們。

總而言之,每個 SciPy 版本的 MSVC 編譯器 resp. 工具組的最低要求主要由當時支援的最舊 CPython 版本決定。第一個將最低要求提高到超出該要求的 SciPy 版本是 SciPy 1.9,這是由於包含了 HiGHS 子模組,該子模組無法使用 vc141 編譯(並且在公共 CI 中積極刪除 VS2017,使其無法繼續確保所有地方的所有內容都使用非預設工具組版本運作)。

SciPy 版本

CPython 支援

MS Visual C++

工具組版本

直到 1.2

2.7 & 3.4+

VS 2008 (9.0)

vc90

1.3, 1.4

3.5+

VS 2010 (10.0)

vc100

1.5

3.6+

VS 2015 (14.0)

vc140

1.6, 1.7

3.7+

VS 2017 (14.1)

vc141

1.8

3.8+

VS 2017 (14.1)

vc141

1.9

3.8+

VS 2019 (14.20)

vc142

就 C 語言標準而言,值得注意的是 C11 具有 可選功能(例如 atomics、threading),其中一些(VLAs 和複雜類型)在 C99 標準中是強制性的。C17(偶爾稱為 C18)可以被認為是 C11 的錯誤修復,因此通常可以完全跳過 C11。

SciPy 在使用更進階的語言功能方面受到可用編譯器支援的限制,特別是 Microsoft 花費了很長時間才實現對 C99/C11/C17 的符合性,但是從 Visual Studio 16.8 開始,支援 C11/C17(儘管沒有 C11 可選功能)。C99 <complex.h> 支援 對於 SciPy 來說特別有趣。但是,仍然可以在 Windows 上使用複雜類型,前提是使用 Windows 特定的類型

因此,使用超出 C90 的 C 功能僅在 Windows 上有支援的情況下才有可能;但是,截至 2021 年底,使用了足夠新的編譯器。這是因為 GCC 和 LLVM 使用目前使用的最舊版本支援所有相關的 C11 功能,並且如上所述,C17 只是 C11 的錯誤修復。簡而言之

日期

C 標準

<= 2018

C90

2019

舊程式碼使用 C90,新程式碼可以考慮 C99

2020

C99(沒有 <complex.h><stdatomic.h><threads.h> 和 VLAs)

2021

C17(沒有 <complex.h><stdatomic.h><threads.h> 和 VLAs)

?

C23、<complex.h><stdatomic.h>、…

C++ 語言標準#

SciPy 的 C++ 語言標準通常是指導方針,而不是官方決策。對於嘗試預測較新標準的採用時間表尤其如此。

日期

C++ 標準

<= 2019

C++03

2020

C++11

2021

C++14

2022

C++17(核心語言 + 通用可用的 stdlib 功能)

?

C++17(具有完整 stdlib)、C++20、C++23、C++26

由於 manylinux 導致編譯器限制的歷史背景

自停止支援 Python 2.7 以來,C++11 可以通用使用,並且自停止支援 Python 3.6 以來,Visual Studio 版本(之前由於與 CPython 的 ABI 相容性而受限於 14.0)已經足夠新,甚至可以支援 C++17。

由於官方建置版本(見上文)使用相當新的 LLVM 版本,因此 C++ 支援的瓶頸是最舊的支援 GCC 版本,其中 SciPy 主要受到最舊的支援 manylinux 版本和映像檔 [MANY] 中的版本限制。

在 2021 年底(隨著最終移除 manylinux1 wheels),GCC 的最低要求提升到 6.3,它具有完整的 C++14 支援 [CPP]。這對應於相關 manylinux 版本中存在的最低 GCC 版本,儘管這仍然考慮到基於 Debian 的 “outlier” manylinux_2_24,它 - 與之前基於 RHEL 衍生產品 CentOS 的 manylinux 映像檔不同,後者可以從 “RHEL 開發工具組” 中的 ABI 相容 GCC backports 中受益 - 受限於 GCC 6.3。該映像檔未能成功,不僅僅是因為那些 過時的編譯器,並且在 2022 年年中達到其 EOL。由於不同的原因,manylinux2010 也在大約 同一時間 達到其 EOL。

剩餘的映像檔 manylinux2014manylinux_2_28 目前分別支援 GCC 10 和 12。後者將繼續接收更新,因為新的 GCC 版本作為 backports 提供,但前者可能不會改變,因為 CentOS 專案不再回應發布 aarch64 backports 的 GCC 11。

這使得所有主要平台及其編譯器都具有相對較新的版本。然而,SciPy 歷史上也一直努力支援不太常見的平台 - 如果不是使用二進制工件(即 wheels),那麼至少通過保持可從原始碼編譯 - 其中包括例如 AIX、Alpine Linux 和 FreeBSD。

平台支援和其他編譯器約束

對於 AIX 7.2 和 7.3,預設編譯器是 GCC 10(AIX 7.1 在 2023 年達到其 EOL),但 GCC 11/12 可以 並排 安裝,類似地,還有基於 LLVM 17 的 Open XL for AIX。

最舊的目前支援的 Alpine Linux 發行版本是 3.16,並且已經 附帶 GCC 11。對於 FreeBSD,最舊的目前支援的 13.x 發行版本 附帶 LLVM 14(並且 GCC 13 可作為 freebsd-port 提供)。

最後,還有一個問題是,哪些機器被需要從原始碼編譯 SciPy 的人們廣泛使用,原因有很多(例如 SciPy 開發人員,或想要為了效能原因自行編譯的人)。最舊的相關發行版本(沒有 RHEL 風格的 backports)是 Ubuntu 20.04 LTS(它具有 GCC 9,但也具有 GCC 10 的 backport;Ubuntu 22.04 LTS 具有 GCC 11)和 Debian Bullseye(具有 GCC 10;Bookworm 具有 GCC 12)。這是確定編譯器支援下限的最弱限制(可以預期進階使用者和開發人員將使其系統至少保持在一定程度上最新,或在可用的情況下使用 backports),並且隨著舊發行版本的使用數量減少,其重要性逐漸降低。

目前所有支援的最低編譯器版本(GCC 9、LLVM 14、VS2019 with vc142)都完全支援 C++17 核心語言,因此可以無條件使用。然而,截至 2024 年年中,並非所有編譯器都已完成對整個 C++17 標準函式庫的支援 [CPP],尤其是 LLVM。因此,必須檢查給定的 stdlib 功能是否受到所有編譯器的支援,然後才能在 SciPy 中使用它。

C++20 支援的穩定速度非常緩慢,即使撇開模組、協程和幾個尚未普遍支援的 stdlib 功能不談。鑑於 C++20 標準是一個多麼大的發行版本,預計還需要一段 時間,我們才能開始考慮移動我們的基準。C++23 和 C++26 的編譯器支援仍在積極開發中 [CPP]

Fortran 編譯器#

通常,任何維護良好的編譯器都可能是合適的,可以用於建置 SciPy。也就是說,我們不使用舊的 gfortran 版本進行測試,這就是為什麼我們將下限與上面 GCC 的下限相匹配的原因。

工具

版本

gfortran

>= 9.x

ifort/ifx

最新版本(未在 CI 中測試)

flang (LLVM)

>= 17.x

Cython 和 Pythran#

SciPy 始終需要最新的 Cython 編譯器。自 1.7 以來,Pythran 是一個建置依賴項(目前可以選擇不使用)。

OpenMP 支援#

由於 各種原因,SciPy 無法與內建的 OpenMP 支援一起發行。當使用可選的 Pythran 支援時,從原始碼建置時可以生成啟用 OpenMP 的並行程式碼。

其他函式庫#

可以使用任何符合 BLAS/LAPACK 介面的函式庫。已知 OpenBLAS、ATLAS、MKL、BLIS 和參考 Netlib 函式庫可以運作。

函式庫

最低版本

LAPACK

3.7.1

BLAS

最新版本的 OpenBLAS、MKL 或 ATLAS。不再支援 Accelerate BLAS 函式庫。

還有一些額外的可選依賴項。

函式庫

版本

網址

mpmath

最新

http://mpmath.org/

scikit-umfpack

最新

https://pypi.org/project/scikit-umfpack/

pooch

最新

https://pypi.org/project/pooch/

此外,SciPy 支援與其他函式庫互動。測試套件具有額外的相容性測試,當安裝這些函式庫時會執行這些測試

工具

版本

網址

pydata/sparse

最新

pydata/sparse

測試和基準測試#

測試和基準測試需要最新版本的

工具

版本

網址

pytest

最新

https://pytest.dev.org.tw/en/latest/

Hypothesis

最新

https://hypothesis.readthedocs.io/

asv (airspeed velocity)

最新

https://asv.readthedocs.io/

建置文件#

工具

版本

Sphinx

任何最新版本都可以運作。 >= 5.0。

PyData Sphinx 主題

任何最新版本都可以運作。 >= 0.15.2。

Sphinx-Design

任何最新版本都可以運作。 >= 0.4.0。

numpydoc

任何最新版本都可以運作。 >= 1.5.0。

matplotlib

一般建議 >= 3.5。

MyST-NB

任何最新版本都可以運作。 >= 0.17.1

jupyterlite-sphinx

任何最新版本都可以運作。 >= 0.13.1

jupyterlite-pyodide-kernel

任何最新版本都可以運作。 >= 0.1.0

注意

開發者注意事項:所需的 numpymatplotlib 版本對 Python docstring 中的範例有影響。範例必須能夠在用於建置文件的環境中以及使用者可能與此 SciPy 發行版本一起使用的任何支援版本的 numpy/matplotlib 中執行。

封裝#

最新版本的

工具

版本

網址

setuptools

最新

https://pypi.org/project/setuptools/

wheel

最新

https://pythonwheels.com

multibuild

最新

matthew-brett/multibuild

製作 SciPy 發行版本發行 包含有關製作和發行 SciPy 發行版本的資訊。

參考文獻#