多網卡系統下如何使用tcp協議實現MPI的分布式多機運行(mpi的實現使用openmpi)


如題:

最近在看MPI方面的東西,主要是Python下的MPI4PY,學校有超算機房可以使用MPI,但是需要申請什么的比較麻煩,目的也本就是為了學習一下,所以就想着在自己的電腦上先配置一下。

現有硬件:兩台裝有Ubuntu18.04的操作系統(下面簡稱A電腦,B電腦)

A電腦: 24物理核心(48邏輯核心)

B電腦:6物理核心(12邏輯核心)

 

網絡:

A、B電腦之間使用100M以太網交換機連接(就是TP-Link路由器)。

 

 

A、B電腦上都裝有docker並且有多個物理網卡,因此各個電腦的網絡情況比較復雜,具體:

A電腦網絡配置:

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:78:17:6c:07  txqueuelen 0  (Ethernet)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp7s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.105.219.170  netmask 255.255.0.0  broadcast 10.105.255.255
        inet6 2001:da8:a800:af00:2e4d:54ff:fe44:a14b  prefixlen 64  scopeid 0x0<global>
        inet6 fe80::2e4d:54ff:fe44:a14b  prefixlen 64  scopeid 0x20<link>
        ether 2c:4d:54:44:a1:4b  txqueuelen 1000  (Ethernet)
        RX packets 2892225  bytes 321651342 (321.6 MB)
        RX errors 0  dropped 3  overruns 0  frame 0
        TX packets 251303  bytes 155089869 (155.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device memory 0xc6400000-c647ffff  

enp8s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.11.66  netmask 255.255.255.0  broadcast 192.168.11.255
        inet6 fe80::2e4d:54ff:fe44:a14c  prefixlen 64  scopeid 0x20<link>
        inet6 2001:da8:a800:af00:2e4d:54ff:fe44:a14c  prefixlen 64  scopeid 0x0<global>
        ether 2c:4d:54:44:a1:4c  txqueuelen 1000  (Ethernet)
        RX packets 3260138  bytes 1003925411 (1.0 GB)
        RX errors 66178  dropped 3  overruns 0  frame 53701
        TX packets 319204  bytes 22576077 (22.5 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
        device memory 0xc6300000-c637ffff  

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 42491  bytes 26674547 (26.6 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 42491  bytes 26674547 (26.6 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 

 

 

B電腦:

docker0: flags=4099<UP,BROADCAST,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        ether 02:42:b9:51:8d:33  txqueuelen 0  (以太網)
        RX packets 0  bytes 0 (0.0 B)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 0  bytes 0 (0.0 B)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp5s0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.105.246.82  netmask 255.255.0.0  broadcast 10.105.255.255
        inet6 2001:da8:a800:af00:645d:7de8:7fe8:99e9  prefixlen 64  scopeid 0x0<global>
        inet6 2001:da8:a800:af00:61f7:413d:2daf:e00a  prefixlen 64  scopeid 0x0<global>
        inet6 fe80::4ed5:7f18:afc3:59e4  prefixlen 64  scopeid 0x20<link>
        ether 94:c6:91:7e:20:24  txqueuelen 1000  (以太網)
        RX packets 2824242  bytes 259143858 (259.1 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 62606  bytes 48094535 (48.0 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enx000ec6c08c64: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.11.206  netmask 255.255.255.0  broadcast 192.168.11.255
        inet6 fe80::a036:3b28:aad9:62ac  prefixlen 64  scopeid 0x20<link>
        inet6 2001:da8:a800:af00:531e:f6f1:a573:9dbc  prefixlen 64  scopeid 0x0<global>
        inet6 2001:da8:a800:af00:a15e:c952:ce3e:f155  prefixlen 64  scopeid 0x0<global>
        ether 00:0e:c6:c0:8c:64  txqueuelen 1000  (以太網)
        RX packets 3089507  bytes 227967288 (227.9 MB)
        RX errors 0  dropped 2977  overruns 0  frame 0
        TX packets 549163  bytes 822545241 (822.5 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (本地環回)
        RX packets 45005  bytes 13777274 (13.7 MB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 45005  bytes 13777274 (13.7 MB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

 

 

其中,A、B電腦的各自兩個網卡均處在兩個局域網中,即:192.168.11.0/24   ,     10.105.0.0/24  。

在子網:192.168.11.0/24  中,

A電腦網卡:enp8s0    ,   B電腦網卡:enx000ec6c08c64

 

在子網:10.105.0.0/24  中,

A電腦網卡:enp7s0    ,   B電腦網卡:enp5s0

 

 

 

為舉例說明,使用下面的MPI4PY代碼:

from mpi4py import MPI
import numpy as np


comm = MPI.COMM_WORLD
size = comm.Get_size()
rank = comm.Get_rank()


sendbuf = np.zeros(100*10000, dtype='i') + rank
recvbuf = None
if rank == 0:
    recvbuf = np.empty([size, 100*10000], dtype='i')


print( MPI.Get_processor_name() )


import time
a = time.time()
for _ in range(1):
    comm.Gather(sendbuf, recvbuf, root=0)
b = time.time()
if rank == 0:
    print(b-a)

代碼意思比較簡單,不進行信息pickle和unpickle情況下做個信息收集gather操作。

 

 

 

 

 

本文前提假設已經安裝好了openmpi及mpi4py,單機環境已經配置好。A、B兩電腦之間免密碼ssh登錄也已經配置好,本文不對此進行介紹。

 

 

 

 

說明:

本文只是學習目的,沒有實際生成價值意義,畢竟分布式mpi大家都是用幾千上萬的infiband網絡連接,而不會使用3元、5元一米網線的以太網TCP連接。

 

 

 

 

=============================================================

 

 

 

 

 

最初的運行方式:

mpiexec -np 8   -host 192.168.11.66:4   -host 192.168.11.206:4   python x.py

 

 

報錯:

WARNING: Open MPI accepted a TCP connection from what appears to be a
another Open MPI process but cannot find a corresponding process
entry for that peer.

This attempted connection will be ignored; your MPI job may or may not
continue properly.

[[61134,1],0][btl_tcp_endpoint.c:626:mca_btl_tcp_endpoint_recv_connect_ack] received unexpected process identifier [[61134,1],2]
[[61134,1],0][btl_tcp_endpoint.c:626:mca_btl_tcp_endpoint_recv_connect_ack] received unexpected process identifier [[61134,1],1]

 

 

 

=======================================================

 

 

如上面運行的報錯,引出了一個問題:多網卡系統下如何使用tcp協議實現MPI的分布式多機運行

如題所述,在單網卡的環境中多個電腦都配置好了openmpi,mpi4py等軟件,而且在各個電腦上都有相同的用戶,運行文件都存在相同的路徑下,Python的運行路徑也都相同,各個電腦之間也都配置好了免密登錄,那么運行代碼自然不會出現上述的問題,但是如果你的電腦上每個電腦都不是只有一個網卡呢,就像本文中每台電腦均有兩個物理網卡並且均有一個虛擬網卡,這個情況下如果運行代碼就會上面的錯誤。為什么多個電腦之間使用mpi,如果只有一個網卡就不報錯,而電腦如果有超過一個網卡的話就會報錯呢???

最終找到了答案,具體看下面的相關討論:

 

 

相關討論:

 

https://www.javaroad.cn/questions/122550

 

 

 

 

相關資料:

https://blog.csdn.net/ljhandlwt/category_6317687.html

 

 

==========================================================

 從上面的討論可以知道使用mpi的時候如果不設置主機之間通信使用的具體網卡或網段,mpi會對所有網卡均進行通信嘗試,從而造成錯誤。

 

 

那么使用mpi在多機分布式使用tcp協議的時候如果主機有多個網卡該如何設置呢???下面給出幾種解決方法:

 

1.  運行時通過設置參數指定運行的網段

設置參數:  --mca btl_tcp_if_include 192.168.11.0/24

上文可以知道網絡中的主機A、B之間其實是存在兩個局域網互聯的,網段分別為:192.168.11.0/24,10.105.0.0/16

如果不指定具體使用的網段那么A、B主機會對這兩個網段均進行通信嘗試,這時可能會出現A主機在網段192.168.11.0/24上對B通信,而此時B在網段10.105.0.0/16上工作,從而導致報錯。設定工作的具體網段后A、B主機均會使用該網段通信,從而避免了上述的錯誤。

 

這里我們的具體運行命令為:

mpirun --mca btl_tcp_if_include 192.168.11.0/24 -np 8 -host 192.168.11.66:4 -host 192.168.11.206:4   /home/xxxxxx/anaconda3/bin/python x.py

 

 

 

 

 

2.  通過mpi配置文件指定工作的具體網卡:

在當前linux用戶的home文件夾下建立 .openmpi 文件夾,並在~/.openmpi 文件夾下面建立openmpi配置文件 mca-params.conf 並為其編寫配置:

 

~/.openmpi/mca-params.conf

 

分別在A、B兩個主機上對應的配置文件上添加內容:

主機A 192.168.11.66 對應網卡enp8s0

btl_tcp_if_include=enp8s0

 

 

主機B 192.168.11.206 對應網卡 enx000ec6c08c64

btl_tcp_if_include=enx000ec6c08c64

 

 


此時執行運行命令:

mpirun -np 8 -host 192.168.11.66:4 -host 192.168.11.206:4   /home/xxxxxx/anaconda3/bin/python x.py

 

 

 

 

 

 

 

以上兩種方法均可解決mpi在多機分布式使用tcp協議的多網卡主機通信報錯問題。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM