Skip to content
Snippets Groups Projects
slu.py 4.15 KiB
Newer Older
Benoit Favre's avatar
Benoit Favre committed
from gi.repository import GObject, GLib
import threading
Benoit Favre's avatar
Benoit Favre committed
from ctypes import *

_backend = None
Benoit Favre's avatar
Benoit Favre committed
_semaphore = None
Benoit Favre's avatar
Benoit Favre committed

class SLU:
    #/src.new/rocio_slu -word "$prefix"_dico_word.txt -action "$prefix"_dico_action.txt -fstmodel "$prefix".fst -fstclean "$prefix"_clean_tail.fst
Benoit Favre's avatar
Benoit Favre committed
    def __init__(self, word_lexicon, action_lexicon, model_fst, cleaner_fst, library='slu/src/librocio_slu.so'):
Benoit Favre's avatar
Benoit Favre committed
        global _backend, _semaphore
Benoit Favre's avatar
Benoit Favre committed
        if _backend == None:
            _backend = cdll.LoadLibrary(library)

            # slu_t* init_slu(char* chfileword, char* chfileaction, char* chfilemodel, char* chfileclean);
            _backend.init_slu.argtypes = [c_char_p, c_char_p, c_char_p, c_char_p]
            _backend.init_slu.restype = c_void_p

            # int run_slu(slu_t* slu, char** words, int num_words, int prevn, char* prevword);
            _backend.run_slu.argtypes = [c_void_p, POINTER(c_char_p), c_int, c_int, c_char_p]
            _backend.run_slu.restype = c_void_p # c_char_p with manual memory management
Benoit Favre's avatar
Benoit Favre committed

            # int num_actions(slu_t* slu)
            _backend.num_actions.argtypes = [c_void_p]
            _backend.num_actions.restype = c_int
            
            # int get_actions(slu_t* slu)
            _backend.get_actions.argtypes = [c_void_p]
            _backend.get_actions.restype = c_void_p

Benoit Favre's avatar
Benoit Favre committed
            # int get_action(slu_t* slu, int index)
            _backend.get_action.argtypes = [c_void_p, c_int]
            _backend.get_action.restype = c_char_p

            # void reset_slu(slu_t* slu);
            _backend.reset_slu.argtypes = [c_void_p]
            _backend.reset_slu.restype = None

Benoit Favre's avatar
Benoit Favre committed
            # void free_slu(slu_t* slu);
            _backend.free_slu.argtypes = [c_void_p]
            _backend.free_slu.restype = None

            # void free(void*)  from libc
            _backend.free.argtypes = [c_void_p]
            _backend.free.restype = None

Benoit Favre's avatar
Benoit Favre committed
            _semaphore = threading.Semaphore()
        _semaphore.acquire()
        thread = threading.Thread(target=self._init_thread, args=[word_lexicon, action_lexicon, model_fst, cleaner_fst])
        thread.daemon = True
        thread.start()

    def _init_thread(self, word_lexicon, action_lexicon, model_fst, cleaner_fst):
        global _backend, _semaphore
Benoit Favre's avatar
Benoit Favre committed
        self.slu = _backend.init_slu(word_lexicon, action_lexicon, model_fst, cleaner_fst)
Benoit Favre's avatar
Benoit Favre committed
        _semaphore.release()

    def process(self, words, old_words, callback, async=True):
        if async:
            thread = threading.Thread(target=self._process_thread, args=[words, old_words, callback])
            thread.daemon = True
            thread.start()
        else:
            self._process_thread(words, old_words, callback)
Benoit Favre's avatar
Benoit Favre committed

    def _process_thread(self, words, old_words, callback):
Benoit Favre's avatar
Benoit Favre committed
        global _backend, _semaphore
Benoit Favre's avatar
Benoit Favre committed
        c_words = (c_char_p * len(words))(*words)
Benoit Favre's avatar
Benoit Favre committed
        _semaphore.acquire()
        c_output = _backend.run_slu(self.slu, c_words, len(words), -1, old_words)
Benoit Favre's avatar
Benoit Favre committed
        _semaphore.release()
        output = cast(c_output, c_char_p).value
        _backend.free(c_output)
Benoit Favre's avatar
Benoit Favre committed
        GLib.idle_add(callback, self, output)
Benoit Favre's avatar
Benoit Favre committed

    def num_actions(self):
Benoit Favre's avatar
Benoit Favre committed
        global _backend, _semaphore
        output = _backend.num_actions(self.slu)
        return output
Benoit Favre's avatar
Benoit Favre committed

    def get_actions(self):
        global _backend, _semaphore
        c_output = _backend.get_actions(self.slu)
        output = cast(c_output, c_char_p).value
        _backend.free(c_output)
        return output

Benoit Favre's avatar
Benoit Favre committed
    def get_action(self, index):
Benoit Favre's avatar
Benoit Favre committed
        global _backend, _semaphore
        output = _backend.get_action(self.slu, index)
        return output
Benoit Favre's avatar
Benoit Favre committed

    def reset_slu(self):
        global _backend, _semaphore
        _semaphore.acquire()
        _backend.reset_slu(self.slu)
        _semaphore.release()

Benoit Favre's avatar
Benoit Favre committed
    def shutdown(self):
Benoit Favre's avatar
Benoit Favre committed
        global _backend, _semaphore
Benoit Favre's avatar
Benoit Favre committed
        _backend.free_slu(self.slu)

if __name__ == '__main__':
    prefix = 'slu/automate/homeostasis_25nov_%s'
    slu = SLU(prefix % 'dico_word.txt', prefix % 'dico_action.txt', prefix % 'section6.fst', prefix % 'clean_tail.fst')
    #print 'before'
Benoit Favre's avatar
Benoit Favre committed
    slu.process(open('slu/homeostasis_25nov.asr/sect6.ref').read().strip().split(), lambda x: sys.stdout.write('%s\n' % x))
    #print 'after'
Benoit Favre's avatar
Benoit Favre committed
    slu.shutdown()