Vous avez reçu un message "Your GitLab account has been locked ..." ? Pas d'inquiétude : lisez cet article https://docs.gricad-pages.univ-grenoble-alpes.fr/help/unlock/

Commit e18e8a2c authored by EXT José Ignacio Requeno Jarabo's avatar EXT José Ignacio Requeno Jarabo
Browse files

Bugfix of OracleMatlab (parallel version)

parent 78c9d7a0
......@@ -63,4 +63,8 @@ test:
- cd dist/
- pip install *.whl --user
- cd ../Tests
- ./coverage_all.sh
\ No newline at end of file
- ./coverage_all.sh
artifacts:
when: on_success
paths:
- coverage/report-python/*
\ No newline at end of file
......@@ -31,9 +31,9 @@ class OracleMatlab(Oracle):
Oracle.__init__(self)
# Initialize the Matlab Engine
self.out = get_stdout_matlab()
self.err = get_stderr_matlab()
self.eng = matlab.engine.start_matlab()
self.out = None
self.err = None
self.eng = None
# Matlab function 'f' not loaded yet.
# Dimension of the space unknown
......@@ -42,12 +42,28 @@ class OracleMatlab(Oracle):
self.matlab_model_file = matlab_model_file
def _lazy_init(self):
def _load_matlab_engine(self):
# type: (OracleMatlab) -> None
assert self.matlab_model_file != ''
# Lazy initialization of the OracleMatlab
RootOracle.logger.debug('Initializing OracleMatlab')
# Lazy initialization of the Matlab engine
RootOracle.logger.debug('Initializing Matlab engine')
self.out = get_stdout_matlab()
self.err = get_stderr_matlab()
self.eng = matlab.engine.start_matlab()
RootOracle.logger.debug('Matlab engine {0}'.format(self.eng))
def _load_function(self):
# type: (OracleMatlab) -> None
assert self.matlab_model_file != '', 'Matlab function not defined'
# assert self.eng is not None, 'Matlab engine not started'
RootOracle.logger.debug('Loading Matlab function')
if self.eng is None:
self._load_matlab_engine()
# Include the path of the Matlab model in the Matlab workspace
self.eng.addpath(os.path.dirname(self.matlab_model_file))
......@@ -73,6 +89,7 @@ class OracleMatlab(Oracle):
self.d = int(self.eng.nargin(func_name))
RootOracle.logger.debug('Function {0} with {1} parameters'.format(func_name, self.d))
RootOracle.logger.debug('Matlab function {0}'.format(self.f))
def __setattr__(self, name, value):
# type: (OracleMatlab, str, None) -> None
......@@ -97,7 +114,8 @@ class OracleMatlab(Oracle):
str_matlab_file = 'matlab_model_file'
if (name == str_matlab_file) and (value.strip() != ''):
self._lazy_init()
self.f = None
self.d = None
def __repr__(self):
# type: (OracleMatlab) -> str
......@@ -147,6 +165,7 @@ class OracleMatlab(Oracle):
"""
other = copy.copy(self)
"""
RootOracle.logger.debug('__copy__: {0}'.format(self))
return OracleMatlab(matlab_model_file=self.matlab_model_file)
def __deepcopy__(self, memo):
......@@ -155,9 +174,40 @@ class OracleMatlab(Oracle):
other = copy.deepcopy(self)
"""
# deepcopy function is required for creating multiple instances of the Oracle in ParSearch.
# deepcopy cannot handle neither regex nor Popen processes
# deepcopy cannot handle neither matlab.engine nor matlab.func
RootOracle.logger.debug('__deeopcopy__: {0}'.format(self))
return OracleMatlab(matlab_model_file=self.matlab_model_file)
def __getattr__(self, name):
# type: (OracleMatlab, str) -> _
"""
Returns:
self.name (object attribute)
"""
elem = object.__getattribute__(self, name)
if (elem is None) and (name in ['f', 'd']):
self._load_function()
elem = object.__getattribute__(self, name)
# elif (elem is None) and (name == 'eng'):
# self._load_matlab_engine()
# elem = object.__getattribute__(self, name)
RootOracle.logger.debug('__getattr__: {0}, {1}'.format(name, elem))
return elem
def __getattribute__(self, name):
# type: (OracleMatlab, str) -> _
"""
Returns:
self.name (object attribute)
"""
elem = object.__getattribute__(self, name)
RootOracle.logger.debug('__getattribute__: {0}, {1}'.format(name, elem))
if elem is None:
raise AttributeError
return elem
def dim(self):
# type: (OracleMatlab) -> int
"""
......@@ -210,7 +260,7 @@ class OracleMatlab(Oracle):
if not os.path.isfile(matlab_model_file):
RootOracle.logger.info('File {0} does not exists or it is not a file'.format(matlab_model_file))
self.__init__(matlab_model_file=matlab_model_file)
self.matlab_model_file = matlab_model_file
except EOFError:
RootOracle.logger.error('Unexpected error when loading {0}: {1}'.format(finput, sys.exc_info()[0]))
......@@ -226,7 +276,7 @@ class OracleMatlab(Oracle):
# The file contains the path to the Matlab file containing the parametrized model.
#
# os.path.join creates absolute path from relative path "./something.txt"
# os.path.realpath uniforms path "2D/./signal.csv" by "2D/signal.csv"
# os.path.realpath uniforms path "2D/./test.m" by "2D/test.m"
#
current_path = os.path.dirname(os.path.abspath(finput.name))
path = finput.readline().strip(' \n\t')
......@@ -236,7 +286,7 @@ class OracleMatlab(Oracle):
if not os.path.isfile(matlab_model_file):
RootOracle.logger.info('File {0} does not exists or it is not a file'.format(matlab_model_file))
self.__init__(matlab_model_file=matlab_model_file)
self.matlab_model_file = matlab_model_file
except EOFError:
RootOracle.logger.error('Unexpected error when loading {0}: {1}'.format(finput, sys.exc_info()[0]))
......
......@@ -197,7 +197,7 @@ class OracleSTLe(Oracle):
"""
elem = object.__getattribute__(self, name)
if elem is None:
RootOracle.logger.debug('Initializing OracleSTLe')
RootOracle.logger.debug('Initializing Oracle')
self._lazy_init()
elem = object.__getattribute__(self, name)
RootOracle.logger.debug('Initialized Oracle')
......
......@@ -209,8 +209,9 @@ def multidim_search_deep_first_opt_3(xspace,
# 'f = oracle.membership()' is not thread safe!
# Create a copy of 'oracle' for each concurrent process
# dict_man = {proc: copy.deepcopy(oracle) for proc in mp.active_children()}
# dict_man = {proc.name: copy.deepcopy(oracle) for proc in mp.active_children()}
for proc in mp.active_children():
RootSearch.logger.debug('cloning: {0}'.format(oracle))
dict_man[proc.name] = copy.deepcopy(oracle)
RootSearch.logger.debug('xspace: {0}'.format(xspace))
......@@ -457,8 +458,9 @@ def multidim_search_deep_first_opt_2(xspace,
# 'f = oracle.membership()' is not thread safe!
# Create a copy of 'oracle' for each concurrent process
# dict_man = {proc: copy.deepcopy(oracle) for proc in mp.active_children()}
# dict_man = {proc.name: copy.deepcopy(oracle) for proc in mp.active_children()}
for proc in mp.active_children():
RootSearch.logger.debug('cloning: {0}'.format(oracle))
dict_man[proc.name] = copy.deepcopy(oracle)
RootSearch.logger.debug('xspace: {0}'.format(xspace))
......@@ -678,8 +680,9 @@ def multidim_search_deep_first_opt_1(xspace,
# 'f = oracle.membership()' is not thread safe!
# Create a copy of 'oracle' for each concurrent process
# dict_man = {proc: copy.deepcopy(oracle) for proc in mp.active_children()}
# dict_man = {proc.name: copy.deepcopy(oracle) for proc in mp.active_children()}
for proc in mp.active_children():
RootSearch.logger.debug('cloning: {0}'.format(oracle))
dict_man[proc.name] = copy.deepcopy(oracle)
RootSearch.logger.debug('xspace: {0}'.format(xspace))
......@@ -896,8 +899,9 @@ def multidim_search_deep_first_opt_inf(xspace,
# 'f = oracle.membership()' is not thread safe!
# Create a copy of 'oracle' for each concurrent process
# dict_man = {proc: copy.deepcopy(oracle) for proc in mp.active_children()}
# dict_man = {proc.name: copy.deepcopy(oracle) for proc in mp.active_children()}
for proc in mp.active_children():
RootSearch.logger.debug('cloning: {0}'.format(oracle))
dict_man[proc.name] = copy.deepcopy(oracle)
RootSearch.logger.debug('xspace: {0}'.format(xspace))
......@@ -1083,8 +1087,9 @@ def multidim_search_deep_first_opt_0(xspace,
# 'f = oracle.membership()' is not thread safe!
# Create a copy of 'oracle' for each concurrent process
# dict_man = {proc: copy.deepcopy(oracle) for proc in mp.active_children()}
# dict_man = {proc.name: copy.deepcopy(oracle) for proc in mp.active_children()}
for proc in mp.active_children():
RootSearch.logger.debug('cloning: {0}'.format(oracle))
dict_man[proc.name] = copy.deepcopy(oracle)
RootSearch.logger.debug('xspace: {0}'.format(xspace))
......
#!/usr/bin/env bash
export MATLAB_INSTALLED=$(python -c 'import matlab')
coverage run -m --parallel-mode pytest test_Oracle_OraclePoint.py
coverage run -m --parallel-mode pytest test_Oracle_OracleFunction.py
coverage run -m --parallel-mode pytest test_Oracle_OracleSTL.py
coverage run -m --parallel-mode pytest test_Oracle_OracleSTLe.py
if [ ! $MATLAB_INSTALLED ]
then
coverage run -m --parallel-mode pytest test_Oracle_OracleMatlab.py
fi
coverage run -m --parallel-mode pytest test_Geometry_Point.py
coverage run -m --parallel-mode pytest test_Geometry_Rectangle.py
coverage run -m --parallel-mode pytest test_Geometry_Segment.py
......@@ -19,7 +24,13 @@ coverage run -m --parallel-mode --concurrency=multiprocessing pytest test_Search
coverage run -m --parallel-mode --concurrency=multiprocessing pytest test_Search.py::SearchOracleSTLTestCase::test_1D
#coverage run -m --parallel-mode --concurrency=multiprocessing pytest test_Search.py::SearchOracleSTLTestCase::test_2D
#coverage run -m --parallel-mode --concurrency=multiprocessing pytest test_Search.py
if [ ! $MATLAB_INSTALLED ]
then
coverage2 run -m --parallel-mode --concurrency=multiprocessing pytest test_Search.py::SearchOracleMatlabTestCase::test_2D
coverage run -m --parallel-mode --concurrency=multiprocessing pytest test_Search.py::SearchOracleMatlabTestCase::test_3D
coverage run -m --parallel-mode --concurrency=multiprocessing pytest test_Search.py::SearchOracleMatlabTestCase::test_ND
fi
coverage combine
coverage report --omit=*ParetoLib/_py3k*
#coverage html -d coverage/report-python
coverage html -d coverage/report-python
coverage erase
\ No newline at end of file
......@@ -8,6 +8,7 @@ import pytest
from ParetoLib.Search.Search import Search2D, Search3D, SearchND
from ParetoLib.Search.ResultSet import ResultSet
from ParetoLib.Oracle.OracleMatlab import OracleMatlab
from ParetoLib.Oracle.OracleFunction import OracleFunction
from ParetoLib.Oracle.OraclePoint import OraclePoint
from ParetoLib.Oracle.OracleSTL import OracleSTL
......@@ -197,6 +198,20 @@ class SearchOracleFunctionTestCase(SearchTestCase):
self.search_verify_ND(human_readable=True, list_test_files=list_test_files)
class SearchOracleMatlabTestCase(SearchOracleFunctionTestCase):
def setUp(self):
# type: (SearchOracleMatlabTestCase) -> None
super(SearchOracleMatlabTestCase, self).setUp()
self.this_dir = 'Oracle/OracleMatlab'
self.oracle = OracleMatlab()
# OracleFunction/[2|3]D/test3.txt contains '1/x', so x > 0
self.min_c = 0.0001
# OracleFunction/[2|3]D/test[3|4|5].txt requires max_c > 1.0 for reaching y_up
self.max_c = 2.0
class SearchOraclePointTestCase(SearchTestCase):
def setUp(self):
......
To install the engine API, choose one of the following.
At a Windows operating system prompt —
cd "matlabroot\extern\engines\python"
python setup.py install
You might need administrator privileges to execute these commands.
At a macOS or Linux operating system prompt —
cd "matlabroot/extern/engines/python"
python setup.py install
You might need administrator privileges to execute these commands.
At the MATLAB command prompt —
cd (fullfile(matlabroot,'extern','engines','python'))
system('python setup.py install')
Use one of the nondefault options described in Install MATLAB Engine API for Python in Nondefault Locations.
Note
You must call this python command in the specified folder.
\ No newline at end of file
Start Python, import the module, and start the MATLAB engine:
import matlab.engine
eng = matlab.engine.start_matlab()
Stop Engine
Call either the exit or the quit function.
eng.quit()
If you exit Python with an engine still running, then Python automatically stops the engine and its MATLAB process.
Start Engine with Startup Options
Start the engine and pass the options as an input argument string to matlab.engine.start_matlab. For example, start MATLAB with the desktop.
eng = matlab.engine.start_matlab("-desktop")
You can define multiple startup options with a single string. For example, start the desktop and set the numeric display format to short.
eng = matlab.engine.start_matlab("-desktop -r 'format short'")
You also can start the desktop after you start the engine.
import matlab.engine
eng = matlab.engine.start_matlab()
eng.desktop(nargout=0)
Start Engine Asynchronously
Start the engine asynchronously. While MATLAB starts, you can enter commands at the Python command line.
import matlab.engine
future = matlab.engine.start_matlab(background=True)
Create the MATLAB instance so you can perform computations in MATLAB.
eng = future.result()
\ No newline at end of file
......@@ -200,7 +200,6 @@ setup_args = {'name': 'ParetoLib',
'ParetoLib.Oracle',
'ParetoLib.Search',
'ParetoLib.STLe',
'ParetoLib.Matlab',
'ParetoLib._py3k'],
'package_data': {'ParetoLib.JAMT': ['*.jar'],
'ParetoLib.STLe': ['*.bin', '*.exe', '*.so.1', '*.dll']},
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment