Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ class AllVeloxConfiguration extends AnyFunSuite {
s"""
|## Gluten Velox backend configurations
|
| Key | Default | Description
| --- | --- | ---
| Key | Status | Default | Description
| --- | --- | --- | ---
|"""

VeloxConfig.allEntries
Expand All @@ -53,16 +53,20 @@ class AllVeloxConfiguration extends AnyFunSuite {
.foreach {
entry =>
val dft = entry.defaultValueString.replace("<", "&lt;").replace(">", "&gt;")
builder += Seq(s"${entry.key}", s"$dft", s"${entry.doc}")
builder += Seq(
s"${entry.key}",
AllGlutenConfiguration.configStatus(entry),
s"$dft",
s"${entry.doc}")
.mkString("|")
}

builder ++=
s"""
|## Gluten Velox backend *experimental* configurations
|
| Key | Default | Description
| --- | --- | ---
| Key | Status | Default | Description
| --- | --- | --- | ---
|"""

VeloxConfig.allEntries
Expand All @@ -72,7 +76,11 @@ class AllVeloxConfiguration extends AnyFunSuite {
.foreach {
entry =>
val dft = entry.defaultValueString.replace("<", "&lt;").replace(">", "&gt;")
builder += Seq(s"${entry.key}", s"$dft", s"${entry.doc}")
builder += Seq(
s"${entry.key}",
AllGlutenConfiguration.configStatus(entry),
s"$dft",
s"${entry.doc}")
.mkString("|")
}

Expand Down
286 changes: 143 additions & 143 deletions docs/Configuration.md

Large diffs are not rendered by default.

156 changes: 78 additions & 78 deletions docs/velox-configuration.md

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,35 @@ trait ConfigRegistry {
require(existing.isEmpty, s"Config entry ${entry.key} already registered!")
}

private def registerToSQLConf(entry: ConfigEntry[_], isStatic: Boolean): Unit = {
(entry.key :: entry.alternatives).foreach(registerToSQLConf(entry, _, isStatic))
}

private def registerToSQLConf(entry: ConfigEntry[_], key: String, isStatic: Boolean): Unit = {
var builder =
if (isStatic) SQLConf.buildStaticConf(key) else SQLConf.buildConf(key)
if (entry.doc.nonEmpty) {
builder = builder.doc(entry.doc)
}
if (entry.version.nonEmpty) {
builder = builder.version(entry.version)
}
if (!entry.isPublic) {
builder = builder.internal()
}

val sparkEntry = builder.stringConf.transform {
value =>
entry.valueConverter(value)
value
}
if (entry.defaultValue.isDefined) {
sparkEntry.createWithDefaultString(entry.defaultValueString)
} else {
sparkEntry.createOptional
}
}

/** Visible for testing. */
private[config] def allEntries: Seq[ConfigEntry[_]] = {
configEntries.values.toSeq
Expand All @@ -38,15 +67,16 @@ trait ConfigRegistry {
ConfigBuilder(key).onCreate {
entry =>
register(entry)
registerToSQLConf(entry, isStatic = false)
ConfigRegistry.registerToAllEntries(entry)
}
}

protected def buildStaticConf(key: String): ConfigBuilder = {
ConfigBuilder(key).onCreate {
entry =>
SQLConf.registerStaticConfigKey(key)
register(entry)
registerToSQLConf(entry, isStatic = true)
ConfigRegistry.registerToAllEntries(entry)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ package org.apache.gluten.config

import org.apache.spark.internal.Logging
import org.apache.spark.network.util.ByteUnit
import org.apache.spark.sql.SparkSession
import org.apache.spark.sql.internal.{SQLConf, SQLConfProvider}

class GlutenCoreConfig(conf: SQLConf) extends Logging {
Expand Down Expand Up @@ -62,7 +63,14 @@ class GlutenCoreConfig(conf: SQLConf) extends Logging {
*/
object GlutenCoreConfig extends ConfigRegistry {
override def get: GlutenCoreConfig = {
new GlutenCoreConfig(SQLConf.get)
new GlutenCoreConfig(activeSQLConf)
}

private[gluten] def activeSQLConf: SQLConf = {
SparkSession.getActiveSession
.filterNot(_.sparkContext.isStopped)
.map(_.sessionState.conf)
.getOrElse(SQLConf.get)
}

val SPARK_OFFHEAP_SIZE_KEY = "spark.memory.offHeap.size"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -462,7 +462,7 @@ object GlutenConfig extends ConfigRegistry {
val SPARK_MAX_BROADCAST_TABLE_SIZE = "spark.sql.maxBroadcastTableSize"

def get: GlutenConfig = {
new GlutenConfig(SQLConf.get)
new GlutenConfig(GlutenCoreConfig.activeSQLConf)
}

def prefixOf(backendName: String): String = s"spark.gluten.sql.columnar.backend.$backendName"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
package org.apache.gluten.config

import org.apache.spark.sql.internal.SQLConf

import org.scalactic.Prettifier
import org.scalactic.source.Position
import org.scalatest.Assertions._
Expand Down Expand Up @@ -67,44 +69,53 @@ class AllGlutenConfiguration extends AnyFunSuite {
s"""
|## Spark base configurations for Gluten plugin
|
| Key | Recommend Setting | Description
| --- | --- | ---
| Key | Status | Recommend Setting | Description
| --- | --- | --- | ---
|"""

// scalastyle:off
builder += Seq(
"spark.plugins",
AllGlutenConfiguration.staticConfigStatus,
"org.apache.gluten.GlutenPlugin",
"To load Gluten's components by Spark's plug-in loader.").mkString("|")
builder += Seq(
"spark.memory.offHeap.enabled",
AllGlutenConfiguration.staticConfigStatus,
"true",
"Gluten use off-heap memory for certain operations.").mkString("|")
builder += Seq(
"spark.memory.offHeap.size",
AllGlutenConfiguration.staticConfigStatus,
"30G",
"The absolute amount of memory which can be used for off-heap allocation, in bytes unless otherwise specified.<br /> Note: Gluten Plugin will leverage this setting to allocate memory space for native usage even offHeap is disabled. <br /> The value is based on your system and it is recommended to set it larger if you are facing Out of Memory issue in Gluten Plugin."
).mkString("|")
builder += Seq(
"spark.shuffle.manager",
AllGlutenConfiguration.staticConfigStatus,
"org.apache.spark.shuffle.sort.ColumnarShuffleManager",
"To turn on Gluten Columnar Shuffle Plugin.").mkString("|")
"To turn on Gluten Columnar Shuffle Plugin."
).mkString("|")
builder += Seq(
"spark.driver.extraClassPath",
AllGlutenConfiguration.staticConfigStatus,
"/path/to/gluten_jar_file",
"Gluten Plugin jar file to prepend to the classpath of the driver.").mkString("|")
"Gluten Plugin jar file to prepend to the classpath of the driver."
).mkString("|")
builder += Seq(
"spark.executor.extraClassPath",
AllGlutenConfiguration.staticConfigStatus,
"/path/to/gluten_jar_file",
"Gluten Plugin jar file to prepend to the classpath of executors.").mkString("|")
"Gluten Plugin jar file to prepend to the classpath of executors."
).mkString("|")
// scalastyle:on

builder ++=
s"""
|## Gluten configurations
|
| Key | Default | Description
| --- | --- | ---
| Key | Status | Default | Description
| --- | --- | --- | ---
|"""

val allEntries = GlutenConfig.allEntries ++ GlutenCoreConfig.allEntries
Expand All @@ -116,16 +127,20 @@ class AllGlutenConfiguration extends AnyFunSuite {
.foreach {
entry =>
val dft = entry.defaultValueString.replace("<", "&lt;").replace(">", "&gt;")
builder += Seq(s"${entry.key}", s"$dft", s"${entry.doc}")
builder += Seq(
s"${entry.key}",
AllGlutenConfiguration.configStatus(entry),
s"$dft",
s"${entry.doc}")
.mkString("|")
}

builder ++=
s"""
|## Gluten *experimental* configurations
|
| Key | Default | Description
| --- | --- | ---
| Key | Status | Default | Description
| --- | --- | --- | ---
|"""

allEntries
Expand All @@ -135,7 +150,11 @@ class AllGlutenConfiguration extends AnyFunSuite {
.foreach {
entry =>
val dft = entry.defaultValueString.replace("<", "&lt;").replace(">", "&gt;")
builder += Seq(s"${entry.key}", s"$dft", s"${entry.doc}")
builder += Seq(
s"${entry.key}",
AllGlutenConfiguration.configStatus(entry),
s"$dft",
s"${entry.doc}")
.mkString("|")
}

Expand All @@ -147,6 +166,16 @@ class AllGlutenConfiguration extends AnyFunSuite {
}

object AllGlutenConfiguration {
private val Anchor = Character.toString(0x2693)
private val CounterclockwiseArrows = new String(Character.toChars(0x1f504))

val staticConfigStatus: String = s"$Anchor Static"
val dynamicConfigStatus: String = s"$CounterclockwiseArrows Dynamic"

def configStatus(entry: ConfigEntry[_]): String = {
if (SQLConf.isStaticConfigKey(entry.key)) staticConfigStatus else dynamicConfigStatus
}

def isRegenerateGoldenFiles: Boolean = sys.env.get("GLUTEN_UPDATE").contains("1")

def getCodeSourceLocation[T](clazz: Class[T]): String = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,26 @@
*/
package org.apache.spark.sql

class GlutenRuntimeConfigSuite extends RuntimeConfigSuite with GlutenTestsTrait {}
import org.apache.gluten.config.GlutenConfig

class GlutenRuntimeConfigSuite extends RuntimeConfigSuite with GlutenTestsTrait {
test("Gluten configs report correct runtime modifiability") {
val conf = SparkSession.active.conf
assert(conf.isModifiable(GlutenConfig.COLUMNAR_FILESCAN_ENABLED.key))
assert(!conf.isModifiable(GlutenConfig.GLUTEN_UI_ENABLED.key))
}

test("GlutenConfig reads active SparkSession runtime configs") {
val conf = SparkSession.active.conf
val key = GlutenConfig.COLUMNAR_FILESCAN_ENABLED.key
val original = conf.get(key)
try {
conf.set(key, false)
assert(!GlutenConfig.get.enableColumnarFileScan)
conf.set(key, true)
assert(GlutenConfig.get.enableColumnarFileScan)
} finally {
conf.set(key, original)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,37 @@ package org.apache.spark.sql.execution

import org.apache.spark.sql.GlutenSQLTestsBaseTrait

class GlutenSparkSqlParserSuite extends SparkSqlParserSuite with GlutenSQLTestsBaseTrait {}
import org.scalactic.source.Position
import org.scalatest.Tag

class GlutenSparkSqlParserSuite extends SparkSqlParserSuite with GlutenSQLTestsBaseTrait {
private var registerQuotedConfigParserTest = false

override protected def test(testName: String, testTags: Tag*)(testFun: => Any)(implicit
pos: Position): Unit = {
if (isConfigParserCoverage(testName) && !registerQuotedConfigParserTest) {
()
} else {
super.test(testName, testTags: _*)(testFun)(pos)
}
}

registerQuotedConfigParserTest = true
test("Checks if SET/RESET can parse all the configurations") {
sqlConf.getAllDefinedConfs.map(_._1).foreach {
key: String =>
val quotedKey = quoteConfigKey(key)
spark.sessionState.sqlParser.parsePlan(s"SET $quotedKey")
spark.sessionState.sqlParser.parsePlan(s"RESET $quotedKey")
}
}
registerQuotedConfigParserTest = false

private def isConfigParserCoverage(testName: String): Boolean = {
testName == "Checks if SET/RESET can parse all the configurations"
}

private def quoteConfigKey(key: String): String = {
s"`${key.replace("`", "``")}`"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,28 @@
*/
package org.apache.spark.sql

import org.apache.gluten.config.GlutenConfig

import org.apache.spark.sql.shim.GlutenTestsTrait

class GlutenRuntimeConfigSuite extends RuntimeConfigSuite with GlutenTestsTrait {}
class GlutenRuntimeConfigSuite extends RuntimeConfigSuite with GlutenTestsTrait {
test("Gluten configs report correct runtime modifiability") {
val conf = SparkSession.active.conf
assert(conf.isModifiable(GlutenConfig.COLUMNAR_FILESCAN_ENABLED.key))
assert(!conf.isModifiable(GlutenConfig.GLUTEN_UI_ENABLED.key))
}

test("GlutenConfig reads active SparkSession runtime configs") {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we move these two tests to a new test suite under gluten-ut/test? Generally, the spark{VERSION} folders are used for Spark's original tests and their version-specific variants.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @philo-he, moved these two Gluten-specific tests into a new shared suite under gluten-ut/test: org.apache.gluten.config.GlutenRuntimeConfigSuite.

I also restored the Spark 4.0 / 4.1 GlutenRuntimeConfigSuite files to only wrap Spark's original RuntimeConfigSuite.

val conf = SparkSession.active.conf
val key = GlutenConfig.COLUMNAR_FILESCAN_ENABLED.key
val original = conf.get(key)
try {
conf.set(key, false)
assert(!GlutenConfig.get.enableColumnarFileScan)
conf.set(key, true)
assert(GlutenConfig.get.enableColumnarFileScan)
} finally {
conf.set(key, original)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,37 @@ package org.apache.spark.sql.execution

import org.apache.spark.sql.GlutenSQLTestsBaseTrait

class GlutenSparkSqlParserSuite extends SparkSqlParserSuite with GlutenSQLTestsBaseTrait {}
import org.scalactic.source.Position
import org.scalatest.Tag

class GlutenSparkSqlParserSuite extends SparkSqlParserSuite with GlutenSQLTestsBaseTrait {
private var registerQuotedConfigParserTest = false

override protected def test(testName: String, testTags: Tag*)(testFun: => Any)(implicit
pos: Position): Unit = {
if (isConfigParserCoverage(testName) && !registerQuotedConfigParserTest) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this mean the original Spark test is excluded and replaced by the variant test? If so, can we just exclude it in VeloxTestSettings.scala and let the variant be tested instead?

testGluten("Checks if SET/RESET can parse all the configurations") {

}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @philo-he, addressed. I removed the custom test(...) override, excluded Spark's original Checks if SET/RESET can parse all the configurations case in VeloxTestSettings.scala, and registered the quoted-key coverage as a normal testGluten(...) variant.

()
} else {
super.test(testName, testTags: _*)(testFun)(pos)
}
}

registerQuotedConfigParserTest = true
test("Checks if SET/RESET can parse all the configurations") {
sqlConf.getAllDefinedConfs.map(_._1).foreach {
key: String =>
val quotedKey = quoteConfigKey(key)
spark.sessionState.sqlParser.parsePlan(s"SET $quotedKey")
spark.sessionState.sqlParser.parsePlan(s"RESET $quotedKey")
}
}
registerQuotedConfigParserTest = false

private def isConfigParserCoverage(testName: String): Boolean = {
testName == "Checks if SET/RESET can parse all the configurations"
}

private def quoteConfigKey(key: String): String = {
s"`${key.replace("`", "``")}`"
}
}
Loading