韋建文, 王 杰, 文敏華, 王一超, 林新華
(上海交通大學網絡信息中心,上海200240)
上海交通大學高性能計算平臺的計算能力位居全國高校前列[1],自2013年上線以來,常年滿負荷運行,已累計為校內300多個課題組提供超過5億核小時的計算服務。為支持用戶高效完成計算任務,除了穩定可靠的硬件環境,還需要靈活易用的軟件環境。在每年2 000多人次技術咨詢中,“如何安裝軟件”占了60%。為應對這種情況,中心配備了一名員工專職從事應用編譯,在過去一年新增了71個計算軟件庫,進行了205次版本更新,可用軟件包總數超過200個。
2019年9月上線的第二代校級高性能計算平臺,計算能力提升了10倍,理論性能達到2PFlops。可以預期的是,用戶必將對軟件種類和易用性提出更高的要求。如何構建一個軟件種類豐富、運行高效、調用方便的軟件環境,是維護高性能計算平臺的一個難題。本文將著重介紹構建高性能計算軟件環境的主要挑戰、軟件包管理器的概念、如何使用Spack軟件包管理器以及使用Spack構建上海交通大學的超算軟件環境。
如圖1所示,編譯一個高性能計算軟件需要準備好軟件源代碼以及依賴軟件庫,通過構建工具編譯出可執行程序,整理出軟件模塊文件供用戶調用。

圖1 軟件編譯流程
構建一個面向高性能計算軟件環境存在如下挑戰:
(1)軟件數量多。常用的高性能計算軟件多達上百種,若算上軟件在版本、編譯器、優化選項上的變種,構建軟件環境需要重復上千次準備源代碼、編譯、撰寫模塊的操作。
(2)編譯流程差異大。常用的軟件編譯工具就有Autotools[12]、CMake[13]、Maven[14]、SCons[15]等10 余種,用法上差異較大,需要投入大量時間才能熟練掌握這些工具。
(3)維護環境模塊工作量大。供最終用戶使用的環境模塊文件,必須與軟件版本一一對應,手動維護模塊文件難以保證內容的正確性。
(4)軟件版本共存。出于性能、穩定性和結果一致性的考慮,高性能計算平臺需要提供同一個軟件的多個版本供用戶使用,這需要在安裝時設計好安裝路徑,避免路徑沖突。
(5)軟件管理角色不清晰。在現有方法中,系統管理員擁有特權可以部署全局可用的軟件,普通用戶因無特權而很難從基礎庫開始構建自定義的軟件環境。
為了應對構建軟件環境的挑戰,一類被稱為軟件包管理器(Software Package Manager)的工具應運而生。這類工具屏蔽了不同軟件在獲取、編譯和加載過程中的差異,為用戶提供了一個統一的軟件包管理接口,在類UNIX操作系統上獲得了廣泛應用,例如Yum、Apt、BSD Ports等。一些針對高性能計算軟件環境的包管理器在此基礎上改進,如OpenHPC、Anaconda、EasyBuild、Spack 等。此外,Docker和Singularity等基于容器技術的軟件部署方法,也獲得了越來越多的關注。這些軟件包管理器的主要特性見表1。

