Multiclass-interface 1.1__tar.gz → 1.2__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.
Files changed (23) hide show
  1. {Multiclass_interface-1.1 → multiclass_interface-1.2}/.gitlab-ci.yml +0 -1
  2. {Multiclass_interface-1.1 → multiclass_interface-1.2/Multiclass_interface.egg-info}/PKG-INFO +1 -1
  3. {Multiclass_interface-1.1 → multiclass_interface-1.2}/Multiclass_interface.egg-info/SOURCES.txt +1 -0
  4. {Multiclass_interface-1.1/Multiclass_interface.egg-info → multiclass_interface-1.2}/PKG-INFO +1 -1
  5. {Multiclass_interface-1.1 → multiclass_interface-1.2}/multiclass_interface/mpi_interface.py +10 -13
  6. {Multiclass_interface-1.1 → multiclass_interface-1.2}/multiclass_interface/tests/test_mpi.py +2 -2
  7. {Multiclass_interface-1.1 → multiclass_interface-1.2}/multiclass_interface/version.py +2 -2
  8. multiclass_interface-1.2/sequence_diagrams.md +228 -0
  9. {Multiclass_interface-1.1 → multiclass_interface-1.2}/.gitignore +0 -0
  10. {Multiclass_interface-1.1 → multiclass_interface-1.2}/LICENSE +0 -0
  11. {Multiclass_interface-1.1 → multiclass_interface-1.2}/Multiclass_interface.egg-info/dependency_links.txt +0 -0
  12. {Multiclass_interface-1.1 → multiclass_interface-1.2}/Multiclass_interface.egg-info/requires.txt +0 -0
  13. {Multiclass_interface-1.1 → multiclass_interface-1.2}/Multiclass_interface.egg-info/top_level.txt +0 -0
  14. {Multiclass_interface-1.1 → multiclass_interface-1.2}/README.md +0 -0
  15. {Multiclass_interface-1.1 → multiclass_interface-1.2}/multiclass_interface/__init__.py +0 -0
  16. {Multiclass_interface-1.1 → multiclass_interface-1.2}/multiclass_interface/multi_object_list.py +0 -0
  17. {Multiclass_interface-1.1 → multiclass_interface-1.2}/multiclass_interface/multiprocess_interface.py +0 -0
  18. {Multiclass_interface-1.1 → multiclass_interface-1.2}/multiclass_interface/tests/__init__.py +0 -0
  19. {Multiclass_interface-1.1 → multiclass_interface-1.2}/multiclass_interface/tests/my_test_cls.py +0 -0
  20. {Multiclass_interface-1.1 → multiclass_interface-1.2}/multiclass_interface/tests/test_multiclass_list.py +0 -0
  21. {Multiclass_interface-1.1 → multiclass_interface-1.2}/multiclass_interface/tests/test_multiprocessinterface.py +0 -0
  22. {Multiclass_interface-1.1 → multiclass_interface-1.2}/pyproject.toml +0 -0
  23. {Multiclass_interface-1.1 → multiclass_interface-1.2}/setup.cfg +0 -0
@@ -13,7 +13,6 @@ test_ubuntu: # name the job what we like
13
13
  script:
14
14
  - pip install -e .[test]
15
15
  - pytest --cov-report term-missing:skip-covered --cov=multiclass_interface multiclass_interface/tests
16
- - pytest --cov-report term-missing:skip-covered --cov=multiclass_interface multiclass_interface/tests
17
16
  coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
18
17
  tags: # only runners with this tag can do the job [3]
19
18
  - ci-ubuntu
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Multiclass_interface
3
- Version: 1.1
3
+ Version: 1.2
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
@@ -3,6 +3,7 @@
3
3
  LICENSE
4
4
  README.md
5
5
  pyproject.toml
6
+ sequence_diagrams.md
6
7
  Multiclass_interface.egg-info/PKG-INFO
7
8
  Multiclass_interface.egg-info/SOURCES.txt
8
9
  Multiclass_interface.egg-info/dependency_links.txt
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: Multiclass_interface
3
- Version: 1.1
3
+ Version: 1.2
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
@@ -1,27 +1,24 @@
1
1
  import numpy as np
2
2
  import sys
3
- import os
4
- import subprocess
5
3
  import traceback
6
4
  import inspect
7
- from enum import Enum
8
5
 
9
- if 'SLURM_NTASKS' in os.environ:
10
- mpi = int(os.environ['SLURM_NTASKS']) > 1
11
- elif any([k in os.environ for k in ['MPI_LOCALNRANKS', 'OMPI_COMM_WORLD_SIZE']]):
12
- mpi = True
13
- else:
14
- mpi = subprocess.run("python -c 'from mpi4py import MPI'", shell=True,
15
- check=False, stderr=subprocess.PIPE).returncode == 0
6
+ comm = None
7
+ size = 1
8
+ rank = 0
9
+ name = ""
10
+ main = True
16
11
 
17
- if mpi:
12
+
13
+ def activate_mpi():
14
+ global comm, size, rank, name, main
18
15
  from mpi4py import MPI
