Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Multiple StellarPopulation instances #60

Open
bd-j opened this issue Jun 2, 2016 · 6 comments
Open

Multiple StellarPopulation instances #60

bd-j opened this issue Jun 2, 2016 · 6 comments

Comments

@bd-j
Copy link
Collaborator

bd-j commented Jun 2, 2016

Because parameter state and dirtiness is specific to each instance, but the computed model is held by the module level driver object, having multiple StellarPopulation instances can cause a model to not be recomputed even though it should be (example code below) This might also cause problems with shared memory multiprocessing.

Some documentation advising only a single sps instance per program might be a good idea.

from numpy.testing import assert_allclose
import fsps
sps = fsps.StellarPopulation(zcontinuous=1, vactoair_flag=False)
pop = fsps.StellarPopulation(zcontinuous=1, vactoair_flag=False)
w1, s1 = sps.get_spectrum(tage=10.0)
w, s = pop.get_spectrum(tage=1.0)
w2, s2 = sps.get_spectrum(tage=10.0)
assert_allclose(s, s2) # this should not pass, but does
assert_allclose(s1, s2) # this should not fail, but does
@changhoonhahn
Copy link

Is there any way to check whether there's already an sps instance running? I also ran into this problem: https://github.com/changhoonhahn/provabgs/blob/main/nb/tests/fsps_multiple_sps_issue.ipynb

@dfm
Copy link
Owner

dfm commented Mar 9, 2021

It would be awesome to fix this, but I think it's probably not simple because of how FSPS is implemented, and the way Fortran modules work. I think the "right" way to do it would be to expose a Fortran "fsps" type that can pass all of the work variables between Fortran and Python, but it might be hard to maintain something like that. So perhaps a more feasible approach would be to do something horrible like importing multiple versions of the fsps Python module and activating the right one when necessary. This would be finicky, but it might just work.

@bd-j
Copy link
Collaborator Author

bd-j commented Mar 10, 2021

I think most applications can get by with a single instance though it might be annoying to have to pass it around (and noting also that the module itself is fairly memory intensive.) Could we instead somehow raise an error or a warning if a second instance is created? This is well beyond my object programming experience, but maybe something like:

from fsps import StellarPopulation

class OnlyStellarPopulation(StellarPopulation):

    _instance = None

    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(OnlyStellarPopulation, cls).__new__(cls)
        else:
            raise TypeError("Try to use only a single instance of StellarPopulation") # or something

        return cls._instance

@dfm
Copy link
Owner

dfm commented Mar 31, 2021

Whoops - just seeing this now! This sounds like a good approach. Do you think we want this to be an error or a warning?

@bd-j
Copy link
Collaborator Author

bd-j commented Apr 1, 2021

I'm not sure. The possible failure mode is insidious enough that an error is probably the way to go, but there are circumstances where it can be done safely and is convenient. Could it raise an error by default, but have the ability to disable the error with a keyword if for users who are sure that's what they want to do?

@dfm
Copy link
Owner

dfm commented Apr 1, 2021

I bet that's possible and seems like a good way to do it! It's possible that we could have a syntax like:

sp1 = StellarPopulation()

sp2 = StellarPopulation()  # raises an error

sp3 = StellarPopulation.new_instance()

Can you say more about these cases where it would make sense?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants