prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Environment variable change in module cray-libsci of CPE 23.12
  Hi, I report a bug affecting EasyBuild on Cray systems (file [libsci.py](https://github.com/easybuilders/easybuild-framework/blob/develop/easybuild/toolchains/linalg/libsci.py)) with the Cray Programming Environment (CPE) 23.12. The bug should be fixed in CPE 24.03 according to HPE/Cray staff, therefore the impact is limited:
  - The environment variable name referenced in [line 68](https://github.com/easybuilders/easybuild-framework/blob/e4524c1c70e496e5886de7d4848bb8147eea84bd/easybuild/toolchains/linalg/libsci.py#L68) changed from `CRAY_LIBSCI_PREFIX_DIR` to `CRAY_PE_LIBSCI_PREFIX_DIR`
  - I have manually fixed [line 69](https://github.com/easybuilders/easybuild-framework/blob/e4524c1c70e496e5886de7d4848bb8147eea84bd/easybuild/toolchains/linalg/libsci.py#L69) using the workaround below:
    `root = os.getenv('CRAY_LIBSCI_PREFIX_DIR', None) or os.getenv('CRAY_PE_LIBSCI_PREFIX_DIR', None)`
  
  The environment variable name should be fixed back to the original one in CPE 24.03 (I did not have the chance to test it yet, though). Since CPE variable names change sometimes, it might be useful to give the option to read the `prefix` of the external module `cray-libsci` from a [metadata file](https://docs.easybuild.io/using-external-modules/?h=metadata#using_external_modules_metadata) instead of having it hard coded.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `easybuild/toolchains/linalg/libsci.py`
  Content:
  ```
  1 ##
  2 # Copyright 2014-2024 Ghent University
  3 #
  4 # This file is part of EasyBuild,
  5 # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
  6 # with support of Ghent University (http://ugent.be/hpc),
  7 # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
  8 # Flemish Research Foundation (FWO) (http://www.fwo.be/en)
  9 # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
  10 #
  11 # https://github.com/easybuilders/easybuild
  12 #
  13 # EasyBuild is free software: you can redistribute it and/or modify
  14 # it under the terms of the GNU General Public License as published by
  15 # the Free Software Foundation v2.
  16 #
  17 # EasyBuild is distributed in the hope that it will be useful,
  18 # but WITHOUT ANY WARRANTY; without even the implied warranty of
  19 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20 # GNU General Public License for more details.
  21 #
  22 # You should have received a copy of the GNU General Public License
  23 # along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.
  24 ##
  25 """
  26 Support for Cray's LibSci library, which provides BLAS/LAPACK support.
  27 cfr. https://www.nersc.gov/users/software/programming-libraries/math-libraries/libsci/
  28 
  29 Authors:
  30 
  31 * Petar Forai (IMP/IMBA, Austria)
  32 * Kenneth Hoste (Ghent University)
  33 """
  34 import os
  35 
  36 from easybuild.tools.build_log import EasyBuildError
  37 from easybuild.tools.toolchain.linalg import LinAlg
  38 
  39 
  40 CRAY_LIBSCI_MODULE_NAME = 'cray-libsci'
  41 TC_CONSTANT_CRAY_LIBSCI = 'CrayLibSci'
  42 
  43 
  44 class LibSci(LinAlg):
  45     """Support for Cray's LibSci library, which provides BLAS/LAPACK support."""
  46     # BLAS/LAPACK support
  47     # via cray-libsci module, which gets loaded via the PrgEnv module
  48     # see https://www.nersc.gov/users/software/programming-libraries/math-libraries/libsci/
  49     BLAS_MODULE_NAME = [CRAY_LIBSCI_MODULE_NAME]
  50 
  51     # no need to specify libraries, compiler driver takes care of linking the right libraries
  52     # FIXME: need to revisit this, on numpy we ended up with a serial BLAS through the wrapper.
  53     BLAS_LIB = ['']
  54     BLAS_LIB_MT = ['']
  55     BLAS_FAMILY = TC_CONSTANT_CRAY_LIBSCI
  56 
  57     LAPACK_MODULE_NAME = [CRAY_LIBSCI_MODULE_NAME]
  58     LAPACK_IS_BLAS = True
  59     LAPACK_FAMILY = TC_CONSTANT_CRAY_LIBSCI
  60 
  61     BLACS_MODULE_NAME = []
  62     SCALAPACK_MODULE_NAME = []
  63 
  64     def _get_software_root(self, name, required=True):
  65         """Get install prefix for specified software name; special treatment for Cray modules."""
  66         if name == 'cray-libsci':
  67             # Cray-provided LibSci module
  68             env_var = 'CRAY_LIBSCI_PREFIX_DIR'
  69             root = os.getenv(env_var, None)
  70             if root is None:
  71                 if required:
  72                     raise EasyBuildError("Failed to determine install prefix for %s via $%s", name, env_var)
  73             else:
  74                 self.log.debug("Obtained install prefix for %s via $%s: %s", name, env_var, root)
  75         else:
  76             root = super(LibSci, self)._get_software_root(name, required=required)
  77 
  78         return root
  79 
  80     def _set_blacs_variables(self):
  81         """Skip setting BLACS related variables"""
  82         pass
  83 
  84     def _set_scalapack_variables(self):
  85         """Skip setting ScaLAPACK related variables"""
  86         pass
  87 
  88     def definition(self):
  89         """
  90         Filter BLAS module from toolchain definition.
  91         The cray-libsci module is loaded indirectly (and versionless) via the PrgEnv module,
  92         and thus is not a direct toolchain component.
  93         """
  94         tc_def = super(LibSci, self).definition()
  95         tc_def['BLAS'] = []
  96         tc_def['LAPACK'] = []
  97         return tc_def
  98
  ```
  --- 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/easybuild/toolchains/linalg/libsci.py b/easybuild/toolchains/linalg/libsci.py
  --- a/easybuild/toolchains/linalg/libsci.py
  +++ b/easybuild/toolchains/linalg/libsci.py
  @@ -65,13 +65,20 @@
           """Get install prefix for specified software name; special treatment for Cray modules."""
           if name == 'cray-libsci':
               # Cray-provided LibSci module
  -            env_var = 'CRAY_LIBSCI_PREFIX_DIR'
  -            root = os.getenv(env_var, None)
  +            root = None
  +            # consider both $CRAY_LIBSCI_PREFIX_DIR and $CRAY_PE_LIBSCI_PREFIX_DIR,
  +            # cfr. https://github.com/easybuilders/easybuild-framework/issues/4536
  +            env_vars = ('CRAY_LIBSCI_PREFIX_DIR', 'CRAY_PE_LIBSCI_PREFIX_DIR')
  +            for env_var in env_vars:
  +                root = os.getenv(env_var, None)
  +                if root is not None:
  +                    self.log.debug("Obtained install prefix for %s via $%s: %s", name, env_var, root)
  +                    break
  +
               if root is None:
                   if required:
  -                    raise EasyBuildError("Failed to determine install prefix for %s via $%s", name, env_var)
  -            else:
  -                self.log.debug("Obtained install prefix for %s via $%s: %s", name, env_var, root)
  +                    env_vars_str = ', '.join('$' + e for e in env_vars)
  +                    raise EasyBuildError("Failed to determine install prefix for %s via $%s", name, env_vars_str)
           else:
               root = super(LibSci, self)._get_software_root(name, required=required)
  
verification_info: {"golden_diff": "diff --git a/easybuild/toolchains/linalg/libsci.py b/easybuild/toolchains/linalg/libsci.py\n--- a/easybuild/toolchains/linalg/libsci.py\n+++ b/easybuild/toolchains/linalg/libsci.py\n@@ -65,13 +65,20 @@\n         \"\"\"Get install prefix for specified software name; special treatment for Cray modules.\"\"\"\n         if name == 'cray-libsci':\n             # Cray-provided LibSci module\n-            env_var = 'CRAY_LIBSCI_PREFIX_DIR'\n-            root = os.getenv(env_var, None)\n+            root = None\n+            # consider both $CRAY_LIBSCI_PREFIX_DIR and $CRAY_PE_LIBSCI_PREFIX_DIR,\n+            # cfr. https://github.com/easybuilders/easybuild-framework/issues/4536\n+            env_vars = ('CRAY_LIBSCI_PREFIX_DIR', 'CRAY_PE_LIBSCI_PREFIX_DIR')\n+            for env_var in env_vars:\n+                root = os.getenv(env_var, None)\n+                if root is not None:\n+                    self.log.debug(\"Obtained install prefix for %s via $%s: %s\", name, env_var, root)\n+                    break\n+\n             if root is None:\n                 if required:\n-                    raise EasyBuildError(\"Failed to determine install prefix for %s via $%s\", name, env_var)\n-            else:\n-                self.log.debug(\"Obtained install prefix for %s via $%s: %s\", name, env_var, root)\n+                    env_vars_str = ', '.join('$' + e for e in env_vars)\n+                    raise EasyBuildError(\"Failed to determine install prefix for %s via $%s\", name, env_vars_str)\n         else:\n             root = super(LibSci, self)._get_software_root(name, required=required)\n", "issue": "Environment variable change in module cray-libsci of CPE 23.12\nHi, I report a bug affecting EasyBuild on Cray systems (file [libsci.py](https://github.com/easybuilders/easybuild-framework/blob/develop/easybuild/toolchains/linalg/libsci.py)) with the Cray Programming Environment (CPE) 23.12. The bug should be fixed in CPE 24.03 according to HPE/Cray staff, therefore the impact is limited:\r\n- The environment variable name referenced in [line 68](https://github.com/easybuilders/easybuild-framework/blob/e4524c1c70e496e5886de7d4848bb8147eea84bd/easybuild/toolchains/linalg/libsci.py#L68) changed from `CRAY_LIBSCI_PREFIX_DIR` to `CRAY_PE_LIBSCI_PREFIX_DIR`\r\n- I have manually fixed [line 69](https://github.com/easybuilders/easybuild-framework/blob/e4524c1c70e496e5886de7d4848bb8147eea84bd/easybuild/toolchains/linalg/libsci.py#L69) using the workaround below:\r\n  `root = os.getenv('CRAY_LIBSCI_PREFIX_DIR', None) or os.getenv('CRAY_PE_LIBSCI_PREFIX_DIR', None)`\r\n\r\nThe environment variable name should be fixed back to the original one in CPE 24.03 (I did not have the chance to test it yet, though). Since CPE variable names change sometimes, it might be useful to give the option to read the `prefix` of the external module `cray-libsci` from a [metadata file](https://docs.easybuild.io/using-external-modules/?h=metadata#using_external_modules_metadata) instead of having it hard coded.\r\n\n", "before_files": [{"content": "##\n# Copyright 2014-2024 Ghent University\n#\n# This file is part of EasyBuild,\n# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),\n# with support of Ghent University (http://ugent.be/hpc),\n# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),\n# Flemish Research Foundation (FWO) (http://www.fwo.be/en)\n# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).\n#\n# https://github.com/easybuilders/easybuild\n#\n# EasyBuild is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation v2.\n#\n# EasyBuild is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.\n##\n\"\"\"\nSupport for Cray's LibSci library, which provides BLAS/LAPACK support.\ncfr. https://www.nersc.gov/users/software/programming-libraries/math-libraries/libsci/\n\nAuthors:\n\n* Petar Forai (IMP/IMBA, Austria)\n* Kenneth Hoste (Ghent University)\n\"\"\"\nimport os\n\nfrom easybuild.tools.build_log import EasyBuildError\nfrom easybuild.tools.toolchain.linalg import LinAlg\n\n\nCRAY_LIBSCI_MODULE_NAME = 'cray-libsci'\nTC_CONSTANT_CRAY_LIBSCI = 'CrayLibSci'\n\n\nclass LibSci(LinAlg):\n    \"\"\"Support for Cray's LibSci library, which provides BLAS/LAPACK support.\"\"\"\n    # BLAS/LAPACK support\n    # via cray-libsci module, which gets loaded via the PrgEnv module\n    # see https://www.nersc.gov/users/software/programming-libraries/math-libraries/libsci/\n    BLAS_MODULE_NAME = [CRAY_LIBSCI_MODULE_NAME]\n\n    # no need to specify libraries, compiler driver takes care of linking the right libraries\n    # FIXME: need to revisit this, on numpy we ended up with a serial BLAS through the wrapper.\n    BLAS_LIB = ['']\n    BLAS_LIB_MT = ['']\n    BLAS_FAMILY = TC_CONSTANT_CRAY_LIBSCI\n\n    LAPACK_MODULE_NAME = [CRAY_LIBSCI_MODULE_NAME]\n    LAPACK_IS_BLAS = True\n    LAPACK_FAMILY = TC_CONSTANT_CRAY_LIBSCI\n\n    BLACS_MODULE_NAME = []\n    SCALAPACK_MODULE_NAME = []\n\n    def _get_software_root(self, name, required=True):\n        \"\"\"Get install prefix for specified software name; special treatment for Cray modules.\"\"\"\n        if name == 'cray-libsci':\n            # Cray-provided LibSci module\n            env_var = 'CRAY_LIBSCI_PREFIX_DIR'\n            root = os.getenv(env_var, None)\n            if root is None:\n                if required:\n                    raise EasyBuildError(\"Failed to determine install prefix for %s via $%s\", name, env_var)\n            else:\n                self.log.debug(\"Obtained install prefix for %s via $%s: %s\", name, env_var, root)\n        else:\n            root = super(LibSci, self)._get_software_root(name, required=required)\n\n        return root\n\n    def _set_blacs_variables(self):\n        \"\"\"Skip setting BLACS related variables\"\"\"\n        pass\n\n    def _set_scalapack_variables(self):\n        \"\"\"Skip setting ScaLAPACK related variables\"\"\"\n        pass\n\n    def definition(self):\n        \"\"\"\n        Filter BLAS module from toolchain definition.\n        The cray-libsci module is loaded indirectly (and versionless) via the PrgEnv module,\n        and thus is not a direct toolchain component.\n        \"\"\"\n        tc_def = super(LibSci, self).definition()\n        tc_def['BLAS'] = []\n        tc_def['LAPACK'] = []\n        return tc_def\n", "path": "easybuild/toolchains/linalg/libsci.py"}], "after_files": [{"content": "##\n# Copyright 2014-2024 Ghent University\n#\n# This file is part of EasyBuild,\n# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),\n# with support of Ghent University (http://ugent.be/hpc),\n# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),\n# Flemish Research Foundation (FWO) (http://www.fwo.be/en)\n# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).\n#\n# https://github.com/easybuilders/easybuild\n#\n# EasyBuild is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation v2.\n#\n# EasyBuild is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with EasyBuild.  If not, see <http://www.gnu.org/licenses/>.\n##\n\"\"\"\nSupport for Cray's LibSci library, which provides BLAS/LAPACK support.\ncfr. https://www.nersc.gov/users/software/programming-libraries/math-libraries/libsci/\n\nAuthors:\n\n* Petar Forai (IMP/IMBA, Austria)\n* Kenneth Hoste (Ghent University)\n\"\"\"\nimport os\n\nfrom easybuild.tools.build_log import EasyBuildError\nfrom easybuild.tools.toolchain.linalg import LinAlg\n\n\nCRAY_LIBSCI_MODULE_NAME = 'cray-libsci'\nTC_CONSTANT_CRAY_LIBSCI = 'CrayLibSci'\n\n\nclass LibSci(LinAlg):\n    \"\"\"Support for Cray's LibSci library, which provides BLAS/LAPACK support.\"\"\"\n    # BLAS/LAPACK support\n    # via cray-libsci module, which gets loaded via the PrgEnv module\n    # see https://www.nersc.gov/users/software/programming-libraries/math-libraries/libsci/\n    BLAS_MODULE_NAME = [CRAY_LIBSCI_MODULE_NAME]\n\n    # no need to specify libraries, compiler driver takes care of linking the right libraries\n    # FIXME: need to revisit this, on numpy we ended up with a serial BLAS through the wrapper.\n    BLAS_LIB = ['']\n    BLAS_LIB_MT = ['']\n    BLAS_FAMILY = TC_CONSTANT_CRAY_LIBSCI\n\n    LAPACK_MODULE_NAME = [CRAY_LIBSCI_MODULE_NAME]\n    LAPACK_IS_BLAS = True\n    LAPACK_FAMILY = TC_CONSTANT_CRAY_LIBSCI\n\n    BLACS_MODULE_NAME = []\n    SCALAPACK_MODULE_NAME = []\n\n    def _get_software_root(self, name, required=True):\n        \"\"\"Get install prefix for specified software name; special treatment for Cray modules.\"\"\"\n        if name == 'cray-libsci':\n            # Cray-provided LibSci module\n            root = None\n            # consider both $CRAY_LIBSCI_PREFIX_DIR and $CRAY_PE_LIBSCI_PREFIX_DIR,\n            # cfr. https://github.com/easybuilders/easybuild-framework/issues/4536\n            env_vars = ('CRAY_LIBSCI_PREFIX_DIR', 'CRAY_PE_LIBSCI_PREFIX_DIR')\n            for env_var in env_vars:\n                root = os.getenv(env_var, None)\n                if root is not None:\n                    self.log.debug(\"Obtained install prefix for %s via $%s: %s\", name, env_var, root)\n                    break\n\n            if root is None:\n                if required:\n                    env_vars_str = ', '.join('$' + e for e in env_vars)\n                    raise EasyBuildError(\"Failed to determine install prefix for %s via $%s\", name, env_vars_str)\n        else:\n            root = super(LibSci, self)._get_software_root(name, required=required)\n\n        return root\n\n    def _set_blacs_variables(self):\n        \"\"\"Skip setting BLACS related variables\"\"\"\n        pass\n\n    def _set_scalapack_variables(self):\n        \"\"\"Skip setting ScaLAPACK related variables\"\"\"\n        pass\n\n    def definition(self):\n        \"\"\"\n        Filter BLAS module from toolchain definition.\n        The cray-libsci module is loaded indirectly (and versionless) via the PrgEnv module,\n        and thus is not a direct toolchain component.\n        \"\"\"\n        tc_def = super(LibSci, self).definition()\n        tc_def['BLAS'] = []\n        tc_def['LAPACK'] = []\n        return tc_def\n", "path": "easybuild/toolchains/linalg/libsci.py"}]}