Julia v0.5 has some serious issues regarding memory allocation. In an attempt to optimize my package I realized many inconsistencies:
- ## Copyright (c) 2015, Júlio Hoffimann Mendes <juliohm@stanford.edu>
- ##
- ## Permission to use, copy, modify, and/or distribute this software for any
- ## purpose with or without fee is hereby granted, provided that the above
- ## copyright notice and this permission notice appear in all copies.
- ##
- ## THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- ## WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- ## MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- ## ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- ## WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- ## ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- ## OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
-
- function boykov_kolmogorov_cut(A::AbstractArray, B::AbstractArray, dir::Symbol)
- # permute dimensions so that the algorithm is
- # the same for cuts in x, y and z directions
- if dir == :x
149056 A = permutedims(A, [1,2,3])
149120 B = permutedims(B, [1,2,3])
0 elseif dir == :y
140160 A = permutedims(A, [2,1,3])
140160 B = permutedims(B, [2,1,3])
0 elseif dir == :z
0 A = permutedims(A, [3,2,1])
0 B = permutedims(B, [3,2,1])
- end
-
453760 E = abs(A - B)
-
0 mx, my, mz = size(E)
0 nvox = mx*my*mz
-
- # compute gradients
679680 ∇xₐ = similar(E); ∇yₐ = similar(E); ∇zₐ = similar(E)
679680 ∇xᵦ = similar(E); ∇yᵦ = similar(E); ∇zᵦ = similar(E)
0 for i=1:mx-1, j=1:my, k=1:mz
793600 ∇xₐ[i,j,k] = A[i+1,j,k] - A[i,j,k]
793600 ∇xᵦ[i,j,k] = B[i+1,j,k] - B[i,j,k]
- end
0 for i=1:mx, j=1:my-1, k=1:mz
858880 ∇yₐ[i,j,k] = A[i,j+1,k] - A[i,j,k]
858880 ∇yᵦ[i,j,k] = B[i,j+1,k] - B[i,j,k]
- end
0 for i=1:mx, j=1:my, k=1:mz-1
0 ∇zₐ[i,j,k] = A[i,j,k+1] - A[i,j,k]
0 ∇zᵦ[i,j,k] = B[i,j,k+1] - B[i,j,k]
- end
0 if mx > 1
24320 ∇xₐ[mx,:,:] = ∇xₐ[mx-1,:,:]
24320 ∇xᵦ[mx,:,:] = ∇xᵦ[mx-1,:,:]
- end
0 if my > 1
8320 ∇yₐ[:,my,:] = ∇yₐ[:,my-1,:]
8320 ∇yᵦ[:,my,:] = ∇yᵦ[:,my-1,:]
- end
0 if mz > 1
0 ∇zₐ[:,:,mz] = ∇zₐ[:,:,mz-1]
0 ∇zᵦ[:,:,mz] = ∇zᵦ[:,:,mz-1]
- end
0 map!(abs, ∇xₐ); map!(abs, ∇yₐ); map!(abs, ∇zₐ)
0 map!(abs, ∇xᵦ); map!(abs, ∇yᵦ); map!(abs, ∇zᵦ)
-
- # add source and sink terminals
0 s = nvox + 1; t = nvox + 2
-
- # construct graph and capacity matrix
0 G = DiGraph(nvox+2)
282880 C = spzeros(nvox+2, nvox+2)
0 for k=1:mz, j=1:my, i=1:mx-1
0 c = sub2ind((mx,my,mz), i, j, k)
0 d = sub2ind((mx,my,mz), i+1, j, k)
0 add_edge!(G, c, d)
0 add_edge!(G, d, c)
2558592 C[c,d] = C[d,c] = (E[c] + E[d]) / (∇xₐ[c] + ∇xₐ[d] + ∇xᵦ[c] + ∇xᵦ[d])
- end
0 for k=1:mz, j=1:my-1, i=1:mx
0 c = sub2ind((mx,my,mz), i, j, k)
0 r = sub2ind((mx,my,mz), i, j+1, k)
0 add_edge!(G, c, r)
0 add_edge!(G, r, c)
2725248 C[c,r] = C[r,c] = (E[c] + E[r]) / (∇yₐ[c] + ∇yₐ[r] + ∇yᵦ[c] + ∇yᵦ[r])
- end
0 for k=1:mz-1, j=1:my, i=1:mx
0 c = sub2ind((mx,my,mz), i, j, k)
0 o = sub2ind((mx,my,mz), i, j, k+1)
0 add_edge!(G, c, o)
0 add_edge!(G, o, c)
0 C[c,o] = C[o,c] = (E[c] + E[o]) / (∇zₐ[c] + ∇zₐ[o] + ∇zᵦ[c] + ∇zᵦ[o])
- end
0 for k=1:mz, j=1:my
0 u = sub2ind((mx,my,mz), 1, j, k)
0 v = sub2ind((mx,my,mz), mx, j, k)
0 add_edge!(G, s, u)
0 add_edge!(G, v, t)
0 C[s,u] = C[v,t] = Inf
- end
-
- # Boykov-Kolmogorov max-flow/min-cut
4192 _, __, labels = maximum_flow(G, s, t, C, algorithm=BoykovKolmogorovAlgorithm())
-
- # remove source and sink terminals
0 labels = labels[1:end-2]
-
- # cut mask
10240 M = falses(E)
188160 M[labels .== 1] = true
188160 M[labels .== 0] = true
-
- # permute back to original shape
0 if dir == :x
14720 M = permutedims(M, [1,2,3])
0 elseif dir == :y
14720 M = permutedims(M, [2,1,3])
0 elseif dir == :z
0 M = permutedims(M, [3,2,1])
- end
-
0 M
- end
-
As can be seen in the output, various lines of code that only index an existing array are allocating memory. This incorrect memory allocation also happens when I just set values of an array with a mask M[labels .== 1] = true
.
Could you please help me fix this issue?