Rapsodia (generator)
 All Classes Namespaces Files Functions Variables Pages
genOpAddSub.py
Go to the documentation of this file.
1 ##########################################################
2 # This file is part of Rapsodia released under the LGPL. #
3 # The full COPYRIGHT notice can be found in the top #
4 # level directory of the Rapsodia distribution #
5 ##########################################################
6 import Common.names as names
7 import Common.parameters as parameters
8 import Common.util as util
9 def genAddSub(sourceList,helper):
10  # the generic bits for additions
11  sourceList.append(generateAddSubBody(helper,True,True,'add'))
12  # the generic bits for active/passive additions
13  sourceList.append(generateAddSubBody(helper,True,False,'add'))
14  # the generic bits for passive/active additions
15  sourceList.append(generateAddSubBody(helper,False,True,'add'))
16  # the add intrinsic
17  sourceList.append(helper.generateBinaryIntrinsic('add','+',{},[],False,False,False,'merge'))
18  # the generic bits for subtractions
19  sourceList.append(generateAddSubBody(helper,True,True,'sub'))
20  # the generic bits for active/passive subtractions
21  sourceList.append(generateAddSubBody(helper,True,False,'sub'))
22  # the generic bits for passive/active subtractions
23  sourceList.append(generateAddSubBody(helper,False,True,'sub'))
24  # the sub intrinsic
25  sourceList.append(helper.generateBinaryIntrinsic('sub','-',{},[],False,False,False,'merge'))
26 
27 
28 import Common.ast as ast
29 import Common.slice as slice
30 
31 def generateAddSubBody(helper,leftActive,rightActive,name):
32  sourceName=names.Fixed.pN+name
33  if leftActive :
34  sourceName+='A'
35  else :
36  sourceName+='P'
37  if rightActive :
38  sourceName+='A'
39  else :
40  sourceName+='P'
41  aSource = ast.SimpleSource(sourceName, helper.p.iE)
42  aLHS=util.vOf('r')
43  if leftActive :
44  leftOperand=util.vOf('a')
45  else :
46  leftOperand=ast.Variable('a')
47  if rightActive :
48  rightOperand=util.vOf('b')
49  else :
50  rightOperand=ast.Variable('b')
51  if name=='add' :
52  aRHS=ast.Addition(leftOperand,rightOperand)
53  elif name=='sub' :
54  aRHS=ast.Subtraction(leftOperand,rightOperand)
55  else :
56  print >> sys.stderr, 'ERROR: generateAddSubBody: no logic for name '+name
57  sys.exit(2)
58 
59  if not parameters.useQueue:
60  aSource.appendChild(ast.Assignment(aLHS,aRHS))
61 
62  s = slice.Slice(aSource)
63  for direct in range(1, parameters.sliceSize+1):
64  for deg in range(1,parameters.o+1):
65 # aLHS=util.dOf('r',direct,deg)
66  aLHS=util.dOf(util.getVarGlobalName('r'),direct,deg)
67  if leftActive and not(rightActive): # AP
68  aRHS=util.dOf('a',direct,deg)
69  elif not(leftActive) and rightActive: # PA
70  aRHS=util.dOf('b',direct,deg)
71  if name=='sub' :
72  aRHS=ast.UnaryMinus(aRHS)
73  elif leftActive and rightActive: # AA
74  leftOperand=util.dOf('a',direct,deg)
75  rightOperand=util.dOf('b',direct,deg)
76  if name=='add' :
77  aRHS=ast.Addition(leftOperand,rightOperand)
78  else : # names tested above
79  aRHS=ast.Subtraction(leftOperand,rightOperand)
80  else:
81  print >> sys.stderr, 'ERROR: generateAddSubBody: leftActive and rightActive cannot both be false'
82  sys.exit(2)
83  s.appendChild(ast.Assignment(aLHS,aRHS))
84 # s.endSlice()
85  s.endSliceAndSave()
86  return aSource
87 
88 
89 #Reverse_Mode Begin, for the first version, we only implement very basic features. No queue, no slice
90 
91 def genAddSubReverse(sourceList,helper):
92  sourceList.append(helper.generateBinaryIntrinsicReverse('add','+',{},[],False,False,False,'merge',getStatementAA,getStatementAP,getStatementPA))
93  sourceList.append(helper.generateBinaryIntrinsicReverse('sub','-',{},[],False,False,False,'merge',getStatementAA,getStatementAP,getStatementPA))
94 
95 def getStatementAA(helper,aSource,name,kl,kr,resultTypes):
96  leftOperand=util.vOf('a')
97  rightOperand=util.vOf('b')
98  da=ast.Constant('1.0')
99  aLHS=util.vOf('r')
100  if name=='add' :
101  aRHS=ast.Addition(leftOperand,rightOperand)
102  db=ast.Constant('1.0')
103  elif name=='sub' :
104  aRHS=ast.Subtraction(leftOperand,rightOperand)
105  db=ast.Constant('-1.0')
106  else :
107  print >> sys.stderr, 'ERROR: generateAddSubBody: no logic for name '+name
108  sys.exit(2)
109  aSource.appendChild(ast.Assignment(aLHS,aRHS))
110  aSource.appendChild(helper.generatePushBinaryLocal(da,db,kl,kr,resultTypes,'r','a','b'))
111  return aSource
112 
113 def getStatementAP(helper,aSource,name,kl,resultTypes):
114  leftOperand=util.vOf('a')
115  rightOperand=ast.Variable('b')
116  da=ast.Constant('1.0')
117  aLHS=util.vOf('r')
118  if name=='add' :
119  aRHS=ast.Addition(leftOperand,rightOperand)
120  elif name=='sub' :
121  aRHS=ast.Subtraction(leftOperand,rightOperand)
122  else :
123  print >> sys.stderr, 'ERROR: generateAddSubBody: no logic for name '+name
124  sys.exit(2)
125  aSource.appendChild(ast.Assignment(aLHS,aRHS))
126  aSource.appendChild(helper.generatePushUnaryLocal(da,kl,resultTypes,'r','a'))
127  return aSource
128 
129 def getStatementPA(helper,aSource,name,kr,resultTypes):
130  leftOperand=ast.Variable('a')
131  rightOperand=util.vOf('b')
132  aLHS=util.vOf('r')
133  if name=='add' :
134  aRHS=ast.Addition(leftOperand,rightOperand)
135  db=ast.Constant('1.0')
136  elif name=='sub' :
137  aRHS=ast.Subtraction(leftOperand,rightOperand)
138  db=ast.Constant('-1.0')
139  else :
140  print >> sys.stderr, 'ERROR: generateAddSubBody: no logic for name '+name
141  sys.exit(2)
142  aSource.appendChild(ast.Assignment(aLHS,aRHS))
143  aSource.appendChild(helper.generatePushUnaryLocal(db,kr,resultTypes,'r','b'))
144  return aSource
145 
146 
147