// File: /workspace/github_c_makefile_star2_O2/openshmem-org[P]openshmem-examples/c++/buffon.cxx
// Function: main
int
main()
{
    const double a = 1.0;
    const double b = 1.0;
    const double l = 1.0;
    const int master = 0;
    double pdf_estimate;
    double pi_error;
    double pi_estimate;
    int process_num;
    int process_rank;
    double random_value;
    int seed;
    int trial_num = 100000;
    int trial_total;

    //
    // Initialize SHMEM.
    //
    shmem_init();
    //
    // Get the number of processes.
    //
    process_num = shmem_n_pes();
    //
    // Get the rank of this process.
    //
    process_rank = shmem_my_pe();
    //
    // The master process prints a message.
    //
    if (process_rank == master) {
        std::cout << "\n";
        std::cout << "BUFFON_LAPLACE - Master process:\n";
        std::cout << "  C++ version\n";
        std::cout << "\n";
        std::cout << "  A SHMEM example program to estimate PI\n";
        std::cout << "  using the Buffon-Laplace needle experiment.\n";
        std::cout << "  On a grid of cells of  width A and height B,\n";
        std::cout << "  a needle of length L is dropped at random.\n";
        std::cout << "  We count the number of times it crosses\n";
        std::cout << "  at least one grid line, and use this to estimate \n";
        std::cout << "  the value of PI.\n";
        std::cout << "\n";
        std::cout << "  The number of processes is " << process_num << "\n";
        std::cout << "\n";
        std::cout << "  Cell width A =    " << a << "\n";
        std::cout << "  Cell height B =   " << b << "\n";
        std::cout << "  Needle length L = " << l << "\n";
    }
    //
    // added barrier here to force output sequence
    //
    shmem_barrier_all();
    //
    // Each process sets a random number seed.
    //
    seed = 123456789 + process_rank * 100;
    srand(seed);
    //
    // Just to make sure that we're all doing different things, have each
    // process print out its rank, seed value, and a first test random value.
    //
    random_value = (double) rand() / (double) RAND_MAX;

    std::cout << "  " << std::setw(8) << process_rank
     << "  " << std::setw(12) << seed
     << "  " << std::setw(14) << random_value << "\n";
    //
    // Each process now carries out TRIAL_NUM trials, and then
    // sends the value back to the master process.
    //
    hit_num = buffon_laplace_simulate(a, b, l, trial_num);

    //
    // initialize sync buffer for reduction
    //
    for (int i = 0; i < SHMEM_BCAST_SYNC_SIZE; ++i) {
        pSync[i] = SHMEM_SYNC_VALUE;
    }
    shmem_barrier_all();

    shmem_int_sum_to_all(&hit_total, &hit_num, 1, 0, 0, process_num, pWrk,
                         pSync);

    //
    // The master process can now estimate PI.
    //
    if (process_rank == master) {
        trial_total = trial_num * process_num;

        pdf_estimate = (double) hit_total / (double) trial_total;

        if (hit_total == 0) {
            pi_estimate = r8_huge();
        }
        else {
            pi_estimate = l * (2.0 * (a + b) - l) / (a * b * pdf_estimate);
        }

        pi_error = r8_abs(PI - pi_estimate);

        std::cout << "\n";
        std::cout <<
            "    Trials      Hits    Estimated PDF       Estimated Pi        Error\n";
        std::cout << "\n";
        std::cout << "  " << std::setw(8) << trial_total
         << "  " << std::setw(8) << hit_total
         << "  " << std::setw(16) << pdf_estimate
         << "  " << std::setw(16) << pi_estimate
         << "  " << std::setw(16) << pi_error << "\n";
    }
    //
    // Shut down
    //
    if (process_rank == master) {
        std::cout << "\n";
        std::cout << "BUFFON_LAPLACE - Master process:\n";
        std::cout << "  Normal end of execution.\n";
    }

    shmem_finalize();

    return 0;
}

