Changeset 135

Show
Ignore:
Timestamp:
11/13/07 13:07:01 (10 months ago)
Author:
Don Clugston
Message:

RevisedExpression? now uses a mapping from new to old variables, instead of old->new.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/blade/Blade.d

    r133 r135  
    2121*  - Error messages refer to the line of user code which generated the error. 
    2222*    The library never produces a torrent of undecipherable template error messages. 
     23*  - A 'const folding' (actually vector/scalar folding) step is performed. 
    2324* 
    2425* FUTURE DIRECTIONS (in order of expected implementation): 
    2526* - Dot product (which was present in BLADE 0.2). 
    2627* - The x87 code generation targets early Pentiums, which are now irrelevant. 
    27 * - A 'const folding' (actually vector/scalar folding) step needs to be performed. 
    2828* - Support for strided vectors. 
    2929* - Matrix support. 
     
    132132    for (int i=0; i<tree.symbolTable.length;++i) { 
    133133        char [] t = tree.symbolTable[i].type; 
    134         int r = tree.symbolTable[i].rank
     134        int r = tree.symbolTable[i].rank-'0'
    135135        if (r>1) return VecExpressionType.DExpression; // can only do scalars and vectors right now. 
    136136        if (r==0) { 
     
    173173    for (int i=0; i<tree.symbolTable.length;++i) { 
    174174        char [] t = tree.symbolTable[i].type; 
    175         if (tree.symbolTable[i].rank==0) { 
     175        if (tree.symbolTable[i].rank=='0') { 
    176176            // Convert scalars into standard form. 
    177177            // long, ulong, and real must become real. 
     
    193193        result ~="," ~ tree.symbolTable[i].value; 
    194194        // 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"; 
    196196    } 
    197197    return result~ ");";         
     
    207207    char [] vectortype = SSE2? ",double*" : ",float*"; 
    208208     
    209     result ~= "SSEVECGEN!(" ~ (SSE2?"2":"1") ~ "," ~ wrapInQuotes(revised.expr);     
     209    result ~= "SSEVECGEN!(" ~ (SSE2?"2":"1") ~ "," ~ wrapInQuotes(revised.expression);     
    210210    // For SSE2, everything must be implicitly convertible to double. 
    211211    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/*     
    212238    for (int i=0; i<tree.symbolTable.length;++i) { 
    213239        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; 
    215241        else result ~= vectortype;         
    216242        vals ~= "," ~ tree.symbolTable[i].value; 
    217243        // 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"; 
    219245    } 
    220246    // Now deal with all of the compound expressions 
    221247    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; 
    223249        else result ~= vectortype; 
    224250        char [] s = ""; 
     
    227253            else s ~= c; 
    228254        } 
    229         if (revised.rank[i]==1) vals ~= ",(" ~ s ~ ").ptr"; 
     255        if (revised.rank[i]=='1') vals ~= ",(" ~ s ~ ").ptr"; 
    230256        else vals ~= "," ~ s; 
    231257    } 
     258*/     
    232259    result ~= ")("; 
    233260    int firstVector = findVectorForLength(tree); 
     
    247274    bool known = arrayLengthIsStatic(tree.symbolTable[firstVector].type); 
    248275    for (int i=0; i<tree.symbolTable.length;++i) { 
    249         if (tree.symbolTable[i].rank==1){ 
     276        if (tree.symbolTable[i].rank=='1'){ 
    250277            if (firstVector != i) { 
    251278                if (known && arrayLengthIsStatic(tree.symbolTable[i].type)) { 
     
    267294    char [] result =""; 
    268295    for (int i=0; i<tree.symbolTable.length;++i) { 
    269         if (tree.symbolTable[i].rank==1){ 
     296        if (tree.symbolTable[i].rank=='1'){ 
    270297            result ~= "assert( (cast(size_t)(" ~ tree.symbolTable[i].value  
    271298                    ~ ".ptr)& 0x1F) == 0, `SSE Vector misalignment: " ~ tree.symbolTable[i].value ~ "`);"\n; 
     
    288315    int dynamic = 0; // last dynamic vector 
    289316    for (int i=0; i<tree.symbolTable.length; ++i) { 
    290         if (tree.symbolTable[i].rank==1) { 
     317        if (tree.symbolTable[i].rank=='1') { 
    291318            dynamic = i; 
    292319            if (arrayLengthIsStatic(tree.symbolTable[i].type)) return i; 
     
    307334            result ~= tree.symbolTable[c-'A'].value; 
    308335            // If it's a vector, index it 
    309             if (tree.symbolTable[c-'A'].rank==1
     336            if (tree.symbolTable[c-'A'].rank=='1'
    310337                result ~= "[blade_index]"; 
    311338        } else result ~= c; 
  • trunk/blade/BladeSimplify.d

    r133 r135  
    22/** 
    33* 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, 
    916*      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. 
    1420* 
    1521* Author: 
     
    2632 
    2733 
    28 // Simplify a vector expression 
    29  
    30  
     34/// A simplified vector expression 
    3135struct RevisedExpression { 
    32     char [] expr; // the revised expression using new variable names 
    33                   // (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) ). 
    3438    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. 
    3841} 
    3942 
     
    4245{ 
    4346    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'; } 
    4548    return simplifyVectorExpression(removeDuplicates(tree), ranks); 
    4649} 
     
    171174    if (op=="*=") { 
    172175        if (rrank==0) { 
    173             char [] m = right; //subexprSimplify(right, rank, "", ""); 
     176            char [] m = right; 
    174177            if (mulexpr.length>0) m ~= "*" ~ mulexpr; 
    175178            if (m.length>1)  m= " {" ~ m ~ "} "; 
     
    204207    if (s.length>1) s = s[1..$-1]; // strip off () 
    205208    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. 
    207211    for (int i=0; i<rank.length; ++i) used~="-"; 
    208     int [] r; 
     212    char [] r; 
    209213    char next = cast(char)('A' + rank.length); 
    210214    char [] e = ""; 
     
    218222                // by indices. Can't just use exprRank, because the [] 
    219223                // 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'
    221225            } else { 
    222226                // it's a scalar expression. Note that it could involve 
    223227                // a vector expression. 
    224                 r~=0;  
     228                r~='0';  
    225229            } 
    226230            e ~= next; 
     
    233237    } 
    234238    // Create a mapping from old to new variable names 
     239    char [] mapping=""; 
    235240    char knt = 'A'; 
    236241    for (int i=0; i<used.length; ++i) { 
    237242        if (used[i]!='-') { 
     243            mapping ~= ('A'+i); 
    238244            used[i] = knt; 
    239245            ++knt; 
    240246        } 
     247    } 
     248    for (int i=0; i<r.length; ++i) { 
     249        mapping ~= ('A'+used.length+i); 
    241250    } 
    242251   // and set the expression to use the new names 
     
    250259    } 
    251260 
    252     return RevisedExpression(f, comp, r, used); 
    253 
    254  
    255 unittest { 
    256     
     261    return RevisedExpression(f, comp, r, mapping); 
     262
     263 
     264unittest {    
    257265    assert(exprSimplify("A+=(((D[E])*B)[E])", [1,0,3,3,0,0],"","")=="(A+=(B* {D[E][E]} ))"); 
    258266    assert(exprSimplify("A+=(B*((C[B])[B..E]))", [1,0,3,3,0,0],"","")=="(A+=(B* {C[B][B..E]} ))"); 
     
    261269 
    262270    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"); 
    265273    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  
    9090    char [] type;  /// the name of the type, as text 
    9191    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) 
    9393} 
    9494 
     
    342342// BLADE-SPECIFIC SEMANTIC PASS 
    343343 
    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. 
    345345// Possible results are 0 = scalar, 1 = vector, 2 = matrix, 3 = tensor of rank 3 or more. 
    346346char [] mixin_rankOf(char [] sym) 
     
    348348    // Implementation: If sym[0][0] is a valid type, we know it's a matrix. 
    349349    // 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'"; 
    351351} 
    352352