- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
[fortran]forall(M=1:MMAX,N=1:NMAX,Q=1:QMAX) C(M,N,Q) = dot_product(A(M,N,:),B(:,Q))[/fortran]but this is far from being optimal. The faster approach includes Level-3 BLAS routimes call
[fortran]call dgemm('n','n',MMAX*NMAX,QMAX,KMAX,1.d0,A,MMAX*NMAX,B,KMAX,&
0.d0,C,MMAX*NMAX)[/fortran]
but since dgemm is subroutine and since it is not PURE, the resulting function also can not be declared as PURE.
We can rely on MATMUL intrinsic function, that is PURE, but it supposes rank-two arrays on input. We can perform like that
[fortran]double precision,allocatable :: atmp(:,:)
allocate(atmp(MMAX*NMAX,KMAX))
forall(M=1:MMAX,N=1:NMAX,K=1:KMAX)atmp(M+(N-1)*MMAX,K)=A(M,N,K)
C=MATMUL(atmp,B)
deallocate(atmp)[/fortran]
but there we need additional array for reshaping of array A.
We can try also the following simple statement
[fortran]C=MATMUL(RESHAPE(A,[MMAX*NMAX,KMAX]),B)[/fortran]
This looks fine, but I am not sure that compiler can do this without implicit allocation of temporary reshaped array on stack or heap. This could greatly decrease the performance in my programs, since I plan to use such procedure in recursive functions.
Could you give a comment on this? Shortly speaking, I need an inplace RESHAPE for arrays or PURE DGEMM-like function with explicitely given array dimensions. Is it possible to solve this problem or to find some simple walkaround?
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thank you, Tim.
But let me clarify. My problem is that I want to have PURE function with matrix multiplication inside. My "matrices" are actually large rank-3 arrays.
I can use DGEMM, but then I lose PURE property.
I can use RESHAPE+MATMUL, but then I probably can not avoid temporary allocation of memory.
Is it possible to combine one with another?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi drraug,
Here's is one way to reshape in place using a pointer (you can build from this example, i.e. bounds checking, etc):
[fortran]program main real, pointer :: v1(:,:,:), v2(:,:,:) real, pointer :: v3(:,:), v4(:,:) allocate(v1(10, 10, 4)) v2 => v1 v2(2,2,2) = 5.d0 call cast2D(v2, v3, 20, 20) v3(10,1) = 10. v3(1,2) = 21. print *, v3(10,1), v1(10,1,1) print *, v3(1,2),v1(1,3,1) contains subroutine cast2D(v1, v3, n, m) real, dimension(n,m), target :: v1 real, dimension(:,:), pointer :: v3 integer :: n, m v3 => v1 end subroutine cast2D end program main [/fortran]

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page