forked from ray-project/ray
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Doc] Revamp ray core design patterns doc [13/n]: nested tasks (ray-p…
…roject#29342) - Edit pass: make the patter generic for nested tasks instead of just recursive tasks. - Move the code to doc_code Signed-off-by: Jiajun Yao <[email protected]> Signed-off-by: Stephanie Wang <[email protected]> Co-authored-by: Stephanie Wang <[email protected]> Signed-off-by: Weichen Xu <[email protected]>
- Loading branch information
1 parent
7783213
commit c310bb8
Showing
7 changed files
with
109 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
# __pattern_start__ | ||
import ray | ||
import time | ||
from numpy import random | ||
|
||
|
||
def partition(collection): | ||
# Use the last element as the pivot | ||
pivot = collection.pop() | ||
greater, lesser = [], [] | ||
for element in collection: | ||
if element > pivot: | ||
greater.append(element) | ||
else: | ||
lesser.append(element) | ||
return lesser, pivot, greater | ||
|
||
|
||
def quick_sort(collection): | ||
if len(collection) <= 200000: # magic number | ||
return sorted(collection) | ||
else: | ||
lesser, pivot, greater = partition(collection) | ||
lesser = quick_sort(lesser) | ||
greater = quick_sort(greater) | ||
return lesser + [pivot] + greater | ||
|
||
|
||
@ray.remote | ||
def quick_sort_distributed(collection): | ||
# Tiny tasks are an antipattern. | ||
# Thus, in our example we have a "magic number" to | ||
# toggle when distributed recursion should be used vs | ||
# when the sorting should be done in place. The rule | ||
# of thumb is that the duration of an individual task | ||
# should be at least 1 second. | ||
if len(collection) <= 200000: # magic number | ||
return sorted(collection) | ||
else: | ||
lesser, pivot, greater = partition(collection) | ||
lesser = quick_sort_distributed.remote(lesser) | ||
greater = quick_sort_distributed.remote(greater) | ||
return ray.get(lesser) + [pivot] + ray.get(greater) | ||
|
||
|
||
for size in [200000, 4000000, 8000000]: | ||
print(f"Array size: {size}") | ||
unsorted = random.randint(1000000, size=(size)).tolist() | ||
s = time.time() | ||
quick_sort(unsorted) | ||
print(f"Sequential execution: {(time.time() - s):.3f}") | ||
s = time.time() | ||
ray.get(quick_sort_distributed.remote(unsorted)) | ||
print(f"Distributed execution: {(time.time() - s):.3f}") | ||
print("--" * 10) | ||
|
||
# Outputs: | ||
|
||
# Array size: 200000 | ||
# Sequential execution: 0.040 | ||
# Distributed execution: 0.152 | ||
# -------------------- | ||
# Array size: 4000000 | ||
# Sequential execution: 6.161 | ||
# Distributed execution: 5.779 | ||
# -------------------- | ||
# Array size: 8000000 | ||
# Sequential execution: 15.459 | ||
# Distributed execution: 11.282 | ||
# -------------------- | ||
|
||
# __pattern_end__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
.. _task-pattern-nested-tasks: | ||
|
||
Pattern: Using nested tasks to achieve nested parallelism | ||
========================================================= | ||
|
||
In this pattern, a remote task can dynamically call other remote tasks (including itself) for nested parallelism. | ||
This is useful when sub-tasks can be parallelized. | ||
|
||
Keep in mind, though, that nested tasks come with their own cost: extra worker processes, scheduling overhead, bookkeeping overhead, etc. | ||
To achieve speedup with nested parallelism, make sure each of your nested tasks does significant work. See :doc:`too-fine-grained-tasks` for more details. | ||
|
||
Example use case | ||
---------------- | ||
|
||
You want to quick-sort a large list of numbers. | ||
By using nested tasks, we can sort the list in a distributed and parallel fashion. | ||
|
||
.. figure:: ../images/tree-of-tasks.svg | ||
|
||
Tree of tasks | ||
|
||
|
||
Code example | ||
------------ | ||
|
||
.. literalinclude:: ../doc_code/pattern_nested_tasks.py | ||
:language: python | ||
:start-after: __pattern_start__ | ||
:end-before: __pattern_end__ | ||
|
||
We call :ref:`ray.get() <ray-get-ref>` after both ``quick_sort_distributed`` function invocations take place. | ||
This allows you to maximize parallelism in the workload. See :doc:`ray-get-loop` for more details. | ||
|
||
Notice in the execution times above that with smaller tasks, the non-distributed version is faster. However, as the task execution | ||
time increases, i.e. because the lists to sort are larger, the distributed version is faster. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.