Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
144 changes: 144 additions & 0 deletions local/apcomp297r-cpu.yml.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
# Jupyter app user-facing configuration form file (default sub-app)

# This config file is both an actual configuration file for an actual sample
# application, and a starting point for configuring a new sub-app. To make a
# custom application launch for a course, make a copy of this file in this same
# folder ("local" folder under the repository root) and customize the form
# config to your liking. There are notes along the way to help you understand
# what options you can make configurable to users. See the docs page from Open
# OnDemand for more details:
# https://osc.github.io/ood-documentation/develop/how-tos/app-development/interactive/form.html
<%-
# Specify admin groups by the full name of the group in the production HKey environment.
adminGroups = [
"ondemand-admins-1025174" # HUIT OOD admin group, prod environment
]
# Specify course groups by Canvas course ID, which you can find in a url:
# canvas.harvard.edu/courses/000000
enabledGroups = [
# Cannot have multiple enabled groups if a spack installation in the course
# shared folder is in use. This is because the course installation uses the
# course shared folder, which is not accessible to users outside of that
# course.
"162018" #APCOMP 297R
]

def arrays_have_common_element(array1, array2)
# Use the `&` operator to get the intersection of the two arrays
# If the intersection is not empty, return true, otherwise false
!(array1 & array2).empty?
end

userGroups = OodSupport::User.new.groups.sort_by(&:id).map(&:name)
# First check if the user is in an admin group
if arrays_have_common_element(userGroups, adminGroups)
cluster="*"
else
# If the user is not in an admin group, check if they're in an authorized Canvas group
userCanvasGroups = userGroups.flat_map{ |str| str.scan(/^canvas(\d+)-\d+/) }.flatten

# Check if the groups that the user is in match any of the courses that should
# have access to this app.

if arrays_have_common_element(userCanvasGroups, enabledGroups)
cluster="*"
else
cluster="disable_this_app"
end
end
-%>
---

# Cluster will be set to either "*" (allowing the app to run on any cluster) or
# "disable_this_app", which will disable the app by only allowing it to run on
# a non-existant cluster.
cluster: "<%= cluster %>"

title: "Jupyter Lab - APCOMP 297R (CPU)"
description: |
This app is configured for CPU access for APCOMP 297R.

