// File: /workspace/github_c_makefile_star2_O0/openshmem-org[P]openshmem-examples/c/cpi.c
// Function: main
int
main(int argc, char *argv[])
{
    struct utsname u;
    int myid, numprocs, i;
    double h, sum;
    struct timeval startwtime, endwtime;
    double *pWrkR;              /* symmetric reduction workspace */

    uname(&u);

    shmem_init();
    numprocs = shmem_n_pes();
    myid = shmem_my_pe();

    printf("PE %d on host \"%s\"\n", myid, u.nodename);

    if (myid == 0) {
        if (argc > 1)
            n = atoi(argv[1]);  /* # rectangles on command line */
        else
            n = 10000;          /* default # of rectangles */

        gettimeofday(&startwtime, NULL);
    }

    /* reduction of 1 value: size the workspace accordingly */
    {
        const long pWrkRSize = max2(1 / 2 + 1, SHMEM_REDUCE_MIN_WRKDATA_SIZE);

        pWrkR = (double *) shmem_malloc(pWrkRSize * sizeof(*pWrkR));
    }

    /* initialize sync arrays */
    for (i = 0; i < SHMEM_BCAST_SYNC_SIZE; i += 1) {
        pSyncB[i] = SHMEM_SYNC_VALUE;
    }
    for (i = 0; i < SHMEM_REDUCE_SYNC_SIZE; i += 1) {
        pSyncR[i] = SHMEM_SYNC_VALUE;
    }

    shmem_barrier_all();

    /* -=- set up done -=- */

    /* send "n" out to everyone */
    shmem_broadcast32(&n, &n, 1, 0, 0, 0, numprocs, pSyncB);

    /* do partial computation */
    h = 1.0 / (double) n;
    sum = 0.0;
    /* A slightly better approach starts from large i and works back */
    for (i = myid + 1; i <= n; i += numprocs) {
        const double x = h * ((double) i - 0.5);
        sum += f(x);
    }
    mypi = h * sum;

    /* wait for everyone to finish */
    shmem_barrier_all();

    /* add up partial pi computations into PI */
    shmem_double_sum_to_all(&pi, &mypi, 1, 0, 0, numprocs, pWrkR, pSyncR);

    /* "master" PE summarizes */
    if (myid == 0) {
        double elapsed;
        gettimeofday(&endwtime, NULL);
        elapsed = (endwtime.tv_sec - startwtime.tv_sec) * 1000.0;   /* sec to ms */
        elapsed += (endwtime.tv_usec - startwtime.tv_usec) / 1000.0;    /* us to ms */
        printf("pi is approximately %.16f, Error is %.16f\n",
               pi, fabs(pi - PI25DT));
        printf("run time = %f ms\n", elapsed);
        fflush(stdout);
    }

    shmem_free(pWrkR);

    shmem_finalize();

    return 0;
}

