// File: WeihuaZhu[P]hpc_prog2/mpi_tests.cpp
// Function: MpiTest_JacobiCrossTest1_Test::TestBody()
TEST(MpiTest, JacobiCrossTest1)
{
    // test random matrixes, test parallel code with sequential solutions
    std::vector<double> A;
    std::vector<double> b;
    std::vector<double> mpi_x;

    // get grid communicator
    MPI_Comm grid_comm;
    get_grid_comm(&grid_comm);
    int rank;
    MPI_Comm_rank(grid_comm, &rank);

    int n = 36;
    // initialize data only on rank 0
    if (rank == 0)
    {
        A = diag_dom_rand(n);
        b = randn(n, 100.0, 50.0);
    }

    // getting sequential results
    std::vector<double> x;
    if (rank == 0)
    {
        x.resize(n);
        jacobi(n, &A[0], &b[0], &x[0]);
    }

    // parallel jacobi
    if (rank == 0)
        mpi_x.resize(n);
    mpi_jacobi(n, &A[0], &b[0], &mpi_x[0], grid_comm);

    if (rank == 0)
    {
        // checking if all values are correct (up to some error value)
        for (int i = 0; i < n; ++i)
        {
            EXPECT_NEAR(x[i], mpi_x[i], 1e-8) << " MPI solution x[" << i << "] differs from sequential result";
        }
    }
}

