I have a directory tree
working_dir\
main.py
my_agent\
my_worker.py
my_utility\
my_utils.py
Code in each file is as follows
""" main.py """
import os, sys
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from my_agent.my_worker import MyWorker
import ray
ray.init()
workers = [MyWorker.remote(i) for i in range(10)]
ids = [worker.get_id.remote() for worker in workers]
# print(*ids, sep='\n')
print(*ray.get(ids), sep='\n')
""" worker.py """
from my_utility import my_utils
import ray
@ray.remote
class MyWorker():
def __init__(self, id):
self.id = id
def get_id(self):
return my_utils.f(self.id)
""" my_utils.py """
def f(id):
return '{}: Everything is fine...'.format(id)
Here's a part of the error message I received
Traceback (most recent call last):
File "/Users/aptx4869/anaconda3/envs/p35/lib/python3.5/site-packages/ray/function_manager.py", line 616, in fetch_and_register_actor unpickled_class = pickle.loads(pickled_class)
File "/Users/aptx4869/anaconda3/envs/p35/lib/python3.5/site-packages/ray/cloudpickle/cloudpickle.py", line 894, in subimport import(name)
ImportError: No module named 'my_utility'
Traceback (most recent call last):
File "main.py", line 12, in print(*ray.get(ids), sep='\n')
File "/Users/aptx4869/anaconda3/envs/p35/lib/python3.5/site-packages/ray/worker.py", line 2377, in get raise value ray.worker.RayTaskError: ray_worker (pid=30025, host=AiMacbook)
Exception: The actor with name MyWorker failed to be imported, and so cannot execute this method
If I remove all statements related to ray
, the above code works fine. Therefore, I boldly guess the reason is that ray
runs each actor in a new process and sys.path.append
only works in the main process. So I add the following code to worker.py
import os, sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
But it still does not work: the same error message shows up. Now I run out of ideas, what should I do?
os.path.dirname(os.path.dirname(__file__))
better than thisos.path.join(os.path.dirname(__file__), '..')
– Cadellesys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
. But this does not work either... – Curacyif __name__ == '__main__' and __package__ is None:
? and simply always add to your path the parent directory? – Cadelle__init__.py
, doesn't it? – Curacy__init__.py
to all directory, even the root directory which contains these three folders. It still does not work. – Curacyutils.py
andworker.py
and I see ray has these files too. Rename your files with a prefix to avoid the clash. – Edisoneditmy
,,, still not working... – Curacyprint
statement. IMHO, if the error is caused by name conflict, it should not happen so late. – Curacymultiprocessing.Pool
it's necessary that imports for used functions are made for every distributed task again. I'm not familiar with ray's internals but that lineImportError: No module named 'utils'
makes me wonder. It looks like it's trying to import utils fromutils.py
instead of from the directory. – EdisoneditImportError
refers to the folder namemy_utility
instead of themy_utils.py
file. To my best knowledge, I think ray callsfrom my_utility import my_utils
in every new actor process, and that causes this problem. – Curacy