Skip to content

Conversation

@tgravescs
Copy link
Contributor

What changes were proposed in this pull request?

Add in GPU and generic resource type allocation to the executors.

Note this is part of a bigger feature for gpu-aware scheduling and is just how the executor find the resources. The general flow :

  • users ask for a certain set of resources, for instance number of gpus - each cluster manager has a specific way to do this.
  • cluster manager allocates a container or set of resources (standalone mode)
  • When spark launches the executor in that container, the executor either has to be told what resources it has or it has to auto discover them.
  • Executor has to register with Driver and tell the driver the set of resources it has so the scheduler can use that to schedule tasks that requires a certain amount of each of those resources

In this pr I added configs and arguments to the executor to be able discover resources. The argument to the executor is intended to be used by standalone mode or other cluster managers that don't have isolation so that it can assign specific resources to specific executors in case there are multiple executors on a node. The argument is a file contains JSON Array of ResourceInformation objects.

The discovery script is meant to be used in an isolated environment where the executor only sees the resources it should use.

Note that there will be follow on PRs to add other parts like the scheduler part. See the epic high level jira: https://issues.apache.org/jira/browse/SPARK-24615

How was this patch tested?

Added unit tests and manually tested.

Please review http://spark.apache.org/contributing.html before opening a pull request.

@tgravescs tgravescs changed the title Gpu sched executor cl[SPARK-27024] Executor interface for cluster managers to support GPU and other resourcesean [SPARK-27024] Executor interface for cluster managers to support GPU and other resourcesean Apr 18, 2019
@SparkQA
Copy link

SparkQA commented Apr 18, 2019

Test build #104710 has finished for PR 24406 at commit abff33f.

  • This patch fails PySpark unit tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@tgravescs
Copy link
Contributor Author

test failure looks unrelated going to kick again

@tgravescs
Copy link
Contributor Author

Jenkins, test this please

@SparkQA
Copy link

SparkQA commented Apr 18, 2019

Test build #104715 has finished for PR 24406 at commit abff33f.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@felixcheung felixcheung changed the title [SPARK-27024] Executor interface for cluster managers to support GPU and other resourcesean [SPARK-27024] Executor interface for cluster managers to support GPU and other resources Apr 20, 2019
@tgravescs
Copy link
Contributor Author

@squito @srowen @mengxr @jiangxb1987 if anyone has time

Copy link
Member

@srowen srowen left a comment

Choose a reason for hiding this comment

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

Just some more style comments to start plus question about units

@tgravescs
Copy link
Contributor Author

Thanks for the comments, at spark summit so will likely update next week.

@SparkQA
Copy link

SparkQA commented Apr 30, 2019

Test build #105035 has finished for PR 24406 at commit e90582a.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@SparkQA
Copy link

SparkQA commented May 1, 2019

Test build #105056 has finished for PR 24406 at commit c07b405.

  • This patch fails Scala style tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@SparkQA
Copy link

SparkQA commented May 1, 2019

Test build #105057 has finished for PR 24406 at commit 01f97c8.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

Copy link
Contributor

@jiangxb1987 jiangxb1987 left a comment

Choose a reason for hiding this comment

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

Looks very good, only some nits.

@jiangxb1987
Copy link
Contributor

To clarify, will the driver side resource discovery being added in a separated following PR?

@tgravescs
Copy link
Contributor Author

The driver resource discovery will be done in separate PR

