dfm / python-fsps

Python bindings to Charlie Conroy's Flexible Stellar Population Synthesis (FSPS) Fortran code
https://python-fsps.readthedocs.io
MIT License
67 stars 38 forks source link

startup / instantiation speed #108

Open dnelson86 opened 6 years ago

dnelson86 commented 6 years ago

Hello,

I'd like to embed fsps into a framework which requires that instances be brought up and down rapidly. In particular, I'd like to get

import fsps
pop = fsps.StellarPopulation()

down to ~1 second or so (currently, for me, this takes more like 10 seconds or even longer). What are the major bottlenecks here?

bd-j commented 6 years ago

I haven't profiled it, but I think the hard work is being done in fsps/src/sps_setup.f90 which reads all the isochrone tables and the stellar spectral libraries and the nebular continuum tables, and then interpolates the stellar libraries to the isochrone metallicities. I suspect it's the interpolation that is taking a long time. If you have a narrow metallicity range it should be possible to read in a restricted range of isochrones and stellar spectra, and do fewer interpolations. But again, I haven't profiled sps_setup; for our use cases several second startup times aren't a problem.

Additionally, generating SSPs on the first call to get_spectrum is time consuming. For the MIST isochrones this can take quite some time; cleverly reducing the number of points in the isochrone tables might help, if this is part of your use case. cc'ing @cconroy20

saethlin commented 5 years ago

I've looked into this. The interpolation is a contributor, but only about half of all startup time. You won't get to 1 second by dealing with the interpolation; one could build FSPS with -Ofast and add !$OMP PARALLEL DO around the interpolation loops, but you'll need to add -fopenmp to the build flags for FSPS itself and also add -fopenmp -lgomp to python-fsps. This isn't a huge challenge but I'm skittish to submit PRs because if FSPS takes the patch first it'll break the python-fsps installation.

The harder obstacle is that calling the StellarPopulation initializer without arguments loads all the FSPS data, which is nearly half a gig of text files. IMO the proper fix is to have these loaded from some kind of binary format, be that huge Fortran array literals (compile time gets pretty silly) or a binary format that can be memcpy'd or mmap'd in at startup. Unfortunately such an operation is well beyond my primitive Fortran skills.

bd-j commented 5 years ago

Thanks for looking into this.

Only one of the set of isochrones text files will be read in at a time, but for the default MIST isochrones this is still ~140MB. The much larger file sizes versus say Padova is largely due to extra isochrone sampling on the TP-AGB evolutionary phase that probably doesn't make much a difference for output SEDs. So the number of isochrone points could be reduced, or the isochrone data could be turned into binary files like the spectral libraries. Hopefully we can get to this (really its an FSPS issue) sometime soon.