Multiclass-interface 1.2__tar.gz → 1.3__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.2 → multiclass_interface-1.3/Multiclass_interface.egg-info}/PKG-INFO +1 -1
- {multiclass_interface-1.2/Multiclass_interface.egg-info → multiclass_interface-1.3}/PKG-INFO +1 -1
- {multiclass_interface-1.2 → multiclass_interface-1.3}/multiclass_interface/mpi_interface.py +19 -11
- {multiclass_interface-1.2 → multiclass_interface-1.3}/multiclass_interface/tests/test_mpi.py +22 -4
- {multiclass_interface-1.2 → multiclass_interface-1.3}/multiclass_interface/version.py +2 -2
- {multiclass_interface-1.2 → multiclass_interface-1.3}/sequence_diagrams.md +49 -2
- {multiclass_interface-1.2 → multiclass_interface-1.3}/.gitignore +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/.gitlab-ci.yml +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/LICENSE +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/Multiclass_interface.egg-info/SOURCES.txt +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/Multiclass_interface.egg-info/dependency_links.txt +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/Multiclass_interface.egg-info/requires.txt +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/Multiclass_interface.egg-info/top_level.txt +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/README.md +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/multiclass_interface/__init__.py +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/multiclass_interface/multi_object_list.py +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/multiclass_interface/multiprocess_interface.py +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/multiclass_interface/tests/__init__.py +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/multiclass_interface/tests/my_test_cls.py +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/multiclass_interface/tests/test_multiclass_list.py +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/multiclass_interface/tests/test_multiprocessinterface.py +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/pyproject.toml +0 -0
- {multiclass_interface-1.2 → multiclass_interface-1.3}/setup.cfg +0 -0
|
@@ -35,6 +35,7 @@ MPIClassInterfaceAttributes = {
|
|
|
35
35
|
|
|
36
36
|
LOOP_UNTIL_CLOSE = True
|
|
37
37
|
TERMINATE_ON_CLOSE = True
|
|
38
|
+
COLLECTIVE_MPI = True
|
|
38
39
|
|
|
39
40
|
|
|
40
41
|
class MPIClassInterface():
|
|
@@ -53,10 +54,9 @@ class MPIClassInterface():
|
|
|
53
54
|
self.object = Dummy()
|
|
54
55
|
self.closed = False
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
elif LOOP_UNTIL_CLOSE:
|
|
57
|
+
self.use_rank = np.array([True] * size)
|
|
58
|
+
self.use_rank[len(args_lst):] = False
|
|
59
|
+
if rank > 0 and COLLECTIVE_MPI and LOOP_UNTIL_CLOSE:
|
|
60
60
|
self.work_loop()
|
|
61
61
|
|
|
62
62
|
def __enter__(self):
|
|
@@ -133,13 +133,18 @@ class MPIClassInterface():
|
|
|
133
133
|
def __getattribute__(self, name):
|
|
134
134
|
if name in MPIClassInterfaceAttributes:
|
|
135
135
|
return object.__getattribute__(self, name)
|
|
136
|
-
elif rank > 0:
|
|
136
|
+
elif COLLECTIVE_MPI and rank > 0:
|
|
137
137
|
self.work_loop()
|
|
138
138
|
return lambda *args, **kwargs: 1
|
|
139
|
+
elif not self.use_rank[rank]:
|
|
140
|
+
raise ChildProcessError('MPI worker not used')
|
|
139
141
|
|
|
140
142
|
def wrap(*args, **kwargs):
|
|
141
|
-
|
|
142
|
-
|
|
143
|
+
if COLLECTIVE_MPI:
|
|
144
|
+
inp = [self.get_input(name, i, args, kwargs) for i in range(size)]
|
|
145
|
+
return self.run_task(inp)
|
|
146
|
+
else:
|
|
147
|
+
return self.do_task(name, args, kwargs)
|
|
143
148
|
|
|
144
149
|
if hasattr(getattr(self.object, name), '__call__'):
|
|
145
150
|
return wrap
|
|
@@ -162,11 +167,14 @@ class MPIClassInterface():
|
|
|
162
167
|
|
|
163
168
|
def close(self):
|
|
164
169
|
if not self.closed:
|
|
165
|
-
if
|
|
166
|
-
|
|
170
|
+
if COLLECTIVE_MPI:
|
|
171
|
+
if rank == 0:
|
|
172
|
+
res = self.run_task([('close', [], {}) for _ in range(size)])
|
|
173
|
+
else:
|
|
174
|
+
self.work_loop()
|
|
175
|
+
res = None
|
|
167
176
|
else:
|
|
168
|
-
self.
|
|
169
|
-
res = None
|
|
177
|
+
res = self.do_task('close', [], {})
|
|
170
178
|
self.closed = True
|
|
171
179
|
|
|
172
180
|
|
{multiclass_interface-1.2 → multiclass_interface-1.3}/multiclass_interface/tests/test_mpi.py
RENAMED
|
@@ -42,11 +42,28 @@ def mpitest_mpi_ProcessClass():
|
|
|
42
42
|
with ProcessClass(MyTest) as cls:
|
|
43
43
|
myTest = cls(1)
|
|
44
44
|
assert myTest.get_id() == 1
|
|
45
|
-
print("done, test_mpi_ProcessClass")
|
|
45
|
+
print("done, test_mpi_ProcessClass", flush=True)
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def mpitest_non_collective_mpi():
|
|
49
|
+
mpi_interface.COLLECTIVE_MPI = False
|
|
50
|
+
rank = mpi_interface.rank
|
|
51
|
+
import time
|
|
52
|
+
N = 3
|
|
53
|
+
with MPIClassInterface(MyTest, [(i + 10,) for i in range(N)]) as m:
|
|
54
|
+
|
|
55
|
+
try:
|
|
56
|
+
assert m.get_id() == rank + 10
|
|
57
|
+
assert rank < N # rank > N will fail with ChildProcessError
|
|
58
|
+
except ChildProcessError:
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
mpi_interface.COLLECTIVE_MPI = True
|
|
46
62
|
|
|
47
63
|
|
|
48
64
|
def mpitest_all():
|
|
49
65
|
mpi_interface.activate_mpi()
|
|
66
|
+
|
|
50
67
|
mpi_interface.exit_mpi_on_close = False
|
|
51
68
|
rank = mpi_interface.rank
|
|
52
69
|
from multiclass_interface.tests.test_multiprocessinterface import test_attribute, test_missing_attribute, test_execption, test_setattr, test_setattr_method
|
|
@@ -67,13 +84,14 @@ def mpitest_all():
|
|
|
67
84
|
run(f)
|
|
68
85
|
|
|
69
86
|
try:
|
|
70
|
-
with MPIClassInterface(MyTest, [(1,), (2,)]) as mpici:
|
|
87
|
+
with MPIClassInterface(MyTest, [(1,), (2,), (3,)]) as mpici:
|
|
71
88
|
for f in [test_attribute, test_missing_attribute, test_execption, test_setattr, test_setattr_method]:
|
|
72
|
-
|
|
89
|
+
|
|
73
90
|
run(f, mpici)
|
|
74
91
|
|
|
75
92
|
except ChildProcessError:
|
|
76
93
|
pass
|
|
77
|
-
|
|
94
|
+
|
|
95
|
+
run(mpitest_non_collective_mpi)
|
|
78
96
|
|
|
79
97
|
print(f"Rank {rank} Done test_all")
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
# Sequence diagrams
|
|
2
|
+
- [ThreadClass](#threadclass)
|
|
3
|
+
- [ProcessClass](#processclass)
|
|
4
|
+
- [MultiThreadClassInterface](#multithreadclassinterface)
|
|
5
|
+
- [MultiProcessClassInterface](#multiprocessclassinterface)
|
|
6
|
+
- [MPIClassInterface](#mpiclassinterface)
|
|
7
|
+
- [MPIClassInterface(LOOP_UNTIL_CLOSE=False)](#mpiclassinterfaceloop_until_closefalse)
|
|
8
|
+
- [MPIClassInterface(COLLECTIVE_MPI=False)](#mpiclassinterfacecollective_mpifalse)
|
|
9
|
+
|
|
1
10
|
## ThreadClass
|
|
2
11
|
```mermaid
|
|
3
12
|
sequenceDiagram
|
|
@@ -42,7 +51,7 @@ This means:
|
|
|
42
51
|
- Libraries (dll/so) will have their own memory space (important if multiple instances are launched)
|
|
43
52
|
- Multiple processes allows parallel execution
|
|
44
53
|
|
|
45
|
-
##
|
|
54
|
+
## MultiThreadClassInterface
|
|
46
55
|
|
|
47
56
|
```mermaid
|
|
48
57
|
sequenceDiagram
|
|
@@ -166,7 +175,7 @@ sequenceDiagram
|
|
|
166
175
|
MPI2->>-MPI2:
|
|
167
176
|
```
|
|
168
177
|
|
|
169
|
-
## MPIClassInterface
|
|
178
|
+
## MPIClassInterface(LOOP_UNTIL_CLOSE=False)
|
|
170
179
|
|
|
171
180
|
Setting `mpi_interface.LOOP_UNTIL_CLOSE=False` results in the following workflow
|
|
172
181
|
|
|
@@ -226,3 +235,41 @@ sequenceDiagram
|
|
|
226
235
|
```
|
|
227
236
|
|
|
228
237
|
|
|
238
|
+
## MPIClassInterface(COLLECTIVE_MPI=False)
|
|
239
|
+
Setting `mpi_interface.COLLECTIVE_MPI=False` results in the following workflow
|
|
240
|
+
|
|
241
|
+
```mermaid
|
|
242
|
+
sequenceDiagram
|
|
243
|
+
|
|
244
|
+
participant MPI0 as MPI,rank0<br>MPIClassInterface
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
MPI0->>+MPI0: cls=A, [(args0),(args1)]
|
|
248
|
+
|
|
249
|
+
|
|
250
|
+
create participant A0
|
|
251
|
+
MPI0->>+A0: args0
|
|
252
|
+
|
|
253
|
+
participant MPI1 as MPI,rank1<br>MPIClassInterface
|
|
254
|
+
MPI1->>+MPI1: cls=A, [(args0),(args1)]
|
|
255
|
+
create participant A1
|
|
256
|
+
MPI1->>A1: args1
|
|
257
|
+
participant MPI2 as MPI,rank2<br>MPIClassInterface
|
|
258
|
+
MPI2->>MPI2: cls=A, [(args0),(args1)]
|
|
259
|
+
|
|
260
|
+
MPI0->>+MPI0:~a.f([args0,args1])
|
|
261
|
+
MPI1->>+MPI1:~a.f([args0,args1])
|
|
262
|
+
MPI2->>+MPI2:~a.f([args0,args1])
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
MPI0->>+A0: f(args0)
|
|
266
|
+
MPI1->>+A1: f(args1)
|
|
267
|
+
MPI2->>-MPI2: ChildProcessError
|
|
268
|
+
A0->>-MPI0: res0
|
|
269
|
+
A1->>-MPI1: res1
|
|
270
|
+
|
|
271
|
+
MPI0->>-MPI0: res0
|
|
272
|
+
MPI1->>-MPI1: res1
|
|
273
|
+
|
|
274
|
+
```
|
|
275
|
+
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{multiclass_interface-1.2 → multiclass_interface-1.3}/Multiclass_interface.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
{multiclass_interface-1.2 → multiclass_interface-1.3}/Multiclass_interface.egg-info/requires.txt
RENAMED
|
File without changes
|
{multiclass_interface-1.2 → multiclass_interface-1.3}/Multiclass_interface.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{multiclass_interface-1.2 → multiclass_interface-1.3}/multiclass_interface/multi_object_list.py
RENAMED
|
File without changes
|
{multiclass_interface-1.2 → multiclass_interface-1.3}/multiclass_interface/multiprocess_interface.py
RENAMED
|
File without changes
|
{multiclass_interface-1.2 → multiclass_interface-1.3}/multiclass_interface/tests/__init__.py
RENAMED
|
File without changes
|
{multiclass_interface-1.2 → multiclass_interface-1.3}/multiclass_interface/tests/my_test_cls.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|