diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index bd576c0..f361d22 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,6 +9,7 @@ on: jobs: manylinux_build: + # build wheels for some linux name: Build linux ${{ matrix.python.name }} wheel runs-on: ubuntu-latest container: quay.io/pypa/manylinux2014_x86_64 @@ -44,7 +45,7 @@ jobs: steps: - name: Checkout sources - uses: actions/checkout@v1 + uses: actions/checkout@v3 with: submodules: true @@ -65,6 +66,10 @@ jobs: python3 setup.py bdist_wheel auditwheel repair dist/*.whl + - name: Build source archive + if: matrix.python.name == 'cp311' + run: python setup.py sdist + - name: Install wheel run: pip3 install wheelhouse/*.whl --user @@ -85,25 +90,24 @@ jobs: python3 -c "from lightsim2grid import LightSimBackend; import grid2op; env = grid2op.make('l2rpn_case14_sandbox', test=True, backend=LightSimBackend())" - name: Upload wheel - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: lightsim2grid-wheel-linux-${{ matrix.python.name }} path: wheelhouse/*.whl - macos_windows_build: - name: Build ${{ matrix.config.name }} ${{ matrix.python.name }} wheel - runs-on: ${{ matrix.config.os }} + - name: Upload source archive + uses: actions/upload-artifact@v3 + if: matrix.python.name == 'cp311' + with: + name: lightsim2grid-sources + path: dist/*.tar.gz + + windows_build: + # build wheels for windows + name: Build windows ${{ matrix.python.name }} wheel + runs-on: windows-2019 strategy: matrix: - config: - - { - name: darwin, - os: macos-latest, - } - - { - name: windows, - os: windows-2019, - } python: - { name: cp37, @@ -125,16 +129,19 @@ jobs: name: cp311, version: '3.11', } + env: + RUNNER_OS: windows-2019 + PYTHON_VERSION: ${{ matrix.python.version }} steps: - name: Checkout sources - uses: actions/checkout@v1 + uses: actions/checkout@v3 with: submodules: true - name: Setup Python - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: ${{ matrix.python.version }} @@ -143,15 +150,7 @@ jobs: python -m pip install --upgrade pip python -m pip install -r requirements.txt - - name: Compile SuiteSparse make - if: matrix.config.name == 'darwin' - run: | - make - export __O3_OPTIM=1 - python3 setup.py build - - name: Compile SuiteSparse cmake - if: matrix.config.name == 'windows' run: | cd build_cmake python generate_c_files.py @@ -168,10 +167,6 @@ jobs: - name: Build wheel run: python setup.py bdist_wheel - - name: Build source archive - if: matrix.config.name == 'darwin' && matrix.python.name == 'cp39' - run: python setup.py sdist - - name: Install wheel shell: bash run: python -m pip install dist/*.whl --user @@ -189,31 +184,151 @@ jobs: python -c "from lightsim2grid import LightSimBackend; import grid2op; env = grid2op.make('l2rpn_case14_sandbox', test=True, backend=LightSimBackend())" - name: Upload wheel - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: lightsim2grid-wheel-${{ matrix.config.name }}-${{ matrix.python.name }} path: dist/*.whl - - name: Upload source archive - uses: actions/upload-artifact@v2 - if: matrix.config.name == 'darwin' && matrix.python.name == 'cp39' + macos_build_37: + # build wheel for python 3.7 for macos + name: Build macos ${{ matrix.python.name }} wheel + runs-on: macos-latest + strategy: + matrix: + python: + - { + name: cp37, + version: '3.7', + } + steps: + - name: Checkout sources + uses: actions/checkout@v3 with: - name: lightsim2grid-sources - path: dist/*.tar.gz + submodules: true + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python.version }} + + - name: Install Python dependencies + run: | + python -m pip install --upgrade pip + python -m pip install -r requirements.txt + + - name: Compile SuiteSparse make + run: | + make + export __O3_OPTIM=1 + python3 setup.py build + + - name: Build wheel + run: python setup.py bdist_wheel + + - name: Install wheel + shell: bash + run: python -m pip install dist/*.whl --user + + - name: Check package can be imported + run: | + python -c "import lightsim2grid" + python -c "from lightsim2grid import *" + python -c "from lightsim2grid.newtonpf import newtonpf" + + - name: Check LightSimBackend can be imported + run: | + python -m pip install grid2op + python -c "from lightsim2grid import LightSimBackend" + python -c "from lightsim2grid import LightSimBackend; import grid2op; env = grid2op.make('l2rpn_case14_sandbox', test=True, backend=LightSimBackend())" + + - name: Upload wheel + uses: actions/upload-artifact@v3 + with: + name: lightsim2grid-wheel-darwin-${{ matrix.python.name }} + path: dist/*.whl + + macos_build_38_: + # build wheel for python 3.8 and above for macos + name: Build darwin ${{ matrix.python.name }} wheel + runs-on: macos-latest + strategy: + matrix: + python: + - { + name: cp38, + version: '3.8', + } + - { + name: cp39, + version: '3.9', + } + - { + name: cp310, + version: '3.10', + } + - { + name: cp311, + version: '3.11', + } + env: + RUNNER_OS: macos-latest + PYTHON_VERSION: ${{ matrix.python.version }} + + steps: + + - name: Checkout sources + uses: actions/checkout@v3 + with: + submodules: true + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python.version }} + + - name: Set Additional Envs + shell: bash + run: | + echo "PYTHON_SUBVERSION=$(echo $PYTHON_VERSION | cut -c 3-)" >> $GITHUB_ENV + echo "DEPLOY=$( [[ $GITHUB_EVENT_NAME == 'push' && $GITHUB_REF == 'refs/tags'* ]] && echo 'True' || echo 'False' )" >> $GITHUB_ENV + + - name: Compile with cibuildwheel + uses: pypa/cibuildwheel@v2.15.0 + env: + CIBW_BUILD: "cp3${{env.PYTHON_SUBVERSION}}-*" # see https://github.com/cvxpy/cvxpy/blob/master/.github/workflows/build.yml + CIBW_ARCHS_LINUX: auto aarch64 # not used I believe + CIBW_ARCHS_MACOS: x86_64 arm64 + CIBW_ENVIRONMENT: __O3_OPTIM=1 + CIBW_BEFORE_BUILD: make clean && make # and not CIBW_BEFORE_ALL ! + CIBW_TEST_REQUIRES: grid2op pandapower + CIBW_TEST_SKIP: "*-macosx_arm64" # to silence warning "While arm64 wheels can be built on x86_64, they cannot be tested." + CIBW_TEST_COMMAND: > + python -c "import lightsim2grid" && + python -c "from lightsim2grid import *" && + python -c "from lightsim2grid.newtonpf import newtonpf" && + python -c "from lightsim2grid.solver import KLUSolver" && + python -c "from lightsim2grid import LightSimBackend" && + python -c "from lightsim2grid import LightSimBackend; import grid2op; env = grid2op.make('l2rpn_case14_sandbox', test=True, backend=LightSimBackend())" + + - name: Upload wheel + uses: actions/upload-artifact@v3 + with: + name: wheels-darwin-${{ matrix.python.name }} + path: ./wheelhouse/*.whl package: name: Package wheels runs-on: ubuntu-latest - needs: [manylinux_build, macos_windows_build] + needs: [manylinux_build, windows_build, macos_build_37, macos_build_38_] steps: - name: Download wheels - uses: actions/download-artifact@v2 + uses: actions/download-artifact@v3 with: path: download - name: Upload wheels - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v3 with: name: lightsim2grid-wheels path: | diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 7ea2691..bda46b0 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -19,12 +19,16 @@ Change Log - easier building (get rid of the "make" part) - code NR with dense matrices -[0.7.3] 2023-07-xx +[0.7.3] 2023-08-24 -------------------- - [FIXED] a bug where, when you disconnect a load (or gen), the next action cannot be performed if it modifies the load (or gen), because you "cannot change the value of a disconnected load (or gen)" +- [FIXED] read-the-docs template is not compatible with latest sphinx version (7.0.0) + see https://github.com/readthedocs/sphinx_rtd_theme/issues/1463 - [IMPROVED] initialize the underlying "PandaPowerBackend" without numba -- [IMPROVED] grid2op import to be more compliant with renaming of +- [IMPROVED] grid2op import to be more compliant with renaming of uppercased file names +- [IMPROVED] decoupling of the PandapowerBackend class and the class "internally" used by LightSimBackend + when loading the grid. This caused some issue, *eg* https://github.com/rte-france/Grid2Op/issues/508 [0.7.2] 2023-06-06 -------------------- diff --git a/README.md b/README.md index b94f0c2..57cb87d 100644 --- a/README.md +++ b/README.md @@ -85,6 +85,10 @@ Pypi packages are available for linux, windows and macos with python versions: - 3.8 - 3.9 - 3.10 (lightsim2grid >= 0.6.1) +- 3.11 (lightsim2grid >= 0.7.1) + +**NB** on some version of MacOs (thanks Apple !), especially the one using M1 or M2 chip, lightsim2grid is only available +on pypi starting from version 0.7.3 ## Installation (from source, for more advanced user) diff --git a/docs/conf.py b/docs/conf.py index 62b0f0d..8b64a4f 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,7 @@ author = 'Benjamin DONNOT' # The full version, including alpha/beta/rc tags -release = "0.7.3" +release = "0.7.4" version = '0.7' # -- General configuration --------------------------------------------------- diff --git a/lightsim2grid/__init__.py b/lightsim2grid/__init__.py index c99bdce..f7d6d89 100644 --- a/lightsim2grid/__init__.py +++ b/lightsim2grid/__init__.py @@ -9,7 +9,7 @@ import faulthandler faulthandler.enable() -__version__ = "0.7.3" +__version__ = "0.7.4" __all__ = ["newtonpf", "SolverType", "ErrorType", "solver"] diff --git a/lightsim2grid/_utils/__init__.py b/lightsim2grid/_utils/__init__.py new file mode 100644 index 0000000..a1b43c0 --- /dev/null +++ b/lightsim2grid/_utils/__init__.py @@ -0,0 +1,11 @@ +# this class is defined to avoid circular references when using grid2op -> pandapower -> lightsim2grid -> grid2op +# this module is lazily imported by the LightSimBackend and should not be used anywhere else, +# as the name states +try: + from grid2op.Backend import PandaPowerBackend + class _DoNotUseAnywherePandaPowerBackend(PandaPowerBackend): + """used to duplicate the class attributes of PandaPowerBackend""" + pass +except ImportError as exc_: + # grid2op is not installed, we do not use it. + pass \ No newline at end of file diff --git a/lightsim2grid/lightSimBackend.py b/lightsim2grid/lightSimBackend.py index 3118613..7a0ce86 100644 --- a/lightsim2grid/lightSimBackend.py +++ b/lightsim2grid/lightSimBackend.py @@ -58,7 +58,7 @@ def __init__(self, detailed_infos_for_cascading_failures=detailed_infos_for_cascading_failures) # lazy loading because it crashes... - from grid2op.Backend import PandaPowerBackend + from lightsim2grid._utils import _DoNotUseAnywherePandaPowerBackend from grid2op.Space import GridObjects # lazy import self.__has_storage = hasattr(GridObjects, "n_storage") if not self.__has_storage: @@ -84,13 +84,12 @@ def __init__(self, self.topo_vect = None self.shunt_topo_vect = None - try: - self.init_pp_backend = PandaPowerBackend(with_numba=False) + self.init_pp_backend = _DoNotUseAnywherePandaPowerBackend(with_numba=False) except TypeError as exc_: # oldest version of grid2op do not support the kwargs "with_numba" # (before 1.9.1) - self.init_pp_backend = PandaPowerBackend() + self.init_pp_backend = _DoNotUseAnywherePandaPowerBackend() self.V = None self.max_it = max_iter @@ -174,6 +173,22 @@ def __init__(self, # add the static gen to the list of controlable gen in grid2Op self._use_static_gen = use_static_gen # TODO implement it + # storage data for this object (otherwise it's in the class) + self.n_storage = None + self.storage_to_subid = None + self.storage_pu_to_kv = None + self.name_storage = None + self.storage_to_sub_pos = None + self.storage_type = None + self.storage_Emin = None + self.storage_Emax = None + self.storage_max_p_prod = None + self.storage_max_p_absorb = None + self.storage_marginal_cost = None + self.storage_loss = None + self.storage_discharging_efficiency = None + self.storage_charging_efficiency = None + def turnedoff_no_pv(self): self._turned_off_pv = False self._grid.turnedoff_no_pv() @@ -439,7 +454,7 @@ def load_grid(self, path=None, filename=None): self.storage_loss = self.init_pp_backend.storage_loss self.storage_discharging_efficiency = self.init_pp_backend.storage_discharging_efficiency self.storage_charging_efficiency = self.init_pp_backend.storage_charging_efficiency - + self.nb_bus_total = self.init_pp_backend._grid.bus.shape[0] self.thermal_limit_a = copy.deepcopy(self.init_pp_backend.thermal_limit_a) @@ -477,7 +492,7 @@ def load_grid(self, path=None, filename=None): tmp.reshape(-1, 1)), axis=-1) self._big_topo_to_obj = [(None, None) for _ in range(self.dim_topo)] - + self._compute_pos_big_topo() # set up the "lightsim grid" accordingly @@ -591,8 +606,8 @@ def assert_grid_correct_after_powerflow(self): """ # test the results gives the proper size super().assert_grid_correct_after_powerflow() - self.init_pp_backend.__class__ = self.init_pp_backend.init_grid(self) - self._backend_action_class = _BackendAction.init_grid(self) + self.init_pp_backend.__class__ = type(self.init_pp_backend).init_grid(type(self)) + self._backend_action_class = _BackendAction.init_grid(type(self)) self._init_action_to_set = self._backend_action_class() try: # feature added in grid2op 1.4 or 1.5 diff --git a/setup.py b/setup.py index 0359640..2025432 100644 --- a/setup.py +++ b/setup.py @@ -14,7 +14,7 @@ from pybind11.setup_helpers import Pybind11Extension, build_ext -__version__ = "0.7.3" +__version__ = "0.7.4" KLU_SOLVER_AVAILABLE = False # Try to link against SuiteSparse (if available) @@ -327,7 +327,7 @@ "extras": { "docs": [ "numpydoc>=0.9.2", - "sphinx>=2.4.4", + "sphinx>=2.4.4,<7", "sphinx-rtd-theme>=0.4.3", "sphinxcontrib-trio>=1.1.0", "autodocsumm>=0.1.13",