Exemple #1
0
def test_synthesizer_count_5s():
    libSynth = getLib()

    tr1_1_28_28 = mkRealTensorSort([1, 1, 28, 28])
    tr1_1 = mkRealTensorSort([1, 1])
    tb1_1 = mkBoolTensorSort([1, 1])

    libSynth.addItems([
        PPLibItem('recog_5', func(tr1_1_28_28, tb1_1), None),
    ])

    fn_sort = func(lst(tr1_1_28_28), tr1_1)

    synth = SymbolicSynthesizer(libSynth, fn_sort)

    I = 10000
    i = 0
    for prog, unkMap in synth.genProgs():

        i = i + 1
        if i > I:
            break
        if i % 100 == 0:
            print(i)

        unks = ASTUtils.getUnks(prog)

        if len(unks) > 1:
            continue

        for unk in unks:
            if ASTUtils.isAbstract(unk.sort):
                continue

        print(repr_py_ann(prog))
Exemple #2
0
def test_synthesizer_sum_digits():
    libSynth = getLib()

    input_type = mkListSort(mkRealTensorSort([1, 1, 28, 28]))
    output_type = mkRealTensorSort([1, 1])
    fn_sort = mkFuncSort(input_type, output_type)

    tr1_1_28_28 = mkRealTensorSort([1, 1, 28, 28])
    tb_1_10 = mkBoolTensorSort([1, 10])
    classify_digit = mkFuncSort(tr1_1_28_28, tb_1_10)

    libSynth.addItems([
        PPLibItem('classify_digit', classify_digit, None),
    ])

    synth = SymbolicSynthesizer(libSynth, fn_sort)

    I = 10000
    i = 0
    for prog, unkMap in synth.genProgs():

        i = i + 1
        if i > I:
            break
        if i % 100 == 0:
            print(i)

        unks = ASTUtils.getUnks(prog)

        if len(unks) > 1:
            continue

        for unk in unks:
            if ASTUtils.isAbstract(unk.sort):
                continue

        print(repr_py_ann(prog))
Exemple #3
0
def is_evaluable(st, ns) -> Tuple[bool, int]:
    # The program should not be open (no non-terminals).
    if ASTUtils.isOpen(st):
        return False, 1

    unks = ASTUtils.getUnks(st)

    # At most 3 unks for now.
    if len(unks) > 3:
        return False, 2

    # return False, 3
    # print(repr_py(st))

    number_of_mlp_nns = 0

    for unk in unks:
        # type variables and dimension variables not allowed.
        if ASTUtils.isAbstract(unk.sort):
            return False, 3

        # Only function types allowed
        if type(unk.sort) != PPFuncSort:
            return False, 4

        # ******* INPUTS ******* :
        # An input to a function can't be a function
        if any([type(arg_sort) == PPFuncSort for arg_sort in unk.sort.args]):
            return False, 11

        fn_input_sort = unk.sort.args[0]
        fn_output_sort = unk.sort.rtpe

        # No more than 2 arguments
        num_input_arguments = unk.sort.args.__len__()
        if num_input_arguments > 1:
            in1_is_2d_tensor = type(
                unk.sort.args[0]
            ) == PPTensorSort and unk.sort.args[0].shape.__len__() == 2
            in2_is_2d_tensor = type(
                unk.sort.args[1]
            ) == PPTensorSort and unk.sort.args[1].shape.__len__() == 2
            out_is_2d_tensor = type(
                unk.sort.rtpe) == PPTensorSort and unk.sort.rtpe.shape.__len__(
                ) == 2
            # If a function takes 2 inputs, they'll be concatenated. Thus, we need them to be 2 dimensional tensors
            if num_input_arguments == 2 and in1_is_2d_tensor and in2_is_2d_tensor and out_is_2d_tensor:
                continue
            else:
                return False, 5

        # If the NN's input is a list, it should be: List<2dTensor> -> 2dTensor
        # (as seq-to-seq models aren't supported)
        # We support List<2dTensor> -> 2dTensor
        if type(unk.sort.args[0]) == PPListSort:
            in_is_list_of_2d_tensors = type(
                unk.sort.args[0].param_sort) == PPTensorSort and len(
                    unk.sort.args[0].param_sort.shape) == 2
            out_is_2d_tensor = type(
                unk.sort.rtpe) == PPTensorSort and unk.sort.rtpe.shape.__len__(
                ) == 2

            if in_is_list_of_2d_tensors and out_is_2d_tensor:
                continue
            else:
                return False, 6

        # If the input to the NN is an image:
        cnn_feature_dim = 64
        input_is_image = type(
            fn_input_sort) == PPTensorSort and fn_input_sort.shape.__len__(
            ) == 4
        if input_is_image:
            # if the input is of size [batch_size, _, 28, 28], the output must be of size [batch_size, 32, 4, 4]
            cond0a1 = fn_input_sort.shape[
                2].value == 28 and fn_input_sort.shape[3].value == 28
            cond0a2 = type(fn_output_sort) == PPTensorSort and fn_output_sort.shape.__len__() == 4 and \
                      fn_output_sort.shape[1].value == cnn_feature_dim \
                      and fn_output_sort.shape[2].value == 4 and fn_output_sort.shape[3].value == 4
            # if the input is of size [batch_size, 32, 4, 4], the output must be two dimensional
            cond0b1 = fn_input_sort.shape[1].value == cnn_feature_dim \
                      and fn_input_sort.shape[2].value == 4 and fn_input_sort.shape[3].value == 4
            cond0b2 = type(
                fn_output_sort
            ) == PPTensorSort and fn_output_sort.shape.__len__() == 2

            if not ((cond0a1 and cond0a2) or (cond0b1 and cond0b2)):
                return False, 50

            if cond0b1 and cond0b2:
                number_of_mlp_nns += 1
            continue

        # if the input is a 2d tensor:
        in_is_2d_tensor = type(
            unk.sort.args[0]
        ) == PPTensorSort and unk.sort.args[0].shape.__len__() == 2
        out_is_2d_tensor = type(
            unk.sort.rtpe) == PPTensorSort and unk.sort.rtpe.shape.__len__(
            ) == 2
        if in_is_2d_tensor:
            if out_is_2d_tensor:
                number_of_mlp_nns += 1
            else:
                return False, 51

        return False, 52

    lib_names = get_lib_names(st)
    # don't allow multiple repeats, as we could just keep on stacking these.
    if lib_names.count("repeat") > 1:
        return False, 15

    # lib_names = self.interpreter
    for lib_name in lib_names:
        # TODO: check if the functions is part of graph convolution, but is used outside of a conv_g operator.

        if type(ns.lib.items[lib_name].obj) == NetMLP:
            number_of_mlp_nns += 1

    # don't allow for multiple MLPs, as we can just keep on stacking them
    # (thus going into architecture search, which is out of scope)
    if number_of_mlp_nns > 1:
        return False, 16

    return True, 0