// Assembly:
subq $0x158, %rsp            # imm = 0x158
movq %rdi, 0x150(%rsp)
leaq 0x138(%rsp), %rdi
callq 0x11c40
leaq 0x120(%rsp), %rdi
callq 0x11c40
leaq 0x108(%rsp), %rdi
callq 0x11c40
leaq 0x100(%rsp), %rdi
callq 0x105a0
jmp 0x10cf5
movq 0x100(%rsp), %rdi
leaq 0xf0(%rsp), %rsi
callq 0xf050
jmp 0x10d0c
movl $0x24, 0xec(%rsp)
cmpl $0x0, 0xf0(%rsp)
jne 0x10dca
movl 0xec(%rsp), %esi
leaq 0xd0(%rsp), %rdi
movsd 0x3e2fc(%rip), %xmm0    # 0x4f038
callq 0x10350
jmp 0x10d43
leaq 0x138(%rsp), %rdi
leaq 0xd0(%rsp), %rsi
movq %rsi, 0x70(%rsp)
callq 0x11c50
movq 0x70(%rsp), %rdi
callq 0x11970
movl 0xec(%rsp), %esi
leaq 0xb8(%rsp), %rdi
movsd 0x3e2c2(%rip), %xmm0    # 0x4f040
movsd 0x3e2c2(%rip), %xmm1    # 0x4f048
callq 0x10250
jmp 0x10d8d
leaq 0x120(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
callq 0x11c50
leaq 0xb8(%rsp), %rdi
callq 0x11970
jmp 0x10dca
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0x11177
leaq 0xa0(%rsp), %rdi
callq 0x11c40
cmpl $0x0, 0xf0(%rsp)
jne 0x10e8c
movslq 0xec(%rsp), %rsi
leaq 0xa0(%rsp), %rdi
callq 0x11c90
jmp 0x10dfc
movl 0xec(%rsp), %eax
movl %eax, 0x5c(%rsp)
xorl %eax, %eax
movl %eax, %esi
movq %rsi, 0x50(%rsp)
leaq 0x138(%rsp), %rdi
callq 0x11950
movq 0x50(%rsp), %rsi
movq %rax, 0x60(%rsp)
leaq 0x120(%rsp), %rdi
callq 0x11950
movq 0x50(%rsp), %rsi
movq %rax, 0x68(%rsp)
leaq 0xa0(%rsp), %rdi
callq 0x11950
movl 0x5c(%rsp), %edi
movq 0x60(%rsp), %rsi
movq 0x68(%rsp), %rdx
movq %rax, %rcx
movl $0x64, %r8d
movsd 0x3e1be(%rip), %xmm0    # 0x4f028
callq 0x4e2f0
jmp 0x10e71
jmp 0x10e8c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0x1116a
cmpl $0x0, 0xf0(%rsp)
jne 0x10eaf
movslq 0xec(%rsp), %rsi
leaq 0x108(%rsp), %rdi
callq 0x11c90
jmp 0x10ead
jmp 0x10eaf
movl 0xec(%rsp), %eax
movl %eax, 0x3c(%rsp)
xorl %eax, %eax
movl %eax, %esi
movq %rsi, 0x30(%rsp)
leaq 0x138(%rsp), %rdi
callq 0x11950
movq 0x30(%rsp), %rsi
movq %rax, 0x40(%rsp)
leaq 0x120(%rsp), %rdi
callq 0x11950
movq 0x30(%rsp), %rsi
movq %rax, 0x48(%rsp)
leaq 0x108(%rsp), %rdi
callq 0x11950
movl 0x3c(%rsp), %edi
movq 0x40(%rsp), %rsi
movq 0x48(%rsp), %rdx
movq %rax, %rcx
movq 0x100(%rsp), %r8
movl $0x64, %r9d
movsd 0x3e103(%rip), %xmm0    # 0x4f028
callq 0x4dff0
jmp 0x10f2c
cmpl $0x0, 0xf0(%rsp)
jne 0x1112e
movl $0x0, 0x9c(%rsp)
movl 0x9c(%rsp), %eax
cmpl 0xec(%rsp), %eax
jge 0x1112c
movslq 0x9c(%rsp), %rsi
leaq 0xa0(%rsp), %rdi
callq 0x11950
movsd (%rax), %xmm0
movsd %xmm0, 0x28(%rsp)
movslq 0x9c(%rsp), %rsi
leaq 0x108(%rsp), %rdi
callq 0x11950
movsd 0x28(%rsp), %xmm0
movsd (%rax), %xmm1
leaq 0x3e169(%rip), %rsi     # 0x4f107
leaq 0x3e17d(%rip), %rdx     # 0x4f122
leaq 0x3e17f(%rip), %rcx     # 0x4f12b
leaq 0x88(%rsp), %rdi
movsd 0x3e094(%rip), %xmm2    # 0x4f050
callq 0x1c2f0
jmp 0x10fc3
leaq 0x88(%rsp), %rdi
callq 0x11a40
movb %al, 0x27(%rsp)
jmp 0x10fd6
movb 0x27(%rsp), %al
testb $0x1, %al
jne 0x10fe0
jmp 0x10ffe
jmp 0x110fa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0x1111d
leaq 0x80(%rsp), %rdi
callq 0x1b7b0
jmp 0x1100d
leaq 0x3e11c(%rip), %rsi     # 0x4f130
leaq 0x80(%rsp), %rdi
callq 0x11d30
movq %rax, 0x18(%rsp)
jmp 0x11028
movq 0x18(%rsp), %rdi
leaq 0x9c(%rsp), %rsi
callq 0x11b60
movq %rax, 0x10(%rsp)
jmp 0x11041
movq 0x10(%rsp), %rdi
leaq 0x3e0f4(%rip), %rsi     # 0x4f141
callq 0x11d70
movq %rax, 0x8(%rsp)
jmp 0x11059
leaq 0x88(%rsp), %rdi
callq 0x11a90
movq %rax, (%rsp)
jmp 0x1106c
movq (%rsp), %r8
leaq 0x3e02c(%rip), %rdx     # 0x4f0a3
leaq 0x78(%rsp), %rdi
movl $0x1, %esi
movl $0x91, %ecx
callq 0x188e0
jmp 0x1108d
movq 0x8(%rsp), %rsi
leaq 0x78(%rsp), %rdi
callq 0x189b0
jmp 0x1109e
leaq 0x78(%rsp), %rdi
callq 0x18970
leaq 0x80(%rsp), %rdi
callq 0x11aa0
jmp 0x110fa
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
jmp 0x110eb
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0xf8(%rsp)
movl %eax, 0xf4(%rsp)
leaq 0x78(%rsp), %rdi
callq 0x18970
leaq 0x80(%rsp), %rdi
callq 0x11aa0
jmp 0x1111d
leaq 0x88(%rsp), %rdi
callq 0x11ab0
movl 0x9c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x9c(%rsp)
jmp 0x10f45
leaq 0x88(%rsp), %rdi
callq 0x11ab0
jmp 0x1116a
jmp 0x1112e
leaq 0xa0(%rsp), %rdi
callq 0x11970
leaq 0x108(%rsp), %rdi
callq 0x11970
leaq 0x120(%rsp), %rdi
callq 0x11970
leaq 0x138(%rsp), %rdi
callq 0x11970
addq $0x158, %rsp            # imm = 0x158
retq
leaq 0xa0(%rsp), %rdi
callq 0x11970
leaq 0x108(%rsp), %rdi
callq 0x11970
leaq 0x120(%rsp), %rdi
callq 0x11970
leaq 0x138(%rsp), %rdi
callq 0x11970
movq 0xf8(%rsp), %rdi
callq 0xf440
nopl (%rax,%rax)