//  [python]
def main():
    print("#####################################################")
    print("Loading t2t model + scoring")
    t2t_sess, t2t_tvars, t2t_inputs_ph, t2t_targets_ph, t2t_losses = t2t_score_file(FLAGS_score_file)

    print("#####################################################")
    print("Loading returnn config")

    rnn.init(
        config_updates={
            "optimize_move_layers_out": True,
            "use_tensorflow": True,
            "num_outputs": num_outputs,
            "num_inputs": num_inputs,
            "task": "nop",
            "log": None,
            "device": "cpu",
            "network": returnn_network,
            "debug_print_layer_output_template": True,
            "debug_add_check_numerics_on_output": False,
        },
        extra_greeting="Import t2t model.",
    )
    assert util.BackendEngine.is_tensorflow_selected()
    config = rnn.config

    rnn.engine.init_train_from_config(config=config)
    network = rnn.engine.network
    assert isinstance(network, TFNetwork)

    print("t2t network model params:")
    t2t_params = {}  # type: dict[str,tf.Variable]
    t2t_total_num_params = 0
    for v in t2t_tvars:
        key = v.name[:-2]
        t2t_params[key] = v
        print("  %s: %s, %s" % (key, v.shape, v.dtype.base_dtype.name))
        t2t_total_num_params += numpy.prod(v.shape.as_list())
    print("t2t total num params: %i" % t2t_total_num_params)

    print("Our network model params:")
    our_params = {}  # type: dict[str,tf.Variable]
    our_total_num_params = 0
    for v in network.get_params_list():
        key = v.name[:-2]
        our_params[key] = v
        print("  %s: %s, %s" % (key, v.shape, v.dtype.base_dtype.name))
        our_total_num_params += numpy.prod(v.shape.as_list())
    print("Our total num params: %i" % our_total_num_params)

    print("Loading t2t params into our network:")
    for ret_var_name, ret_var in our_params.items():
        if ret_var_name in ret_to_t2t:
            t2t_var_names = ret_to_t2t[ret_var_name]
            # in return QKV params are concatenated into one tensor
            if isinstance(t2t_var_names, tuple):
                # params_np = numpy.concatenate([t2t_params[var_name].eval(t2t_sess) for var_name in t2t_var_names], axis=1) # Not enough...
                # More complex stacking necessary: head1 Q, head1 K, head1 V,   head2 Q, head2 K, head2 V, ...
                q_np = t2t_params[t2t_var_names[0]].eval(t2t_sess)
                k_np = t2t_params[t2t_var_names[1]].eval(t2t_sess)
                v_np = t2t_params[t2t_var_names[2]].eval(t2t_sess)
                qkv_dim_total = 2 * EncKeyTotalDim + EncValueTotalDim
                params_np = numpy.empty((EncValueTotalDim, qkv_dim_total), dtype=q_np.dtype)
                qkv_dim_per_head = qkv_dim_total // AttNumHeads
                for i in range(EncKeyPerHeadDim):
                    params_np[:, i::qkv_dim_per_head] = q_np[:, i::EncKeyPerHeadDim]
                for i in range(EncKeyPerHeadDim):
                    params_np[:, i + EncKeyPerHeadDim :: qkv_dim_per_head] = k_np[:, i::EncKeyPerHeadDim]
                for i in range(EncValuePerHeadDim):
                    params_np[:, i + 2 * EncKeyPerHeadDim :: qkv_dim_per_head] = v_np[:, i::EncValuePerHeadDim]
            else:
                t2t_var = t2t_params[t2t_var_names]
                params_np = t2t_var.eval(t2t_sess)
            if ret_var_name in ["output/rec/output_prob/W"]:  # ToDo: Something else to transpose?
                params_np = params_np.transpose()
            if ret_var_name in ["source_embed_raw/W", "output/rec/target_embed_raw/W"]:
                # params_np = params_np * (EncValueTotalDim**0.5) # ToDo: Only because of weight-tying?
                print("loading %s with * (EncValueTotalDim**0.5) or doing it in config" % ret_var.name)
            ret_var.load(params_np, rnn.engine.tf_session)
            print("loaded %s" % ret_var.name)
        else:
            print("skpipped over %s" % ret_var.name)

    ret_ph_train = rnn.engine.tf_session.graph.get_tensor_by_name("global_tensor_train_flag/train_flag:0")
    ret_ph_data = rnn.engine.tf_session.graph.get_tensor_by_name("extern_data/placeholders/data/data:0")
    ret_ph_data_dim = rnn.engine.tf_session.graph.get_tensor_by_name("extern_data/placeholders/data/data_dim0_size:0")
    ret_ph_classes = rnn.engine.tf_session.graph.get_tensor_by_name("extern_data/placeholders/classes/classes:0")
    ret_ph_classes_dim = rnn.engine.tf_session.graph.get_tensor_by_name(
        "extern_data/placeholders/classes/classes_dim0_size:0"
    )

    # ret_feed = {ret_ph_train: True, ret_ph_data: [[11, 78, 42, 670, 2415, 2, 134, 2, 61, 522, 2, 847, 2, 3353, 15, 33, 2534, 1], [3,6]], ret_ph_data_dim: [18, 2],
    #            ret_ph_classes: [[4, 60, 18, 46, 26, 2937, 520, 2, 1317, 2, 10, 642, 4, 639, 1], [2,5]], ret_ph_classes_dim:[14, 2]}

    # src = [[78, 1,0], [2, 134, 1]]; src_lens = [2,3]; trg = [[4, 60, 1], [639, 1, 0]]; trg_lens = [3,2]; ret_feed = {ret_ph_train: False, ret_ph_data: src, ret_ph_data_dim: src_lens, ret_ph_classes: trg, ret_ph_classes_dim: trg_lens}; t2t_feed = {t2t_inputs_ph: src, t2t_targets_ph: trg}

    src = [[2, 134, 1]]
    src_lens = [3]
    trg = [[4, 60, 1]]
    trg_lens = [3]
    ret_feed = {
        ret_ph_train: False,
        ret_ph_data: src,
        ret_ph_data_dim: src_lens,
        ret_ph_classes: trg,
        ret_ph_classes_dim: trg_lens,
    }
    t2t_feed = {t2t_inputs_ph: src, t2t_targets_ph: trg}

    compare_acts(network, t2t_sess, ret_feed, t2t_feed, act_ret_to_t2t)

    # filtered = [op for op in t2t_sess.graph.get_operations() if '/encoder/layer_0/self_attention' in op.name and op.type == 'MatMul']
    # filtered = [op for op in rnn.engine.tf_session.graph.get_operations() if 'enc_1_self_att_/' in op.name and op.type == 'MatMul']
    # for op in filtered: print(op.name)
    #

    ipdb.set_trace()