Dear Tim and Viral (and others),
The allocation check just showed that memory is being allocated all over
the place (seemingly for no reason?), so I went ahead and simplified the
function a bit to supply it with some random data. This is printed below.
It turns out that if I pass standard arrays instead of custom types, then
there is no problem at all; I get the performance I expect.
Without custom types:
elapsed time: 0.01496518 seconds (13888 bytes allocated)
With custom types:
elapsed time: 1.178802132 seconds (320878944 bytes allocated, 11.28% gc
time)
I then tried to use the @code_warntype / @code_typewarn macro to see if
this would detect something, but it seems this macro does not exist in my
Julia installation? Does this only come with 0.4?
As an aside: for the fast version, @time claims only 13888 bytes have been
allocated, but track-allocation claims that one particular line allocated
2480888 bytes???
The .mem output is printed below. I will post a clean version in a separate
post. I can work around this issue for now, but is it possible this is a
bug? Or am I missing something else here? Many thanks for your help so far,
Christoph
- type SiteLinear
- stencil::Array{Int, 1}
- coeffs::Array{Float64, 3}
- end
-
-
- function evalSiteFunction_without_type!(coeffs::Array{Float64, 3},
- stencil::Array{Int, 1},
- J::Array{Int, 1},
- Y::Array{Float64,2},
- Frc::Array{Float64,2})
- # extract dimension information (d1, d2 \in \{2, 3\})
2480888 d1, d2, nneig = size(coeffs)
- # allocate some variables
0 kX = 0::Int; jX = 0::Int; n = 0::Int
- # loop over sites
0 for jX in J # length(J) = 11268
- # initialise force to 0
0 Frc[:,jX] = 0.0
- # loop over neighbouring sites
0 for n in 1:nneig # nneig = 37
- # get the X-index of the current neighbour (highly
simplified)
0 kX = jX + stencil[n]
- # evaluate the term (devectorized and unrolled for
performance)
- # f[:] += slice(sp.coeffs, :, :, n) * Y[:, kX]
0 for i = 1:d1, j = 1:d2
0 Frc[i,jX] += coeffs[i,j,n]*Y[j,kX]
- end
- end
- end
- end
-
-
-
- function evalSiteFunction!(sp::SiteLinear,
- J::Array{Int, 1},
- Y::Array{Float64,2},
- Frc::Array{Float64,2})
- # extract dimension information (d1, d2 \in \{2, 3\})
15841976 d1, d2, nneig = size(coeffs)
- # allocate some variables
0 kX = 0::Int; jX = 0::Int; n = 0::Int
- # loop over sites
2492256 for jX in J # length(J) = 11268
- # initialise force to 0
0 Frc[:,jX] = 0.0
- # loop over neighbouring sites
116952768 for n in 1:nneig # nneig = 37
- # get the X-index of the current neighbour (highly
simplified)
25515200 kX = jX + sp.stencil[n]
- # evaluate the term (devectorized and unrolled for
performance)
- # f[:] += slice(sp.coeffs, :, :, n) * Y[:, kX]
496803016 for i = 1:d1, j = 1:d2
224 Frc[i,jX] += sp.coeffs[i,j,n]*Y[j,kX]
- end
- end
- end
- end
-
-
- # problem size
- nneigs = 18
- nsites = 11268
- dim = 2
-
- # data to be passed to function (simplified)
- coeffs = rand(dim,dim,2*nneigs+1)
- stencil = int(linspace(-nneigs, nneigs, 2*nneigs+1))
- Y = rand(2, nsites + 2*nneigs)
- Frc = zeros(2, nsites + 2*nneigs)
- J = int(linspace(nneigs+1, nsites+nneigs, nsites))
-
-
- evalSiteFunction_without_type!(coeffs, stencil, J, Y, Frc)
- @time evalSiteFunction_without_type!(coeffs, stencil, J, Y, Frc)
-
-
- # now try same with types
- sp = SiteLinear(stencil, coeffs)
- evalSiteFunction!(sp, J, Y, Frc)
- @time evalSiteFunction!(sp, J, Y, Frc)