fortran - Abnormal mpi behaviour for large array -


in following code of array summation give me correct answer, when use max_rows=10,100,1000,10000 , when use max_rows=100000 or more, getting abnormal answer , getting negative partial sum 1 of proces.

program sum_vector use mpi implicit none  integer,parameter::max_rows=100000 integer::myrank,master=0,ierr,status(mpi_status_size),num_procs integer::i,rank,avg_rows_per_procs,sender integer::num_rows_to_send,num_rows_to_receive,start_row,end_row,partial_sum,total_sum,st1,st2 integer,allocatable::vector(:),vector2(:) allocate(vector(max_rows),stat=st1) allocate(vector2(max_rows),stat=st2) if(st1/=0 .or. st2/=0)then     print*,'cannot allocate'     stop end if  call mpi_init(ierr) call mpi_comm_rank(mpi_comm_world,myrank,ierr) call mpi_comm_size(mpi_comm_world,num_procs,ierr) if (myrank==0)then      i=1,max_rows         vector(i)=i     end      avg_rows_per_procs=max_rows/num_procs     rank=1,num_procs-1         start_row=rank*avg_rows_per_procs+1         end_row=start_row+avg_rows_per_procs-1         if (rank==num_procs-1)end_row=max_rows         num_rows_to_send=end_row-start_row+1         call mpi_send(num_rows_to_send,1,mpi_int,rank,101,mpi_comm_world,ierr)         call mpi_send(vector(start_row),num_rows_to_send,mpi_int,rank,102,mpi_comm_world,ierr)     end     total_sum=0     i=1,avg_rows_per_procs         total_sum=total_sum+vector(i)     end     print*,'partial sum=',total_sum,'from root process'      rank=1,num_procs-1         call mpi_recv(partial_sum,1,mpi_int,mpi_any_source,103,mpi_comm_world,status,ierr)         sender=status(mpi_source)         print*,'partial sum=',partial_sum,'from rank',sender         total_sum=total_sum+partial_sum     end      print*,'total sum=',total_sum else     call mpi_recv(num_rows_to_receive,1,mpi_int,master,mpi_any_tag,mpi_comm_world,status,ierr)     call mpi_recv(vector2,num_rows_to_receive,mpi_int,master,mpi_any_tag,mpi_comm_world,status,ierr)     partial_sum=0     i=1,num_rows_to_receive         partial_sum=partial_sum+vector2(i)     end     call mpi_send(partial_sum,1,mpi_int,master,103,mpi_comm_world,ierr) end if  call mpi_finalize(ierr)     stop end program sum_vector 

it seems integer overflow occurs total_sum , partial_sum large max_rows because former become large ~ max_rows**2. changing declaration to

use iso_fortran_env, only: int64 integer(int64) :: total_sum, partial_sum 

and mpi calls sending/receiving partial_sum as

call mpi_recv(partial_sum,1,mpi_long_long_int,mpi_any_source,103,mpi_comm_world,status,ierr) 

and

call mpi_send(partial_sum,1,mpi_long_long_int,master,103,mpi_comm_world,ierr) 

probably gives expected result. example, result obtained max_rows = 100000 , 4 processes (using gfortran 4.7 , openmpi 1.6.5) is

partial sum=            312512500 root process partial sum=            937512500 rank           1 partial sum=           1562512500 rank           2 partial sum=           2187512500 rank           3 total sum=           5000050000 

and result max_rows = 100000000 is

partial sum=      312500012500000 root process partial sum=      937500012500000 rank           1 partial sum=     1562500012500000 rank           2 partial sum=     2187500012500000 rank           3 total sum=     5000000050000000 

this code works long max_rows less ~ 2*10^9.

additional notes:

  • the exact answer total sum = max_rows * (max_rows + 1) / 2 (simply sum 1 max_rows).

  • the maximum number of integer approximately 2*10^9 (please see integer), if max_rows greater 10^5, (10^5)^2 / 2 becomes greater 2*10^9, may exceed limit of integer.

edit: have changed integer(8) integer(int64) portable (please see @casey's comment).


Comments

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -