diff --git a/Cargo.lock b/Cargo.lock
index 2469033dbc83358fcffdee40dd41a87616863985..5cdc28487106e1615cea8b90f7bf3c345035cc2a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1378,11 +1378,8 @@ name = "juno_matmul"
 version = "0.1.0"
 dependencies = [
  "async-std",
- "dlopen",
- "dlopen_derive",
  "hercules_rt",
  "juno_build",
- "juno_scheduler",
  "rand 0.9.0",
  "with_builtin_macros",
 ]
diff --git a/juno_samples/matmul/src/matmul.sch b/juno_samples/matmul/src/matmul.sch
index e6fe7bc84c83b39ae63ca918c206762e88ee4f8d..5c6ec43ec92434735f69399592ae19dbbdfda019 100644
--- a/juno_samples/matmul/src/matmul.sch
+++ b/juno_samples/matmul/src/matmul.sch
@@ -70,7 +70,7 @@ if feature("cuda") {
 
   // Parallelize by computing output array as 16 chunks
   let par = matmul@outer \ matmul@inner;
-  fork-chunk![4](par);
+  fork-chunk![num_cpus/4](par);
   let (outer, inner, _) = fork-reshape[[0, 2], [1], [3]](par);
   parallelize!(outer \ inner);
 
diff --git a/juno_scheduler/src/lang.l b/juno_scheduler/src/lang.l
index 726264a348666e9033794493ae51c4e95ba361a4..ddaaee4ed45d08e51d7fb3739d52b2c47800104f 100644
--- a/juno_scheduler/src/lang.l
+++ b/juno_scheduler/src/lang.l
@@ -50,6 +50,8 @@ false           "false"
 \|\|            "||"
 &&              "&&"
 
+/               "/"
+
 panic[\t \n\r]+after "panic_after"
 print[\t \n\r]+iter  "print_iter"
 stop[\t \n\r]+after  "stop_after"
diff --git a/juno_scheduler/src/lang.y b/juno_scheduler/src/lang.y
index 4500f42f5bea948764f9b47bb7bb7b3dc4e82aab..c9426acbd46d3224e346dade30c0b7c500eacda6 100644
--- a/juno_scheduler/src/lang.y
+++ b/juno_scheduler/src/lang.y
@@ -10,6 +10,7 @@
 %left '&&'
 %right '!'
 %left '.' '@'
+%left '/'
 
 %%
 
@@ -98,6 +99,8 @@ Expr -> Expr
       { Expr::BinaryOp { span: $span, op: BinaryOp::Or, lhs: Box::new($1), rhs: Box::new($3) } }
   | Expr '&&' Expr
       { Expr::BinaryOp { span: $span, op: BinaryOp::And, lhs: Box::new($1), rhs: Box::new($3) } }
+  | Expr '/' Expr
+      { Expr::BinaryOp { span: $span, op: BinaryOp::Div, lhs: Box::new($1), rhs: Box::new($3) } }
   ;
 
 Args -> Vec<Expr>
@@ -208,6 +211,7 @@ pub enum BinaryOp {
   Intersection,
   Or,
   And,
+  Div,
 }
 
 pub enum Expr {
diff --git a/juno_scheduler/src/lib.rs b/juno_scheduler/src/lib.rs
index 2a634664da5d41754ce8c1e9759ab93a554dc9ea..7dbe2ca421930c01e1bec4f442d51a5467735caa 100644
--- a/juno_scheduler/src/lib.rs
+++ b/juno_scheduler/src/lib.rs
@@ -107,6 +107,9 @@ pub fn schedule_juno(
         let func_name = strings.lookup_string(func_name);
         env.insert(func_name, Value::JunoFunction { func: func_id });
     }
+    let num_cpus_id = strings.lookup_string("num_cpus".to_owned());
+    // Hardcoding hack
+    env.insert(num_cpus_id, Value::Integer { val: 16 });
     let mut s = InterpretState {
         stringtab: strings,
         env,
diff --git a/juno_scheduler/src/pm.rs b/juno_scheduler/src/pm.rs
index 867a387c5ac05b41d18c27d9d44defc8caa9ba90..15d5948c8cb33ef2be9213408facc86ad48481cf 100644
--- a/juno_scheduler/src/pm.rs
+++ b/juno_scheduler/src/pm.rs
@@ -1639,6 +1639,15 @@ fn interp_expr(
                         lhs_mod || rhs_mod,
                     ))
                 }
+                parser::BinaryOp::Div => {
+                    let (Value::Integer { val: lhs_i }, Value::Integer { val: rhs_i }) = (lhs, rhs)
+                    else {
+                        return Err(SchedulerError::SemanticError(
+                            "Cannot divide nonintegers".to_owned(),
+                        ));
+                    };
+                    Ok((Value::Integer { val: lhs_i / rhs_i }, lhs_mod || rhs_mod))
+                }
             }
         }
         ScheduleExp::Field { collect, field } => {