// check that script exists and try to execute
if (scriptFile.exists()) {
try {
val output = executeAndGetOutput(Seq(script.get), new File("."))
Copy link
Contributor

Choose a reason for hiding this comment

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

In standalone mode, worker needs to run the script provided by users. Could you leave a TODO inline?

// requirements (spark.task.resource.*) and that they match the executor configs
// specified by the user (spark.executor.resource.*) to catch mismatches between what
// the user requested and what resource manager gave or what the discovery script found.
private def checkExecResourcesMeetTaskRequirements(
Copy link
Contributor

Choose a reason for hiding this comment

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

We can have a general function works for both driver and executor. Essentially, the request is resourcePrefix -> count and the resource is resourcePrefix -> addresses. If they don't match, we just include resourcePrefix in the error message, which is clear to users whether it is driver or executor.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I don't completely follow what you are asking for here. We are comparing 3 things
spark.task.resource.* -> count with spark.executor.resource.* -> count and with the actual found in the script or pass in which is a Map[resourceName, ResourceInformation]. You can't have the resourceprefix on the type else it won't compare properly to the Map[resourceName]

I can certainly make it more generic to handle both executor and driver and I made some code changes to go that way but I would prefer to wait til the jira that implements the Driver side to finish that to make sure we don't need anything else. This function will likely have to move somewhere anyway.

Copy link
Contributor

@squito squito left a comment

Choose a reason for hiding this comment

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

I just took a brief look, but seems reasonable.

If the script fails, the user would have to get the logs of this executor to try to figure out what went wrong, right? That's OK, I guess, just checking on the error behavior

@tgravescs
Copy link
Contributor Author

Yes if the script fails its only in the executor logs

@tgravescs
Copy link
Contributor Author

@mengxr I'm not sure if its a github issues or what but your comment on standalone wouldn't let me comment from this page, I had to go into the changes page, so please go there to see my response. I can add something there but not exactly sure what you were asking for

@tgravescs
Copy link
Contributor Author

upmerging to the latest to fix the merge conflict

@SparkQA
Copy link

SparkQA commented May 10, 2019

Test build #105323 has finished for PR 24406 at commit dbb61fb.

  • This patch fails Spark unit tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@SparkQA
Copy link

SparkQA commented May 10, 2019

Test build #105322 has finished for PR 24406 at commit 4165c60.

  • This patch fails Spark unit tests.
  • This patch does not merge cleanly.
  • This patch adds no public classes.

@tgravescs
Copy link
Contributor Author

Ok to test

@tgravescs
Copy link
Contributor Author

Test this please

@tgravescs
Copy link
Contributor Author

Jenkins, test this please

@SparkQA
Copy link

SparkQA commented May 11, 2019

Test build #105330 has finished for PR 24406 at commit dbb61fb.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

// check that script exists and try to execute
if (scriptFile.exists()) {
try {
val output = executeAndGetOutput(Seq(script.get), new File("."))
Copy link
Contributor

Choose a reason for hiding this comment

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

nvm, I was thinking about users might be able to let manager/executor run arbitrary scripts.


test("Resource discoverer multiple gpus") {
val sparkconf = new SparkConf
assume(!(Utils.isWindows))
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't know what happens if user tries to run the test on Windows. Does it fail or silently skip? I don't have a Windows machine to verify. But if other tests are doing this, we might just follow.

@mengxr
Copy link
Contributor

mengxr commented May 13, 2019

LGTM. cc: @srowen @squito @jiangxb1987

@SparkQA
Copy link

SparkQA commented May 13, 2019

Test build #105363 has finished for PR 24406 at commit dd60e42.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

Copy link
Contributor

@jiangxb1987 jiangxb1987 left a comment

Choose a reason for hiding this comment

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

LGTM

// requirements and that they match the configs specified by the user to catch
// mismatches between what the user requested and what resource manager gave or
// what the discovery script found.
private def checkResourcesMeetRequirements(
Copy link
Contributor

@mengxr mengxr May 14, 2019

Choose a reason for hiding this comment

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

Had an offline discussion with @WeichenXu123 . He suggested refactoring this check to make it easier to read. Now the arguments are:

  • reqResourcesAndCounts: request per task (not per executor)
  • actualResources: resources allocated per executor

It is not easy to tell from the variable names and hence make the code harder to read. Basically we need the following:

  1. number allocated per executor cannot be smaller than requested count for each resource name
  2. requested count for executor cannot be smaller than requested count for task for each resource name. Note that this doesn't require resource discovery.
  3. the set of requested resource names for executors should match the set of requested resource names for tasks.

It would be nice to refactor the method into those three. We can also do it in a follow-up PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I added a comment to the driver jira since it needs to be refactored for that anyway:
https://issues.apache.org/jira/browse/SPARK-27488

@SparkQA
Copy link

SparkQA commented May 14, 2019

Test build #105372 has finished for PR 24406 at commit b9dacef.

  • This patch passes all tests.
  • This patch merges cleanly.
  • This patch adds no public classes.

@tgravescs
Copy link
Contributor Author

I merged this, thanks for the reviews.

@asfgit asfgit closed this in db2e3c4 May 14, 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

Successfully merging this pull request may close these issues.

7 participants