Skip to content

Commit

Permalink
Merge branch 'development' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
pgleeson authored Jul 4, 2022
2 parents 55006fb + d7e57f7 commit 8a89c2f
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 55 deletions.
25 changes: 12 additions & 13 deletions examples/MDF/abc_conditions.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import os

import abcd_python as abcd

import graph_scheduler
from modeci_mdf.mdf import (
Condition,
ConditionSet,
Expand Down Expand Up @@ -67,17 +67,7 @@ def create_simple_node(graph, id_, sender=None):
mod.to_json_file(os.path.join(os.path.dirname(__file__), "%s.json" % mod.id))
mod.to_yaml_file(os.path.join(os.path.dirname(__file__), "%s.yaml" % mod.id))

print_summary(mod_graph)
print(
mod.to_graph_image(
engine="dot",
output_format="png",
view_on_render=False,
level=3,
filename_root="abc_conditions",
only_warn_on_fail=True, # Makes sure test of this doesn't fail on Windows on GitHub Actions
)
)
# print_summary(mod_graph)
import sys

if "-run" in sys.argv:
Expand All @@ -89,7 +79,16 @@ def create_simple_node(graph, id_, sender=None):
format = FORMAT_TENSORFLOW if "-tf" in sys.argv else FORMAT_NUMPY
eg = EvaluableGraph(mod_graph, verbose=verbose)
eg.evaluate(array_format=format)

# evaluating the current state of the graph's parameters
print(
"Output of A: %s" % eg.enodes["A"].evaluable_outputs["output_1"].curr_value
)
print(
"Output of B: %s" % eg.enodes["B"].evaluable_outputs["output_1"].curr_value
)
print(
"Output of C: %s" % eg.enodes["C"].evaluable_outputs["output_1"].curr_value
)
if "-graph" in sys.argv:
mod.to_graph_image(
engine="dot",
Expand Down
124 changes: 84 additions & 40 deletions examples/PyTorch/README.md
Original file line number Diff line number Diff line change
@@ -1,68 +1,112 @@
# PyTorch and MDF

The current implementation of our PyTorch to MDF conversion functionality is built
on top of the TorchScript infrastructure provided by PyTorch. PyTorch models that
can be translated to TorchScript (via `torch.jit.script` or `torch.jit.trace`) should
then be able to be converted to their MDF representation automatically. Below are
several working examples of this functionality.
1. [MDF to Pytorch](#MDF-to-PyTorch)
2. [Pytorch to MDF](#PyTorch-to-MDF)

### Inception Blocks Model
## MDF to PyTorch

![Inception from PyTorch](inception.svg?raw=1)

To run an example of converting a PyTorch InceptionV3 like model written in PyTorch
to its MDF representation simply run:
To perform an MDF to PyTorch conversion, provide an MDF model as an input to the `mdf_to_pytorch` function
which is available in [exporter.py](/src/modeci_mdf/interfaces/pytorch/exporter.py). The output of `mdf_to_pytorch` is a PyTorch model.

```bash
python inception.py
```
mdf_to_pytorch(
mdf_model: model in MDF format
eval_models: Set Evaluation of model to True or False
version: MDF version
model_input: input file name
)
```
Returns a dictionary where **key** = **model name**, **value** = **pytorch model object**

### Implementation

This will define the model in PyTorch, invoke the TorchScript tracing compiler,
convert the underlying IR representation of the model to MDF. The MDF for this
model is the written to [inception.json](inception.json). The model is then executed
via the MDF scheduler and the results are compared to the native execution in PyTorch.
Below are some working examples of this functionality.

The graph representation of the MDF model can be generated with:
1. One of sample MDF examples [ABCD.json](../MDF/ABCD.json) is converted to PyTorch [ABCD_pytorch.py](MDF_PyTorch/ABCD_pytorch.py).
The PyTorch model is further converted to ONNX [ABCD.onnx](MDF_PyTorch/ABCD.onnx) and the results are compared in all three environments.

2. Multi-Layer Perceptron MDF to PyTorch Conversion:

To run an example where a simple Multi-Layer Perceptron (MLP) created using the MDF specification and executed using sample digit-recognition data, run:

```bash
python mlp_pure_mdf.py
```

A graph of the network can be created with `python mlp_pure_mdf.py -graph`:

**MDF graph**
<p align="center"><img src="mlp_pure_mdf.png" alt="mlp_pure_mdf.png" height="400"></p>

The network can be run against images from the MNIST database with: `python mlp_pure_mdf.py -run`, and produce 98% accuracy. The image below shows the results of 300 images:

<p align="center"><img src="mlp_pure_mdf.results.png" alt="mlp_pure_mdf.results.png" height="250"></p>

Conversion to PyTorch: TODO...

The demo to convert an MDF model to PyTorch is at [MDF_to_PyTorch.py](/examples/PyTorch/MDF_PyTorch/MDF_to_PyTorch.py). This converts all the available MDF models to their respective Pytorch Models.
Any model created using the MDF specification is translated to a PyTorch model, run:

```bash
python inception.py -graph
python MDF_to_PyTorch
```

<img alt="Inception MDF" height="500" src="inception.png"/>
**NOTE:** The converted models are available in folder: [MDF_PyTorch](/examples/PyTorch/MDF_PyTorch).

### Multi-Layer Perceptron MDF to PyTorch Conversion

To run an example where a simple Multi-Layer Perceptron (MLP) created using the MDF specification and executed using sample digit-recognition data, run:
## PyTorch to MDF

The current implementation of our PyTorch to MDF conversion functionality is built
on top of the TorchScript infrastructure provided by PyTorch. PyTorch models that
can be translated to TorchScript (via `torch.jit.script` or `torch.jit.trace`) should
then be able to be converted to their MDF representation automatically. Below are
several working examples of this functionality.

To perform an PyTorch to MDF conversion, provide a PyTorch model as an input to the `pytorch_to_mdf` function
which is available in [importer.py](/src/modeci_mdf/interfaces/pytorch/importer.py). The output of `pytorch_to_mdf` is an MDF model.

```bash
python mlp_pure_mdf.py
```
pytorch_to_mdf(
model: The model to translate into MDF.
args: The input arguments for this model. If a nn.Module is passed then the model will be traced with these
inputs. If a ScriptModule is passed, they are still needed to deterimine input shapes.
trace: Force the use of tracing to compile the model. The default is to use torch.jit.script
use_onnx_ops: Use ONNX ops when possible, fallback to ATEN ops when not available. Default is True. If False,
use only ATEN ops.
)
```
Returns a translated MDF model

A graph of the network can be created with `python mlp_pure_mdf.py -graph`:
### Implementation

<p align="center"><img src="mlp_pure_mdf.png" alt="mlp_pure_mdf.png" height="400"></p>
Below are some working examples of this functionality.

The network can be run against images from the MNIST database with: `python mlp_pure_mdf.py -run`, and produce 98% accuracy. The image below shows the results of 300 images:
1. A DDM A model that simulates a simple noisy drift diffusion model using Euler-Maruyama integration. This is implemented without performance in mind. [pytorch_ddm.py](pytorch_ddm.py) is converted to [ddm.json](ddm.json)
```bash
python pytorch_ddm.py -graph
```

<p align="center"><img src="mlp_pure_mdf.results.png" alt="mlp_pure_mdf.results.png"></p>
<p align="center"><img alt="DDM mdf" src="ddm.png"/></p>

Conversion to PyTorch: TODO...

2. Inception Blocks Model:

### MDF to PyTorch Conversion
To run an example of converting a PyTorch InceptionV3 like model written in PyTorch
to its MDF representation simply run:

To perform an MDF to PyTorch conversion, provide an MDF model as an input to the `mdf_to_pytorch` function
which is available in [exporter.py](https://github.com/ModECI/MDF/blob/development/src/modeci_mdf/interfaces/pytorch/exporter.py). The output of `mdf_to_pytorch`
are PyTorch models. Below are some working examples of this functionality. The converted
models are available in folder: [MDF_PyTorch](https://github.com/ModECI/MDF/tree/development/examples/PyTorch/MDF_PyTorch).
```bash
python inception.py
```

The demo to convert an MDF model to PyTorch is at [MDF_to_PyTorch.py](https://github.com/ModECI/MDF/blob/development/examples/PyTorch/MDF_PyTorch/MDF_to_PyTorch.py).
This will define the model in PyTorch, invoke the TorchScript tracing compiler,
convert the underlying IR representation of the model to MDF. The MDF for this
model is the written to [inception.json](inception.json). The model is then executed
via the MDF scheduler and the results are compared to the native execution in PyTorch.

Any model created using the MDF specification is translated to a PyTorch model, run:
The graph representation of the MDF model can be generated with:

```bash
python MDF_to_PyTorch
```
```bash
python inception.py -graph
```

One of sample MDF examples [ABCD.json](../MDF/ABCD.json) is converted PyTorch [ABCD_pytorch.py](MDF_PyTorch/ABCD_pytorch.py)
The PyTorch model is further converted to ONNX [ABCD.onnx](MDF_PyTorch/ABCD.onnx) and the results are compared in all three environments.
<p align="center"><img alt="Inception MDF" height="600" src="inception.png"/></p>
5 changes: 3 additions & 2 deletions src/modeci_mdf/execution_engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -1035,7 +1035,6 @@ def __init__(self, graph: Graph, verbose: Optional[bool] = False):
else:
conditions = {}
termination_conds = {}

self.scheduler = graph_scheduler.Scheduler(
graph=self.graph.dependency_dict,
conditions=conditions,
Expand Down Expand Up @@ -1114,7 +1113,9 @@ def evaluate(
)

if self.verbose:
print("Trial terminated")
print("Order of execution of nodes\n")
print(list(self.scheduler.run()))
print("\n Trial terminated")

def evaluate_edge(
self,
Expand Down

0 comments on commit 8a89c2f

Please sign in to comment.