Skip to content
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

Upgrade to Python3.11 + Cython3 #213

Merged
merged 14 commits into from
Jan 25, 2024
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 10 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,15 @@ jobs:
linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: actions/setup-python@v4
with:
python-version: '3.11.x'
- name: Setup Python
run: |
python3 -m pip install Cython numpy scipy matplotlib nose-py3
- name: Install system
run: |
sudo apt-get -y install python3-scipy python3-setuptools python3-nose cython3 python3-matplotlib
sudo apt-get -y install cmake liblapack-dev libsuitesparse-dev libhypre-dev
sudo cp -v /usr/lib/x86_64-linux-gnu/libblas.so /usr/lib/x86_64-linux-gnu/libblas_OPENMP.so
- name: Install superlu
Expand All @@ -35,9 +40,8 @@ jobs:
sudo make install
- name: Install assimulo
run: |
cd /tmp
curl -fSsL https://github.com/modelon-community/Assimulo/archive/Assimulo-3.4.1.tar.gz | tar xz
cd Assimulo-Assimulo-3.4.1
git clone --depth 1 -b dev-pm-python_upgrade https://github.com/modelon-community/Assimulo /tmp/Assimulo
cd /tmp/Assimulo
PeterMeisrimelModelon marked this conversation as resolved.
Show resolved Hide resolved
python3 setup.py install --user --sundials-home=/usr --blas-home=/usr/lib/x86_64-linux-gnu/ --lapack-home=/usr/lib/x86_64-linux-gnu/ --superlu-home=/usr --extra-fortran-compile-flags="-fallow-argument-mismatch"
- name: Install fmilib
run: |
Expand All @@ -55,5 +59,4 @@ jobs:
run: |
rm src/pyfmi/__init__.py
cp -rv src/pyfmi/tests/files tests
nosetests3 tests

