The problem is to write code that will allow to use the same name of variable that can refer array or function basing on conditions.
In more details: I have real*8 function that takes 4 integer indices. Calculation of such function is quite expensive. The values that return this function are used many millions times. The most obvious solution - to calculate them once and use 4-dimension array instead of function. It saves huge amount of time.
But when the size of the task increases, there is no possibility to store such array in memory. So to be hardware-independent, it is required to turn off storing in the memory and use function instead.
The only one solution that came to me is to use abstract interface with "virtual function" that do nothing but return the values of array by four indices.
First of all, It is necessary to define abstract interface:
abstract interface
real(kind=rglu) function integral(a,b,c,d)
use glob, only: iglu,rglu
integer(kind=iglu), intent(in) :: a,b,c,d
end function integral
end interface
procedure (integral), pointer :: R=>null()
next, write the function:
real(kind=rglu) function stored_int(a,b,c,d) result(ret)
implicit none
integer(kind=iglu), intent(in) :: a,b,c,d
ret=hR(a,b,c,d); return
end function stored_int
and then we will use it in the following way:
if (storeIntegrals) then
do i = 1,N
do j = 1,N
do a = 1,N
do b = 1,N
hR(i,j,a,b)=my_integral(i,j,a,b)
enddo
enddo
enddo
enddo
R=>stored_int
else
R=>my_integral
endif
Function my_integral is that we need to replace with an array.
Such approach unfortunately shows very bad performance.
Compiled with ifort -O3 -fpp -openmp
on four cores it gives twice worse result then the same code but with an array (without virtual function).
Are any other variants to solve this problem?
returninto every function in Fortran.returnand if it does not affect performance I will continue writing it.