Repository: projectmesa/mesa
Pull request #1141 (2022-01-22 17:09:48)

update number_processes and associated docs
This updates `nr_processes` to `number_processes` in batch_run and the associated tutorial.

I looked through Keras, Pytorch, multiprocessing to follow the *principle of least surprise*. Both the deep learning libraries use threads which did not seem appropriate. and so trying to mirror multiprocessing conventions I used `number_processes`. 

other changes: 
 - black updated the .pre-commit-config file
 - jupyterlab updated some hidden fields


codecov[bot]: # [Codecov](https://codecov.io/gh/projectmesa/mesa/pull/1141?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa) Report
> Merging [#1141](https://codecov.io/gh/projectmesa/mesa/pull/1141?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa) (7e89b90) into [main](https://codecov.io/gh/projectmesa/mesa/commit/246c69d592a82e89c75d555c79736c3f619d434a?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa) (246c69d) will **decrease** coverage by `0.14%`.
> The diff coverage is `100.00%`.

[![Impacted file tree graph](https://codecov.io/gh/projectmesa/mesa/pull/1141/graphs/tree.svg?width=650&height=150&src=pr&token=OUHxz83iDi&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa)](https://codecov.io/gh/projectmesa/mesa/pull/1141?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa)

```diff
@@            Coverage Diff             @@
##             main    #1141      +/-   ##
==========================================
- Coverage   89.46%   89.32%   -0.15%     
==========================================
  Files          19       19              
  Lines        1253     1255       +2     
  Branches      256      251       -5     
==========================================
  Hits         1121     1121              
- Misses         97       98       +1     
- Partials       35       36       +1     
```


| [Impacted Files](https://codecov.io/gh/projectmesa/mesa/pull/1141?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa) | Coverage Δ | |
|---|---|---|
| [mesa/batchrunner.py](https://codecov.io/gh/projectmesa/mesa/pull/1141/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa#diff-bWVzYS9iYXRjaHJ1bm5lci5weQ==) | `91.63% <100.00%> (-0.57%)` | :arrow_down: |
| [mesa/space.py](https://codecov.io/gh/projectmesa/mesa/pull/1141/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa#diff-bWVzYS9zcGFjZS5weQ==) | `95.89% <0.00%> (-0.02%)` | :arrow_down: |

------

[Continue to review full report at Codecov](https://codecov.io/gh/projectmesa/mesa/pull/1141?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/projectmesa/mesa/pull/1141?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa). Last update [246c69d...7e89b90](https://codecov.io/gh/projectmesa/mesa/pull/1141?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=projectmesa).

rht: PyTorch does have multiprocessing module: https://pytorch.org/docs/stable/_modules/torch/multiprocessing/spawn.html#spawn, and they use `nrprocs`.

But they also say:
> The API is 100% compatible with the original module - it’s enough to change import multiprocessing to import torch.multiprocessing to have all the tensors sent through the queues or shared via other mechanisms, moved to shared memory.

So they are not being consistent.
tpike3: @rht I completely missed that, thanks. I think with a lack of consistency and to your original point of making it more obvious, I am good with `number_processes`. But happy to defer to the group consensus. 

Patch:
diff --git a/.github/workflows/python.yml b/.github/workflows/python.yml
index 6ed533ac..a5e9c8d5 100644
--- a/.github/workflows/python.yml
+++ b/.github/workflows/python.yml
@@ -42,8 +42,9 @@ jobs:
       run: pip install .[dev]
     - name: Test with pytest
       run: pytest --cov=mesa tests/ --cov-report=xml
-    - name: Codecov
-      uses: codecov/codecov-action@v1.0.15
+    - if: matrix.os == 'ubuntu'
+      name: Codecov
+      uses: codecov/codecov-action@v2
 
   lint-flake:
     runs-on: ubuntu-latest
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 7a99e40a..9366459b 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,6 +1,6 @@
 repos:
 -   repo: https://github.com/ambv/black
-    rev: stable
+    rev: 21.12b0
     hooks:
     - id: black
       exclude: mesa/cookiecutter-mesa/*
diff --git a/README.rst b/README.rst
index dd2c581a..2dbc6604 100644
--- a/README.rst
+++ b/README.rst
@@ -54,7 +54,7 @@ Or any other (development) branch on this repo or your own fork:
 
 .. code-block:: bash
 
-    $ pip install -e git+https://github.com/YOUR_FORK/mesa@YOUR_BRANCH
+    $ pip install -e git+https://github.com/YOUR_FORK/mesa@YOUR_BRANCH#egg=mesa
 
 Take a look at the `examples <https://github.com/projectmesa/mesa/tree/main/examples>`_ folder for sample models demonstrating Mesa features.
 
diff --git a/docs/tutorials/intro_tutorial.ipynb b/docs/tutorials/intro_tutorial.ipynb
index ada51204..5e32142d 100644
--- a/docs/tutorials/intro_tutorial.ipynb
+++ b/docs/tutorials/intro_tutorial.ipynb
@@ -229,9 +229,7 @@
   },
   {
    "cell_type": "markdown",
-   "metadata": {
-    "collapsed": true
-   },
+   "metadata": {},
    "source": [
     "### Agent Step\n",
     "\n",
@@ -1046,11 +1044,11 @@
     "A dictionary containing all the parameters of the model class and desired values to use for the batch run as key-value pairs. Each value can either be fixed ( e.g. `{\"height\": 10, \"width\": 10}`) or an iterable (e.g. `{\"N\": range(10, 500, 10)}`). `batch_run` will then generate all possible parameter combinations based on this dictionary and run the model `iterations` times for each combination.\n",
     "<br/><br/>\n",
     "\n",
-    "* `nr_processes`\n",
+    "* `number_processes`\n",
     "<br/><br/>\n",
     "Number of processors used to run the sweep in parallel. Optional. If not specified, defaults to use all the available processors.\n",
     "<br/><br/>\n",
-    "Note: Multiprocessing does make debugging challenging. If your parameter sweeps are resulting in unexpected errors set `nr_processes = 1`.\n",
+    "Note: Multiprocessing does make debugging challenging. If your parameter sweeps are resulting in unexpected errors set `number_processes = 1`.\n",
     "<br/><br/>\n",
     "\n",
     "* `iterations`\n",
@@ -1117,7 +1115,7 @@
     "    parameters=params,\n",
     "    iterations=5,\n",
     "    max_steps=100,\n",
-    "    nr_processes=None,\n",
+    "    number_processes=None,\n",
     "    data_collection_period=1,\n",
     "    display_progress=True,\n",
     ")"
@@ -1328,7 +1326,7 @@
  "metadata": {
   "anaconda-cloud": {},
   "kernelspec": {
-   "display_name": "Python 3",
+   "display_name": "Python 3 (ipykernel)",
    "language": "python",
    "name": "python3"
   },
@@ -1342,7 +1340,7 @@
    "name": "python",
    "nbconvert_exporter": "python",
    "pygments_lexer": "ipython3",
-   "version": "3.7.12"
+   "version": "3.9.6"
   },
   "widgets": {
    "state": {},
@@ -1350,5 +1348,5 @@
   }
  },
  "nbformat": 4,
- "nbformat_minor": 1
+ "nbformat_minor": 4
 }
diff --git a/docs/tutorials/intro_tutorial.rst b/docs/tutorials/intro_tutorial.rst
index ca3cdf7b..967a0dd6 100644
--- a/docs/tutorials/intro_tutorial.rst
+++ b/docs/tutorials/intro_tutorial.rst
@@ -919,13 +919,13 @@ We call ``batch_run`` with the following arguments:
   will then generate all possible parameter combinations based on this
   dictionary and run the model ``iterations`` times for each combination.
 
-* ``nr_processes``
+* ``number_processes``
 
   Number of processors used to run the sweep in parallel. Optional.
   If not specified, defaults to use all the available processors.
 
   Note: Multiprocessing does make debugging challenging. If your
-  parameter sweeps are resulting in unexpected errors set ``nr_processes = 1``.
+  parameter sweeps are resulting in unexpected errors set ``number_processes = 1``.
 
 * ``iterations``
 
@@ -980,7 +980,7 @@ iteration).
         parameters=params,
         iterations=5,
         max_steps=100,
-        nr_processes=None,
+        number_processes=None,
         data_collection_period=1,
         display_progress=True,
     )
diff --git a/mesa/batchrunner.py b/mesa/batchrunner.py
index 9178f0d1..4b19c47e 100644
--- a/mesa/batchrunner.py
+++ b/mesa/batchrunner.py
@@ -12,6 +12,7 @@ from collections import OrderedDict
 from functools import partial
 from itertools import count, product
 from multiprocessing import Pool, cpu_count
+from warnings import warn
 from typing import (
     Any,
     Counter,
@@ -34,7 +35,7 @@ from mesa.model import Model
 def batch_run(
     model_cls: Type[Model],
     parameters: Mapping[str, Union[Any, Iterable[Any]]],
-    nr_processes: Optional[int] = None,
+    number_processes: Optional[int] = None,
     iterations: int = 1,
     data_collection_period: int = -1,
     max_steps: int = 1000,
@@ -48,7 +49,7 @@ def batch_run(
         The model class to batch-run
     parameters : Mapping[str, Union[Any, Iterable[Any]]],
         Dictionary with model parameters over which to run the model. You can either pass single values or iterables.
-    nr_processes : int, optional
+    number_processes : int, optional
         Number of processes used. Set to None (default) to use all available processors
     iterations : int, optional
         Number of iterations for each parameter combination, by default 1
@@ -79,7 +80,7 @@ def batch_run(
     results: List[Dict[str, Any]] = []
 
     with tqdm(total_iterations, disable=not display_progress) as pbar:
-        if nr_processes == 1:
+        if number_processes == 1:
             for iteration in range(iterations):
                 for kwargs in kwargs_list:
                     _, rawdata = process_func(kwargs)
@@ -94,7 +95,7 @@ def batch_run(
 
         else:
             iteration_counter: Counter[Tuple[Any, ...]] = Counter()
-            with Pool(nr_processes) as p:
+            with Pool(number_processes) as p:
                 for paramValues, rawdata in p.imap_unordered(process_func, kwargs_list):
                     iteration_counter[paramValues] += 1
                     iteration = iteration_counter[paramValues]
@@ -525,7 +526,8 @@ class ParameterSampler:
 
 
 class BatchRunner(FixedBatchRunner):
-    """This class is instantiated with a model class, and model parameters
+    """DEPRECATION WARNING: BatchRunner Class has been replaced batch_run function
+    This class is instantiated with a model class, and model parameters
     associated with one or more values. It is also instantiated with model and
     agent-level reporters, dictionaries mapping a variable name to a function
     which collects some data from the model or its agents at the end of the run
@@ -579,6 +581,11 @@ class BatchRunner(FixedBatchRunner):
             display_progress: Display progress bar with time estimation?
 
         """
+        warn(
+            "BatchRunner class has been replaced by batch_run function. Please see documentation.",
+            DeprecationWarning,
+            2,
+        )
         if variable_parameters is None:
             super().__init__(
                 model_cls,
@@ -604,7 +611,8 @@ class BatchRunner(FixedBatchRunner):
 
 
 class BatchRunnerMP(BatchRunner):
-    """Child class of BatchRunner, extended with multiprocessing support."""
+    """DEPRECATION WARNING: BatchRunner class has been replaced by batch_run
+    Child class of BatchRunner, extended with multiprocessing support."""
 
     def __init__(self, model_cls, nr_processes=None, **kwargs):
         """Create a new BatchRunnerMP for a given model with the given
@@ -616,6 +624,11 @@ class BatchRunnerMP(BatchRunner):
                       should start, all running in parallel.
         kwargs: the kwargs required for the parent BatchRunner class
         """
+        warn(
+            "BatchRunnerMP class has been replaced by batch_run function. Please see documentation.",
+            DeprecationWarning,
+            2,
+        )
         if nr_processes is None:
             # identify the number of processors available on users machine
             available_processors = cpu_count()


Test patch:
diff --git a/tests/test_batch_run.py b/tests/test_batch_run.py
index 7d24e88f..072b1dae 100644
--- a/tests/test_batch_run.py
+++ b/tests/test_batch_run.py
@@ -141,4 +141,4 @@ def test_batch_run_no_agent_reporters():
 
 
 def test_batch_run_single_core():
-    batch_run(MockModel, {}, nr_processes=1, iterations=10)
+    batch_run(MockModel, {}, number_processes=1, iterations=10)