// File: /workspace/github_c_makefile_star2_O1/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 %r13
pushq %r12
pushq %rbx
subq $0x28, %rsp
callq 0x1110
callq 0x1080
movl %eax, %ebx
callq 0x10a0
movl %eax, %ebp
testl %eax, %eax
jne 0x1565
movq 0x2c38(%rip), %r15      # 0x3fd8
leaq 0xdef(%rip), %r14       # 0x2196
movl $0x1, %edx
movq %r15, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0xc92(%rip), %rsi       # 0x2050
movl $0x21, %edx
movq %r15, %rdi
callq 0x1090
leaq 0xca0(%rip), %rsi       # 0x2072
movl $0xe, %edx
movq %r15, %rdi
callq 0x1090
movl $0x1, %edx
movq %r15, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0xc8b(%rip), %rsi       # 0x2081
movl $0x29, %edx
movq %r15, %rdi
callq 0x1090
leaq 0xca1(%rip), %rsi       # 0x20ab
movl $0x2e, %edx
movq %r15, %rdi
callq 0x1090
leaq 0xcbc(%rip), %rsi       # 0x20da
movl $0x2f, %edx
movq %r15, %rdi
callq 0x1090
leaq 0xcd8(%rip), %rsi       # 0x210a
movl $0x2d, %edx
movq %r15, %rdi
callq 0x1090
leaq 0xcf2(%rip), %rsi       # 0x2138
movl $0x2a, %edx
movq %r15, %rdi
callq 0x1090
leaq 0xd09(%rip), %rsi       # 0x2163
movl $0x34, %edx
movq %r15, %rdi
callq 0x1090
leaq 0xd2a(%rip), %rsi       # 0x2198
movl $0x13, %edx
movq %r15, %rdi
callq 0x1090
movl $0x1, %edx
movq %r15, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0xd1a(%rip), %rsi       # 0x21ac
movl $0x1d, %edx
movq %r15, %rdi
callq 0x1090
movq %r15, %rdi
movl %ebx, %esi
callq 0x10f0
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x1090
movl $0x1, %edx
movq %r15, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0xcfa(%rip), %rsi       # 0x21ca
movl $0x14, %edx
movq %r15, %rdi
callq 0x1090
movsd 0xb43(%rip), %xmm0      # 0x2028
movq %r15, %rdi
callq 0x10e0
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0xcdb(%rip), %rsi       # 0x21df
movl $0x14, %edx
movq %r15, %rdi
callq 0x1090
movq %r15, %rdi
movsd 0xb0c(%rip), %xmm0      # 0x2028
callq 0x10e0
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x1090
leaq 0xcbc(%rip), %rsi       # 0x21f4
movl $0x14, %edx
movq %r15, %rdi
callq 0x1090
movq %r15, %rdi
movsd 0xad8(%rip), %xmm0      # 0x2028
callq 0x10e0
movl $0x1, %edx
movq %rax, %rdi
movq %r14, %rsi
callq 0x1090
callq 0x10b0
imull $0x64, %ebp, %r15d
addl $0x75bcd15, %r15d       # imm = 0x75BCD15
movl %r15d, %edi
callq 0x1070
callq 0x1040
xorps %xmm0, %xmm0
cvtsi2sd %eax, %xmm0
divsd 0xa77(%rip), %xmm0      # 0x2008
movsd %xmm0, (%rsp)
movq 0x2a3b(%rip), %r14      # 0x3fd8
leaq 0xc38(%rip), %r12       # 0x21dc
movl $0x2, %edx
movq %r14, %rdi
movq %r12, %rsi
callq 0x1090
movq (%r14), %rax
movq -0x18(%rax), %rax
movq $0x8, 0x10(%r14,%rax)
movq %r14, %rdi
movl %ebp, %esi
callq 0x10f0
movq %rax, %r13
movl $0x2, %edx
movq %rax, %rdi
movq %r12, %rsi
callq 0x1090
movq (%r13), %rax
movq -0x18(%rax), %rax
movq $0xc, 0x10(%r13,%rax)
movq %r13, %rdi
movl %r15d, %esi
callq 0x10f0
movq %rax, %r15
movl $0x2, %edx
movq %rax, %rdi
movq %r12, %rsi
callq 0x1090
movq (%r15), %rax
movq -0x18(%rax), %rax
movq $0xe, 0x10(%r15,%rax)
movq %r15, %rdi
movsd (%rsp), %xmm0
callq 0x10e0
leaq 0xb62(%rip), %rsi       # 0x2196
movl $0x1, %edx
movq %rax, %rdi
callq 0x1090
movq 0x9df(%rip), %xmm0      # 0x2028
movdqa %xmm0, %xmm1
movdqa %xmm0, %xmm2
movl $0x186a0, %edi          # imm = 0x186A0
callq 0x124c
movl %eax, 0x2a73(%rip)      # 0x40d4
leaq 0x2a6c(%rip), %r15      # 0x40d4
pcmpeqd %xmm0, %xmm0
movdqa %xmm0, 0x2a4c(%rip)     # 0x40c0
leaq 0x2a45(%rip), %r12      # 0x40c0
callq 0x10b0
leaq 0x2a2d(%rip), %rax      # 0x40b4
leaq 0x2a42(%rip), %rdi      # 0x40d0
movq %r15, %rsi
movl $0x1, %edx
xorl %ecx, %ecx
xorl %r8d, %r8d
movl %ebx, %r9d
pushq %r12
pushq %rax
callq 0x10c0
addq $0x10, %rsp
testl %ebp, %ebp
jne 0x189b
imull $0x186a0, %ebx, %ebp    # imm = 0x186A0
movl 0x2a12(%rip), %eax      # 0x40d0
xorps %xmm2, %xmm2
cvtsi2sd %eax, %xmm2
xorps %xmm0, %xmm0
cvtsi2sd %ebp, %xmm0
divsd %xmm0, %xmm2
testl %eax, %eax
movsd %xmm2, 0x18(%rsp)
je 0x16e8
movsd 0x94e(%rip), %xmm1      # 0x2030
divsd %xmm2, %xmm1
jmp 0x16f0
movsd 0x930(%rip), %xmm1      # 0x2020
movsd %xmm1, 0x20(%rsp)
movsd 0x93a(%rip), %xmm0      # 0x2038
subsd %xmm1, %xmm0
movapd 0x936(%rip), %xmm1      # 0x2040
xorpd %xmm0, %xmm1
movapd %xmm1, %xmm2
cmplesd %xmm0, %xmm2
andpd %xmm2, %xmm0
andnpd %xmm1, %xmm2
orpd %xmm0, %xmm2
movapd %xmm2, (%rsp)
leaq 0xa67(%rip), %rbx       # 0x2196
movl $0x1, %edx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x1090
leaq 0xac3(%rip), %rsi       # 0x2209
movl $0x46, %edx
movq %r14, %rdi
callq 0x1090
movl $0x1, %edx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x1090
leaq 0xa72(%rip), %r15       # 0x21dc
movl $0x2, %edx
movq %r14, %rdi
movq %r15, %rsi
callq 0x1090
movq (%r14), %rax
movq -0x18(%rax), %rax
movl $0x8, %r13d
movq %r13, 0x10(%r14,%rax)
movq %r14, %rdi
movl %ebp, %esi
callq 0x10f0
movq %rax, %r12
movl $0x2, %edx
movq %rax, %rdi
movq %r15, %rsi
callq 0x1090
movq (%r12), %rax
movq -0x18(%rax), %rax
movq %r13, 0x10(%r12,%rax)
movl 0x2914(%rip), %esi      # 0x40d0
movq %r12, %rdi
callq 0x10f0
movq %rax, %r12
movl $0x2, %edx
movq %rax, %rdi
movq %r15, %rsi
callq 0x1090
movq (%r12), %rax
movq -0x18(%rax), %rax
movl $0x10, %r13d
movq %r13, 0x10(%r12,%rax)
movq %r12, %rdi
movsd 0x18(%rsp), %xmm0
callq 0x10e0
movq %rax, %r12
movl $0x2, %edx
movq %rax, %rdi
movq %r15, %rsi
callq 0x1090
movq (%r12), %rax
movq -0x18(%rax), %rax
movq %r13, 0x10(%r12,%rax)
movq %r12, %rdi
movsd 0x20(%rsp), %xmm0
callq 0x10e0
movq %rax, %r12
movl $0x2, %edx
movq %rax, %rdi
movq %r15, %rsi
callq 0x1090
movq (%r12), %rax
movq -0x18(%rax), %rax
movq %r13, 0x10(%r12,%rax)
movq %r12, %rdi
movdqa (%rsp), %xmm0
callq 0x10e0
movl $0x1, %edx
movq %rax, %rdi
movq %rbx, %rsi
callq 0x1090
movl $0x1, %edx
movq %r14, %rdi
movq %rbx, %rsi
callq 0x1090
leaq 0x7d6(%rip), %rsi       # 0x2050
movl $0x21, %edx
movq %r14, %rdi
callq 0x1090
leaq 0x9c2(%rip), %rsi       # 0x2250
movl $0x1b, %edx
movq %r14, %rdi
callq 0x1090
callq 0x1050
xorl %eax, %eax
addq $0x28, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq