architecture-building-systems / CityEnergyAnalyst

The City Energy Analyst (CEA)
https://www.cityenergyanalyst.com/
MIT License
196 stars 66 forks source link

Thermal Network Simulation on Apple Silicon #3633

Closed ldrame21 closed 3 months ago

ldrame21 commented 4 months ago

Describe the bug I encountered an architecture incompatibility error while trying to run the Thermal Network Simulation (Part II) as well as the optimizations modules on an Apple Silicon (M1) Mac. The error indicates that the _evaluator.cpython-38-darwin.so binary is compiled for x86_64, but my system requires arm64 or arm64e. This issue seems to have been discussed between @jimenofonseca and @reyery here: #3120. I however do not see a clear resolution. To Reproduce Steps to reproduce the behavior:

  1. Download CEA Developer Version on a M1 Mac
  2. Create a scenario using the GUI
  3. Run all the necessary modules
  4. Run the Thermal Network (part II)
  5. See error

Logs

Job Output for 2 - thermal-network
Traceback (most recent call last):
  File "/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/wntr/sim/aml/evaluator.py", line 14, in swig_import_helper
    return importlib.import_module(mname)
  File "/Users/louis/micromamba/envs/cea/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 657, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 556, in module_from_spec
  File "<frozen importlib._bootstrap_external>", line 1166, in create_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
ImportError: dlopen(/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/wntr/sim/aml/_evaluator.cpython-38-darwin.so, 0x0002): tried: '/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/wntr/sim/aml/_evaluator.cpython-38-darwin.so' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64')), '/System/Volumes/Preboot/Cryptexes/OS/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/wntr/sim/aml/_evaluator.cpython-38-darwin.so' (no such file), '/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/wntr/sim/aml/_evaluator.cpython-38-darwin.so' (mach-o file, but is an incompatible architecture (have 'x86_64', need 'arm64e' or 'arm64'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/worker.py", line 146, in worker
    run_job(config, job, server)
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/worker.py", line 108, in run_job
    script(config=config, **parameters)
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/api.py", line 60, in __call__
    self._runner.__call__(*args, **kwargs)
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/api.py", line 65, in __getattribute__
    self._runner = script_wrapper(self._cea_script)
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/api.py", line 16, in script_wrapper
    script_module = importlib.import_module(module_path)
  File "/Users/louis/micromamba/envs/cea/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 1014, in _gcd_import
  File "<frozen importlib._bootstrap>", line 991, in _find_and_load
  File "<frozen importlib._bootstrap>", line 975, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 671, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 843, in exec_module
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/technologies/thermal_network/thermal_network.py", line 28, in <module>
    from cea.technologies.thermal_network.simplified_thermal_network import thermal_network_simplified
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/technologies/thermal_network/simplified_thermal_network.py", line 9, in <module>
    import wntr
  File "/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/wntr/__init__.py", line 3, in <module>
    from wntr import morph
  File "/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/wntr/morph/__init__.py", line 13, in <module>
    from wntr.morph.skel import skeletonize
  File "/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/wntr/morph/skel.py", line 11, in <module>
    from wntr.sim.core import WNTRSimulator
  File "/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/wntr/sim/__init__.py", line 5, in <module>
    from wntr.sim.core import WaterNetworkSimulator, WNTRSimulator
  File "/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/wntr/sim/core.py", line 1, in <module>
    import wntr.sim.hydraulics
  File "/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/wntr/sim/hydraulics.py", line 14, in <module>
    from wntr.sim import aml
  File "/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/wntr/sim/aml/__init__.py", line 2, in <module>
    from .aml import Model, ParamDict, VarDict, ConstraintDict, Constraint
  File "/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/wntr/sim/aml/aml.py", line 3, in <module>
    from .evaluator import Evaluator
  File "/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/wntr/sim/aml/evaluator.py", line 17, in <module>
    _evaluator = swig_import_helper()
  File "/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/wntr/sim/aml/evaluator.py", line 16, in swig_import_helper
    return importlib.import_module('_evaluator')
  File "/Users/louis/micromamba/envs/cea/lib/python3.8/importlib/__init__.py", line 127, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
ModuleNotFoundError: No module named '_evaluator'

Hardware (please complete the following information):

reyery commented 4 months ago

Hi @ldrame21, thank you for reporting this issue.

Can I confirm if you installed it using the steps found in the docs here (https://city-energy-analyst.readthedocs.io/en/latest/installation/installation-on-macos.html#developer-version)?

ldrame21 commented 4 months ago

Hi @reyery, yes I did. Looking at this issue on the wrnt github, it seems that they have maybe not released a version for arm64 processor yet: https://github.com/USEPA/WNTR/issues/331

I've tried to create a new separate environment with this wntr library and then import it in a python script, the same error occurred. However, when done with a Rosetta terminal the error disappears.

I therefore reinstalled everything (brew, micromamba, cea etc.) via a Rosetta terminal and it fixed the issue. Even brew needs to be reinstalled otherwise when doing brew install micromamba, an arm64 version of micromamba will be downloaded. If someone needs to do the same, be careful with the path settings for micromamba and brew as they are different installations than the one that are used to download arm64 software on your mac. I would recommend creating a separate .bash file specifically for this rosetta installation.

I however now have an unrelated error when running this thermal network simulation and maybe you can help me with that. It says that Ths_sys_sup_ahu_C is not in the DataFrame and I see that there's a FIXME comment in the code. Do you have any idea what could cause this error ?

Error

Job Output for 67 - thermal-network
City Energy Analyst version 3.37.1
Running `cea thermal-network` with the following parameters:
- general:scenario = /Users/louis/Desktop/EPFL/Thesis/Github/CEA/cea/AMS_OOST/gva
  (default: {general:project}/{general:scenario-name})
- general:multiprocessing = True
  (default: True)
- general:number-of-cpus-to-keep-free = 1
  (default: 1)
- thermal-network:network-type = DH
  (default: DH)
- thermal-network:network-model = simplified
  (default: simplified)
- thermal-network:min-head-substation = 20.0
  (default: 20.0)
- thermal-network:hw-friction-coefficient = 100
  (default: 100)
- thermal-network:peak-load-velocity = 2.0
  (default: 2.0)
- thermal-network:equivalent-length-factor = 0.2
  (default: 0.2)
- thermal-network:peak-load-percentage = 100.0
  (default: 100.0)
- thermal-network:network-names = []
  (default: [])
- thermal-network:set-diameter = True
  (default: True)
- thermal-network:load-max-edge-flowrate-from-previous-run = False
  (default: False)
- thermal-network:start-t = 0
  (default: 0)
- thermal-network:stop-t = 8760
  (default: 8760)
- thermal-network:use-representative-week-per-month = False
  (default: False)
- thermal-network:minimum-mass-flow-iteration-limit = 30
  (default: 30)
- thermal-network:minimum-edge-mass-flow = 0.1
  (default: 0.1)
- thermal-network:diameter-iteration-limit = 10
  (default: 10)
- thermal-network:substation-cooling-systems = ['ahu', 'aru', 'scu']
  (default: ['ahu', 'aru', 'scu'])
- thermal-network:substation-heating-systems = ['ahu', 'aru', 'shu', 'ww']
  (default: ['ahu', 'aru', 'shu', 'ww'])
- thermal-network:temperature-control = VT
  (default: VT)
- thermal-network:plant-supply-temperature = 80.0
  (default: 80.0)
- thermal-network-optimization:use-representative-week-per-month = False
  (default: False)
Traceback (most recent call last):
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/worker.py", line 146, in worker
    run_job(config, job, server)
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/worker.py", line 108, in run_job
    script(config=config, **parameters)
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/api.py", line 60, in __call__
    self._runner.__call__(*args, **kwargs)
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/api.py", line 38, in script_runner
    script_module.main(config)
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/technologies/thermal_network/thermal_network.py", line 3443, in main
    thermal_network_simplified(locator, config, network_name)
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/technologies/thermal_network/simplified_thermal_network.py", line 195, in thermal_network_simplified
    substation.substation_main_heating(locator, total_demand, building_names, DHN_barcode=DHN_barcode)
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/technologies/substation.py", line 64, in substation_main_heating
    Ths_supply_C, Ths_return_C = calc_temp_hex_building_side_heating(substation_demand, heating_configuration)
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/technologies/substation.py", line 85, in calc_temp_hex_building_side_heating
    Ths_return, Ths_supply = calc_compound_Ths(building_demand_df, heating_configuration)
  File "/Users/louis/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst/cea/technologies/substation.py", line 380, in calc_compound_Ths
    Ths_ahu_supply = building_demand_df.Ths_sys_sup_ahu_C.values  # FIXME: it's the best to have nan when there is no demand
  File "/Users/louis/micromamba/envs/cea/lib/python3.8/site-packages/pandas/core/generic.py", line 5989, in __getattr__
    return object.__getattribute__(self, name)
AttributeError: 'DataFrame' object has no attribute 'Ths_sys_sup_ahu_C'
ldrame21 commented 4 months ago

I found the error, here's the solution:

When the Demand Forecasting/Building Energy Demand job is done monthly, Temparature values are not stored in the output dataframe. Therefore, if one wants to do Thermal Network or Supply System optimization, demand must be computed hourly.

reyery commented 4 months ago

Looking at this issue on the wrnt github, it seems that they have maybe not released a version for arm64 processor yet: https://github.com/USEPA/WNTR/issues/331

We actually built and included the arm64 binaries required for wntr to work, within the source code of CEA (https://github.com/architecture-building-systems/CityEnergyAnalyst/tree/master/cea/lib). It is automatically loaded when it detects that the machine is using the M series processors for Mac. I personally use a M1 Macbook to develop CEA as well. I tried reinstalling it again on my machine and was still able to run thermal-network without any issues.

CEA uses this logic to decide when to apply this "fix"

if sys.platform == "darwin" and platform.processor() == "arm":

My guess is that maybe there was some PATH variable issue or something similar, where the python interpreter that you were using was the x86 version. Would it be possible for you to check by running the following command in the activated cea environment, to see if it is indeed "arm" or something similar (mine shows "arm"). Maybe for yours it gave "arm64", and that could be something we can change.

python -c "import platform; print(platform.processor())"

The newer wntr versions do include binaries for arm64 in their source code. But after testing, the results were wildly different than the version we are using (0.2.3) for CEA. We do not have the resources to investigate the differences for now so this separate loading of binaries is a workaround.

ldrame21 commented 4 months ago

Thank you for your answer @reyery. Indeed, I just checked even in my base environment, my python command is using x86 processor instead of arm. It's because my Homebrew ARM64 path variable was overridden by an Anaconda python executable using x86... As the thing is working now with Rosetta, I will continue like that. I will try again when I have time and update you on this post.

Best, Louis

ldrame21 commented 4 months ago

Update The problem is fixed but it doesn't work on my pycharm terminal as it is not using the right processor for some reason:

` ~/Desktop/EPFL/Thesis/Github/CEA/CityEnergyAnalyst master !3 ?9 ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 02:45:56 PM

python -c "import sys; print(sys.platform); import platform; print(platform.processor())" darwin i386 ` while it is when I'm using my normal terminal. It must be a problem with the pycharm interpreter but I will just use my normal terminal.

Thanks for your help!

reyery commented 3 months ago

Closing since it seems that the issue has been resolved. Let me know if there are any more issue.