diff --git a/.gitignore b/.gitignore
index 6308795ca93308744c0904f57058f26b25296900..753768920bd24d092689aa597e5e0527cf1161bd 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,3 @@
 /tmp/
 /local
+._*
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 47dbeea27fc43dda758ef3131f73fc904797ec0c..35c56219b19764a366dd0c101a45de9493850beb 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,6 +5,9 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
 and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased]
+## [0.5.0]
+### Added
+- Added control to select number of CPUs
 
 ## [0.4.0]
 ### Added
@@ -52,7 +55,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
 ### Added
 - Initial release!
 
-[Unreleased]: https://github.com/OSC/bc_osc_matlab/compare/v0.4.0...HEAD
+[Unreleased]: https://github.com/OSC/bc_osc_matlab/compare/v0.5.0...HEAD
+[0.5.0]: https://github.com/OSC/bc_osc_matlab/compare/v0.4.0...v0.5.0
 [0.4.0]: https://github.com/OSC/bc_osc_matlab/compare/v0.3.0...v0.4.0
 [0.3.0]: https://github.com/OSC/bc_osc_matlab/compare/v0.2.0...v0.3.0
 [0.2.0]: https://github.com/OSC/bc_osc_matlab/compare/v0.1.0...v0.2.0
diff --git a/form.js b/form.js
new file mode 100644
index 0000000000000000000000000000000000000000..e074fd9297a7d5eb16f76e3a04e467d33fa0d71e
--- /dev/null
+++ b/form.js
@@ -0,0 +1,57 @@
+'use strict'
+
+/**
+ * Fix num cores
+ */
+function fix_num_cores() {
+  let node_type_input = $('#batch_connect_session_context_node_type');
+  let node_type = node_type_input.val();
+  let num_cores_input = $('#num_cores');
+  
+  if(node_type === ':hugemem') {
+    set_ppn_owens_hugemem(num_cores_input);
+  } else {
+    set_ppn_owens_regular(num_cores_input);
+  }
+}
+
+/**
+ * Sets the PPN limits available for Owens hugemem nodes.
+ * 
+ * hugemem reservations are always assigned the full node
+ *
+ * @param      {element}  num_cores_input  The input for num_cores
+ */
+function set_ppn_owens_hugemem(num_cores_input) {
+  const NUM_CORES = 48;
+  num_cores_input.attr('max', NUM_CORES);
+  num_cores_input.attr('min', NUM_CORES);
+  num_cores_input.val(NUM_CORES);
+}
+
+/**
+ * Sets the PPN limits available for non hugemem Owens nodes.
+ *
+ * @param      {element}  num_cores_input  The input for num_cores
+ */
+function set_ppn_owens_regular(num_cores_input) {
+  const NUM_CORES = 28;
+  num_cores_input.attr('max', NUM_CORES);
+  num_cores_input.attr('min', 1);
+  num_cores_input.val(Math.min(NUM_CORES, num_cores_input.val()));
+}
+
+
+/**
+ * Change the maximum number of cores selected.
+ */
+function set_node_type_change_handler() {
+  let node_type_input = $('#batch_connect_session_context_node_type');
+  node_type_input.change(node_type_input, fix_num_cores);
+}
+
+$(document).ready(function() {
+  // Set the max value to be what was set in the last session
+  fix_num_cores();
+  set_node_type_change_handler();
+});
\ No newline at end of file
diff --git a/form.yml b/form.yml
index 923aaee5a5d49296f4cc1fbb437f708cb13745fd..0d64dde70d95880f67de1e11db97ef20e26b2c9a 100644
--- a/form.yml
+++ b/form.yml
@@ -5,10 +5,22 @@ form:
   - bc_account
   - bc_num_hours
   - bc_num_slots
+  - num_cores
   - node_type
   - bc_vnc_resolution
   - bc_email_on_started
 attributes:
+  num_cores:
+    widget: "number_field"
+    label: "Number of cores"
+    value: 1
+    help: |
+      Number of cores on node type (4 GB per core unless requesting whole
+      node). Leave blank if requesting full node.
+    min: 1
+    max: 48
+    step: 1
+    id: 'num_cores'
   bc_num_slots: "1"
   bc_vnc_resolution:
     required: true
@@ -19,19 +31,19 @@ attributes:
     widget: select
     label: "Node type"
     help: |
-      - **any** - (*28 cores*) Use any available Owens node. This reduces the
+      - **any** - (*1-28 cores*) Use any available Owens node. This reduces the
         wait time as there are no node requirements.
       - **hugemem** - (*48 cores*) Use an Owens node that has 1.5TB of
         available RAM as well as 48 cores. There are 16 of these nodes on
-        Owens.
-      - **vis** - (*28 cores*) Use an Owens node that has an [NVIDIA Tesla P100
+        Owens. Requesting hugemem nodes allocates entire nodes.
+      - **vis** - (*1-28 cores*) Use an Owens node that has an [NVIDIA Tesla P100
         GPU](http://www.nvidia.com/object/tesla-p100.html) with an X server
         running in the background. This utilizes the GPU for hardware
         accelerated 3D visualization. There are 160 of these nodes on Owens.
     options:
-      - [ "any",     ":ppn=28"            ]
-      - [ "hugemem", ":ppn=48:hugemem"    ]
-      - [ "vis",     ":ppn=28:vis:gpus=1" ]
+      - [ "any",     ""            ]
+      - [ "hugemem", ":hugemem"    ]
+      - [ "vis",     ":vis:gpus=1" ]
   version:
     widget: select
     label: "MATLAB version"
diff --git a/submit.yml.erb b/submit.yml.erb
index b3e272936a7d33488737a86d0161ac72d136c630..1ced8356be63afee9bc6a62e6bdf2f47f620fc13 100644
--- a/submit.yml.erb
+++ b/submit.yml.erb
@@ -1,7 +1,13 @@
+<%-
+ppn = num_cores.blank? ? 28 : num_cores.to_i
+if node_type == ':hugemem'
+  ppn = 48
+end
+%>
 ---
 batch_connect:
   template: vnc
 script:
   native:
     resources:
-      nodes: "<%= bc_num_slots.blank? ? "1" : bc_num_slots.to_i %><%= node_type %>"
+      nodes: "<%= bc_num_slots.blank? ? "1" : bc_num_slots.to_i %>:ppn=<%= ppn %><%= node_type %>"