def test_unknown_const_1(): #IGNORE:C01111 msg = '''Test correct treatment of unknown constants.''' py.test.skip(msg) print msg from freeode.optimizer import MakeDataFlowDecorations, DataFlowChecker from freeode.interpreter import (Interpreter, IFloat) from freeode.ast import DotName, NodeAssignment prog_text = \ ''' data c1: Float const class A: data a, b: Float data c2: Float const func dynamic(this): a = c1 b = c2 compile A ''' #interpret the program intp = Interpreter() intp.interpret_module_string(prog_text, None, 'test') #the module #mod = intp.modules['test'] #print mod #get the flattened version of the A class sim = intp.get_compiled_objects()[0] #print sim #get attributes a = sim.get_attribute(DotName('a')) b = sim.get_attribute(DotName('b')) # c = sim.get_attribute(DotName('c1')) # c = sim.get_attribute(DotName('c2')) #get generated main function dyn = sim.get_attribute(DotName('dynamic')) hexid = lambda x: hex(id(x)) print 'a:', hexid(a), ' b:', hexid(b)#, ' c2:', hexid(c) #create the input and output decorations on each statement of the #function dd = MakeDataFlowDecorations() dd.decorate_simulation_object(sim) #check data flow of all functions fc = DataFlowChecker() fc.set_sim_object(sim) assert False, 'This program should raise an exceptions because unknown const attributes were used'
def test_MakeDataFlowDecorations_1(): #IGNORE:C01111 msg = '''Test the creation of data flow annotations.''' #py.test.skip(msg) print msg from freeode.optimizer import MakeDataFlowDecorations from freeode.interpreter import (Interpreter, IFloat) from freeode.ast import DotName, NodeAssignment prog_text = \ ''' class A: data p1,p2: Float param data a,b,c,d: Float func dynamic(this): a = p1 b = a - p2 if a > p1: c = p1 d = p1 else: c = p2 d = p2 compile A ''' #interpret the program intp = Interpreter() intp.interpret_module_string(prog_text, None, 'test') #the module #mod = intp.modules['test'] #print mod #get the flattened version of the A class sim = intp.get_compiled_objects()[0] #print sim #get attributes a = sim.get_attribute(DotName('a')) b = sim.get_attribute(DotName('b')) c = sim.get_attribute(DotName('c')) d = sim.get_attribute(DotName('d')) p1 = sim.get_attribute(DotName('p1')) p2 = sim.get_attribute(DotName('p2')) #get generated main function dyn = sim.get_attribute(DotName('dynamic')) #print object ids in hex (for easier manual testing) hexid = lambda x: hex(id(x)) print 'a:', hexid(a), ' b:', hexid(b), ' c:', hexid(c), ' d:', hexid(d), \ ' p1:', hexid(p1), ' p2:', hexid(p2) #------- the test ------------------- #create the input and output decorations on each statement of the #function dd = MakeDataFlowDecorations() dd.decorate_simulation_object(sim) #dd.decorate_main_function(dyn) #see if the inputs and outputs were detected correctly # a = p1 stmt = dyn.statements[0] assert stmt.inputs == set([p1]) assert stmt.outputs == set([a]) # b = a - p2 stmt = dyn.statements[1] assert stmt.inputs == set([a, p2]) assert stmt.outputs == set([b]) #'if' statement stmt = dyn.statements[2] #look at inputs assert stmt.inputs.issuperset(set([a, p1, p2])) #there is an additional constant IFloat(1) in the condition of the else one_set = stmt.inputs - set([a, p1, p2]) assert len(one_set) == 1 one_obj = one_set.pop() assert one_obj == IFloat(1) #look at outputs assert stmt.outputs == set([c, d]) #the dynamic function assert dyn.inputs == set([p1, p2, one_obj]) assert dyn.outputs == set([a, b, c, d])
def test_VariableUsageChecker_1(): #IGNORE:C01111 msg = '''Test checking of variable usage. Simple program with no errors. Use individual checking functions. These are the rules: Constants (rules enforced in the interpreter): - All constants must be known. - No assignments to constants. Parameters: - All must be assigned in all init**** function. - No assignment to parameters elsewhere. Variables: - All derivatives must be assigned in dynamic function. - No states must be assigned in dynamic function. - All states must be assigned initial values in init*** function. ''' #skip_test(msg) print msg from freeode.optimizer import MakeDataFlowDecorations, VariableUsageChecker from freeode.interpreter import Interpreter from freeode.util import DotName#, aa_make_tree prog_text = \ ''' class A: data p1,p2: Float param data a,b,c: Float func init_1(this, ext1, ext2): ext2 = 1 #not useful but legal for simplicity p1 = ext1 p2 = 1 a = 0 func initialize(this): p1 = 1 p2 = 1 a = 0 print(time) data lo: Float lo = p1 func dynamic(this): $a = p1 b = a - p2 if a > p1: c = p1 else: c = p2 data lo: Float variable lo = p1 func final(this): b = 1 print(a, b, p1) data lo: Float variable lo = p1 compile A ''' #interpret the program intp = Interpreter() intp.interpret_module_string(prog_text, None, 'test') #the module #mod = intp.modules['test'] #print mod #get the flattened version of the A class sim = intp.get_compiled_objects()[0] #print aa_make_tree(sim) #print aa_make_tree(sim.func_locals) #create the input and output decorations on each statement of the #function dd = MakeDataFlowDecorations() dd.decorate_simulation_object(sim) #Find all input and output variables vu = VariableUsageChecker() vu.set_annotated_sim_object(sim) #Check the usage of the variables init_1 = vu.main_funcs[DotName('init_1')] vu.check_initialize_function(init_1) initialize = vu.main_funcs[DotName('initialize')] vu.check_initialize_function(initialize) dynamic = vu.main_funcs[DotName('dynamic')] vu.check_dynamic_function(dynamic) final = vu.main_funcs[DotName('final')] vu.check_final_function(final)
def test_MakeDataFlowDecorations_1(): #IGNORE:C01111 msg = '''Test the creation of data flow annotations.''' #skip_test(msg) print msg from freeode.optimizer import MakeDataFlowDecorations from freeode.interpreter import Interpreter, IFloat #from freeode.ast import NodeAssignment from freeode.util import DotName prog_text = \ ''' class A: data p1,p2: Float param data a,b,c,d: Float #5 func dynamic(this): a = p1 b = a - p2 if a > p1: c = p1 #10 d = p1 else: c = p2 d = p2 print(a) compile A ''' #interpret the program intp = Interpreter() intp.interpret_module_string(prog_text, None, 'test') #the module #mod = intp.modules['test'] #print mod #get the flattened version of the A class sim = intp.get_compiled_objects()[0] #print sim #get attributes a = sim.get_attribute(DotName('a')) b = sim.get_attribute(DotName('b')) c = sim.get_attribute(DotName('c')) d = sim.get_attribute(DotName('d')) p1 = sim.get_attribute(DotName('p1')) p2 = sim.get_attribute(DotName('p2')) #get generated main function dyn = sim.get_attribute(DotName('dynamic')) #print object ids in hex (for easier manual testing) hexid = lambda x: hex(id(x)) print 'a:', hexid(a), ' b:', hexid(b), ' c:', hexid(c), ' d:', hexid(d), \ ' p1:', hexid(p1), ' p2:', hexid(p2) #------- the test ------------------- #create the input and output decorations on each statement of the #function dd = MakeDataFlowDecorations() dd.decorate_simulation_object(sim) #dd.decorate_main_function(dyn) #see if the inputs and outputs were detected correctly # a = p1-------------------------------------- stmt0 = dyn.statements[0] assert stmt0.inputs == set([p1]) assert stmt0.outputs == set([a]) # b = a - p2 -------------------------------- stmt1 = dyn.statements[1] assert stmt1.inputs == set([a, p2]) assert stmt1.outputs == set([b]) #'if' statement ------------------------------ stmt2 = dyn.statements[2] #look at inputs assert stmt2.inputs.issuperset(set([a, p1, p2])) #there is an additional constant IFloat(1) in the condition of the else one_set = stmt2.inputs - set([a, p1, p2]) assert len(one_set) == 1 one_obj = one_set.pop() assert one_obj == IFloat(1) #look at outputs assert stmt2.outputs == set([c, d]) #print(a) ------------------------------------- stmt3 = dyn.statements[3] assert stmt3.inputs == set([a]) assert stmt3.outputs == set() #the dynamic function as a whole -------------- assert dyn.inputs == set([p1, p2, one_obj]) assert dyn.outputs == set([a, b, c, d]) #The input_locs, output_locs mappings for creating error messages #Parameter p1 assert p1 not in dyn.output_locs #p1 is written nowhere p1_in_locs = dyn.input_locs[p1] assert len(p1_in_locs) == 4 #p1 read in 4 places assert p1_in_locs[0].line_no() == stmt0.loc.line_no() #read in statement 0 assert p1_in_locs[1].line_no() == stmt2.loc.line_no() #read in 'if' statement # + read in two lines in body of 'if' statement # for loc in p1_in_locs: # print loc #Variable a a_out_loc = dyn.output_locs[a] assert len(a_out_loc) == 1 #a written in 1 place assert a_out_loc[0].line_no() == stmt0.loc.line_no() #written in statement 0 a_in_loc = dyn.input_locs[a] assert len(a_in_loc) == 3 #a read in 3 places assert a_in_loc[0].line_no() == stmt1.loc.line_no() assert a_in_loc[1].line_no() == stmt2.loc.line_no() assert a_in_loc[2].line_no() == stmt3.loc.line_no()
def test_VariableUsageChecker_1(): #IGNORE:C01111 msg = '''Test checking of variable usage. Provoke all errors at least once.''' #skip_test(msg) print msg from freeode.optimizer import MakeDataFlowDecorations, VariableUsageChecker from freeode.interpreter import Interpreter from freeode.util import DotName, UserException#, aa_make_tree prog_text = \ ''' class A: data p1,p2: Float param data a,b,c: Float #illegal read of parameter p1 func init_1(this): p2 = p1 a = 0 #illegal write to derivative $a func init_2(this): $a = 1 p1 = 1 p2 = 1 a = 0 #Missing assignment to parameter p1 func init_3(this): p2 = 1 a = 0 #illegal write to state variable a func dynamic(this): a = 2 $a = p1 b = a - p2 c = p1 #illegal write to state variable a func final(this): a = 2 b = 1 print(a, b, p1) compile A ''' #interpret the program intp = Interpreter() intp.interpret_module_string(prog_text, None, 'test') #the module #mod = intp.modules['test'] #print mod #get the flattened version of the A class sim = intp.get_compiled_objects()[0] #aa_make_tree(sim) #create the input and output decorations on each statement of the #function dd = MakeDataFlowDecorations() dd.decorate_simulation_object(sim) #Find all input and output variables vu = VariableUsageChecker() vu.set_annotated_sim_object(sim) #illegal read of parameter p1 initialize = vu.main_funcs[DotName('init_1')] #vu.check_initialize_function(initialize) assert_raises(UserException, 4500100, vu.check_initialize_function, initialize) #illegal write to derivative $a initialize = vu.main_funcs[DotName('init_2')] #vu.check_initialize_function(initialize) assert_raises(UserException, 4500200, vu.check_initialize_function, initialize) #Missing assignment to parameter p1 initialize = vu.main_funcs[DotName('init_3')] #vu.check_initialize_function(initialize) assert_raises(UserException, 4500300, vu.check_initialize_function, initialize) #illegal write to state variable a dynamic = vu.main_funcs[DotName('dynamic')] #vu.check_dynamic_function(dynamic) assert_raises(UserException, 4500200, vu.check_dynamic_function, dynamic) #illegal write to state variable a final = vu.main_funcs[DotName('final')] #vu.check_final_function(final) assert_raises(UserException, 4500200, vu.check_final_function, final)