Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
doku:jupyterhub:dask [2022/08/24 07:32] – katrin | doku:jupyterhub:dask [2023/05/10 09:43] (current) – katrin | ||
---|---|---|---|
Line 1: | Line 1: | ||
====== Dask on JupyterHub ====== | ====== Dask on JupyterHub ====== | ||
- | We have a prepared | + | ===== Profile & Environment ===== |
+ | |||
+ | The VSC JupyterHub already provides | ||
{{: | {{: | ||
- | To properly use dask from the jupyterhub conda environment use the following | + | Since we run updates in regular intervals the exact name may vary. |
+ | |||
+ | At the time of writing the most current name was '' | ||
+ | |||
+ | |||
+ | ===== Python Example ===== | ||
+ | |||
+ | To properly use dask from the jupyterhub conda environment use the following | ||
<code python> | <code python> | ||
+ | ########################################################################## | ||
+ | # if you are running on a shared node it is important to setup some dask variables | ||
+ | # to not prevent interfering with other users dask setups (e.g. dashboard port ...) | ||
+ | |||
+ | import os | ||
import dask | import dask | ||
+ | import dask.config | ||
import dask.distributed | import dask.distributed | ||
- | import | + | USER = os.environ.get(' |
+ | if USER.startswith(' | ||
+ | user_number = int(USER.replace(' | ||
+ | else: | ||
+ | user_number = hash(USER) % 100 | ||
+ | print(' | ||
+ | |||
+ | DASHBOARD_PORT = 45000 + user_number | ||
+ | SCHEDULER_PORT = 46000 + user_number | ||
+ | ########################################################################### | ||
- | DASHBOARD_PORT | + | print(' |
+ | print(' | ||
- | user = os.environ.get(' | + | dask.config.set({'temporary_directory': |
+ | print(' | ||
- | dask.config.set({' | + | dask.config.set({' |
- | dask.config.get(' | + | print(' |
+ | </ | ||
+ | <box 80% round blue|Info> | ||
+ | |||
+ | For a complete and up 2 date list of configuration parameters have a look at the dask documentation: | ||
+ | |||
+ | <code python> | ||
from dask_jobqueue import SLURMCluster | from dask_jobqueue import SLURMCluster | ||
- | cluster = SLURMCluster(queue=' | + | cluster = SLURMCluster(queue=' |
- | project='sysadmin', | + | #account='p70824', |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | ' | + | |
- | job_extra=['--qos=" | + | ' |
- | header_skip=['-n 1']) # omit this line from the generated | + | ' |
- | print(cluster.job_script()) | + | ' |
+ | }, | ||
+ | # if you use adaptive scaling you might want to set these as well | ||
+ | # see https:// | ||
+ | # | ||
+ | # | ||
+ | # | ||
+ | #], | ||
+ | job_directives_skip=[ | ||
+ | '-J dask-worker', | ||
+ | ], | ||
+ | | ||
+ | | ||
+ | ' | ||
+ | #' | ||
+ | ]) | ||
- | cluster.scale(jobs=1) # jobs here means how many slurm worker jobs we will get | + | # the settings from above are turned into a slurm job script that can be |
+ | # displayed for debugging by using the ' | ||
+ | print(cluster.job_script()) | ||
+ | </ | ||
- | cluster.get_logs() | + | After running |
+ | < | ||
+ | $ squeue -u $USER | ||
+ | </ | ||
+ | |||
+ | The next step we need to take is now to scale up the cluster to get some worker processes running. In dask there are two options available: | ||
+ | - '' | ||
+ | - '' | ||
+ | |||
+ | Since they are scheduled via SLURM it depends heavily on your resource settings from earlier how long it will take to get them scheduled and be in a running state. | ||
+ | |||
+ | <code python> | ||
+ | # use ' | ||
+ | cluster.scale(jobs=1) | ||
+ | |||
+ | # OR use ' | ||
+ | # | ||
+ | |||
+ | # call the ' | ||
+ | cluster.get_logs() | ||
+ | </ | ||
+ | |||
+ | After executing the above code using '' | ||
+ | < | ||
+ | $ squeue -u $USER | ||
+ | | ||
+ | 475376 | ||
+ | </ | ||
+ | |||
+ | The next step is important: here we create a dask distributed client that uses the cluster instance. | ||
+ | |||
+ | From this point on all scheduled tasks will be sent to the cluster for execution | ||
+ | |||
+ | <code python> | ||
from dask.distributed import Client | from dask.distributed import Client | ||
- | client = Client(cluster) | + | client = Client(cluster) |
+ | </ | ||
- | # now schedule some work | + | After the slurm jobs with the worker processes are running we can finally |
+ | < | ||
import dask.array as da | import dask.array as da | ||
- | x = da.random.random((10_000,10_000,10), chunks=(1000, | + | x = da.random.random((1000, 1000, 10), chunks=(1000, |
- | y = da.random.random((10_000,10_000,10), chunks=(1000, | + | y = da.random.random((1000, 1000, 10), chunks=(1000, |
z = (da.arcsin(x) + da.arccos(y)).sum(axis=(1, | z = (da.arcsin(x) + da.arccos(y)).sum(axis=(1, | ||
z.compute() | z.compute() | ||
+ | </ | ||
- | cluster.close() | + | To cleanup resources one can close client & cluster |
+ | |||
+ | <code python> | ||
+ | client.close() | ||
+ | del client | ||
+ | cluster.close() | ||
+ | del cluster | ||
</ | </ | ||
- | Result: | + | Example of the dask ui in the JupyterHub |
{{: | {{: | ||