# Path: nmt_chainer/utilities/utils.py
# def ortho_init(link):
#     if isinstance(link, chainer.links.Linear):
#         print("init ortho", link)
#         link.W.data[...] = gen_ortho(link.W.data.shape)
#     elif isinstance(link, chainer.links.GRU):
#         print("init ortho", link)
#         for name_lin in "W_r U_r W_z U_z W U".split(" "):
#             print("case", name_lin, getattr(link, name_lin))
#             ortho_init(getattr(link, name_lin))
#     elif isinstance(link, chainer.links.Maxout):
#         print("init ortho", link)
#         ortho_init(link.linear)
#     else:
#         raise NotImplemented


import chainer
import chainer.functions as F
import chainer.links as L
import six
import logging
from chainer import cuda, Variable
from chainer import Link, Chain, ChainList
from . import rnn_cells
from nmt_chainer.utilities.utils import ortho_init
        sequence[i].data[j] should be the jth element of source sequence number i, or a padding value if the sequence number i is
            shorter than j.

        mask should be a python list of Chainer Variables wrapping a numpy/cupy array of shape (mb_size,) and type bool each.
        mask[i].data[j] should be True if and only if sequence[i].data[j] is not a padding value.

        Return a chainer variable of shape (mb_size, #length, 2*Hi) and type float32
    """

    def __init__(self, Vi, Ei, Hi, init_orth=False, use_bn_length=0, cell_type=rnn_cells.LSTMCell):
        gru_f = cell_type(Ei, Hi)
        gru_b = cell_type(Ei, Hi)

        log.info("constructing encoder [%s]" % (cell_type,))
        super(Encoder, self).__init__(
            emb=L.EmbedID(Vi, Ei),
            #             gru_f = L.GRU(Hi, Ei),
            #             gru_b = L.GRU(Hi, Ei)

            gru_f=gru_f,
            gru_b=gru_b
        )
        self.Hi = Hi

        if use_bn_length > 0:
            self.add_link("bn_f", BNList(Hi, use_bn_length))
#             self.add_link("bn_b", BNList(Hi, use_bn_length)) #TODO
        self.use_bn_length = use_bn_length

        if init_orth:

# Path: nmt_chainer/utilities/utils.py
# def ortho_init(link):
#     if isinstance(link, chainer.links.Linear):
#         print("init ortho", link)
#         link.W.data[...] = gen_ortho(link.W.data.shape)
#     elif isinstance(link, chainer.links.GRU):
#         print("init ortho", link)
#         for name_lin in "W_r U_r W_z U_z W U".split(" "):
#             print("case", name_lin, getattr(link, name_lin))
#             ortho_init(getattr(link, name_lin))
#     elif isinstance(link, chainer.links.Maxout):
#         print("init ortho", link)
#         ortho_init(link.linear)
#     else:
#         raise NotImplemented


# Path: nmt_chainer/models/encoders.py
import chainer
import chainer.functions as F
import chainer.links as L
import six
import logging
from chainer import cuda, Variable
from chainer import Link, Chain, ChainList
from . import rnn_cells
from nmt_chainer.utilities.utils import ortho_init

        sequence[i].data[j] should be the jth element of source sequence number i, or a padding value if the sequence number i is
            shorter than j.

        mask should be a python list of Chainer Variables wrapping a numpy/cupy array of shape (mb_size,) and type bool each.
        mask[i].data[j] should be True if and only if sequence[i].data[j] is not a padding value.

        Return a chainer variable of shape (mb_size, #length, 2*Hi) and type float32
    """

    def __init__(self, Vi, Ei, Hi, init_orth=False, use_bn_length=0, cell_type=rnn_cells.LSTMCell):
        gru_f = cell_type(Ei, Hi)
        gru_b = cell_type(Ei, Hi)

        log.info("constructing encoder [%s]" % (cell_type,))
        super(Encoder, self).__init__(
            emb=L.EmbedID(Vi, Ei),
            #             gru_f = L.GRU(Hi, Ei),
            #             gru_b = L.GRU(Hi, Ei)

            gru_f=gru_f,
            gru_b=gru_b
        )
        self.Hi = Hi

        if use_bn_length > 0:
            self.add_link("bn_f", BNList(Hi, use_bn_length))
#             self.add_link("bn_b", BNList(Hi, use_bn_length)) #TODO
        self.use_bn_length = use_bn_length

        if init_orth:

            ortho_init(self.gru_f)