19
16
  comm = MPI.COMM_WORLD
20
17
  size = MPI.COMM_WORLD.Get_size()
21
18
  rank = MPI.COMM_WORLD.Get_rank()
22
19
  name = MPI.Get_processor_name()
23
- else:
24
- size = 1
20
+ main = rank == 0
21
+
25
22
 
26
23
  MPIClassInterfaceAttributes = {
27
24
  'close',
@@ -46,9 +46,9 @@ def mpitest_mpi_ProcessClass():
46
46
 
47
47
 
48
48
  def mpitest_all():
49
+ mpi_interface.activate_mpi()
49
50
  mpi_interface.exit_mpi_on_close = False
50
- from mpi4py import MPI
51
- rank = MPI.COMM_WORLD.Get_rank()
51
+ rank = mpi_interface.rank
52
52
  from multiclass_interface.tests.test_multiprocessinterface import test_attribute, test_missing_attribute, test_execption, test_setattr, test_setattr_method
53
53
  mpi_interface.TERMINATE_ON_CLOSE = False
54
54
 
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '1.1'
16
- __version_tuple__ = version_tuple = (1, 1)
15
+ __version__ = version = '1.2'
16
+ __version_tuple__ = version_tuple = (1, 2)
@@ -0,0 +1,228 @@
1
+ ## ThreadClass
2
+ ```mermaid
3
+ sequenceDiagram
4
+ participant U as Main
5
+ participant TC as ThreadClass
6
+
7
+ U->>+TC: cls=A
8
+
9
+ create participant Q as IOQueue
10
+ TC->>Q:
11
+ TC->>-U: ~A
12
+ U->>+TC: ~A(*args,**kwargs)
13
+ create participant T as Thread
14
+ TC->>T: A, IOQueue, args, kwargs
15
+ create participant A
16
+ T->>A: __init__(*args, **kwargs)
17
+ T->>+T: Run()
18
+ T->>+Q: get()
19
+ TC->>-U: ~a
20
+ U->>+TC: ~a.f(*args,**kwargs)
21
+ TC->>Q: put(f,args,kwargs)
22
+
23
+ Q->>-T: f,args,kwargs
24
+ T->>+A: f(*args, **kwargs)
25
+ A->>-T: res
26
+ TC->>+Q: get()
27
+ T->>Q: put(res)
28
+ Q->>-TC: res
29
+ TC->>-U: res
30
+ TC->>T: close()
31
+ T->>-T:
32
+
33
+
34
+ ```
35
+
36
+ ## ProcessClass
37
+
38
+ The `ProcessClass` is similar to the `ThreadClas` except that it uses a seprate Process instead of a Thread.
39
+ This means:
40
+ - More time used to spawn process
41
+ - Changes to `os.environ['LD_LIBRARY_PATH']` are effective in the process
42
+ - Libraries (dll/so) will have their own memory space (important if multiple instances are launched)
43
+ - Multiple processes allows parallel execution
44
+
45
+ ## MultiProcessClassInterface
46
+
47
+ ```mermaid
48
+ sequenceDiagram
49
+ participant U as Main
50
+ participant TC as MultiThreadClassInterface
51
+
52
+ U->>+TC: cls=A, [args1,args2])
53
+
54
+ create participant Q1 as IOQueue1
55
+ TC->>Q1:
56
+ create participant T1 as Thread1
57
+ TC->>T1: A, IOQueue1, args1
58
+ create participant A1
59
+ T1->>A1: __init__(*args1)
60
+ T1->>+T1: Run()
61
+ T1->>+Q1: get()
62
+
63
+ create participant Q2 as IOQueue2
64
+ TC->>Q2:
65
+ create participant T2 as Thread2
66
+ TC->>T2: A, IOQueue2, args2
67
+ create participant A2
68
+ T2->>A2: __init__(*args2)
69
+ T2->>+T2: Run()
70
+ T2->>+Q2: get()
71
+
72
+ TC->>-U: ~a
73
+ U->>+TC: ~a.f(*args,**kwargs)
74
+ TC->>Q1: put(f,args,kwargs)
75
+ TC->>Q2: put(f,args,kwargs)
76
+
77
+ Q1->>-T1: f,args,kwargs
78
+ Q2->>-T2: f,args,kwargs
79
+ T1->>+A1: f(*args, **kwargs)
80
+ T2->>+A2: f(*args, **kwargs)
81
+ A1->>-T1: res1
82
+ A2->>-T2: res2
83
+ TC->>+Q1: get()
84
+ T1->>Q1: put(res)
85
+ T2->>Q2: put(res)
86
+ Q1->>-TC: res1
87
+ TC->>+Q2: get()
88
+ Q2->>-TC: res2
89
+ TC->>-U: [res1,res2]
90
+
91
+ TC->>T1: close()
92
+ T1->>-T1:
93
+ TC->>T2: close()
94
+ T2->>-T2:
95
+ ```
96
+
97
+
98
+ ## MultiProcessClassInterface
99
+
100
+ The `MultiProcessClassInterface` is similar to the `MultiThreadClassInterfaces` except that it uses a seprate processes instead of a threads.
101
+ This means:
102
+ - More time used to spawn processes
103
+ - Changes to `os.environ['LD_LIBRARY_PATH']` are effective in the processes
104
+ - Libraries (dll/so) executed in the processes will their own individual memory space (changes to a variable in one dll does not affect the others)
105
+ - Parallel execution of class functions
106
+
107
+ ## MPIClassInterface
108
+ ```mermaid
109
+ sequenceDiagram
110
+ actor U as User
111
+
112
+ participant MPI0 as MPI,rank0<br>MPIClassInterface
113
+
114
+
115
+ MPI0->>+MPI0: cls=A, [(args0),(args1)]
116
+
117
+
118
+ create participant A0
119
+ MPI0->>+A0: args0
120
+ MPI0->>-U: ~a
121
+ participant MPI1 as MPI,rank1<br>MPIClassInterface
122
+ MPI1->>+MPI1: cls=A, [(args0),(args1)]
123
+ create participant A1
124
+ MPI1->>A1: args1
125
+ participant MPI2 as MPI,rank2<br>MPIClassInterface
126
+ MPI2->>MPI2: cls=A, [(args0),(args1)]
127
+ MPI1->>-U:
128
+ MPI2->>U:
129
+
130
+ U->>+MPI0:~a.f([args0,args1])
131
+ MPI0->>+MPI0: run_task()
132
+ MPI1->>+MPI1: work_loop
133
+ MPI2->>+MPI2: work_loop
134
+
135
+ rect rgb(191, 223, 255)
136
+ note right of MPI0: Scatter
137
+ MPI0->>MPI0: f,args0
138
+ MPI0->>MPI1: f,args1
139
+ MPI0->>MPI2: "skip",[]
140
+ end
141
+ MPI0->>+A0: f(args0)
142
+ MPI1->>+A1: f(args1)
143
+ A0->>-MPI0: res0
144
+ A1->>-MPI1: res1
145
+
146
+ rect rgb(191, 223, 255)
147
+ note right of MPI0: Gather
148
+ MPI0->>MPI0: res0
149
+ MPI1->>MPI0: res1
150
+ MPI2->>MPI0: None
151
+ end
152
+
153
+
154
+ MPI0->>-U: [res1,res2]
155
+
156
+ U->>+MPI0:~a.close()
157
+ MPI0->>+MPI0: run_task()
158
+ rect rgb(191, 223, 255)
159
+ note right of MPI0: Scatter
160
+ MPI0->>MPI0: close
161
+ MPI0->>MPI1: close
162
+ MPI0->>MPI2: close
163
+ end
164
+ MPI0->>-MPI0:
165
+ MPI1->>-MPI1:
166
+ MPI2->>-MPI2:
167
+ ```
168
+
169
+ ## MPIClassInterface
170
+
171
+ Setting `mpi_interface.LOOP_UNTIL_CLOSE=False` results in the following workflow
172
+
173
+ ```mermaid
174
+ sequenceDiagram
175
+ actor U as User
176
+
177
+ participant MPI0 as MPI,rank0<br>MPIClassInterface
178
+
179
+
180
+ MPI0->>+MPI0: cls=A, [(args0),(args1)]
181
+
182
+
183
+ create participant A0
184
+ MPI0->>+A0: args0
185
+ MPI0->>-U: ~a
186
+ participant MPI1 as MPI,rank1<br>MPIClassInterface
187
+ MPI1->>+MPI1: cls=A, [(args0),(args1)]
188
+ create participant A1
189
+ MPI1->>A1: args1
190
+ participant MPI2 as MPI,rank2<br>MPIClassInterface
191
+ MPI2->>MPI2: cls=A, [(args0),(args1)]
192
+ MPI1->>-U:
193
+ MPI2->>U:
194
+
195
+ U->>+MPI0:~a.f([args0,args1])
196
+ MPI0->>+MPI0: run_task()
197
+ MPI1->>+MPI1: work_loop
198
+ MPI2->>+MPI2: work_loop
199
+ MPI2->>-MPI2:
200
+ MPI2->>U:
201
+
202
+
203
+ rect rgb(191, 223, 255)
204
+ note right of MPI0: Scatter
205
+ MPI0->>MPI0: f,args0
206
+ MPI0->>MPI1: f,args1
207
+ MPI0->>MPI2: "skip",[]
208
+ end
209
+ MPI0->>+A0: f(args0)
210
+ MPI1->>+A1: f(args1)
211
+ A0->>-MPI0: res0
212
+ A1->>-MPI1: res1
213
+ MPI1->>-MPI1:
214
+ MPI1->>U:
215
+
216
+ rect rgb(191, 223, 255)
217
+ note right of MPI0: Gather
218
+ MPI0->>MPI0: res0
219
+ MPI1->>MPI0: res1
220
+ MPI2->>MPI0: None
221
+ end
222
+
223
+
224
+ MPI0->>-U: [res1,res2]
225
+
226
+ ```
227
+
228
+