• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

SpiNNakerManchester / sPyNNaker / 9316203034

31 May 2024 09:39AM UTC coverage: 68.066% (-0.007%) from 68.073%
9316203034

Pull #1455

github

Christian-B
install_modul needed
Pull Request #1455: runs an intergation test in linux, windows and macos

6113 of 8798 branches covered (69.48%)

Branch coverage included in aggregate %.

13064 of 19376 relevant lines covered (67.42%)

0.67 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.61
/spynnaker/pyNN/extra_algorithms/spynnaker_neuron_network_specification_report.py
1
# Copyright (c) 2016 The University of Manchester
2
#
3
# Licensed under the Apache License, Version 2.0 (the "License");
4
# you may not use this file except in compliance with the License.
5
# You may obtain a copy of the License at
6
#
7
#     https://www.apache.org/licenses/LICENSE-2.0
8
#
9
# Unless required by applicable law or agreed to in writing, software
10
# distributed under the License is distributed on an "AS IS" BASIS,
11
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
# See the License for the specific language governing permissions and
13
# limitations under the License.
14
from __future__ import annotations
1✔
15
import logging
1✔
16
import os
1✔
17
from typing import Dict, Set, Tuple, Type, TypeVar, TYPE_CHECKING
1✔
18
from spinn_utilities.config_holder import get_config_str_or_none
1✔
19
from spinn_utilities.log import FormatAdapter
1✔
20
from spinn_utilities.progress_bar import ProgressBar
1✔
21
from pacman.model.graphs.application import ApplicationVertex
1✔
22
from spynnaker.pyNN.data import SpynnakerDataView
1✔
23
from spynnaker.pyNN.exceptions import SpynnakerException
1✔
24
from spynnaker.pyNN.models.neural_projections import ProjectionApplicationEdge
1✔
25
if TYPE_CHECKING:
26
    import graphviz as gv  # type: ignore[import]
27

28
logger = FormatAdapter(logging.getLogger(__name__))
1✔
29
_RE = TypeVar("_RE", bound=RuntimeError)
1✔
30

31
CUTOFF = 100
1✔
32
_GRAPH_TITLE = "The graph of the network in graphical form"
1✔
33
_GRAPH_NAME = "network_graph.gv"
1✔
34
_GRAPH_FORMAT = "png"
1✔
35

36

37
def _get_diagram(label: str) -> Tuple[gv.Digraph, Type[gv.ExecutableNotFound]]:
1✔
38
    """
39
    :param str label:
40
    :rtype: tuple(~graphviz.Digraph, type)
41
    """
42
    # pylint: disable=import-error,import-outside-toplevel
43
    try:
1✔
44
        import graphviz
1✔
45
    except ImportError as e:
×
46
        raise SpynnakerException(
×
47
            "graphviz is required to use this report. "
48
            "Please install graphviz if you want to use this report."
49
            ) from e
50
    return (graphviz.Digraph(comment=label),
1✔
51
            graphviz.ExecutableNotFound)
52

53

54
def spynnaker_neuron_graph_network_specification_report() -> None:
1✔
55
    """
56
    Produces a report describing the graph created from the neural
57
    populations and projections.
58

59
    :param str report_folder: the report folder to put figure into
60
    """
61
    # create holders for data
62
    dot_diagram, exe_not_found_exn = _get_diagram(_GRAPH_TITLE)
1✔
63

64
    graph_format = get_config_str_or_none("Reports", "network_graph_format")
1✔
65
    if graph_format is None:
1✔
66
        graph_format = _GRAPH_FORMAT
1✔
67
        if (SpynnakerDataView.get_n_vertices() +
1!
68
                SpynnakerDataView.get_n_partitions()) > CUTOFF:
69
            logger.warning(
×
70
                "cfg write_network_graph ignored as network_graph_format "
71
                "is None and the network is big")
72
            return
×
73
    # build progress bar for the vertices, edges, and rendering
74
    progress = ProgressBar(
1✔
75
        SpynnakerDataView.get_n_vertices() +
76
        SpynnakerDataView.get_n_partitions(),
77
        "generating the graphical representation of the neural network")
78

79
    # write vertices into dot diagram
80
    vertex_ids = _generate_vertices(dot_diagram, progress)
1✔
81
    # write edges into dot diagram
82
    _generate_edges(dot_diagram, vertex_ids, progress)
1✔
83

84
    # write dot file and generate PDF
85
    file_to_output = os.path.join(
1✔
86
        SpynnakerDataView.get_run_dir_path(), _GRAPH_NAME)
87
    progress.end()
1✔
88

89
    logger.info(f"rendering dot diagram {file_to_output}")
1✔
90
    try:
1✔
91
        dot_diagram.render(file_to_output, view=False, format=graph_format)
1✔
92
    except exe_not_found_exn:
×
93
        logger.exception("could not render diagram in {}", file_to_output)
×
94

95

96
def _generate_vertices(
1✔
97
        dot_diagram: gv.Digraph,
98
        progress: ProgressBar) -> Dict[ApplicationVertex, str]:
99
    """
100
    :param ~graphviz.Digraph dot_diagram:
101
    :param ~.ProgressBar progress:
102
    :return: the mapping from vertex to ID for the generated vertices
103
    :rtype: dict(~.ApplicationVertex,str)
104
    """
105
    vertex_ids: Dict[ApplicationVertex, str] = dict()
1✔
106
    for vertex_counter, vertex in progress.over(
1✔
107
            enumerate(SpynnakerDataView.iterate_vertices()), False):
108
        # Arbitrary labels used inside dot
109
        vertex_id = str(vertex_counter)
1✔
110
        dot_diagram.node(
1✔
111
            vertex_id, f"{vertex.label} ({vertex.n_atoms} neurons)")
112
        vertex_ids[vertex] = vertex_id
1✔
113
    return vertex_ids
1✔
114

115

116
def _generate_edges(
1✔
117
        dot_diagram: gv.Digraph, vertex_ids: Dict[ApplicationVertex, str],
118
        progress: ProgressBar):
119
    """
120
    :param ~graphviz.Digraph dot_diagram:
121
    :param dict(~.ApplicationVertex,str) vertex_ids:
122
    :param ~.ProgressBar progress:
123
    """
124
    for partition in progress.over(
1✔
125
            SpynnakerDataView.iterate_partitions(), False):
126
        for edge in partition.edges:
1✔
127
            source_vertex_id = vertex_ids[edge.pre_vertex]
1✔
128
            dest_vertex_id = vertex_ids[edge.post_vertex]
1✔
129
            if isinstance(edge, ProjectionApplicationEdge):
1!
130
                links: Set[str] = set()
1✔
131
                for synapse_info in edge.synapse_information:
1✔
132
                    links.add(str(synapse_info.connector))
1✔
133
                for synapse_str in links:
1✔
134
                    dot_diagram.edge(
1✔
135
                        source_vertex_id, dest_vertex_id, synapse_str)
136
            else:
137
                # Unlabelled edge
138
                dot_diagram.edge(source_vertex_id, dest_vertex_id)
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc