Skip to content

[Bug] [TVMScript] Weird output of my script #13695

@lightzhan-intellif

Description

@lightzhan-intellif

Hi all,
I have a program like this:

import numpy as np
from tvm.script import tir as T
import tvm

@T.prim_func
def test_case(A: T.Buffer[(1, ), "uint8"], B: T.Buffer[(1, ), "float32"]):
  B[0] = A[0]


if __name__ == "__main__":
  compiled = tvm.build(test_case, target="llvm")
  in_data = np.empty((1,), dtype=np.uint8)
  in_data[0] = 100
  out_data = np.empty((1,), dtype=np.float32)
  A_tvm = tvm.nd.array(in_data, tvm.cpu(0))
  B_tvm = tvm.nd.array(out_data, tvm.cpu(0))
  compiled(A_tvm, B_tvm)
  print(B_tvm.numpy())

I just want to assign a value 100 typed uint8 to an address of type float. In python, we should get the result 100 in the B[0], but it give me a weird result [2.0000238] without any warning or error.

I change the target to c, and get the following c code:

// tvm target: c -keys=cpu 
#define TVM_EXPORTS
#include "tvm/runtime/c_runtime_api.h"
#include "tvm/runtime/c_backend_api.h"
#include <math.h>
#ifdef __cplusplus
extern "C"
#endif
TVM_DLL int32_t default_function(void* args, int32_t* arg_type_ids, int32_t num_args, void* out_ret_value, int32_t* out_ret_tcode, void* resource_handle) {
  void* arg_A_handle = (((TVMValue*)args)[0].v_handle);
  int32_t arg_A_handle_code = arg_type_ids[0];
  void* arg_B_handle = (((TVMValue*)args)[1].v_handle);
  int32_t arg_B_handle_code = arg_type_ids[1];
  void* A = (((DLTensor*)arg_A_handle)[0].data);
  void* arg_A_handle_shape = (((DLTensor*)arg_A_handle)[0].shape);
  void* arg_A_handle_strides = (((DLTensor*)arg_A_handle)[0].strides);
  int32_t dev_id = (((DLTensor*)arg_A_handle)[0].device.device_id);
  void* B = (((DLTensor*)arg_B_handle)[0].data);
  void* arg_B_handle_shape = (((DLTensor*)arg_B_handle)[0].shape);
  void* arg_B_handle_strides = (((DLTensor*)arg_B_handle)[0].strides);
  if (!(arg_A_handle_strides == NULL)) {
  }
  if (!(arg_B_handle_strides == NULL)) {
  }
  *(uint8_t*)(((float*)B) + 0) = ((uint8_t*)A)[0];
  return 0;
}

// CodegenC: NOTE: Auto-generated entry function
#ifdef __cplusplus
extern "C"
#endif
TVM_DLL int32_t __tvm_main__(void* args, int* arg_type_ids, int num_args, void* out_ret_value, int* out_ret_tcode, void* resource_handle) {
  return default_function(args, arg_type_ids, num_args, out_ret_value, out_ret_tcode, resource_handle);
}

From the code *(uint8_t*)(((float*)B) + 0) = ((uint8_t*)A)[0];, you can see that tvm does not do any casting to the assignment operation, which causes this strange behavior.

So, how can we fix this? Any idea is welcome.

@junrushao @wrongtest-intellif @Hzfengsy

Metadata

Metadata

Assignees

No one assigned

    Labels

    needs-triagePRs or issues that need to be investigated by maintainers to find the right assignees to address ittype: bug

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions