Advertisement
Guest User

Untitled

a guest
Nov 19th, 2019
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.47 KB | None | 0 0
  1. assign6-grade -- e. torres davila
  2.  
  3. comments:
  4. o the program compiles using the supplied makefile,
  5. and runs
  6.  
  7. o but the makefile is not commented, is supposed to
  8. be commented
  9.  
  10. o code for assessing danger of division by zero is
  11. addressed in a coherent manner; avoids floating
  12. point overflows
  13.  
  14. o the program seems to produce results that are
  15. consistent w/ those produced by the c-lang
  16. templates for this benchmark
  17.  
  18. o presents a clear, coherent user interface
  19.  
  20. o good, tight coding logic, good commenting, sharp
  21. looking source code.
  22.  
  23. grade: 97/100
  24.  
  25.  
  26. ! matvec.F90 -- Eduardo Torres Davila, 11/05/19
  27. ! Description -- Perform matrix-vector muliplication y = Ax, for a
  28. ! n x n matrix A, represented in double precision. We will prompt the
  29. ! user to provide n. We will then perform the matrix-vector product 3 ways:
  30. ! programmed row-based, programmed column-based, and by way of an external
  31. ! library call dgemv(). When calling each one we will use fortran built
  32. ! in timing function cpu_time() to get the run time of each
  33. ! matrix-vector product. We will then provide the timings for each and
  34. ! giving the ratio between row-based/column-based and ratio for
  35. ! column-based/dgemv(). We finally find the infinity norm of yB - yR and
  36. ! yB - yC to check that the results are accurate.
  37.  
  38. program matvec
  39. ! Don't allow implicit type assignment for our variables
  40. implicit none
  41.  
  42. ! Declaring variables
  43. double precision, allocatable :: A(:,:), x(:), errvect(:)
  44. double precision, allocatable :: yC(:), yR(:), yB(:)
  45. double precision :: rowerr, colerr, infnorm
  46. integer :: n
  47. integer :: ii, istatus
  48. real :: start, finish
  49. real :: t_R, t_C, t_B
  50.  
  51. ! Prompt the user to give the dimensions of matrix A
  52. print '("Please provide n which is the size of matrix A.")'
  53. print '("A = n x n matrix.")'
  54. read (*,*) n
  55.  
  56. print *, " "
  57.  
  58. ! Allocate memory for matrix A
  59. allocate(A(n,n),STAT=istatus)
  60. if (istatus .NE. 0) then
  61. print *, "failed to allocate storage for matrix A. exiting."
  62. stop
  63. end if
  64.  
  65. ! Allocate memory for vector x
  66. allocate(x(n),STAT=istatus)
  67. if (istatus .NE. 0) then
  68. print *, "failed to allocate storage for vector x. exiting."
  69. stop
  70. end if
  71.  
  72. ! Allocate memory for vector yR
  73. allocate(yR(n),STAT=istatus)
  74. if (istatus .NE. 0) then
  75. print *, "failed to allocate storage for vector y. exiting."
  76. stop
  77. end if
  78.  
  79. ! Allocate memory for vector yC
  80. allocate(yC(n),STAT=istatus)
  81. if (istatus .NE. 0) then
  82. print *, "failed to allocate storage for vector y. exiting."
  83. stop
  84. end if
  85.  
  86. ! Allocate memory for vector yB
  87. allocate(yB(n),STAT=istatus)
  88. if (istatus .NE. 0) then
  89. print *, "failed to allocate storage for vector y. exiting."
  90. stop
  91. end if
  92.  
  93. ! Allocate memory for error vector errvect
  94. allocate(errvect(n),STAT=istatus)
  95. if (istatus .NE. 0) then
  96. print *, "failed to allocate storage for errvect. exiting."
  97. stop
  98. end if
  99.  
  100. ! Load vector x and A with values
  101. call loadvalues(n, x, A)
  102.  
  103. ! Calculate vector y = Ax doing it Row based and timing the computation
  104. call cpu_time(start)
  105. call matvecR(n, A, x, yR)
  106. call cpu_time(finish)
  107.  
  108. ! Print the duration of the computation and display time to STDOUT
  109. t_R = finish - start
  110. print '("Time for (row-oriented) matvecR() = ",f10.6,"&
  111. & seconds.")', t_R
  112.  
  113. ! Calculate vector y = Ax doing it Column based and timing the operation
  114. call cpu_time(start)
  115. call matvecC(n, A, x, yC)
  116. call cpu_time(finish)
  117.  
  118. ! Print the duration of the computation and display time to STDOUT
  119. t_C = finish - start
  120. print '("Time for (column-oriented) matvecC() = ",f10.6,"&
  121. & seconds.")', t_C
  122.  
  123. ! Usage of dgemv() --
  124. ! first entry - 'n' means y = \a A x + \b y
  125. ! second and third - number of rows and num of cols
  126. ! 4th entry - the scalar \a
  127. ! 5th entry - the matrix A
  128. ! 6th entry - first dimension of A
  129. ! 7th entry - our x vector - x
  130. ! 8th entry - our x increment - 1
  131. ! 9th entry - the scalar \b
  132. ! 10th entry - our y vector - yB
  133. ! 11th entry - our y increment - 1
  134. call cpu_time(start)
  135. call dgemv('N', n, n, 1.0d+0, A, n, x, 1, 0.0d+0, yB, 1)
  136. call cpu_time(finish)
  137.  
  138. ! Print the duration of the computation and display time to STDOUT
  139. t_B = finish - start
  140. print '("Time for dgemv() = ",f10.6," seconds.")', t_B
  141.  
  142. print *, " "
  143.  
  144. ! Before computing ratio we make sure we are not dividing by zero
  145. if ( abs(t_C) .LT. 0.000001 ) then
  146. print '("WARNING: looks like we have a zero timing result&
  147. & for col-oriented computation,")'
  148. print '("WARNING: maybe the problem size is too&
  149. & fine-grained...")'
  150. else
  151. print '("Ratio of R timing...")'
  152. print '("row oriented / col oriented = ",f10.7,".")', t_R/t_C
  153. end if
  154.  
  155. print *, " "
  156.  
  157. ! Before computing ratio we make sure we are not dividing by zero
  158. if ( abs(t_B) .LT. 0.000001 ) then
  159. print '("WARNING: looks like we have a zero timing result&
  160. & for dgemv() computation,")'
  161. print '("WARNING: maybe the problem size is too &
  162. &fine-grained...")'
  163. else
  164. print '("Ratio of C timing...")'
  165. print '("col oriented / call dgemv() = ",f10.7,".")', t_C/t_B
  166. end if
  167.  
  168. print *, " "
  169.  
  170. ! Generate error vector for row-based vector and check infinity norm for
  171. ! correctness of the computation.
  172. errvect = yB - yR
  173. rowerr = infnorm(n, errvect)
  174. print '("Norm of row-based matvec error = ",f6.4,".")', rowerr
  175.  
  176. ! Generate error vector for column-based vector and check infinity norm
  177. ! for correctness of the computation.
  178. errvect = yB - yC
  179. colerr = infnorm(n, errvect)
  180. print '("Norm of column-based matvec error = ",f6.4,".")',&
  181. &colerr
  182.  
  183. ! deallocate all memory for matrices/vectors created
  184. deallocate(A)
  185. deallocate(x)
  186. deallocate(yR)
  187. deallocate(yC)
  188. deallocate(yB)
  189. deallocate(errvect)
  190. end program matvec
  191.  
  192. ! loadvalues() -- this routine loads a vector and matrix of dimensions
  193. ! n with specific values.
  194. !
  195. ! param list:
  196. ! n -- integer value -- input value, the number of array elements
  197. ! x -- empty array of size n with double precision elements
  198. ! output value
  199. ! A -- empty 2 dimensional array with double precision elements
  200. ! which is our n x n matrix -- output value
  201.  
  202. subroutine loadvalues(n, x, A)
  203. ! Don't allow implicit type assignment for our variables
  204. implicit none
  205.  
  206. integer, intent(in) :: n
  207. integer :: ii, jj
  208. double precision, dimension(n,n), intent(out) :: A
  209. double precision, dimension(n), intent(out) :: x
  210.  
  211. do ii=1, n
  212. x(ii) = 1.0
  213. do jj=1, n
  214. A(ii,jj) = (ii+1)*(jj+1)/(float(n))
  215. end do
  216. end do
  217.  
  218. end subroutine loadvalues
  219.  
  220. ! matvecR() -- row-oriented matrix-vector multiplication routine.
  221. !
  222. ! param list:
  223. ! n -- integer value -- input value, the number of array elements
  224. ! A -- 2 dimensional array filled with double precision elements
  225. ! which is our n x n matrix -- input value
  226. ! x -- array with n double precision values -- input value
  227. ! y -- array with n double precision values -- output value
  228.  
  229. subroutine matvecR(n, A, x, y)
  230. ! Don't allow implicit type assignment for our variables
  231. implicit none
  232.  
  233. integer, intent(in) :: n
  234. integer :: ii, jj
  235. double precision, intent(in) :: A(n,n), x(n)
  236. double precision, intent(out) :: y(n)
  237.  
  238. do ii=1, n
  239. y(ii) = a(ii,1) * x(1)
  240. do jj=2, n
  241. y(ii) = y(ii) + a(ii,jj) * x(jj)
  242. end do
  243. end do
  244.  
  245. end subroutine matvecR
  246.  
  247. ! matvecC() -- column-oriented matrix-vector multiplication routine.
  248. !
  249. ! param list:
  250. ! n -- integer value -- input value, the number of array elements
  251. ! A -- 2 dimensional array filled with double precision elements
  252. ! which is our n x n matrix -- input value
  253. ! x -- array with n double precision values -- input value
  254. ! y -- array with n double precision values -- output value
  255.  
  256. subroutine matvecC(n, A, x, y)
  257. ! Don't allow implicit type assignment for our variables
  258. implicit none
  259.  
  260. integer, intent(in) :: n
  261. integer :: ii, jj
  262. double precision, intent(in) :: A(n,n), x(n)
  263. double precision, intent(out) :: y(n)
  264.  
  265. do ii=1, n
  266. y(ii) = a(ii,1) * x(1)
  267. end do
  268.  
  269. do jj=2, n
  270. do ii=1, n
  271. y(ii) = y(ii) + a(ii,jj) * x(jj)
  272. end do
  273. end do
  274.  
  275. end subroutine matvecC
  276.  
  277. ! function body for infnorm which is used to find the maximal value of
  278. ! the absolute value of the array xx.
  279. !
  280. ! param list:
  281. ! n -- integer value -- input value, the length of the array xx
  282. ! xx -- array with n double precision values -- input value
  283. ! return value:
  284. ! infnorm -- double precision -- return the absolute value of
  285. ! the maximal double precision value in array xx
  286.  
  287. double precision function infnorm( n, xx )
  288. ! Don't allow implicit type assignment for our variables
  289. implicit none
  290.  
  291. integer, intent(in) :: n
  292. double precision, intent(in) :: xx(n)
  293.  
  294. infnorm = maxval(dabs(xx))
  295. end function
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement