# Bagpype: Better Academic Graphs for Processor Pipelines
A Python library for describing and visualizing processor pipeline diagrams with a clean, intuitive syntax.
## Installation
```bash
pip install bagpype
```
## Quick Start
```python
import bagpype as bp
# Create a pipeline
p = bp.Pipeline()
# Add instructions (operations)
p += (i := bp.Op("add x1, x2, x3"))
# Add edge and nodes
p += bp.Edge(i.IF(0) >> i.DE(1) >> i.EX(2) >> i.WB(3), legend="simple_pipeline").set_node_color("violet")
# Visualize the pipeline
p.draw()
```
## Core Concepts
### Operations (Op)
An operation represents one instruction in your pipeline. Each operation is visualized as a row and can contain multiple pipeline stages.
```python
# A one-liner
p += (i0 := Op("add x1, x2, x3"))
# for the faint of heart
i1 = Op("orr x4, x5, x6")
p.add_op(i1)
```
### Nodes
Nodes represent pipeline stages (fetch, decode, execute, etc.). They're positioned by time (x-axis) and instruction (y-axis).
```python
# Create nodes with timing
i0.fetch(0) # fetch at cycle 0
i0.decode(1, "red") # decode at cycle 1, optional color
i0.add_node(Node("execute", 2)) # for the faint of heart
# Access nodes later
print(i0.fetch) # fetch@0
```
### Edges
Edges show dependencies between pipeline stages using the `>>` operator:
```python
# Simple dependency
edge1 = Edge(i0.execute >> i1.fetch)
# Chain multiple dependencies, optional color and legend
i0.fetch(0) # create a fetch node
# create decode and execute node in the edge declaration
edge2 = Edge(i0.fetch >> i0.decode(1) >> i0.execute(2), "purple", "simple-pipeline")
# Avoid using weird syntax, by using other weird syntax
edge3 = Edge([i0.execute, i1.decode]).set_edge_color("blue").set_edge_legend("forwarding")
# Style Nodes along the edge
edge3 = Edge(i0.execute >> i1.decode).set_node_color("lightblue")
```
### Pipeline
The main container that holds operations and edges:
```python
p = Pipeline()
p += i0 # add operation
p += i1 # add another operation
p += edge1 # add dependency
p.draw() # visualize
# saving
p.draw(save=True, file="something.png")
```
## Styling Options
### Node Colors
```python
i0.fetch(0, color="lightblue")
i0.decode(1, color="lightgreen")
```
### Edge Colors and Legends
```python
p += Edge(i0.execute >> i1.fetch).set_edge_color("red").set_edge_legend("data hazard")
p += Edge(i0.writeback >> i2.fetch).set_edge_color("blue").set_edge_legend("control hazard")
```
## Example: 5-Stage Pipeline with Hazards
This example demonstrates why we might want to use a DSL to describe the pipeline.
```python
def example_program():
p = bp.Pipeline()
stall_node_style = bp.NodeStyle(color="red", linestyle="--")
# Three instructions
insns = [bp.Op("add x1, x1, x3"),
bp.Op("sub x4, x1, x5"), # depends on x1 from i0
bp.Op("mul x6, x4, x7")] # depends on x4 from i1
# Normal pipeline stages
for i, op in enumerate(insns):
op.IF(i + 1)
op.DE(i + 2)
# add stall nodes
for j in range(i):
op.add_node(bp.Node(f"stall{j}", i + 3 + j, stall_node_style))
op.EX(2 * i + 3)
op.WB(2 * i + 4)
p += op
for i in range(len(insns) - 1):
p += bp.Edge(insns[i].WB >> insns[i + 1].EX, bp.EdgeStyle(color="red"), "data hazard").set_node_color("pink")
p.draw(save=True, filename="assets/program.png")
```
This produces the follwing diagram:

## Requirements
- Python ≥ 3.10
- matplotlib ≥ 3.7.0
- seaborn ≥ 0.12.0
## License
MIT
Raw data
{
"_id": null,
"home_page": null,
"name": "bagpype",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "pipeline, visualization, computer architecture",
"author": null,
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/4d/8e/95011cce64bc2d0344c1f2981e50b132e05f410cf173d9ea56060317d1c7/bagpype-0.1.2.tar.gz",
"platform": null,
"description": "# Bagpype: Better Academic Graphs for Processor Pipelines\n\nA Python library for describing and visualizing processor pipeline diagrams with a clean, intuitive syntax.\n\n## Installation\n\n```bash\npip install bagpype\n```\n\n## Quick Start\n\n```python\nimport bagpype as bp\n\n# Create a pipeline\np = bp.Pipeline()\n\n# Add instructions (operations)\np += (i := bp.Op(\"add x1, x2, x3\"))\n\n# Add edge and nodes \np += bp.Edge(i.IF(0) >> i.DE(1) >> i.EX(2) >> i.WB(3), legend=\"simple_pipeline\").set_node_color(\"violet\")\n\n# Visualize the pipeline\np.draw()\n```\n\n## Core Concepts\n\n### Operations (Op)\nAn operation represents one instruction in your pipeline. Each operation is visualized as a row and can contain multiple pipeline stages.\n\n```python\n# A one-liner\np += (i0 := Op(\"add x1, x2, x3\")) \n# for the faint of heart\ni1 = Op(\"orr x4, x5, x6\") \np.add_op(i1)\n```\n\n### Nodes\nNodes represent pipeline stages (fetch, decode, execute, etc.). They're positioned by time (x-axis) and instruction (y-axis).\n\n```python\n# Create nodes with timing\ni0.fetch(0) # fetch at cycle 0\ni0.decode(1, \"red\") # decode at cycle 1, optional color \ni0.add_node(Node(\"execute\", 2)) # for the faint of heart\n\n# Access nodes later\nprint(i0.fetch) # fetch@0\n```\n\n### Edges\nEdges show dependencies between pipeline stages using the `>>` operator:\n\n```python\n# Simple dependency\nedge1 = Edge(i0.execute >> i1.fetch)\n\n# Chain multiple dependencies, optional color and legend\ni0.fetch(0) # create a fetch node\n# create decode and execute node in the edge declaration \nedge2 = Edge(i0.fetch >> i0.decode(1) >> i0.execute(2), \"purple\", \"simple-pipeline\")\n\n# Avoid using weird syntax, by using other weird syntax\nedge3 = Edge([i0.execute, i1.decode]).set_edge_color(\"blue\").set_edge_legend(\"forwarding\")\n\n# Style Nodes along the edge\nedge3 = Edge(i0.execute >> i1.decode).set_node_color(\"lightblue\")\n```\n\n### Pipeline\nThe main container that holds operations and edges:\n\n```python\np = Pipeline()\np += i0 # add operation\np += i1 # add another operation \np += edge1 # add dependency\np.draw() # visualize\n# saving\np.draw(save=True, file=\"something.png\") \n```\n\n## Styling Options\n\n### Node Colors\n```python\ni0.fetch(0, color=\"lightblue\")\ni0.decode(1, color=\"lightgreen\")\n```\n\n### Edge Colors and Legends\n```python\np += Edge(i0.execute >> i1.fetch).set_edge_color(\"red\").set_edge_legend(\"data hazard\")\np += Edge(i0.writeback >> i2.fetch).set_edge_color(\"blue\").set_edge_legend(\"control hazard\")\n```\n\n## Example: 5-Stage Pipeline with Hazards\n\nThis example demonstrates why we might want to use a DSL to describe the pipeline. \n\n```python\ndef example_program():\n p = bp.Pipeline()\n\n stall_node_style = bp.NodeStyle(color=\"red\", linestyle=\"--\")\n\n # Three instructions\n insns = [bp.Op(\"add x1, x1, x3\"),\n bp.Op(\"sub x4, x1, x5\"), # depends on x1 from i0\n bp.Op(\"mul x6, x4, x7\")] # depends on x4 from i1\n\n # Normal pipeline stages\n for i, op in enumerate(insns):\n op.IF(i + 1)\n op.DE(i + 2)\n # add stall nodes\n for j in range(i):\n op.add_node(bp.Node(f\"stall{j}\", i + 3 + j, stall_node_style))\n op.EX(2 * i + 3)\n op.WB(2 * i + 4)\n p += op\n\n for i in range(len(insns) - 1):\n p += bp.Edge(insns[i].WB >> insns[i + 1].EX, bp.EdgeStyle(color=\"red\"), \"data hazard\").set_node_color(\"pink\")\n\n p.draw(save=True, filename=\"assets/program.png\")\n```\nThis produces the follwing diagram:\n\n\n## Requirements\n\n- Python \u2265 3.10\n- matplotlib \u2265 3.7.0\n- seaborn \u2265 0.12.0\n\n## License\n\nMIT ",
"bugtrack_url": null,
"license": "MIT",
"summary": "A python library for pipeline diagram visualization",
"version": "0.1.2",
"project_urls": {
"Homepage": "https://github.com/iansseijelly/bagpype"
},
"split_keywords": [
"pipeline",
" visualization",
" computer architecture"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "88df831867e480893960c619cc73e45181237c24106b2826d4057f92cb299495",
"md5": "28987159ac3e2d50dc799023c754b597",
"sha256": "44e16c2aac049fc4f853c88da710c1ca6a7515fd6d8d8e9cd3670e7bd7a46b35"
},
"downloads": -1,
"filename": "bagpype-0.1.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "28987159ac3e2d50dc799023c754b597",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 7053,
"upload_time": "2025-08-22T17:35:51",
"upload_time_iso_8601": "2025-08-22T17:35:51.157457Z",
"url": "https://files.pythonhosted.org/packages/88/df/831867e480893960c619cc73e45181237c24106b2826d4057f92cb299495/bagpype-0.1.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "4d8e95011cce64bc2d0344c1f2981e50b132e05f410cf173d9ea56060317d1c7",
"md5": "5ea30bbfb8f913d3edbec63d1b2134c4",
"sha256": "ce65f1808f328a444f4329c202e78139294a286b2691777872c72bbf1d3b93c8"
},
"downloads": -1,
"filename": "bagpype-0.1.2.tar.gz",
"has_sig": false,
"md5_digest": "5ea30bbfb8f913d3edbec63d1b2134c4",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 5470,
"upload_time": "2025-08-22T17:35:52",
"upload_time_iso_8601": "2025-08-22T17:35:52.004645Z",
"url": "https://files.pythonhosted.org/packages/4d/8e/95011cce64bc2d0344c1f2981e50b132e05f410cf173d9ea56060317d1c7/bagpype-0.1.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-22 17:35:52",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "iansseijelly",
"github_project": "bagpype",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "bagpype"
}