You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tvm.apache.org by GitBox <gi...@apache.org> on 2021/04/07 11:59:12 UTC

[GitHub] [tvm] tqchen commented on issue #7805: [TIR][Bug] The buffer map, parameters and body do not agree on buffer variable identity.

tqchen commented on issue #7805:
URL: https://github.com/apache/tvm/issues/7805#issuecomment-814855497


   This is an expected behavior. See explaination of the buffer_map signature here https://github.com/apache/tvm/blob/main/include/tvm/tir/function.h#L57
   
   Specifically, in the low level code, note there is a difference between the two things:
   - The DLTensor* pointer that points to the DLTensor* structure
   - The actual data pointer in the DLTensor structure that points to a data field.
   
   The tvmscript format illustrates this fact more clearly
   
   ```python
   @tvm.script.tir
   def fun(a: ty.handle, b: ty.handle):
       Abuf = tir.match_buffer((3,), a, dtype="float32")
       Bbuf = tir.match_buffer((3,), b, dtype="float32")
       A_buffer_var: ty.Pointer("float32") = Abuf.data
       B_buffer_var: ty.Pointer("float32") = Bbuf.data
       B_buffer_var[0] = A_buffer_var[0] + 1
   ```
   See also a C version that illustrate the type signature)
   ```c++
   void func(DLTensor* a, DLTensor* b) {
       A_buffer_var = (float*)a.data;
       B_buffer_var = (float*)b.data;
       B_buffer_var[0] = A_buffer_var[0] + 1;
   }
   ```
   
   In the low level IR, the buffer vars corresponds to the data field(A_buffer_var and B_buffer_var). While the parameter arguments corresponds to the pointer to the DLTensor* field. Their relation are maintained via the match_buffer statements, and translates to the buffer_map field in the function signature.
   
   This behavior is intended because it is important to distinguish the following three things in the IR:
   - T0: in-memory pointer to the DLTensor*
   - T1: abstract buffer(Abuf, Bbuf) that only exists during compile time, but will be staged to the individual elements
   - T2: The pointer to the data field (A_buffer_var and B_buffer_var)
   
   - T0 is needed because we need to faithfully represent the argument being passed to a function.
   - T1 is needed, and cannot be T0 because in certainly cases like GPU, we cannot afford to pass a DLTensor* pointer directly to the kernel, but need to construct a buffer in an abstracted way, which get stagged to the individual fields
   - T2 is needed because this is the data pointer that we directly operates on.
   
   
   
   
   


-- 
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:
users@infra.apache.org