Performance hit with 0.7


#1

Just heads up: testing my package indicated major performance hits with 0.7.

With 0.6.2:

julia> Pkg.test("FinEtools")
INFO: Testing FinEtools
WARNING: Method definition pairs(Any) in module FEMMBaseModule at C:\Users\PetrKrysl\.julia\v0.6\FinEtools\src\FEMMBaseModule.jl:9 overwritten at C:\Users\PetrKrysl\.julia\v0.6\FinEtools\src\FEMMBaseModule.jl:34.
Test Summary: | Pass  Total
Miscellaneous |  100    100
timing = 24.399999856948853
Test Summary: | Pass  Total
Acoustics     |   20     20
timing = 73.90499997138977
Test Summary:  | Pass  Total
Heat diffusion |   25     25
timing = 23.575999975204468
Test Summary:      | Pass  Total
Linear deformation |  159    159
timing = 87.45600008964539
Test Summary: | Pass  Total
Meshing       |   97     97
timing = 668.6500000953674
Test Summary: | Pass  Total
Voxel box     |   27     27
timing = 3.1499998569488525
INFO: FinEtools tests passed

and with 0.7:

$ ~/AppData/Local/Julia-0.7.0-DEV/bin/julia
               _
   _       _ _(_)_     |  A fresh approach to technical computing
  (_)     | (_) (_)    |  Documentation: https://docs.julialang.org
   _ _   _| |_  __ _   |  Type "?help" for help.
  | | | | | | |/ _` |  |
  | | |_| | | | (_| |  |  Version 0.7.0-DEV.3404 (2018-01-14 21:52 UTC)
 _/ |\__'_|_|_|\__'_|  |  Commit d569a2923c* (4 days old master)
|__/                   |  x86_64-w64-mingw32

julia> Pkg.test("FinEtools")
[ Info: Testing FinEtools
WARNING: using SparseArrays.At_mul_B! in module FEMMBaseModule conflicts with an existing identifier.
WARNING: Method definition At_mul_B!(Any, Any, Any) in module FEMMBaseModule at C:\Users\PetrKrysl\.julia\v0.7\FinEtools\src\FEMMBaseModule.jl:12 overwritten at C:\Users\PetrKrysl\.julia\v0.7\FinEtools\src\FEMMBaseModule.jl:37.
WARNING: using SparseArrays.A_mul_B! in module AlgoDeforLinearModule conflicts with an existing identifier.
WARNING: using SparseArrays.At_mul_B! in module AlgoDeforLinearModule conflicts with an existing identifier.
Test Summary: | Pass  Total
Miscellaneous |  100    100
timing = 31.23099994659424
┌ Warning: `diff(A::AbstractMatrix)` is deprecated, use `diff(A, 1)` instead.
│   caller = (::getfield(Main.mmhhemispheremm, Symbol("#find_peaks#64")))(::Array{Float64,2}, ::Array{Float64,2}) at test_acoustics.jl:1022
└ @ Main.mmhhemispheremm test_acoustics.jl:1022
Test Summary: | Pass  Total
Acoustics     |   20     20
timing = 279.1560001373291
Test Summary:  | Pass  Total
Heat diffusion |   25     25
timing = 298.2389998435974
Test Summary:      | Pass  Total
Linear deformation |  159    159
timing = 571.5829999446869
Test Summary: | Pass  Total
Meshing       |   97     97
timing = 481.1980001926422
Test Summary: | Pass  Total
Voxel box     |   27     27
timing = 2.757999897003174
[ Info: FinEtools tests passed

As before, I will try to track down where the computations get stuck. Stay tuned please.


#2

The first thing to do is to fix any deprecation warnings – those slow things down quite a bit. Short of that, time with deprecations off and see if that’s still slow.


#3

Since I know you are dealing with sparse matrices, make sure that a lazy transposed sparse matrix is not being used somewhere where it shouldn’t.


#4

Yep, it was sparse-matrix transpose:

julia> S = sparse([2, 3], [1, 2], [3., 4.], 3, 3)
3×3 SparseMatrixCSC{Float64,Int64} with 2 stored entries:
  [2, 1]  =  3.0
  [3, 2]  =  4.0

julia> S + transpose(S)
3×3 Array{Float64,2}:
 0.0  3.0  0.0
 3.0  0.0  4.0
 0.0  4.0  0.0

julia> S + Transpose(S)
3×3 Array{Float64,2}:
 0.0  3.0  0.0
 3.0  0.0  4.0
 0.0  4.0  0.0

I am guessing that the addition of a sparse matrix and the transpose of a sparse matrix is not defined, and the default produces a regular dense array?


#5

To do the similar as in 0.6 you would need to right now do S + copy(S') but ideally this should be fixed.

Imo, using the word copy for materializing an adjoint feels weird…


#6

Thanks. Could you elaborate on how this would be fixed?


#7

By defining e.g a method +(::SparseMatrixCSC, ::Adjoint{SparseMatrixCSC}) which returns a sparse array.


#8

Right. But how is it actually going to be implemented inside the ‘+’ function? Will it have to be done with copy()?


#9

You can access the original array in the .parent field. So either you write an optimized sparse matrix + sparse matrix transpose method or you materialize the transpose and do a normal sparse matrix + sparse matrix.


#10

I see. Thank you very much.