csarofeen opened a new pull request #4270: [Codgen] Thread variable use before 
define
URL: https://github.com/apache/incubator-tvm/pull/4270
 
 
   There are instances where threads can be used before defined. This can 
happen, for example, when a consumer stage has a thread dimension bound to an 
axis and that dimension is propagated to producer stages as a Domain of 
`(ThreadIdx.[x,y,z], 1)`.
   
   This PR adds a pass during schedule_ops which looks for uses of either 
threadIdx.[x,y,z] or blockIdx.[x,y,z] before the corresponding attr statement. 
If use before define is detected on these variables it will check if they are 
defined later in the function being lowered and will copy the attr statement to 
the beginning of the producer scope where the use before define was found.
   
   For example given an IR as:
   
   ```// attr [compute(C, 0x55addf266ad0)] realize_scope = ""
   realize C([0, 1024], [0, 1024]) {
     produce C {
       // attr [iter_var(blockIdx.x, , blockIdx.x)] thread_extent = 1024
       // attr [compute(B, 0x55addf146840)] realize_scope = "local"
       realize B([blockIdx.x, 1], [threadIdx.x, 1]) {
         produce B {
           B(blockIdx.x, threadIdx.x) =(A(blockIdx.x, threadIdx.x)*1.001f)
         }
         // attr [iter_var(threadIdx.x, , threadIdx.x)] thread_extent = 1024
         C(blockIdx.x, threadIdx.x) =(B(blockIdx.x, threadIdx.x)*2f)
       }
     }
   }```
   
   Produce B will be modified to:
   ```
         produce B {
         // attr [iter_var(threadIdx.x, , threadIdx.x)] thread_extent = 1024
           B(blockIdx.x, threadIdx.x) =(A(blockIdx.x, threadIdx.x)*1.001f)
         }
   ```
   
   As when we attempt to compile the first we end up with errors, either in the 
make_api pass or later.
   
   **Minimal repro:**
   ```
   import tvm
   
   bx = tvm.thread_axis("blockIdx.x")
   tx = tvm.thread_axis("threadIdx.x")
   
   n = 1024
   m = 1024
   
   A = tvm.placeholder((n, m), name='A')
   
   B = tvm.compute(
       (n, m),
       lambda i, j:
       A[i, j] * 1.001,
       name="B"
   )
   
   C = tvm.compute(
       (n, m),
       lambda i, j:
       B[i, j] * 2.0,
       name="C"
   )
   
   deps = [A, C]
   
   s = tvm.create_schedule(C.op)
   s[C].bind(s[C].op.axis[0], bx)
   s[C].bind(s[C].op.axis[1], tx)
   s[B].compute_at(s[C], s[C].op.axis[0])
   s[B].set_scope("local")
   
   print(tvm.lower(s, [A, C], simple_mode=True))
   
   fcuda = tvm.build(s, deps, "cuda")
   print(fcuda.imported_modules[0].get_source())
   ```

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
[email protected]


With regards,
Apache Git Services

Reply via email to