Hi @kparzysz ,
Sorry to hear that there was downstream failure because of #8509 .
kparzysz:
Constants that are not parameters cannot have type float16, because that type is not supported by current TIR code (for embedded constants). If this extraction doesn’t happen, compilation will abort if a float16 constant is found in TIR.
I am also wondering how this is true, because of the following (note that we just used what was supported in TVM via LinkedParam node) :
case runtime::DataType::TypeCode::kFloat:
switch (arr_type.bits()) {
case 16:
// NOTE: float16 is treated as uint16_t.
element_type = llvm::Type::getIntNTy(*ctx, arr_type.bits());
BuildLLVMVector<uint16_t>(element_type, arr->data, num_elements, &elements);
break;
case 32:
element_type = llvm::Type::getFloatTy(*ctx);
BuildLLVMVector<float>(element_type, arr->data, num_elements, &elements);
break;
case 64:
element_type = llvm::Type::getDoubleTy(*ctx);
BuildLLVMVector<double>(element_type, arr->data, num_elements, &elements);
break;
default:
CHECK(false) << "CodegenParams: only support 32- or 64-bit floating point; saw "
<< arr_type.bits() << "-bit array";
break;
}
break;
case runtime::DataType::TypeCode::kFloat: {
os.fill(' ');
os.setf(std::ios::left, std::ios::adjustfield);
if (arr_type.bits() == 16) {
// NOTE: print types not widely supported by C as uint16_t.
PrintIntegralArray<uint16_t>(arr->data, num_elements, indent_chars, os);
} else if (arr_type.bits() == 32) {
PrintFloatingPointArray<float>(arr->data, num_elements, indent_chars, os);
} else if (arr_type.bits() == 64) {
PrintFloatingPointArray<double>(arr->data, num_elements, indent_chars, os);
} else {
CHECK(false) << "CodegenParams: only support 32- or 64-bit floating point; saw "
<< arr_type.bits() << "-bit array";
}
break;
}
The above are called respectively in the following locations :
builder_->CreateCondBr(cond, then_block, end_block, md_very_likely_branch_);
builder_->SetInsertPoint(then_block);
this->VisitStmt(op->then_case);
builder_->CreateBr(end_block);
}
builder_->SetInsertPoint(end_block);
}
void CodeGenLLVM::VisitStmt_(const AllocateConstNode* op) {
auto data = op->data.value();
auto array = NDArrayToLLVMArray(ctx_, data);
std::string symbol_name = op->buffer_var->name_hint;
llvm::GlobalVariable* param_symbol = new llvm::GlobalVariable(
*module_, array->getType(), true, llvm::GlobalValue::InternalLinkage, array, symbol_name);
var_map_[op->buffer_var.operator->()] = param_symbol;
this->VisitStmt(op->body);
}
void CodeGenLLVM::VisitStmt_(const AllocateNode* op) {
ICHECK(!is_zero(op->condition));
<< "extern \"C\" {\n"
<< "#endif\n"
<< "static const ";
PrintType(data.DataType(), decl_stream);
// Allocate the global static variable
decl_stream << " __attribute__((section(\".rodata.tvm\"), "
<< "aligned(" << constants_byte_alignment_->value << "))) " << symbol_name << "["
<< num_elements << "] = {\n";
NDArrayDataToC(data, 4, decl_stream);
decl_stream << "};\n"
<< "#ifdef __cplusplus\n"
<< "} // extern \"C\"\n"
<< "#endif\n";
var_idmap_[op->buffer_var.operator->()] = symbol_name;
this->PrintStmt(op->body);
}
void CodeGenC::VisitExpr_(const LoadNode* op, std::ostream& os) { // NOLINT(*)
kparzysz:
This can be, at least in theory, overridden by pass context flag relay.FuseOps.link_params
, but there is an issue.
We need to fix this if it is not happenning. @kparzysz would you be able to file an issue ?
attn : @dmitriy-arm @Mousius
I think we need to move the link-params to be a property of the TIR backend (i.e. target).
However, the above seems to be the workaround of the issue, the real issue I suspect is hexagon backend expect LinkedParams node if --link-params is used, however, there is not a unit test (a simple codegen one) to assert this – that should have been broken by #8509 .