PaIRS-UniNa 0.2.4__cp310-cp310-macosx_10_9_universal2.whl → 0.2.6__cp310-cp310-macosx_10_9_universal2.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.
- PaIRS_UniNa/Changes.txt +35 -0
- PaIRS_UniNa/Custom_Top.py +1 -1
- PaIRS_UniNa/Explorer.py +3063 -3049
- PaIRS_UniNa/FolderLoop.py +371 -371
- PaIRS_UniNa/Input_Tab.py +717 -709
- PaIRS_UniNa/Input_Tab_CalVi.py +4 -4
- PaIRS_UniNa/Input_Tab_tools.py +3018 -3009
- PaIRS_UniNa/Output_Tab.py +2 -2
- PaIRS_UniNa/PaIRS.py +17 -17
- PaIRS_UniNa/PaIRS_PIV.py +56 -1
- PaIRS_UniNa/PaIRS_pypacks.py +323 -60
- PaIRS_UniNa/Process_Tab.py +8 -13
- PaIRS_UniNa/Process_Tab_Disp.py +9 -4
- PaIRS_UniNa/Saving_tools.py +277 -277
- PaIRS_UniNa/TabTools.py +63 -21
- PaIRS_UniNa/Vis_Tab.py +293 -115
- PaIRS_UniNa/Whatsnew.py +13 -0
- PaIRS_UniNa/_PaIRS_PIV.so +0 -0
- PaIRS_UniNa/__init__.py +3 -3
- PaIRS_UniNa/gPaIRS.py +3825 -3600
- PaIRS_UniNa/icons/flaticon_PaIRS_download_warning.png +0 -0
- PaIRS_UniNa/icons/pylog.png +0 -0
- PaIRS_UniNa/icons/python_warning.png +0 -0
- PaIRS_UniNa/icons/queue.png +0 -0
- PaIRS_UniNa/icons/uninitialized.png +0 -0
- PaIRS_UniNa/icons/window.png +0 -0
- PaIRS_UniNa/listLib.py +301 -301
- PaIRS_UniNa/parForMulti.py +433 -433
- PaIRS_UniNa/parForWorkers.py +46 -1
- PaIRS_UniNa/pivParFor.py +1 -1
- PaIRS_UniNa/procTools.py +17 -7
- PaIRS_UniNa/rqrdpckgs.txt +9 -0
- PaIRS_UniNa/stereo.py +683 -683
- PaIRS_UniNa/stereoPivParFor.py +1 -1
- PaIRS_UniNa/tabSplitter.py +606 -606
- PaIRS_UniNa/ui_Calibration_Tab.py +542 -542
- PaIRS_UniNa/ui_Custom_Top.py +294 -294
- PaIRS_UniNa/ui_Input_Tab.py +1098 -1098
- PaIRS_UniNa/ui_Input_Tab_CalVi.py +1280 -1280
- PaIRS_UniNa/ui_Log_Tab.py +261 -261
- PaIRS_UniNa/ui_Output_Tab.py +2360 -2360
- PaIRS_UniNa/ui_Process_Tab.py +3808 -3808
- PaIRS_UniNa/ui_Process_Tab_CalVi.py +1547 -1547
- PaIRS_UniNa/ui_Process_Tab_Disp.py +1139 -968
- PaIRS_UniNa/ui_Process_Tab_Min.py +435 -435
- PaIRS_UniNa/ui_ResizePopup.py +203 -203
- PaIRS_UniNa/ui_Vis_Tab.py +1626 -1533
- PaIRS_UniNa/ui_Vis_Tab_CalVi.py +1249 -1249
- PaIRS_UniNa/ui_Whatsnew.py +131 -131
- PaIRS_UniNa/ui_gPairs.py +873 -849
- PaIRS_UniNa/ui_infoPaIRS.py +550 -428
- PaIRS_UniNa/whatsnew.txt +4 -4
- {PaIRS_UniNa-0.2.4.dist-info → pairs_unina-0.2.6.dist-info}/METADATA +47 -30
- {PaIRS_UniNa-0.2.4.dist-info → pairs_unina-0.2.6.dist-info}/RECORD +56 -54
- {PaIRS_UniNa-0.2.4.dist-info → pairs_unina-0.2.6.dist-info}/WHEEL +1 -1
- PaIRS_UniNa/icons/order.png +0 -0
- PaIRS_UniNa/icons/order_reverse.png +0 -0
- PaIRS_UniNa/icons/run_piv.png +0 -0
- PaIRS_UniNa-0.2.4.dist-info/LICENSE +0 -19
- {PaIRS_UniNa-0.2.4.dist-info → pairs_unina-0.2.6.dist-info}/top_level.txt +0 -0
PaIRS_UniNa/parForMulti.py
CHANGED
|
@@ -1,435 +1,435 @@
|
|
|
1
|
-
''' Parallel for for PIV '''
|
|
2
|
-
#import os
|
|
3
|
-
import traceback
|
|
4
|
-
import queue
|
|
5
|
-
import asyncio
|
|
6
|
-
#import random
|
|
7
|
-
import multiprocessing as mp
|
|
8
|
-
from time import sleep, time
|
|
1
|
+
''' Parallel for for PIV '''
|
|
2
|
+
#import os
|
|
3
|
+
import traceback
|
|
4
|
+
import queue
|
|
5
|
+
import asyncio
|
|
6
|
+
#import random
|
|
7
|
+
import multiprocessing as mp
|
|
8
|
+
from time import sleep, time
|
|
9
9
|
from .tAVarie import PrintTA, PrintTAPriority
|
|
10
10
|
from .__init__ import __version__,__year__,__mail__
|
|
11
|
-
#import numpy as np
|
|
12
|
-
#import scipy as sc
|
|
13
|
-
|
|
14
|
-
prTime=PrintTA(PrintTA.blue, PrintTA.faceStd, PrintTAPriority.medium).prTime
|
|
15
|
-
pr=PrintTA(PrintTA.blue, PrintTA.faceStd, PrintTAPriority.medium).prTime
|
|
16
|
-
# pylint: disable=unused-argument
|
|
17
|
-
lock=None
|
|
18
|
-
def prLock( *args,**kwargs):
|
|
19
|
-
''' print in parallel pool without overlap (slower)'''
|
|
20
|
-
try:
|
|
21
|
-
with lock:
|
|
22
|
-
PrintTA(PrintTA.blue, PrintTA.faceStd, PrintTAPriority.medium).pr( *args,**kwargs)
|
|
23
|
-
except :
|
|
24
|
-
print(ParForMul.printExceptionPFM(flagMessage=True))
|
|
25
|
-
|
|
26
|
-
def prTimeLock( *args,**kwargs):
|
|
27
|
-
''' print in parallel pool without overlap (slower)'''
|
|
28
|
-
try:
|
|
29
|
-
with lock:
|
|
30
|
-
PrintTA(PrintTA.blue, PrintTA.faceStd, PrintTAPriority.medium).prTime( *args,**kwargs)
|
|
31
|
-
except:
|
|
32
|
-
print(ParForMul.printExceptionPFM(flagMessage=True))
|
|
33
|
-
|
|
34
|
-
def printExceptionMasterParFor(stringa='',flagMessage=False): #timemilliseconds=-1 ***
|
|
35
|
-
''' used to print when an exception is raised TA has decided that the printing function is a simple
|
|
36
|
-
print in this way we cannot have any problems when printing in non-compatible terminals
|
|
37
|
-
use with something like
|
|
38
|
-
|
|
39
|
-
try:
|
|
40
|
-
a=1/0
|
|
41
|
-
except :#non need to put a variable al the info are in traceback
|
|
42
|
-
printException()
|
|
43
|
-
* stringa is an additional string (to specify the point where the error comes from)
|
|
44
|
-
* flagMessage is a flag, if true the error message is generated; default value is Flag_DEBUG
|
|
45
|
-
* flagDispDialog is a flag, if true a critical dialog appears after the exception
|
|
46
|
-
'''
|
|
47
|
-
#print(f'***** ParForMul Exception ***** Deltat={time()-PrintTA.startTime}\n{traceback.format_exc()}',*args,**kwargs)
|
|
48
|
-
#print(sys.exc_info()[2])
|
|
49
|
-
Message=""
|
|
50
|
-
if flagMessage:
|
|
51
|
-
Message+=f'Please, mail to: {__mail__}\n\n'
|
|
52
|
-
Message+=f'***** PaIRS Exception ***** time={time()-PrintTA.startTime}\n'+stringa
|
|
53
|
-
Message+=f'***** traceback.print_exc() ***** \n'
|
|
54
|
-
Message+=traceback.format_exc()
|
|
55
|
-
Message+=f'***** traceback.extract_stack() ***** \n'
|
|
56
|
-
# to print all the queue comment if not needed
|
|
57
|
-
for st in traceback.format_list( traceback.extract_stack()):
|
|
58
|
-
if 'PAIRS_GUI' in st and 'printException'not in st:# limits to files that have PAIRS_GUI in the path
|
|
59
|
-
Message+=st
|
|
60
|
-
Message+=f'***** PaIRS Exception -> End *****'
|
|
61
|
-
return Message
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
def fakePIV(iImg,procId, p, procTime, flagOutput=False, mes="fakePIV"):
|
|
66
|
-
''' fakePIV'''
|
|
67
|
-
startTime = time()
|
|
68
|
-
#print(f'reading Img {iImg} pid={os.getpid()} pid={mp.current_process().pid}')
|
|
69
|
-
#print(f'reading Img {iImg} pid={mp.current_process().pid} procId={procId}')
|
|
70
|
-
#sleep(0.5)
|
|
71
|
-
#print(f'Finished reading Img {iImg}')
|
|
72
|
-
|
|
73
|
-
a=0
|
|
74
|
-
count=1*1000*1000#on my pc 10*1000*1000=1sec
|
|
75
|
-
nIt=1
|
|
76
|
-
while nIt<2000000:
|
|
77
|
-
for _ in range(count):
|
|
78
|
-
a+=5#random.random()
|
|
79
|
-
if time()-startTime>procTime:
|
|
80
|
-
break
|
|
81
|
-
nIt+=1
|
|
82
|
-
if flagOutput:
|
|
83
|
-
print(f'fine proc Img {iImg} Nit={nIt} t={time()-startTime} mes={mes}')
|
|
84
|
-
return (0,f'fine proc Img {iImg} Nit={nIt} t={time()-startTime} mes={mes}')
|
|
85
|
-
|
|
86
|
-
#return iImg
|
|
87
|
-
|
|
88
|
-
class ParForCom():
|
|
89
|
-
''' Comunication varibles used by ParFor'''
|
|
90
|
-
def __init__(self):
|
|
91
|
-
#prTime(0,'Dentro ParForCom Com')
|
|
92
|
-
manager=mp.Manager()#si potrebbe creare un lock al posto della variabile globale qui cercare su internet
|
|
93
|
-
#prTime(0,'Dentro ParForCom dopo manager')
|
|
94
|
-
self.q = manager.Queue()
|
|
95
|
-
self.qOut= manager.Queue()
|
|
96
|
-
self.qProcessed= manager.Queue()
|
|
97
|
-
self.eventExit = manager.Event()
|
|
98
|
-
|
|
99
|
-
def clearAll(self):
|
|
100
|
-
''' Clears all the queues'''
|
|
101
|
-
self.clear(self.q)
|
|
102
|
-
self.clear(self.qOut)
|
|
103
|
-
self.clear(self.qProcessed)
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
def clear(self,q:queue):
|
|
108
|
-
'''clears a Queue'''
|
|
109
|
-
try:
|
|
110
|
-
while True:
|
|
111
|
-
q.get_nowait()
|
|
112
|
-
except queue.Empty:
|
|
113
|
-
pass
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
class ParForMul():
|
|
118
|
-
''' class Parallel for for PIV '''
|
|
119
|
-
printExceptionPFM=printExceptionMasterParFor #class variable
|
|
120
|
-
def __init__(self):
|
|
121
|
-
#prTime(0,'Dentro ParForMul inizio')
|
|
122
|
-
self.parForCom:ParForCom=ParForCom()
|
|
123
|
-
# valori impostabili dall'esterno
|
|
124
|
-
self.sleepTime=1. # waiting to do things
|
|
125
|
-
self.nonProcessed=0 # waiting to do things
|
|
126
|
-
#self.numUsedCores =psutil.cpu_count(logical=False)
|
|
127
|
-
## numUsedCores is the number of cores used fo processing and can be different from numCoresParPool that is the number of cores used in the parPool
|
|
128
|
-
self.numCoresParPool=self.numUsedCores = mp.cpu_count()//2#da decidere per intel /2 sono i processori reali
|
|
129
|
-
#prTime(0,'Dentro ParForMul fine')
|
|
130
|
-
self.numCalledCallbacks=0 # identify the times that the callbacks have been called
|
|
131
|
-
self.p=None
|
|
132
|
-
self.flagError=False
|
|
133
|
-
self.exception=None
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
def initTask(self,eventExit,name,procId,*args,**kwargs):
|
|
137
|
-
''' dummy InitTask sample
|
|
138
|
-
id is the id of the task should be a numeber between 1 and numUsedCores
|
|
139
|
-
if needed initTask should call the main task with name
|
|
140
|
-
'''
|
|
141
|
-
|
|
142
|
-
(flag,var)=fakePIV(name, procId,('initTask',2), *args,**kwargs)
|
|
143
|
-
return (flag,var,('initTask',2))
|
|
144
|
-
|
|
145
|
-
def wrapUp(self,procId,flagHasWorked,P,*args,**kwargs):
|
|
146
|
-
''' Dummy wrapUp function '''
|
|
147
|
-
if flagHasWorked:#do something
|
|
148
|
-
pass
|
|
149
|
-
return P
|
|
150
|
-
|
|
151
|
-
def callBack(self,flag,perc,procId,flagOutFromTask, name,varOutFromTask):
|
|
152
|
-
''' Dummy callBack function
|
|
153
|
-
perc=percentage of processed images
|
|
154
|
-
flag=true new data False just check exit
|
|
155
|
-
perc= precentage done
|
|
156
|
-
flagOutFromTasks,varOutFromTask Out variables from task e.g.:
|
|
157
|
-
flagOutFromTasks= 0 success, 1 skipped, -1 error, -2 blocked from caller
|
|
158
|
-
varOutFromTask whatever for now string
|
|
159
|
-
name current element in names
|
|
160
|
-
to stop the process the return value should be True otherwise sleep '''
|
|
161
|
-
if not flag:
|
|
162
|
-
return False
|
|
163
|
-
return False
|
|
164
|
-
|
|
165
|
-
def finalTask(self,procId,*args,**kwargs):
|
|
166
|
-
''' dummy final finalTask function
|
|
167
|
-
id is the id of the task should be a numeber between 1 and numUsedCores'''
|
|
168
|
-
return ('finalTask',2)
|
|
169
|
-
|
|
170
|
-
def launchTask(self,procId,task,initTask,finalTask, *args,**kwargs):
|
|
171
|
-
''' the main parallel function first calls initTask (eventExit is an event that enables the safe exit)
|
|
172
|
-
then for all the element in the queue q calls task with the variable returned by initTask
|
|
173
|
-
finally calls finalTask puts in the queue qOut the final result '''
|
|
174
|
-
# aggiunto try così almeno ci rendiamo conto se c'è un errore
|
|
175
|
-
'''
|
|
176
|
-
try:
|
|
177
|
-
procId=mp.current_process()._identity[0]
|
|
178
|
-
except:
|
|
179
|
-
procId=0 # '''
|
|
180
|
-
#pid=mp.current_process().pid
|
|
181
|
-
flagHasWorked=False#if true the task has processed at least one element
|
|
182
|
-
#if procId==2: prTimeLock(f"launchTask |||||||||||| Inizio procId={procId} flagHasWorked={flagHasWorked} ")
|
|
183
|
-
media=None
|
|
184
|
-
try:
|
|
185
|
-
i,n=self.parForCom.q.get()# the first time task must be called by initTask
|
|
186
|
-
if i!=-1:
|
|
187
|
-
flagHasWorked=True
|
|
188
|
-
(flag,var,P)=initTask(self.parForCom.eventExit,n,procId,*args,**kwargs)
|
|
189
|
-
self.parForCom.qProcessed.put((procId,flag,i,var))
|
|
190
|
-
while True:
|
|
191
|
-
i,n=self.parForCom.q.get()
|
|
192
|
-
if i==-1:
|
|
193
|
-
break
|
|
194
|
-
(flag,var)=task(n,procId,P,*args,**kwargs)
|
|
195
|
-
self.parForCom.qProcessed.put((procId,flag,i,var))
|
|
196
|
-
media=finalTask(procId,P,*args,**kwargs)# media should be different from None
|
|
197
|
-
except Exception as e:
|
|
198
|
-
raise(e) # I do not really care to have a full report if in debug it may be important
|
|
199
|
-
#ParForMul.printExceptionPFM()
|
|
200
|
-
flagHasWorked=False if media is None else flagHasWorked #if true the task has processed at least one element and media should be different from None
|
|
201
|
-
return (procId,flagHasWorked,media)
|
|
202
|
-
|
|
203
|
-
def readQOutProcess(self,strOutput,flagProcessed,callBack,names,nElements):
|
|
204
|
-
''' reads the qOut queue save the data and calls callback'''
|
|
205
|
-
com=self.parForCom
|
|
206
|
-
while not com.qProcessed.empty():
|
|
207
|
-
(procId,flag,i,var)=com.qProcessed.get_nowait()
|
|
208
|
-
perc=1-(com.q.qsize()-self.numUsedCores)/nElements#
|
|
209
|
-
strOutput[i]=var
|
|
210
|
-
flagProcessed[i]=flag
|
|
211
|
-
|
|
212
|
-
#prLock(f'callBack {i} {perc} {com.q.qsize()}')
|
|
213
|
-
if callBack(True,perc,procId,flag,names[i],var):
|
|
214
|
-
com.eventExit.set()# in this case the process will stop
|
|
215
|
-
self.numCalledCallbacks+=1
|
|
216
|
-
|
|
217
|
-
def errorHandler(self,error):
|
|
218
|
-
''' error function '''
|
|
219
|
-
#self.errorMessage=ParForMul.printExceptionPFM(flagMessage=True)
|
|
220
|
-
self.exception=error
|
|
221
|
-
self.flagError=True
|
|
222
|
-
self.parForCom.eventExit.set()# in this case the process will stop
|
|
223
|
-
#raise(error)
|
|
224
|
-
def parForExtPool(self,parPool,task,names,*args,initTask=None,finalTask=None,wrapUp=None,callBack=None,**kwargs):
|
|
225
|
-
''' parallel for main function with external mp pool
|
|
226
|
-
task is the main function that is called for each value in names.
|
|
227
|
-
optionally initTask and finalTask are called only one time per worker
|
|
228
|
-
args and kwargs are passed to all the functions.add()
|
|
229
|
-
callBack is called frequently and can be used to stop the parFor
|
|
230
|
-
Finally the WrapUp function is called one time per worker to wrap things up
|
|
231
|
-
'''
|
|
232
|
-
#prTime(0,'Dentro parForExtPool')
|
|
233
|
-
|
|
234
|
-
com=self.parForCom
|
|
235
|
-
com.eventExit.clear()
|
|
236
|
-
initTask=self.initTask if initTask is None else initTask
|
|
237
|
-
finalTask=self.finalTask if finalTask is None else finalTask
|
|
238
|
-
wrapUp=self.wrapUp if wrapUp is None else wrapUp
|
|
239
|
-
callBack=self.callBack if callBack is None else callBack
|
|
240
|
-
self.flagError=False
|
|
241
|
-
self.numCalledCallbacks=0 # reset the number of called callbacks
|
|
242
|
-
nElements=len(names)
|
|
243
|
-
flagProcessed=[self.nonProcessed]*nElements #lista delle immagini processate inizialmente tutti -1 ma possiamo modificarla
|
|
244
|
-
strOutput = [None]*nElements #lista dei messaggi in output in realtà potrebbe essere di qualunque tipo
|
|
245
|
-
def callWrapUp(var):
|
|
246
|
-
self.p=wrapUp(*var,*args,**kwargs)
|
|
247
|
-
self.parForCom.qOut.put((var[0:2])) #procid , flagHasWorked
|
|
248
|
-
#prTime(f"callWrapUp fine procid={var[0]} ")
|
|
249
|
-
|
|
250
|
-
# per ora -1 non processato, -2 errore ,numero positivo processato
|
|
251
|
-
for i,n in enumerate(names):
|
|
252
|
-
com.q.put((i,n))
|
|
253
|
-
for _ in range(self.numUsedCores):
|
|
254
|
-
com.q.put((-1,-1))
|
|
255
|
-
|
|
256
|
-
for i in range(self.numUsedCores):
|
|
257
|
-
_=parPool.apply_async(self.launchTask,(i,task, initTask,finalTask)+args,kwargs,callback=callWrapUp, error_callback=self.errorHandler)
|
|
258
|
-
#_=parPool.apply_async(self.launchTask,(task, initTask,finalTask)+args,kwargs, error_callback=self.errorHandler)
|
|
259
|
-
#prTime(0,'Dopo apply async in parForExtPool ++++++++++++++++++++++++++++++++++')
|
|
260
|
-
nThreadEnd=0
|
|
261
|
-
while True:
|
|
262
|
-
try:
|
|
263
|
-
#(procId,flagHasWorked)=com.qOut.get_nowait()
|
|
264
|
-
(_,_)=com.qOut.get_nowait()
|
|
265
|
-
#p=wrapUp(procId,flagHasWorked,p,*args,**kwargs)
|
|
266
|
-
nThreadEnd+=1
|
|
267
|
-
#if nThreadEnd==1: prTime(f"fine nThreadEnd={nThreadEnd} procId={procId}")
|
|
268
|
-
if nThreadEnd==self.numUsedCores:
|
|
269
|
-
break
|
|
270
|
-
except queue.Empty :
|
|
271
|
-
#prTime(' except queue.Empty Prima ')
|
|
272
|
-
if self.flagError : break # in this case a critical exception has been raised we should exit
|
|
273
|
-
if com.qProcessed.empty():
|
|
274
|
-
if callBack(False,None,None,None,None,None):
|
|
275
|
-
com.eventExit.set()# in this case the process will be stopped
|
|
276
|
-
#print("com.eventExit.set()# in this case the process will be stopped")
|
|
277
|
-
else:
|
|
278
|
-
self.readQOutProcess(strOutput,flagProcessed,callBack,names,nElements)
|
|
279
|
-
#prTime('********************************\n******************************dopo ')
|
|
280
|
-
sleep(self.sleepTime)
|
|
281
|
-
|
|
282
|
-
#prTime(f"fine parForExtPool")
|
|
283
|
-
# some of the processes may have finished without saving the data
|
|
284
|
-
self.readQOutProcess(strOutput,flagProcessed,callBack,names,nElements)
|
|
285
|
-
com.clearAll()# just to be sure ideally only needed when self.flagError is True
|
|
286
|
-
|
|
287
|
-
return self.p,flagProcessed,strOutput,self.flagError
|
|
288
|
-
|
|
289
|
-
def simpleFor(self,parPool,task,names,*args,initTask=None,finalTask=None,wrapUp=None,callBack=None,**kwargs):
|
|
290
|
-
''' parallel for main function
|
|
291
|
-
task is the main function that is called for each value in names.
|
|
292
|
-
optionally initTask and finalTask are called only one time per worker
|
|
293
|
-
args and kwargs are passed to all the functions.add()
|
|
294
|
-
Finally the WrapUp function is called one time per worker to wrap things up
|
|
295
|
-
'''
|
|
296
|
-
com=self.parForCom
|
|
297
|
-
com.eventExit.clear()
|
|
298
|
-
initTask=self.initTask if initTask is None else initTask
|
|
299
|
-
finalTask=self.finalTask if finalTask is None else finalTask
|
|
300
|
-
wrapUp=self.wrapUp if wrapUp is None else wrapUp
|
|
301
|
-
callBack=self.callBack if callBack is None else callBack
|
|
302
|
-
self.flagError=False
|
|
303
|
-
self.numCalledCallbacks=0 # reset the number of called callbacks
|
|
304
|
-
nElements=len(names)
|
|
305
|
-
flagProcessed=[self.nonProcessed]*nElements #lista delle immagini processate inizialmente tutti -1 ma possiamo modificarla
|
|
306
|
-
strOutput = [None]*nElements #lista dei messaggi in output in realtà potrebbe essere di qualunque tipo
|
|
307
|
-
|
|
308
|
-
def callWrapUp(var):
|
|
309
|
-
self.p=wrapUp(*var,*args,**kwargs)
|
|
310
|
-
self.parForCom.qOut.put((var[0:2]))
|
|
311
|
-
|
|
312
|
-
# per ora -1 non processato, -2 errore ,numero positivo processato
|
|
313
|
-
for i,n in enumerate(names):
|
|
314
|
-
com.q.put((i,n))
|
|
315
|
-
for _ in range(1):
|
|
316
|
-
com.q.put((-1,-1))
|
|
317
|
-
#with mp.Pool(self.numUsedCores) as pp:
|
|
318
|
-
procId=0
|
|
319
|
-
var=self.launchTask(procId,task, initTask,finalTask,*args,**kwargs)
|
|
320
|
-
callWrapUp(var)
|
|
321
|
-
nThreadEnd=0
|
|
322
|
-
while True:
|
|
323
|
-
try:
|
|
324
|
-
#(procId,flagHasWorked)=com.qOut.get_nowait()
|
|
325
|
-
(_,_)=com.qOut.get_nowait()
|
|
326
|
-
#p=wrapUp(procId,flagHasWorked,p,*args,**kwargs)
|
|
327
|
-
nThreadEnd+=1
|
|
328
|
-
#prTime(f"fine nThreadEnd={nThreadEnd} procId={procId} flagHasWorked={flagHasWorked}")
|
|
329
|
-
if nThreadEnd==1:
|
|
330
|
-
break
|
|
331
|
-
except queue.Empty :
|
|
332
|
-
#prTime('********************************\n******************************Prima ')
|
|
333
|
-
if self.flagError : break # in this case a critical exception has been raised we should exit
|
|
334
|
-
if com.qProcessed.empty():
|
|
335
|
-
if callBack(False,None,None,None,None,None):
|
|
336
|
-
com.eventExit.set()# in this case the process will be stopped
|
|
337
|
-
#print("com.eventExit.set()# in this case the process will be stopped")
|
|
338
|
-
else:
|
|
339
|
-
self.readQOutProcess(strOutput,flagProcessed,callBack,names,nElements)
|
|
340
|
-
#prTime('********************************\n******************************dopo ')
|
|
341
|
-
sleep(self.sleepTime)
|
|
342
|
-
# some of the processes may have finished without saving the data
|
|
343
|
-
self.readQOutProcess(strOutput,flagProcessed,callBack,names,nElements)
|
|
344
|
-
return self.p,flagProcessed,strOutput ,self.flagError
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
def parFor(self,task,names,*args,initTask=None,finalTask=None,wrapUp=None,callBack=None,**kwargs):
|
|
348
|
-
''' parallel for main function
|
|
349
|
-
task is the main function that is called for each value in names.
|
|
350
|
-
optionally initTask and finalTask are called only one time per worker
|
|
351
|
-
args and kwargs are passed to all the functions.add()
|
|
352
|
-
callBack is called frequently and can be used to stop the parFor
|
|
353
|
-
Finally the WrapUp function is called one time per worker to wrap things up
|
|
354
|
-
'''
|
|
355
|
-
prTime(0,'Dentro parFor')
|
|
356
|
-
pfPool=ParForPool()
|
|
357
|
-
pfPool.startParPool(self.numUsedCores)
|
|
358
|
-
(p,flagProcessed,strOutput)=self.parForExtPool(pfPool.parPool,task,names,*args,initTask=initTask,finalTask=finalTask,wrapUp=wrapUp,callBack=callBack,**kwargs)
|
|
359
|
-
pfPool.closeParPool()
|
|
360
|
-
return p,flagProcessed,strOutput
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
def initPoolProcesses(the_lock):
|
|
365
|
-
'''Initialize each process with a global variable lock.
|
|
366
|
-
'''
|
|
367
|
-
global lock
|
|
368
|
-
lock = the_lock
|
|
369
|
-
|
|
370
|
-
class ParForPool():
|
|
371
|
-
''' Saves the pool '''
|
|
372
|
-
def __init__(self):
|
|
373
|
-
self.parPool=None
|
|
374
|
-
self.numCoresParPool = mp.cpu_count()//2#da decidere per intel sono /2 son i processori reali
|
|
375
|
-
async def startParPoolAsync(self,numCoresParPool):
|
|
376
|
-
''' dummy function to call startParPool in async'''
|
|
377
|
-
self.startParPool(numCoresParPool)
|
|
378
|
-
def startParPool(self,numCoresParPool):
|
|
379
|
-
''' Starts the pool'''
|
|
380
|
-
the_lock = mp.Lock() # neded for prLock and the like
|
|
381
|
-
if self.parPool is None:
|
|
382
|
-
self.parPool=mp.Pool(numCoresParPool,initializer=initPoolProcesses, initargs=(the_lock,))
|
|
383
|
-
elif self.numCoresParPool!=numCoresParPool:
|
|
384
|
-
self.parPool.close()# Si potrebbe usare terminate che ammazza tutti i processi in essere
|
|
385
|
-
self.parPool=mp.Pool(numCoresParPool)
|
|
386
|
-
self.numCoresParPool=numCoresParPool
|
|
387
|
-
def closeParPool(self):
|
|
388
|
-
''' Closes the pool'''
|
|
389
|
-
if self.parPool is not None:
|
|
390
|
-
self.parPool.close()# Si potrebbe usare terminate che ammazza tutti i processi in essere
|
|
391
|
-
|
|
392
|
-
async def initParForAsync(numCoresParPool):
|
|
393
|
-
''' initialise the parPool'''
|
|
394
|
-
#prTime(0,'PIV_ParFor_Worker init')
|
|
395
|
-
pfPool=ParForPool()
|
|
396
|
-
t1=asyncio.create_task(pfPool.startParPoolAsync(numCoresParPool))
|
|
397
|
-
parForMul=ParForMul()
|
|
398
|
-
parForMul.numUsedCores=parForMul.numCoresParPool=numCoresParPool
|
|
399
|
-
await t1
|
|
400
|
-
#prTime(0,'PIV_ParFor_Worker Dopo ParForPool')
|
|
401
|
-
return (pfPool,parForMul)
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
def main():
|
|
405
|
-
''' main '''
|
|
406
|
-
prTime(6,'start')
|
|
407
|
-
|
|
408
|
-
pp=ParForMul()
|
|
409
|
-
#prTime(0,'Dopo ParForMul ****************')
|
|
410
|
-
|
|
411
|
-
pp.sleepTime=.1 # time between calls of callBack not used in this example
|
|
412
|
-
procTime=.02
|
|
413
|
-
nImg= [x for x in range(20)]
|
|
414
|
-
#startTime = time()
|
|
415
|
-
args=(procTime,)
|
|
416
|
-
kwargs={"flagOutput":False, "mes":"fakePIV"}
|
|
417
|
-
#pp.initParPool()
|
|
418
|
-
#pp.parForCache(fakePIV,nImg,*args,**kwargs)
|
|
419
|
-
|
|
420
|
-
pfPool=ParForPool()
|
|
421
|
-
pfPool.startParPool(pfPool.numCoresParPool)
|
|
422
|
-
#pp.simpleFor(fakePIV,nImg,*args,**kwargs)
|
|
423
|
-
pp.numUsedCores =4
|
|
424
|
-
|
|
425
|
-
#pp.parForExtPool(pfPool.parPool,fakePIV,nImg,*args,**kwargs)
|
|
426
|
-
pp.parForExtPool(pfPool.parPool,fakePIV,nImg,*args,**kwargs)
|
|
427
|
-
pfPool.closeParPool()
|
|
428
|
-
pp.parFor(fakePIV,nImg,*args,**kwargs)
|
|
429
|
-
#pp.parFor(fakePIV,nImg,*args,**kwargs)
|
|
430
|
-
prTime(0,'Fine')
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
if __name__ == "__main__":
|
|
435
|
-
main()
|
|
11
|
+
#import numpy as np
|
|
12
|
+
#import scipy as sc
|
|
13
|
+
|
|
14
|
+
prTime=PrintTA(PrintTA.blue, PrintTA.faceStd, PrintTAPriority.medium).prTime
|
|
15
|
+
pr=PrintTA(PrintTA.blue, PrintTA.faceStd, PrintTAPriority.medium).prTime
|
|
16
|
+
# pylint: disable=unused-argument
|
|
17
|
+
lock=None
|
|
18
|
+
def prLock( *args,**kwargs):
|
|
19
|
+
''' print in parallel pool without overlap (slower)'''
|
|
20
|
+
try:
|
|
21
|
+
with lock:
|
|
22
|
+
PrintTA(PrintTA.blue, PrintTA.faceStd, PrintTAPriority.medium).pr( *args,**kwargs)
|
|
23
|
+
except :
|
|
24
|
+
print(ParForMul.printExceptionPFM(flagMessage=True))
|
|
25
|
+
|
|
26
|
+
def prTimeLock( *args,**kwargs):
|
|
27
|
+
''' print in parallel pool without overlap (slower)'''
|
|
28
|
+
try:
|
|
29
|
+
with lock:
|
|
30
|
+
PrintTA(PrintTA.blue, PrintTA.faceStd, PrintTAPriority.medium).prTime( *args,**kwargs)
|
|
31
|
+
except:
|
|
32
|
+
print(ParForMul.printExceptionPFM(flagMessage=True))
|
|
33
|
+
|
|
34
|
+
def printExceptionMasterParFor(stringa='',flagMessage=False): #timemilliseconds=-1 ***
|
|
35
|
+
''' used to print when an exception is raised TA has decided that the printing function is a simple
|
|
36
|
+
print in this way we cannot have any problems when printing in non-compatible terminals
|
|
37
|
+
use with something like
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
a=1/0
|
|
41
|
+
except :#non need to put a variable al the info are in traceback
|
|
42
|
+
printException()
|
|
43
|
+
* stringa is an additional string (to specify the point where the error comes from)
|
|
44
|
+
* flagMessage is a flag, if true the error message is generated; default value is Flag_DEBUG
|
|
45
|
+
* flagDispDialog is a flag, if true a critical dialog appears after the exception
|
|
46
|
+
'''
|
|
47
|
+
#print(f'***** ParForMul Exception ***** Deltat={time()-PrintTA.startTime}\n{traceback.format_exc()}',*args,**kwargs)
|
|
48
|
+
#print(sys.exc_info()[2])
|
|
49
|
+
Message=""
|
|
50
|
+
if flagMessage:
|
|
51
|
+
Message+=f'Please, mail to: {__mail__}\n\n'
|
|
52
|
+
Message+=f'***** PaIRS Exception ***** time={time()-PrintTA.startTime}\n'+stringa
|
|
53
|
+
Message+=f'***** traceback.print_exc() ***** \n'
|
|
54
|
+
Message+=traceback.format_exc()
|
|
55
|
+
Message+=f'***** traceback.extract_stack() ***** \n'
|
|
56
|
+
# to print all the queue comment if not needed
|
|
57
|
+
for st in traceback.format_list( traceback.extract_stack()):
|
|
58
|
+
if 'PAIRS_GUI' in st and 'printException'not in st:# limits to files that have PAIRS_GUI in the path
|
|
59
|
+
Message+=st
|
|
60
|
+
Message+=f'***** PaIRS Exception -> End *****'
|
|
61
|
+
return Message
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def fakePIV(iImg,procId, p, procTime, flagOutput=False, mes="fakePIV"):
|
|
66
|
+
''' fakePIV'''
|
|
67
|
+
startTime = time()
|
|
68
|
+
#print(f'reading Img {iImg} pid={os.getpid()} pid={mp.current_process().pid}')
|
|
69
|
+
#print(f'reading Img {iImg} pid={mp.current_process().pid} procId={procId}')
|
|
70
|
+
#sleep(0.5)
|
|
71
|
+
#print(f'Finished reading Img {iImg}')
|
|
72
|
+
|
|
73
|
+
a=0
|
|
74
|
+
count=1*1000*1000#on my pc 10*1000*1000=1sec
|
|
75
|
+
nIt=1
|
|
76
|
+
while nIt<2000000:
|
|
77
|
+
for _ in range(count):
|
|
78
|
+
a+=5#random.random()
|
|
79
|
+
if time()-startTime>procTime:
|
|
80
|
+
break
|
|
81
|
+
nIt+=1
|
|
82
|
+
if flagOutput:
|
|
83
|
+
print(f'fine proc Img {iImg} Nit={nIt} t={time()-startTime} mes={mes}')
|
|
84
|
+
return (0,f'fine proc Img {iImg} Nit={nIt} t={time()-startTime} mes={mes}')
|
|
85
|
+
|
|
86
|
+
#return iImg
|
|
87
|
+
|
|
88
|
+
class ParForCom():
|
|
89
|
+
''' Comunication varibles used by ParFor'''
|
|
90
|
+
def __init__(self):
|
|
91
|
+
#prTime(0,'Dentro ParForCom Com')
|
|
92
|
+
manager=mp.Manager()#si potrebbe creare un lock al posto della variabile globale qui cercare su internet
|
|
93
|
+
#prTime(0,'Dentro ParForCom dopo manager')
|
|
94
|
+
self.q = manager.Queue()
|
|
95
|
+
self.qOut= manager.Queue()
|
|
96
|
+
self.qProcessed= manager.Queue()
|
|
97
|
+
self.eventExit = manager.Event()
|
|
98
|
+
|
|
99
|
+
def clearAll(self):
|
|
100
|
+
''' Clears all the queues'''
|
|
101
|
+
self.clear(self.q)
|
|
102
|
+
self.clear(self.qOut)
|
|
103
|
+
self.clear(self.qProcessed)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def clear(self,q:queue):
|
|
108
|
+
'''clears a Queue'''
|
|
109
|
+
try:
|
|
110
|
+
while True:
|
|
111
|
+
q.get_nowait()
|
|
112
|
+
except queue.Empty:
|
|
113
|
+
pass
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
class ParForMul():
|
|
118
|
+
''' class Parallel for for PIV '''
|
|
119
|
+
printExceptionPFM=printExceptionMasterParFor #class variable
|
|
120
|
+
def __init__(self):
|
|
121
|
+
#prTime(0,'Dentro ParForMul inizio')
|
|
122
|
+
self.parForCom:ParForCom=ParForCom()
|
|
123
|
+
# valori impostabili dall'esterno
|
|
124
|
+
self.sleepTime=1. # waiting to do things
|
|
125
|
+
self.nonProcessed=0 # waiting to do things
|
|
126
|
+
#self.numUsedCores =psutil.cpu_count(logical=False)
|
|
127
|
+
## numUsedCores is the number of cores used fo processing and can be different from numCoresParPool that is the number of cores used in the parPool
|
|
128
|
+
self.numCoresParPool=self.numUsedCores = mp.cpu_count()//2#da decidere per intel /2 sono i processori reali
|
|
129
|
+
#prTime(0,'Dentro ParForMul fine')
|
|
130
|
+
self.numCalledCallbacks=0 # identify the times that the callbacks have been called
|
|
131
|
+
self.p=None
|
|
132
|
+
self.flagError=False
|
|
133
|
+
self.exception=None
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
def initTask(self,eventExit,name,procId,*args,**kwargs):
|
|
137
|
+
''' dummy InitTask sample
|
|
138
|
+
id is the id of the task should be a numeber between 1 and numUsedCores
|
|
139
|
+
if needed initTask should call the main task with name
|
|
140
|
+
'''
|
|
141
|
+
|
|
142
|
+
(flag,var)=fakePIV(name, procId,('initTask',2), *args,**kwargs)
|
|
143
|
+
return (flag,var,('initTask',2))
|
|
144
|
+
|
|
145
|
+
def wrapUp(self,procId,flagHasWorked,P,*args,**kwargs):
|
|
146
|
+
''' Dummy wrapUp function '''
|
|
147
|
+
if flagHasWorked:#do something
|
|
148
|
+
pass
|
|
149
|
+
return P
|
|
150
|
+
|
|
151
|
+
def callBack(self,flag,perc,procId,flagOutFromTask, name,varOutFromTask):
|
|
152
|
+
''' Dummy callBack function
|
|
153
|
+
perc=percentage of processed images
|
|
154
|
+
flag=true new data False just check exit
|
|
155
|
+
perc= precentage done
|
|
156
|
+
flagOutFromTasks,varOutFromTask Out variables from task e.g.:
|
|
157
|
+
flagOutFromTasks= 0 success, 1 skipped, -1 error, -2 blocked from caller
|
|
158
|
+
varOutFromTask whatever for now string
|
|
159
|
+
name current element in names
|
|
160
|
+
to stop the process the return value should be True otherwise sleep '''
|
|
161
|
+
if not flag:
|
|
162
|
+
return False
|
|
163
|
+
return False
|
|
164
|
+
|
|
165
|
+
def finalTask(self,procId,*args,**kwargs):
|
|
166
|
+
''' dummy final finalTask function
|
|
167
|
+
id is the id of the task should be a numeber between 1 and numUsedCores'''
|
|
168
|
+
return ('finalTask',2)
|
|
169
|
+
|
|
170
|
+
def launchTask(self,procId,task,initTask,finalTask, *args,**kwargs):
|
|
171
|
+
''' the main parallel function first calls initTask (eventExit is an event that enables the safe exit)
|
|
172
|
+
then for all the element in the queue q calls task with the variable returned by initTask
|
|
173
|
+
finally calls finalTask puts in the queue qOut the final result '''
|
|
174
|
+
# aggiunto try così almeno ci rendiamo conto se c'è un errore
|
|
175
|
+
'''
|
|
176
|
+
try:
|
|
177
|
+
procId=mp.current_process()._identity[0]
|
|
178
|
+
except:
|
|
179
|
+
procId=0 # '''
|
|
180
|
+
#pid=mp.current_process().pid
|
|
181
|
+
flagHasWorked=False#if true the task has processed at least one element
|
|
182
|
+
#if procId==2: prTimeLock(f"launchTask |||||||||||| Inizio procId={procId} flagHasWorked={flagHasWorked} ")
|
|
183
|
+
media=None
|
|
184
|
+
try:
|
|
185
|
+
i,n=self.parForCom.q.get()# the first time task must be called by initTask
|
|
186
|
+
if i!=-1:
|
|
187
|
+
flagHasWorked=True
|
|
188
|
+
(flag,var,P)=initTask(self.parForCom.eventExit,n,procId,*args,**kwargs)
|
|
189
|
+
self.parForCom.qProcessed.put((procId,flag,i,var))
|
|
190
|
+
while True:
|
|
191
|
+
i,n=self.parForCom.q.get()
|
|
192
|
+
if i==-1:
|
|
193
|
+
break
|
|
194
|
+
(flag,var)=task(n,procId,P,*args,**kwargs)
|
|
195
|
+
self.parForCom.qProcessed.put((procId,flag,i,var))
|
|
196
|
+
media=finalTask(procId,P,*args,**kwargs)# media should be different from None
|
|
197
|
+
except Exception as e:
|
|
198
|
+
raise(e) # I do not really care to have a full report if in debug it may be important
|
|
199
|
+
#ParForMul.printExceptionPFM()
|
|
200
|
+
flagHasWorked=False if media is None else flagHasWorked #if true the task has processed at least one element and media should be different from None
|
|
201
|
+
return (procId,flagHasWorked,media)
|
|
202
|
+
|
|
203
|
+
def readQOutProcess(self,strOutput,flagProcessed,callBack,names,nElements):
|
|
204
|
+
''' reads the qOut queue save the data and calls callback'''
|
|
205
|
+
com=self.parForCom
|
|
206
|
+
while not com.qProcessed.empty():
|
|
207
|
+
(procId,flag,i,var)=com.qProcessed.get_nowait()
|
|
208
|
+
perc=1-(com.q.qsize()-self.numUsedCores)/nElements#
|
|
209
|
+
strOutput[i]=var
|
|
210
|
+
flagProcessed[i]=flag
|
|
211
|
+
|
|
212
|
+
#prLock(f'callBack {i} {perc} {com.q.qsize()}')
|
|
213
|
+
if callBack(True,perc,procId,flag,names[i],var):
|
|
214
|
+
com.eventExit.set()# in this case the process will stop
|
|
215
|
+
self.numCalledCallbacks+=1
|
|
216
|
+
|
|
217
|
+
def errorHandler(self,error):
|
|
218
|
+
''' error function '''
|
|
219
|
+
#self.errorMessage=ParForMul.printExceptionPFM(flagMessage=True)
|
|
220
|
+
self.exception=error
|
|
221
|
+
self.flagError=True
|
|
222
|
+
self.parForCom.eventExit.set()# in this case the process will stop
|
|
223
|
+
#raise(error)
|
|
224
|
+
def parForExtPool(self,parPool,task,names,*args,initTask=None,finalTask=None,wrapUp=None,callBack=None,**kwargs):
|
|
225
|
+
''' parallel for main function with external mp pool
|
|
226
|
+
task is the main function that is called for each value in names.
|
|
227
|
+
optionally initTask and finalTask are called only one time per worker
|
|
228
|
+
args and kwargs are passed to all the functions.add()
|
|
229
|
+
callBack is called frequently and can be used to stop the parFor
|
|
230
|
+
Finally the WrapUp function is called one time per worker to wrap things up
|
|
231
|
+
'''
|
|
232
|
+
#prTime(0,'Dentro parForExtPool')
|
|
233
|
+
|
|
234
|
+
com=self.parForCom
|
|
235
|
+
com.eventExit.clear()
|
|
236
|
+
initTask=self.initTask if initTask is None else initTask
|
|
237
|
+
finalTask=self.finalTask if finalTask is None else finalTask
|
|
238
|
+
wrapUp=self.wrapUp if wrapUp is None else wrapUp
|
|
239
|
+
callBack=self.callBack if callBack is None else callBack
|
|
240
|
+
self.flagError=False
|
|
241
|
+
self.numCalledCallbacks=0 # reset the number of called callbacks
|
|
242
|
+
nElements=len(names)
|
|
243
|
+
flagProcessed=[self.nonProcessed]*nElements #lista delle immagini processate inizialmente tutti -1 ma possiamo modificarla
|
|
244
|
+
strOutput = [None]*nElements #lista dei messaggi in output in realtà potrebbe essere di qualunque tipo
|
|
245
|
+
def callWrapUp(var):
|
|
246
|
+
self.p=wrapUp(*var,*args,**kwargs)
|
|
247
|
+
self.parForCom.qOut.put((var[0:2])) #procid , flagHasWorked
|
|
248
|
+
#prTime(f"callWrapUp fine procid={var[0]} ")
|
|
249
|
+
|
|
250
|
+
# per ora -1 non processato, -2 errore ,numero positivo processato
|
|
251
|
+
for i,n in enumerate(names):
|
|
252
|
+
com.q.put((i,n))
|
|
253
|
+
for _ in range(self.numUsedCores):
|
|
254
|
+
com.q.put((-1,-1))
|
|
255
|
+
|
|
256
|
+
for i in range(self.numUsedCores):
|
|
257
|
+
_=parPool.apply_async(self.launchTask,(i,task, initTask,finalTask)+args,kwargs,callback=callWrapUp, error_callback=self.errorHandler)
|
|
258
|
+
#_=parPool.apply_async(self.launchTask,(task, initTask,finalTask)+args,kwargs, error_callback=self.errorHandler)
|
|
259
|
+
#prTime(0,'Dopo apply async in parForExtPool ++++++++++++++++++++++++++++++++++')
|
|
260
|
+
nThreadEnd=0
|
|
261
|
+
while True:
|
|
262
|
+
try:
|
|
263
|
+
#(procId,flagHasWorked)=com.qOut.get_nowait()
|
|
264
|
+
(_,_)=com.qOut.get_nowait()
|
|
265
|
+
#p=wrapUp(procId,flagHasWorked,p,*args,**kwargs)
|
|
266
|
+
nThreadEnd+=1
|
|
267
|
+
#if nThreadEnd==1: prTime(f"fine nThreadEnd={nThreadEnd} procId={procId}")
|
|
268
|
+
if nThreadEnd==self.numUsedCores:
|
|
269
|
+
break
|
|
270
|
+
except queue.Empty :
|
|
271
|
+
#prTime(' except queue.Empty Prima ')
|
|
272
|
+
if self.flagError : break # in this case a critical exception has been raised we should exit
|
|
273
|
+
if com.qProcessed.empty():
|
|
274
|
+
if callBack(False,None,None,None,None,None):
|
|
275
|
+
com.eventExit.set()# in this case the process will be stopped
|
|
276
|
+
#print("com.eventExit.set()# in this case the process will be stopped")
|
|
277
|
+
else:
|
|
278
|
+
self.readQOutProcess(strOutput,flagProcessed,callBack,names,nElements)
|
|
279
|
+
#prTime('********************************\n******************************dopo ')
|
|
280
|
+
sleep(self.sleepTime)
|
|
281
|
+
|
|
282
|
+
#prTime(f"fine parForExtPool")
|
|
283
|
+
# some of the processes may have finished without saving the data
|
|
284
|
+
self.readQOutProcess(strOutput,flagProcessed,callBack,names,nElements)
|
|
285
|
+
com.clearAll()# just to be sure ideally only needed when self.flagError is True
|
|
286
|
+
|
|
287
|
+
return self.p,flagProcessed,strOutput,self.flagError
|
|
288
|
+
|
|
289
|
+
def simpleFor(self,parPool,task,names,*args,initTask=None,finalTask=None,wrapUp=None,callBack=None,**kwargs):
|
|
290
|
+
''' parallel for main function
|
|
291
|
+
task is the main function that is called for each value in names.
|
|
292
|
+
optionally initTask and finalTask are called only one time per worker
|
|
293
|
+
args and kwargs are passed to all the functions.add()
|
|
294
|
+
Finally the WrapUp function is called one time per worker to wrap things up
|
|
295
|
+
'''
|
|
296
|
+
com=self.parForCom
|
|
297
|
+
com.eventExit.clear()
|
|
298
|
+
initTask=self.initTask if initTask is None else initTask
|
|
299
|
+
finalTask=self.finalTask if finalTask is None else finalTask
|
|
300
|
+
wrapUp=self.wrapUp if wrapUp is None else wrapUp
|
|
301
|
+
callBack=self.callBack if callBack is None else callBack
|
|
302
|
+
self.flagError=False
|
|
303
|
+
self.numCalledCallbacks=0 # reset the number of called callbacks
|
|
304
|
+
nElements=len(names)
|
|
305
|
+
flagProcessed=[self.nonProcessed]*nElements #lista delle immagini processate inizialmente tutti -1 ma possiamo modificarla
|
|
306
|
+
strOutput = [None]*nElements #lista dei messaggi in output in realtà potrebbe essere di qualunque tipo
|
|
307
|
+
|
|
308
|
+
def callWrapUp(var):
|
|
309
|
+
self.p=wrapUp(*var,*args,**kwargs)
|
|
310
|
+
self.parForCom.qOut.put((var[0:2]))
|
|
311
|
+
|
|
312
|
+
# per ora -1 non processato, -2 errore ,numero positivo processato
|
|
313
|
+
for i,n in enumerate(names):
|
|
314
|
+
com.q.put((i,n))
|
|
315
|
+
for _ in range(1):
|
|
316
|
+
com.q.put((-1,-1))
|
|
317
|
+
#with mp.Pool(self.numUsedCores) as pp:
|
|
318
|
+
procId=0
|
|
319
|
+
var=self.launchTask(procId,task, initTask,finalTask,*args,**kwargs)
|
|
320
|
+
callWrapUp(var)
|
|
321
|
+
nThreadEnd=0
|
|
322
|
+
while True:
|
|
323
|
+
try:
|
|
324
|
+
#(procId,flagHasWorked)=com.qOut.get_nowait()
|
|
325
|
+
(_,_)=com.qOut.get_nowait()
|
|
326
|
+
#p=wrapUp(procId,flagHasWorked,p,*args,**kwargs)
|
|
327
|
+
nThreadEnd+=1
|
|
328
|
+
#prTime(f"fine nThreadEnd={nThreadEnd} procId={procId} flagHasWorked={flagHasWorked}")
|
|
329
|
+
if nThreadEnd==1:
|
|
330
|
+
break
|
|
331
|
+
except queue.Empty :
|
|
332
|
+
#prTime('********************************\n******************************Prima ')
|
|
333
|
+
if self.flagError : break # in this case a critical exception has been raised we should exit
|
|
334
|
+
if com.qProcessed.empty():
|
|
335
|
+
if callBack(False,None,None,None,None,None):
|
|
336
|
+
com.eventExit.set()# in this case the process will be stopped
|
|
337
|
+
#print("com.eventExit.set()# in this case the process will be stopped")
|
|
338
|
+
else:
|
|
339
|
+
self.readQOutProcess(strOutput,flagProcessed,callBack,names,nElements)
|
|
340
|
+
#prTime('********************************\n******************************dopo ')
|
|
341
|
+
sleep(self.sleepTime)
|
|
342
|
+
# some of the processes may have finished without saving the data
|
|
343
|
+
self.readQOutProcess(strOutput,flagProcessed,callBack,names,nElements)
|
|
344
|
+
return self.p,flagProcessed,strOutput ,self.flagError
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
def parFor(self,task,names,*args,initTask=None,finalTask=None,wrapUp=None,callBack=None,**kwargs):
|
|
348
|
+
''' parallel for main function
|
|
349
|
+
task is the main function that is called for each value in names.
|
|
350
|
+
optionally initTask and finalTask are called only one time per worker
|
|
351
|
+
args and kwargs are passed to all the functions.add()
|
|
352
|
+
callBack is called frequently and can be used to stop the parFor
|
|
353
|
+
Finally the WrapUp function is called one time per worker to wrap things up
|
|
354
|
+
'''
|
|
355
|
+
prTime(0,'Dentro parFor')
|
|
356
|
+
pfPool=ParForPool()
|
|
357
|
+
pfPool.startParPool(self.numUsedCores)
|
|
358
|
+
(p,flagProcessed,strOutput)=self.parForExtPool(pfPool.parPool,task,names,*args,initTask=initTask,finalTask=finalTask,wrapUp=wrapUp,callBack=callBack,**kwargs)
|
|
359
|
+
pfPool.closeParPool()
|
|
360
|
+
return p,flagProcessed,strOutput
|
|
361
|
+
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
def initPoolProcesses(the_lock):
|
|
365
|
+
'''Initialize each process with a global variable lock.
|
|
366
|
+
'''
|
|
367
|
+
global lock
|
|
368
|
+
lock = the_lock
|
|
369
|
+
|
|
370
|
+
class ParForPool():
|
|
371
|
+
''' Saves the pool '''
|
|
372
|
+
def __init__(self):
|
|
373
|
+
self.parPool=None
|
|
374
|
+
self.numCoresParPool = mp.cpu_count()//2#da decidere per intel sono /2 son i processori reali
|
|
375
|
+
async def startParPoolAsync(self,numCoresParPool):
|
|
376
|
+
''' dummy function to call startParPool in async'''
|
|
377
|
+
self.startParPool(numCoresParPool)
|
|
378
|
+
def startParPool(self,numCoresParPool):
|
|
379
|
+
''' Starts the pool'''
|
|
380
|
+
the_lock = mp.Lock() # neded for prLock and the like
|
|
381
|
+
if self.parPool is None:
|
|
382
|
+
self.parPool=mp.Pool(numCoresParPool,initializer=initPoolProcesses, initargs=(the_lock,))
|
|
383
|
+
elif self.numCoresParPool!=numCoresParPool:
|
|
384
|
+
self.parPool.close()# Si potrebbe usare terminate che ammazza tutti i processi in essere
|
|
385
|
+
self.parPool=mp.Pool(numCoresParPool)
|
|
386
|
+
self.numCoresParPool=numCoresParPool
|
|
387
|
+
def closeParPool(self):
|
|
388
|
+
''' Closes the pool'''
|
|
389
|
+
if self.parPool is not None:
|
|
390
|
+
self.parPool.close()# Si potrebbe usare terminate che ammazza tutti i processi in essere
|
|
391
|
+
|
|
392
|
+
async def initParForAsync(numCoresParPool):
|
|
393
|
+
''' initialise the parPool'''
|
|
394
|
+
#prTime(0,'PIV_ParFor_Worker init')
|
|
395
|
+
pfPool=ParForPool()
|
|
396
|
+
t1=asyncio.create_task(pfPool.startParPoolAsync(numCoresParPool))
|
|
397
|
+
parForMul=ParForMul()
|
|
398
|
+
parForMul.numUsedCores=parForMul.numCoresParPool=numCoresParPool
|
|
399
|
+
await t1
|
|
400
|
+
#prTime(0,'PIV_ParFor_Worker Dopo ParForPool')
|
|
401
|
+
return (pfPool,parForMul)
|
|
402
|
+
|
|
403
|
+
|
|
404
|
+
def main():
|
|
405
|
+
''' main '''
|
|
406
|
+
prTime(6,'start')
|
|
407
|
+
|
|
408
|
+
pp=ParForMul()
|
|
409
|
+
#prTime(0,'Dopo ParForMul ****************')
|
|
410
|
+
|
|
411
|
+
pp.sleepTime=.1 # time between calls of callBack not used in this example
|
|
412
|
+
procTime=.02
|
|
413
|
+
nImg= [x for x in range(20)]
|
|
414
|
+
#startTime = time()
|
|
415
|
+
args=(procTime,)
|
|
416
|
+
kwargs={"flagOutput":False, "mes":"fakePIV"}
|
|
417
|
+
#pp.initParPool()
|
|
418
|
+
#pp.parForCache(fakePIV,nImg,*args,**kwargs)
|
|
419
|
+
|
|
420
|
+
pfPool=ParForPool()
|
|
421
|
+
pfPool.startParPool(pfPool.numCoresParPool)
|
|
422
|
+
#pp.simpleFor(fakePIV,nImg,*args,**kwargs)
|
|
423
|
+
pp.numUsedCores =4
|
|
424
|
+
|
|
425
|
+
#pp.parForExtPool(pfPool.parPool,fakePIV,nImg,*args,**kwargs)
|
|
426
|
+
pp.parForExtPool(pfPool.parPool,fakePIV,nImg,*args,**kwargs)
|
|
427
|
+
pfPool.closeParPool()
|
|
428
|
+
pp.parFor(fakePIV,nImg,*args,**kwargs)
|
|
429
|
+
#pp.parFor(fakePIV,nImg,*args,**kwargs)
|
|
430
|
+
prTime(0,'Fine')
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
if __name__ == "__main__":
|
|
435
|
+
main()
|