// File: WeihuaZhu[P]hpc_prog2/mpi_tests.cpp
// Function: MpiTest_Jacobi1_Test::TestBody()
TEST(MpiTest, Jacobi1)
{
    // simple 4 by 4 input matrix
    double A[4*4] = {10., -1., 2., 0.,
                           -1., 11., -1., 3.,
                           2., -1., 10., -1.,
                           0.0, 3., -1., 8.};
    double b[4] =  {6., 25., -11., 15.};
    double x[4];
    double expected_x[4] = {1.0,  2.0, -1.0, 1.0};
    int n = 4;

    // get grid communicator
    MPI_Comm grid_comm;
    get_grid_comm(&grid_comm);

    // testing sequential matrix multiplication
    mpi_jacobi(n, A, b, x, grid_comm);

    // checking if all values are correct (up to some error value)
    for (int i = 0; i < n; ++i)
    {
        EXPECT_NEAR(expected_x[i], x[i], 1e-5) << " element y[" << i << "] is wrong";
    }
}

// Assembly:
subq $0x168, %rsp            # imm = 0x168
movq %rdi, 0x160(%rsp)
leaq 0xe0(%rsp), %rdi
leaq 0x3e7f2(%rip), %rsi     # 0x4f230
movl $0x80, %edx
callq 0xe870
movq 0x3e8c1(%rip), %rax     # 0x4f310
movq %rax, 0xc0(%rsp)
movq 0x3e8ba(%rip), %rax     # 0x4f318
movq %rax, 0xc8(%rsp)
movq 0x3e8b3(%rip), %rax     # 0x4f320
movq %rax, 0xd0(%rsp)
movq 0x3e8ac(%rip), %rax     # 0x4f328
movq %rax, 0xd8(%rsp)
movq 0x3e8c5(%rip), %rax     # 0x4f350
movq %rax, 0x80(%rsp)
movq 0x3e8be(%rip), %rax     # 0x4f358
movq %rax, 0x88(%rsp)
movq 0x3e8b7(%rip), %rax     # 0x4f360
movq %rax, 0x90(%rsp)
movq 0x3e8b0(%rip), %rax     # 0x4f368
movq %rax, 0x98(%rsp)
movl $0x4, 0x7c(%rsp)
leaq 0x70(%rsp), %rdi
callq 0x105a0
movl 0x7c(%rsp), %edi
leaq 0xe0(%rsp), %rsi
leaq 0xc0(%rsp), %rdx
leaq 0xa0(%rsp), %rcx
movq 0x70(%rsp), %r8
movl $0x64, %r9d
movsd 0x3e527(%rip), %xmm0    # 0x4f028
callq 0x4dff0
movl $0x0, 0x6c(%rsp)
movl 0x6c(%rsp), %eax
cmpl 0x7c(%rsp), %eax
jge 0x10c97
movslq 0x6c(%rsp), %rax
movsd 0x80(%rsp,%rax,8), %xmm0
movsd 0xa0(%rsp,%rax,8), %xmm1
leaq 0x3e5c4(%rip), %rsi     # 0x4f0fe
leaq 0x3e5c6(%rip), %rdx     # 0x4f107
leaq 0x3e5c4(%rip), %rcx     # 0x4f10c
leaq 0x58(%rsp), %rdi
movq %rdi, 0x28(%rsp)
movsd 0x3e4d6(%rip), %xmm2    # 0x4f030
callq 0x1c2f0
movq 0x28(%rsp), %rdi
callq 0x11a40
movb %al, 0x37(%rsp)
jmp 0x10b6f
movb 0x37(%rsp), %al
testb $0x1, %al
jne 0x10b79
jmp 0x10b91
jmp 0x10c71
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x50(%rsp)
movl %eax, 0x4c(%rsp)
jmp 0x10c8b
leaq 0x40(%rsp), %rdi
callq 0x1b7b0
jmp 0x10b9d
leaq 0x3e53b(%rip), %rsi     # 0x4f0df
leaq 0x40(%rsp), %rdi
callq 0x11b20
movq %rax, 0x20(%rsp)
jmp 0x10bb5
movq 0x20(%rsp), %rdi
leaq 0x6c(%rsp), %rsi
callq 0x11b60
movq %rax, 0x18(%rsp)
jmp 0x10bcb
movq 0x18(%rsp), %rdi
leaq 0x3e514(%rip), %rsi     # 0x4f0eb
callq 0x11ba0
movq %rax, 0x10(%rsp)
jmp 0x10be3
leaq 0x58(%rsp), %rdi
callq 0x11a90
movq %rax, 0x8(%rsp)
jmp 0x10bf4
movq 0x8(%rsp), %r8
leaq 0x3e4a3(%rip), %rdx     # 0x4f0a3
leaq 0x38(%rsp), %rdi
movl $0x1, %esi
movl $0x62, %ecx
callq 0x188e0
jmp 0x10c16
movq 0x10(%rsp), %rsi
leaq 0x38(%rsp), %rdi
callq 0x189b0
jmp 0x10c27
leaq 0x38(%rsp), %rdi
callq 0x18970
leaq 0x40(%rsp), %rdi
callq 0x11aa0
jmp 0x10c71
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x50(%rsp)
movl %eax, 0x4c(%rsp)
jmp 0x10c65
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x50(%rsp)
movl %eax, 0x4c(%rsp)
leaq 0x38(%rsp), %rdi
callq 0x18970
leaq 0x40(%rsp), %rdi
callq 0x11aa0
jmp 0x10c8b
leaq 0x58(%rsp), %rdi
callq 0x11ab0
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x6c(%rsp)
jmp 0x10b0e
leaq 0x58(%rsp), %rdi
callq 0x11ab0
jmp 0x10c9f
addq $0x168, %rsp            # imm = 0x168
retq
movq 0x50(%rsp), %rdi
callq 0xf440
nopl (%rax)