Example #1
0
def test_routinesymbol_init():
    '''Test that a RoutineSymbol instance can be created.'''

    assert isinstance(RoutineSymbol('jo'), RoutineSymbol)
    assert isinstance(
        RoutineSymbol('ellie', visibility=Symbol.Visibility.PRIVATE),
        RoutineSymbol)
    assert isinstance(
        RoutineSymbol('isaac', interface=UnresolvedInterface()),
        RoutineSymbol)
Example #2
0
def test_call_error2():
    '''Test that the appropriate exception is raised if the arguments
    argument to the create method is not a list'''
    routine = RoutineSymbol("isaac")
    with pytest.raises(GenerationError) as info:
        _ = Call.create(routine, None)
    assert ("Call create arguments argument should be a list but found "
            "'NoneType'." in str(info.value))
Example #3
0
def test_lfricalgorithminvokecall_create_nodescription():
    '''Check that the LFRicAlgorithmInvokeCall create method sets
    description to None if it is not provided.

    '''
    routine = RoutineSymbol("hello")
    call = LFRicAlgorithmInvokeCall.create(routine, [], 0)
    assert call._description is None
Example #4
0
def test_routinesymbol_init_error():
    '''Test that the RoutineSymbol raises an error (via the Symbol parent
    class) if there is an invalid argument.

    '''
    with pytest.raises(TypeError) as error:
        _ = RoutineSymbol(None)
    assert ("RoutineSymbol 'name' attribute should be of type 'str' but "
            "'NoneType' found." in str(error.value))
Example #5
0
def test_lfricalgorithminvokecall_node_str():
    '''Check that the LFRicAlgorithmInvokeCall node_str  method creates the
    expected object.

    '''
    routine = RoutineSymbol("hello")
    call = LFRicAlgorithmInvokeCall.create(
        routine, [], 0, description="describing an invoke")
    assert ("LFRicAlgorithmInvokeCall[description=\"describing an invoke\"]"
            in call.node_str(colour=False))
Example #6
0
def test_algorithminvokecall():
    '''Check that an instance of AlgorithmInvokeCall can be
    created.

    '''
    routine = RoutineSymbol("hello")
    call = AlgorithmInvokeCall(routine, 2)
    assert call._text_name == "AlgorithmInvokeCall"
    assert call._colour == "green"
    assert call.psylayer_routine_symbol is None
    assert call._index == 2
Example #7
0
def test_invoke_error():
    '''Test that the expected exception is raised in the validate method
    when the supplied node is a call but its name is not the expected
    'invoke' name.

    '''
    invoke_trans = InvokeCallTrans()
    with pytest.raises(TransformationError) as info:
        invoke_trans.validate(Call(RoutineSymbol("hello")))
    assert ("Error in InvokeCallTrans transformation. The supplied call "
            "argument should be a `Call` node with name 'invoke' but "
            "found 'hello'." in str(info.value))
Example #8
0
def test_lfricalgorithminvokecall_options():
    '''Check that an instance of LFRicAlgorithmInvokeCall can be created
    with optional arguments and that these optional arguments are
    stored as expected.

    '''
    node = Node()
    routine = RoutineSymbol("hello")
    call = LFRicAlgorithmInvokeCall(
        routine, 0, description="describing an invoke", parent=node)
    assert call._description == "describing an invoke"
    assert call.parent is node
Example #9
0
def test_call_error3():
    '''Test that the appropriate exception is raised if one or more of the
    arguments argument list entries to the create method is not a
    DataNode.

    '''
    routine = RoutineSymbol("roo")
    with pytest.raises(GenerationError) as info:
        _ = Call.create(routine,
                        [Reference(DataSymbol("arg1", INTEGER_TYPE)), None])
    assert ("Item 'NoneType' can't be child 1 of 'Call'. The valid format "
            "is: '[DataNode]*'." in str(info.value))
Example #10
0
def test_lfricalgorithminvokecall():
    '''Check that an instance of LFRicAlgorithmInvokeCall can be
    created.

    '''
    routine = RoutineSymbol("hello")
    index = 2
    call = LFRicAlgorithmInvokeCall(routine, index)
    assert call._description is None
    assert call.parent is None
    assert call.routine is routine
    assert call._index == index
    assert call._text_name == "LFRicAlgorithmInvokeCall"
Example #11
0
    def name(self, new_name):
        '''
        Sets a new name for the Routine.

        :param str new_name: new name for the Routine.

        :raises TypeError: if new_name is not a string.

        '''
        if not isinstance(new_name, six.string_types):
            raise TypeError("Routine name must be a str but got "
                            "'{0}'".format(type(new_name).__name__))
        if not self._name:
            self._name = new_name
            self.symbol_table.add(RoutineSymbol(new_name),
                                  tag='own_routine_symbol')
        elif self._name != new_name:
            old_symbol = self.symbol_table.lookup(self._name)
            self.symbol_table.remove(old_symbol)
            self._name = new_name
            self.symbol_table.add(RoutineSymbol(new_name),
                                  tag='own_routine_symbol')
Example #12
0
def test_aic_validate_child():
    '''Check that the _validate_child method behaves as expected.'''

    kernel_functor = KernelFunctor(DataTypeSymbol("dummy", REAL_TYPE))
    assert AlgorithmInvokeCall._validate_child(0, kernel_functor)
    assert not AlgorithmInvokeCall._validate_child(0, "Invalid")

    routine = RoutineSymbol("hello")
    call = AlgorithmInvokeCall(routine, 0)
    with pytest.raises(GenerationError) as info:
        call.children = ["invalid"]
    assert ("Item 'str' can't be child 0 of 'AlgorithmInvokeCall'. The valid "
            "format is: '[KernelFunctor]*'." in str(info.value))
    call.children = [kernel_functor]
Example #13
0
def test_call_create():
    '''Test that the create method creates a valid call with arguments'''

    routine = RoutineSymbol("ellie")
    array_type = ArrayType(INTEGER_TYPE, shape=[10, 20])
    arguments = [
        Reference(DataSymbol("arg1", INTEGER_TYPE)),
        Array(DataSymbol("arg2", array_type))
    ]
    call = Call.create(routine, arguments)
    assert call.routine is routine
    for idx, child, in enumerate(call.children):
        assert child is arguments[idx]
        assert child.parent is call
Example #14
0
def test_lfricalgorithminvokecall_create(cls):
    '''Check that the LFRicAlgorithmInvokeCall create method creates the
    expected object.

    '''
    routine = RoutineSymbol("hello")
    klc = LFRicKernelFunctor.create(DataTypeSymbol("arg", StructureType()), [])
    call = cls.create(routine, [klc], 0, description="describing an invoke")
    assert call._description == "describing an invoke"
    assert call.routine is routine
    # pylint: disable=unidiomatic-typecheck
    assert type(call) is cls
    assert len(call.children) == 1
    assert call.children[0] == klc
Example #15
0
def test_aic_defroutinerootname():
    '''Check that the _def_routine_root_name() internal method behaves as
    expected.

    '''
    symbol_name = "dummy"
    kernel_functor = KernelFunctor(DataTypeSymbol(symbol_name, REAL_TYPE))
    routine = RoutineSymbol("hello")
    index = 3
    call = AlgorithmInvokeCall(routine, index)
    call.children = [kernel_functor]
    assert call._def_routine_root_name() == "invoke_{0}_{1}".format(
        index, symbol_name)
    call.children.append(kernel_functor.copy())
    assert call._def_routine_root_name() == "invoke_{0}".format(index)
Example #16
0
def test_algorithminvokecall_error():
    '''Check that AlgorithmInvokeCall raises the expected exceptions if
    the invoke argument has an invalid value.

    '''
    routine = RoutineSymbol("hello")
    with pytest.raises(TypeError) as info:
        AlgorithmInvokeCall(routine, "error")
    assert ("AlgorithmInvokeCall index argument should be an int but found "
            "'str'." in str(info.value))

    with pytest.raises(ValueError) as info:
        AlgorithmInvokeCall(routine, -1)
    assert ("AlgorithmInvokeCall index argument should be a non-negative "
            "integer but found -1." in str(info.value))
Example #17
0
def test_aic_create():
    '''Check that the create method behaves as expected.'''

    kernel_functor = KernelFunctor(DataTypeSymbol("dummy", REAL_TYPE))
    routine = RoutineSymbol("hello")
    index = 10
    aic = AlgorithmInvokeCall.create(routine, [kernel_functor], index)
    assert isinstance(aic, AlgorithmInvokeCall)
    assert len(aic.children) == 1
    assert aic.children[0] is kernel_functor
    assert aic._routine is routine
    assert aic._index == index

    with pytest.raises(GenerationError) as info:
        AlgorithmInvokeCall.create(routine, kernel_functor, index)
    assert ("AlgorithmInvokeCall create arguments argument should be a list "
            "but found 'KernelFunctor'." in str(info.value))
Example #18
0
def test_name_clash_derived_type_def(f2008_parser):
    ''' Check that the frontend raises an error if it encounters a definition
    of a derived type with a name that clashes with another symbol. '''
    fake_parent = KernelSchedule("dummy_schedule")
    symtab = fake_parent.symbol_table
    # Add a RoutineSymbol to the symbol table that will clash with the name
    # of the derived type.
    symtab.add(RoutineSymbol("my_type"))
    # Add a DataTypeSymbol to the symbol table. Make it appear that we've
    # already seen a definition of this symbol by making it of
    # UnknownFortranType.
    symtab.new_symbol("my_type2",
                      symbol_type=DataTypeSymbol,
                      datatype=UnknownFortranType("huh"))
    processor = Fparser2Reader()
    fparser2spec = f2008_parser(
        FortranStringReader("subroutine my_sub()\n"
                            "  type :: my_type\n"
                            "    integer :: flag\n"
                            "  end type my_type\n"
                            "end subroutine my_sub\n"))
    # This should raise an error because the Container symbol table will
    # already contain a RoutineSymbol named 'my_type'
    with pytest.raises(SymbolError) as err:
        processor.process_declarations(fake_parent, fparser2spec.content, [])
    assert ("Error processing definition of derived type 'my_type'. The "
            "symbol table already contains an entry with this name but it is a"
            " 'RoutineSymbol' when it should be a 'DataTypeSymbol' (for the "
            "derived-type definition 'TYPE :: my_type\n  INTEGER :: flag\n"
            "END TYPE my_type')" in str(err.value))
    # Repeat but with a derived-type name that will clash with our existing
    # DataTypeSymbol
    fparser2spec = f2008_parser(
        FortranStringReader("subroutine my_sub2()\n"
                            "  type :: my_type2\n"
                            "    integer :: flag\n"
                            "  end type my_type2\n"
                            "end subroutine my_sub2\n"))
    with pytest.raises(SymbolError) as err:
        processor.process_declarations(fake_parent, fparser2spec.content, [])
    assert ("Error processing definition of derived type 'my_type2'. The "
            "symbol table already contains a DataTypeSymbol with this name but"
            " it is of type 'UnknownFortranType' when it should be of "
            "'DeferredType'" in str(err.value))
Example #19
0
def test_call_init():
    '''Test that a Call can be created as expected. Also test the routine
    property.

    '''
    # routine argument
    routine = RoutineSymbol("jo")
    call = Call(routine)
    assert call._routine is routine
    assert call.routine is call._routine
    assert call.parent is None
    assert call.children == []

    # optional parent argument
    parent = Schedule()
    call = Call(routine, parent=parent)
    assert call.routine is routine
    assert call.parent is parent
    assert call.children == []
Example #20
0
    def _parse_args(code_block, fp2_node):
        '''Return the arguments from a Structure Constructor stored as a
        CodeBlock containing an fparser2 ast.

        :param code_block: the CodeBlock containing a StructureConstructor.
        :type code_block: :py:class:`psyclone.psyir.nodes.CodeBlock`
        :param fp2_node: the fparser2 Structure Constructor node.
        :type fp2_node: \
            :py:class:`fparser.two.Fortran2003.Structure_Constructor`

        :returns: a list of PSyIR nodes containing the \
            StructureConstructor arguments.
        :rtype: list of :py:class:`psyclone.psyir.nodes.Node`

        '''
        dummy_call = Call(RoutineSymbol("dummy"), parent=code_block.parent)
        fparser2 = Fparser2Reader()
        for arg in fp2_node.children[1].children:
            fparser2.process_nodes(dummy_call, [arg])
        return dummy_call.pop_all_children()
Example #21
0
def test_name_clash_derived_type(f2008_parser, type_name):
    ''' Check that the frontend raises an error if it encounters a reference
    to a derived type that clashes with another symbol. '''
    fake_parent = KernelSchedule("dummy_schedule")
    symtab = fake_parent.symbol_table
    # Add a RoutineSymbol to the symbol table that clashes with the name
    # of the derived type.
    symtab.add(RoutineSymbol("my_type"))
    processor = Fparser2Reader()
    reader = FortranStringReader("subroutine my_sub()\n"
                                 "  type({0}) :: some_var\n"
                                 "end subroutine my_sub\n".format(type_name))
    fparser2spec = f2008_parser(reader)
    # This should raise an error because the Container symbol table should
    # already contain a RoutineSymbol named 'my_type'
    with pytest.raises(SymbolError) as err:
        processor.process_declarations(fake_parent, fparser2spec.content, [])
    assert ("Search for a DataTypeSymbol named '{0}' (required by "
            "specification 'TYPE({0})') found a 'RoutineSymbol' instead".
            format(type_name) in str(err.value))
Example #22
0
    def create_psylayer_symbols(self):
        '''If the PSy-layer routine and container symbols have not been
        created, then create them. The names are based on the position
        of this node (compared to other nodes of the same type) in the
        PSyIR tree.

        '''
        if self.psylayer_routine_symbol:
            # The language-level symbols have already been created
            return

        routine_root_name = self._def_routine_root_name()

        symbol_table = self.scope.symbol_table
        routine_name = symbol_table.next_available_name(
            root_name=routine_root_name)

        container_root_name = "{0}_mod".format(routine_name)
        container_name = symbol_table.next_available_name(
            root_name=container_root_name)

        interface = GlobalInterface(ContainerSymbol(container_name))
        self.psylayer_routine_symbol = RoutineSymbol(routine_name,
                                                     interface=interface)
Example #23
0
def test_call_str():
    ''' Test that the str method behaves as expected '''
    routine = RoutineSymbol("roo")
    call = Call(routine)
    assert str(call) == "Call[name='roo']"
Example #24
0
def test_call_node_str():
    ''' Test that the node_str method behaves as expected '''
    routine = RoutineSymbol("isaac")
    call = Call(routine)
    colouredtext = colored("Call", SCHEDULE_COLOUR_MAP["Call"])
    assert call.node_str() == colouredtext + "[name='isaac']"
Example #25
0
ARG1 = DataSymbol(TMP_NAME1,
                  REAL_TYPE,
                  interface=ArgumentInterface(
                      ArgumentInterface.Access.READWRITE))
SYMBOL_TABLE.add(ARG1)
TMP_NAME2 = SYMBOL_TABLE.new_symbol_name()
TMP_SYMBOL = DataSymbol(TMP_NAME2, REAL_DOUBLE_TYPE)
SYMBOL_TABLE.add(TMP_SYMBOL)
INDEX_NAME = SYMBOL_TABLE.new_symbol_name(root_name="i")
INDEX_SYMBOL = DataSymbol(INDEX_NAME, INTEGER4_TYPE)
SYMBOL_TABLE.add(INDEX_SYMBOL)
SYMBOL_TABLE.specify_argument_list([ARG1])
REAL_KIND_NAME = SYMBOL_TABLE.new_symbol_name(root_name="RKIND")
REAL_KIND = DataSymbol(REAL_KIND_NAME, INTEGER_TYPE, constant_value=8)
SYMBOL_TABLE.add(REAL_KIND)
ROUTINE_SYMBOL = RoutineSymbol("my_sub")

# Array using precision defined by another symbol
ARRAY_NAME = SYMBOL_TABLE.new_symbol_name(root_name="a")
SCALAR_TYPE = ScalarType(ScalarType.Intrinsic.REAL, REAL_KIND)
ARRAY = DataSymbol(ARRAY_NAME, ArrayType(SCALAR_TYPE, [10]))
SYMBOL_TABLE.add(ARRAY)

# Nodes which do not have Nodes as children and (some) predefined
# scalar datatypes
ZERO = Literal("0.0", REAL_TYPE)
ONE = Literal("1.0", REAL4_TYPE)
TWO = Literal("2.0", SCALAR_TYPE)
INT_ZERO = Literal("0", INTEGER_SINGLE_TYPE)
INT_ONE = Literal("1", INTEGER8_TYPE)
TMP1 = Reference(ARG1)
Example #26
0
def test_routinesymbol_str():
    '''Test that the __str__ method in routinesymbol behaves as expected.'''
    routine_symbol = RoutineSymbol("roo")
    assert routine_symbol.__str__() == "roo : RoutineSymbol"
Example #27
0
    "diff_basis_w3",
    [3, Reference(NDF_W3),
     Reference(NQP_XY),
     Reference(NQP_Z)],
    "w3",
    interface=READ_ARG)
for symbol in [NQP_XY, NQP_Z, WEIGHTS_XY, WEIGHTS_Z, BASIS_W3, DIFF_BASIS_W3]:
    SYMBOL_TABLE.add(symbol)

SYMBOL_TABLE.specify_argument_list([
    NDF_W3, UNDF_W3, NCELL_3D, FIELD2, OPERATOR, NQP_XY, NQP_Z, WEIGHTS_XY,
    WEIGHTS_Z, BASIS_W3, DIFF_BASIS_W3
])

# Routine symbol
ROUTINE_SYMBOL = RoutineSymbol("my_sub")

# Call
CALL = Call.create(ROUTINE_SYMBOL,
                   [Reference(FIELD1),
                    Reference(FIELD2),
                    Reference(OPERATOR)])

# KernelSchedule
KERNEL_SCHEDULE = KernelSchedule.create("work", SYMBOL_TABLE, [CALL])

# Container
CONTAINER_SYMBOL_TABLE = SymbolTable()
CONTAINER = Container.create("CONTAINER", CONTAINER_SYMBOL_TABLE,
                             [KERNEL_SCHEDULE])