This app will launch a Jupyter Notebook server on one or more nodes. This
configuration uses [Spack](https://spack.io/) to load a
[Mamba](https://mamba.readthedocs.io/en/latest/index.html) environment to then load Jupyter Lab and was built for the course APCOMP 297R.
<br/><br/>
The app launches outside of a container, so it has access to slurm commands, but
since the app is running as a slurm job, the `srun` command will use the
resources of the current job, rather than starting a new job. That is, unless
you first run an `salloc` command to allocate a new interactive session.

# Do not cache the application form
# The intent is to revert to the default Number of CPUs and Hours each time.
cacheable: false

# Define attributes that are set up by this configuration. If an attribute is
# set up with a static value here, it will be assigned that value in the job,
# and will not appear in the form. If the attribute is configured with a widget
# and/or other options, and it is configured in the form section below, it will
# appear to users as a configurable option.
attributes:
# Canvas course ID, used to reference a course shared folder when a spack
# installation in the course shared folder is in use.
course: "162018" #APCOMP 297R

# Spack environment to activate, regardless of which Spack installation is in use.
spack: "mamba"

# mamba environment to activate from inside the Spack environment
mamba: "cs1090b-cpu" # Assuming this mamba environment is built and already created in the spack mamba environment
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.

Nice idea to reuse the cs1090b environments.


# Which queue to submit to. Usually `general` is the best choice, unless this
# app is configured for a specific EC2 instance type, like an instance type
# with GPU resources.
bc_queue: "general"

# How many times can you say environment before the word loses all meaning?
# In this case, this form option toggles between using the global Spack
# installation and a spack installation in the course shared folder. If the
# course has no intention of managing their own Spack environments, this can
# be hard-coded to "global".
environment: "global"


# How many GPU GRES resources to include in the job submission.
custom_num_gpus: 0

# How many CPU cores to include in the slurm job submission
custom_num_cores:
widget: "number_field"
label: "Number of CPUs"
value: 1
min: 1
max: 4
step: 1

# How long will the job run for? Configure min, max, and step to set limits
# on how long app sessions can run.
bc_num_hours:
value: 2
min: 1
max: 6 # 6 hours max
step: 1

# Any extra command line arguments to feed to the `jupyter notebook ...`
# command that launches the Jupyter notebook within the batch job
extra_jupyter_args: ""

# All of the attributes that make up the Dashboard form (in respective order),
# and made available to the submit configuration file and the template ERB
# files
#
# @note You typically do not need to modify this unless you want to add a new
# configurable value
# @note If an attribute listed below is hard-coded above in the `attributes`
# option, then it will not appear in the form page that the user sees in the
# Dashboard
form:
- course
- spack
- mamba
- environment
- bc_queue
- extra_jupyter_args
- bc_num_hours
- custom_num_cores
136 changes: 136 additions & 0 deletions local/apcomp297r-gpu.yml.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
# Jupyter app user-facing configuration form file (default sub-app)

# This config file is both an actual configuration file for an actual sample
# application, and a starting point for configuring a new sub-app. To make a
# custom application launch for a course, make a copy of this file in this same
# folder ("local" folder under the repository root) and customize the form
# config to your liking. There are notes along the way to help you understand
# what options you can make configurable to users. See the docs page from Open
# OnDemand for more details:
# https://osc.github.io/ood-documentation/develop/how-tos/app-development/interactive/form.html
<%-
# Specify admin groups by the full name of the group in the production HKey environment.
adminGroups = [
"ondemand-admins-1025174" # HUIT OOD admin group, prod environment
]
# Specify course groups by Canvas course ID, which you can find in a url:
# canvas.harvard.edu/courses/000000
enabledGroups = [
# Cannot have multiple enabled groups if a spack installation in the course
# shared folder is in use. This is because the course installation uses the
# course shared folder, which is not accessible to users outside of that
# course.
"162018" #APCOMP 297R
]

def arrays_have_common_element(array1, array2)
# Use the `&` operator to get the intersection of the two arrays
# If the intersection is not empty, return true, otherwise false
!(array1 & array2).empty?
end

userGroups = OodSupport::User.new.groups.sort_by(&:id).map(&:name)
# First check if the user is in an admin group
if arrays_have_common_element(userGroups, adminGroups)
cluster="*"
else
# If the user is not in an admin group, check if they're in an authorized Canvas group
userCanvasGroups = userGroups.flat_map{ |str| str.scan(/^canvas(\d+)-\d+/) }.flatten

# Check if the groups that the user is in match any of the courses that should
# have access to this app.

if arrays_have_common_element(userCanvasGroups, enabledGroups)
cluster="*"
else
cluster="disable_this_app"
end
end
-%>
---

# Cluster will be set to either "*" (allowing the app to run on any cluster) or
# "disable_this_app", which will disable the app by only allowing it to run on
# a non-existant cluster.
cluster: "<%= cluster %>"

title: "Jupyter Lab - APCOMP 297R (GPU)"
description: |
This app is configured for GPU access for APCOMP 297R.

This app will launch a Jupyter Notebook server on one or more nodes. This
configuration uses [Spack](https://spack.io/) to load a
[Mamba](https://mamba.readthedocs.io/en/latest/index.html) environment to then load Jupyter Lab and was built for the course BST 236.
<br/><br/>
The app launches outside of a container, so it has access to slurm commands, but
since the app is running as a slurm job, the `srun` command will use the
resources of the current job, rather than starting a new job. That is, unless
you first run an `salloc` command to allocate a new interactive session.

# Do not cache the application form
# The intent is to revert to the default Number of CPUs and Hours each time.
cacheable: false

# Define attributes that are set up by this configuration. If an attribute is
# set up with a static value here, it will be assigned that value in the job,
# and will not appear in the form. If the attribute is configured with a widget
# and/or other options, and it is configured in the form section below, it will
# appear to users as a configurable option.
attributes:
# Canvas course ID, used to reference a course shared folder when a spack
# installation in the course shared folder is in use.
course: "162018"

# Spack environment to activate, regardless of which Spack installation is in use.
spack: "mamba-gpu"

# mamba environment to activate from inside the Spack environment
mamba: "cs1090b-gpu"
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.

I was able to successfully launch the Jupyter Lab - APCOMP 297R (GPU) app in my sandbox apps from this branch and confirmed I was able to load tensorflow and see a GPU.

import tensorflow as tf
gpus = tf.config.list_physical_devices('GPU')
print(f"Detected GPUs: {gpus}")

Output:

Detected GPUs: [PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU')]


# Which queue to submit to. Usually `general` is the best choice, unless this
# app is configured for a specific EC2 instance type, like an instance type
# with GPU resources.
bc_queue: "gpu"

# How many times can you say environment before the word loses all meaning?
# In this case, this form option toggles between using the global Spack
# installation and a spack installation in the course shared folder. If the
# course has no intention of managing their own Spack environments, this can
# be hard-coded to "global".
environment: "global"


# How many CPU cores to include in the slurm job submission
custom_num_cores: 8 # For Stage Testing: 8, For Production: 12
# How many GPU GRES resources to include in the job submission.
custom_num_gpus: 1

bc_num_hours:
value: 2
min: 1
max: 6 # 6 hours max
step: 1

# Any extra command line arguments to feed to the `jupyter notebook ...`
# command that launches the Jupyter notebook within the batch job
extra_jupyter_args: ""

# All of the attributes that make up the Dashboard form (in respective order),
# and made available to the submit configuration file and the template ERB
# files
#
# @note You typically do not need to modify this unless you want to add a new
# configurable value
# @note If an attribute listed below is hard-coded above in the `attributes`
# option, then it will not appear in the form page that the user sees in the
# Dashboard
form:
- course
- spack
- mamba
- environment
- bc_queue
- extra_jupyter_args
- bc_num_hours
- custom_num_cores
- custom_num_gpus