Is there a recommended way to create a Ray remote class (actor pattern) from a Python class that is subclassed from a Cython wrapper?
When I use Cython to wrap a C++ class, then create a Python subclass from that – even though the code works fine, Ray throws exceptions when I add the @ray.remote
decorator to the Python subclass. From the exceptions, it appears that the constructor does not have the correct arguments. Is there a recommended way to work around this?
Here’s an example:
the libffurf.hpp
C++ header file:
namespace ffurf {
class Foo {
public:
int x;
Foo ();
Foo (int x);
~Foo ();
};
}
the libffurf.cpp
C++ source file:
#include "libffurf.hpp"
using namespace ffurf;
// default constructor
Foo::Foo () {}
// overloaded constructor
Foo::Foo (int x) {
this->x = x;
}
// destructor
Foo::~Foo () {}
the ffurf_part.pyx
Cython extension file:
cdef extern from "libffurf.hpp" namespace "ffurf":
cdef cppclass Foo:
Foo (int) except +
int x
cdef class CyFoo:
cdef Foo *cpp_obj
def __cinit__ (self, int x):
self.cpp_obj = new Foo(x)
the partact.py
Python source file used for testing:
import ray
import ffurf_part
@ray.remote
class Foo (ffurf_part.CyFoo):
def see_foo ():
print("hello")
the error traceback:
Traceback (most recent call last):
File "partact.py", line 8, in <module>
class Foo (ffurf_part.CyFoo):
File "/home/paco/anaconda3/lib/python3.8/site-packages/ray/worker.py", line 1990, in remote
return make_decorator(worker=worker)(args[0])
File "/home/paco/anaconda3/lib/python3.8/site-packages/ray/worker.py", line 1868, in decorator
return ray.actor.make_actor(function_or_class, num_cpus, num_gpus,
File "/home/paco/anaconda3/lib/python3.8/site-packages/ray/actor.py", line 1069, in make_actor
return ActorClass._ray_from_modified_class(
File "/home/paco/anaconda3/lib/python3.8/site-packages/ray/actor.py", line 383, in _ray_from_modified_class
self = DerivedActorClass.__new__(DerivedActorClass)
File "ffurf_part.pyx", line 26, in ffurf_part.CyFoo.__cinit__
def __cinit__ (self, int x):
TypeError: __cinit__() takes exactly 1 positional argument (0 given)
When I remove the @ray.remote
decorator, then instantiate a Foo
object and call its methods, this example works fine.