Changeset 135
- Timestamp:
- 11/13/07 13:07:01 (10 months ago)
- Files:
-
- trunk/blade/Blade.d (modified) (10 diffs)
- trunk/blade/BladeSimplify.d (modified) (9 diffs)
- trunk/blade/SyntaxTree.d (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/blade/Blade.d
r133 r135 21 21 * - Error messages refer to the line of user code which generated the error. 22 22 * The library never produces a torrent of undecipherable template error messages. 23 * - A 'const folding' (actually vector/scalar folding) step is performed. 23 24 * 24 25 * FUTURE DIRECTIONS (in order of expected implementation): 25 26 * - Dot product (which was present in BLADE 0.2). 26 27 * - The x87 code generation targets early Pentiums, which are now irrelevant. 27 * - A 'const folding' (actually vector/scalar folding) step needs to be performed.28 28 * - Support for strided vectors. 29 29 * - Matrix support. … … 132 132 for (int i=0; i<tree.symbolTable.length;++i) { 133 133 char [] t = tree.symbolTable[i].type; 134 int r = tree.symbolTable[i].rank ;134 int r = tree.symbolTable[i].rank-'0'; 135 135 if (r>1) return VecExpressionType.DExpression; // can only do scalars and vectors right now. 136 136 if (r==0) { … … 173 173 for (int i=0; i<tree.symbolTable.length;++i) { 174 174 char [] t = tree.symbolTable[i].type; 175 if (tree.symbolTable[i].rank== 0) {175 if (tree.symbolTable[i].rank=='0') { 176 176 // Convert scalars into standard form. 177 177 // long, ulong, and real must become real. … … 193 193 result ~="," ~ tree.symbolTable[i].value; 194 194 // for vectors, we only need the pointer, not the length 195 if (tree.symbolTable[i].rank== 1) result ~= ".ptr";195 if (tree.symbolTable[i].rank=='1') result ~= ".ptr"; 196 196 } 197 197 return result~ ");"; … … 207 207 char [] vectortype = SSE2? ",double*" : ",float*"; 208 208 209 result ~= "SSEVECGEN!(" ~ (SSE2?"2":"1") ~ "," ~ wrapInQuotes(revised.expr );209 result ~= "SSEVECGEN!(" ~ (SSE2?"2":"1") ~ "," ~ wrapInQuotes(revised.expression); 210 210 // For SSE2, everything must be implicitly convertible to double. 211 211 char [] vals; 212 for (int i=0; i<revised.mapping.length;++i) { 213 int x = revised.mapping[i]-'A'; 214 char rnk; 215 char [] v; 216 if (x<tree.symbolTable.length) { 217 // it's an original symbol 218 rnk = tree.symbolTable[x].rank; 219 v = tree.symbolTable[x].value; 220 } else { 221 // it's a compound 222 rnk = revised.rank[x-tree.symbolTable.length]; 223 v = "("; 224 foreach(c; revised.compounds[x-tree.symbolTable.length]) { 225 if (c>='A' && c<='Z') v ~= tree.symbolTable[c-'A'].value; 226 else v ~= c; 227 } 228 v ~=")"; 229 } 230 if (rnk=='0') result ~= scalartype; 231 else result ~= vectortype; 232 vals ~= "," ~ v; 233 // for vectors, we only need the pointer, not the length 234 if (rnk=='1') vals ~= ".ptr"; 235 } 236 237 /* 212 238 for (int i=0; i<tree.symbolTable.length;++i) { 213 239 if (revised.used[i]=='-') continue; // ignore unused symbols 214 if (tree.symbolTable[i].rank== 0) result ~= scalartype;240 if (tree.symbolTable[i].rank=='0') result ~= scalartype; 215 241 else result ~= vectortype; 216 242 vals ~= "," ~ tree.symbolTable[i].value; 217 243 // for vectors, we only need the pointer, not the length 218 if (tree.symbolTable[i].rank== 1) vals ~= ".ptr";244 if (tree.symbolTable[i].rank=='1') vals ~= ".ptr"; 219 245 } 220 246 // Now deal with all of the compound expressions 221 247 for (int i=0; i<revised.rank.length;++i) { 222 if (revised.rank[i]== 0) result ~= scalartype;248 if (revised.rank[i]=='0') result ~= scalartype; 223 249 else result ~= vectortype; 224 250 char [] s = ""; … … 227 253 else s ~= c; 228 254 } 229 if (revised.rank[i]== 1) vals ~= ",(" ~ s ~ ").ptr";255 if (revised.rank[i]=='1') vals ~= ",(" ~ s ~ ").ptr"; 230 256 else vals ~= "," ~ s; 231 257 } 258 */ 232 259 result ~= ")("; 233 260 int firstVector = findVectorForLength(tree); … … 247 274 bool known = arrayLengthIsStatic(tree.symbolTable[firstVector].type); 248 275 for (int i=0; i<tree.symbolTable.length;++i) { 249 if (tree.symbolTable[i].rank== 1){276 if (tree.symbolTable[i].rank=='1'){ 250 277 if (firstVector != i) { 251 278 if (known && arrayLengthIsStatic(tree.symbolTable[i].type)) { … … 267 294 char [] result =""; 268 295 for (int i=0; i<tree.symbolTable.length;++i) { 269 if (tree.symbolTable[i].rank== 1){296 if (tree.symbolTable[i].rank=='1'){ 270 297 result ~= "assert( (cast(size_t)(" ~ tree.symbolTable[i].value 271 298 ~ ".ptr)& 0x1F) == 0, `SSE Vector misalignment: " ~ tree.symbolTable[i].value ~ "`);"\n; … … 288 315 int dynamic = 0; // last dynamic vector 289 316 for (int i=0; i<tree.symbolTable.length; ++i) { 290 if (tree.symbolTable[i].rank== 1) {317 if (tree.symbolTable[i].rank=='1') { 291 318 dynamic = i; 292 319 if (arrayLengthIsStatic(tree.symbolTable[i].type)) return i; … … 307 334 result ~= tree.symbolTable[c-'A'].value; 308 335 // If it's a vector, index it 309 if (tree.symbolTable[c-'A'].rank== 1)336 if (tree.symbolTable[c-'A'].rank=='1') 310 337 result ~= "[blade_index]"; 311 338 } else result ~= c; trunk/blade/BladeSimplify.d
r133 r135 2 2 /** 3 3 * Simplify a vector expression. 4 * - Remove all duplicate symbols. 5 * - Use slicing distributive law: A[B..C] for expressions A,B,C 6 * where B and C are both rank 0, and A is rank 1, the slice can 7 * be moved to every vector inside A. 8 * - Convert A[]*B into B*A[] (assumes * is commutative, 4 * Part of BLADE : Basic Linear Algebra D Expressions 5 * 6 * The following transformations are performed: 7 * (A) Remove all duplicate symbols. 8 * (B) Create 'compound' variables, consisting of multiple symbols: 9 * - Combine all scalars into a single scalar. 10 * - Rank reduction: Combine slicing operations into vectors 11 * (C) Arithmetic transformations. 12 * - Use slicing distributive law: Given A[B..C] for expressions A,B,C 13 * where B and C are both rank 0, and A is rank 1 or more, the slice can 14 * be moved to every vector inside A. 15 * - Convert A[]*B into B*A[] (assumes * is commutative, 9 16 * not valid for quaternions). 10 * - Use associativity of *: A*(B*C[]) == (A*B)*C[] 11 * - Use * distributive law over + and -. (Not strictly correct). 12 * Convert -A*B into +(-A)*B whenever possible. 13 * Combine all scalars into a single scalar. 17 * - Use associativity of *: A*(B*C[]) == (A*B)*C[] 18 * - Use * distributive law over + and -. (Not strictly correct). 19 * - Convert C-A*B into C+(-A)*B whenever possible. 14 20 * 15 21 * Author: … … 26 32 27 33 28 // Simplify a vector expression 29 30 34 /// A simplified vector expression 31 35 struct RevisedExpression { 32 char [] expr ; // the revised expression using new variable names33 // (so, for example, B+=(D-F) becomes A+=(B-C) ).36 char [] expression; // the revised expression using new variable names 37 // (so, for example, B+=(D-F) becomes A+=(B-C) ). 34 38 char [][] compounds; // the compound variables, defined using the old names 35 int [] rank; // rank of all of the compound variables 36 char [] used; // which of the old variables are used; gives the new mapping 37 // of the name, or - if not used. 39 char [] rank; // rank of all of the compound variables 40 char [] mapping; // mapping from new names onto old names. 38 41 } 39 42 … … 42 45 { 43 46 int [] ranks=[]; 44 for (int i=0; i<tree.symbolTable.length; ++i) {ranks~=tree.symbolTable[i].rank ; }47 for (int i=0; i<tree.symbolTable.length; ++i) {ranks~=tree.symbolTable[i].rank-'0'; } 45 48 return simplifyVectorExpression(removeDuplicates(tree), ranks); 46 49 } … … 171 174 if (op=="*=") { 172 175 if (rrank==0) { 173 char [] m = right; //subexprSimplify(right, rank, "", "");176 char [] m = right; 174 177 if (mulexpr.length>0) m ~= "*" ~ mulexpr; 175 178 if (m.length>1) m= " {" ~ m ~ "} "; … … 204 207 if (s.length>1) s = s[1..$-1]; // strip off () 205 208 char [][] comp; 206 char [] used=""; 209 char [] used=""; // which of the old variables are used; gives the new mapping 210 // of the name, or - if not used. 207 211 for (int i=0; i<rank.length; ++i) used~="-"; 208 int[] r;212 char [] r; 209 213 char next = cast(char)('A' + rank.length); 210 214 char [] e = ""; … … 218 222 // by indices. Can't just use exprRank, because the [] 219 223 // aren't wrapped by (). 220 r ~= rank[s[i+2]-'A'] - indexRank(s[i+2..k-1]);224 r ~= (rank[s[i+2]-'A'] - indexRank(s[i+2..k-1]))+'0'; 221 225 } else { 222 226 // it's a scalar expression. Note that it could involve 223 227 // a vector expression. 224 r~= 0;228 r~='0'; 225 229 } 226 230 e ~= next; … … 233 237 } 234 238 // Create a mapping from old to new variable names 239 char [] mapping=""; 235 240 char knt = 'A'; 236 241 for (int i=0; i<used.length; ++i) { 237 242 if (used[i]!='-') { 243 mapping ~= ('A'+i); 238 244 used[i] = knt; 239 245 ++knt; 240 246 } 247 } 248 for (int i=0; i<r.length; ++i) { 249 mapping ~= ('A'+used.length+i); 241 250 } 242 251 // and set the expression to use the new names … … 250 259 } 251 260 252 return RevisedExpression(f, comp, r, used); 253 } 254 255 unittest { 256 261 return RevisedExpression(f, comp, r, mapping); 262 } 263 264 unittest { 257 265 assert(exprSimplify("A+=(((D[E])*B)[E])", [1,0,3,3,0,0],"","")=="(A+=(B* {D[E][E]} ))"); 258 266 assert(exprSimplify("A+=(B*((C[B])[B..E]))", [1,0,3,3,0,0],"","")=="(A+=(B* {C[B][B..E]} ))"); … … 261 269 262 270 RevisedExpression e = simplifyVectorExpression("A+=(((D[B])*C)[B])", [2,0,0,4]); 263 assert(e.expr == "A+=(B*C)");264 assert(e.rank [0]==2);271 assert(e.expression == "A+=(B*C)"); 272 assert(e.rank == "2"); 265 273 assert(e.compounds[0]=="D[B][B]"); 266 assert(e.used=="A-B-"); 267 // assert(removedUnusedSymbolsFromExpression(e)=="A+=(B*C)"); 268 } 274 assert(e.mapping=="ACE"); 275 } trunk/blade/SyntaxTree.d
r134 r135 90 90 char [] type; /// the name of the type, as text 91 91 char [] value; /// the value, as text. 92 int rank; /// the tensor rank (0=scalar, 1=vector, 2 = matrix, 3=tensor)92 char rank; /// the tensor rank ('0'=scalar, 1=vector, 2 = matrix, 3=tensor) 93 93 } 94 94 … … 342 342 // BLADE-SPECIFIC SEMANTIC PASS 343 343 344 // When mixed in, creates a const integer describing the (tensor) rank of symbol sym.344 // When mixed in, creates a const char describing the (tensor) rank of symbol sym. 345 345 // Possible results are 0 = scalar, 1 = vector, 2 = matrix, 3 = tensor of rank 3 or more. 346 346 char [] mixin_rankOf(char [] sym) … … 348 348 // Implementation: If sym[0][0] is a valid type, we know it's a matrix. 349 349 // else if sym[0] is a valid type, we know it's a vector. Etc. 350 return "is(typeof(" ~ sym ~ "[0]))?is(typeof(" ~ sym ~ "[0][0]))?is(typeof(" ~ sym ~ "[0][0][0]))? 3:2:1:0";350 return "is(typeof(" ~ sym ~ "[0]))?is(typeof(" ~ sym ~ "[0][0]))?is(typeof(" ~ sym ~ "[0][0][0]))?'3':'2':'1':'0'"; 351 351 } 352 352
