h2lib 13.0.604__cp38-cp38-win_amd64.whl → 13.0.705__cp38-cp38-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.
- h2lib/HAWC2Lib.dll +0 -0
- h2lib/_h2lib.py +116 -46
- h2lib/_version.py +3 -3
- h2lib/dll_wrapper.py +83 -77
- h2lib/h2lib_signatures.py +85 -43
- h2lib-13.0.705.dist-info/METADATA +18 -0
- h2lib-13.0.705.dist-info/RECORD +14 -0
- {h2lib-13.0.604.dist-info → h2lib-13.0.705.dist-info}/WHEEL +1 -1
- h2lib-13.0.705.dist-info/top_level.txt +2 -0
- multiclass_interface/mpi_interface.py +184 -0
- multiclass_interface/multi_object_list.py +57 -0
- multiclass_interface/multiprocess_interface.py +184 -0
- multiclass_interface/my_test_cls.py +33 -0
- h2lib/utils.py +0 -149
- h2lib-13.0.604.dist-info/METADATA +0 -15
- h2lib-13.0.604.dist-info/RECORD +0 -11
- h2lib-13.0.604.dist-info/top_level.txt +0 -1
@@ -0,0 +1,184 @@
|
|
1
|
+
import multiprocessing
|
2
|
+
import atexit
|
3
|
+
import numpy as np
|
4
|
+
from threading import Thread
|
5
|
+
from functools import wraps
|
6
|
+
import traceback
|
7
|
+
from _queue import Empty
|
8
|
+
import os
|
9
|
+
from contextlib import contextmanager
|
10
|
+
import sys
|
11
|
+
import inspect
|
12
|
+
from multiclass_interface.multi_object_list import MultiObjectList
|
13
|
+
|
14
|
+
|
15
|
+
def run(cls, inputQueue, outputQueue, cls_args, **kwargs):
|
16
|
+
o = cls(*cls_args, **kwargs)
|
17
|
+
while True:
|
18
|
+
method, args, kwargs = inputQueue.get()
|
19
|
+
try:
|
20
|
+
if method == 'getattr':
|
21
|
+
name = args[0]
|
22
|
+
outputQueue.put(getattr(o, name))
|
23
|
+
elif method == 'setattr':
|
24
|
+
name, value = args
|
25
|
+
if hasattr(value, '__call__'): # pragma: no cover # cov not registered?
|
26
|
+
|
27
|
+
def wrap(*args, func=value, **kwargs):
|
28
|
+
if inspect.getfullargspec(func).args[:1] == ['self']:
|
29
|
+
args = (o,) + args
|
30
|
+
return func(*args, **kwargs)
|
31
|
+
outputQueue.put(setattr(o, name, wrap))
|
32
|
+
else:
|
33
|
+
outputQueue.put(setattr(o, name, value))
|
34
|
+
elif method == 'iscallable':
|
35
|
+
name = args[0]
|
36
|
+
outputQueue.put(hasattr(getattr(o, name), '__call__'))
|
37
|
+
else:
|
38
|
+
att = getattr(o, method)
|
39
|
+
outputQueue.put(att(*args, **kwargs))
|
40
|
+
if method == 'close':
|
41
|
+
outputQueue.put('Exit process')
|
42
|
+
return
|
43
|
+
except BaseException as e:
|
44
|
+
outputQueue.put((e, traceback.format_exc()))
|
45
|
+
|
46
|
+
|
47
|
+
class ProcessClass():
|
48
|
+
cls = None
|
49
|
+
|
50
|
+
def __init__(self, cls, cls_attrs={}):
|
51
|
+
self.cls_attrs = cls_attrs
|
52
|
+
self.cls = cls
|
53
|
+
self.ctx = multiprocessing.get_context('spawn')
|
54
|
+
self.inputQueue = self.ctx.Queue()
|
55
|
+
self.outputQueue = self.ctx.Queue()
|
56
|
+
atexit.register(self.close)
|
57
|
+
self.closed = False
|
58
|
+
|
59
|
+
def __call__(self, *args, **kwargs):
|
60
|
+
kwargs.update({'cls': self.cls, 'inputQueue': self.inputQueue, 'outputQueue': self.outputQueue,
|
61
|
+
'cls_args': args})
|
62
|
+
s = 'vs_debug.py'
|
63
|
+
if s in "".join(traceback.format_stack()): # pragma: no cover
|
64
|
+
self.process = Thread(target=run, kwargs=kwargs) # use this to debug from Visual studio
|
65
|
+
else:
|
66
|
+
self.process = self.ctx.Process(target=run, kwargs=kwargs, daemon=True)
|
67
|
+
|
68
|
+
self.process.start()
|
69
|
+
return self
|
70
|
+
|
71
|
+
def __enter__(self):
|
72
|
+
return self
|
73
|
+
|
74
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
75
|
+
self.close()
|
76
|
+
|
77
|
+
def __getattribute__(self, name):
|
78
|
+
try:
|
79
|
+
if name != 'cls_attrs' and name in self.cls_attrs:
|
80
|
+
raise AttributeError()
|
81
|
+
return object.__getattribute__(self, name)
|
82
|
+
except AttributeError:
|
83
|
+
if self.is_callable(name):
|
84
|
+
@wraps(getattr(self.cls, name, None))
|
85
|
+
def wrap(*args, wait_for_result=True, **kwargs):
|
86
|
+
self.inputQueue.put((name, args, kwargs))
|
87
|
+
if wait_for_result:
|
88
|
+
return self.get_result(raise_exception=True,
|
89
|
+
cmd=lambda: f'executing {name}({", ".join(list(map(str,args))+["%s=%s"%(k,v) for k,v in kwargs.items()])})')
|
90
|
+
return wrap
|
91
|
+
else:
|
92
|
+
self.inputQueue.put(('getattr', (name,), {}))
|
93
|
+
return self.get_result(raise_exception=True, cmd=lambda: f"getting attribute '{name}'")
|
94
|
+
|
95
|
+
def is_callable(self, name):
|
96
|
+
self.inputQueue.put(('iscallable', (name,), {}))
|
97
|
+
return self.get_result(raise_exception=True, cmd=lambda: f"checking if '{name}' is callable")
|
98
|
+
|
99
|
+
def __setattr__(self, name, value):
|
100
|
+
if name in {'cls', 'ctx', 'inputQueue', 'outputQueue', 'closed', 'process', 'cls_attrs'}:
|
101
|
+
return object.__setattr__(self, name, value)
|
102
|
+
else:
|
103
|
+
self.inputQueue.put(('setattr', (name, value), {}))
|
104
|
+
return self.get_result(raise_exception=True, cmd=lambda: f"setting attribute '{name}'")
|
105
|
+
|
106
|
+
def get_result(self, raise_exception, cmd):
|
107
|
+
while True:
|
108
|
+
if self.process.is_alive() or self.closed:
|
109
|
+
try:
|
110
|
+
res = self.outputQueue.get(timeout=2)
|
111
|
+
if isinstance(res, tuple) and len(res) > 1 and isinstance(res[0], BaseException):
|
112
|
+
res = res[0].__class__(res[1])
|
113
|
+
if raise_exception:
|
114
|
+
raise res
|
115
|
+
return res
|
116
|
+
except Empty:
|
117
|
+
pass # time out. Check process is alive and try again
|
118
|
+
else:
|
119
|
+
if hasattr(cmd, '__call__'):
|
120
|
+
cmd = cmd()
|
121
|
+
e = Exception(f'{self.cls.__name__} process died before or while {cmd}')
|
122
|
+
if raise_exception:
|
123
|
+
raise e
|
124
|
+
return e
|
125
|
+
|
126
|
+
def close(self, wait_for_result=False):
|
127
|
+
if not self.closed:
|
128
|
+
self.inputQueue.put(('close', [], {}))
|
129
|
+
r = self.get_result(False, 'close')
|
130
|
+
self.process.join()
|
131
|
+
self.inputQueue.close()
|
132
|
+
self.outputQueue.close()
|
133
|
+
self.closed = True
|
134
|
+
return r
|
135
|
+
|
136
|
+
|
137
|
+
class MultiProcessClassInterface(MultiObjectList):
|
138
|
+
|
139
|
+
def __init__(self, cls, args_lst, cls_attrs={}):
|
140
|
+
MultiObjectList.__init__(self, [ProcessClass(cls, cls_attrs)(*args) for args in args_lst], SubsetProcessWrapper)
|
141
|
+
|
142
|
+
def __getattr__(self, name):
|
143
|
+
obj_lst = self.obj_lst
|
144
|
+
if obj_lst[0].is_callable(name):
|
145
|
+
def wrap(*args, **kwargs):
|
146
|
+
for obj, (o_args, o_kwargs) in zip(obj_lst, self.get_obj_args_lst(args, kwargs)):
|
147
|
+
getattr(obj, name)(*o_args, wait_for_result=False, **o_kwargs)
|
148
|
+
res = [o.get_result(raise_exception=False, cmd=lambda: f"executing {name}(...)")
|
149
|
+
for o in obj_lst]
|
150
|
+
for r in res:
|
151
|
+
if isinstance(r, Exception):
|
152
|
+
raise r
|
153
|
+
return res
|
154
|
+
return wrap
|
155
|
+
else:
|
156
|
+
return [getattr(o, name) for o in obj_lst]
|
157
|
+
|
158
|
+
def __enter__(self):
|
159
|
+
return self
|
160
|
+
|
161
|
+
def __exit__(self, exc_type, exc_val, exc_tb):
|
162
|
+
self.close()
|
163
|
+
|
164
|
+
def close(self, wait_for_result=False):
|
165
|
+
for obj in self.obj_lst:
|
166
|
+
obj.inputQueue.put(('close', [], {}))
|
167
|
+
obj.process.join()
|
168
|
+
obj.closed = True
|
169
|
+
|
170
|
+
|
171
|
+
class SubsetProcessWrapper(MultiProcessClassInterface):
|
172
|
+
def __init__(self, obj_lst):
|
173
|
+
MultiObjectList.__init__(self, obj_lst)
|
174
|
+
|
175
|
+
def __getitem__(self, slice):
|
176
|
+
if np.all(np.atleast_1d(self.obj_lst[slice]) == self.obj_lst):
|
177
|
+
return self
|
178
|
+
raise Exception('Cannot make subset of SubsetProcessWrapper')
|
179
|
+
|
180
|
+
def __getattribute__(self, name):
|
181
|
+
if name == 'close':
|
182
|
+
raise Exception("Cannot close SubsetProcessWrapper. Please close all instances at once")
|
183
|
+
|
184
|
+
return MultiProcessClassInterface.__getattribute__(self, name)
|
@@ -0,0 +1,33 @@
|
|
1
|
+
import time
|
2
|
+
import os
|
3
|
+
|
4
|
+
|
5
|
+
class MyTest():
|
6
|
+
def __init__(self, id):
|
7
|
+
self.id = id
|
8
|
+
self.name = self.__class__.__name__
|
9
|
+
|
10
|
+
def get_id(self,):
|
11
|
+
return self.id
|
12
|
+
|
13
|
+
def work(self, t):
|
14
|
+
start_time = time.time()
|
15
|
+
s1 = f'{self.id} starts working for {t}s at t={start_time}. '
|
16
|
+
# print (s1)
|
17
|
+
while time.time() < start_time + t:
|
18
|
+
pass
|
19
|
+
s2 = f'{self.id} ends working at {time.time()}.'
|
20
|
+
# print (s2)
|
21
|
+
return s1 + s2
|
22
|
+
|
23
|
+
def return_input(self, *args, **kwargs):
|
24
|
+
return f"{self.id} got: {str(args)} and {str(kwargs)}"
|
25
|
+
|
26
|
+
def get_ld_library_path(self):
|
27
|
+
return os.environ['LD_LIBRARY_PATH']
|
28
|
+
|
29
|
+
def close(self):
|
30
|
+
return f"closing {self.get_id()}"
|
31
|
+
|
32
|
+
def raise_exception(self):
|
33
|
+
1 / 0 # raise ZeroDivisionError
|
h2lib/utils.py
DELETED
@@ -1,149 +0,0 @@
|
|
1
|
-
import multiprocessing
|
2
|
-
import atexit
|
3
|
-
import numpy as np
|
4
|
-
from threading import Thread
|
5
|
-
from functools import wraps
|
6
|
-
import traceback
|
7
|
-
|
8
|
-
|
9
|
-
def run(cls, inputQueue, outputQueue, cls_args, **kwargs):
|
10
|
-
o = cls(*cls_args, **kwargs)
|
11
|
-
while True:
|
12
|
-
method, args, kwargs = inputQueue.get()
|
13
|
-
# if method == "Sentinel":
|
14
|
-
# outputQueue.put(method)
|
15
|
-
# else:
|
16
|
-
# print(method, args, kwargs)
|
17
|
-
att = getattr(o, method)
|
18
|
-
if hasattr(att, '__call__'):
|
19
|
-
outputQueue.put(att(*args, **kwargs))
|
20
|
-
else:
|
21
|
-
outputQueue.put(att)
|
22
|
-
if method == 'close':
|
23
|
-
outputQueue.put('Exit process')
|
24
|
-
return
|
25
|
-
|
26
|
-
|
27
|
-
class ProcessClass():
|
28
|
-
cls = None
|
29
|
-
|
30
|
-
def __init__(self, cls, cls_attrs={}):
|
31
|
-
self.cls_attrs = cls_attrs
|
32
|
-
self.cls = cls
|
33
|
-
self.ctx = multiprocessing.get_context('spawn')
|
34
|
-
self.inputQueue = self.ctx.Queue()
|
35
|
-
self.outputQueue = self.ctx.Queue()
|
36
|
-
atexit.register(self.close)
|
37
|
-
self.closed = False
|
38
|
-
|
39
|
-
def __call__(self, *args, **kwargs):
|
40
|
-
kwargs.update({'cls': self.cls, 'inputQueue': self.inputQueue, 'outputQueue': self.outputQueue,
|
41
|
-
'cls_args': args})
|
42
|
-
s = 'vs_debug.py'
|
43
|
-
if s in "".join(traceback.format_stack()): # pragma: no cover
|
44
|
-
self.process = Thread(target=run, kwargs=kwargs) # use this to debug from Visual studio
|
45
|
-
else:
|
46
|
-
self.process = self.ctx.Process(target=run, kwargs=kwargs, daemon=True)
|
47
|
-
|
48
|
-
self.process.start()
|
49
|
-
return self
|
50
|
-
|
51
|
-
def __enter__(self):
|
52
|
-
return self
|
53
|
-
|
54
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
55
|
-
self.close()
|
56
|
-
|
57
|
-
def __getattribute__(self, name):
|
58
|
-
try:
|
59
|
-
if name != 'cls_attrs' and name in self.cls_attrs:
|
60
|
-
raise AttributeError()
|
61
|
-
return object.__getattribute__(self, name)
|
62
|
-
except AttributeError:
|
63
|
-
if hasattr(self.cls, name):
|
64
|
-
if hasattr(getattr(self.cls, name), '__call__'):
|
65
|
-
@wraps(getattr(self.cls, name))
|
66
|
-
def wrap(*args, wait_for_result=True, **kwargs):
|
67
|
-
self.inputQueue.put((name, args, kwargs))
|
68
|
-
if wait_for_result:
|
69
|
-
return self.get_result()
|
70
|
-
return wrap
|
71
|
-
else:
|
72
|
-
self.inputQueue.put((name, (), {}))
|
73
|
-
return self.get_result()
|
74
|
-
else:
|
75
|
-
raise AttributeError(f"'{self.cls.__name__}' object has no attribute '{name}'")
|
76
|
-
|
77
|
-
def get_result(self):
|
78
|
-
if self.process.is_alive() or self.closed:
|
79
|
-
return self.outputQueue.get()
|
80
|
-
# self.inputQueue.put(('Sentinel', (), {}))
|
81
|
-
# res_lst = []
|
82
|
-
# print('get result')
|
83
|
-
# while True:
|
84
|
-
# print('get')
|
85
|
-
# r = self.outputQueue.get()
|
86
|
-
# print(' got')
|
87
|
-
#
|
88
|
-
# if isinstance(r, str):
|
89
|
-
# if r == 'Exit process':
|
90
|
-
# return r
|
91
|
-
# elif r == 'Sentinel':
|
92
|
-
# return res_lst[0]
|
93
|
-
# else:
|
94
|
-
# res_lst.append(r)
|
95
|
-
# else:
|
96
|
-
# res_lst.append(r)
|
97
|
-
|
98
|
-
raise Exception(f'{self.cls.__name__} process died')
|
99
|
-
|
100
|
-
def close(self, wait_for_result=False):
|
101
|
-
self.inputQueue.put(('close', [], {}))
|
102
|
-
self.process.join()
|
103
|
-
self.closed = True
|
104
|
-
|
105
|
-
|
106
|
-
class MultiProcessInterface():
|
107
|
-
def __init__(self, cls, args_lst):
|
108
|
-
self.cls = cls
|
109
|
-
self.obj_lst = [ProcessClass(cls)(*args) for args in args_lst]
|
110
|
-
|
111
|
-
def __getattribute__(self, name):
|
112
|
-
if name in ['obj_lst']:
|
113
|
-
return object.__getattribute__(self, name)
|
114
|
-
|
115
|
-
a_lst = self.obj_lst
|
116
|
-
if hasattr(getattr(self.obj_lst[0], name), '__call__'):
|
117
|
-
def wrap(*args, **kwargs):
|
118
|
-
for i, o in enumerate(self.obj_lst):
|
119
|
-
def get_arg(arg):
|
120
|
-
if isinstance(arg, list) and len(arg) == len(a_lst):
|
121
|
-
return arg[i]
|
122
|
-
else:
|
123
|
-
return arg
|
124
|
-
a_args = [get_arg(arg) for arg in args]
|
125
|
-
a_kwargs = {k: get_arg(v) for k, v in kwargs.items()}
|
126
|
-
getattr(o, name)(*a_args, wait_for_result=False, **a_kwargs)
|
127
|
-
if isinstance(self, SubsetProcessWrapper) and len(self.obj_lst) == 1:
|
128
|
-
return self.obj_lst[0].get_result()
|
129
|
-
return [o.get_result() for o in self.obj_lst]
|
130
|
-
return wrap
|
131
|
-
else:
|
132
|
-
if isinstance(self, SubsetProcessWrapper) and len(self.obj_lst) == 1:
|
133
|
-
return getattr(self.obj_lst[0], name)
|
134
|
-
return [getattr(o, name) for o in self.obj_lst]
|
135
|
-
|
136
|
-
def __getitem__(self, slice):
|
137
|
-
lst = np.atleast_1d(np.array(self.obj_lst)[slice]).tolist()
|
138
|
-
return SubsetProcessWrapper(lst)
|
139
|
-
|
140
|
-
def __enter__(self):
|
141
|
-
return self
|
142
|
-
|
143
|
-
def __exit__(self, exc_type, exc_val, exc_tb):
|
144
|
-
self.close()
|
145
|
-
|
146
|
-
|
147
|
-
class SubsetProcessWrapper(MultiProcessInterface):
|
148
|
-
def __init__(self, obj_lst):
|
149
|
-
self.obj_lst = obj_lst
|
@@ -1,15 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: h2lib
|
3
|
-
Version: 13.0.604
|
4
|
-
Summary: Python interface to HAWC2 (13.0.6+5-g438f4c5)
|
5
|
-
Download-URL:
|
6
|
-
Author: S.G.Horcas and N.G.Ramos
|
7
|
-
Author-email:
|
8
|
-
Maintainer:
|
9
|
-
Maintainer-email:
|
10
|
-
Requires-Dist: numpy
|
11
|
-
Requires-Dist: intel-fortran-rt ==2021.3.0
|
12
|
-
Requires-Dist: mkl ==2021.3.0
|
13
|
-
Provides-Extra: test
|
14
|
-
Requires-Dist: h2lib-tests ; extra == 'test'
|
15
|
-
|
h2lib-13.0.604.dist-info/RECORD
DELETED
@@ -1,11 +0,0 @@
|
|
1
|
-
h2lib/HAWC2Lib.dll,sha256=UJUTEQmd7XG_pjM92kNDutX_fNX9YQzlMpg9UFm2kIE,29309952
|
2
|
-
h2lib/__init__.py,sha256=f3fO4I6IEFRM9LaV2O3w9Pioj3GPI8qRl7P5Tg5ONtE,528
|
3
|
-
h2lib/_h2lib.py,sha256=bW67zt5aBWshTCNMM3BV10xvrPGs-8uTrMo65AbskEA,12011
|
4
|
-
h2lib/_version.py,sha256=JOfUkYqbKt7CtLcwwE8OpdNNvdDbDsa-8kVL-OEpFhU,157
|
5
|
-
h2lib/dll_wrapper.py,sha256=jFCcT1gnjIl6k_I5nvzeLgG75I0D5VTiWwwWKV7M77w,11962
|
6
|
-
h2lib/h2lib_signatures.py,sha256=u-xOD-7dpoxOtG2K5a9ARHzchpg-nBV6Grt4iBDXV1o,12811
|
7
|
-
h2lib/utils.py,sha256=5EtSX4ByKg19TaI8EHtWa_C6A9jc6j5zGU1p0NHp6L0,5400
|
8
|
-
h2lib-13.0.604.dist-info/METADATA,sha256=ytTx9p2B2dLeHd_7iBFNgn1msrx7fvPu-v6w2Uek0Fg,378
|
9
|
-
h2lib-13.0.604.dist-info/WHEEL,sha256=KplWMgwSZbeAOumvxNxIrVbNPnn_LVzfBH7l38jDCVM,100
|
10
|
-
h2lib-13.0.604.dist-info/top_level.txt,sha256=y_a-tUqphEZQ_0nsWSMaSb21P8Lsd8hUxUdE9g2Dcbk,6
|
11
|
-
h2lib-13.0.604.dist-info/RECORD,,
|
@@ -1 +0,0 @@
|
|
1
|
-
h2lib
|