Example #28
0
def create_psyir_tree():
    ''' Create an example PSyIR Tree.

    :returns: an example PSyIR tree.
    :rtype: :py:class:`psyclone.psyir.nodes.Container`

    '''
    # Symbol table, symbols and scalar datatypes
    symbol_table = SymbolTable()
    arg1 = symbol_table.new_symbol(symbol_type=DataSymbol,
                                   datatype=REAL_TYPE,
                                   interface=ArgumentInterface(
                                       ArgumentInterface.Access.READWRITE))
    symbol_table.specify_argument_list([arg1])
    tmp_symbol = symbol_table.new_symbol(symbol_type=DataSymbol,
                                         datatype=REAL_DOUBLE_TYPE)
    index_symbol = symbol_table.new_symbol(root_name="i",
                                           symbol_type=DataSymbol,
                                           datatype=INTEGER4_TYPE)
    real_kind = symbol_table.new_symbol(root_name="RKIND",
                                        symbol_type=DataSymbol,
                                        datatype=INTEGER_TYPE,
                                        constant_value=8)
    routine_symbol = RoutineSymbol("my_sub")

    # Array using precision defined by another symbol
    scalar_type = ScalarType(ScalarType.Intrinsic.REAL, real_kind)
    array = symbol_table.new_symbol(root_name="a",
                                    symbol_type=DataSymbol,
                                    datatype=ArrayType(scalar_type, [10]))

    # Make generators for nodes which do not have other Nodes as children,
    # with some predefined scalar datatypes
    def zero():
        return Literal("0.0", REAL_TYPE)

    def one():
        return Literal("1.0", REAL4_TYPE)

    def two():
        return Literal("2.0", scalar_type)

    def int_zero():
        return Literal("0", INTEGER_SINGLE_TYPE)

    def int_one():
        return Literal("1", INTEGER8_TYPE)

    def tmp1():
        return Reference(arg1)

    def tmp2():
        return Reference(tmp_symbol)

    # Unary Operation
    oper = UnaryOperation.Operator.SIN
    unaryoperation = UnaryOperation.create(oper, tmp2())

    # Binary Operation
    oper = BinaryOperation.Operator.ADD
    binaryoperation = BinaryOperation.create(oper, one(), unaryoperation)

    # Nary Operation
    oper = NaryOperation.Operator.MAX
    naryoperation = NaryOperation.create(oper, [tmp1(), tmp2(), one()])

    # Array reference using a range
    lbound = BinaryOperation.create(BinaryOperation.Operator.LBOUND,
                                    Reference(array), int_one())
    ubound = BinaryOperation.create(BinaryOperation.Operator.UBOUND,
                                    Reference(array), int_one())
    my_range = Range.create(lbound, ubound)
    tmparray = ArrayReference.create(array, [my_range])

    # Assignments
    assign1 = Assignment.create(tmp1(), zero())
    assign2 = Assignment.create(tmp2(), zero())
    assign3 = Assignment.create(tmp2(), binaryoperation)
    assign4 = Assignment.create(tmp1(), tmp2())
    assign5 = Assignment.create(tmp1(), naryoperation)
    assign6 = Assignment.create(tmparray, two())

    # Call
    call = Call.create(routine_symbol, [tmp1(), binaryoperation.copy()])

    # If statement
    if_condition = BinaryOperation.create(BinaryOperation.Operator.GT, tmp1(),
                                          zero())
    ifblock = IfBlock.create(if_condition, [assign3, assign4])

    # Loop
    loop = Loop.create(index_symbol, int_zero(), int_one(), int_one(),
                       [ifblock])

    # KernelSchedule
    kernel_schedule = KernelSchedule.create(
        "work", symbol_table, [assign1, call, assign2, loop, assign5, assign6])

    # Container
    container_symbol_table = SymbolTable()
    container = Container.create("CONTAINER", container_symbol_table,
                                 [kernel_schedule])

    # Import data from another container
    external_container = ContainerSymbol("some_mod")
    container_symbol_table.add(external_container)
    external_var = DataSymbol("some_var",
                              INTEGER_TYPE,
                              interface=GlobalInterface(external_container))
    container_symbol_table.add(external_var)
    routine_symbol.interface = GlobalInterface(external_container)
    container_symbol_table.add(routine_symbol)
    return container
