{"id":64538,"date":"2013-04-02T15:57:34","date_gmt":"2013-04-02T19:57:34","guid":{"rendered":"http:\/\/www.bu.edu\/tech\/?page_id=64538"},"modified":"2014-05-15T16:35:42","modified_gmt":"2014-05-15T20:35:42","slug":"matrix-multiply-fortran","status":"publish","type":"page","link":"https:\/\/www.bu.edu\/tech\/support\/research\/software-and-programming\/gpu-computing\/openacc-fortran\/matrix-multiply-fortran\/","title":{"rendered":"Matrix Multiply Fortran Code"},"content":{"rendered":"<pre class=\"code-block\"><code>program matrix_multiply\r\n   use omp_lib\r\n   use openacc\r\n   implicit none\r\n   integer :: i, j, k, myid, m, n, compiled_for, option\r\n   integer, parameter :: fd = 11\r\n   integer :: t1, t2, dt, count_rate, count_max\r\n   real, allocatable, dimension(:,:) :: a, b, c\r\n   real :: tmp, secs\r\n\r\n   open(fd,file='wallclocktime',form='formatted')\r\n\r\n   option = compiled_for(fd) ! 1-serial, 2-OpenMP, 3-OpenACC, 4-both\r\n\r\n!$omp parallel\r\n!$    myid = OMP_GET_THREAD_NUM()\r\n!$    if (myid .eq. 0) then\r\n!$      write(fd,\"('Number of procs is ',i4)\") OMP_GET_NUM_THREADS()\r\n!$    endif\r\n!$omp end parallel\r\n\r\n   call system_clock(count_max=count_max, count_rate=count_rate)\r\n\r\n   do m=1,4    <span class=\"comment\">! compute for different size matrix multiplies<\/span>\r\n\r\n      call system_clock(t1)\r\n\r\n      n = 1000*2**(m-1)    <span class=\"comment\">! 1000, 2000, 4000, 8000<\/span>\r\n      allocate( a(n,n), b(n,n), c(n,n) )\r\n\r\n<span class=\"comment\">! Initialize matrices<\/span>\r\n      do j=1,n\r\n         do i=1,n\r\n            a(i,j) = real(i + j)\r\n            b(i,j) = real(i - j)\r\n         enddo\r\n      enddo\r\n\r\n!$omp parallel do shared(a,b,c,n,tmp) reduction(+: tmp)\r\n!$acc data copyin(a,b) copy(c)\r\n!$acc kernels\r\n<span class=\"comment\">! Compute matrix multiplication.<\/span>\r\n      do j=1,n\r\n         do i=1,n\r\n            tmp = 0.0  <span class=\"comment\">! enables ACC parallelism for k-loop<\/span>\r\n            do k=1,n\r\n               tmp = tmp + a(i,k) * b(k,j)\r\n            enddo\r\n            c(i,j) = tmp\r\n         enddo\r\n      enddo\r\n!$acc end kernels\r\n!$acc end data\r\n!$omp end parallel do\r\n\r\n      call system_clock(t2)\r\n      dt = t2-t1\r\n      secs = real(dt)\/real(count_rate)\r\n      write(fd,\"('For n=',i4,', wall clock time is ',f12.2,' seconds')\") &amp;\r\n              n, secs\r\n\r\n      deallocate(a, b, c)\r\n\r\n   enddo\r\n\r\n  close(fd)\r\nend program matrix_multiply\r\n\r\ninteger function compiled_for(fd)\r\nimplicit none\r\ninteger :: fd\r\n#if defined _OPENMP &amp;&amp; defined _OPENACC\r\n  compiled_for = 4\r\n  write(fd,\"('This code is compiled with OpenMP &amp; OpenACC')\")\r\n#elif defined _OPENACC\r\n  compiled_for = 3\r\n  write(fd,\"('This code is compiled with OpenACC')\")\r\n#elif defined _OPENMP\r\n  compiled_for = 2\r\n  write(fd,\"('This code is compiled with OpenMP')\")\r\n#else\r\n  compiled_for = 1\r\n  write(fd,\"('This code is compiled for serial operations')\")\r\n#endif\r\n\r\nend function compiled_for\r\n<\/code><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>program matrix_multiply use omp_lib use openacc implicit none integer :: i, j, k, myid, m, n, compiled_for, option integer, parameter :: fd = 11 integer :: t1, t2, dt, count_rate, count_max real, allocatable, dimension(:,:) :: a, b, c real :: tmp, secs open(fd,file=&#8217;wallclocktime&#8217;,form=&#8217;formatted&#8217;) option = compiled_for(fd) ! 1-serial, 2-OpenMP, 3-OpenACC, 4-both !$omp parallel !$ myid&#8230;<\/p>\n","protected":false},"author":1692,"featured_media":0,"parent":64342,"menu_order":1,"comment_status":"closed","ping_status":"closed","template":"","meta":[],"_links":{"self":[{"href":"https:\/\/www.bu.edu\/tech\/wp-json\/wp\/v2\/pages\/64538"}],"collection":[{"href":"https:\/\/www.bu.edu\/tech\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/www.bu.edu\/tech\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/www.bu.edu\/tech\/wp-json\/wp\/v2\/users\/1692"}],"replies":[{"embeddable":true,"href":"https:\/\/www.bu.edu\/tech\/wp-json\/wp\/v2\/comments?post=64538"}],"version-history":[{"count":5,"href":"https:\/\/www.bu.edu\/tech\/wp-json\/wp\/v2\/pages\/64538\/revisions"}],"predecessor-version":[{"id":79192,"href":"https:\/\/www.bu.edu\/tech\/wp-json\/wp\/v2\/pages\/64538\/revisions\/79192"}],"up":[{"embeddable":true,"href":"https:\/\/www.bu.edu\/tech\/wp-json\/wp\/v2\/pages\/64342"}],"wp:attachment":[{"href":"https:\/\/www.bu.edu\/tech\/wp-json\/wp\/v2\/media?parent=64538"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}