执行@ ray.remote函数时,即使我提供函数定义中设置的所有参数,也会引发以下异常:
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ray/signature.py in extend_args(function_signature, args, kwargs)
208 raise Exception("No value was provided for the argument "
209 "'{}' for the function '{}'.".format(
--> 210 keyword_name, function_name))
211
212 no_positionals = len(arg_is_positionals) == 0 or not arg_is_positionals[-1]
Exception: No value was provided for the argument 'phones' for the function 'compile_file'.
编辑:我的远程函数定义和远程调用的一个最小示例如下:
import ray
ray.init(num_cpus=4, num_gpus=1, include_webui=False) #initialize ray with 4 CPUs
@ray.remote
def compile_file(self, rgx_patts, phones): # method for my Case class
self._phones = self.phonelist(rgx_patts, phones)
def compile_all(inputDirectory='C/TODOS', phones = ['10002000']):
d = {}
file_lst = pdfLister(inputDirectory, termin)
for i, file in enumerate(file_lst):
doc = Case(file)
doc.compile_file.remote(rgx_patts, phones) # exception thrown here
d[i] = doc
case_dic = {k: ray.get(dic_id) for k, dic_id in d.items()}
return case_dic
编辑:以下为完全例外
---------------------------------------------------------------------------
Exception Traceback (most recent call last)
<timed exec> in <module>()
~/compile_files.py in compile_all(pckle, inputDirectory, pickle_op_file, termin, rgx_patts, ceav_phones)
111 prm._rgx_patts, prm._ceav_phones)
114 d[i] = doc
115 ceav_dic = {k: ray.get(dic_id) for k, dic_id in d.items()}
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ray/remote_function.py in remote(self, *args, **kwargs)
103 def remote(self, *args, **kwargs):
104 """This runs immediately when a remote function is called."""
--> 105 return self._submit(args=args, kwargs=kwargs)
106
107 def _submit(self,
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ray/remote_function.py in _submit(self, args, kwargs, num_return_vals, num_cpus, num_gpus, resources)
118 kwargs = {} if kwargs is None else kwargs
119 args = ray.signature.extend_args(self._function_signature, args,
--> 120 kwargs)
121
122 if num_return_vals is None:
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/ray/signature.py in extend_args(function_signature, args, kwargs)
208 raise Exception("No value was provided for the argument "
209 "'{}' for the function '{}'.".format(
--> 210 keyword_name, function_name))
211
212 no_positionals = len(arg_is_positionals) == 0 or not arg_is_positionals[-1]
Exception: No value was provided for the argument 'ceav_phones' for the function 'compile_file'.
答案 0 :(得分:2)
在您的示例中,compile_file
似乎是一个类的方法,但是未提供类定义。
我建议将所有内容都移到compile_file
函数中,以便它是一个独立的函数,例如
import ray
ray.init(num_cpus=4, num_gpus=1)
class Case(object):
def __init__(self, file):
pass
def compile_file(self):
pass
@ray.remote
def compile_file_helper(file):
case = Case(file)
case.compile_file()
value_ids = []
for file in ['file1', 'file2', 'file3']:
value_ids.append(compile_file_helper.remote(file))
values = ray.get(value_ids)
另一种替代方法是使Case
类成为演员。例如,
# This assumes you've already called "import ray" and "ray.init()".
@ray.remote
class Case(object):
def __init__(self, file):
pass
def compile_file(self):
pass
# Create one actor per file (more generally, you could create a pool
# of actors and have each actor compile multiple files).
value_ids = []
for file in ['file1', 'file2', 'file3']:
case = Case.remote(file)
value_ids.append(case.compile_file.remote())
values = ray.get(value_ids)
在此示例中,我们仅在每个actor上调用一个方法,但是,这种方法仅在您要为每个actor调用多个方法时才有意义。
答案 1 :(得分:0)
发生异常的原因是您的远程函数需要三个参数:self,rgx_patts和phone,因为这是它的声明方式:
@ray.remote
def compile_file(self, rgx_patts, phones):
请注意,您在通话中仅传递了两个参数:
doc.compile_file.remote(rgx_patts, phones)
第一个参数被解释为self,第二个参数被解释为rgx_patts,并且电话没有传递任何参数,因此是例外。可能的解决方法是将对象(在您的示例中为doc)作为第一个参数传递,这样调用将变为:
doc.compile_file.remote(doc, rgx_patts, phones)
哪个看起来有些古怪,但是我认为它应该工作-实际上,它在类似的情况下也对我有用,尽管由于您的代码示例不是自包含的,所以我无法针对您的情况对其进行测试。如果采用此解决方案,并且doc
的使用时间相同,则可能要使用ray.put()
来序列化doc
一次,而不是每次调用该方法时都要使用。为此,您可以做doc_id = ray.put(doc)
(仅一次),然后在上面的代码中将doc
替换为doc_id
(doc_id
是序列化{{1的对象ID }})。
请注意,另一种解决方案是将您的类转换为Actor,如果您的类的“状态”需要在方法的两次调用之间存储在内存中,则这似乎是合适的。