Source code for ffc.uflacs.analysis.graph_symbols

# -*- coding: utf-8 -*-
# Copyright (C) 2011-2017 Martin Sandve Alnæs
#
# This file is part of UFLACS.
#
# UFLACS is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# UFLACS is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with UFLACS. If not, see <http://www.gnu.org/licenses/>.

"""Assigning symbols to computational graph nodes."""

import numpy
from ufl import product

from ffc.uflacs.analysis.crsarray import CRSArray
from ffc.uflacs.analysis.valuenumbering import ValueNumberer
from ffc.uflacs.analysis.expr_shapes import total_shape


[docs]def build_node_shapes(V): """Build total shapes for each node in list representation of expression graph. V is an array of ufl expressions, possibly nonscalar and with free indices. Returning a CRSArray where row i is the total shape of V[i]. """ # Dimensions of returned CRSArray nv = len(V) k = 0 # Store shapes intermediately in an array of tuples V_shapes = numpy.empty(nv, dtype=object) for i, v in enumerate(V): # Compute total shape of V[i] tsh = total_shape(v) V_shapes[i] = tsh # Count number of elements for CRSArray representation k += len(tsh) # Return a more memory efficient CRSArray representation
return CRSArray.from_rows(V_shapes, nv, k, int)
[docs]def build_node_sizes(V_shapes): "Compute all the products of a sequence of shapes." nv = len(V_shapes) V_sizes = numpy.zeros(nv, dtype=int) for i, sh in enumerate(V_shapes): V_sizes[i] = product(sh)
return V_sizes
[docs]def build_node_symbols(V, e2i, V_shapes, V_sizes): """Tabulate scalar value numbering of all nodes in a a list based representation of an expression graph. Returns: V_symbols - CRSArray of symbols (value numbers) of each component of each node in V. total_unique_symbols - The number of symbol values assigned to unique scalar components of the nodes in V. """ # "Sparse" int matrix for storing variable number of entries (symbols) per row (vertex), # with a capasity bounded by the number of scalar subexpressions including repetitions V_symbols = CRSArray(len(V), sum(V_sizes), int) # Visit each node with value numberer algorithm, storing the result for each as a row in the V_symbols CRSArray value_numberer = ValueNumberer(e2i, V_sizes, V_symbols) for i, v in enumerate(V): V_symbols.push_row(value_numberer(v, i)) # Get the actual number of symbols created total_unique_symbols = value_numberer.symbol_count # assert all(x < total_unique_symbols for x in V_symbols.data) # assert (total_unique_symbols-1) in V_symbols.data
return V_symbols, total_unique_symbols
[docs]def build_graph_symbols(V, e2i, DEBUG): """Tabulate scalar value numbering of all nodes in a a list based representation of an expression graph. Returns: V_shapes - CRSArray of the total shapes of nodes in V. V_symbols - CRSArray of symbols (value numbers) of each component of each node in V. total_unique_symbols - The number of symbol values assigned to unique scalar components of the nodes in V. """ # Compute the total shape (value shape x index dimensions) for each node V_shapes = build_node_shapes(V) # Compute the total value size for each node V_sizes = build_node_sizes(V_shapes) # Mark values with symbols V_symbols, total_unique_symbols = build_node_symbols(V, e2i, V_shapes, V_sizes)
return V_shapes, V_symbols, total_unique_symbols