Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/358.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MPI中复杂乘法的Python代码不一致性_Python_Numpy_Mpi_Complex Numbers_Mpi4py - Fatal编程技术网

MPI中复杂乘法的Python代码不一致性

MPI中复杂乘法的Python代码不一致性,python,numpy,mpi,complex-numbers,mpi4py,Python,Numpy,Mpi,Complex Numbers,Mpi4py,假设有一个Python MPI程序,其中主节点向每个工作节点发送一对复杂矩阵,工作节点应该计算它们的乘积(传统的矩阵乘积)。输入矩阵在主节点根据某种算法构造,无需解释。现在,为了简单起见,假设我们只有两个MPI进程,一个主进程和一个工作进程。我已经为这个案例创建了两个版本的程序。第一种方法构造两个复数(为了简单起见,是1乘1矩阵),并将它们发送给工作人员以计算乘积。这个程序就像一个骨架,我正试图与多个工人做什么。在第二个程序中,我省略了算法,只是将这两个复数硬编码到代码中。这些程序应提供与此处所

假设有一个Python MPI程序,其中主节点向每个工作节点发送一对复杂矩阵,工作节点应该计算它们的乘积(传统的矩阵乘积)。输入矩阵在主节点根据某种算法构造,无需解释。现在,为了简单起见,假设我们只有两个MPI进程,一个主进程和一个工作进程。我已经为这个案例创建了两个版本的程序。第一种方法构造两个复数(为了简单起见,是1乘1矩阵),并将它们发送给工作人员以计算乘积。这个程序就像一个骨架,我正试图与多个工人做什么。在第二个程序中,我省略了算法,只是将这两个复数硬编码到代码中。这些程序应提供与此处所示相同的产品:

a=28534314.10478439+28534314.10478436j

b=-1.398115e+09+1.398115e+09j

a*b=-7.97922802e+16+48j

这已经在Matlab中进行了检查。相反,第一个程序不工作,工人给出
a*b=-7.97922801e+16+28534416.j
,而第二个程序正常工作。请注意,在这两种情况下,数据都正确地从主机传输到工作机(请参阅
print()
函数)。第一个(错误的)程序是:

from mpi4py import MPI
import numpy as np

N = 1
ell = 9
s_cod = 7
var = np.array([np.exp(1j*2*np.pi*1/8)])
comm = MPI.COMM_WORLD

if comm.rank == 0:

    print("I am sender")

    #Construction algorithm, explanation skipped
    A=np.matrix('1 0; 0 1')
    B=np.matrix('1 0; 0 1')
    Ah=np.split(A,2)
    Bh=np.split(B,2)
    Ahv = []
    Bhv = []
    for i in range(2):
        Ahv.append(np.split(Ah[i], 2, axis=1))
        Bhv.append(np.split(Bh[i], 2, axis=1))
    a = []
    b = []
    for i in range(N):
        a.append(Ahv[0][0]*(pow(s_cod*var[i], ell)) + Ahv[1][0] + Ahv[0][1]*(pow(s_cod*var[i], ell+1)) + Ahv[1][1]*s_cod*var[i])
        b.append(Bhv[0][0] + Bhv[1][0]*(pow(s_cod*var[i], ell)) + Bhv[0][1]*(pow(s_cod*var[i], 2)) + Bhv[1][1]*(pow(s_cod*var[i], ell+2)))

    #Send message with a predefined tag, like 15 and 16, to each receiver
    for i in range(N):
        comm.Isend([a[i],MPI.COMPLEX], dest=i+1, tag=15)
        comm.Isend([b[i],MPI.COMPLEX], dest=i+1, tag=16)

    print("Sender sent:  ")
    print(a[0])
    print(b[0])

else:

    print("I am receiver")

    A = np.empty_like(np.matrix([[0]*(1) for i in range(1)])).astype(np.complex128)
    B = np.empty_like(np.matrix([[0]*(1) for i in range(1)])).astype(np.complex128)

    #Receive message with tags 15, 16 from rank 0
    rA = comm.Irecv(A, source=0, tag=15)
    rB = comm.Irecv(B, source=0, tag=16)

    rA.wait()
    rB.wait()

    C = np.dot(A, B)

    print("Receiver received:  ")
    print(A)
    print(B)

    print("Receiver computed:  ")
    print(C)
from mpi4py import MPI
import numpy as np

comm = MPI.COMM_WORLD

if comm.rank == 0:

    print("I am sender")

    a = np.matrix('28534314.10478439+28534314.10478436j')
    b = np.matrix('-1.39818115e+09+1.39818115e+09j')

    #Send message with a predefined tag, like 15 and 16, to rank 1
    comm.Isend([a, MPI.COMPLEX], dest=1, tag=15)
    comm.Isend([b, MPI.COMPLEX], dest=1, tag=16)

    print("Sender sent:  ")
    print(a[0])
    print(b[0])

