---
# System prepended metadata

title: 要1000行了，換下個文章

---

第二頁



[How to use a Software Module hierarchy(寫的不錯)(如果打算在比賽中實做，所有人都得讀完並弄懂這個)](https://lmod.readthedocs.io/en/latest/080_hierarchy.html)
在了解Module hierarchy後 ，下一步是撰寫他們

[Frequently Asked Questions](https://lmod.readthedocs.io/en/latest/040_FAQ.html)
根據我的經驗，這是個重要的文章:D
:::spoiler 問題總結 
How does the module command work?
What are the environment variables _ModuleTable001_, _ModuleTable002_, etc doing it in the environment?
How does one debug a modulefile?
Why doesn’t % module avail |& grep ucc work under tcsh and works under bash?
Why does Lmod require a static location of lua? Why shouldn’t a site allow Lmod to use the lua found in the path?
Can I disable the pager output?
Why are messages printed to standard error and not standard out?
Can I force the output of list, avail and spider to go to stdout instead of stderr?
How can I use grep easily with the module command?
Can I ignore the spider cache files when doing module avail?
I have created a module and “module avail” can’t find it. What do I do?
Why doesn’t the module command work in shell scripts?
How do I use the initializing shell script that comes with this application with Lmod?
Why is the output of module avail not filling the width of the terminal?
Why isn’t the module defined when using the screen program?
Why does LD_LIBRARY_PATH get cleared when using the screen program?
How can you write TCL files that can be safely used with both Lmod and Tmod?
How can I get the shell functions created by modules in bash shell scripts such as job submission scripts?
Why do modules sometimes get loaded when I execute module use \<path>?
How to use module commands inside a Makefile?
What to do if new modules are missing when doing module avail?
How to edit a modulefile?
If my startup shell is bash or tcsh and I start zsh, why do I get a message that is like: “/etc/zsh/zshrc\:48: compinit: function definition file not found”
Why doesn’t setting CC in compiler and mpi modulefiles always work reliably in a software hierarchy?
How does one handle backslashed characters (aka escaped characters) in an environment variable?
Why is using os.getenv() directly in the functions setenv(), prepend_path() or append_path() a bad idea?
Why don’t collections work on HPE/Cray systems?
How to compare Lmod versions inside a module file?
Why can’t Lmod find this module in $MODULEPATH?
:::

:::spoiler [Prompt]幫幫我整理這些問題，並製作成中英對照板。
1. How does the module command work?	
module 指令是如何運作的？

2. How can I use grep easily with the module command?
如何更方便地使用 grep 配合 module 指令？

26. Why can’t Lmod find this module in $MODULEPATH
為什麼 Lmod 在 $MODULEPATH 中找不到這個模組？

6. I have created a module and “module avail” can’t find it. What do I do?	
我創建了一個模組，但 module avail 找不到它，該怎麼辦？

7. What to do if new modules are missing when doing module avail?	
如果執行 module avail 時缺少新模組，該怎麼辦？

9. Why is the output of module avail not filling the width of the terminal?	
為什麼 module avail 的輸出沒有填滿終端的寬度？

10. Why doesn’t the module command work in shell scripts?	
為什麼 module 指令在 shell 腳本中不起作用？

13. Why does Lmod require a static location of lua? Why shouldn’t a site allow Lmod to use the lua found in the path?	
為什麼 Lmod 需要一個靜態的 lua 位置？為什麼不應該允許 Lmod 使用路徑中的 lua？


8. How to edit a modulefile?
如何編輯 modulefile？

14. How does one debug a modulefile?	
如何偵錯 modulefile？

25. How to compare Lmod versions inside a module file?
如何在模組文件中比較 Lmod 版本？

27. Why is using os.getenv() directly in the functions setenv(), prepend_path() or append_path() a bad idea?	
為什麼直接在 setenv(), prepend_path() 或 append_path() 函數中使用 os.getenv() 是個壞主意？

15. How do I use the initializing shell script that comes with this application with Lmod?	
如何將此應用程序自帶的初始化 shell 腳本與 Lmod 配合使用？

17. How can I get the shell functions created by modules in bash shell scripts such as job submission scripts?	
如何在像是工作提交腳本的 bash shell 腳本中取得模組創建的 shell 函數？


20. Why do modules sometimes get loaded when I execute module use <path>?
為什麼有時候執行 module use <path> 時會自動加載模組？

22. How does one handle backslashed characters (aka escaped characters) in an environment variable?	
如何處理環境變數中的反斜線字元（即轉義字元）？

28. Why don’t collections work on HPE/Cray systems?
為什麼 collections 在 HPE/Cray 系統上不起作用？

11. Can I ignore the spider cache files when doing module avail?	
執行 module avail 時可以忽略 spider cache 檔案嗎？

以下不打算閱讀。

16. How to use module commands inside a Makefile?
如何在 Makefile 中使用 module 指令？

18. Why isn’t the module defined when using the screen program?	
為什麼在使用 screen 程式時，模組沒有被定義？

19. Why does LD_LIBRARY_PATH get cleared when using the screen program?	
為什麼在使用 screen 程式時，LD_LIBRARY_PATH 會被清空？

21. If my startup shell is bash or tcsh and I start zsh, why do I get a message like: “/etc/zsh/zshrc\:48: compinit: function definition file not found”	
如果我的啟動 shell 是 bash 或 tcsh，當我啟動 zsh 為什麼會出現「/etc/zsh/zshrc\:48: compinit: function definition file not found」這樣的消息？

23. Why doesn’t setting CC in compiler and mpi modulefiles always work reliably in a software hierarchy?	
為什麼在軟件層次結構中，在編譯器和 mpi 模組文件中設置 CC 並不總是可靠工作？

24. How can you write TCL files that can be safely used with both Lmod and Tmod?	
如何編寫可同時安全使用於 Lmod 和 Tmod 的 TCL 文件？

12. Why doesn’t % module avail |& grep ucc work under tcsh and works under bash?	
為什麼 % module avail |& grep ucc 在 tcsh 不工作而在 bash 工作？

29. What are the environment variables ModuleTable001, ModuleTable002, etc doing in the environment?	
環境變數 _ModuleTable001_, _ModuleTable002_ 等在環境中起什麼作用？

3. Can I disable the pager output?	
我可以禁用分頁器輸出嗎？

4. Why are messages printed to standard error and not standard out?	
為什麼消息打印到標準錯誤而不是標準輸出？

5. Can I force the output of list, avail, and spider to go to stdout instead of stderr?	
我可以強制 list, avail 和 spider 的輸出到標準輸出而不是標準錯誤嗎？

:::
沒有閱讀的必要，出問題後來看看就好。

:::spoiler [Prompt] 什麼是screen程式？
screen 是一個終端多工工具，允許你在單一終端會話中管理多個虛擬終端，並可以在不同的工作環境之間切換。這個程式對於遠端操作特別有用，因為它可以讓你保持會話持續執行，即使你斷開了連接或關閉了終端。

具體功能包括：

    多個會話：你可以同時啟動多個 screen 窗口，每個窗口可以運行不同的命令或應用程式。
    會話恢復：如果你使用 SSH 連接到遠端伺服器，並且不小心斷開了連接，你可以通過 screen 恢復之前的工作環境，而不會丟失工作進程。
    背景執行：在一個 screen 會話中運行的命令可以繼續在背景中執行，即使你暫時離開了終端或斷開連接。
    共享會話：你可以和其他用戶共享一個 screen 會話，這對於協作工作特別有用。

常見的命令：

    screen：啟動一個新的 screen 會話。
    screen -r：恢復一個已斷開的 screen 會話。
    Ctrl + A 然後按 D：將當前會話放到背景執行，並返回到普通終端。

透過 screen，你可以在執行長時間任務時不必擔心因為連接問題而中斷工作，非常適合在遠端伺服器上進行持續運行的任務。
:::

:::spoiler [Prompt] 我看到了 Finally we will discuss the advanced module functions to flexibly control your site via modules，module可以用在網站上？
module 在這裡提到的 "site" 並不是指傳統意義上的「網站」，而是指「系統環境」或「運算環境」，特別是在高效能計算（HPC）或伺服器群組中。

module 是一種用來管理軟體環境的工具。它的主要目的是透過「模組化」的方式，根據不同使用需求動態地設定或切換軟體環境。這在不同使用者需要不同版本的編譯器、MPI庫或其他軟體包時特別有用，因為它可以避免系統內多種軟體版本之間的衝突。

所以這句話的意思是：

    "site" 指的是某個特定的系統或環境（如一個HPC叢集或運算節點）。
    "modules" 是指那些用於管理軟體環境的模組檔案（通常是 .module 或 .lua 格式的配置檔）。

"advanced module functions" 指的是更高級的模組功能，這些功能允許管理員更加靈活地控制整個系統上的軟體配置，適應不同用戶或情境的需求。這包括根據不同的編譯器版本、運行環境（如MPI、數據庫等）來動態加載相應的軟體包。

這樣的「模組」系統在網站伺服器上一般較少使用，更多是針對運算資源的靈活管理。
:::


[An Introduction to Writing Modulefiles(寫的很好)](https://lmod.readthedocs.io/en/latest/015_writing_modules.html)
>[sub modulefile reference](https://lmod.readthedocs.io/en/latest/050_lua_modulefiles.html#lua-modulefile-functions-label)
Note: module 是一個套殼的指令，不是二進制文件。by `type module`
[Modulefile Examples from simple to complex](https://lmod.readthedocs.io/en/latest/100_modulefile_examples.html)

NOTE: 在/opt/需要大量使用root，可以切換到root帳號，不過root帳號的env var可以在多人使用時依舊分隔嘛(應該可以)，以及使用root帳號導致在原本帳號設置的env var都會不見，需要解決。


[modulefile 語法筆記](/Gl7CPhzzQhyzMDumi8zcjA)


mpfr安裝
[wget取得鍊結](https://www.mpfr.org/mpfr-current/#changes)
NOTE: mpfr depends on GMP5.0+
./configure --with-gmp=/opt/GMP/6.2.1 --prefix=/opt/mpfr/4.2.1
make check
make check-gmp-symbols
sudo make install

MPC 安裝
wget https://ftp.gnu.org/gnu/mpc/mpc-1.3.1.tar.gz
./configure --prefix=/opt/mpc/1.3.1 --with-mpfr=/opt/mpfr/4.2.1  --with-gmp=/opt/GMP/6.2.1
make 
make check -j4
sudo make install

gcc 還需要 isl0.15+
wget https://libisl.sourceforge.io/isl-0.27.tar.gz
tar zxvf isl-0.27.tar.gz isl-0.27/
rm isl-0.27.tar.gz 
cd isl-0.27/
mkdir build
cd build
../configure --prefix=/opt/isl/0.27 --with-gmp=/opt/GMP/6.2.1
make 
make check

安裝gcc!
```!
./configure --prefix=/opt/gcc/11.4.0 --with-mpc=/opt/mpc/1.3.1 --with-mpfr=/opt/mpfr/4.2.1  --with-gmp=/opt/GMP/6.2.1 --with-isl=/opt/isl/0.27 --host=x86_64-pc-linux-gnu --disable-multilib --enable-languages=c,c++
```
最後的--disable-multilib是因為缺乏32bit開發inc和lib，成品無法用於32bit，只能64bit (fine for me)，你可以嘗試把他們找全，應該有apt指令能一鍵安裝。
[相關的文章](https://www.linuxquestions.org/questions/ubuntu-63/cannot-find-crti-o-no-such-file-or-directory-4175448890/)
[相關的文章2](https://askubuntu.com/questions/251978/cannot-find-crti-o-no-such-file-or-directory)

sudo make -j$(nproc)
可能要減少語言到c和c++，加快編譯。
sudo make check -j14
sudo make install

有gcc了，讓charGPT幫我寫 modulefile!
:::spoiler [Prompt] 我完成了編譯gcc/11.4.0的工作了，我該怎麼編寫modulefile呢？我需要添加這些目錄到哪些env var呢？bin  include  lib  lib64  libexec  share
恭喜完成 GCC 11.4.0 的編譯！現在你可以編寫對應的 modulefile 來管理該版本的 GCC。這個文件會幫助用戶加載與卸載相應的環境變數。
modulefile 的編寫步驟：
1. 基礎目錄結構：

在適當的目錄下（如 /path/to/modulefiles/gcc/），創建一個文件，命名為 11.4.0.lua 或類似名稱。
2. 設置環境變數：

你需要將編譯後的 GCC 路徑加到一些關鍵環境變數中，例如 PATH、LD_LIBRARY_PATH、C_INCLUDE_PATH、LIBRARY_PATH 等。

假設 GCC 安裝到了 /opt/gcc/11.4.0，以下是一個基本的 modulefile 內容範例。
modulefile 內容範例：

lua

-- 設置模組的描述信息
help([[
GCC 11.4.0 Compiler Collection
]])

whatis("Description: GNU Compiler Collection 11.4.0")
whatis("Version: 11.4.0")
whatis("Category: Compiler")

-- 設置安裝路徑
local gcc_root = "/opt/gcc/11.4.0"

-- 設置 PATH 環境變數，使得編譯器（gcc、g++等）可執行
prepend_path("PATH", pathJoin(gcc_root, "bin"))

-- 設置 LD_LIBRARY_PATH，確保動態鏈接器能找到必要的庫
prepend_path("LD_LIBRARY_PATH", pathJoin(gcc_root, "lib"))
prepend_path("LD_LIBRARY_PATH", pathJoin(gcc_root, "lib64"))

-- 設置 C_INCLUDE_PATH 和 CPLUS_INCLUDE_PATH，讓編譯器能找到頭文件
prepend_path("C_INCLUDE_PATH", pathJoin(gcc_root, "include"))
prepend_path("CPLUS_INCLUDE_PATH", pathJoin(gcc_root, "include"))

-- 設置 LIBRARY_PATH，讓編譯器能找到靜態庫和共享庫
prepend_path("LIBRARY_PATH", pathJoin(gcc_root, "lib"))
prepend_path("LIBRARY_PATH", pathJoin(gcc_root, "lib64"))

-- 設置 MANPATH，讓用戶能查找 GCC 的手冊頁
prepend_path("MANPATH", pathJoin(gcc_root, "share/man"))

-- 設置 INFOPATH，讓用戶能查找 GCC 的 Info 手冊
prepend_path("INFOPATH", pathJoin(gcc_root, "share/info"))

-- 顯示加載模組後的確認信息
if (mode() == "load") then
   io.stderr:write("GCC 11.4.0 loaded\n")
end

-- 顯示卸載模組後的確認信息
if (mode() == "unload") then
   io.stderr:write("GCC 11.4.0 unloaded\n")
end

3. 說明各環境變數的作用：

    PATH：將 GCC 編譯器可執行文件（如 gcc、g++、gfortran 等）所在目錄加到 PATH，使得你可以從命令行調用這些工具。
    LD_LIBRARY_PATH：設置庫路徑，以便動態鏈接器能夠找到 GCC 的動態庫（例如 libgcc_s.so 等）。
    C_INCLUDE_PATH 和 CPLUS_INCLUDE_PATH：用來指定 GCC 頭文件的搜索路徑，分別適用於 C 和 C++。
    LIBRARY_PATH：設置靜態和共享庫的搜索路徑，當 GCC 編譯器需要鏈接時使用。
    MANPATH 和 INFOPATH：設置 man 和 info 命令能找到 GCC 的幫助手冊。

4. 測試你的 modulefile：

當你編寫好 modulefile 後，可以使用 module 命令來測試是否正確工作：

bash

module load gcc/11.4.0

這樣你就可以通過 modulefile 管理 GCC 11.4.0 的環境配置，並確保所有必要的環境變數正確設置。
:::

實驗成功了，下一步是使用這個gcc編譯一個mpi套件。
最後一部是使用mpi+編譯器弄出一個。

:::spoiler [Prompt] 提供一份清單，內容是依賴於gcc的mpi套件和依賴於gcc+mpi套件，可以供我練習編譯和架設和寫modulefile系統，
這裡提供一些常見的依賴於 GCC 的 MPI 套件，以及需要同時依賴 GCC 和 MPI 的科學計算庫，供你練習編譯、架設和編寫 modulefile 系統。這些套件廣泛應用於高性能計算 (HPC) 和科學計算領域。
依賴於 GCC 的 MPI 套件

這些套件主要是 MPI 底層通信庫，用於支援分布式內存並行計算：

    OpenMPI
        說明：一個常用的開源 MPI 實現，與多種編譯器和系統集成。
        官方網站：https://www.open-mpi.org/
        編譯和安裝時依賴於 GCC。
    MPICH
        說明：MPI 的另一個高效實現，支持高性能網絡。
        官方網站：https://www.mpich.org/
        同樣可以使用 GCC 編譯安裝。

依賴於 GCC + MPI 的科學計算庫

這些套件除了依賴 GCC 編譯器，還需要 MPI 作為通信層，適合進行大規模的科學計算和數值模擬：

    PETSc (Portable, Extensible Toolkit for Scientific Computation)
        說明：一個用於可擴展求解偏微分方程和其他數值問題的工具包。
        官方網站：https://www.mcs.anl.gov/petsc/
        PETSc 需要 MPI 作為通信層，並且可以與多種線性代數庫（如 BLAS、LAPACK、Hypre）集成。

    Trilinos
        說明：一組用於求解線性和非線性方程的軟件庫，特別適合並行計算。
        官方網站：https://trilinos.github.io/
        依賴 MPI 作為通信基礎，同時支持多種底層線性代數庫（如 Tpetra 和 Epetra）。

    HDF5 (Hierarchical Data Format)
        說明：一個高效的數據格式，用於存儲和管理大規模的數據集，支持 MPI-IO。
        官方網站：https://www.hdfgroup.org/solutions/hdf5/
        HDF5 的 MPI 版本依賴 MPI 通信來進行並行 IO 操作。

    Hypre (High Performance Preconditioners)
        說明：一個並行求解大規模稀疏矩陣的工具，支持多種前置條件器算法。
        官方網站：https://hypre.readthedocs.io/en/latest/
        Hypre 依賴 MPI 進行並行求解，需要與 PETSc 或 Trilinos 集成使用。

    LAMMPS (Large-scale Atomic/Molecular Massively Parallel Simulator)
        說明：一個分子動力學模擬軟件，適合進行材料科學和物理計算。
        官方網站：https://www.lammps.org/
        LAMMPS 支持 MPI 並行運行，適合大規模模擬。

    GROMACS (GROningen MAchine for Chemical Simulations)
        說明：一個高速且靈活的分子動力學模擬套件。
        官方網站：https://www.gromacs.org/
        同樣依賴 MPI 進行大規模並行模擬。

編譯與配置流程：

    下載源代碼：從官方網站或 GitHub 倉庫下載這些軟件的源代碼。

    配置和編譯：在編譯過程中使用 ./configure 或 cmake，並確保設置正確的 GCC 和 MPI 編譯器環境。以 OpenMPI 為例：

    bash

    ./configure CC=gcc CXX=g++ FC=gfortran --prefix=/opt/openmpi/4.1.1
    make -j$(nproc)
    sudo make install

    編寫 modulefile：為這些軟件編寫相應的 modulefile，添加所需的環境變數，例如 PATH、LD_LIBRARY_PATH、C_INCLUDE_PATH 等。你可以參照 GCC modulefile 的範例，來編寫 MPI 和其上層套件的 modulefile。

這些套件可以提供豐富的練習機會，幫助你更好地掌握編譯、安裝和模組管理技巧。
:::

開始安裝openmpi，看起來stable版本的有自己帶好一些dependences。我們需要在infiniteBand上跑，需要加上很多dependences.我們還想要高效能，我想要能加的就加上。
[openmpi configure options](https://docs.open-mpi.org/en/v5.0.x/installing-open-mpi/configure-cli-options/index.html)

:::spoiler openMP會比pthread好嗎？
ChatGPT

OpenMP 和 Pthreads 都是並行編程的工具，各有優勢，具體選擇哪個工具取決於你的需求和應用場景。以下是兩者的比較，幫助你判斷哪個更適合你的項目：
1. 開發簡單性

    OpenMP：提供更高層次的抽象，使用簡單的編譯指令（pragma 指令）來指定並行區域和共享變量。對於已有的程式，只需在關鍵的程式碼段添加一些指令，就可以實現並行化。
    Pthreads：提供更低層次的控制，要求顯式地創建和管理線程、同步機制（例如鎖、條件變量等），這使得程式的開發變得更為複雜。

結論：OpenMP 更易於使用，開發時間較短，而 Pthreads 則提供了更多的靈活性。
2. 並行模型

    OpenMP：採用共享內存並行編程模型，專為多核 CPU 設計。OpenMP 更適合用於對資料共享頻繁的應用，因為它假設所有線程都能訪問同一塊共享內存。
    Pthreads：也是基於共享內存的線程庫，但它提供更底層的線程管理，允許開發者手動控制線程的行為、同步、通信，這在需要更多控制時更靈活。

結論：如果只需要基本的並行處理，OpenMP 更適合。但如果需要自定義線程行為和控制，Pthreads 更好。
3. 性能

    OpenMP：由於 OpenMP 抽象化了線程的創建和管理，它在某些應用場景中可能會導致一些額外的開銷，特別是在非常細粒度的並行化操作中。
    Pthreads：由於 Pthreads 提供較低層次的線程控制，對性能的影響較小。因此，在性能極為關鍵的場景中，Pthreads 可能表現得更好。

結論：對於需要高度優化的應用，Pthreads 可能能夠提供更好的性能，但代價是更高的開發複雜度。
4. 可移植性

    OpenMP：標準化程度更高，廣泛支持於不同的編譯器和平台（如 GCC、Clang、Intel 等）。它主要針對共享內存系統，在多核 CPU 上效果較好。
    Pthreads：是 POSIX 標準的一部分，幾乎所有的 Unix/Linux 系統都支持 Pthreads，但它的移植性稍差，特別是在 Windows 平台上，需要使用 POSIX 層模擬 Pthreads 功能。

結論：OpenMP 在可移植性上更強，而 Pthreads 在不同平台上的移植可能需要更多工作。
5. 使用場景

    OpenMP：適合用於科學計算、大規模數據處理和需要簡單並行化的應用，例如矩陣運算、數據分割等場景。它可以快速應用於已存在的序列代碼中，且效果顯著。
    Pthreads：適合需要自定義線程行為的應用，特別是在需要多線程直接通信、同步的情況下，例如多線程伺服器、實時系統等場景。

結論：OpenMP 更適合簡單並行化和快速實現並行應用，而 Pthreads 則適合需要高度自定義的多線程應用。
總結：

    OpenMP：適合於需要快速實現並行化、開發時間有限的應用，特別是數據並行性明顯的計算型應用。如果你正在處理大規模計算任務且不想管理線程細節，OpenMP 是不錯的選擇。
    Pthreads：更適合於需要精細控制線程行為、性能要求高或對並行細節有更高要求的應用。如果你需要更多靈活性並且能投入更多的開發精力，Pthreads 是更強大的選擇。

在你基於 Linux 和 Infiniband 的叢集環境中，如果並行化邏輯相對簡單並且只需要利用多核 CPU，那麼 OpenMP 可能是更好、更高效的選擇。如果需要進行更加複雜的線程管理，或者應用對性能要求極高，可以考慮使用 Pthreads。
:::

:::spoiler 能根據安裝清單解單的說明每一項嘛？

ChatGPT

你提供的 OpenMPI 安裝清單中的每一項選項，對應著不同的硬體或軟體支持功能。以下是每一項的說明：
1. Open UCC: no

    Open Unified Collective Communication (UCC) 是一個針對集體通信操作的通信庫，適用於高性能計算的各種通信網絡，例如 Infiniband。當選項顯示 "no" 時，表示此功能未啟用。
    如果你的應用程序依賴於集體通信操作（如 MPI 的集體操作），你可以考慮啟用 UCC。

2. Cisco usNIC: no

    usNIC (User Space Network Interface Card) 是 Cisco 開發的一種基於用戶空間的低延遲網絡接口，主要用於高效能計算環境中的 MPI 通信。顯示 "no" 表示此選項未啟用，這與你的 Infiniband 環境無關，因為這是 Cisco 特有的技術。

3. Cray uGNI (Gemini/Aries): no

    uGNI (User Generic Network Interface) 是 Cray 高性能計算機使用的一種通信接口，適用於 Cray Gemini 和 Aries 網絡架構。由於這是 Cray 專有技術，因此你無需啟用它，除非你在使用 Cray 的超算設備。

4. Intel Omnipath (PSM2): no (not found)

    Intel Omnipath (PSM2) 是 Intel 開發的高速通信網絡技術，主要用於超算集群。你目前不需要啟用此功能，因為你的系統並不使用 Intel Omnipath 網絡。

5. Open UCX: no

    Open Unified Communication X (UCX) 是一個高度可擴展的通訊框架，支持多種高性能計算網絡，如 Infiniband 和以太網。UCX 提供對 MPI 和其他應用的低延遲通信支持。建議在 Infiniband 環境中啟用 UCX，以獲得更好的性能。

6. OpenFabrics OFI Libfabric: no (not found)

    OFI Libfabric 是 OpenFabrics Interface 的一部分，為高效能應用提供了對高性能網絡（如 Infiniband 和 RoCE）的支持。這對 Infiniband 非常重要，你應該考慮安裝和啟用它。

7. Portals4: no (not found)

    Portals4 是一個針對高性能計算的網絡通信層，常見於超算環境。這不是標準的 Infiniband 驅動，因此你可以忽略此項，除非你的系統需要使用 Portals4 架構。

8. Shared memory/Linux KNEM: no

    KNEM 是 Linux 下的一個共享內存加速通信的機制，用於優化在同一節點上的進程之間的通信。這對於多進程 MPI 應用可能有性能提升。若有多核節點的需求，考慮啟用 KNEM。

9. Shared memory/XPMEM: no

    XPMEM 是一個允許在多進程間快速共享內存的通信機制。與 KNEM 類似，它能優化節點內的 MPI 通信性能。可以根據需求選擇啟用。

10. CUDA support: no

    CUDA support 允許 MPI 程序與 NVIDIA GPU 使用的 CUDA 技術集成。如果你的應用涉及 GPU 加速（如 CUDA），啟用這個選項會有幫助。你的清單顯示 "no"，這表示此支持未啟用。

11. ROCm support: no

    ROCm (Radeon Open Compute) 是 AMD 開發的 GPU 加速框架。如果你的系統使用 AMD GPU，可以考慮啟用 ROCm 支持。若不使用 AMD GPU，則不需要此選項。

12. DDN Infinite Memory Engine: no

    DDN IME (Infinite Memory Engine) 是 DataDirect Networks 開發的一個高速文件系統，適用於超算環境中的 I/O 加速。如果你不使用 DDN 的文件系統，則不需要啟用這個選項。

13. Generic Unix FS: yes

    Generic Unix Filesystem 是一個基本的文件系統支持，允許 MPI 程序在 Unix 系統上的文件系統中進行 I/O 操作。這是必須的基本支持，故顯示為 "yes"。

14. IBM Spectrum Scale/GPFS: no (not found)

    IBM Spectrum Scale/GPFS 是 IBM 的分佈式文件系統，常見於大規模存儲環境中。如果不使用 IBM Spectrum Scale，則不需要此支持。

15. Lustre: no (not found)

    Lustre 是一個高性能分佈式文件系統，通常用於超算環境中的大規模存儲。如果你的系統不使用 Lustre，則不需要此選項。

16. PVFS2/OrangeFS: no

    PVFS2/OrangeFS 是一個開源的分佈式文件系統，主要用於高性能計算集群中的文件存取。如果你的系統不使用 OrangeFS，也不需要啟用此選項。

總結：

    必須安裝/啟用：Open UCX、OpenFabrics OFI Libfabric、KNEM 或 XPMEM（若有需要加速節點內進程通信）。
    不需要：Cisco usNIC、Cray uGNI、Intel Omnipath、ROCm support、DDN IME、IBM Spectrum Scale、Lustre、PVFS2/OrangeFS，除非使用這些特定的硬體或文件系統。

依照這個清單進行相應的安裝，將有助於你在 Infiniband 叢集環境中正確配置 OpenMPI。

:::

需要這些
Generic Unix FS: yes
Shared memory/Linux KNEM: no 二挑一，我選下面那個
Shared memory/XPMEM: no
Open UCC: no
Open UCX: no
OpenFabrics OFI Libfabric: no (not found)
CUDA support: no

考慮中
Lustre: no (not found)
這是一個分佈式文件系統，如果我們在處理大型叢集，NFS是絕對不夠的，可以順水推舟使用這個分佈式文件系統。
PVFS2/OrangeFS: no
另外一個分佈式文件系統。

不需要這些
Portals4: no (not found)
不基於Portals4架構，不需要
ROCm support: no
不基於AMD的GPU，不需要
DDN Infinite Memory Engine: no
不使用DDN IME文件系統，不需要
IBM Spectrum Scale/GPFS: no (not found)
不需要。

[內容太多，開新文章](/oLCXsVDdQeaC55oJ0KVQ1w)

:::spoiler 題外化: 還需要什麼？[Prompt] 我目前預計使用套件層級架構實現以編譯器xMPI分類+modulefile層級架構以編譯器xMPI分類+Lustre分佈式文件系統實現叢集電腦文件相同+cuda實現GPU+infiniteBand實現網路。對於這樣子架構叢集電腦運算，還缺少什麼嘛？或是添加什麼可以讓事情更好
你目前的架構設計已經涵蓋了許多關鍵組件，如編譯器和 MPI 的層級分類、Lustre 作為分佈式文件系統、CUDA 用於 GPU 加速，以及 InfiniBand 用於高效的網路連接。這些元素為叢集運算的高性能計算（HPC）環境提供了堅實的基礎。

以下是一些可能的增強建議，可以進一步提升你的架構：
1. 資源管理與工作調度系統

    SLURM（Simple Linux Utility for Resource Management） 是一個廣泛使用的資源管理和工作調度系統，能夠有效管理叢集資源並分配運算任務。它可以讓你更好地控制作業的排程、資源分配，以及優化多用戶環境下的作業效率。
    PBS（Portable Batch System） 或 HTCondor 也是類似的工具，根據你的需求選擇合適的系統能讓資源管理更流暢。

2. 監控與管理工具

    添加如 Ganglia 或 Prometheus 這類監控工具可以幫助你實時追蹤叢集的資源使用情況（CPU、內存、GPU、網路等）。這樣的監控能協助你迅速發現瓶頸並進行優化。
    Nagios 或 Zabbix 則是針對叢集健康狀態監控的工具，能讓你在出現硬體故障或資源耗盡時快速響應。

3. MPI 通訊優化

    OpenUCX 是一個先進的 MPI 通訊框架，能針對多種網路架構（如 InfiniBand）進行最佳化，提升 MPI 通訊性能。你可以考慮整合 OpenUCX 來增強 MPI 通訊的效率。
    KNEM/XPMEM：這些是優化共享內存傳輸的工具，對於高效的節點內部通訊特別有幫助。

4. 容錯與恢復機制

    在大型叢集環境中，容錯機制是很重要的。可以考慮使用像 BLCR（Berkeley Lab Checkpoint/Restart） 這樣的工具來實現作業的檢查點保存和恢復，確保在系統故障時不會丟失計算進度。

5. 軟體版本控制與環境管理

    使用 Spack 或 EasyBuild 這樣的軟件構建和管理工具，能夠簡化叢集軟件包的管理，特別是在多個軟件版本和依賴關係上，能幫助保持環境的一致性和可重現性。

6. 擴展到雲端的混合架構

    如果你的叢集有彈性需求，你可以考慮擴展到雲端。整合如 OpenStack 或 Kubernetes 的混合架構，讓叢集能夠根據工作負載進行動態擴展。

7. 高效的資料管理與傳輸

    RDMA（Remote Direct Memory Access） 能進一步提升資料傳輸效率，特別是在使用 InfiniBand 時，可以降低網路延遲和 CPU 佔用。

總結：

你的架構已經涵蓋了 HPC 叢集中的多個關鍵組件，並且設計合理。添加如資源管理、監控系統、MPI 優化工具和容錯機制，能進一步增強集群的穩定性和效率。如果擁有雲端擴展的需求，也可以考慮混合架構來提升彈性。
:::

Ganglia 或 Prometheus 節點資源監控，考慮
Nagios 或 Zabbix 節點健康狀況，不考慮
SLURM 排程系統，添加
BLCR（Berkeley Lab Checkpoint/Restart) 系統恢復，不考慮
Spack 或 EasyBuild 套件安裝，使用spack，ezb沒聽過
OpenStack 或 Kubernetes 雲端化，不考慮
RDMA（Remote Direct Memory Access）資源傳輸，添加

:::spoiler 題外化: 需要不同的編譯器。[Prompt] 假設目前套件A需要gcc/8而套件A的依賴項需要gcc/10，這種事情會發生嘛？
這種情況是可能發生的，但在實際情況中相對少見，且通常會被認為是一個不理想的軟件依賴狀況。具體來說，套件 A 需要 gcc/8 編譯，而套件 A 的依賴項卻需要 gcc/10 這樣的場景會導致編譯器的不一致問題，因為編譯器的 ABI（Application Binary Interface）可能不同，這樣在執行階段可能會導致兼容性問題。
為什麼會發生？

    編譯器的版本特定優化或特性：
        某些軟件可能針對特定版本的 GCC 進行了編譯器優化，或依賴該版本的特定功能或特性。例如，某個庫的性能在 gcc/10 中表現更佳，而應用程序本身則可能與 gcc/8 更兼容。

    編譯器不兼容的 ABI：
        不同的 GCC 版本有時可能會引入 ABI 的變更，這意味著使用不同編譯器編譯的二進制文件之間可能無法相互運行。這會導致一個軟件使用 gcc/8 生成，而其依賴項使用 gcc/10 時發生運行時錯誤。

    軟件包的構建流程不一致：
        在某些情況下，軟件開發者可能只對特定 GCC 版本進行測試和支持，這會導致某些軟件包無法在其他版本的 GCC 上正常運行。當系統中存在多個 GCC 版本，且開發者沒有測試這些組合時，這樣的問題更容易發生。

解決方案與建議

    統一編譯器版本：
        最理想的情況是確保所有依賴項都使用相同的編譯器版本進行編譯，以避免 ABI 和二進制不兼容的問題。

    多版本編譯和安裝：
        如果必須依賴不同版本的 GCC，則需要針對不同的編譯器版本進行分別編譯。你可以將每個依賴項針對不同 GCC 版本分別編譯，並使用類似 module 系統來管理不同編譯器版本的切換。

    靜態編譯依賴項：
        可以將某些依賴項進行靜態編譯，這樣最終的可執行文件將不再依賴系統中的共享庫版本。這能在某些情況下避免運行時的版本不匹配問題。

    容器化技術：
        使用容器技術（如 Docker）能夠將應用及其依賴環境封裝在一起，不同容器中的軟件可以使用不同版本的編譯器，而不會互相影響。

    ABI 兼容性：
        檢查不同 GCC 版本的 ABI 變化，並盡量在 ABI 相容的情況下進行編譯。如果 gcc/8 和 gcc/10 在某個平台上 ABI 保持兼容，則可以允許這樣的混合依賴。

總結

在理想情況下，應該避免軟件及其依賴項使用不同版本的編譯器，因為這可能引發兼容性問題。當遇到這種情況時，可以考慮編譯不同版本的套件，或使用容器技術來隔離依賴環境。
:::
想太多.jpg。如果發生了，那就痛苦面具了:D。
目前規劃上，是編譯器+基於編譯器+基於編譯器MPI的套件
如果有一個目標需要兩種編譯器，就痛苦面具。

:::spoiler [Prompt] 好的，還有一個問題，關於驅動，例如nvidia driver跟ofed驅動，這些東西能靠module實現版本選擇嘛？如果不能，conda能嘛？如果不能，該怎麼做？
關於驅動版本的選擇，像是 NVIDIA 驅動 和 OFED 驅動 這樣的底層系統驅動，通常不適合使用像 module 或 conda 這樣的環境管理工具來進行版本切換。原因在於這些驅動直接與系統內核和硬體進行交互，依賴於底層內核模組和驅動程序，而 module 和 conda 通常用於高層次的應用或庫的管理。
驅動版本管理的挑戰：

    系統內核依賴性：
        系統驅動（如 NVIDIA 驅動、OFED 驅動）通常是以內核模組的形式加載，它們需要與操作系統內核緊密結合。因此，切換驅動版本涉及內核模組的卸載和重載，並可能需要重新編譯內核模組，這不是 module 或 conda 可以管理的範疇。

    系統級權限要求：
        驅動的安裝與切換通常需要 root 權限，並且改變驅動可能會影響整個系統的穩定性，因此，不能像普通應用程式一樣在用戶層面輕鬆進行切換。

    驅動的持久性和穩定性要求：
        許多運算密集型的環境，像是 GPU 和 InfiniBand 網路，需要穩定且高度優化的驅動版本。頻繁切換驅動版本可能會導致不穩定，因此系統通常會選擇一個版本並長期保持不變。

Module 和 Conda 的局限性

    module 系統：
        module 更適合管理用戶態軟件環境（如編譯器、MPI 庫等），而不適合管理內核級的驅動。
    conda 系統：
        conda 也是一種應用層面的包管理工具，主要管理 Python 生態系中的軟件包，不負責底層硬件驅動的管理。它無法處理系統驅動的安裝和切換。

如何進行驅動版本切換？

    手動切換：
        NVIDIA 驅動 和 OFED 驅動 的版本切換通常需要通過手動的方式來完成，包括卸載舊驅動並安裝新驅動。這通常包括以下步驟：
            卸載現有驅動 (sudo apt-get remove 或 yum remove)。
            下載和安裝新版本的驅動。
            重啟系統以加載新的驅動模組。

    DKMS（Dynamic Kernel Module Support）：
        NVIDIA 驅動 使用 DKMS 機制來管理驅動的編譯和安裝，這樣在內核更新時，驅動可以自動重新編譯。如果有多個驅動版本，則需要手動卸載再安裝。

    容器化方案：
        如果需要在不同環境中使用不同版本的驅動，容器技術（如 Docker）可以提供一些靈活性。例如，使用帶有不同驅動的容器鏡像來管理不同應用對驅動版本的需求。
        然而，這樣的方式仍依賴宿主系統中已安裝的驅動，所以宿主系統的驅動版本仍是關鍵。

    多內核環境或多引導系統：
        另一種方案是設置不同的操作系統或內核版本，每個內核加載不同版本的驅動，並通過多重引導（multi-boot）進行選擇。但這樣的方法在實際應用中不常用，因為維護較為複雜。

    使用官方工具管理：
        許多硬件供應商提供了官方工具來管理驅動版本。例如，NVIDIA 有專門的 NVIDIA Driver Manager，可以自動檢測系統的最佳驅動版本並進行更新。
        OFED 驅動 則有來自 Mellanox 的 MLNX_OFED 工具，提供安裝和更新功能。你可以使用它來切換不同版本的 InfiniBand 驅動。

小結

驅動版本的切換不是 module 或 conda 能解決的問題，這些工具主要管理應用和庫層級別的軟件。如果需要切換驅動，通常需要手動操作或使用官方提供的驅動管理工具，根據需要進行安裝、卸載或更新。如果需要靈活管理不同版本驅動，可以考慮容器技術來隔離環境，或者設置多內核或多引導系統來選擇不同的驅動版本。
:::
痛苦面具.jpg

[Lmod Environment variables](https://lmod.readthedocs.io/en/latest/052_Environment_Variables.html)
[How Lmod Picks which Modulefiles to Load](https://lmod.readthedocs.io/en/latest/060_locating.html)
[Providing A Standard Set Of Modules for all Users](https://lmod.readthedocs.io/en/latest/070_standard_modules.html)
[Rules for PATH-like variables](https://lmod.readthedocs.io/en/latest/077_ref_counting.html)
[Hidden Modules](https://lmod.readthedocs.io/en/latest/079_hidden_modules.html)

[Module Properties](https://lmod.readthedocs.io/en/latest/145_properties.html)
[Debugging Modulefiles](https://lmod.readthedocs.io/en/latest/160_debugging_modulefiles.html)

[Terse output for computer programs](https://lmod.readthedocs.io/en/latest/105_terse_output.html)
[The Interaction between Modules, MPI and Parallel Filesystems](https://lmod.readthedocs.io/en/latest/110_lmod_mpi_parallel_filesystem.html)
[Sticky Modules](https://lmod.readthedocs.io/en/latest/240_sticky_modules.html)
[Shell scripts and Lmod](https://lmod.readthedocs.io/en/latest/260_sh_to_modulefile.html)
[Tracking Module Usage](https://lmod.readthedocs.io/en/latest/300_tracking_module_usage.html)




## others



