I am trying to simulate multiple Modelica FMUs in parallel using python/pyfmi and multiprocessing. However I am not able to return any pyfmi FMI objects from the subprocesses once the FMUs are initialized. It seems that pyfmi FMI objects (e.g. pyfmi.fmi.FMUModelCS2 or pyfmi.fmi.FMUState2) are not pickable. I also tried dill to pickle, which doesn't work for me eather. With dill the objects are picklable though, meaning no error, but somehow corrupted if I try to reload them afterwards. Does anyone have an idea of how to solve this issue? Thanks!
The problem is that pyfmi.fmiFMUModelCS2 is a Cython class dependent on external libraries which makes it unpickable. So it is not possible unfortunately.
If you want to use multiprocessing the only way forward that I see is that you first create the processes and then load the FMUs into the separate processes. In this way you do not need to pickle the classes.
I faced a similar problem when I created EstimationPy. I ended up creating a wrapper for running parallel simulation of the same FMU using multiple processes.
I suggest you to look at the implementation here
https://github.com/lbl-srg/EstimationPy/blob/master/estimationpy/fmu_utils/fmu_pool.py
And to the example http://lbl-srg.github.io/EstimationPy/modules/examples/first_order.html#run-multiple-simulations
The pathos module allows multiprocessing with a similar interface as the multiprocessing but relies on dill instead of pickle for serialisation.
The Pool method works for parallel execution of model.simulate, provided that results are handled in memory:
n_core = 2
n_simulation = 10
# ====
import pyfmi
model = pyfmi.load_fmu(path_fmu)
def worker(*args):
model.reset()
print "================> %d" % args[0]
return model.simulate(options=dict(result_handling="memory"))["y"]
from pathos.multiprocessing import Pool
pool = Pool(n_core)
out = pool.map(worker, range(n_simulation))
pool.close()
pool.join()
Note in the above snippet that it is necessary to handle results in memory : options=dict(result_handling="memory").
The default is to use temporary files which works for when the amount of simulations is small.
However, the longer the queue, the higher the chance to get something like
Exception in thread Thread-27:
Traceback (most recent call last):
File "/home/USER/anaconda2/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/home/USER/anaconda2/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "/home/USER/anaconda2/lib/python2.7/site-packages/multiprocess/pool.py", line 389, in _handle_results
task = get()
File "/home/USER/anaconda2/lib/python2.7/site-packages/dill/dill.py", line 260, in loads
return load(file)
File "/home/USER/anaconda2/lib/python2.7/site-packages/dill/dill.py", line 250, in load
obj = pik.load()
File "/home/USER/anaconda2/lib/python2.7/pickle.py", line 864, in load
dispatch[key](self)
File "/home/USER/anaconda2/lib/python2.7/pickle.py", line 1139, in load_reduce
value = func(*args)
TypeError: __init__() takes exactly 2 arguments (1 given)
which I fail to grasp.
Related
We recently added X-Ray to our code by having:
from aws_xray_sdk.core import xray_recorder
from aws_xray_sdk.core import patch_all
patch_all()
While this runs fine on AWS Lambda, but when trying to run locally during calling ElasticSearch we got the following exception:
ERROR:aws_xray_sdk.core.context:cannot find the current segment/subsegment, please make sure you have a segment open
queryCustomers - DEBUG - Caught exception for <function search_customer at 0x10bfcf0d0>
Traceback (most recent call last):
File "/Users/jameslin/virtualenvs/test-project/lib/python3.6/site-packages/chalice/app.py", line 659, in _get_view_function_response
response = view_function(**function_args)
File "/Users/jameslin/projects/test-project/src/app.py", line 57, in search_customer
return query[0:size].execute().to_dict()['hits']['hits']
File "/Users/jameslin/virtualenvs/test-project/lib/python3.6/site-packages/elasticsearch_dsl/search.py", line 639, in execute
**self._params
File "/Users/jameslin/virtualenvs/test-project/lib/python3.6/site-packages/elasticsearch/client/utils.py", line 73, in _wrapped
return func(*args, params=params, **kwargs)
File "/Users/jameslin/virtualenvs/test-project/lib/python3.6/site-packages/elasticsearch/client/__init__.py", line 632, in search
doc_type, '_search'), params=params, body=body)
File "/Users/jameslin/virtualenvs/test-project/lib/python3.6/site-packages/elasticsearch/transport.py", line 312, in perform_request
status, headers, data = connection.perform_request(method, url, params, body, ignore=ignore, timeout=timeout)
File "/Users/jameslin/virtualenvs/test-project/lib/python3.6/site-packages/elasticsearch/connection/http_requests.py", line 71, in perform_request
prepared_request = self.session.prepare_request(request)
File "/Users/jameslin/virtualenvs/test-project/lib/python3.6/site-packages/aws_xray_sdk/ext/requests/patch.py", line 38, in _inject_header
inject_trace_header(headers, xray_recorder.current_subsegment())
File "/Users/jameslin/virtualenvs/test-project/lib/python3.6/site-packages/aws_xray_sdk/core/recorder.py", line 251, in current_subsegment
entity = self.get_trace_entity()
File "/Users/jameslin/virtualenvs/test-project/lib/python3.6/site-packages/aws_xray_sdk/core/recorder.py", line 316, in get_trace_entity
return self.context.get_trace_entity()
File "/Users/jameslin/virtualenvs/test-project/lib/python3.6/site-packages/aws_xray_sdk/core/context.py", line 93, in get_trace_entity
return self.handle_context_missing()
File "/Users/jameslin/virtualenvs/test-project/lib/python3.6/site-packages/aws_xray_sdk/core/context.py", line 118, in handle_context_missing
raise SegmentNotFoundException(MISSING_SEGMENT_MSG)
aws_xray_sdk.core.exceptions.exceptions.SegmentNotFoundException: cannot find the current segment/subsegment, please make sure you have a segment open
I have no idea what his means and how to get rid of it, my google attempts gives not many relevant results and I also tried running the x-ray daemon locally but still having the same problem:
./xray_mac -o -n ap-southeast-2
When your code is running on AWS Lambda with tracing enabled, Lambda container will generate a segment representing the whole function invocation. It also sets the context as the environment variable so the SDK can link any subsegment created inside the function back to the parent segment.
If you run the same code locally the SDK still tries to create subsegments for the actual function code but it can't find any context, thus throwing the error you posted.
To solve this you will need to setup some environment variables to make sure the SDK has the same information as it were running on an actual Lambda container.
Make sure the SDK thinks it is running on a Lambda container by setting LAMBDA_TASK_ROOT with whatever value you'd like (only the presence of the key matters). You can see the source code here: https://github.com/aws/aws-xray-sdk-python/blob/master/aws_xray_sdk/core/lambda_launcher.py
Setting LAMBDA_TRACE_HEADER_KEY so the function has a tracing context. The value must be a trace header and you can see more details here: https://docs.aws.amazon.com/lambda/latest/dg/lambda-x-ray.html
This workaround is not ideal as it requires extra code changes from user side. We would like to provide better customer experience for testing X-Ray instrumented Lambda function locally. Do you mind sharing more details about how you are doing local testing and how you expect X-Ray tracing works in such testing environment, so we can have better improvement for your use case?
Here's the simplified example. I have this code:
from pygame import mixer
def say():
mixer.init()
mixer.music.load('/home/orif/Downloads/english.wav')
mixer.music.play()
while mixer.music.get_busy():
time.sleep(0.2)
It displays some warnings but works perfectly. The warnings:
ALSA lib pcm_dsnoop.c:606:(snd_pcm_dsnoop_open) unable to open slave
ALSA lib pcm_dmix.c:1029:(snd_pcm_dmix_open) unable to open slave ALSA
lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM cards.pcm.rear ALSA
lib pcm.c:2266:(snd_pcm_open_noupdate) Unknown PCM
cards.pcm.center_lfe ALSA lib pcm.c:2266:(snd_pcm_open_noupdate)
Unknown PCM cards.pcm.side ALSA lib
pcm_dmix.c:1029:(snd_pcm_dmix_open) unable to open slave
But if I run it in child process it won't:
def test():
talk_process = Process(target=say)
talk_process.start()
print 'waiting for the process...'
talk_process.join()
print 'done'
It prints the same warnings, then:
waiting for the process...
Process Process-1:
Traceback (most recent call last):
File "/usr/lib/python2.7/multiprocessing/process.py", line 258, in _bootstrap
self.run()
File "/usr/lib/python2.7/multiprocessing/process.py", line 114, in run
self._target(*self._args, **self._kwargs)
File "/home/orif/Projects/example.py", line 178, in say
mixer.init()
error: No available audio device
done
If I do the same but with threading, it runs fine. I have tried what's written here and here. In the former link the solution in the comments almost helped me. I initialized mixer just before running the subprocess:
mixer.init()
talk_process.start()
But now the sound doesn't play, and the waiting loop while mixer.music.get_busy() is endless
What is happening and how to solve it?
Alright, my bad, I didn't check everything before asking the question. The code snippet above is a bit incomplete. There were also several imports what I thought was irrelevant. I imported my module where I use SpeechRecognition. In the code there was a function declaration which looked like this:
def foo(m = sr.Microphone()):
pass
At the moment of writing that code I thought, since Python executes everything in the last possible moment, it should work too. And when I ran that code, it did, so everything seemed to be fine. I was wrong.
At the moment of function declaration, that method call was not treated as "if no argument given, substitute with the result of this call", but it was actually called and the return value was used as an optional argument. I don't know what exactly went wrong with sound card while multiprocessing, but that's why I got those weird and obscure error messages.
Here's a little example to show what was causing the issue:
def foo():
print 'TRIGGERED'
return 42
def bar(a = foo()):
print a
if __name__ == '__main__':
pass
Though seems it should do nothing, this code actually prints TRIGGERED. So, instead of assigning values to optional arguments like that, I do something like this:
def foo(a = None):
a = 'bar' if a is None else a
I am trying to use multiprocessing in python for running 10-20 input files which are in xml format together using parallel process which can be achieved by multiprocessing. But when i try to run the code
service = Process(name='my_service', target=function_name, args=(run_xml, result_dest,))
service.start()
I get pickling error when i tried to run the code and can any one suggest me the possible solution?
f(self, obj) # Call unbound method with explicit self
File "D:\Program Files\Aon\PathWise 2.0\apps\py_vendors\Python27\lib\pickle.py", line 748, in save_global
(obj, module, name))
pickle.PicklingError: Can't pickle : it's not found as __main__.new
Hope you can help me out, first question I ask myself but I am always impressed by the professional answers I find here!
I am using xlwings to both read and write data from .xls files. I am not a seasoned programmer, and I make mistakes. From time to time, this means rebooting processes, Python and what-not.
Every now and again, I would get the following AttributeError upon calling Workbook(). The real problem is not that I don't have a clue what is happening (I tried reading the modules the error diagnostics reference to, but they are written on a level of Python that is beyond my skills), but that restarting and even rebooting(!) my laptop don't (always) solve the problem.
I wish I could give some clues as to what is happening, but it appears to be a randomly occurring problem and right now, three reboots and several restarts didn't fix it. Google can't help either. I must have run my program a hundred times by now and it wasn't always a problem! The error message, upon simply calling Workbook():
wb = Workbook()
Traceback (most recent call last):
File "<ipython-input-22-4a3c36eb9bf9>", line 1, in <module>
wb = Workbook()
File "C:\Program Files\Anaconda\lib\site-packages\xlwings\main.py", line 141, in __init__
self.xl_app, self.xl_workbook = xlplatform.new_workbook()
File "C:\Program Files\Anaconda\lib\site-packages\xlwings\_xlwindows.py", line 104, in new_workbook
xl_app = _get_latest_app()
File "C:\Program Files\Anaconda\lib\site-packages\xlwings\_xlwindows.py", line 88, in _get_latest_app
return xl_workbook_current.Application
File "C:\Program Files\Anaconda\lib\site-packages\win32com\client\dynamic.py", line 522, in __getattr__
raise AttributeError("%s.%s" % (self._username_, attr))
AttributeError: Open.Application
And as a follow up, the piece of code from 'dyamic.py' raising the error:
[...]
# If we are still here, and have a retEntry, get the OLE item
if not retEntry is None:
invoke_type = _GetDescInvokeType(retEntry, pythoncom.INVOKE_PROPERTYGET)
debug_attr_print("Getting property Id 0x%x from OLE object" % retEntry.dispid)
try:
ret = self._oleobj_.Invoke(retEntry.dispid,0,invoke_type,1)
except pythoncom.com_error, details:
if details.hresult in ERRORS_BAD_CONTEXT:
# May be a method.
self._olerepr_.mapFuncs[attr] = retEntry
return self._make_method_(attr)
raise
debug_attr_print("OLE returned ", ret)
return self._get_good_object_(ret)
# no where else to look.
raise AttributeError("%s.%s" % (self._username_, attr))
As I mentioned before, the last bit it too much for me :P
I guessed some lingering Excel.exe (or similar) process was interfering with the script after I closed some random window due to some random error, but I cant find one in the task manager. Also, this is the kind of thing a reboot should fix, right?! I also upgraded to xlwings .34 (latest version, as of now).
Windows 8.1 64 bit, Python 2.7 (Anaconda distribution, Spyder IDE), Excel 2013.
Any help is very much appreciated, of course!
Thanks a lot, kind regards,
Gordon.
EDIT:
Following advice given in the comments, I can now report that even at times when wb = Workbook() fails, from win32com.client import dynamic followed by dynamic.Dispatch('Excel.Application') returns <COMObject Excel.Application>.
Hope it helps!
Always check either any issues to open the excel sheet, such as password protected/Licensed issues..
If there is any pop up coming while opening excel, you may get the same error.
on my Raspberry Pi, I encounter a strange behaviour regarding the use of the PiCamera module.
The following code runs smoothly when either started from IDLE (F5) or from the command prompt ($python test.py)
import picamera
if __name__ == "__main__":
camera=picamera.PiCamera()
camera.close()
But when I put the camera object into a class the code will run only when started from IDLE (F5):
import picamera
class VF:
def __init__(self):
self.camera = picamera.PiCamera()
def __del__(self):
self.camera.close()
if __name__ == "__main__":
myvf = VF()
When I start the above code from the command prompt, I get the following error message:
mmal: mmal_vc_component_enable: failed to enable component: ENOSPC
Traceback (most recent call last): File "test.py", line 14, in
myvf = VF()
File "test.py", line 6, in init
self.camera = picamera.PiCamera()
File "/usr/lib/python2.7/dist-packages/picamera/camera.py", line
379, in init
camera_num, self.STEREO_MODES[stereo_mode], stereo_decimate)
File "/usr/lib/python2.7/dist-packages/picamera/camera.py", line
505, in _init_camera
prefix="Camera component couldn't be enabled")
File "/usr/lib/python2.7/dist-packages/picamera/exc.py", line 133,
in mmal_check
raise PiCameraMMALError(status, prefix)
picamera.exc.PiCameraMMALError: Camera component couldn't be enabled:
Out of resources (other than memory)
The camera module is working correct, I just stripped the code down to the least possible size. Does anybody know this problem, or a similar problem, and can probably provide a solution? The Python Version is 2.7 and the Raspberry Rasbiab-System is completely up to date.
Thanks in advance.
I struggled with this one for hours, and kept getting the "out of resources" error. I finally figured out that in my take-the-picture function, I needed to make sure I did it like this:
camera = PiCamera()
(...camera settings here...)
camera.capture(myfileName)
camera.close()
If I didn't do the close(), I'd get that error every time.
So make sure that camera.close() is getting called right after the 'snap'. It solved the problem for me.
Found out, that the camera-module is not properly shut down when the destructor is not explicitly called (had LED turned off, so didn't see this).
IDLE handles a running camera by somehow resetting it before the script starts, but not the python interpreter.
So everything is ok now when the destructor is called before the script ends.