表1 軟件包管理器對比
OpenHPC[6]是一個基于Yum的軟件包管理工具,以預編譯包提供x86和ARM平臺的常用高性能計算庫。OpenHPC需要使用管理員權限安裝,系統中只能保留軟件的一個版本。
Anaconda[7]是基于Pip的軟件包管理器,用于管理Python擴展包和一般的科學計算軟件包。Anaconda可以把軟件安裝在用戶家目錄,不需要管理員特權,并可以創建多個相互隔離的軟件環境。
Docker[8]和Singularity[9]是基于容器技術的軟件封裝技術,他們將軟件連同系統庫一起打包,構建出一個共享宿主節點內核的運行環境。應用只需要打包一次就能在支持容器技術、同一指令集架構的操作系統上運行。
EasyBuild[10]和Spack[11]借鑒了BSD Ports,將軟件編譯過程中的關鍵步驟抽象成一系列函數,用戶使用函數而非具體執行的命令描述編譯過程,在實際執行時包管理器根據用戶編寫的流程完成下載源代碼包、解壓、編譯、安裝的流程。這兩個工具都可以方便地以普通用戶權限安裝軟件,且已支持超過1 000種科學計算軟件。Spack安裝簡單,命令行提供了豐富的編譯選項,評估試用后被選中用于構建上海交通大學高性能計算平臺的軟件環境。
Spack只需要Python和GCC編譯器就能工作,安裝過程非常簡單,不需要管理員特權,只要將源代碼克隆到本地即可使用。
$ git clone https://github.com/spack/spack.git
$ cd spack/bin
$ ./spack-v
Spack使用install命令安裝軟件包,這個命令可指定軟件版本、軟件功能、優化選項、編譯器、依賴軟件包等編譯參數。如圖2所示,使用Spack安裝aoflagger[12]2.10.0 版本,指定編譯器優化參數(cflags)為“-O2”,使用符號“%”指定編譯器為Intel編譯器18.0.3,使用“^”符號指定依賴軟件為casacore 2.4.1版本,并要求在casacore上開啟對python的支持。

圖2 Spack安裝軟件示例
編譯軟件時,Spack根據命令行指定的選項,讀取與軟件包對應的package.py包文件,解析軟件包下載地址、特性選項、依賴和沖突、編譯方式,然后編譯軟件。aoflagger軟件的包文件片段如圖3所示。

圖3 Aoflagger的package.py示例片段
其中,class指定軟件包類型,以決定使用什么工具編譯這個軟件,Spack支持的軟件包類型包括AutotoolsPackage、CMakePackage、MakePackage 以及一般的Package等;home和url分別用于指定軟件主頁和下載地址;version指定軟件包的版本和校驗和,確保用戶下載的軟件源碼包是正確的;variant用于描述軟件支持的特性,常見的如是否開啟對openmp、mpi、python的支持等,使用者可以在spack install選項中通過“+”或“~”符號開啟或關閉這些特性;depends_on和conflicts指令用于描述這個軟件依賴的其他軟件包,或是與之沖突的軟件包、編譯器等。
Spack將遞歸地構建出一個包含軟件及其依賴包的有向無圈圖(directed acyclic graph,DAG),以此指導編譯過程。編譯aoflagger的有向無圈圖如圖4所示,Spack將從下到上依次編譯依賴包最后編譯aoflagger。

圖4 Aoflagger軟件包依賴關系
高性能計算系統普遍使用環境模塊[13](Environment Module)調用軟件,環境模塊通過修改“PATH”“CPATH”“LD_LIBRARY_PATH”等環境變量動態地調用軟件。為軟件的每一個版本及其依賴庫手工編寫模塊文件,其工作量很大,Spack通過RPATH和自動生成模塊降低了軟件調用的難度。Spack在編譯時使用RPATH參數將依賴庫的路徑寫入了編譯出的二進制程序中而無須依賴環境模塊提供的LD_LIBRARY_PATH。每一個安裝的軟件唯一地對應了一個有向無圈圖,Spack在軟件安裝路徑中添加了這個圖的散列值,從而保證同一軟件的不同編譯版本或變種能唯一地確定,不會發生路徑沖突。Spack根據軟件的構建選項和安裝路徑,可自動生成環境模塊供用戶調用。下面的示例展示了通過module命令加載和使用軟件的流程。
$module avail gromacs
gromacs/4.5.5-intel-19.0.4 groamcs/4.5.5-gcc-8.3.0
$ module load gromacs/4.5.5-intel-19.0.4
$ which mdrun_mpi
/lustre/spack/opt/sandybridge/intel-19.0.4/gromacs-4.5.5-f239hfe823gf/bin
使用軟件編譯時間與軟件運行時間來考察Spack性能,與之對比的是手動編譯和Docker編譯。用于測試的程序是基因數據處理軟件Samtools[14]和計算流體軟件OpenFOAM[15],前者運行一個單機多線程算例,后者運行一個4節點MPI算例。
編譯耗時如圖5所示。Samtools編譯耗時差異很小,Docker因為需要下載鏡像,最耗時。OpenFOAM編譯耗時差異大,Docker可以直接使用操作系統預編譯的OpenMPI庫因而最快;Spack可以自動解決依賴包,可在無人值守狀態下完成編譯,也比手工方式快。

