KronLinInv  0.3
Kronecker-product-based linear inversion

◆ blockpostcov()

subroutine, public ompi_kronlininv::blockpostcov ( real(dp), dimension(:,:), intent(in)  U1,
real(dp), dimension(:,:), intent(in)  U2,
real(dp), dimension(:,:), intent(in)  U3,
real(dp), dimension(:), intent(in)  diaginvlambda,
real(dp), dimension(:,:), intent(in)  iUCm1,
real(dp), dimension(:,:), intent(in)  iUCm2,
real(dp), dimension(:,:), intent(in)  iUCm3,
integer, intent(in)  astart,
integer, intent(in)  aend,
integer, intent(in)  bstart,
integer, intent(in)  bend,
real(dp), dimension(:,:), intent(out)  postC 
)

Computes a block of the posterior covariance.

Parameters
[in]U1,U2,U3\( \mathbf{U}_1 \), \( \mathbf{U}_2 \), \( \mathbf{U}_3 \) of \( F_{\sf{A}} \)
[in]diaginvlambda\( F_{\sf{B}} \)
[in]iUCm1,iUCm2,iUCm3\(\mathbf{U}_1^{-1} \mathbf{C}_{\rm{M}}^{\rm{x}}\), \(\mathbf{U}_2^{-1} \mathbf{C}_{\rm{M}}^{\rm{y}}\), \(\mathbf{U}_2^{-1} \mathbf{C}_{\rm{M}}^{\rm{z}}\) of \( F_{\sf{C}} \)
[in]astart,aendindex of first/last row of the requested block
[in]bstart,bendindex of first/last column of the requested block
[out]postCblock of the posterior covariance
Date
5/8/2016 - Initial Version
4/11/2016 - Removed indices lv,mv,kv
27/13/2016 - New ETA calculations
27/1/2017 - OpenMPI version

Definition at line 585 of file ompi_kronlininv.f08.

