We think it will reduce the confusion with the meaning.
https://discuss.tvm.ai/t/discuss-consider-rename-vm-datatype/4339
Allocate a tensor value of the appropriate shape (stored in `shape_register`) and `dtype`. The result
is saved to register `dst`.
-AllocDatatype
+AllocADT
^^^^^^^^^^^^^
**Arguments**:
::
RegName object
RegName dst
-Get the object tag for Datatype object in register `object`. And saves the reult to register `dst`.
+Get the object tag for ADT object in register `object`. And saves the reult to register `dst`.
Fatal
^^^^^
::
- VMObject VMTensor(const tvm::runtime::NDArray& data);
- VMObject VMDatatype(size_t tag, const std::vector<VMObject>& fields);
- VMObject VMClosure(size_t func_index, std::vector<VMObject> free_vars);
+ Object Tensor(const tvm::runtime::NDArray& data);
+ Object ADT(size_t tag, const std::vector<Object>& fields);
+ Object Closure(size_t func_index, std::vector<Object> free_vars);
Stack and State
kRoot = 0,
kVMTensor = 1,
kVMClosure = 2,
- kVMDatatype = 3,
+ kVMADT = 3,
kStaticIndexEnd,
/*! \brief Type index is allocated during runtime. */
kDynamic = kStaticIndexEnd
/*! \brief An object representing a structure or enumeration. */
-class DatatypeObj : public Object {
+class ADTObj : public Object {
public:
/*! \brief The tag representing the constructor used. */
size_t tag;
/*! \brief The fields of the structure. */
std::vector<ObjectRef> fields;
- static constexpr const uint32_t _type_index = TypeIndex::kVMDatatype;
- static constexpr const char* _type_key = "vm.Datatype";
- TVM_DECLARE_FINAL_OBJECT_INFO(DatatypeObj, Object);
+ static constexpr const uint32_t _type_index = TypeIndex::kVMADT;
+ static constexpr const char* _type_key = "vm.ADT";
+ TVM_DECLARE_FINAL_OBJECT_INFO(ADTObj, Object);
};
-/*! \brief reference to data type. */
-class Datatype : public ObjectRef {
+/*! \brief reference to algebraic data type objects. */
+class ADT : public ObjectRef {
public:
- Datatype(size_t tag, std::vector<ObjectRef> fields);
+ ADT(size_t tag, std::vector<ObjectRef> fields);
/*!
* \brief construct a tuple object.
* \param fields The fields of the tuple.
* \return The constructed tuple type.
*/
- static Datatype Tuple(std::vector<ObjectRef> fields);
+ static ADT Tuple(std::vector<ObjectRef> fields);
- TVM_DEFINE_OBJECT_REF_METHODS(Datatype, ObjectRef, DatatypeObj);
+ TVM_DEFINE_OBJECT_REF_METHODS(ADT, ObjectRef, ADTObj);
};
/*! \brief An object representing a closure. */
InvokePacked = 4U,
AllocTensor = 5U,
AllocTensorReg = 6U,
- AllocDatatype = 7U,
+ AllocADT = 7U,
AllocClosure = 8U,
GetField = 9U,
If = 10U,
/*! \brief The register to project from. */
RegName object;
} get_tag;
- struct /* AllocDatatype Operands */ {
+ struct /* AllocADT Operands */ {
/*! \brief The datatype's constructor tag. */
Index constructor_tag;
/*! \brief The number of fields to store in the datatype. */
* \param dst The register name of the destination.
* \return The allocate instruction tensor.
*/
- static Instruction AllocDatatype(Index tag, Index num_fields, const std::vector<RegName>& fields,
+ static Instruction AllocADT(Index tag, Index num_fields, const std::vector<RegName>& fields,
RegName dst);
/*! \brief Construct an allocate closure instruction.
* \param func_index The index of the function table.
from .interpreter import Executor
Tensor = _obj.Tensor
-Datatype = _obj.Datatype
+ADT = _obj.ADT
def _convert(arg, cargs):
if isinstance(arg, (np.ndarray, tvm.nd.NDArray)):
return self.data.asnumpy()
-@register_object("vm.Datatype")
-class Datatype(Object):
- """Datatype object.
+@register_object("vm.ADT")
+class ADT(Object):
+ """Algebatic data type(ADT) object.
Parameters
----------
tag : int
- The tag of datatype.
+ The tag of ADT.
fields : list[Object] or tuple[Object]
The source tuple.
for f in fields:
assert isinstance(f, Object)
self.__init_handle_by_constructor__(
- _vmobj.Datatype, tag, *fields)
+ _vmobj.ADT, tag, *fields)
@property
def tag(self):
- return _vmobj.GetDatatypeTag(self)
+ return _vmobj.GetADTTag(self)
def __getitem__(self, idx):
return getitem_helper(
- self, _vmobj.GetDatatypeFields, len(self), idx)
+ self, _vmobj.GetADTFields, len(self), idx)
def __len__(self):
- return _vmobj.GetDatatypeNumberOfFields(self)
+ return _vmobj.GetADTNumberOfFields(self)
def tuple_object(fields):
- """Create a datatype object from source tuple.
+ """Create a ADT object from source tuple.
Parameters
----------
Returns
-------
- ret : Datatype
+ ret : ADT
The created object.
"""
for f in fields:
DLOG(INFO) << "VMCompiler::Emit: instr=" << instr;
CHECK((int)instr.op < 100) << "Invalid opcode " << (int)instr.op;
switch (instr.op) {
- case Opcode::AllocDatatype:
+ case Opcode::AllocADT:
case Opcode::AllocTensor:
case Opcode::AllocTensorReg:
case Opcode::GetField:
}
// TODO(@jroesch): use correct tag
- Emit(Instruction::AllocDatatype(
+ Emit(Instruction::AllocADT(
0,
tuple->fields.size(),
fields_registers,
for (size_t i = arity - return_count; i < arity; ++i) {
fields_registers.push_back(unpacked_arg_regs[i]);
}
- Emit(Instruction::AllocDatatype(0, return_count, fields_registers, NewRegister()));
+ Emit(Instruction::AllocADT(0, return_count, fields_registers, NewRegister()));
}
}
}
} else if (auto constructor_node = op.as<ConstructorNode>()) {
auto constructor = GetRef<Constructor>(constructor_node);
- Emit(Instruction::AllocDatatype(constructor->tag, call_node->args.size(), args_registers,
+ Emit(Instruction::AllocADT(constructor->tag, call_node->args.size(), args_registers,
NewRegister()));
} else if (auto var_node = op.as<VarNode>()) {
VisitExpr(GetRef<Var>(var_node));
fields.push_back(instr.dst);
break;
}
- case Opcode::AllocDatatype: {
+ case Opcode::AllocADT: {
// Number of fields = 3 + instr.num_fields
fields.assign({instr.constructor_tag, instr.num_fields, instr.dst});
return Instruction::AllocTensorReg(shape_register, dtype, dst);
}
- case Opcode::AllocDatatype: {
+ case Opcode::AllocADT: {
// Number of fields = 3 + instr.num_fields
DCHECK_GE(instr.fields.size(), 3U);
DCHECK_EQ(instr.fields.size(), 3U + static_cast<size_t>(instr.fields[1]));
RegName dst = instr.fields[2];
std::vector<Index> fields = ExtractFields(instr.fields, 3, num_fields);
- return Instruction::AllocDatatype(constructor_tag, num_fields, fields, dst);
+ return Instruction::AllocADT(constructor_tag, num_fields, fields, dst);
}
case Opcode::AllocClosure: {
// Number of fields = 3 + instr.num_freevar
data_ = std::move(ptr);
}
-Datatype::Datatype(size_t tag, std::vector<ObjectRef> fields) {
- auto ptr = make_object<DatatypeObj>();
+ADT::ADT(size_t tag, std::vector<ObjectRef> fields) {
+ auto ptr = make_object<ADTObj>();
ptr->tag = tag;
ptr->fields = std::move(fields);
data_ = std::move(ptr);
}
-Datatype Datatype::Tuple(std::vector<ObjectRef> fields) {
- return Datatype(0, fields);
+ADT ADT::Tuple(std::vector<ObjectRef> fields) {
+ return ADT(0, fields);
}
Closure::Closure(size_t func_index, std::vector<ObjectRef> free_vars) {
*rv = cell->data;
});
-TVM_REGISTER_GLOBAL("_vmobj.GetDatatypeTag")
+TVM_REGISTER_GLOBAL("_vmobj.GetADTTag")
.set_body([](TVMArgs args, TVMRetValue* rv) {
ObjectRef obj = args[0];
- const auto* cell = obj.as<DatatypeObj>();
+ const auto* cell = obj.as<ADTObj>();
CHECK(cell != nullptr);
*rv = static_cast<int64_t>(cell->tag);
});
-TVM_REGISTER_GLOBAL("_vmobj.GetDatatypeNumberOfFields")
+TVM_REGISTER_GLOBAL("_vmobj.GetADTNumberOfFields")
.set_body([](TVMArgs args, TVMRetValue* rv) {
ObjectRef obj = args[0];
- const auto* cell = obj.as<DatatypeObj>();
+ const auto* cell = obj.as<ADTObj>();
CHECK(cell != nullptr);
*rv = static_cast<int64_t>(cell->fields.size());
});
-TVM_REGISTER_GLOBAL("_vmobj.GetDatatypeFields")
+TVM_REGISTER_GLOBAL("_vmobj.GetADTFields")
.set_body([](TVMArgs args, TVMRetValue* rv) {
ObjectRef obj = args[0];
int idx = args[1];
- const auto* cell = obj.as<DatatypeObj>();
+ const auto* cell = obj.as<ADTObj>();
CHECK(cell != nullptr);
CHECK_LT(idx, cell->fields.size());
*rv = cell->fields[idx];
for (auto i = 0; i < args.size(); ++i) {
fields.push_back(args[i]);
}
- *rv = Datatype::Tuple(fields);
+ *rv = ADT::Tuple(fields);
});
-TVM_REGISTER_GLOBAL("_vmobj.Datatype")
+TVM_REGISTER_GLOBAL("_vmobj.ADT")
.set_body([](TVMArgs args, TVMRetValue* rv) {
int itag = args[0];
size_t tag = static_cast<size_t>(itag);
for (int i = 1; i < args.size(); i++) {
fields.push_back(args[i]);
}
- *rv = Datatype(tag, fields);
+ *rv = ADT(tag, fields);
});
TVM_REGISTER_OBJECT_TYPE(TensorObj);
-TVM_REGISTER_OBJECT_TYPE(DatatypeObj);
+TVM_REGISTER_OBJECT_TYPE(ADTObj);
TVM_REGISTER_OBJECT_TYPE(ClosureObj);
} // namespace vm
} // namespace runtime
this->alloc_tensor_reg.shape_register = instr.alloc_tensor_reg.shape_register;
this->alloc_tensor_reg.dtype = instr.alloc_tensor_reg.dtype;
return;
- case Opcode::AllocDatatype:
+ case Opcode::AllocADT:
this->constructor_tag = instr.constructor_tag;
this->num_fields = instr.num_fields;
this->datatype_fields = Duplicate<RegName>(instr.datatype_fields, instr.num_fields);
this->alloc_tensor_reg.shape_register = instr.alloc_tensor_reg.shape_register;
this->alloc_tensor_reg.dtype = instr.alloc_tensor_reg.dtype;
return *this;
- case Opcode::AllocDatatype:
+ case Opcode::AllocADT:
this->constructor_tag = instr.constructor_tag;
this->num_fields = instr.num_fields;
FreeIf(this->datatype_fields);
case Opcode::AllocTensor:
delete this->alloc_tensor.shape;
return;
- case Opcode::AllocDatatype:
+ case Opcode::AllocADT:
delete this->datatype_fields;
return;
case Opcode::AllocClosure:
return instr;
}
-Instruction Instruction::AllocDatatype(Index tag, Index num_fields,
+Instruction Instruction::AllocADT(Index tag, Index num_fields,
const std::vector<RegName>& datatype_fields, Index dst) {
Instruction instr;
- instr.op = Opcode::AllocDatatype;
+ instr.op = Opcode::AllocADT;
instr.dst = dst;
instr.constructor_tag = tag;
instr.num_fields = num_fields;
DLDatatypePrint(os, instr.alloc_tensor_reg.dtype);
break;
}
- case Opcode::AllocDatatype: {
+ case Opcode::AllocADT: {
os << "alloc_data $" << instr.dst << " tag(" << instr.constructor_tag << ") [$"
<< StrJoin<RegName>(instr.datatype_fields, 0, instr.num_fields, ",$") << "]";
break;
const std::vector<ObjectRef>& args) {
size_t arity = 0;
for (Index i = 0; i < arg_count; i++) {
- if (const auto* obj = args[i].as<DatatypeObj>()) {
+ if (const auto* obj = args[i].as<ADTObj>()) {
arity += obj->fields.size();
} else {
++arity;
runtime::TVMArgsSetter setter(values.data(), codes.data());
int idx = 0;
for (Index i = 0; i < arg_count; i++) {
- if (const auto* dt_cell = args[i].as<DatatypeObj>()) {
+ if (const auto* dt_cell = args[i].as<ADTObj>()) {
for (auto obj : dt_cell->fields) {
const auto* tensor = obj.as<TensorObj>();
CHECK(tensor != nullptr);
}
case Opcode::GetField: {
auto object = ReadRegister(instr.object);
- const auto* tuple = object.as<DatatypeObj>();
+ const auto* tuple = object.as<ADTObj>();
CHECK(tuple != nullptr)
<< "Object is not data type object, register " << instr.object << ", Object tag "
<< object->type_index();
}
case Opcode::GetTag: {
auto object = ReadRegister(instr.get_tag.object);
- const auto* data = object.as<DatatypeObj>();
+ const auto* data = object.as<ADTObj>();
CHECK(data != nullptr)
<< "Object is not data type object, register "
<< instr.get_tag.object << ", Object tag "
pc++;
goto main_loop;
}
- case Opcode::AllocDatatype: {
+ case Opcode::AllocADT: {
std::vector<ObjectRef> fields;
for (Index i = 0; i < instr.num_fields; ++i) {
fields.push_back(ReadRegister(instr.datatype_fields[i]));
}
- ObjectRef obj = Datatype(instr.constructor_tag, fields);
+ ObjectRef obj = ADT(instr.constructor_tag, fields);
WriteRegister(instr.dst, obj);
pc++;
goto main_loop;
def vmobj_to_list(o):
if isinstance(o, tvm.relay.backend.vmobj.Tensor):
return [o.asnumpy().tolist()]
- elif isinstance(o, tvm.relay.backend.vmobj.Datatype):
+ elif isinstance(o, tvm.relay.backend.vmobj.ADT):
result = []
for f in o:
result.extend(vmobj_to_list(f))
return [o.asnumpy().tolist()]
elif isinstance(o, tvm.relay.backend.interpreter.TensorValue):
return [o.asnumpy()]
- elif isinstance(o, tvm.relay.backend.vmobj.Datatype):
+ elif isinstance(o, tvm.relay.backend.vmobj.ADT):
result = []
for f in o:
result.extend(vmobj_to_list(f))
def vmobj_to_list(o):
if isinstance(o, tvm.relay.backend.vm.Tensor):
return [o.asnumpy().tolist()]
- elif isinstance(o, tvm.relay.backend.vm.Datatype):
+ elif isinstance(o, tvm.relay.backend.vm.ADT):
result = []
for f in o:
result.extend(vmobj_to_list(f))
assert isinstance(x.data, tvm.nd.NDArray)
-def test_datatype():
+def test_adt():
arr = tvm.nd.array([1,2,3])
x = vm.Tensor(arr)
- y = vm.Datatype(0, [x, x])
+ y = vm.ADT(0, [x, x])
assert len(y) == 2
- assert isinstance(y, vm.Datatype)
+ assert isinstance(y, vm.ADT)
y[0:1][-1].data == x.data
assert y.tag == 0
assert isinstance(x.data, tvm.nd.NDArray)
if __name__ == "__main__":
test_tensor()
- test_datatype()
+ test_adt()