Multiclass-interface 1.15__tar.gz → 1.18__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {multiclass_interface-1.15 → multiclass_interface-1.18}/.gitlab-ci.yml +1 -1
- {multiclass_interface-1.15 → multiclass_interface-1.18/Multiclass_interface.egg-info}/PKG-INFO +3 -2
- {multiclass_interface-1.15 → multiclass_interface-1.18}/Multiclass_interface.egg-info/SOURCES.txt +2 -0
- multiclass_interface-1.18/Multiclass_interface.egg-info/scm_file_list.json +19 -0
- multiclass_interface-1.18/Multiclass_interface.egg-info/scm_version.json +8 -0
- {multiclass_interface-1.15/Multiclass_interface.egg-info → multiclass_interface-1.18}/PKG-INFO +3 -2
- {multiclass_interface-1.15 → multiclass_interface-1.18}/multiclass_interface/mpi_interface.py +71 -1
- {multiclass_interface-1.15 → multiclass_interface-1.18}/multiclass_interface/multi_object_list.py +6 -0
- {multiclass_interface-1.15 → multiclass_interface-1.18}/multiclass_interface/multiprocess_interface.py +3 -2
- {multiclass_interface-1.15 → multiclass_interface-1.18}/multiclass_interface/tests/my_test_cls.py +1 -0
- {multiclass_interface-1.15 → multiclass_interface-1.18}/multiclass_interface/tests/test_mpi.py +28 -8
- multiclass_interface-1.18/multiclass_interface/version.py +24 -0
- multiclass_interface-1.15/multiclass_interface/version.py +0 -21
- {multiclass_interface-1.15 → multiclass_interface-1.18}/.gitignore +0 -0
- {multiclass_interface-1.15 → multiclass_interface-1.18}/LICENSE +0 -0
- {multiclass_interface-1.15 → multiclass_interface-1.18}/Multiclass_interface.egg-info/dependency_links.txt +0 -0
- {multiclass_interface-1.15 → multiclass_interface-1.18}/Multiclass_interface.egg-info/requires.txt +0 -0
- {multiclass_interface-1.15 → multiclass_interface-1.18}/Multiclass_interface.egg-info/top_level.txt +0 -0
- {multiclass_interface-1.15 → multiclass_interface-1.18}/README.md +0 -0
- {multiclass_interface-1.15 → multiclass_interface-1.18}/multiclass_interface/__init__.py +0 -0
- {multiclass_interface-1.15 → multiclass_interface-1.18}/multiclass_interface/tests/__init__.py +0 -0
- {multiclass_interface-1.15 → multiclass_interface-1.18}/multiclass_interface/tests/test_multiclass_list.py +0 -0
- {multiclass_interface-1.15 → multiclass_interface-1.18}/multiclass_interface/tests/test_multiprocessinterface.py +0 -0
- {multiclass_interface-1.15 → multiclass_interface-1.18}/pyproject.toml +0 -0
- {multiclass_interface-1.15 → multiclass_interface-1.18}/sequence_diagrams.md +0 -0
- {multiclass_interface-1.15 → multiclass_interface-1.18}/setup.cfg +0 -0
|
@@ -42,7 +42,7 @@ pypi_linux:
|
|
|
42
42
|
#- pip install pypandoc
|
|
43
43
|
- pip install -e . --upgrade
|
|
44
44
|
- pip install --upgrade build
|
|
45
|
-
- pip install twine
|
|
45
|
+
- pip install twine packaging --upgrade
|
|
46
46
|
- python3 -m build
|
|
47
47
|
- twine upload dist/* -u $TWINE_USERNAME -p $TWINE_PASSWORD
|
|
48
48
|
rules:
|
{multiclass_interface-1.15 → multiclass_interface-1.18/Multiclass_interface.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: Multiclass_interface
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.18
|
|
4
4
|
Summary: Multiclass interface
|
|
5
5
|
Author-email: "Mads M. Pedersen" <mmpe@dtu.dk>
|
|
6
6
|
Project-URL: Homepage, https://gitlab.windenergy.dtu.dk/DYNAMIKS/multiclass_interface
|
|
@@ -15,6 +15,7 @@ Requires-Dist: numpy
|
|
|
15
15
|
Provides-Extra: test
|
|
16
16
|
Requires-Dist: pytest; extra == "test"
|
|
17
17
|
Requires-Dist: pytest-cov; extra == "test"
|
|
18
|
+
Dynamic: license-file
|
|
18
19
|
|
|
19
20
|
# Multiclass interface
|
|
20
21
|
|
{multiclass_interface-1.15 → multiclass_interface-1.18}/Multiclass_interface.egg-info/SOURCES.txt
RENAMED
|
@@ -8,6 +8,8 @@ Multiclass_interface.egg-info/PKG-INFO
|
|
|
8
8
|
Multiclass_interface.egg-info/SOURCES.txt
|
|
9
9
|
Multiclass_interface.egg-info/dependency_links.txt
|
|
10
10
|
Multiclass_interface.egg-info/requires.txt
|
|
11
|
+
Multiclass_interface.egg-info/scm_file_list.json
|
|
12
|
+
Multiclass_interface.egg-info/scm_version.json
|
|
11
13
|
Multiclass_interface.egg-info/top_level.txt
|
|
12
14
|
multiclass_interface/__init__.py
|
|
13
15
|
multiclass_interface/mpi_interface.py
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"files": [
|
|
3
|
+
".gitignore",
|
|
4
|
+
".gitlab-ci.yml",
|
|
5
|
+
"LICENSE",
|
|
6
|
+
"README.md",
|
|
7
|
+
"multiclass_interface/__init__.py",
|
|
8
|
+
"multiclass_interface/mpi_interface.py",
|
|
9
|
+
"multiclass_interface/multi_object_list.py",
|
|
10
|
+
"multiclass_interface/multiprocess_interface.py",
|
|
11
|
+
"multiclass_interface/tests/__init__.py",
|
|
12
|
+
"multiclass_interface/tests/my_test_cls.py",
|
|
13
|
+
"multiclass_interface/tests/test_mpi.py",
|
|
14
|
+
"multiclass_interface/tests/test_multiclass_list.py",
|
|
15
|
+
"multiclass_interface/tests/test_multiprocessinterface.py",
|
|
16
|
+
"pyproject.toml",
|
|
17
|
+
"sequence_diagrams.md"
|
|
18
|
+
]
|
|
19
|
+
}
|
{multiclass_interface-1.15/Multiclass_interface.egg-info → multiclass_interface-1.18}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: Multiclass_interface
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.18
|
|
4
4
|
Summary: Multiclass interface
|
|
5
5
|
Author-email: "Mads M. Pedersen" <mmpe@dtu.dk>
|
|
6
6
|
Project-URL: Homepage, https://gitlab.windenergy.dtu.dk/DYNAMIKS/multiclass_interface
|
|
@@ -15,6 +15,7 @@ Requires-Dist: numpy
|
|
|
15
15
|
Provides-Extra: test
|
|
16
16
|
Requires-Dist: pytest; extra == "test"
|
|
17
17
|
Requires-Dist: pytest-cov; extra == "test"
|
|
18
|
+
Dynamic: license-file
|
|
18
19
|
|
|
19
20
|
# Multiclass interface
|
|
20
21
|
|
{multiclass_interface-1.15 → multiclass_interface-1.18}/multiclass_interface/mpi_interface.py
RENAMED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
+
import inspect
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import pytest
|
|
4
|
+
import os
|
|
1
5
|
import numpy as np
|
|
6
|
+
import shutil
|
|
2
7
|
import sys
|
|
3
8
|
import traceback
|
|
4
9
|
from contextlib import contextmanager
|
|
@@ -155,7 +160,7 @@ class MPIClassInterface():
|
|
|
155
160
|
def __getattribute__(self, name):
|
|
156
161
|
if name in MPIClassInterfaceAttributes:
|
|
157
162
|
return object.__getattribute__(self, name)
|
|
158
|
-
elif not self.use_rank[rank]:
|
|
163
|
+
elif not COLLECTIVE_MPI and not self.use_rank[rank]:
|
|
159
164
|
raise ChildProcessError(f'MPI worker {rank} not used')
|
|
160
165
|
|
|
161
166
|
def wrap(*args, **kwargs):
|
|
@@ -234,3 +239,68 @@ class SubsetMPIClassInterface(MPIClassInterface):
|
|
|
234
239
|
|
|
235
240
|
def close(self):
|
|
236
241
|
raise Exception('Cannot close SubsetMPIClassInterface. Please close all instances at once')
|
|
242
|
+
|
|
243
|
+
|
|
244
|
+
def barrier_print(s):
|
|
245
|
+
from mpi4py import MPI
|
|
246
|
+
|
|
247
|
+
newData = comm.gather(rank, root=0)
|
|
248
|
+
newData = comm.gather(rank, root=0)
|
|
249
|
+
import sys
|
|
250
|
+
sys.stdout.flush()
|
|
251
|
+
if rank == 0:
|
|
252
|
+
print("#########", s, newData, flush=True)
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
def bcast_function_result(f):
|
|
256
|
+
# Decorator to broadcast the return value of a function as a wt dependent list to all mpi workers
|
|
257
|
+
# collect the return value from each mpiworker and broadcast the full list with wt as first dimension to all workers
|
|
258
|
+
def wrapper(*args, **kwargs):
|
|
259
|
+
if mpi:
|
|
260
|
+
try:
|
|
261
|
+
v = f(*args, **kwargs)[0]
|
|
262
|
+
except ChildProcessError:
|
|
263
|
+
v = None
|
|
264
|
+
|
|
265
|
+
# collect the return value from each mpiworker (wt as first dimension)
|
|
266
|
+
v = comm.gather(v, root=0)
|
|
267
|
+
# broadcast the full list to all workers
|
|
268
|
+
return comm.bcast(v, root=0)
|
|
269
|
+
else:
|
|
270
|
+
return f(*args, **kwargs)
|
|
271
|
+
return wrapper
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
def mpi_run_test(n, cwd='.', mpirun_cmd='mpirun'):
|
|
275
|
+
if callable(n):
|
|
276
|
+
return mpi_run_test(n=4)(n)
|
|
277
|
+
|
|
278
|
+
def decorator(test_function):
|
|
279
|
+
try:
|
|
280
|
+
import mpi4py
|
|
281
|
+
assert shutil.which('mpirun') is not None
|
|
282
|
+
except Exception: # pragma: no cover
|
|
283
|
+
return lambda: pytest.xfail('mpirun or mpi4py missing')
|
|
284
|
+
name = test_function.__name__
|
|
285
|
+
|
|
286
|
+
def wrap(mpirun=False):
|
|
287
|
+
cwd = os.getcwd()
|
|
288
|
+
try:
|
|
289
|
+
if mpirun:
|
|
290
|
+
os.chdir(cwd)
|
|
291
|
+
return test_function()
|
|
292
|
+
else:
|
|
293
|
+
|
|
294
|
+
import_path = Path(inspect.getsourcefile(test_function)).relative_to(os.getcwd()).as_posix()
|
|
295
|
+
import_path = import_path[:-3].replace('/', '.')
|
|
296
|
+
cmd = f'''{mpirun_cmd} -n {n} {sys.executable} -c "from {import_path} import {name}; {name}(mpirun=True)"'''
|
|
297
|
+
print(f"cd {os.getcwd()} && {cmd}", flush=True)
|
|
298
|
+
assert os.system(cmd) == 0, name
|
|
299
|
+
|
|
300
|
+
finally:
|
|
301
|
+
os.chdir(cwd)
|
|
302
|
+
|
|
303
|
+
wrap.__name__ = name
|
|
304
|
+
return wrap
|
|
305
|
+
|
|
306
|
+
return decorator
|
{multiclass_interface-1.15 → multiclass_interface-1.18}/multiclass_interface/multi_object_list.py
RENAMED
|
@@ -9,6 +9,12 @@ class MultiObjectList():
|
|
|
9
9
|
def __str__(self):
|
|
10
10
|
return f'{self.__class__.__name__}({self.obj_lst})'
|
|
11
11
|
|
|
12
|
+
def __enter__(self):
|
|
13
|
+
return self
|
|
14
|
+
|
|
15
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
|
16
|
+
pass
|
|
17
|
+
|
|
12
18
|
def get_obj_args_lst(self, args, kwargs):
|
|
13
19
|
N = len(self.obj_lst)
|
|
14
20
|
|
|
@@ -21,7 +21,8 @@ from multiclass_interface.multi_object_list import MultiObjectList
|
|
|
21
21
|
|
|
22
22
|
def run(cls, inputQueue, outputQueue, cls_args, **kwargs):
|
|
23
23
|
o = cls(*cls_args, **kwargs)
|
|
24
|
-
|
|
24
|
+
running = True
|
|
25
|
+
while running:
|
|
25
26
|
method, args, kwargs = inputQueue.get()
|
|
26
27
|
try:
|
|
27
28
|
if method == 'getattr':
|
|
@@ -48,7 +49,7 @@ def run(cls, inputQueue, outputQueue, cls_args, **kwargs):
|
|
|
48
49
|
finally:
|
|
49
50
|
if method == 'close':
|
|
50
51
|
outputQueue.put('Exit process')
|
|
51
|
-
|
|
52
|
+
running = False
|
|
52
53
|
|
|
53
54
|
|
|
54
55
|
class ProcessClass():
|
{multiclass_interface-1.15 → multiclass_interface-1.18}/multiclass_interface/tests/test_mpi.py
RENAMED
|
@@ -10,6 +10,8 @@ from multiclass_interface.multiprocess_interface import ProcessClass
|
|
|
10
10
|
import numpy as np
|
|
11
11
|
from multiclass_interface.tests.my_test_cls import MyTest
|
|
12
12
|
from multiclass_interface import mpi_interface
|
|
13
|
+
from multiclass_interface.mpi_interface import mpi_run_test
|
|
14
|
+
from multiclass_interface.multi_object_list import MultiClassInterface
|
|
13
15
|
|
|
14
16
|
|
|
15
17
|
def mpirun(f):
|
|
@@ -27,7 +29,7 @@ def mpirun(f):
|
|
|
27
29
|
return f
|
|
28
30
|
|
|
29
31
|
|
|
30
|
-
@
|
|
32
|
+
@mpi_run_test
|
|
31
33
|
def test_mpi_collective_too_few_slots():
|
|
32
34
|
mpi_interface.activate_mpi()
|
|
33
35
|
N = 4
|
|
@@ -42,7 +44,7 @@ def test_mpi_collective_too_few_slots():
|
|
|
42
44
|
assert str(e) == 'Not enough mpi slots. Slots: 4, Requested: 5'
|
|
43
45
|
|
|
44
46
|
|
|
45
|
-
@
|
|
47
|
+
@mpi_run_test
|
|
46
48
|
def test_mpi_collective_MyTest():
|
|
47
49
|
mpi_interface.activate_mpi()
|
|
48
50
|
N = 4
|
|
@@ -60,6 +62,8 @@ def test_mpi_collective_MyTest():
|
|
|
60
62
|
i = mpi_interface.main_run(lambda: m.get_id())
|
|
61
63
|
npt.assert_array_equal(i, 1)
|
|
62
64
|
|
|
65
|
+
assert m[1].get_id() == [2]
|
|
66
|
+
|
|
63
67
|
try:
|
|
64
68
|
npt.assert_array_equal(m[1:3].get_id(), np.arange(1, 3) + 1)
|
|
65
69
|
except ChildProcessError:
|
|
@@ -90,7 +94,7 @@ def test_mpi_collective_MyTest():
|
|
|
90
94
|
m[:3][1]
|
|
91
95
|
|
|
92
96
|
|
|
93
|
-
@
|
|
97
|
+
@mpi_run_test
|
|
94
98
|
def test_mpi_collective_close_released_mpi_workers():
|
|
95
99
|
mpi_interface.activate_mpi()
|
|
96
100
|
N = 4
|
|
@@ -100,7 +104,7 @@ def test_mpi_collective_close_released_mpi_workers():
|
|
|
100
104
|
m.close()
|
|
101
105
|
|
|
102
106
|
|
|
103
|
-
@
|
|
107
|
+
@mpi_run_test
|
|
104
108
|
def test_mpi_ProcessClass():
|
|
105
109
|
mpi_interface.activate_mpi()
|
|
106
110
|
with ProcessClass(MyTest) as cls:
|
|
@@ -108,13 +112,19 @@ def test_mpi_ProcessClass():
|
|
|
108
112
|
assert myTest.get_id() == 1
|
|
109
113
|
|
|
110
114
|
|
|
111
|
-
@
|
|
115
|
+
@mpi_run_test
|
|
112
116
|
def test_non_collective_mpi2():
|
|
113
117
|
mpi_interface.activate_mpi(collective_mpi=False)
|
|
114
118
|
rank = mpi_interface.rank
|
|
115
119
|
N = 3
|
|
116
120
|
with MPIClassInterface(MyTest, [(i + 10,) for i in range(N)]) as m:
|
|
117
121
|
|
|
122
|
+
id_lst = mpi_interface.bcast_function_result(lambda: m.get_id())()
|
|
123
|
+
assert id_lst == [10, 11, 12, None], id_lst
|
|
124
|
+
id_lst = mpi_interface.bcast_function_result(lambda: m.return_input(['a', 'b', 'c']))()
|
|
125
|
+
assert id_lst == ["10 got: ('a',) and {}", "11 got: ('b',) and {}", "12 got: ('c',) and {}", None], id_lst
|
|
126
|
+
|
|
127
|
+
mpi_interface.barrier_print('hello world')
|
|
118
128
|
try:
|
|
119
129
|
assert m.get_id()[0] == rank + 10, m.get_id()
|
|
120
130
|
main_id = mpi_interface.main_run(lambda: m.get_id())
|
|
@@ -135,7 +145,17 @@ def test_non_collective_mpi2():
|
|
|
135
145
|
m.object.cls
|
|
136
146
|
|
|
137
147
|
|
|
138
|
-
|
|
148
|
+
def test_non_collective_mpi2_no_mpi():
|
|
149
|
+
N = 3
|
|
150
|
+
with MultiClassInterface(MyTest, [(i + 10,) for i in range(N)]) as m:
|
|
151
|
+
|
|
152
|
+
id_lst = mpi_interface.bcast_function_result(lambda: m.get_id())()
|
|
153
|
+
assert id_lst == [10, 11, 12], id_lst
|
|
154
|
+
id_lst = mpi_interface.bcast_function_result(lambda: m.return_input(['a', 'b', 'c']))()
|
|
155
|
+
assert id_lst == ["10 got: ('a',) and {}", "11 got: ('b',) and {}", "12 got: ('c',) and {}"], id_lst
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
@mpi_run_test(4)
|
|
139
159
|
def test_mpi_non_collective_MyTest():
|
|
140
160
|
mpi_interface.activate_mpi(collective_mpi=False)
|
|
141
161
|
rank = mpi_interface.rank
|
|
@@ -183,7 +203,7 @@ def test_mpi_non_collective_MyTest():
|
|
|
183
203
|
m[:3][1]
|
|
184
204
|
|
|
185
205
|
|
|
186
|
-
@
|
|
206
|
+
@mpi_run_test(4)
|
|
187
207
|
def test_multiprocessinterface_tests():
|
|
188
208
|
from multiclass_interface.tests.test_multiprocessinterface import test_attribute, test_missing_attribute, test_execption, test_setattr, test_setattr_method
|
|
189
209
|
mpi_interface.activate_mpi()
|
|
@@ -196,7 +216,7 @@ def test_multiprocessinterface_tests():
|
|
|
196
216
|
pass
|
|
197
217
|
|
|
198
218
|
|
|
199
|
-
@
|
|
219
|
+
@mpi_run_test(4)
|
|
200
220
|
def test_multiprocessinterface_tests_diff_interface():
|
|
201
221
|
from multiclass_interface.tests.test_multiprocessinterface import test_attribute, test_missing_attribute, test_execption, test_setattr, test_setattr_method
|
|
202
222
|
mpi_interface.activate_mpi(terminate_on_close=False)
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# file generated by vcs-versioning
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"__version__",
|
|
7
|
+
"__version_tuple__",
|
|
8
|
+
"version",
|
|
9
|
+
"version_tuple",
|
|
10
|
+
"__commit_id__",
|
|
11
|
+
"commit_id",
|
|
12
|
+
]
|
|
13
|
+
|
|
14
|
+
version: str
|
|
15
|
+
__version__: str
|
|
16
|
+
__version_tuple__: tuple[int | str, ...]
|
|
17
|
+
version_tuple: tuple[int | str, ...]
|
|
18
|
+
commit_id: str | None
|
|
19
|
+
__commit_id__: str | None
|
|
20
|
+
|
|
21
|
+
__version__ = version = '1.18'
|
|
22
|
+
__version_tuple__ = version_tuple = (1, 18)
|
|
23
|
+
|
|
24
|
+
__commit_id__ = commit_id = 'gb93401984'
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
# file generated by setuptools-scm
|
|
2
|
-
# don't change, don't track in version control
|
|
3
|
-
|
|
4
|
-
__all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
|
|
5
|
-
|
|
6
|
-
TYPE_CHECKING = False
|
|
7
|
-
if TYPE_CHECKING:
|
|
8
|
-
from typing import Tuple
|
|
9
|
-
from typing import Union
|
|
10
|
-
|
|
11
|
-
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
12
|
-
else:
|
|
13
|
-
VERSION_TUPLE = object
|
|
14
|
-
|
|
15
|
-
version: str
|
|
16
|
-
__version__: str
|
|
17
|
-
__version_tuple__: VERSION_TUPLE
|
|
18
|
-
version_tuple: VERSION_TUPLE
|
|
19
|
-
|
|
20
|
-
__version__ = version = '1.15'
|
|
21
|
-
__version_tuple__ = version_tuple = (1, 15)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{multiclass_interface-1.15 → multiclass_interface-1.18}/Multiclass_interface.egg-info/requires.txt
RENAMED
|
File without changes
|
{multiclass_interface-1.15 → multiclass_interface-1.18}/Multiclass_interface.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{multiclass_interface-1.15 → multiclass_interface-1.18}/multiclass_interface/tests/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|