python3 -m nose --verbose tests/*
1 change: 1 addition & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
--- PyFMI-NEXT_VERSION ---
* Removed utilities related to the obsolete FMUX model interface.
* Removed no longer required dependency on lxml.
* Upgraded to Cython3.

--- PyFMI-2.11.0 ---
* Refactored result handling for dynamic_diagnostics. It is now possible use dynamic_diagnostics with a custom result handler.
Expand Down
14 changes: 7 additions & 7 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
[options]
setup_requires =
setuptools
numpy >= 1.17
cython >= 0.29.13
numpy >= 1.26.3
cython >= 3.0.7
PeterMeisrimelModelon marked this conversation as resolved.
Show resolved Hide resolved

install_requires =
numpy >= 1.17
scipy >= 1.3
cython >= 0.29.13
nose >= 1.3.7
numpy >= 1.26.3
scipy >= 1.11.4
cython >= 3.0.7
nose-py3 >= 1.6.3
matplotlib > 3
assimulo >= 3.2
assimulo >= 3.5.0
32 changes: 19 additions & 13 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,13 @@
from Cython.Distutils import build_ext
from Cython.Build import cythonize
except ImportError:
raise Exception("Please upgrade to a newer Cython version, >= 0.15.")
raise Exception("Please upgrade to a newer Cython version, >= 3.")


NAME = "PyFMI"
AUTHOR = "Modelon AB"
AUTHOR_EMAIL = ""
VERSION = "3.0-dev"
VERSION = "2.12.0"
LICENSE = "LGPL"
URL = "https://github.com/modelon-community/PyFMI"
DOWNLOAD_URL = "https://github.com/modelon-community/PyFMI/releases"
Expand Down Expand Up @@ -73,7 +73,7 @@
-------------
- `FMI Library (at least 2.0.1) <https://github.com/modelon-community/fmi-library>`_
- `Python-headers (usually included on Windows, python-dev on Ubuntu)`_
- `Python 3.7 or newer`_
- `Python 3.11 or newer`_
- Python package dependencies are listed in file setup.cfg.

Optional
Expand All @@ -90,9 +90,10 @@

copy_args = sys.argv[1:]

if os.getenv("FMIL_HOME"): #Check for if there exists and environment variable that specifies FMIL
incdirs = os.path.join(os.getenv("FMIL_HOME"), 'include')
libdirs = os.path.join(os.getenv("FMIL_HOME"), 'lib')
fmil_home = os.getenv("FMIL_HOME")
if fmil_home: #Check for environment variable that specifies FMIL
incdirs = os.path.join(fmil_home, 'include')
libdirs = os.path.join(fmil_home, 'lib')
else:
incdirs = ""
libdirs = ""
Expand Down Expand Up @@ -153,7 +154,6 @@
debug_flag = False
copy_args.remove(x)


if not incdirs:
raise Exception("FMI Library cannot be found. Please specify its location, either using the flag to the setup script '--fmil-home' or specify it using the environment variable FMIL_HOME.")

Expand Down Expand Up @@ -214,29 +214,35 @@ def check_extensions():
incl_path = [".", "src", os.path.join("src", "pyfmi")]
#FMI PYX
ext_list += cythonize([os.path.join("src", "pyfmi", "fmi.pyx")],
include_path = incl_path)
include_path = incl_path,
compiler_directives={'language_level' : "3str"})

#FMI UTIL
ext_list += cythonize([os.path.join("src", "pyfmi", "fmi_util.pyx")],
include_path = incl_path)
include_path = incl_path,
compiler_directives={'language_level' : "3str"})

#FMI Extended PYX
ext_list += cythonize([os.path.join("src", "pyfmi", "fmi_extended.pyx")],
include_path = incl_path)
include_path = incl_path,
compiler_directives={'language_level' : "3str"})

#FMI Coupled PYX
ext_list += cythonize([os.path.join("src", "pyfmi", "fmi_coupled.pyx")],
include_path = incl_path)
include_path = incl_path,
compiler_directives={'language_level' : "3str"})

#Simulation interface PYX
ext_list += cythonize([os.path.join("src", "pyfmi", "simulation", "assimulo_interface.pyx")],
include_path = incl_path)
include_path = incl_path,
compiler_directives={'language_level' : "3str"})

#MASTER PYX
compile_time_env = {'WITH_OPENMP': with_openmp}
ext_list += cythonize([os.path.join("src", "pyfmi", "master.pyx")],
include_path = incl_path,
compile_time_env=compile_time_env)
compile_time_env=compile_time_env,
compiler_directives={'language_level' : "3str"})

for i in range(len(ext_list)):

Expand Down
4 changes: 2 additions & 2 deletions src/common/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def _exec_algorithm(self, module, algorithm, options):
Exception if algorithm is not a subclass of
common.algorithm_drivers.AlgorithmBase.
"""
from .algorithm_drivers import AlgorithmBase
from pyfmi.algorithm_drivers import AlgorithmBase

if isinstance(algorithm, str):
module = __import__(module, globals(), locals(), [algorithm], 0)
Expand Down Expand Up @@ -182,7 +182,7 @@ def _exec_simulate_algorithm(self,
Exception if algorithm is not a subclass of
common.algorithm_drivers.AlgorithmBase.
"""
from .algorithm_drivers import AlgorithmBase
from pyfmi.algorithm_drivers import AlgorithmBase

if isinstance(algorithm, str):
module = __import__(module, globals(), locals(), [algorithm], 0)
Expand Down
6 changes: 3 additions & 3 deletions src/common/io.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,20 +370,20 @@ class ResultWriter():
Base class for writing results to file.
"""

def write_header():
def write_header(self):
"""
The header is intended to be used for writing general information about
the model. This is intended to be called once.
"""
pass

def write_point():
def write_point(self):
"""
This method does the writing of the actual result.
"""
pass

def write_finalize():
def write_finalize(self):
"""
The finalize method can be used to for instance close the file.
"""
Expand Down
4 changes: 2 additions & 2 deletions src/common/log/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
The log analysis toolkit.
"""

from .parser import parse_xml_log, parse_xml_log, extract_xml_log, parse_fmu_xml_log
from .prettyprinter import prettyprint_to_file
from pyfmi.common.log.parser import parse_xml_log, parse_xml_log, extract_xml_log, parse_fmu_xml_log
from pyfmi.common.log.prettyprinter import prettyprint_to_file

__all__=['parser','tree','prettyprinter']
2 changes: 1 addition & 1 deletion src/common/log/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
import os
import numpy as np
from distutils.util import strtobool
from .tree import *
from pyfmi.common.log.tree import *
from pyfmi.fmi_util import python3_flag
from pyfmi.fmi import FMUException

Expand Down
2 changes: 1 addition & 1 deletion src/common/log/prettyprinter.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"""

from numpy import ndarray
from .tree import *
from pyfmi.common.log.tree import *

def prettyprint(write, node):
"""Prettyprint a log node to the write callback write."""
Expand Down
14 changes: 6 additions & 8 deletions src/pyfmi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
__all__ = ['fmi_algorithm_drivers', 'examples', 'fmi', 'common']

#Import the model class allowing for users to type e.g.,: from pyfmi import FMUModelME1
from .fmi import load_fmu, FMUModelME1, FMUModelME2
from .fmi import FMUModelCS1, FMUModelCS2
from .fmi_coupled import CoupledFMUModelME2
from .master import Master
from .fmi_extended import FMUModelME1Extended
from pyfmi.fmi import load_fmu, FMUModelME1, FMUModelME2
from pyfmi.fmi import FMUModelCS1, FMUModelCS2
from pyfmi.fmi_coupled import CoupledFMUModelME2
from pyfmi.master import Master
from pyfmi.fmi_extended import FMUModelME1Extended
import numpy as N
import os.path
import sys
Expand All @@ -49,7 +49,7 @@ def wrap(func):


try:
curr_dir = os.path.dirname(os.path.abspath(__file__));
curr_dir = os.path.dirname(os.path.abspath(__file__))
_fpath=os.path.join(curr_dir,'version.txt')
with open(_fpath, 'r') as f:
__version__=f.readline().strip()
Expand Down Expand Up @@ -178,5 +178,3 @@ def check_packages():
This package is needed to be able to use the plot-GUI.")

sys.stdout.write("\n\n")


31 changes: 19 additions & 12 deletions src/pyfmi/fmi.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ cimport numpy as N

N.import_array()

cimport fmil_import as FMIL
cimport pyfmi.fmil_import as FMIL

cdef FMIL.fmi_version_enu_t import_and_get_version(FMIL.fmi_import_context_t*, char*, char*, int)

Expand Down Expand Up @@ -116,7 +116,7 @@ cdef class FMUModelBase(ModelBase):
cdef FMIL.jm_callbacks* callbacks_standard

#Internal values
cdef public object __t
cdef public object _t
PeterMeisrimelModelon marked this conversation as resolved.
Show resolved Hide resolved
cdef public object _file_open
cdef public object _npoints
cdef public object _enable_logging
Expand Down Expand Up @@ -158,10 +158,11 @@ cdef class FMUModelME1(FMUModelBase):
cpdef _get_time(self)
cpdef _set_time(self, FMIL.fmi1_real_t t)
cpdef get_derivatives(self)
cdef int __get_nominal_continuous_states(self, FMIL.fmi1_real_t* xnominal, size_t nx)
cdef int _get_nominal_continuous_states_fmil(self, FMIL.fmi1_real_t* xnominal, size_t nx)
cdef public object _preinit_nominal_continuous_states

cdef class __ForTestingFMUModelME1(FMUModelME1):
cdef class _ForTestingFMUModelME1(FMUModelME1):
cdef int _get_nominal_continuous_states_fmil(self, FMIL.fmi1_real_t* xnominal, size_t nx)
cpdef set_allocated_fmu(self, int value)

cdef class FMUModelBase2(ModelBase):
Expand Down Expand Up @@ -190,7 +191,7 @@ cdef class FMUModelBase2(ModelBase):
cdef public list _save_real_variables_val
cdef public list _save_int_variables_val
cdef public list _save_bool_variables_val
cdef object __t
cdef object _t
cdef public object _pyEventInfo
cdef char* _fmu_temp_dir
cdef object _states_references
Expand Down Expand Up @@ -234,9 +235,9 @@ cdef class FMUModelBase2(ModelBase):
cdef int _get_directional_derivative(self, N.ndarray v_ref, N.ndarray z_ref, N.ndarray dv, N.ndarray dz) except -1
cpdef set_real(self, valueref, values)
cpdef N.ndarray get_real(self, valueref)
cdef int __set_real(self, FMIL.fmi2_value_reference_t* vrefs, FMIL.fmi2_real_t* values, size_t size)
cdef int __get_real(self, FMIL.fmi2_value_reference_t* vrefs, size_t size, FMIL.fmi2_real_t* values)
cdef int _get_real(self, FMIL.fmi2_value_reference_t[:] valueref, size_t size, FMIL.fmi2_real_t[:] values)
cdef int _set_real(self, FMIL.fmi2_value_reference_t* vrefs, FMIL.fmi2_real_t* values, size_t size)
cdef int _get_real_by_ptr(self, FMIL.fmi2_value_reference_t* vrefs, size_t size, FMIL.fmi2_real_t* values)
cdef int _get_real_by_list(self, FMIL.fmi2_value_reference_t[:] valueref, size_t size, FMIL.fmi2_real_t[:] values)
cdef int _get_integer(self, FMIL.fmi2_value_reference_t[:] valueref, size_t size, FMIL.fmi2_integer_t[:] values)
cdef int _get_boolean(self, FMIL.fmi2_value_reference_t[:] valueref, size_t size, FMIL.fmi2_real_t[:] values)

Expand All @@ -255,11 +256,11 @@ cdef class FMUModelME2(FMUModelBase2):
cpdef get_derivatives(self)
cdef public object force_finite_differences
cdef int _get_derivatives(self, FMIL.fmi2_real_t[:] values)
cdef int __get_continuous_states(self, FMIL.fmi2_real_t[:] ndx)
cdef int __set_continuous_states(self, FMIL.fmi2_real_t[:] ndx)
cdef int _get_continuous_states_fmil(self, FMIL.fmi2_real_t[:] ndx)
cdef int _set_continuous_states_fmil(self, FMIL.fmi2_real_t[:] ndx)
cdef int _get_event_indicators(self, FMIL.fmi2_real_t[:] values)
cdef int _completed_integrator_step(self, int* enter_event_mode, int* terminate_simulation)
cdef int __get_nominal_continuous_states(self, FMIL.fmi2_real_t* xnominal, size_t nx)
cdef int _get_nominal_continuous_states_fmil(self, FMIL.fmi2_real_t* xnominal, size_t nx)
cdef public object _preinit_nominal_continuous_states

cdef class WorkerClass2:
Expand All @@ -274,5 +275,11 @@ cdef class WorkerClass2:
cdef N.ndarray get_real_numpy_vector(self, int index)
cpdef verify_dimensions(self, int dim)

cdef class __ForTestingFMUModelME2(FMUModelME2):
cdef class _ForTestingFMUModelME2(FMUModelME2):
cdef int _get_real_by_ptr(self, FMIL.fmi2_value_reference_t* vrefs, size_t size, FMIL.fmi2_real_t* values)
cdef int _set_real(self, FMIL.fmi2_value_reference_t* vrefs, FMIL.fmi2_real_t* values, size_t size)
cdef int _get_real_by_list(self, FMIL.fmi2_value_reference_t[:] valueref, size_t size, FMIL.fmi2_real_t[:] values)
cdef int _get_integer(self, FMIL.fmi2_value_reference_t[:] valueref, size_t size, FMIL.fmi2_integer_t[:] values)
cdef int _get_boolean(self, FMIL.fmi2_value_reference_t[:] valueref, size_t size, FMIL.fmi2_real_t[:] values)
cdef int _get_nominal_continuous_states_fmil(self, FMIL.fmi2_real_t* xnominal, size_t nx)
cpdef set_initialized_fmu(self, int value)
Loading