prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Update Example Launcher Plugin mention restoring the singletons
  The singletons should be restored when performing multi-process launching.
  something 
  
  ```python
  # In the launcher's launch:
  state = Singleton.get_state()
  
  # In the remote process
  Singleton.set_state(state)
  ```
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py`
  Content:
  ```
  1 # Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved
  2 import logging
  3 from pathlib import Path
  4 from typing import Optional, Sequence
  5 
  6 from hydra.core.config_loader import ConfigLoader
  7 from hydra.core.config_search_path import ConfigSearchPath
  8 from hydra.core.hydra_config import HydraConfig
  9 from hydra.core.utils import (
  10     JobReturn,
  11     configure_log,
  12     filter_overrides,
  13     run_job,
  14     setup_globals,
  15 )
  16 from hydra.plugins.launcher import Launcher
  17 from hydra.plugins.search_path_plugin import SearchPathPlugin
  18 from hydra.types import TaskFunction
  19 from omegaconf import DictConfig, open_dict
  20 
  21 # IMPORTANT:
  22 # If your plugin imports any module that takes more than a fraction of a second to import,
  23 # Import the module lazily (typically inside launch()).
  24 # Installed plugins are imported during Hydra initialization and plugins that are slow to import plugins will slow
  25 # the startup of ALL hydra applications.
  26 # Another approach is to place heavy includes in a file prefixed by _, such as _core.py:
  27 # Hydra will not look for plugin in such files and will not import them during plugin discovery.
  28 
  29 
  30 log = logging.getLogger(__name__)
  31 
  32 
  33 class ExampleLauncherSearchPathPlugin(SearchPathPlugin):
  34     """
  35     This plugin is allowing configuration files provided by the ExampleLauncher plugin to be discovered
  36     and used once the ExampleLauncher plugin is installed
  37     """
  38 
  39     def manipulate_search_path(self, search_path: ConfigSearchPath) -> None:
  40         # Appends the search path for this plugin to the end of the search path
  41         search_path.append(
  42             "hydra-example-launcher", "pkg://hydra_plugins.example_launcher_plugin.conf"
  43         )
  44 
  45 
  46 class ExampleLauncher(Launcher):
  47     def __init__(self, foo: str, bar: str) -> None:
  48         self.config: Optional[DictConfig] = None
  49         self.config_loader: Optional[ConfigLoader] = None
  50         self.task_function: Optional[TaskFunction] = None
  51 
  52         # foo and var are coming from the the plugin's configuration
  53         self.foo = foo
  54         self.bar = bar
  55 
  56     def setup(
  57         self,
  58         config: DictConfig,
  59         config_loader: ConfigLoader,
  60         task_function: TaskFunction,
  61     ) -> None:
  62         self.config = config
  63         self.config_loader = config_loader
  64         self.task_function = task_function
  65 
  66     def launch(
  67         self, job_overrides: Sequence[Sequence[str]], initial_job_idx: int
  68     ) -> Sequence[JobReturn]:
  69         """
  70         :param job_overrides: a List of List<String>, where each inner list is the arguments for one job run.
  71         :param initial_job_idx: Initial job idx in batch.
  72         :return: an array of return values from run_job with indexes corresponding to the input list indexes.
  73         """
  74         setup_globals()
  75         assert self.config is not None
  76         assert self.config_loader is not None
  77         assert self.task_function is not None
  78 
  79         configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)
  80         sweep_dir = Path(str(self.config.hydra.sweep.dir))
  81         sweep_dir.mkdir(parents=True, exist_ok=True)
  82         log.info(
  83             f"Example Launcher(foo={self.foo}, bar={self.bar}) is launching {len(job_overrides)} jobs locally"
  84         )
  85         log.info(f"Sweep output dir : {sweep_dir}")
  86         runs = []
  87 
  88         for idx, overrides in enumerate(job_overrides):
  89             idx = initial_job_idx + idx
  90             lst = " ".join(filter_overrides(overrides))
  91             log.info(f"\t#{idx} : {lst}")
  92             sweep_config = self.config_loader.load_sweep_config(
  93                 self.config, list(overrides)
  94             )
  95             with open_dict(sweep_config):
  96                 # This typically coming from the underlying scheduler (SLURM_JOB_ID for instance)
  97                 # In that case, it will not be available here because we are still in the main process.
  98                 # but instead should be populated remotely before calling the task_function.
  99                 sweep_config.hydra.job.id = f"job_id_for_{idx}"
  100                 sweep_config.hydra.job.num = idx
  101             HydraConfig.instance().set_config(sweep_config)
  102 
  103             ret = run_job(
  104                 config=sweep_config,
  105                 task_function=self.task_function,
  106                 job_dir_key="hydra.sweep.dir",
  107                 job_subdir_key="hydra.sweep.subdir",
  108             )
  109             runs.append(ret)
  110             # reconfigure the logging subsystem for Hydra as the run_job call configured it for the Job.
  111             # This is needed for launchers that calls run_job in the same process and not spawn a new one.
  112             configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)
  113         return runs
  114
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py b/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py
  --- a/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py
  +++ b/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py
  @@ -6,6 +6,7 @@
   from hydra.core.config_loader import ConfigLoader
   from hydra.core.config_search_path import ConfigSearchPath
   from hydra.core.hydra_config import HydraConfig
  +from hydra.core.singleton import Singleton
   from hydra.core.utils import (
       JobReturn,
       configure_log,
  @@ -100,6 +101,17 @@
                   sweep_config.hydra.job.num = idx
               HydraConfig.instance().set_config(sweep_config)
   
  +            # If your launcher is executing code in a different process, it is important to restore
  +            # the singleton state in the new process.
  +            # To do this, you will likely need to serialize the singleton state along with the other
  +            # parameters passed to the child process.
  +
  +            # happening on launcher process
  +            state = Singleton.get_state()
  +
  +            # happening on the spawned process
  +            Singleton.set_state(state)
  +
               ret = run_job(
                   config=sweep_config,
                   task_function=self.task_function,
  
verification_info: {"golden_diff": "diff --git a/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py b/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py\n--- a/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py\n+++ b/plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py\n@@ -6,6 +6,7 @@\n from hydra.core.config_loader import ConfigLoader\n from hydra.core.config_search_path import ConfigSearchPath\n from hydra.core.hydra_config import HydraConfig\n+from hydra.core.singleton import Singleton\n from hydra.core.utils import (\n     JobReturn,\n     configure_log,\n@@ -100,6 +101,17 @@\n                 sweep_config.hydra.job.num = idx\n             HydraConfig.instance().set_config(sweep_config)\n \n+            # If your launcher is executing code in a different process, it is important to restore\n+            # the singleton state in the new process.\n+            # To do this, you will likely need to serialize the singleton state along with the other\n+            # parameters passed to the child process.\n+\n+            # happening on launcher process\n+            state = Singleton.get_state()\n+\n+            # happening on the spawned process\n+            Singleton.set_state(state)\n+\n             ret = run_job(\n                 config=sweep_config,\n                 task_function=self.task_function,\n", "issue": "Update Example Launcher Plugin mention restoring the singletons\nThe singletons should be restored when performing multi-process launching.\r\nsomething \r\n\r\n```python\r\n# In the launcher's launch:\r\nstate = Singleton.get_state()\r\n\r\n# In the remote process\r\nSingleton.set_state(state)\r\n```\n", "before_files": [{"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport logging\nfrom pathlib import Path\nfrom typing import Optional, Sequence\n\nfrom hydra.core.config_loader import ConfigLoader\nfrom hydra.core.config_search_path import ConfigSearchPath\nfrom hydra.core.hydra_config import HydraConfig\nfrom hydra.core.utils import (\n    JobReturn,\n    configure_log,\n    filter_overrides,\n    run_job,\n    setup_globals,\n)\nfrom hydra.plugins.launcher import Launcher\nfrom hydra.plugins.search_path_plugin import SearchPathPlugin\nfrom hydra.types import TaskFunction\nfrom omegaconf import DictConfig, open_dict\n\n# IMPORTANT:\n# If your plugin imports any module that takes more than a fraction of a second to import,\n# Import the module lazily (typically inside launch()).\n# Installed plugins are imported during Hydra initialization and plugins that are slow to import plugins will slow\n# the startup of ALL hydra applications.\n# Another approach is to place heavy includes in a file prefixed by _, such as _core.py:\n# Hydra will not look for plugin in such files and will not import them during plugin discovery.\n\n\nlog = logging.getLogger(__name__)\n\n\nclass ExampleLauncherSearchPathPlugin(SearchPathPlugin):\n    \"\"\"\n    This plugin is allowing configuration files provided by the ExampleLauncher plugin to be discovered\n    and used once the ExampleLauncher plugin is installed\n    \"\"\"\n\n    def manipulate_search_path(self, search_path: ConfigSearchPath) -> None:\n        # Appends the search path for this plugin to the end of the search path\n        search_path.append(\n            \"hydra-example-launcher\", \"pkg://hydra_plugins.example_launcher_plugin.conf\"\n        )\n\n\nclass ExampleLauncher(Launcher):\n    def __init__(self, foo: str, bar: str) -> None:\n        self.config: Optional[DictConfig] = None\n        self.config_loader: Optional[ConfigLoader] = None\n        self.task_function: Optional[TaskFunction] = None\n\n        # foo and var are coming from the the plugin's configuration\n        self.foo = foo\n        self.bar = bar\n\n    def setup(\n        self,\n        config: DictConfig,\n        config_loader: ConfigLoader,\n        task_function: TaskFunction,\n    ) -> None:\n        self.config = config\n        self.config_loader = config_loader\n        self.task_function = task_function\n\n    def launch(\n        self, job_overrides: Sequence[Sequence[str]], initial_job_idx: int\n    ) -> Sequence[JobReturn]:\n        \"\"\"\n        :param job_overrides: a List of List<String>, where each inner list is the arguments for one job run.\n        :param initial_job_idx: Initial job idx in batch.\n        :return: an array of return values from run_job with indexes corresponding to the input list indexes.\n        \"\"\"\n        setup_globals()\n        assert self.config is not None\n        assert self.config_loader is not None\n        assert self.task_function is not None\n\n        configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)\n        sweep_dir = Path(str(self.config.hydra.sweep.dir))\n        sweep_dir.mkdir(parents=True, exist_ok=True)\n        log.info(\n            f\"Example Launcher(foo={self.foo}, bar={self.bar}) is launching {len(job_overrides)} jobs locally\"\n        )\n        log.info(f\"Sweep output dir : {sweep_dir}\")\n        runs = []\n\n        for idx, overrides in enumerate(job_overrides):\n            idx = initial_job_idx + idx\n            lst = \" \".join(filter_overrides(overrides))\n            log.info(f\"\\t#{idx} : {lst}\")\n            sweep_config = self.config_loader.load_sweep_config(\n                self.config, list(overrides)\n            )\n            with open_dict(sweep_config):\n                # This typically coming from the underlying scheduler (SLURM_JOB_ID for instance)\n                # In that case, it will not be available here because we are still in the main process.\n                # but instead should be populated remotely before calling the task_function.\n                sweep_config.hydra.job.id = f\"job_id_for_{idx}\"\n                sweep_config.hydra.job.num = idx\n            HydraConfig.instance().set_config(sweep_config)\n\n            ret = run_job(\n                config=sweep_config,\n                task_function=self.task_function,\n                job_dir_key=\"hydra.sweep.dir\",\n                job_subdir_key=\"hydra.sweep.subdir\",\n            )\n            runs.append(ret)\n            # reconfigure the logging subsystem for Hydra as the run_job call configured it for the Job.\n            # This is needed for launchers that calls run_job in the same process and not spawn a new one.\n            configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)\n        return runs\n", "path": "plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py"}], "after_files": [{"content": "# Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved\nimport logging\nfrom pathlib import Path\nfrom typing import Optional, Sequence\n\nfrom hydra.core.config_loader import ConfigLoader\nfrom hydra.core.config_search_path import ConfigSearchPath\nfrom hydra.core.hydra_config import HydraConfig\nfrom hydra.core.singleton import Singleton\nfrom hydra.core.utils import (\n    JobReturn,\n    configure_log,\n    filter_overrides,\n    run_job,\n    setup_globals,\n)\nfrom hydra.plugins.launcher import Launcher\nfrom hydra.plugins.search_path_plugin import SearchPathPlugin\nfrom hydra.types import TaskFunction\nfrom omegaconf import DictConfig, open_dict\n\n# IMPORTANT:\n# If your plugin imports any module that takes more than a fraction of a second to import,\n# Import the module lazily (typically inside launch()).\n# Installed plugins are imported during Hydra initialization and plugins that are slow to import plugins will slow\n# the startup of ALL hydra applications.\n# Another approach is to place heavy includes in a file prefixed by _, such as _core.py:\n# Hydra will not look for plugin in such files and will not import them during plugin discovery.\n\n\nlog = logging.getLogger(__name__)\n\n\nclass ExampleLauncherSearchPathPlugin(SearchPathPlugin):\n    \"\"\"\n    This plugin is allowing configuration files provided by the ExampleLauncher plugin to be discovered\n    and used once the ExampleLauncher plugin is installed\n    \"\"\"\n\n    def manipulate_search_path(self, search_path: ConfigSearchPath) -> None:\n        # Appends the search path for this plugin to the end of the search path\n        search_path.append(\n            \"hydra-example-launcher\", \"pkg://hydra_plugins.example_launcher_plugin.conf\"\n        )\n\n\nclass ExampleLauncher(Launcher):\n    def __init__(self, foo: str, bar: str) -> None:\n        self.config: Optional[DictConfig] = None\n        self.config_loader: Optional[ConfigLoader] = None\n        self.task_function: Optional[TaskFunction] = None\n\n        # foo and var are coming from the the plugin's configuration\n        self.foo = foo\n        self.bar = bar\n\n    def setup(\n        self,\n        config: DictConfig,\n        config_loader: ConfigLoader,\n        task_function: TaskFunction,\n    ) -> None:\n        self.config = config\n        self.config_loader = config_loader\n        self.task_function = task_function\n\n    def launch(\n        self, job_overrides: Sequence[Sequence[str]], initial_job_idx: int\n    ) -> Sequence[JobReturn]:\n        \"\"\"\n        :param job_overrides: a List of List<String>, where each inner list is the arguments for one job run.\n        :param initial_job_idx: Initial job idx in batch.\n        :return: an array of return values from run_job with indexes corresponding to the input list indexes.\n        \"\"\"\n        setup_globals()\n        assert self.config is not None\n        assert self.config_loader is not None\n        assert self.task_function is not None\n\n        configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)\n        sweep_dir = Path(str(self.config.hydra.sweep.dir))\n        sweep_dir.mkdir(parents=True, exist_ok=True)\n        log.info(\n            f\"Example Launcher(foo={self.foo}, bar={self.bar}) is launching {len(job_overrides)} jobs locally\"\n        )\n        log.info(f\"Sweep output dir : {sweep_dir}\")\n        runs = []\n\n        for idx, overrides in enumerate(job_overrides):\n            idx = initial_job_idx + idx\n            lst = \" \".join(filter_overrides(overrides))\n            log.info(f\"\\t#{idx} : {lst}\")\n            sweep_config = self.config_loader.load_sweep_config(\n                self.config, list(overrides)\n            )\n            with open_dict(sweep_config):\n                # This typically coming from the underlying scheduler (SLURM_JOB_ID for instance)\n                # In that case, it will not be available here because we are still in the main process.\n                # but instead should be populated remotely before calling the task_function.\n                sweep_config.hydra.job.id = f\"job_id_for_{idx}\"\n                sweep_config.hydra.job.num = idx\n            HydraConfig.instance().set_config(sweep_config)\n\n            # If your launcher is executing code in a different process, it is important to restore\n            # the singleton state in the new process.\n            # To do this, you will likely need to serialize the singleton state along with the other\n            # parameters passed to the child process.\n\n            # happening on launcher process\n            state = Singleton.get_state()\n\n            # happening on the spawned process\n            Singleton.set_state(state)\n\n            ret = run_job(\n                config=sweep_config,\n                task_function=self.task_function,\n                job_dir_key=\"hydra.sweep.dir\",\n                job_subdir_key=\"hydra.sweep.subdir\",\n            )\n            runs.append(ret)\n            # reconfigure the logging subsystem for Hydra as the run_job call configured it for the Job.\n            # This is needed for launchers that calls run_job in the same process and not spawn a new one.\n            configure_log(self.config.hydra.hydra_logging, self.config.hydra.verbose)\n        return runs\n", "path": "plugins/examples/example_launcher_plugin/hydra_plugins/example_launcher_plugin/example_launcher.py"}]}