// File: /workspace/github_c_makefile_star2_O0/lukas783[P]N-Queens-MPI/nqueens.c
// Function: main
int main(int argc, char*argv[]) {

  // declare some variables
  int rnk, sze;    
  ull i = 0 , n = 0, total = 0, subtot = 0;
  double elapsed_time;

  // initialize mpi
  MPI_Init(&argc, &argv);

  // set rank and size of all procs
  MPI_Comm_rank(MPI_COMM_WORLD, &rnk);
  MPI_Comm_size(MPI_COMM_WORLD, &sze);

  // set start time
  MPI_Barrier(MPI_COMM_WORLD);
  elapsed_time = -MPI_Wtime();

  // find out if program has correct command line arguments, prompt if not
  if(argc != 2) {
    if(rnk == 0)
      printf("Invalid number of command line arguments.\nFormat should be ./nqueens <n>\n\n");
  } else {
    // set value of n from command line and create an array of length n
    n = atoi(argv[1]);

    // find the max size for the loop below
    ull max = factorial(n);

    // start at the rnkth permutation and move up sze permutations at a time till at end
    for( i = rnk; i < max; i+=sze ) {
      subtot += nqueens(rnk, i, n);
    }

    // reduce subtotal into grand total
    MPI_Reduce(&subtot, &total, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);
    
  }

  // find ending time
  MPI_Barrier(MPI_COMM_WORLD);
  elapsed_time += MPI_Wtime();

  // if root rank, output solutions found and time taken
  if(0 == rnk) {
    printf("Program executed in %8.3f ms\n", 1000*elapsed_time);
    printf("Total number of solutions found: %llu\n\n", total);
    fflush(stdout);
  }

  //exit program
  MPI_Finalize();
  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x50, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movq $0x0, -0x20(%rbp)
movq $0x0, -0x28(%rbp)
movq $0x0, -0x30(%rbp)
movq $0x0, -0x38(%rbp)
leaq -0x8(%rbp), %rdi
leaq -0x10(%rbp), %rsi
callq 0x77c0
movq 0xa356(%rip), %rdi      # 0x11fc0
leaq -0x14(%rbp), %rsi
callq 0x77b0
movq 0xa346(%rip), %rdi      # 0x11fc0
leaq -0x18(%rbp), %rsi
callq 0x75f0
movq 0xa336(%rip), %rdi      # 0x11fc0
callq 0x7350
callq 0x76a0
movq %xmm0, %rax
movabsq $-0x8000000000000000, %rcx # imm = 0x8000000000000000
xorq %rcx, %rax
movq %rax, %xmm0
movsd %xmm0, -0x40(%rbp)
cmpl $0x2, -0x8(%rbp)
je 0x7ccf
cmpl $0x0, -0x14(%rbp)
jne 0x7cca
leaq 0x534d(%rip), %rdi      # 0xd010
movb $0x0, %al
callq 0x7040
jmp 0x7d57
movq -0x10(%rbp), %rax
movq 0x8(%rax), %rdi
callq 0x7870
cltq
movq %rax, -0x28(%rbp)
movq -0x28(%rbp), %rdi
callq 0x7dd0
movq %rax, -0x48(%rbp)
movslq -0x14(%rbp), %rax
movq %rax, -0x20(%rbp)
movq -0x20(%rbp), %rax
cmpq -0x48(%rbp), %rax
jae 0x7d29
movl -0x14(%rbp), %edi
movq -0x20(%rbp), %rsi
movq -0x28(%rbp), %rdx
callq 0x7e20
cltq
addq -0x38(%rbp), %rax
movq %rax, -0x38(%rbp)
movslq -0x18(%rbp), %rax
addq -0x20(%rbp), %rax
movq %rax, -0x20(%rbp)
jmp 0x7cf7
leaq -0x38(%rbp), %rdi
leaq -0x30(%rbp), %rsi
movl $0x1, %edx
movq 0xa29b(%rip), %rcx      # 0x11fd8
movq 0xa264(%rip), %r8       # 0x11fa8
xorl %r9d, %r9d
movq 0xa272(%rip), %rax      # 0x11fc0
movq %rax, (%rsp)
callq 0x7700
movq 0xa262(%rip), %rdi      # 0x11fc0
callq 0x7350
callq 0x76a0
addsd -0x40(%rbp), %xmm0
movsd %xmm0, -0x40(%rbp)
xorl %eax, %eax
cmpl -0x14(%rbp), %eax
jne 0x7db5
movsd 0x5287(%rip), %xmm0     # 0xd008
mulsd -0x40(%rbp), %xmm0
leaq 0x52ce(%rip), %rdi      # 0xd05b
movb $0x1, %al
callq 0x7040
movq -0x30(%rbp), %rsi
leaq 0x52da(%rip), %rdi      # 0xd079
movb $0x0, %al
callq 0x7040
movq 0xa203(%rip), %rax      # 0x11fb0
movq (%rax), %rdi
callq 0x7600
callq 0x73c0
xorl %eax, %eax
addq $0x50, %rsp
popq %rbp
retq
nopw %cs:(%rax,%rax)