-
Notifications
You must be signed in to change notification settings - Fork 28.9k
[SPARK-23711][SQL] Add fallback generator for UnsafeProjection #21106
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
Conversation
|
cc @hvanhovell |
| import org.codehaus.commons.compiler.CompileException | ||
| import org.codehaus.janino.InternalCompilerException | ||
|
|
||
| object CodegenObjectFactory { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we make this an abstract class in which we just need to implement hooks for the code generated and interpreted versions, i.e.:
object CodegenError {
def unapply(throwable: Throwable): Option[Exception] = throwable match {
case e: InternalCompilerException => Some(e)
case e: CompileException => Some(e)
case _ => None
}
}
abstract class CodegenObjectFactory[IN, OUT] {
def create(in: IN): OUT = try createCodeGeneratedObject(in) catch {
case CodegenError(_) =>createInterpretedObject(in)
}
protected def createCodeGeneratedObject(in: IN): OUT
protected def createInterpretedObject(in: IN): OUT
}
object UnsafeProjectionCreator extends CodegenObjectFactory[Seq[Expression], UnsafeProjection] {
...
}There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good to me, except that I think UnsafeProjectionCreator should still support UnsafeProjectionCreator's APIs. So we can replace all usage of UnsafeProjection with UnsafeProjectionCreator.
|
Test build #89578 has finished for PR 21106 at commit
|
|
Test build #89603 has finished for PR 21106 at commit
|
|
retest this please. |
|
Test build #89604 has finished for PR 21106 at commit
|
|
retest this please. |
|
Test build #89615 has finished for PR 21106 at commit
|
|
@hvanhovell Any more comments on the current design? If not, I will apply this to all places that we create unsafe projection. |
|
Yeah, let's move forward slowly. I am still pondering about the what the right abstraction here would look like; this looks promising though. Can you try to unify this class with |
|
I think it's very hard to unify the entry point(input type) for all the code generators. E.g. some use I'd like to make |
|
I tried to unify this class with Without the trait For test, I think we still need to test codegen and interpreted unsafe projection implementations individually as |
|
I think How about we provide a sql conf for test only, to be able to disable the fallback(always codegen) or skip the codegen(always interpretation)? |
|
Test build #89882 has finished for PR 21106 at commit
|
|
A sql conf sounds good to me. @hvanhovell What do you think? |
|
@hvanhovell If you don't have other comment, I will follow @cloud-fan's suggestion to add a sql conf for it. Thanks. |
|
@hvanhovell @cloud-fan A SQL config was added to control codegen/interpreted for test. Please let me know if you have any comment on current approach. Thanks. |
|
Test build #90277 has finished for PR 21106 at commit
|
|
Test build #90278 has finished for PR 21106 at commit
|
| // Creates wanted object. First trying codegen implementation. If any compile error happens, | ||
| // fallbacks to interpreted version. | ||
| def createObject(in: IN): OUT = { | ||
| val fallbackMode = SQLConf.get.getConf(SQLConf.CODEGEN_OBJECT_FALLBACK) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can only access SQLConf on the driver. Now this causes test failure. We can't know this config value inside createObject which can be called on executors.
To solve this, UnsafeProjection can't be an object as now, but a case class with a fallback mode parameter. So we can create this factory on driver. @cloud-fan @hvanhovell WDYT?
|
Test build #90313 has finished for PR 21106 at commit
|
|
Test build #90319 has finished for PR 21106 at commit
|
| if (unsafeRow != expectedRow) { | ||
| fail("Incorrect evaluation in unsafe mode: " + | ||
| s"$expression, actual: $unsafeRow, expected: $expectedRow$input") | ||
| for (fallbackMode <- Seq("CODEGEN_ONLY", "NO_CODEGEN")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let's not hardcode it, call CodegenObjectFactoryMode.xxx instead
| f(UnsafeProjection) | ||
| f(InterpretedUnsafeProjection) | ||
| private def testBothCodegenAndInterpreted(name: String)(f: => Unit): Unit = { | ||
| for (fallbackMode <- Seq("CODEGEN_ONLY", "NO_CODEGEN")) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ditto
|
Test build #90725 has finished for PR 21106 at commit
|
|
Test build #90724 has finished for PR 21106 at commit
|
|
Test build #90776 has finished for PR 21106 at commit
|
|
retest this please. |
|
also cc @rednaxelafx |
|
Should this PR wait for #21299 so that accessing confs on executors can be made simpler? |
|
Test build #90783 has finished for PR 21106 at commit
|
|
@cloud-fan @rednaxelafx Accessing confs are now simpler. Please review this again. Thanks. |
|
Test build #90932 has finished for PR 21106 at commit
|
|
retest this please. |
|
Test build #90939 has finished for PR 21106 at commit
|
|
retest this please |
| private def testBothCodegenAndInterpreted(name: String)(f: => Unit): Unit = { | ||
| val modes = Seq(CodegenObjectFactoryMode.CODEGEN_ONLY, CodegenObjectFactoryMode.NO_CODEGEN) | ||
| for (fallbackMode <- modes) { | ||
| test(name + " with " + fallbackMode) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: s"$name with $fallbackMode"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok.
|
Test build #90947 has finished for PR 21106 at commit
|
|
Test build #90951 has finished for PR 21106 at commit
|
|
|
|
@cloud-fan Fixed. Thanks. |
|
Test build #90965 has finished for PR 21106 at commit
|
|
thanks, merging to master! |
What changes were proposed in this pull request?
Add fallback logic for
UnsafeProjection. In production we can try to create unsafe projection using codegen implementation. Once any compile error happens, it fallbacks to interpreted implementation.How was this patch tested?
Added test.