10000 Mixing of indices of lvalue when using `for` generators in rvalue · Issue #138 · orcc/orcc · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Mixing of indices of lvalue when using for generators in rvalue #138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasion 8000 ally send you account related emails.

Already on GitHub? Sign in to your account

Open
Junaiid-Ahmad opened this issue Dec 3, 2015 · 2 comments
Open

Comments

@Junaiid-Ahmad
Copy link

Given the following action:

uint(size=8) pt[192] := [...data...];
action ==> OP:[pt[offset1+i]: for int i in 0 .. 15] repeat 16
var
     int offset1 := 64,     
     uint(size=8) tempList[16]
do
     tempList := [pt[i]: for int i in offset1 .. offset1+15];
end

The C-backend generates the following code for this two list generations:

   // 1) For statement: tempList := [pt[i]: for int i in offset1 .. offset1+15];
i = offset1;
while (i <= offset1 + 15) {
    tmp_pt = pt[i];
    tempList[i] = tmp_pt;
    i = i + 1;
}

   // 2) For statement: OP:[pt[offset1+i]: for int i in 0 .. 15] repeat 16
i = offset1;
while (i <= 15) {
    tmp_pt = pt[offset1+i];
    tokens_OP[(index_OP % SIZE_OP) + (i)] = tmp_pt;
    i = i + 1;
}       

In both cases, index i (which is the index of the generator for) has also been used to populate the lvalue lists (tempList, tokensOP). This usage is fine, when the indexing in the for generator is starting from 0. But when the for generator is starting with some non-zero positive number, the index i mistakenly refers to a wrong location in the lvalue list, hence results in index of out bound exceptions.

@robstewart57
Copy link
Contributor

@JunaidJameel the closest (complete) actor example containing your action is:

package cal;

actor my_actor() uint(size=8) In ==> uint(size=8) OP:
List(type:uint(size=8),size=192) pt;

action In:[xs] repeat 192 ==>
do
 foreach int i in 0 .. 191 do
  pt[i] := xs[i];
 end
end

// the action in your bug report
action ==> OP:[ [ pt[offset1+i] : for int i in 0 .. 15] ] repeat 16
var
     int offset1 := 64,     
     uint(size=8) tempList[16]
do
     tempList := [pt[i]: for int i in offset1 .. offset1+15];
end
end

The C for the action in question is:

static void untagged_1() {
    i32 offset1;
    u8 tempList[16];
    i32 i;
    u8 tmp_pt;
    i32 i0;
    u8 tmp_pt0;
    offset1 = 64;
    i = offset1;
    while (i <= offset1 + 15) {
        tmp_pt = pt[i];
        tempList[i - 64] = tmp_pt;
        i = i + 1;
    }
    i0 = 0;
    while (i0 <= 15) {
        tmp_pt0 = pt[offset1 + i0];
        i0 = i0 + 1;
    }
    // Update ports indexes
}

Which doesn't match your C output. Could you provide a complete actor that contains the action in question, so that I could replicate the C output you are getting?

@Junaiid-Ahmad
Copy link
Author

Hi @robstewart57 ,

Please checkout to branch tta_experimental, commit: 7312522 and then go to this design: Crypto/CTL/Block_Ciphers/AES/AES_CBC_4_Enciphers.xdf
In the source actor, replace action sendDataBlock with the code given below:

sendDataBlock:
action ==>    
           OP4_PT1:[[pt[offset1+i]: for int i in 0 .. 15]] repeat 16,
           OP4_PT2:[[pt[offset2+i]: for int i in 0 .. 15]] repeat 16,
           OP4_PT3:[[pt[offset3+i]: for int i in 0 .. 15]] repeat 16,
           OP4_PT4:[[pt[offset4+i]: for int i in 0 .. 15]] repeat 16,               
           OP5_GR:[[gr[offset1+i]: for int i in 0 .. 63]] repeat 16*4
guard numBlocks < 12                          
var
    int offset1 := numBlocks * 16,
    int offset2 := numBlocks * 16 + 16,
    int offset3 := numBlocks * 16 + 16 * 2,
    int offset4 := numBlocks * 16 + 16 * 3,
    uint(size=8) tempList[16]
do    
    numBlocks := numBlocks + 4;

    tempList := [pt[i]: for int i in offset1 .. offset1+15]; 
end

Note that, tempList and corresponding list copy instruction in the action body are added just to reproduce the problem I was referring to.

After compiling, I see the following code for the action's body:

static void sendDataBlock_aligned() {
    i32 local_numBlocks;
    i32 offset1;
    i32 offset2;
    i32 offset3;
    i32 offset4;
    u8 tempList[16];
    i32 i;
    u8 tmp_pt;
    i32 i0;
    u8 tmp_pt0;
    i32 i1;
    u8 tmp_pt1;
    i32 i2;
    u8 tmp_pt2;
    i32 i3;
    u8 tmp_pt3;
    i32 i4;
    u8 tmp_gr;
    local_numBlocks = numBlocks;
    offset1 = local_numBlocks * 16;
    local_numBlocks = numBlocks;
    offset2 = local_numBlocks * 16 + 16;
    local_numBlocks = numBlocks;
    offset3 = local_numBlocks * 16 + 16 * 2;
    local_numBlocks = numBlocks;
    offset4 = local_numBlocks * 16 + 16 * 3;
    local_numBlocks = numBlocks;
    numBlocks = local_numBlocks + 4;
    i = offset1;
    while (i <= offset1 + 15) {
        tmp_pt = pt[i];
        tempList[i] = tmp_pt;
        i = i + 1;
    }
    i0 = 0;
    while (i0 <= 15) {
        tmp_pt0 = pt[offset1 + i0];
        tokens_OP4_PT1[(index_OP4_PT1 % SIZE_OP4_PT1) + (i0)] = tmp_pt0;
        i0 = i0 + 1;
    }
    i1 = 0;
    while (i1 <= 15) {
        tmp_pt1 = pt[offset2 + i1];
        tokens_OP4_PT2[(index_OP4_PT2 % SIZE_OP4_PT2) + (i1)] = tmp_pt1;
        i1 = i1 + 1;
    }
    i2 = 0;
    while (i2 <= 15) {
        tmp_pt2 = pt[offset3 + i2];
        tokens_OP4_PT3[(index_OP4_PT3 % SIZE_OP4_PT3) + (i2)] = tmp_pt2;
        i2 = i2 + 1;
    }
    i3 = 0;
    while (i3 <= 15) {
        tmp_pt3 = pt[offset4 + i3];
        tokens_OP4_PT4[(index_OP4_PT4 % SIZE_OP4_PT4) + (i3)] = tmp_pt3;
        i3 = i3 + 1;
    }
    i4 = 0;
    while (i4 <= 63) {
        tmp_gr = gr[offset1 + i4];
        tokens_OP5_GR[(index_OP5_GR % SIZE_OP5_GR) + (i4)] = tmp_gr;
        i4 = i4 + 1;
    }
    // Update ports indexes
    index_OP4_PT1 += 16;
    write_end_OP4_PT1();
    index_OP4_PT2 += 16;
    write_end_OP4_PT2();
    index_OP4_PT3 += 16;
    write_end_OP4_PT3();
    index_OP4_PT4 += 16;
    write_end_OP4_PT4();
    index_OP5_GR += 64;
    write_end_OP5_GR();
}

Note this tempList[i] = tmp_pt; in the body of while (i <= offset1 + 15) loop. This is different from what you posted above.

For the rest of the while loops, also note how indices (i0 .. i4) have been used to index their corresponding output fifo buffers, while these indices actually belong to their corresponding for generators. In this case, they work fine to populate output buffers at the correct location because they are starting from 0.

We can also produce the problem similar to tempList with fifo buffers too by replacing the statements sending tokens to output ports with the following 5 lines in CAL code.

           OP4_PT1:[[pt[i]: for int i in offset1 .. offset1+15]] repeat 16,
           OP4_PT2:[[pt[i]: for int i in offset2 .. offset2+15]] repeat 16,
           OP4_PT3:[[pt[i]: for int i in offset1 .. offset3+15]] repeat 16,
           OP4_PT4:[[pt[i]: for int i in offset1 .. offset4+15]] repeat 16,               
           OP5_GR:[[gr[i]: for int i in offset1 .. offset1+63]] repeat 16*4

I hope this would help you reproduce the problems.

PS: If you would like to run this design, no input is needed. Just compile and run. You will see errors in output if you happen to test with the above code for output ports.

In case it is important, I am on commit 4c15ff7 of orcc master.

@Junaiid-Ahmad Junaiid-Ahmad changed the title Mixing of indices of lvalue when using for generators in rvalue Mixing of indices of lvalue when using for generators in rvalue Dec 4, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants
0