Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[CODEGEN] Enhance OpenCL Generator to Support Conditional Generation that Preserves Type #2787

Closed
lixiaoquan opened this issue Mar 12, 2019 · 3 comments

Comments

@lixiaoquan
Copy link
Contributor

lixiaoquan commented Mar 12, 2019

This code (simplified) can't be built with both NV OpenCL and llvm. Error is "error: call to 'max' is ambiguous"

   uchar i = 0, j = 0;
   uchar t = max((uchar)j, ((i > 0) ? (uchar)1 : (uchar)0));

It seems the type of the ternary operator is not unchar.

My current workaround is to always add a conversion for uint8 before tvm::if_then_else, if you think it's OK, I'll send a PR.

diff --git a/tvm/src/codegen/codegen_c.cc b/tvm/src/codegen/codegen_c.cc
index 9b73e4e..3a5357a 100644
--- a/tvm/src/codegen/codegen_c.cc
+++ b/tvm/src/codegen/codegen_c.cc
@@ -524,6 +524,13 @@ void CodeGenC::VisitExpr_(const Call *op, std::ostream& os) {  // NOLINT(*)
   } else if (op->is_intrinsic(Call::shift_right)) {
     PrintBinaryIntrinsitc(op, " >> ", os, this);
   } else if (op->is_intrinsic(intrinsic::tvm_if_then_else)) {
+    // Workaround OpenCL compiler issue
+    // type of ternary expression in NV OpenCL compiler isn't same as type of true/false value
+    if (op->args[2].type() == UInt(8)) {
+      os << "(";
+      PrintType(UInt(8), os);
+      os << ")";
+    }
     os << "(";
     PrintExpr(op->args[0], os);
     os << " ? ";

@tqchen
Copy link
Member

tqchen commented Mar 12, 2019

Should we always convert then?

@lixiaoquan
Copy link
Contributor Author

It is in codegen_c, and I haven't found an easy way to distinguish between CUDA and OpenCL.

When the ternary operator is printed, we can't know whether it's a parameter of max().

And this issue should also apply to other functions like min().

Maybe we can override the handling of tvm::if_then_else in CodeGenOpenCL.

Is there any suggestion for an ideal solution?

@tqchen
Copy link
Member

tqchen commented Mar 12, 2019

yes an override is fine you can override codegen of call and then fallback to base

@tqchen tqchen changed the title OpenCL build error [CODEGEN] Enhance OpenCL Generator to Support Conditional Generation that Preserves Type Mar 15, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants