GalSim-developers / GalSim

The modular galaxy image simulation toolkit. Documentation:
http://galsim-developers.github.io/GalSim/
Other
224 stars 105 forks source link

Delay calculation of SED until it is actually needed. #1245

Closed rmjarvis closed 1 year ago

rmjarvis commented 1 year ago

I was looking through the profile Jim made recently of an imSim run, which inspired the combine_wave_list speed up in #1243. This PR continues in that vein with various optimizations, mostly related to the SEDs.

The relevant timing script is devel/time_faint_bd_gals.py. On my laptop, the time to draw 1000 galaxies went from 1.48 seconds before these changes down to 0.47 seconds after. So a factor of 3 faster, which feels pretty good to me. The remaining tall (ish) poles are initializing the knots in c++, multiplying the sed by a scalar to get the final flux right, making the non-chromatic Transformation object, and initializing the SED objects. Here is the full profile now, fwiw

Time for 1000 iterations of draw_faint = 0.47057316699999996
         2083935 function calls (1973139 primitive calls) in 0.769 seconds

   Ordered by: internal time
   List reduced from 344 to 30 due to restriction <30>

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
      959    0.042    0.000    0.074    0.000 /Users/Mike/GalSim/galsim/knots.py:134(_sbp)
65602/35898    0.025    0.000    0.199    0.000 /Users/Mike/GalSim/galsim/_utilities.py:56(__get__)
    10713    0.024    0.000    0.090    0.000 /Users/Mike/GalSim/galsim/sed.py:525(_mul_scalar)
    10774    0.020    0.000    0.054    0.000 /Users/Mike/GalSim/galsim/transform.py:197(__init__)
    10713    0.017    0.000    0.047    0.000 /Users/Mike/GalSim/galsim/sed.py:133(__init__)
     4063    0.016    0.000    0.018    0.000 /Users/Mike/GalSim/galsim/photon_array.py:546(_pa)
4063/1918    0.015    0.000    0.086    0.000 /Users/Mike/GalSim/galsim/transform.py:585(_shoot)
   217331    0.013    0.000    0.013    0.000 {built-in method builtins.isinstance}
     9314    0.013    0.000    0.013    0.000 {method 'reduce' of 'numpy.ufunc' objects}
     4567    0.013    0.000    0.013    0.000 /Users/Mike/GalSim/galsim/table.py:170(_tab)
     1000    0.012    0.000    0.769    0.001 time_faint_bd_gals.py:52(draw_faint)
     8076    0.011    0.000    0.021    0.000 /Users/Mike/GalSim/galsim/table.py:197(__call__)
    36202    0.011    0.000    0.011    0.000 /Users/Mike/GalSim/galsim/_utilities.py:316(__init__)
    10713    0.011    0.000    0.021    0.000 /Users/Mike/GalSim/galsim/sed.py:238(_setup_funcs)
    12479    0.011    0.000    0.015    0.000 /Users/Mike/GalSim/galsim/table.py:514(_LookupTable)
    13651    0.010    0.000    0.014    0.000 /Users/Mike/GalSim/galsim/position.py:81(_parse_args)
     9382    0.010    0.000    0.049    0.000 /Users/Mike/GalSim/galsim/transform.py:40(Transform)
      959    0.010    0.000    0.366    0.000 /Users/Mike/GalSim/galsim/chromatic.py:406(drawImage)
     7193    0.010    0.000    0.037    0.000 /Users/Mike/GalSim/galsim/sed.py:418(_call_fast)
     1918    0.009    0.000    0.208    0.000 /Users/Mike/GalSim/galsim/gsobject.py:1273(drawImage)
     1842    0.008    0.000    0.046    0.000 /Users/Mike/GalSim/galsim/table.py:310(integrate_product)
16530/13805    0.008    0.000    0.050    0.000 {built-in method numpy.core._multiarray_umath.implement_array_function}
    81602    0.008    0.000    0.008    0.000 {built-in method builtins.setattr}
     9086    0.008    0.000    0.025    0.000 /Users/Mike/mambaforge/envs/py3.8/lib/python3.8/site-packages/numpy/core/fromnumeric.py:69(_wrapreduction)
     3959    0.008    0.000    0.009    0.000 /Users/Mike/GalSim/galsim/random.py:157(duplicate)
      959    0.008    0.000    0.063    0.000 /Users/Mike/GalSim/galsim/sum.py:312(_shoot)
    10713    0.008    0.000    0.101    0.000 /Users/Mike/GalSim/galsim/sed.py:551(__mul__)
    15432    0.007    0.000    0.007    0.000 {built-in method numpy.array}
    22156    0.007    0.000    0.011    0.000 /Users/Mike/GalSim/galsim/gsparams.py:180(check)
    10713    0.007    0.000    0.126    0.000 /Users/Mike/GalSim/galsim/chromatic.py:2067(sed)

(The __get__ call in the second line is our lazy_property decorator, so it's just farming out to various other things and then writing the result as an attribute.) Nothing jumps out as particularly egregious now.

jmeyers314 commented 1 year ago

Actually, I have one more thing while we're here. I think the following really ought to work, but it doesn't:

sed = galsim.SED(
    galsim.LookupTable(
        [0, 621, 622, 623, np.inf],
        # [0, 621, 622, 623, 10000],
        [0, 0, 1, 0, 0],
        interpolant='linear'
    ),
    wave_type='nm',
    flux_type='fphotons'
)

bp = galsim.Bandpass("LSST_r.dat", 'nm')  
print(sed.calculateFlux(bp))  # gives nan

If I swap the np.inf for 10000 though, it does seem to work. Something about Table::integrateProduct I suspect, though I didn't dive in.