else:

    print("I am receiver")

    A = np.empty_like(np.matrix([[0]*(1) for i in range(1)])).astype(np.complex128)
    B = np.empty_like(np.matrix([[0]*(1) for i in range(1)])).astype(np.complex128)

    #Receive message with tags 15, 16 from rank 0
    rA = comm.Irecv(A, source=0, tag=15)
    rB = comm.Irecv(B, source=0, tag=16)

    rA.wait()
    rB.wait()

    C = np.dot(A, B)

    print("Receiver received:  ")
    print(A)
    print(B)

    print("Receiver computed:  ")
    print(C)
第二个(正确的)程序是:

from mpi4py import MPI
import numpy as np

N = 1
ell = 9
s_cod = 7
var = np.array([np.exp(1j*2*np.pi*1/8)])
comm = MPI.COMM_WORLD

if comm.rank == 0:

    print("I am sender")

    #Construction algorithm, explanation skipped
    A=np.matrix('1 0; 0 1')
    B=np.matrix('1 0; 0 1')
    Ah=np.split(A,2)
    Bh=np.split(B,2)
    Ahv = []
    Bhv = []
    for i in range(2):
        Ahv.append(np.split(Ah[i], 2, axis=1))
        Bhv.append(np.split(Bh[i], 2, axis=1))
    a = []
    b = []
    for i in range(N):
        a.append(Ahv[0][0]*(pow(s_cod*var[i], ell)) + Ahv[1][0] + Ahv[0][1]*(pow(s_cod*var[i], ell+1)) + Ahv[1][1]*s_cod*var[i])
        b.append(Bhv[0][0] + Bhv[1][0]*(pow(s_cod*var[i], ell)) + Bhv[0][1]*(pow(s_cod*var[i], 2)) + Bhv[1][1]*(pow(s_cod*var[i], ell+2)))

    #Send message with a predefined tag, like 15 and 16, to each receiver
    for i in range(N):
        comm.Isend([a[i],MPI.COMPLEX], dest=i+1, tag=15)
        comm.Isend([b[i],MPI.COMPLEX], dest=i+1, tag=16)

    print("Sender sent:  ")
    print(a[0])
    print(b[0])

else:

    print("I am receiver")

    A = np.empty_like(np.matrix([[0]*(1) for i in range(1)])).astype(np.complex128)
    B = np.empty_like(np.matrix([[0]*(1) for i in range(1)])).astype(np.complex128)

    #Receive message with tags 15, 16 from rank 0
    rA = comm.Irecv(A, source=0, tag=15)
    rB = comm.Irecv(B, source=0, tag=16)

    rA.wait()
    rB.wait()

    C = np.dot(A, B)

    print("Receiver received:  ")
    print(A)
    print(B)

    print("Receiver computed:  ")
    print(C)
from mpi4py import MPI
import numpy as np

comm = MPI.COMM_WORLD

if comm.rank == 0:

    print("I am sender")

    a = np.matrix('28534314.10478439+28534314.10478436j')
    b = np.matrix('-1.39818115e+09+1.39818115e+09j')

    #Send message with a predefined tag, like 15 and 16, to rank 1
    comm.Isend([a, MPI.COMPLEX], dest=1, tag=15)
    comm.Isend([b, MPI.COMPLEX], dest=1, tag=16)

    print("Sender sent:  ")
    print(a[0])
    print(b[0])

else:

    print("I am receiver")

    A = np.empty_like(np.matrix([[0]*(1) for i in range(1)])).astype(np.complex128)
    B = np.empty_like(np.matrix([[0]*(1) for i in range(1)])).astype(np.complex128)

    #Receive message with tags 15, 16 from rank 0
    rA = comm.Irecv(A, source=0, tag=15)
    rB = comm.Irecv(B, source=0, tag=16)

    rA.wait()
    rB.wait()

    C = np.dot(A, B)

    print("Receiver received:  ")
    print(A)
    print(B)

    print("Receiver computed:  ")
    print(C)

我正在使用mpi4py3.0.0。以及Python 2.7.14和OpenMPI 2.1.2的内核。我已经为这个问题纠结了一整天,仍然不知道发生了什么。我尝试过许多初始化,如
np.zeros()
np.zeros_-like()
np.empty_-like()
,以及
np.array
np.matrix
和函数
np.dot()
np.matmul()
和操作符
*/code>。最后,根据我尝试过的其他例子,我认为问题总是与产品的虚部有关。有什么建议吗?

这与MPI完全无关

np.set_printoptions(precision=15)
确认计算的
a
b
实际上与您输入到“正确”版本的不同

我不确定结果的基本真相是什么。在计算过程中,可能会出现影响增大的舍入误差。在点积过程中,差异急剧显现,因为在“正确”版本中,
b
的实部/虚部的绝对值相等,而在计算版本中,它们仅相对接近,但存在显著的绝对差异