585  !!
586  !! Calculates a block of the posterior covariance
587  !!
588  real(dp),intent(in) :: u1(:,:),u2(:,:),u3(:,:),iucm1(:,:), &
589  iucm2(:,:),iucm3(:,:)
590  !! diaginvlambda = (I + lam1 x lam2 x lam3 )^-1
591  real(dp),intent(in) :: diaginvlambda(:) !! diagonal/vector central factor
592  real(dp),intent(out) :: postc(:,:)
593  integer,intent(in) :: astart,aend,bstart,bend
594 
595  integer :: a,b,irow,i,j,sender
596  real(dp),allocatable :: row2(:),col1(:)
597  integer :: nr12,nc1
598  integer :: ni,nj,nk,nl,nm,nn,na,nb,ntota,ntotb
599 
600  integer,allocatable :: av(:)!,bv(:)
601  integer,allocatable :: iv(:),jv(:),kv(:) !,lv(:),mv(:),nv(:)
602  integer :: p,everynit,impicount,mytotit,rirow
603  real(dp) :: startt,firststartt,endt
604  integer,allocatable :: scheduling(:),looping(:,:)
605  real(dp),allocatable :: postcmpi(:,:),recvrow(:),sendrow(:)
606  character(len=30) :: loopinfo
607 
608  if (myrank==masterrank) then
609  write(output_unit,*) "posteriormean(): calculating posterior mean... [using OpenMPI]"
610  end if
611 
612  ni = size(u1,1)
613  nl = size(u1,2)
614  nj = size(u2,1)
615  nm = size(u2,2)
616  nk = size(u3,1)
617  nn = size(u3,2)
618  na = ni*nj*nk
619  nb = nl*nm*nn
620 
621  !! check shape of output array
622  if (na /= nb) then
623  write(*,*) '(Na /= Nb)', na,nb
624  stop
625  end if
626  ntota = aend-astart+1
627  ntotb = bend-bstart+1
628  if ( (size(postc,1)/=ntota) .or. (size(postc,2)/=ntotb)) then
629  write(*,*) "Wrong size of the posterior covariance block array."
630  stop
631  end if
632  !! check limits of requested block
633  if ( (astart<1) .or. (aend>na) .or. (astart>aend) .or. &
634  (bstart<1) .or. (bend>na) .or. (bstart>bend) ) then
635  write(*,*) "Wrong size of the requested block array."
636  stop
637  end if
638 
639  !! vectorize row and col calculations for Kron prod AxBxC
640  allocate(av(na),iv(na),jv(na),kv(na))
641  !allocate(bv(Nb),lv(Nb),mv(Nb),nv(Nb))
642  forall(p = 1:na) av(p) = p
643  !forall(p = 1:Nb) bv(p) = p
644 
645  !! vectors containing all possible indices for
646  !! row calculations of Kron prod AxBxC
647  iv = (av-1)/(nk*nj)+1
648  jv = (av-1-(iv-1)*nk*nj)/nk + 1
649  kv = av-(jv-1)*nk-(iv-1)*nk*nj
650 
651  !! allocate stuff
652  nr12 = size(u1,2)* size(u2,2)* size(u3,2)
653  nc1 = size(iucm1,1)* size(iucm2,1)* size(iucm3,1)
654  allocate(row2(nr12),col1(nc1))
655 
656  !!------------------------
657  if (ntota<1000) then
658  everynit = 20
659  else
660  everynit = ntota/1000
661  end if
662 
663  !!---------------------------------
664  firststartt = mpi_wtime()
665  loopinfo = "blockpostcov() "
666  if (myrank==masterrank) write(output_unit,*)
667  !! calculate scheduling for a
668  call spreadwork(ntota,numcpus,scheduling,looping,1)
669  allocate(postcmpi(scheduling(myrank+1),ntotb),recvrow(ntotb),sendrow(ntotb))
670  mytotit = scheduling(myrank+1)
671 
672  !!print*,myrank,":",looping(myrank+1,1),"|",looping(myrank+1,2),"|",scheduling
673 
674  !!-----------------------
675  startt = mpi_wtime()
676  impicount = 0
677  do irow=looping(myrank+1,1),looping(myrank+1,2)
678  !! set a
679  a=irow+astart-1
680  !! info
681  if ( (myrank==masterrank) .and. (mod(irow,everynit)==0) ) then
682  call timeinfo(mytotit,irow,startt,loopinfo)
683  end if
684 
685  !! row first two factors
686  !! a row x diag matrix
687  !!row2 = U1(iv(a),lv) * U2(jv(a),mv) * U3(kv(a),nv) * diaginvlambda
688  row2 = u1(iv(a),iv) * u2(jv(a),jv) * u3(kv(a),kv) * diaginvlambda
689 
690  j=0
691  do b=bstart,bend
692  j=j+1
693  !! calculate one row of first TWO factors
694  !!call columnAxBxC(Ni,Nj,Nk,Nl,Nm,Nn, iUCm1,iUCm2,iUCm3,b,col1)
695  col1 = iucm1(iv,iv(b)) * iucm2(jv,jv(b)) * iucm3(kv,kv(b))
696 
697  !! calculate one element of the posterior covariance
698  i = irow-looping(myrank+1,1)+1
699  postcmpi(i,j) = sum(row2*col1)
700 
701  end do
702 
703  end do
704 
705  !! collect all results in masterrank
706  call para_barrier()
707  do sender=0,numcpus-1
708  if ( (myrank==sender) .or. (myrank==masterrank) ) then
709  do i=looping(sender+1,1),looping(sender+1,2)
710  !!----------------------
711  !! send/rec each row
712  !print*,"==>",myrank,": sender=",sender,"i=",i
713  if (myrank==sender) sendrow = postcmpi(i,:)
714  call para_srarr1ddp(sender,masterrank,i,sendrow,recvrow)
715  !call para_srint(myrank,masterrank,impicount,irow,rirow)
716  if (myrank==masterrank) postc(i,:) = recvrow
717  end do
718  end if
719  end do
720 
721  call para_barrier()
722  if (myrank==masterrank) then
723  write(output_unit,*)
724  endt = MPI_Wtime()
725  print*,"blockpostcov():",endt-firststartt," MPI wall clock time"
726  end if
727 
integer, parameter, public masterrank
subroutine para_srarr1ddp(source, dest, tag, sendrow, recvrow)
subroutine para_barrier()
integer, public, protected myrank
subroutine spreadwork(nit, nunits, scheduling, looping, startpoint)
integer, public, protected numcpus
subroutine timeinfo(totit, curit, startt, loopinfo)
Here is the call graph for this function:
Here is the caller graph for this function: