File: fortran_rsb_fi.F90

package info (click to toggle)
librsb 1.2.0-rc7-6
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 38,188 kB
  • sloc: ansic: 429,415; f90: 84,255; sh: 12,894; objc: 686; makefile: 686; awk: 18; sed: 1
file content (195 lines) | stat: -rw-r--r-- 7,854 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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
! 
! Copyright (C) 2008-2016 Michele Martone
! 
! This file is part of librsb.
! 
! librsb is free software; you can redistribute it and/or modify it
! under the terms of the GNU Lesser General Public License as published
! by the Free Software Foundation; either version 3 of the License, or
! (at your option) any later version.
! 
! librsb is distributed in the hope that it will be useful, but WITHOUT
! ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
! FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
! License for more details.
! 
! You should have received a copy of the GNU Lesser General Public
! License along with librsb; see the file COPYING.
! If not, see <http://www.gnu.org/licenses/>.
! 
      SUBROUTINE rsb_mod_example1(res)
      USE rsb
      USE ISO_C_BINDING
      IMPLICIT NONE
      INTEGER ::res
      INTEGER,TARGET :: istat = 0, i
      INTEGER :: transt = RSB_TRANSPOSITION_N ! Please note that this interface is unfinished
      INTEGER :: incx = 1, incy = 1
      REAL(KIND=8),TARGET :: alpha = 3, beta = 1
! 1 1
! 1 1
      ! declaration of VA,IA,JA 
      INTEGER :: nnz = 4
      INTEGER :: nr = 2
      INTEGER :: nc = 2
      INTEGER :: nrhs = 1
      INTEGER :: order = RSB_FLAG_WANT_COLUMN_MAJOR_ORDER ! rhs layout
      INTEGER :: flags = RSB_FLAG_NOFLAGS 
      INTEGER,TARGET :: IA(4) = (/0, 1, 1,0/)
      INTEGER,TARGET :: JA(4) = (/0, 0, 1,1/)
      REAL(KIND=8),TARGET :: VA(4) = (/1,1,1,1/)
      REAL(KIND=8),TARGET :: x(2) = (/1, 1/)! reference x 
      REAL(KIND=8),TARGET :: cy(2) = (/9, 9/)! reference cy after 
      REAL(KIND=8),TARGET :: y(2) = (/3, 3/)! y will be overwritten
      TYPE(C_PTR),TARGET :: mtxAp = C_NULL_PTR ! matrix pointer
      REAL(KIND=8) :: tmax = 2.0 ! tuning max time
      INTEGER :: titmax = 2 ! tuning max iterations
      INTEGER,TARGET :: ont = 0     ! optimal number of threads

      res = 0
      mtxAp = rsb_mtx_alloc_from_coo_const(C_LOC(VA),C_LOC(IA),C_LOC(JA)&
       &,nnz,&
       & RSB_NUMERICAL_TYPE_DOUBLE,nr,nc,1,1,flags,C_LOC(istat))

      IF (istat.NE.RSB_ERR_NO_ERROR) GOTO 9997

      istat = rsb_file_mtx_save(mtxAp,C_NULL_PTR)

      ! Structure autotuning:
      istat = rsb_tune_spmm(C_LOC(mtxAp),C_NULL_PTR,C_NULL_PTR,titmax,&
       & tmax,&
       & transt,C_LOC(alpha),C_NULL_PTR,nrhs,order,C_LOC(x),nr,&
       & C_LOC(beta),C_LOC(y),nc)

      IF (istat.NE.RSB_ERR_NO_ERROR) GOTO 9997

      ! Thread count autotuning:
      istat = rsb_tune_spmm(C_NULL_PTR,C_NULL_PTR,C_LOC(ont),titmax,&
       & tmax,&
       & transt,C_LOC(alpha),mtxAp,nrhs,order,C_LOC(x),nr,C_LOC(beta),&
       & C_LOC(y),nc)
      PRINT *, "Optimal number of threads:", ont

      y(:) = (/3, 3/)! reference y 
      IF (istat.NE.RSB_ERR_NO_ERROR) GOTO 9997
      
      istat = rsb_file_mtx_save(mtxAp,C_NULL_PTR)
      IF (istat.NE.RSB_ERR_NO_ERROR) GOTO 9997

      istat = rsb_spmv(transt,C_LOC(alpha),mtxAp,C_LOC(x),incx,&
       & C_LOC(beta),C_LOC(y),incy)
      IF (istat.NE.RSB_ERR_NO_ERROR) GOTO 9997
      DO i = 1, 2
            IF (y(i).NE.cy(i)) PRINT *, "type=d dims=2x2 sym=g diag=g &
      &blocks=1x1 usmv alpha= 3 beta= 1 incx=1 incy=1 trans=n is not ok"
            IF (y(i).NE.cy(i)) GOTO 9997
      END DO
      PRINT*,"type=d dims=2x2 sym=g diag=g blocks=1x1 usmv alpha= 3&
       & beta= 1 incx=1 incy=1 trans=n is ok"
      GOTO 9998
9997      res = -1
9998      CONTINUE
      mtxAp = rsb_mtx_free(mtxAp)
      IF (istat.NE.RSB_ERR_NO_ERROR) res = -1 
! 9999      CONTINUE
      istat = rsb_perror(C_NULL_PTR,istat)
      end SUBROUTINE rsb_mod_example1

      SUBROUTINE rsb_mod_example2(res)
      USE rsb
      USE ISO_C_BINDING
      IMPLICIT NONE
      INTEGER,TARGET :: errval
      INTEGER :: res
      INTEGER :: transt = RSB_TRANSPOSITION_N  ! no transposition
      INTEGER :: incX = 1, incB = 1        ! X, B vectors increment
      REAL(KIND=8),TARGET :: alpha = 3,beta = 1
      INTEGER :: nnzA = 4, nrA = 3, ncA = 3     ! nonzeroes, rows, columns of matrix A
      INTEGER,TARGET :: IA(4) = (/1, 2, 3, 3/)  ! row    indices
      INTEGER,TARGET :: JA(4) = (/1, 2, 1, 3/)  ! column indices
      INTEGER(C_SIGNED_CHAR) :: typecode = RSB_NUMERICAL_TYPE_DOUBLE
      INTEGER :: flags =RSB_FLAG_DEFAULT_MATRIX_FLAGS+RSB_FLAG_SYMMETRIC
      REAL(KIND=8),TARGET :: VA(4) = (/11.0, 22.0, 13.0, 33.0/) ! coefficients
      REAL(KIND=8),TARGET :: X(3) = (/   0,    0,    0/)
      REAL(KIND=8),TARGET :: B(3) = (/-1.0, -2.0, -2.0/)
      TYPE(C_PTR),TARGET  :: mtxAp = C_NULL_PTR
      TYPE(C_PTR)  :: mtxApp = C_NULL_PTR
      REAL(KIND=8),TARGET :: ETIME = 0.0
      !TYPE(C_PTR),PARAMETER :: EO = RSB_NULL_EXIT_OPTIONS
      !TYPE(C_PTR),PARAMETER :: IO = RSB_NULL_INIT_OPTIONS
      ! Note: using C_NULL_PTR instead of the previous lines because of http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59411
      TYPE(C_PTR),PARAMETER :: EO = C_NULL_PTR
      TYPE(C_PTR),PARAMETER :: IO = C_NULL_PTR

      errval = rsb_lib_init(IO)                ! librsb initialization
      IF (errval.NE.RSB_ERR_NO_ERROR) &
       & STOP "error calling rsb_lib_init"
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 5)
#define RSB_SKIP_BECAUSE_OLD_COMPILER 1
#endif
#ifndef RSB_SKIP_BECAUSE_OLD_COMPILER
      mtxAp = rsb_mtx_alloc_from_coo_begin(nnzA,typecode,nrA,ncA,flags,&
       & C_LOC(errval)) ! begin matrix creation
      errval = rsb_mtx_set_vals(mtxAp,&
       & C_LOC(VA),C_LOC(IA),C_LOC(JA),nnzA,flags) ! insert some nonzeroes
      mtxApp = C_LOC(mtxAp) ! Old compilers like e.g.: Gfortran 4.4.7 will NOT compile this.
      IF (errval.NE.RSB_ERR_NO_ERROR) &
       & STOP "error calling rsb_mtx_set_vals"
      errval = rsb_mtx_alloc_from_coo_end(mtxApp)                   ! end matrix creation
      IF (errval.NE.RSB_ERR_NO_ERROR) &
       & STOP "error calling rsb_mtx_alloc_from_coo_end"
      errval = rsb_spmv(transt,C_LOC(alpha),mtxAp,C_LOC(X),&
       & incX,C_LOC(beta),C_LOC(B),incB) ! X := X + (3) * A * B 
      IF (errval.NE.RSB_ERR_NO_ERROR)&
       & STOP "error calling rsb_spmv"
      mtxAp = rsb_mtx_free(mtxAp)                                 ! destroy matrix

      ! The following is optional and depends on configure options, so it is allowed to fail
      errval = rsb_lib_get_opt(RSB_IO_WANT_LIBRSB_ETIME,C_LOC(ETIME))
      IF (errval.EQ.RSB_ERR_NO_ERROR)&
       & PRINT*,"Time spent in librsb is:",ETIME
      ! IF (errval.NE.0)STOP "error calling rsb_lib_get_opt" 
      errval = RSB_ERR_NO_ERROR

      IF (errval.NE.RSB_ERR_NO_ERROR) &
       & STOP "error calling rsb_mtx_free"
#else
      PRINT*,"You have an old Fortran compiler not supporting C_LOC."
      PRINT*,"Skipping a part of the test"
#endif
      errval=rsb_lib_exit(EO)                 ! librsb finalization
      IF (errval.NE.RSB_ERR_NO_ERROR)&
       & STOP "error calling rsb_lib_exit"
      PRINT *, "rsb module fortran test is ok"
      res = errval
      end SUBROUTINE rsb_mod_example2

      PROGRAM main
      USE rsb
      IMPLICIT NONE
      INTEGER :: res = RSB_ERR_NO_ERROR, passed = 0, failed = 0
      !TYPE(C_PTR),PARAMETER :: EO = RSB_NULL_EXIT_OPTIONS
      !TYPE(C_PTR),PARAMETER :: IO = RSB_NULL_INIT_OPTIONS
      ! Note: using C_NULL_PTR instead of the previous lines because of http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59411
      TYPE(C_PTR),PARAMETER :: EO = C_NULL_PTR
      TYPE(C_PTR),PARAMETER :: IO = C_NULL_PTR

      res = rsb_lib_init(IO)
      
      CALL rsb_mod_example1(res)
      IF (res.LT.0) failed = failed + 1
      IF (res.EQ.0) passed = passed + 1

      res = rsb_lib_exit(EO)

      CALL rsb_mod_example2(res)
      IF (res.LT.0) failed = failed + 1
      IF (res.EQ.0) passed = passed + 1
      
      PRINT *, "FAILED:", failed
      PRINT *, "PASSED:", passed
      IF (failed.GT.0) THEN
       STOP 1
      END IF
      END PROGRAM