global sizes
  var N := 10    # matrix dimension, default 10
  var W := 2     # number of workers, default 2
body sizes
  getarg(1, N); getarg(2, W)
end

resource mult()
  import sizes
  var a[N,N], b[N,N], c[N,N]: real
  op bag(row: int)

  # initialize the arrays and bag of tasks
  fa i := 1 to N ->
    fa j := 1 to N ->
      a[i,j] := 1.0; b[i,j] := 1.0
    af
    send bag(i)
  af

  process worker(id := 1 to W)
    var i: int    # index of row of c to compute
    do true ->
      receive bag(i)
      fa j := 1 to N ->
        var inner_prod := 0.0
        fa k := 1 to N ->
            inner_prod +:= a[i,k]*b[k,j]
        af
        c[i,j] := inner_prod
      af
    od
  end

  final
    fa i := 1 to N ->
      fa j := 1 to N -> writes(c[i,j], " ") af
      write()
    af
  end
end
