Example #1
0
 def test_new_handle(self):
     ffi = FFI(backend=self.Backend())
     o = [2, 3, 4]
     p = ffi.new_handle(o)
     assert ffi.typeof(p) == ffi.typeof("void *")
     assert ffi.from_handle(p) is o
     assert ffi.from_handle(ffi.cast("char *", p)) is o
     py.test.raises(RuntimeError, ffi.from_handle, ffi.NULL)
Example #2
0
 def test_new_handle(self):
     ffi = FFI(backend=self.Backend())
     o = [2, 3, 4]
     p = ffi.new_handle(o)
     assert ffi.typeof(p) == ffi.typeof("void *")
     assert ffi.from_handle(p) is o
     assert ffi.from_handle(ffi.cast("char *", p)) is o
     py.test.raises(RuntimeError, ffi.from_handle, ffi.NULL)
Example #3
0
class CTC(object):
    """
    """
    def __init__(self, on_device='cpu', blank_label=0):
        libpath = get_ctc_lib()
        self.ffi = FFI()
        self.ffi.cdef(ctc_header())
        self.ctclib = self.ffi.dlopen(libpath)

        supported_devices = ['cpu', 'gpu']
        if on_device not in supported_devices:
            print("the requested device {} is not supported".format(on_device),
                  file=sys.stderr)
            sys.exit(1)
        assign_device = 0 if on_device is 'cpu' else 1

        self.options = self.ffi.new('ctcOptions*', {
            "loc": assign_device,
            "blank_label": blank_label
        })[0]
        self.size_in_bytes = self.ffi.new("size_t*")
        self.nout = None
        self.bsz = None

    def get_buf_size(self, ptr_to_buf):
        return self.ffi.sizeof(
            self.ffi.getctype(self.ffi.typeof(ptr_to_buf).item))

    def buf_ref_from_array(self, arr):
        return self.ffi.from_buffer(
            self.ffi.buffer(self.ffi.cast('void*', arr.ptr), arr.nbytes))

    def buf_ref_from_ptr(self, ptr, size):
        return self.ffi.from_buffer(self.ffi.buffer(ptr, size))

    def get_gpu_workspace_size(self, lbl_lens, utt_lens, nout, bsz):
        self.nout = nout
        self.bsz = bsz
        _lbl_lens = self.ffi.cast("int*", lbl_lens.ravel().ctypes.data)
        _utt_lens = self.ffi.cast("int*", utt_lens.ravel().ctypes.data)

        status = self.ctclib.get_workspace_size(_lbl_lens, _utt_lens,
                                                self.nout, self.bsz,
                                                self.options,
                                                self.size_in_bytes)
        assert status is 0, "get_workspace_size() in warp-ctc failed"

        return self.size_in_bytes[0]

    def bind_to_gpu(self, acts, grads, lbls, lbl_lens, utt_lens, costs,
                    workspace, scratch_size, stream):

        if stream is None:
            stream_ptr = self.ffi.cast('void*', 0)
            stream_buf_size = self.ffi.sizeof(self.ffi.new_handle(stream))
            stream_buf = self.buf_ref_from_ptr(stream_ptr, stream_buf_size)
        else:
            stream_buf = self.ffi.cast("void*", stream.handle)

        self.options.stream = stream_buf

        flat_dims = np.prod(acts.shape)
        assert np.prod(grads.shape) == flat_dims

        acts_buf = self.ffi.cast("float*", self.buf_ref_from_array(acts))
        grads_buf = self.ffi.cast("float*", self.buf_ref_from_array(grads))
        costs_buf = self.ffi.cast("float*", self.buf_ref_from_array(costs))

        warp_grads_buf_size = flat_dims * self.get_buf_size(grads_buf)
        warp_costs_buf_size = self.bsz * self.get_buf_size(costs_buf)

        warp_labels = self.ffi.cast("int*", lbls.ravel().ctypes.data)
        warp_label_lens = self.ffi.cast("int*", lbl_lens.ravel().ctypes.data)
        warp_input_lens = self.ffi.cast("int*", utt_lens.ravel().ctypes.data)

        workspace_buf = self.buf_ref_from_ptr(
            self.ffi.cast('void*', workspace), int(scratch_size))

        ctc_status = self.ctclib.compute_ctc_loss(acts_buf, grads_buf,
                                                  warp_labels, warp_label_lens,
                                                  warp_input_lens, self.nout,
                                                  self.bsz, costs_buf,
                                                  workspace_buf, self.options)

        assert ctc_status is 0, "warp-ctc run failed"

    def bind_to_cpu(self,
                    acts,
                    lbls,
                    utt_lens,
                    lbl_lens,
                    grads,
                    costs,
                    n_threads=1):

        self.options.num_threads = n_threads
        _, self.bsz, self.nout = acts.shape
        flat_dims = np.prod(acts.shape)
        assert np.prod(grads.shape) == flat_dims

        acts_buf = self.ffi.cast("float*", acts.ctypes.data)
        grads_buf = self.ffi.cast("float*", grads.ctypes.data)
        costs_buf = self.ffi.cast("float*", costs.ctypes.data)

        warp_grads_buf_size = flat_dims * self.get_buf_size(grads_buf)
        warp_costs_buf_size = self.bsz * self.get_buf_size(costs_buf)

        warp_labels = self.ffi.cast("int*", lbls.ravel().ctypes.data)
        warp_label_lens = self.ffi.cast("int*", lbl_lens.ravel().ctypes.data)
        warp_input_lens = self.ffi.cast("int*", utt_lens.ravel().ctypes.data)
        status = self.ctclib.get_workspace_size(warp_label_lens,
                                                warp_input_lens, self.nout,
                                                self.bsz, self.options,
                                                self.size_in_bytes)

        assert status is 0, "get_workspace_size() in warp-ctc failed"

        # TODO: workspace is a variable size buffer whose size is
        # determined during each call, so we can't initialize ahead
        # of time. Can we avoid this?
        workspace = self.ffi.new("char[]", self.size_in_bytes[0])

        ctc_status = self.ctclib.compute_ctc_loss(acts_buf, grads_buf,
                                                  warp_labels, warp_label_lens,
                                                  warp_input_lens, self.nout,
                                                  self.bsz, costs_buf,
                                                  workspace, self.options)

        # transfer grads and costs back without copying
        self.ffi.memmove(grads, grads_buf, warp_grads_buf_size)
        grads = grads.reshape((acts.shape))
        self.ffi.memmove(costs, costs_buf, warp_costs_buf_size)

        assert ctc_status is 0, "warp-ctc run failed"
Example #4
0
class LibGraphqlParser:
    def __init__(self):
        self._ffi = FFI()
        self._ffi.cdef(CDEFS_LIBGRAPHQL)
        # TODO do a conf of this ?
        try:
            self._lib = self._ffi.dlopen("/usr/local/lib/libgraphqlparser.so")
        except OSError:
            self._lib = self._ffi.dlopen("/usr/local/lib/libgraphqlparser.dylib")
        self._lib_callbacks = self._ffi.new(
            "struct GraphQLAstVisitorCallbacks *"
        )
        self._errors = self._ffi.new("char **")
        self._callbacks = []
        self._interested_by = {}
        self._default_visitor_cls = Visitor
        self._creates_callbacks()

    def _create_visitor_element(self, libgraphql_type, element):
        try:
            return _LIBGRAPHQL_TYPE_TO_CLASS[libgraphql_type](
                self._lib, self._ffi, element)
        except KeyError:
            pass

        return _VisitorElement(self._lib, self._ffi, libgraphql_type, element)

    def _callback_enter(self, libgraphql_type, element, udata):
        context = self._ffi.from_handle(udata)
        context.update(
            Visitor.IN, self._create_visitor_element(libgraphql_type, element)
        )
        return context.continue_child

    def _callback_exit(self, libgraphql_type, element, udata):
        context = self._ffi.from_handle(udata)
        if context.continue_child:
            context.update(
                Visitor.OUT, self._create_visitor_element(libgraphql_type, element)
            )
        return None

    def _set_callback(self, proto, func, attr):
        c_func = self._ffi.callback(proto)(func)
        # Keep the callbacks alive in this list
        # to keep the underlying cdata alive.
        # because we do it with reflexion and
        # not with decoration
        self._callbacks.append(c_func)
        setattr(self._lib_callbacks, attr, c_func)

    def _set_exit_callback(self, typee):
        self._set_callback(
            "void(struct GraphQLAst%s *, void *)" % typee[0],
            partial(self._callback_exit, typee[0]), "end_visit_%s" % typee[1]
        )

    def _set_enter_callback(self, typee):
        self._set_callback(
            "int(struct GraphQLAst%s *, void *)" % typee[0],
            partial(self._callback_enter, typee[0]), "visit_%s" % typee[1]
        )

    def _creates_callbacks(self):
        for typee in TYPES_LIBGRAPHQL:
            if typee[0] not in ["Name"]:
                self._set_enter_callback(typee)
                self._set_exit_callback(typee)

    def _parse(self, query):
        if isinstance(query, str):
            # TODO don't replace here.
            query = query.replace("\n", " ").encode("UTF-8")

        c_query = self._ffi.new("char[]", query)
        parsed_data = _ParsedData(
            self._lib.graphql_parse_string(c_query, self._errors),
            self._lib.graphql_node_free
        )

        if self._errors[0] != self._ffi.NULL:
            # TODO specialize Exception here
            e = Exception(
                self._ffi.string(self._errors[0]).decode('UTF-8', 'replace')
            )
            self._lib.graphql_error_free(self._errors[0])
            raise e

        return parsed_data

    def parse_and_visit(self, query, ctx=None):
        if not ctx:
            ctx = self._default_visitor_cls()

        with self._parse(query) as parsed:
            self._lib.graphql_node_visit(
                parsed, self._lib_callbacks, self._ffi.new_handle(ctx)
            )

    def parse_and_jsonify(self, query):
        with self._parse(query) as parsed:
            return self._ffi.string(self._lib.graphql_ast_to_json(parsed))
Example #5
0
# -*- coding: utf-8 -*-

# TODO: this does not works.

from cffi import FFI
ffi = FFI()
ffi.cdef("""
    void print_address(void *obj);
""")

c_lib = ffi.dlopen("./libsample2.so")


class Foo(object):
    def __init__(self, address):
        self.address = address

    def get_address(self):
        return self.address

print_address = c_lib.print_address

instance = Foo("Foo Bar")
_instance = ffi.new_handle(instance)

print_address(instance)