dbcsr_mm_multrec_multiply Subroutine

public subroutine dbcsr_mm_multrec_multiply(this, left, right, flop, a_norms, b_norms, k_sizes)

Multiplies two DBCSR matrices using recursive algorithm This routine sets up the multiplication. Specifically, it

  • verifies input sanity
  • converts everything into "local indexing"

Arguments

Type IntentOptional Attributes Name
type(dbcsr_mm_multrec_type), intent(inout) :: this
type(dbcsr_type), intent(in) :: left

left DBCSR matrix right DBCSR matrix

type(dbcsr_type), intent(in) :: right

left DBCSR matrix right DBCSR matrix

integer(kind=int_8), intent(inout) :: flop

number of effective double-precision floating point operations performed

real(kind=sp), intent(in), DIMENSION(:), TARGET :: a_norms

norms of left-matrix blocks norms of right-matrix blocks

real(kind=sp), intent(in), DIMENSION(:), TARGET :: b_norms

norms of left-matrix blocks norms of right-matrix blocks

integer, intent(in), DIMENSION(:), POINTER :: k_sizes

Source Code

   SUBROUTINE dbcsr_mm_multrec_multiply(this, left, right, flop, &
                                        a_norms, b_norms, k_sizes)
      !! Multiplies two DBCSR matrices using recursive algorithm
      !! This routine sets up the multiplication.  Specifically, it <ul>
      !! <li> verifies input sanity
      !! <li> converts everything into "local indexing"
      !! </ul>

      TYPE(dbcsr_mm_multrec_type), INTENT(inout)         :: this
      TYPE(dbcsr_type), INTENT(IN)                       :: left, right
         !! left DBCSR matrix
         !! right DBCSR matrix
      INTEGER(KIND=int_8), INTENT(INOUT)                 :: flop
         !! number of effective double-precision floating point operations performed
      REAL(kind=sp), DIMENSION(:), INTENT(in), TARGET    :: a_norms, b_norms
         !! norms of left-matrix blocks
         !! norms of right-matrix blocks
      INTEGER, DIMENSION(:), INTENT(IN), POINTER         :: k_sizes

!$    INTEGER                                            :: ithread
      INTEGER                                            :: t_a_f, t_a_l, t_b_f, t_b_l
      INTEGER, DIMENSION(:), POINTER                     :: k_locals

!   ---------------------------------------------------------------------------

      IF (.NOT. this%initialized) &
         DBCSR_ABORT("multrec not initialized.")

      this%flop = 0

      ! Find out the local A columns / B rows and sizes
      ! The right%local_rows is setup by the communication engine.
      k_locals => array_data(right%local_rows)
      this%k_locals => k_locals
      this%k_sizes => k_sizes
      ! Setup the block norms
      this%a_norms => a_norms
      this%b_norms => b_norms

      ! Start local multiplication
      t_a_f = 1
      t_a_l = left%nblks
      t_b_f = 1
      t_b_l = right%nblks
!$    IF (ASSOCIATED(left%thr_c)) THEN
!$       ithread = OMP_GET_THREAD_NUM()
!$       t_a_f = left%thr_c(ithread + 1) + 1
!$       t_a_l = left%thr_c(ithread + 2)
!$    END IF
      CALL sparse_multrec(this, left, right, &
                          1, left%nblkrows_local, &
                          1, right%nblkcols_local, &
                          1, SIZE(k_locals), &
                          t_a_f, t_a_l, left%coo_l, &
                          t_b_f, t_b_l, right%coo_l, &
                          0)

      CALL dbcsr_mm_csr_purge_stacks(this%csr, left, right)

      flop = flop + this%flop
      !
   END SUBROUTINE dbcsr_mm_multrec_multiply