圖5 編譯時間
運行耗時如圖6所示。單節點Samtools運行耗時差異很小,Docker多了首次啟動需要的15 s時間。4節點OpenFOAM運行耗時差異大,手動編譯和Spack安裝的版本基本持平,分別需要603 s和598 s完成計算;而Docker版需要1 028 s,慢了41%。經檢查發現,Docker版本使用的操作系統自帶OpenMPI庫沒有加入對Infiniband網絡的支持,運行過程中使用了低速的千兆網導致多節點運行效率降低。

圖6 運行時間
綜上,手動編譯和Spack編譯都能發揮出了高性能計算平臺的應有性能。而Docker為保證兼容性優先選擇了操作系統預編譯的軟件包,這在配備了Infiniband等特殊硬件的高性能計算平臺上并不是最優方案。使用Spack作為構建Docker鏡像工具,以解決Docker應用在高性能計算平臺上多節點運行效率低的問題,是一個可行的方向。
上海交大高性能計算中心摸索出了一套使用Spack構建高性能計算軟件環境的方法,在國內率先使用Spack安裝生產環境上的軟件,構建流程如圖7所示。

圖7 基于Spack按角色分工的高性能計算軟件環境構建方法
首先,Spack使用者被分為3類:Spack開發者,負責定期從Spack社區更新軟件包,測試軟件包穩定性,并補充Spack缺失的軟件包;系統管理員,根據Spack開發者反饋的測試結果,將軟件的穩定版本部署到系統中供所有用戶使用;普通用戶,既可以直接使用Spack部署在系統中的應用,也可以只使用Spack部署的編譯器或科學庫,或者完全從頭用Spack部署自己的軟件環境。3個角色在相互隔離的環境中測試與合作,管理員只部署通過驗證的軟件,而開發者進行的測試不會影響生產環境,普通用戶可自由選擇復用或重新構建整個軟件環境。
按類別選擇需要部署的軟件。軟件環境中的軟件數量并非越多越好,環境中共存的軟件數量越多,生成模塊文件和指定依賴關系時產生沖突的概率也越大。根據軟件類型、使用廣泛程度等因素,選擇一個穩定可靠的子集部署在軟件環境中。對于編譯器和科學庫這類基礎軟件,如GCC、OpenBLAS等,可安裝盡可能多的版本供用戶選擇,并保持一個版本能用至少半年;常用科學計算軟件會保留最近的2~3個版本,更新頻率要比基礎庫高;對于使用量小的軟件將被部署在特定用戶的家目錄下。
這套分角色分類別的軟件構建方法,很好兼顧了只需要運行計算軟件的初級用戶需求和需要構建自己軟件環境的高級用戶的需求。軟件部署前經過測試,超過生命周期后有序退出,管理員部署的軟件也能最大限度地復用,避免了重復勞動。
本文總結了構建高性能計算軟件環境遇到的軟件數量多、編譯流程差異大、維護模塊工作量大、軟件版本共存、軟件管理角色不清晰等挑戰,在對比數個軟件包管理器后,重點介紹了Spack軟件包管理器的安裝方法、工作流程和軟件調用方法,并通過測試展示了Spack優異的編譯速度和高質量的編譯結果。最后介紹了上海交通大學高性能計算平臺基于Spack的分角色分類別的軟件環境部署流程,這套流程能涵蓋Spack開發者、系統管理員和普通用戶的軟件部署需求,為構建高性能計算軟件環境提供了有效方法。Spack收錄的軟件包數量和功能仍在穩步增加,將為高性能計算用戶構建特定領域的軟件環境帶來便利。