Skip to content

Commit

Permalink
1. Automatically load AOT functions, if failed, load JIT functions in…
Browse files Browse the repository at this point in the history
…stead.
  • Loading branch information
mzy2240 committed Jan 28, 2022
1 parent 991cb30 commit b8cef3a
Show file tree
Hide file tree
Showing 9 changed files with 87 additions and 5 deletions.
2 changes: 1 addition & 1 deletion RELEASE_PROCESS.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ESA.

#. (Optional) If any updates has been made to the ``_performance.py``
then you need to compile the module first by running
``pythran --config compiler.blas=mkl -O3 -ffast-math -DUSE_XSIMD esa/_performance.py -o esa/performance.pyd``.
``compile_for_all_versions.py``.
#. Ensure you have checked out the ``develop`` branch and have a clean
repository (no local changes, new files, etc.).
#. Run all tests for all Python versions (3.5 - 3.8) by running the
Expand Down
44 changes: 44 additions & 0 deletions compile_for_all_versions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
"""Run this script to automatically compile AOT functions for python 3.7, 3.8 and 3.9
"""
import argparse
import os
import subprocess
import shutil



def main():
list_of_envs = []
envs = subprocess.check_output('conda env list').splitlines()[2:-1]
for string in envs:
try:
list_of_envs.append(string.decode("utf-8").split()[0])
except IndexError:
pass
print(list_of_envs)
# print(env_name)

versions = ['37', '38', '39'] # pythran seems to only work in 3.7 3.8 3.9

for ver in versions:
# Create a virtual environment if necessary.
if f"compile{ver}" in list_of_envs:
print(f"No need to create Conda python {ver} env")
else:
subprocess.run(f'conda create -n compile{ver} python={ver[0]}.{ver[1]} -y')
subprocess.run(f'conda activate compile{ver} && conda install -c conda-forge "numpy<1.22" pythran -y', shell=True)

# Compile
compile_statement = f"pythran --config compiler.blas=mkl -O3 -ffast-math -DUSE_XSIMD esa/_performance.py -o esa/performance{ver}.pyd"
subprocess.run(f"conda activate compile{ver} && {compile_statement}", shell=True)
print('DONE!')

print('*' * 80)
print('ALL DONE!')




if __name__ == '__main__':
main()

2 changes: 1 addition & 1 deletion docs/rst/coverage_to_rst.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@

def main():
# Initialize coverage stuff.
cov = Coverage(source=[ESA_DIR], config_file=False, omit=[os.path.join(ESA_DIR, '_performance.py')])
cov = Coverage(source=[ESA_DIR], config_file=False, omit=[os.path.join(ESA_DIR, '_performance.py'), os.path.join(ESA_DIR, '_performance_jit.py')])
cov.start()

# Run tests.
Expand Down
35 changes: 35 additions & 0 deletions esa/_performance_jit.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import numba as nb


@nb.njit
def initialize_bound(bpmax, bpmin, bnmax, bnmin, A):
bp0 = A.copy()
bp1 = A.copy()
bn0 = A.copy()
bn1 = A.copy()
for i in range(len(bpmax)):
bp0[i, :] *= bpmax[i]
bp1[i, :] *= bpmin[i]
bn0[i, :] *= bnmax[i]
bn1[i, :] *= bnmin[i]
Wbuf1 = np.maximum(bp0, bp1)
Wbuf2 = np.maximum(bn0, bn1)
w = np.maximum(Wbuf1+Wbuf1.conj().T, Wbuf2+Wbuf2.conj().T)
return w, Wbuf1, Wbuf2


@nb.njit
def calculate_bound(bp, bn, Amax1, Amin1, Wbuf1, Wbuf2):
bp0 = bp.copy()
bp1 = bp.copy()
bn0 = bn.copy()
bn1 = bn.copy()
for i in range(len(Amax1)):
bp0[:, i] *= Amax1[i]
bp1[:, i] *= Amin1[i]
bn0[:, i] *= Amax1[i]
bn1[:, i] *= Amin1[i]
wb1 = np.maximum(bp0, bp1) + Wbuf1
wb2 = np.maximum(bn0, bn1) + Wbuf2
w = np.maximum(wb1,wb2)
return w
Binary file added esa/performance37.pyd
Binary file not shown.
Binary file modified esa/performance38.pyd
Binary file not shown.
Binary file added esa/performance39.pyd
Binary file not shown.
7 changes: 5 additions & 2 deletions esa/saw.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@
from win32com.client import VARIANT
import tempfile

# Import corresponding compiled functions
# Import corresponding AOT/JIT functions
import platform
PYTHON_VERSION = platform.python_version_tuple()
exec(f"from .performance{PYTHON_VERSION[0]}{PYTHON_VERSION[1]} import initialize_bound, calculate_bound")
if PYTHON_VERSION[1] in ['7', '8', '9']: # pragma: no cover
exec(f"from .performance{PYTHON_VERSION[0]}{PYTHON_VERSION[1]} import initialize_bound, calculate_bound")
else: # pragma: no cover
from ._performance_jit import initialize_bound, calculate_bound


# Before doing anything else, set up the locale. The docs note this is
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
'Automation', 'Power Systems', 'Electric Power', 'Power',
'Easy SimAuto', 'ESA', 'Smart Grid', 'Numpy', 'Pandas'],
install_requires=['pandas >= 0.25', 'numpy >= 1.13.3, <1.22', 'scipy', 'pywin32',
'pypiwin32', 'networkx', 'tqdm', 'numba >= 0.55'],
'pypiwin32', 'networkx', 'tqdm', 'numba'],
python_requires='>=3.5',
# There are a couple tests that use networkx, and we use the magic
# of sphinx for documentation. Coverage is necessary to keep the
Expand Down

0 comments on commit b8cef3a

Please sign in to comment.