File: xgemm.F

package info (click to toggle)
aces3 3.0.6-7
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 82,460 kB
  • sloc: fortran: 225,647; ansic: 20,413; cpp: 4,349; makefile: 953; sh: 137
file content (109 lines) | stat: -rw-r--r-- 3,655 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109

cYAU - WARNING ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING ! WARNING
c
c    The original xgemm filtered lda, ldb, and ldc through max(1,ld?).
c This subtly changes the behavior of dgemm depending on the other arguments.
c I refused to continue that tradition. There is quite a bit of debugging
c info in this routine which should help in finding the places where the
c leading dimensions are not properly checked.

      subroutine xgemm(transa,transb,
     &                 m,n,k,alpha,a,lda,
     &                             b,ldb,
     &                       beta, c,ldc)

c ARGUMENT LIST
      character*1 transa, transb
      integer m, n, k, lda, ldb, ldc
      double precision alpha, beta
c      double precision a(lda,*), b(ldb,*), c(ldc,*)
      double precision a, b, c

c EXTERNAL FUNCTIONS

c INTERNAL VARIABLES
c Be careful here. If you build your own generic gemm, then make sure
c you use the same integer type. Otherwise, if you link against
c system-BLAS, make sure you cast the arguments correctly.

#ifdef _32BIT_BLAS
      integer*4 int_m, int_n, int_k, int_lda, int_ldb, int_ldc
#else
      integer   int_m, int_n, int_k, int_lda, int_ldb, int_ldc
#endif /* _32BIT_BLAS */

c ----------------------------------------------------------------------

c This quick return code was taken straight from blas/dgemm. We need it
c for cases when m=lda=0 (e.g., the number of occupied orbitals is zero
c but we didn't check for it). Rather than have dgemm crash, we just
c want to return having done nothing. This also saves us from filtering
c lda, ldb, and ldc through max(1,ld?).

c BEWARE!!! xgemm will, therefore, not crash when the other arguments
c are ill-conditioned.

      if ((m.eq.0).or.
     &    (n.eq.0).or.
     &    (((alpha.eq.(0.0d0)).or.(k.eq.0)).and.(beta.eq.(1.0d0)))
     &   ) return

c ----------------------------------------------------------------------

#ifdef _DEBUG
      if (.not.(
     &             (
     &                  (transa.eq.'N').or.(transa.eq.'n').or.
     &                  (transa.eq.'T').or.(transa.eq.'t').or.
     &                  (transa.eq.'C').or.(transa.eq.'c')
     &             )
     &             .and.
     &             (
     &                  (transb.eq.'N').or.(transb.eq.'n').or.
     &                  (transb.eq.'T').or.(transb.eq.'t').or.
     &                  (transb.eq.'C').or.(transb.eq.'c')
     &             )
     &         )
     &   ) then
         print *, '@XGEMM: TRANSA and TRANSB must be N, T, or C.'
         print *, '        TRANSA : ', TRANSA, ', TRANSB : ', TRANSB
         call c_exit(1)
      end if
      if (min(lda,ldb,ldc).eq.0) then
         print *, '@XGEMM: A leading dimension cannot be zero.'
         print *, '        M = ',M,', N = ',N,', K = ',K
         print *, '        LDA = ',LDA,', LDB = ',LDB,', LDC = ',LDC
c      o Trap this with a debugger. Hopefully, the optimizer will fail
c        to recognize the denominator is definitely 0.
         lda=1/lda
         ldb=1/ldb
         ldc=1/ldc
         call c_exit(1)
      end if
#endif

c ----------------------------------------------------------------------

c   o recast the arguments
      int_m   = m
      int_n   = n
      int_k   = k
      int_lda = lda
      int_ldb = ldb
      int_ldc = ldc

#ifdef USE_SP_BLAS
      call sgemm(transa,transb,int_m,int_n,int_k,
     &           alpha,a,int_lda,
     &                 b,int_ldb,
     &           beta, c,int_ldc)
#else
      call dgemm(transa,transb,int_m,int_n,int_k,
     &           alpha,a,int_lda,
     &                 b,int_ldb,
     &           beta, c,int_ldc)
#endif

      return
      end