Example #29
0
def create_psyir_tree():
    ''' Create an example PSyIR Tree.

    :returns: an example PSyIR tree.
    :rtype: :py:class:`psyclone.psyir.nodes.Container`

    '''
    # Symbol table, symbols and scalar datatypes
    symbol_table = SymbolTable()
    arg1 = symbol_table.new_symbol(symbol_type=DataSymbol,
                                   datatype=REAL_TYPE,
                                   interface=ArgumentInterface(
                                       ArgumentInterface.Access.READWRITE))
    symbol_table.specify_argument_list([arg1])
    tmp_symbol = symbol_table.new_symbol(symbol_type=DataSymbol,
                                         datatype=REAL_DOUBLE_TYPE)
    index_symbol = symbol_table.new_symbol(root_name="i",
                                           symbol_type=DataSymbol,
                                           datatype=INTEGER4_TYPE)
    real_kind = symbol_table.new_symbol(root_name="RKIND",
                                        symbol_type=DataSymbol,
                                        datatype=INTEGER_TYPE,
                                        constant_value=8)
    routine_symbol = RoutineSymbol("my_sub")

    # Array using precision defined by another symbol
    scalar_type = ScalarType(ScalarType.Intrinsic.REAL, real_kind)
    array = symbol_table.new_symbol(root_name="a",
                                    symbol_type=DataSymbol,
                                    datatype=ArrayType(scalar_type, [10]))

    # Nodes which do not have Nodes as children and (some) predefined
    # scalar datatypes
    # TODO: Issue #1136 looks at how to avoid all of the _x versions
    zero_1 = Literal("0.0", REAL_TYPE)
    zero_2 = Literal("0.0", REAL_TYPE)
    zero_3 = Literal("0.0", REAL_TYPE)
    one_1 = Literal("1.0", REAL4_TYPE)
    one_2 = Literal("1.0", REAL4_TYPE)
    one_3 = Literal("1.0", REAL4_TYPE)
    two = Literal("2.0", scalar_type)
    int_zero = Literal("0", INTEGER_SINGLE_TYPE)
    int_one_1 = Literal("1", INTEGER8_TYPE)
    int_one_2 = Literal("1", INTEGER8_TYPE)
    int_one_3 = Literal("1", INTEGER8_TYPE)
    int_one_4 = Literal("1", INTEGER8_TYPE)
    tmp1_1 = Reference(arg1)
    tmp1_2 = Reference(arg1)
    tmp1_3 = Reference(arg1)
    tmp1_4 = Reference(arg1)
    tmp1_5 = Reference(arg1)
    tmp1_6 = Reference(arg1)
    tmp2_1 = Reference(tmp_symbol)
    tmp2_2 = Reference(tmp_symbol)
    tmp2_3 = Reference(tmp_symbol)
    tmp2_4 = Reference(tmp_symbol)
    tmp2_5 = Reference(tmp_symbol)
    tmp2_6 = Reference(tmp_symbol)

    # Unary Operation
    oper = UnaryOperation.Operator.SIN
    unaryoperation_1 = UnaryOperation.create(oper, tmp2_1)
    unaryoperation_2 = UnaryOperation.create(oper, tmp2_2)

    # Binary Operation
    oper = BinaryOperation.Operator.ADD
    binaryoperation_1 = BinaryOperation.create(oper, one_1, unaryoperation_1)
    binaryoperation_2 = BinaryOperation.create(oper, one_2, unaryoperation_2)

    # Nary Operation
    oper = NaryOperation.Operator.MAX
    naryoperation = NaryOperation.create(oper, [tmp1_1, tmp2_3, one_3])

    # Array reference using a range
    lbound = BinaryOperation.create(BinaryOperation.Operator.LBOUND,
                                    Reference(array), int_one_1)
    ubound = BinaryOperation.create(BinaryOperation.Operator.UBOUND,
                                    Reference(array), int_one_2)
    my_range = Range.create(lbound, ubound)
    tmparray = ArrayReference.create(array, [my_range])

    # Assignments
    assign1 = Assignment.create(tmp1_2, zero_1)
    assign2 = Assignment.create(tmp2_4, zero_2)
    assign3 = Assignment.create(tmp2_5, binaryoperation_1)
    assign4 = Assignment.create(tmp1_3, tmp2_6)
    assign5 = Assignment.create(tmp1_4, naryoperation)
    assign6 = Assignment.create(tmparray, two)

    # Call
    call = Call.create(routine_symbol, [tmp1_5, binaryoperation_2])

    # If statement
    if_condition = BinaryOperation.create(BinaryOperation.Operator.GT, tmp1_6,
                                          zero_3)
    ifblock = IfBlock.create(if_condition, [assign3, assign4])

    # Loop
    loop = Loop.create(index_symbol, int_zero, int_one_3, int_one_4, [ifblock])

    # KernelSchedule
    kernel_schedule = KernelSchedule.create(
        "work", symbol_table, [assign1, call, assign2, loop, assign5, assign6])

    # Container
    container_symbol_table = SymbolTable()
    container = Container.create("CONTAINER", container_symbol_table,
                                 [kernel_schedule])

    # Import data from another container
    external_container = ContainerSymbol("some_mod")
    container_symbol_table.add(external_container)
    external_var = DataSymbol("some_var",
                              INTEGER_TYPE,
                              interface=GlobalInterface(external_container))
    container_symbol_table.add(external_var)
    routine_symbol.interface = GlobalInterface(external_container)
    container_symbol_table.add(routine_symbol)
    return container