// Assembly:
pushq %rbp
pushq %r15
pushq %r14
pushq %r12
pushq %rbx
subq $0x20, %rsp
callq 0x1110
callq 0x1080
movl %eax, %ebx
callq 0x10a0
movl %eax, %ebp
testl %eax, %eax
jne 0x14f4
movq 0x2c40(%rip), %r15      # 0x3fd8
leaq 0xdf7(%rip), %r14       # 0x2196
movq %r15, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0xc9f(%rip), %rsi       # 0x2050
movq %r15, %rdi
callq 0x1090
leaq 0xcb2(%rip), %rsi       # 0x2072
movq %r15, %rdi
callq 0x1090
movq %r15, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0xca7(%rip), %rsi       # 0x2081
movq %r15, %rdi
callq 0x1090
leaq 0xcc2(%rip), %rsi       # 0x20ab
movq %r15, %rdi
callq 0x1090
leaq 0xce2(%rip), %rsi       # 0x20da
movq %r15, %rdi
callq 0x1090
leaq 0xd03(%rip), %rsi       # 0x210a
movq %r15, %rdi
callq 0x1090
leaq 0xd22(%rip), %rsi       # 0x2138
movq %r15, %rdi
callq 0x1090
leaq 0xd3e(%rip), %rsi       # 0x2163
movq %r15, %rdi
callq 0x1090
leaq 0xd64(%rip), %rsi       # 0x2198
movq %r15, %rdi
callq 0x1090
movq %r15, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0xd5e(%rip), %rsi       # 0x21ac
movq %r15, %rdi
callq 0x1090
movq %rax, %rdi
movl %ebx, %esi
callq 0x10f0
movq %rax, %rdi
movq %r14, %rsi
callq 0x1090
movq %r15, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0xd4d(%rip), %rsi       # 0x21ca
movq %r15, %rdi
callq 0x1090
movsd 0xb9b(%rip), %xmm0      # 0x2028
movq %rax, %rdi
callq 0x10e0
movq %rax, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0xd38(%rip), %rsi       # 0x21df
movq %r15, %rdi
callq 0x1090
movq %rax, %rdi
movsd 0xb6e(%rip), %xmm0      # 0x2028
callq 0x10e0
movq %rax, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0xd23(%rip), %rsi       # 0x21f4
movq %r15, %rdi
callq 0x1090
movq %rax, %rdi
movsd 0xb44(%rip), %xmm0      # 0x2028
callq 0x10e0
movq %rax, %rdi
movq %r14, %rsi
callq 0x1090
callq 0x10b0
imull $0x64, %ebp, %r14d
addl $0x75bcd15, %r14d       # imm = 0x75BCD15
movl %r14d, %edi
callq 0x1070
callq 0x1040
cvtsi2sd %eax, %xmm0
divsd 0xaeb(%rip), %xmm0      # 0x2008
movsd %xmm0, (%rsp)
movq 0x2aaf(%rip), %rdi      # 0x3fd8
leaq 0xcac(%rip), %r15       # 0x21dc
movq %r15, %rsi
callq 0x1090
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq $0x8, 0x10(%rax,%rcx)
movq %rax, %rdi
movl %ebp, %esi
callq 0x10f0
movq %rax, %rdi
movq %r15, %rsi
callq 0x1090
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq $0xc, 0x10(%rax,%rcx)
movq %rax, %rdi
movl %r14d, %esi
callq 0x10f0
movq %rax, %rdi
movq %r15, %rsi
callq 0x1090
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq $0xe, 0x10(%rax,%rcx)
movq %rax, %rdi
movsd (%rsp), %xmm0
callq 0x10e0
leaq 0xbef(%rip), %rsi       # 0x2196
movq %rax, %rdi
callq 0x1090
movq 0xa71(%rip), %xmm0      # 0x2028
movdqa %xmm0, %xmm1
movdqa %xmm0, %xmm2
movl $0x186a0, %edi          # imm = 0x186A0
callq 0x124c
movl %eax, 0x2b05(%rip)      # 0x40d4
leaq 0x2afe(%rip), %r14      # 0x40d4
pcmpeqd %xmm0, %xmm0
movdqa %xmm0, 0x2ade(%rip)     # 0x40c0
leaq 0x2ad7(%rip), %r15      # 0x40c0
callq 0x10b0
leaq 0x2abf(%rip), %rax      # 0x40b4
leaq 0x2ad4(%rip), %rdi      # 0x40d0
pushq $0x1
popq %rdx
movq %r14, %rsi
xorl %ecx, %ecx
xorl %r8d, %r8d
movl %ebx, %r9d
pushq %r15
pushq %rax
callq 0x10c0
popq %rax
popq %rcx
testl %ebp, %ebp
jne 0x17b6
imull $0x186a0, %ebx, %ebp    # imm = 0x186A0
movl 0x2aa8(%rip), %eax      # 0x40d0
cvtsi2sd %eax, %xmm2
cvtsi2sd %ebp, %xmm0
divsd %xmm0, %xmm2
testl %eax, %eax
movsd %xmm2, 0x10(%rsp)
je 0x164c
movsd 0x9ea(%rip), %xmm1      # 0x2030
divsd %xmm2, %xmm1
jmp 0x1654
movsd 0x9cc(%rip), %xmm1      # 0x2020
movsd %xmm1, 0x18(%rsp)
movsd 0x9d6(%rip), %xmm0      # 0x2038
subsd %xmm1, %xmm0
movapd 0x9d2(%rip), %xmm1      # 0x2040
xorpd %xmm0, %xmm1
movapd %xmm1, %xmm2
cmplesd %xmm0, %xmm2
andpd %xmm2, %xmm0
andnpd %xmm1, %xmm2
orpd %xmm0, %xmm2
movapd %xmm2, (%rsp)
movq 0x2945(%rip), %rbx      # 0x3fd8
leaq 0xafc(%rip), %r14       # 0x2196
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0xb5d(%rip), %rsi       # 0x2209
movq %rbx, %rdi
callq 0x1090
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0xb16(%rip), %r15       # 0x21dc
movq %rbx, %rdi
movq %r15, %rsi
callq 0x1090
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
pushq $0x8
popq %r12
movq %r12, 0x10(%rax,%rcx)
movq %rax, %rdi
movl %ebp, %esi
callq 0x10f0
movq %rax, %rdi
movq %r15, %rsi
callq 0x1090
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq %r12, 0x10(%rax,%rcx)
movl 0x29c8(%rip), %esi      # 0x40d0
movq %rax, %rdi
callq 0x10f0
movq %rax, %rdi
movq %r15, %rsi
callq 0x1090
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
pushq $0x10
popq %r12
movq %r12, 0x10(%rax,%rcx)
movq %rax, %rdi
movsd 0x10(%rsp), %xmm0
callq 0x10e0
movq %rax, %rdi
movq %r15, %rsi
callq 0x1090
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq %r12, 0x10(%rax,%rcx)
movq %rax, %rdi
movsd 0x18(%rsp), %xmm0
callq 0x10e0
movq %rax, %rdi
movq %r15, %rsi
callq 0x1090
movq (%rax), %rcx
movq -0x18(%rcx), %rcx
movq %r12, 0x10(%rax,%rcx)
movq %rax, %rdi
movdqa (%rsp), %xmm0
callq 0x10e0
movq %rax, %rdi
movq %r14, %rsi
callq 0x1090
movq %rbx, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0x8b1(%rip), %rsi       # 0x2050
movq %rbx, %rdi
callq 0x1090
leaq 0xaa2(%rip), %rsi       # 0x2250
movq %rbx, %rdi
callq 0x1090
callq 0x1050
xorl %eax, %eax
addq $0x20, %rsp
popq %rbx
popq %r12
popq %r14
popq %r15
popq %rbp
retq