-
-
Notifications
You must be signed in to change notification settings - Fork 657
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
[Bug] Recent release possibly mutating the structured config object #1621
Comments
hi @jgbos thanks trying out 1.1 rc. Could you provide a minimal repro with the |
@jieru-hu understood that it's not encouraged, I was just been playing around with Hydra and noticed this behavior and thought it would be of interest to you. I wouldn't see this from a command line as I wouldn't need to reuse the configuration after running |
Here is a minimal repro that does not call Hydra internals. # my_app.py
from dataclasses import dataclass
import hydra
from hydra.core.config_store import ConfigStore
from omegaconf import OmegaConf
@dataclass
class Test:
dim: int = 1
cs = ConfigStore.instance()
cs.store(name="test_config", node=Test)
@hydra.main(config_path=None, config_name="test_config")
def my_app(cfg):
pass
if __name__ == "__main__":
assert OmegaConf.create(Test) == {"dim": 1} # passes
my_app()
assert OmegaConf.create(Test) == {"dim": 1} # fails $ python my_app.py --multirun hydra/launcher=submitit_local
[2021-05-17 13:31:03,056][HYDRA] Submitit 'local' sweep output dir : multirun/2021-05-17/13-31-02
[2021-05-17 13:31:03,058][HYDRA] #0 :
Traceback (most recent call last):
File "/home/jbss/tmp/my_app.py", line 22, in <module>
assert OmegaConf.create(Test) == {"dim": 1} # fails
AssertionError |
This happens in 1.0 as well. Something is happening to the dataclass itself. After the run, # my_app.py
import copy
from dataclasses import dataclass
import dataclasses
import hydra
from hydra.core.config_store import ConfigStore
@dataclass
class Test:
dim: int = 1
cs = ConfigStore.instance()
cs.store(name="test_config", node=copy.deepcopy(Test))
@hydra.main(config_path=None, config_name="test_config")
def my_app(cfg):
pass
if __name__ == "__main__":
print("before", dataclasses.fields(Test))
my_app()
print("after", dataclasses.fields(Test))
|
Hmm, interesting. I thought I saw some behavior change from
I'll see if I can reproduce my "successful" runs on older versions of Hydra doing slurm submissions. |
I am seeing the same behavior in Hydra 1.0.6 (not 1.1 at all). There is something really weird going on here but I don't think it's new. |
A workaround seems to be to place the config class in a different module (not the main one). I think a good plan here is to try to eliminate layers to determine where this is coming from. This is a pretty hard one. I am not sure what could be causing it. # cfg.py
from dataclasses import dataclass
@dataclass
class Test:
dim: int = 1 # my_app.py
from cfg import Test
import hydra
from hydra.core.config_store import ConfigStore
from omegaconf import OmegaConf
cs = ConfigStore.instance()
cs.store(name="test_config", node=Test)
@hydra.main(config_path=None, config_name="test_config")
def my_app(cfg):
pass
if __name__ == "__main__":
assert OmegaConf.create(Test) == {"dim": 1} # passes
my_app()
assert OmegaConf.create(Test) == {"dim": 1} # ALSO PASSES |
I had a feeling it might be related to pickling last night given the launchers used. Just searched cloudpickle and found this issue: Do you think this captures what's going on: import cloudpickle
from dataclasses import dataclass
import dataclasses
@dataclass
class Test:
dim: int = 1
print(dataclasses.fields(Test))
t2 = cloudpickle.loads(cloudpickle.dumps(Test))
print(dataclasses.fields(t2)) output:
|
Definitely looks related... |
It's worse than this: import cloudpickle
from dataclasses import dataclass
import dataclasses
@dataclass
class Test:
dim: int = 1
print(dataclasses.fields(Test))
_unused_deserialized_class = cloudpickle.loads(cloudpickle.dumps(Test))
print(dataclasses.fields(Test)) Output:
|
Just to add one more example, similar to @omry's example loading from a separate file: import dataclasses
from dataclasses import dataclass
import cloudpickle
def build_class():
@dataclass
class Test:
dim: int = 1
return Test
test = build_class()
print(dataclasses.fields(test))
_unused_deserialized_class = cloudpickle.loads(cloudpickle.dumps(test))
print(dataclasses.fields(build_class())) Output
|
Closing as this is not a Hydra bug. feel free to continue the discussion here. |
🐛 Bug
Description
Just playing around with Hydra and noticed the behavior below. It only happens for the
submitit
andjoblib
launchers and not thebasic
launcher (that's all I've tested on).Checklist
To reproduce
First I define a sample structured config.
Running the following command outputs:
Now if I run a
multirun
experiment with eithersubmitit
orjoblib
launchers (all I have to work with)and then try to create the object again:
The only way to create the object again is to restart my notebook.
Expected Behavior
I would expect no issues with creating the object after a run. It seems some sort of mutation is happening on the object, but I'm not sure where this is happening.
System information
The text was updated successfully, but these errors were encountered: