File: octave_blas.m4

package info (click to toggle)
octave 10.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 145,280 kB
  • sloc: cpp: 335,864; ansic: 82,242; fortran: 20,963; objc: 9,396; sh: 8,713; yacc: 4,392; lex: 4,327; perl: 1,544; java: 1,366; awk: 1,259; makefile: 656; xml: 191
file content (143 lines) | stat: -rw-r--r-- 4,918 bytes parent folder | download
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
dnl --------------------------------------------------------------------
dnl
dnl Copyright (C) 2022-2025 The Octave Project Developers
dnl
dnl See the file COPYRIGHT.md in the top-level directory of this
dnl distribution or <https://octave.org/copyright/>.
dnl
dnl This file is part of Octave.
dnl
dnl Octave is free software: you can redistribute it and/or modify it
dnl under the terms of the GNU General Public License as published by
dnl the Free Software Foundation, either version 3 of the License, or
dnl (at your option) any later version.
dnl
dnl Octave is distributed in the hope that it will be useful, but
dnl WITHOUT ANY WARRANTY; without even the implied warranty of
dnl MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
dnl GNU General Public License for more details.
dnl
dnl You should have received a copy of the GNU General Public License
dnl along with Octave; see the file COPYING.  If not, see
dnl <https://www.gnu.org/licenses/>.
dnl
dnl --------------------------------------------------------------------
dnl
dnl Check for BLAS library and, if valid, determine integer size of library
dnl
AC_DEFUN([OCTAVE_BLAS], [
  AC_PREREQ(2.50)
  dnl Call reference macro to find BLAS library
  AX_BLAS

  if test "$cross_compiling" = yes ; then
    dnl Assume BLAS library exists when cross compiling
    ax_blas_ok=yes
    AC_MSG_CHECKING([BLAS can be called from Fortran])
    AC_MSG_RESULT([yes assumed for cross compilation])
    dnl Assume generic 4-byte BLAS library if not specified
    AC_MSG_CHECKING([BLAS library integer size])
    if test -z "$ax_cv_blas_integer_size" ; then
      ax_cv_blas_integer_size=4
    fi
    AC_MSG_RESULT([$ax_cv_blas_integer_size assumed for cross compilation])
  elif test $ax_blas_ok = yes; then
    ac_octave_save_LIBS="$LIBS"
    LIBS="$BLAS_LIBS $LIBS"
    AC_LANG_PUSH(Fortran 77)
    # Check if BLAS functions with single precision return value work
    # correctly
    AC_CACHE_CHECK([whether BLAS functions with single precision return value work correctly],
      [octave_cv_working_blas_single_precision],
      [AC_RUN_IFELSE([AC_LANG_PROGRAM(,[[
      implicit none
      real d
      real x(2), y(2)
      real sdot

      data x /1.0, 2.0/
      data y /3.0, 4.0/

      d = sdot (2, x, 1, y, 1)
*     print *, 'result: ', d

c Some implementations of BLAS (e.g., the one from Apple Accelerate)
c erroneously return a *double*-precision floating point value for functions
c that should be returning a single-precision floating point value.
c Check if the result for SDOT is correct if we (correctly) assume that it
c returns a single-precision floating point value.

      if (d .ne. 11.0) then
        stop 1
      endif

        ]])],
        octave_cv_working_blas_single_precision=yes,
        octave_cv_working_blas_single_precision=no)
      ])
    if test "$octave_cv_working_blas_single_precision" != yes; then
      AC_MSG_ERROR([The function SDOT does not work correctly with the selected BLAS library. Use a different implementation of BLAS.])
    fi

    ## Check BLAS library integer size.
    ## If it does not appear to be 8 bytes, we assume it is 4 bytes.
    ## FIXME: this may fail with options like -ftrapping-math.
    AC_CACHE_CHECK([BLAS library integer size],
      [ax_cv_blas_integer_size],
      [AC_RUN_IFELSE([AC_LANG_PROGRAM(,[[
      integer*8 two, n
      integer*4 n2(2)
      double precision d, a(1), b(1), ddot
      equivalence (n, n2)

      a(1) = 1.0
      b(1) = 1.0

c Generate 2**32 + 1 in an 8-byte integer.  Whether we have a big
c endian or little endian system, both 4-byte words of this value
c should be 1.

      two = 2
      n = (two ** 32) + 1

c Check that our expectation about the type conversions are correct.

      if (n2(1) .ne. 1 .or. n2(2) .ne. 1) then
        print *, 'invalid assumption about integer type conversion'
        stop 2
      endif

*     print *, n, n2(1), n2(2)
*     print *, a(1), b(1)

c DDOT will either see 1 or a large value for N.  Since INCX and INCY
c are both 0, we will never increment the index, so A and B only need to
c have a single element.  If N is interpreted as 1 (BLAS compiled with
c 4-byte integers) then the result will be 1.  If N is interpreted as a
c large value (BLAS compiled with 8-byte integers) then the result will
c be the summation a(1)*b(1) 2^32+1 times.  This will also take some
c time to compute, but at least for now it is the unusual case so we are
c much more likely to exit quickly after detecting that the BLAS library
c was compiled with 4-byte integers.

      d = ddot (n, a, 0, b, 0)

*     print *, a(1), b(1), d

c Success (0 exit status) means we detected BLAS compiled with
c 8-byte integers.

      if (d .eq. 1.0) then
        stop 1
      endif

        ]])],
        ax_cv_blas_integer_size=8,
        ax_cv_blas_integer_size=4)
      ])

  AC_LANG_POP(Fortran 77)
  LIBS="$ac_octave_save_LIBS"
fi

])