h2lib 0.0.3__cp39-cp39-win_amd64.whl → 13.0.705__cp39-cp39-win_amd64.whl

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.
@@ -0,0 +1,318 @@
1
+ # noqa
2
+
3
+ from h2lib.dll_wrapper import DLLWrapper
4
+
5
+
6
+ class H2LibSignatures():
7
+ def add_sensor(self, sensor_line, index_start, index_stop):
8
+ '''subroutine add_sensor(sensor_line, index_start, index_stop) bind(C, name="add_sensor")
9
+ integer*8 :: index_start, index_stop
10
+ character(kind=c_char, len=1), intent(in) :: sensor_line(1024)
11
+ end subroutine'''
12
+ return self.get_lib_function('add_sensor')(sensor_line, index_start, index_stop)
13
+
14
+ def echo_version(self, ):
15
+ '''subroutine echo_version() BIND(C, NAME='echo_version')
16
+ !DEC$ ATTRIBUTES DLLEXPORT :: echo_version
17
+ !GCC$ ATTRIBUTES DLLEXPORT :: echo_version
18
+ type (tbuildinfo) :: b
19
+ end subroutine'''
20
+ return self.get_lib_function('echo_version')()
21
+
22
+ def extern_write_log(self, c_msg, n, dll_name, error, warning):
23
+ '''subroutine extern_write_log(c_msg, n, dll_name, error, warning) bind(C, name="extern_write_log")
24
+ integer, intent(in) :: n
25
+ character(kind=c_char, len=1), intent(in) :: c_msg(n)
26
+ character(kind=c_char), intent(in) :: dll_name(50)
27
+ logical(kind=c_bool), intent(in), optional :: error, warning
28
+ character(kind=c_char, len=1), intent(in) :: c_msg(n_msg)
29
+ integer, intent(in) :: n_msg
30
+ character(kind=c_char), intent(in) :: dll_name(50)
31
+ character(len=50) :: n
32
+ logical(kind=c_bool), intent(in), optional :: error, warning
33
+ end subroutine'''
34
+ return self.get_lib_function('extern_write_log')(c_msg, n, dll_name, error, warning)
35
+
36
+ def fail(self, str_arr): # pragma: no cover
37
+ '''subroutine fail(str_arr) bind(C, name='fail')
38
+ character(kind=c_char, len=1), intent(inout) :: str_arr(255)
39
+ end subroutine'''
40
+ return self.get_lib_function('fail')(str_arr)
41
+
42
+ def finalize(self, ):
43
+ '''SUBROUTINE finalize() bind(C, name="finalize")
44
+ !DEC$ ATTRIBUTES DLLEXPORT :: finalize
45
+ integer:: i
46
+ real*4:: T2
47
+ END SUBROUTINE'''
48
+ return self.get_lib_function('finalize')()
49
+
50
+ def getSquare(self, val, restype):
51
+ '''function getSquare(val) result(valSquared) BIND(C, NAME='getSquare')
52
+ !DEC$ ATTRIBUTES DLLEXPORT :: getSquare
53
+ real(RK), intent(in) :: val
54
+ real(RK) :: valSquared
55
+ end function'''
56
+ return self.get_lib_function('getSquare')(val, restype=restype)
57
+
58
+ def getState(self, restype):
59
+ '''function getState() result(val) BIND(C, NAME='getState')
60
+ !DEC$ ATTRIBUTES DLLEXPORT :: getState
61
+ integer :: val
62
+ end function'''
63
+ return self.get_lib_function('getState')(restype=restype)
64
+
65
+ def get_aerosections_forces(self, rotor, Fxyz):
66
+ '''subroutine get_aerosections_forces(rotor, Fxyz) bind(C, name='get_aerosections_forces')
67
+ integer*8, intent(in) :: rotor
68
+ real(c_double),intent(out)::Fxyz(rotors_gl%rotor(rotor)%nbld, rotors_gl%rotor(rotor)%blade(1)%nsec, 3)
69
+ end subroutine'''
70
+ return self.get_lib_function('get_aerosections_forces')(rotor, Fxyz)
71
+
72
+ def get_aerosections_moments(self, rotor, Mxyz):
73
+ '''subroutine get_aerosections_moments(rotor, Mxyz) bind(C, name='get_aerosections_moments')
74
+ integer*8, intent(in) :: rotor
75
+ real(c_double),intent(out):: Mxyz(rotors_gl%rotor(rotor)%nbld, rotors_gl%rotor(rotor)%blade(1)%nsec, 3)
76
+ end subroutine'''
77
+ return self.get_lib_function('get_aerosections_moments')(rotor, Mxyz)
78
+
79
+ def get_aerosections_position(self, rotor, position):
80
+ '''subroutine get_aerosections_position(rotor, position) bind(C, name="get_aerosections_position")
81
+ integer*8, intent(in) :: rotor
82
+ real(c_double),intent(out) :: position(rotors_gl%rotor(rotor)%nbld, rotors_gl%rotor(rotor)%blade(1)%nsec, 3)
83
+ end subroutine'''
84
+ return self.get_lib_function('get_aerosections_position')(rotor, position)
85
+
86
+ def get_bem_grid(self, rotor, azi, rad):
87
+ '''subroutine get_bem_grid(rotor, azi, rad) bind(C, name="get_bem_grid")
88
+ integer*8, intent(in) :: rotor
89
+ real(c_double), intent(out) :: azi(rotors_gl%rotor(rotor)%dyn_induc%bem%nazi)
90
+ real(c_double), intent(out) :: rad(rotors_gl%rotor(rotor)%dyn_induc%bem%nrad)
91
+ end subroutine'''
92
+ return self.get_lib_function('get_bem_grid')(rotor, azi, rad)
93
+
94
+ def get_bem_grid_dim(self, rotor, nazi, nrad):
95
+ '''subroutine get_bem_grid_dim(rotor, nazi, nrad) bind(C, name="get_bem_grid_dim")
96
+ integer*8, intent(in) :: rotor
97
+ integer*8, intent(out) :: nazi, nrad
98
+ end subroutine'''
99
+ return self.get_lib_function('get_bem_grid_dim')(rotor, nazi, nrad)
100
+
101
+ def get_diameter(self, rotor, restype):
102
+ '''function get_diameter(rotor) bind(C, name="get_diameter")
103
+ !DEC$ ATTRIBUTES DLLEXPORT :: get_diameter
104
+ integer*8, intent(in) :: rotor
105
+ Type (Taerorotor),pointer :: rotor_p
106
+ real(c_double) :: get_diameter
107
+ end function'''
108
+ return self.get_lib_function('get_diameter')(rotor, restype=restype)
109
+
110
+ def get_induction_axisymmetric(self, rotor, induction):
111
+ '''subroutine get_induction_axisymmetric(rotor, induction) bind(C, name="get_induction_axisymmetric")
112
+ integer*8, intent(in) :: rotor
113
+ real(c_double),intent(out) :: induction(rotors_gl%rotor(rotor)%dyn_induc%bem%nrad)
114
+ end subroutine'''
115
+ return self.get_lib_function('get_induction_axisymmetric')(rotor, induction)
116
+
117
+ def get_induction_polargrid(self, rotor, induction):
118
+ '''subroutine get_induction_polargrid(rotor, induction) bind(C, name="get_induction_polargrid")
119
+ integer*8, intent(in) :: rotor
120
+ real(c_double),intent(out) :: induction(rotors_gl%rotor(rotor)%dyn_induc%bem%nazi, rotors_gl%rotor(rotor)%dyn_induc%bem%nrad)
121
+ end subroutine'''
122
+ return self.get_lib_function('get_induction_polargrid')(rotor, induction)
123
+
124
+ def get_induction_rotoravg(self, rotor, induction):
125
+ '''subroutine get_induction_rotoravg(rotor, induction) bind(C, name="get_induction_rotoravg")
126
+ !DEC$ ATTRIBUTES DLLEXPORT :: get_induction_rotoravg
127
+ integer*8, intent(in) :: rotor
128
+ real(c_double), intent(out) :: induction
129
+ end subroutine'''
130
+ return self.get_lib_function('get_induction_rotoravg')(rotor, induction)
131
+
132
+ def get_nSections(self, rotor, blade, restype):
133
+ '''function get_nSections(rotor, blade) bind(C, name="get_nSections")
134
+ !DEC$ ATTRIBUTES DLLEXPORT :: get_nSections
135
+ integer*8, intent(in) :: rotor, blade
136
+ integer*8 :: get_nSections
137
+ end function'''
138
+ return self.get_lib_function('get_nSections')(rotor, blade, restype=restype)
139
+
140
+ def get_nblades(self, rotor, restype):
141
+ '''function get_nblades(rotor) bind(C, name="get_nblades")
142
+ !DEC$ ATTRIBUTES DLLEXPORT :: get_nblades
143
+ integer*8, intent(in) :: rotor
144
+ integer*8 :: get_nblades
145
+ end function'''
146
+ return self.get_lib_function('get_nblades')(rotor, restype=restype)
147
+
148
+ def get_nrotors(self, restype):
149
+ '''function get_nrotors() bind(C, name="get_nrotors")
150
+ !DEC$ ATTRIBUTES DLLEXPORT :: get_nrotors
151
+ integer*8 :: get_nrotors
152
+ end function'''
153
+ return self.get_lib_function('get_nrotors')(restype=restype)
154
+
155
+ def get_rotor_avg_wsp(self, coo, rotor, wsp):
156
+ '''subroutine get_rotor_avg_wsp(coo, rotor, wsp) bind(C, name="get_rotor_avg_wsp")
157
+ integer*8, intent(in) :: rotor
158
+ integer*8, intent(in) :: coo ! 1: global, 2: rotor
159
+ real(c_double), dimension(3):: wsp
160
+ end subroutine'''
161
+ return self.get_lib_function('get_rotor_avg_wsp')(coo, rotor, wsp)
162
+
163
+ def get_rotor_orientation(self, rotor, yaw, tilt, azi):
164
+ '''subroutine get_rotor_orientation(rotor, yaw, tilt, azi) bind(C, name="get_rotor_orientation")
165
+ !DEC$ ATTRIBUTES DLLEXPORT :: get_rotor_orientation
166
+ integer*8, intent(in) :: rotor
167
+ real(c_double), intent(out) :: yaw, tilt, azi
168
+ end subroutine'''
169
+ return self.get_lib_function('get_rotor_orientation')(rotor, yaw, tilt, azi)
170
+
171
+ def get_rotor_position(self, rotor, position):
172
+ '''subroutine get_rotor_position(rotor, position) bind(C, name="get_rotor_position")
173
+ !DEC$ ATTRIBUTES DLLEXPORT :: get_rotor_position
174
+ integer*8, intent(in) :: rotor
175
+ real(c_double), dimension(3), intent(out) :: position
176
+ !DEC$ ATTRIBUTES DLLEXPORT :: get_rotor_avg_wsp
177
+ integer*8, intent(in) :: rotor
178
+ integer*8, intent(in) :: coo ! 1: global, 2: rotor
179
+ end subroutine'''
180
+ return self.get_lib_function('get_rotor_position')(rotor, position)
181
+
182
+ def get_sensor_info(self, id, name, unit, desc):
183
+ '''subroutine get_sensor_info(id, name, unit, desc) bind(C, name="get_sensor_info")
184
+ integer*8, intent(in) :: id
185
+ character(kind=c_char, len=1), intent(out) :: name(30), unit(10), desc(512)
186
+ end subroutine'''
187
+ return self.get_lib_function('get_sensor_info')(id, name, unit, desc)
188
+
189
+ def get_sensor_values(self, ids, values, n):
190
+ '''subroutine get_sensor_values(ids, values, n) bind(C, name="get_sensor_values")
191
+ integer*8, intent(in) :: n
192
+ integer*8, intent(in) :: ids(n)
193
+ real(c_double), intent(out) :: values(n)
194
+ end subroutine'''
195
+ return self.get_lib_function('get_sensor_values')(ids, values, n)
196
+
197
+ def get_time(self, time):
198
+ '''subroutine
199
+ subroutine'''
200
+ return self.get_lib_function('get_time')(time)
201
+
202
+ def get_version(self, s):
203
+ '''subroutine get_version(s) BIND(C, NAME='get_version')
204
+ character(kind=c_char, len=1), intent(inout) :: s(255)
205
+ end subroutine'''
206
+ return self.get_lib_function('get_version')(s)
207
+
208
+ def init(self, ):
209
+ '''subroutine init() bind(C, name="init")
210
+ !DEC$ ATTRIBUTES DLLEXPORT :: init
211
+ end subroutine'''
212
+ return self.get_lib_function('init')()
213
+
214
+ def init_windfield(self, Nxyz, dxyz, box_offset_yz, transport_speed):
215
+ '''subroutine init_windfield(Nxyz, dxyz, box_offset_yz, transport_speed) bind(C, name="init_windfield")
216
+ integer*8, dimension(3), intent(in) :: Nxyz
217
+ real*8 :: transport_speed
218
+ end subroutine'''
219
+ return self.get_lib_function('init_windfield')(Nxyz, dxyz, box_offset_yz, transport_speed)
220
+
221
+ def loop(self, N, restype):
222
+ '''function loop(N) bind(C, Name='loop')
223
+ !DEC$ ATTRIBUTES DLLEXPORT :: loop
224
+ integer*8, intent(in) :: N
225
+ real(c_double) :: loop,a
226
+ integer*8 :: i, j
227
+ end function'''
228
+ return self.get_lib_function('loop')(N, restype=restype)
229
+
230
+ def myfunction(self, int, dbl, restype):
231
+ '''function myfunction(int, dbl) bind(C, name='myfunction')
232
+ !DEC$ ATTRIBUTES DLLEXPORT :: myfunction
233
+ integer*8, intent(in) :: int
234
+ real(c_double), intent(in) :: dbl
235
+ real(c_double) :: myfunction
236
+ end function'''
237
+ return self.get_lib_function('myfunction')(int, dbl, restype=restype)
238
+
239
+ def mysubroutine(self, str_arr, dbl_arr):
240
+ '''subroutine mysubroutine(str_arr, dbl_arr) bind(C, name='mysubroutine')
241
+ character(kind=c_char, len=1), intent(inout) :: str_arr(20)
242
+ real(c_double), intent(inout), dimension(2) :: dbl_arr
243
+ end subroutine'''
244
+ return self.get_lib_function('mysubroutine')(str_arr, dbl_arr)
245
+
246
+ def read_input(self, htc_path):
247
+ '''subroutine read_input(htc_path) bind(C, name="read_input")
248
+ character(kind=c_char, len=1), intent(in) :: htc_path(1024)
249
+ end subroutine'''
250
+ return self.get_lib_function('read_input')(htc_path)
251
+
252
+ def run(self, time, restype):
253
+ '''function run(time) bind(C, name='run')
254
+ !DEC$ ATTRIBUTES DLLEXPORT :: run
255
+ real(c_double), intent(in) :: time
256
+ real(c_double) :: run, eps
257
+ end function'''
258
+ return self.get_lib_function('run')(time, restype=restype)
259
+
260
+ def setState(self, val):
261
+ '''subroutine setState(val) BIND(C, NAME='setState')
262
+ integer, intent(in) :: val
263
+ end subroutine'''
264
+ return self.get_lib_function('setState')(val)
265
+
266
+ def set_aerosections_windspeed(self, rotor, uvw):
267
+ '''subroutine set_aerosections_windspeed(rotor, uvw) bind(C, name="set_aerosections_windspeed")
268
+ integer*8, intent(in) :: rotor
269
+ real(c_double),intent(in) :: uvw(rotors_gl%rotor(rotor)%nbld, rotors_gl%rotor(rotor)%blade(1)%nsec, 3)
270
+ end subroutine'''
271
+ return self.get_lib_function('set_aerosections_windspeed')(rotor, uvw)
272
+
273
+ def set_variable_sensor_value(self, id, value):
274
+ '''subroutine set_variable_sensor_value(id, value) bind(C, name="set_variable_sensor_value")
275
+ integer*8, intent(in) :: id
276
+ real(c_double) :: value
277
+ end subroutine'''
278
+ return self.get_lib_function('set_variable_sensor_value')(id, value)
279
+
280
+ def set_windfield(self, uvw, box_offset_x, time):
281
+ '''subroutine set_windfield(uvw, box_offset_x, time) bind(C, name="set_windfield")
282
+ real*4, intent(in) :: uvw(3, gwsd%TMOD%buffer_points_x,gwsd%TMOD%buffer_points_y,gwsd%TMOD%buffer_points_z)
283
+ real*8, intent(in):: box_offset_x, time
284
+ end subroutine'''
285
+ return self.get_lib_function('set_windfield')(uvw, box_offset_x, time)
286
+
287
+ def sqr2(self, val):
288
+ '''subroutine sqr2(val) BIND(C, NAME='sqr2')
289
+ integer, intent(inout) :: val
290
+ end subroutine'''
291
+ return self.get_lib_function('sqr2')(val)
292
+
293
+ def step(self, restype):
294
+ '''function step() bind(C, name='step')
295
+ !DEC$ ATTRIBUTES DLLEXPORT :: step
296
+ real(c_double) :: step
297
+ end function'''
298
+ return self.get_lib_function('step')(restype=restype)
299
+
300
+ def test_hdf5(self, ):
301
+ '''subroutine test_hdf5() BIND(C, NAME='test_hdf5')
302
+ !DEC$ ATTRIBUTES DLLEXPORT :: test_hdf5
303
+ INTEGER :: hdferr ! Error flag
304
+ CHARACTER(9) :: filename = 'test.hdf5'
305
+ INTEGER(HID_T) :: file_id ! File identifier
306
+ INTEGER(HID_T) :: H5_Create_file,H5_Open_file ! File identifier
307
+ type(c_ptr) :: x
308
+ end subroutine'''
309
+ return self.get_lib_function('test_hdf5')()
310
+
311
+ def work(self, time, restype):
312
+ '''function work(time) bind(C, Name='work')
313
+ !DEC$ ATTRIBUTES DLLEXPORT :: work
314
+ real(c_double), intent(in) :: time
315
+ real*4 :: start_time, t
316
+ integer*8 :: N, work
317
+ end function'''
318
+ return self.get_lib_function('work')(time, restype=restype)
@@ -0,0 +1,18 @@
1
+ Metadata-Version: 2.1
2
+ Name: h2lib
3
+ Version: 13.0.705
4
+ Summary: Python interface to HAWC2 (13.0.9)
5
+ Download-URL:
6
+ Author: Mads M. Pedersen, S.G.Horcas and N.G.Ramos
7
+ Author-email: mmpe@dtu.dk
8
+ Maintainer:
9
+ Maintainer-email:
10
+ Project-URL: Documentation, https://hawc2.pages.windenergy.dtu.dk/HAWC2Lib/
11
+ Project-URL: Source, https://gitlab.windenergy.dtu.dk/HAWC2/HAWC2Lib
12
+ Project-URL: Tracker, https://gitlab.windenergy.dtu.dk/HAWC2/HAWC2Lib/-/issues
13
+ Requires-Dist: numpy
14
+ Requires-Dist: intel-fortran-rt ==2021.3.0
15
+ Requires-Dist: mkl ==2021.3.0
16
+ Provides-Extra: test
17
+ Requires-Dist: h2lib-tests ; extra == 'test'
18
+
@@ -0,0 +1,14 @@
1
+ h2lib/HAWC2Lib.dll,sha256=GhnrcvnvBrC_KxHN2Asm1U7Ak6SW1axLhiBGPocwAvw,29301760
2
+ h2lib/__init__.py,sha256=f3fO4I6IEFRM9LaV2O3w9Pioj3GPI8qRl7P5Tg5ONtE,528
3
+ h2lib/_h2lib.py,sha256=PvXyuoVW6IDbjeYWYtCHRYcpLMlZh7aCiJkfLBl88gg,14938
4
+ h2lib/_version.py,sha256=xyyOn5ozEvCx53n7O9Ht13YA4b22VWeehuYZqCSUdEk,146
5
+ h2lib/dll_wrapper.py,sha256=vO7IGbnPTpzrbjsvm-jRnYabXM97gCukJDTPJHDLEpA,11824
6
+ h2lib/h2lib_signatures.py,sha256=uIcqvgVbm_L5C4jpHc9mBqz_6G5sLIk_6n2i-j1oA04,14500
7
+ multiclass_interface/mpi_interface.py,sha256=eGftiuyQ3QkcenpEmbZjy_3VomWoXADnQsGUCFoFBvs,6274
8
+ multiclass_interface/multi_object_list.py,sha256=5bEdwvtzQkPyBrS-W64i3EHJmuTfNGmRhGm5ToK7SXI,2072
9
+ multiclass_interface/multiprocess_interface.py,sha256=L5G7-EL5rXQtze5-4oSTBFs0AjswbD2diNtt0ynfWOM,7271
10
+ multiclass_interface/my_test_cls.py,sha256=7ZDsFkxrLfOY6q00U5Y-daxfuhATK-K5H04RP-VmQdE,850
11
+ h2lib-13.0.705.dist-info/METADATA,sha256=54FEPqcr2y_3vR70shyoAVXYpWfUwFdJcDNWW-EFR3M,623
12
+ h2lib-13.0.705.dist-info/WHEEL,sha256=GZFS91_ufm4WrNPBaFVPB9MvOXR6bMZQhPcZRRTN5YM,100
13
+ h2lib-13.0.705.dist-info/top_level.txt,sha256=CafRr3oTgH80oaQrp2SGKlPcX7cag5ag4EGKAZAy1ow,27
14
+ h2lib-13.0.705.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: bdist_wheel (0.41.1)
2
+ Generator: bdist_wheel (0.42.0)
3
3
  Root-Is-Purelib: false