// Assembly:
subq $0x208, %rsp            # imm = 0x208
movl $0x0, 0x204(%rsp)
movl %edi, 0x200(%rsp)
movq %rsi, 0x1f8(%rsp)
leaq 0x72(%rsp), %rdi
callq 0x1040
callq 0x10e0
callq 0x1070
movl %eax, 0x68(%rsp)
callq 0x10a0
movl %eax, 0x6c(%rsp)
movl 0x6c(%rsp), %esi
leaq 0x72(%rsp), %rdx
addq $0x41, %rdx
leaq 0xdda(%rip), %rdi       # 0x2040
movb $0x0, %al
callq 0x1030
cmpl $0x0, 0x6c(%rsp)
jne 0x12af
cmpl $0x1, 0x200(%rsp)
jle 0x1297
movq 0x1f8(%rsp), %rax
movq 0x8(%rax), %rdi
callq 0x10b0
movl %eax, 0x2e1b(%rip)      # 0x40b0
jmp 0x12a1
movl $0x2710, 0x2e0f(%rip)   # imm = 0x2710
leaq 0x40(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1050
movl $0x1, %esi
movq %rsi, %rdi
callq 0x1510
movq %rax, 0x20(%rsp)
movq 0x20(%rsp), %rdi
shlq $0x3, %rdi
callq 0x10c0
movq %rax, 0x28(%rsp)
movl $0x0, 0x64(%rsp)
cmpl $0x2, 0x64(%rsp)
jge 0x1304
movslq 0x64(%rsp), %rcx
leaq 0x2dd1(%rip), %rax      # 0x40c0
movq $-0x1, (%rax,%rcx,8)
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x12dc
movl $0x0, 0x64(%rsp)
cmpl $0x3, 0x64(%rsp)
jge 0x1334
movslq 0x64(%rsp), %rcx
leaq 0x2db1(%rip), %rax      # 0x40d0
movq $-0x1, (%rax,%rcx,8)
movl 0x64(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
jmp 0x130c
callq 0x10d0
movl 0x68(%rsp), %r10d
leaq 0x2d6b(%rip), %rsi      # 0x40b0
movl $0x1, %edx
xorl %r9d, %r9d
leaq 0x2d6c(%rip), %rax      # 0x40c0
movq %rsi, %rdi
movl %r9d, %ecx
movl %r9d, %r8d
movl %r10d, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x1060
cvtsi2sdl 0x2d3d(%rip), %xmm1 # 0x40b0
movsd 0xc8d(%rip), %xmm0      # 0x2008
divsd %xmm1, %xmm0
movsd %xmm0, 0x58(%rsp)
xorps %xmm0, %xmm0
movsd %xmm0, 0x50(%rsp)
movl 0x6c(%rsp), %eax
addl $0x1, %eax
movl %eax, 0x64(%rsp)
movl 0x64(%rsp), %eax
cmpl 0x2d0d(%rip), %eax      # 0x40b0
jg 0x13ec
movsd 0x58(%rsp), %xmm0
cvtsi2sdl 0x64(%rsp), %xmm1
movsd 0xc67(%rip), %xmm2      # 0x2020
subsd %xmm2, %xmm1
mulsd %xmm1, %xmm0
movsd %xmm0, 0x18(%rsp)
movsd 0x18(%rsp), %xmm0
callq 0x1550
addsd 0x50(%rsp), %xmm0
movsd %xmm0, 0x50(%rsp)
movl 0x68(%rsp), %eax
addl 0x64(%rsp), %eax
movl %eax, 0x64(%rsp)
jmp 0x1399
movsd 0x58(%rsp), %xmm0
mulsd 0x50(%rsp), %xmm0
movsd %xmm0, 0x2ce8(%rip)     # 0x40e8
callq 0x10d0
movl 0x68(%rsp), %r9d
movq 0x28(%rsp), %r10
leaq 0x2cda(%rip), %rdi      # 0x40f0
leaq 0x2ccb(%rip), %rsi      # 0x40e8
movl $0x1, %edx
xorl %r8d, %r8d
leaq 0x2ca4(%rip), %rax      # 0x40d0
movl %r8d, %ecx
movq %r10, (%rsp)
movq %rax, 0x8(%rsp)
callq 0x1080
cmpl $0x0, 0x6c(%rsp)
jne 0x14f6
leaq 0x30(%rsp), %rdi
xorl %eax, %eax
movl %eax, %esi
callq 0x1050
movq 0x30(%rsp), %rax
subq 0x40(%rsp), %rax
cvtsi2sd %rax, %xmm0
movsd 0xbab(%rip), %xmm1      # 0x2018
mulsd %xmm1, %xmm0
movsd %xmm0, 0x10(%rsp)
movq 0x38(%rsp), %rax
subq 0x48(%rsp), %rax
cvtsi2sd %rax, %xmm0
movsd 0xb8a(%rip), %xmm1      # 0x2018
divsd %xmm1, %xmm0
addsd 0x10(%rsp), %xmm0
movsd %xmm0, 0x10(%rsp)
movsd 0x2c4a(%rip), %xmm0     # 0x40f0
movsd 0x2c42(%rip), %xmm1     # 0x40f0
movsd 0xb5a(%rip), %xmm2      # 0x2010
subsd %xmm2, %xmm1
movaps 0xb6f(%rip), %xmm2      # 0x2030
pand %xmm2, %xmm1
leaq 0xb88(%rip), %rdi       # 0x2054
movb $0x2, %al
callq 0x1030
movsd 0x10(%rsp), %xmm0
leaq 0xb9f(%rip), %rdi       # 0x207f
movb $0x1, %al
callq 0x1030
movq 0x2b0a(%rip), %rax      # 0x3ff8
movq (%rax), %rdi
callq 0x1100
movq 0x28(%rsp), %rdi
callq 0x10f0
callq 0x1090
xorl %eax, %eax
addq $0x208, %rsp            # imm = 0x208
retq
nop