4
4
  Tag: cp39-cp39-win_amd64
5
5
 
@@ -0,0 +1,2 @@
1
+ h2lib
2
+ multiclass_interface
@@ -0,0 +1,184 @@
1
+ import numpy as np
2
+ import sys
3
+ import os
4
+ import subprocess
5
+ import traceback
6
+ import inspect
7
+ from enum import Enum
8
+
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
16
+
17
+ if mpi:
18
+ from mpi4py import MPI
19
+ comm = MPI.COMM_WORLD
20
+ size = MPI.COMM_WORLD.Get_size()
21
+ rank = MPI.COMM_WORLD.Get_rank()
22
+ name = MPI.Get_processor_name()
23
+ else:
24
+ size = 1
25
+
26
+ MPIClassInterfaceAttributes = {'close', 'use_rank', 'cls', 'work_loop', 'object', '__class__','get_input','do_task', 'run_task', 'closed'}
27
+
28
+
29
+ LOOP_UNTIL_CLOSE=True
30
+ TERMINATE_ON_CLOSE=True
31
+
32
+
33
+ class MPIClassInterface():
34
+ def __init__(self, cls, args_lst):
35
+ if len(args_lst) > size:
36
+ if rank == 0:
37
+ raise Exception(f"Not enough mpi slots. Slots: {size}, Requested: {len(args_lst)}")
38
+ return
39
+ self.cls = cls
40
+ if rank < len(args_lst):
41
+ self.object = cls(*args_lst[rank])
42
+ else:
43
+ class Dummy():
44
+ def close(self):
45
+ pass
46
+ self.object = Dummy()
47
+ self.closed=False
48
+
49
+ if rank == 0:
50
+ self.use_rank = np.array([True] * size)
51
+ self.use_rank[len(args_lst):] = False
52
+ elif LOOP_UNTIL_CLOSE:
53
+ self.work_loop()
54
+
55
+ def __enter__(self):
56
+ return self
57
+
58
+ def __exit__(self, exc_type, exc_val, exc_tb):
59
+ self.close()
60
+
61
+ def work_loop(self):
62
+ while True:
63
+ method, args, kwargs = comm.scatter(None)
64
+ comm.gather(self.do_task(method, args, kwargs))
65
+ if LOOP_UNTIL_CLOSE:
66
+ if method == 'close':
67
+ if TERMINATE_ON_CLOSE:
68
+ #comm.gather(f'Exit, rank {rank}')
69
+ print ("sys.exit", rank, flush=True)
70
+ sys.exit(0)
71
+ else:
72
+ raise ChildProcessError('MPI worker done')
73
+ else:
74
+ break
75
+
76
+
77
+ def do_task(self, method, args, kwargs):
78
+ try:
79
+ if method == 'skip':
80
+ res = None
81
+ elif method=='setattr':
82
+ name, value = args
83
+ if hasattr(value, '__call__'):
84
+ def wrap(*args, func=value, **kwargs):
85
+ if inspect.getfullargspec(func).args[:1] == ['self']:
86
+ args = (self.object,) + args
87
+ return func(*args, **kwargs)
88
+ value = wrap
89
+ res = setattr(self.object, name, value)
90
+ else:
91
+ res = getattr(self.object, method)
92
+ if hasattr(res, '__call__'):
93
+ res = res(*args, **kwargs)
94
+ except BaseException as e:
95
+ res = (e, traceback.format_exc())
96
+ return res
97
+
98
+ def run_task(self, input_lst):
99
+ comm.scatter(input_lst, root=0)
100
+ if rank == 0:
101
+ method, args, kwargs = input_lst[0]
102
+ res = self.do_task(method, args, kwargs)
103
+ else:
104
+ res = None
105
+ use_rank = self.use_rank
106
+
107
+ res = [res for i, res in enumerate(comm.gather(res, root=0)) if use_rank[i]]
108
+ if rank==0:
109
+ for r in res:
110
+ if isinstance(r, tuple) and len(r) > 1 and isinstance(r[0], BaseException):
111
+ raise r[0].__class__(r[1])
112
+ return res
113
+
114
+
115
+ def get_input(self, name, i, args, kwargs):
116
+ use_rank = self.use_rank
117
+ N = np.sum(use_rank)
118
+ if use_rank[i]:
119
+ def get_arg(arg):
120
+ if isinstance(arg, list) and len(arg) == N:
121
+ return arg[np.where(use_rank)[0][i]]
122
+ else:
123
+ return arg
124
+ return (name, [get_arg(arg) for arg in args], {k: get_arg(v) for k, v in kwargs.items()})
125
+ else:
126
+ return ('skip', [], {})
127
+
128
+ def __getattribute__(self, name):
129
+ if name in MPIClassInterfaceAttributes:
130
+ return object.__getattribute__(self, name)
131
+ elif rank > 0:
132
+ self.work_loop()
133
+ return lambda *args, **kwargs:1
134
+
135
+ def wrap(*args, **kwargs):
136
+ inp = [self.get_input(name, i, args, kwargs) for i in range(size)]
137
+ return self.run_task(inp)
138
+
139
+ if hasattr(getattr(self.object, name), '__call__'):
140
+ return wrap
141
+ else:
142
+ return wrap()
143
+
144
+ def __setattr__(self, name, value):
145
+ if rank > 0 or name in MPIClassInterfaceAttributes:
146
+ return object.__setattr__(self, name, value)
147
+ else:
148
+ inp = [self.get_input('setattr', i, (name, value), {}) for i in range(size)]
149
+ return self.run_task(inp)
150
+
151
+
152
+ def __getitem__(self, slice):
153
+ use_rank = np.full_like(self.use_rank, False)
154
+ use_rank[slice] = True
155
+ if np.all(self.use_rank == use_rank):
156
+ return self
157
+ return SubsetMPIClassInterface(self.cls, self.object, use_rank)
158
+
159
+ def close(self):
160
+ if not self.closed:
161
+ if rank==0:
162
+ res = self.run_task([('close', [], {}) for _ in range(size)])
163
+ else:
164
+ self.work_loop()
165
+ res = None
166
+ self.closed=True
167
+
168
+
169
+
170
+
171
+ class SubsetMPIClassInterface(MPIClassInterface):
172
+ def __init__(self, cls, object, use_rank):
173
+ self.use_rank = use_rank
174
+ self.cls = cls
175
+ self.object = object
176
+
177
+ def __getitem__(self, slice):
178
+ l = np.arange(np.sum(self.use_rank))
179
+ if np.all(l == l[slice]):
180
+ return self
181
+ raise Exception('Cannot make subset of SubsetMPIClassInterface')
182
+
183
+ def close(self):
184
+ raise Exception('Cannot close SubsetMPIClassInterface. Please close all instances at once')
@@ -0,0 +1,57 @@
1
+ import numpy as np
2
+
3
+
4
+ class MultiObjectList():
5
+ def __init__(self, obj_lst, subset_cls=None):
6
+ self.obj_lst = np.atleast_1d(obj_lst)
7
+ self.subset_cls = subset_cls
8
+
9
+ def __str__(self):
10
+ return f'{self.__class__.__name__}({self.obj_lst})'
11
+
12
+ def get_obj_args_lst(self, args, kwargs):
13
+ N = len(self.obj_lst)
14
+
15
+ def get_obj_args(i):
16
+ def get_arg(arg):
17
+ if isinstance(arg, list) and len(arg) == N:
18
+ return arg[i]
19
+ else:
20
+ return arg
21
+ obj_args = [get_arg(arg) for arg in args]
22
+ obj_kwargs = {k: get_arg(v) for k, v in kwargs.items()}
23
+ return obj_args, obj_kwargs
24
+ return [get_obj_args(i) for i in range(N)]
25
+
26
+ def iscallable(self, name):
27
+ return hasattr(getattr(self.obj_lst[0], name), '__call__')
28
+
29
+ def __getitem__(self, s):
30
+ obj_lst = np.atleast_1d(self.obj_lst[s])
31
+ if len(obj_lst) == len(self.obj_lst) and np.all(obj_lst == self.obj_lst):
32
+ return self
33
+ subset_cls = self.subset_cls or MultiObjectList
34
+ return subset_cls(self.obj_lst[s])
35
+
36
+ def __getattr__(self, name):
37
+ att_lst = [getattr(obj, name) for obj in self.obj_lst]
38
+ if self.iscallable(name):
39
+ def wrap(*args, **kwargs):
40
+ return [att(*o_args, **o_kwargs)
41
+ for att, (o_args, o_kwargs) in zip(att_lst, self.get_obj_args_lst(args, kwargs))]
42
+ return wrap
43
+ else:
44
+ return att_lst
45
+
46
+ def __setattr__(self, name, value):
47
+ if name in {'obj_lst', 'subset_cls'}:
48
+ return object.__setattr__(self, name, value)
49
+ obj_lst = self.obj_lst
50
+ for obj, (o_args, _) in zip(obj_lst, self.get_obj_args_lst((value,), {})):
51
+ setattr(obj, name, *o_args)
52
+
53
+
54
+ class MultiClassInterface(MultiObjectList):
55
+ def __init__(self, cls, args_lst):
56
+ self.cls = cls
57
+ MultiObjectList.__init__(self, [cls(*args) for args in args_lst])