Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
No results found
Show changes
Showing
with 9128 additions and 551 deletions
import os
import runpy
import sys
import tempfile
import warnings
import nbformat
import pytest
from nbconvert import PythonExporter
from pystencils.boundaries.createindexlist import * # NOQA
# Trigger config file reading / creation once - to avoid race conditions when multiple instances are creating it
# at the same time
from pystencils.cpu import cpujit
# trigger cython imports - there seems to be a problem when multiple processes try to compile the same cython file
# at the same time
try:
import pyximport
pyximport.install(language_level=3)
except ImportError:
pass
SCRIPT_FOLDER = os.path.dirname(os.path.realpath(__file__))
sys.path.insert(0, os.path.abspath('pystencils'))
# the Ubuntu pipeline uses an older version of pytest which uses deprecated functionality.
# This leads to many warinings in the test and coverage pipeline.
pytest_numeric_version = [int(x, 10) for x in pytest.__version__.split('.')]
pytest_numeric_version.reverse()
pytest_version = sum(x * (100 ** i) for i, x in enumerate(pytest_numeric_version))
def add_path_to_ignore(path):
if not os.path.exists(path):
return
global collect_ignore
collect_ignore += [os.path.join(SCRIPT_FOLDER, path, f) for f in os.listdir(os.path.join(SCRIPT_FOLDER, path))]
collect_ignore = [os.path.join(SCRIPT_FOLDER, "doc", "conf.py"),
os.path.join(SCRIPT_FOLDER, "src", "pystencils", "opencl", "opencl.autoinit")]
add_path_to_ignore('tests/benchmark')
add_path_to_ignore('_local_tmp')
try:
import cupy
except ImportError:
collect_ignore += [os.path.join(SCRIPT_FOLDER, "tests/test_gpu.py")]
add_path_to_ignore('src/pystencils/gpu')
try:
import waLBerla
except ImportError:
collect_ignore += [os.path.join(SCRIPT_FOLDER, "tests/test_aligned_array.py"),
os.path.join(SCRIPT_FOLDER, "tests/test_datahandling_parallel.py"),
os.path.join(SCRIPT_FOLDER, "doc/notebooks/03_tutorial_datahandling.ipynb"),
os.path.join(SCRIPT_FOLDER, "src/pystencils/datahandling/parallel_datahandling.py"),
os.path.join(SCRIPT_FOLDER, "tests/test_small_block_benchmark.ipynb")]
try:
import blitzdb
except ImportError:
add_path_to_ignore('src/pystencils/runhelper')
collect_ignore += [os.path.join(SCRIPT_FOLDER, "tests/test_parameterstudy.py")]
collect_ignore += [os.path.join(SCRIPT_FOLDER, "tests/test_json_serializer.py")]
try:
import islpy
except ImportError:
collect_ignore += [os.path.join(SCRIPT_FOLDER, "src/pystencils/integer_set_analysis.py")]
try:
import graphviz
except ImportError:
collect_ignore += [os.path.join(SCRIPT_FOLDER, "src/pystencils/backends/dot.py")]
collect_ignore += [os.path.join(SCRIPT_FOLDER, "doc/notebooks/01_tutorial_getting_started.ipynb")]
try:
import pyevtk
except ImportError:
collect_ignore += [os.path.join(SCRIPT_FOLDER, "src/pystencils/datahandling/vtk.py")]
collect_ignore += [os.path.join(SCRIPT_FOLDER, 'setup.py')]
for root, sub_dirs, files in os.walk('.'):
for f in files:
if f.endswith(".ipynb") and not any(f.startswith(k) for k in ['demo', 'tutorial', 'test', 'doc']):
collect_ignore.append(f)
class IPythonMockup:
def run_line_magic(self, *args, **kwargs):
pass
def run_cell_magic(self, *args, **kwargs):
pass
def magic(self, *args, **kwargs):
pass
def __bool__(self):
return False
class IPyNbTest(pytest.Item):
def __init__(self, name, parent, code):
super(IPyNbTest, self).__init__(name, parent)
self.code = code
self.add_marker('notebook')
@pytest.mark.filterwarnings("ignore:IPython.core.inputsplitter is deprecated")
def runtest(self):
global_dict = {'get_ipython': lambda: IPythonMockup(),
'is_test_run': True}
# disable matplotlib output
exec("import matplotlib.pyplot as p; "
"p.switch_backend('Template')", global_dict)
# in notebooks there is an implicit plt.show() - if this is not called a warning is shown when the next
# plot is created. This warning is suppressed here
exec("import warnings;"
"warnings.filterwarnings('ignore', 'Adding an axes using the same arguments as a previous.*')",
global_dict)
with tempfile.NamedTemporaryFile() as f:
f.write(self.code.encode())
f.flush()
runpy.run_path(f.name, init_globals=global_dict, run_name=self.name)
class IPyNbFile(pytest.File):
def collect(self):
exporter = PythonExporter()
exporter.exclude_markdown = True
exporter.exclude_input_prompt = True
notebook_contents = self.fspath.open(encoding='utf-8')
with warnings.catch_warnings():
warnings.filterwarnings("ignore", "IPython.core.inputsplitter is deprecated")
notebook = nbformat.read(notebook_contents, 4)
code, _ = exporter.from_notebook_node(notebook)
if pytest_version >= 50403:
yield IPyNbTest.from_parent(name=self.name, parent=self, code=code)
else:
yield IPyNbTest(self.name, self, code)
def teardown(self):
pass
def pytest_collect_file(path, parent):
glob_exprs = ["*demo*.ipynb", "*tutorial*.ipynb", "test_*.ipynb"]
if any(path.fnmatch(g) for g in glob_exprs):
if pytest_version >= 50403:
return IPyNbFile.from_parent(fspath=path, parent=parent)
else:
return IPyNbFile(path, parent)
from pystencils.cpu.kernelcreation import createKernel, addOpenMP
from pystencils.cpu.cpujit import makePythonFunction
from pystencils.backends.cbackend import generateC
import os
import subprocess
from ctypes import cdll, c_double, c_float, sizeof
from tempfile import TemporaryDirectory
from pystencils.backends.cbackend import generateC
import numpy as np
import pickle
import hashlib
from pystencils.transformations import symbolNameToVariableName
CONFIG_GCC = {
'compiler': 'g++',
'flags': '-Ofast -DNDEBUG -fPIC -shared -march=native -fopenmp',
}
CONFIG_INTEL = {
'compiler': '/software/intel/2017/bin/icpc',
'flags': '-Ofast -DNDEBUG -fPIC -shared -march=native -fopenmp -Wl,-rpath=/software/intel/2017/lib/intel64',
'env': {
'INTEL_LICENSE_FILE': '1713@license4.rrze.uni-erlangen.de',
'LM_PROJECT': 'iwia',
}
}
CONFIG_INTEL_SUPERMUC = {
'compiler': '/lrz/sys/intel/studio2017_u1/compilers_and_libraries_2017.1.132/linux/bin/intel64/icpc',
'flags': '-Ofast -DNDEBUG -fPIC -shared -march=native -fopenmp -Wl,'
'-rpath=/lrz/sys/intel/studio2016_u4/compilers_and_libraries_2016.4.258/linux/mkl/lib/intel64',
'env': {
'INTEL_LICENSE_FILE': '/lrz/sys/intel/licenses',
}
}
CONFIG_CLANG = {
'compiler': 'clang++',
'flags': '-Ofast -DNDEBUG -fPIC -shared -march=native -fopenmp',
}
CONFIG = CONFIG_GCC
def ctypeFromString(typename, includePointers=True):
import ctypes as ct
typename = str(typename).replace("*", " * ")
typeComponents = typename.split()
basicTypeMap = {
'double': ct.c_double,
'float': ct.c_float,
'int': ct.c_int,
'long': ct.c_long,
}
resultType = None
for typeComponent in typeComponents:
typeComponent = typeComponent.strip()
if typeComponent == "const" or typeComponent == "restrict" or typeComponent == "volatile":
continue
if typeComponent in basicTypeMap:
resultType = basicTypeMap[typeComponent]
elif typeComponent == "*" and includePointers:
assert resultType is not None
resultType = ct.POINTER(resultType)
return resultType
def ctypeFromNumpyType(numpyType):
typeMap = {
np.dtype('float64'): c_double,
np.dtype('float32'): c_float,
}
return typeMap[numpyType]
def compile(code, tmpDir, libFile, createAssemblyCode=False):
srcFile = os.path.join(tmpDir, 'source.cpp')
with open(srcFile, 'w') as sourceFile:
print('#include <iostream>', file=sourceFile)
print("#include <cmath>", file=sourceFile)
print('extern "C" { ', file=sourceFile)
print(code, file=sourceFile)
print('}', file=sourceFile)
compilerCmd = [CONFIG['compiler']] + CONFIG['flags'].split()
compilerCmd += [srcFile, '-o', libFile]
configEnv = CONFIG['env'] if 'env' in CONFIG else {}
env = os.environ.copy()
env.update(configEnv)
subprocess.call(compilerCmd, env=env)
assembly = None
if createAssemblyCode:
assemblyFile = os.path.join(tmpDir, "assembly.s")
compilerCmd = [CONFIG['compiler'], '-S', '-o', assemblyFile, srcFile] + CONFIG['flags'].split()
subprocess.call(compilerCmd, env=env)
assembly = open(assemblyFile, 'r').read()
return assembly
def compileAndLoad(kernelFunctionNode):
with TemporaryDirectory() as tmpDir:
libFile = os.path.join(tmpDir, "jit.so")
compile(generateC(kernelFunctionNode), tmpDir, libFile)
loadedJitLib = cdll.LoadLibrary(libFile)
return loadedJitLib
def buildCTypeArgumentList(parameterSpecification, argumentDict):
argumentDict = {symbolNameToVariableName(k): v for k, v in argumentDict.items()}
ctArguments = []
for arg in parameterSpecification:
if arg.isFieldArgument:
field = argumentDict[arg.fieldName]
if arg.isFieldPtrArgument:
ctArguments.append(field.ctypes.data_as(ctypeFromString(arg.dtype)))
elif arg.isFieldShapeArgument:
dataType = ctypeFromString(arg.dtype, includePointers=False)
ctArguments.append(field.ctypes.shape_as(dataType))
elif arg.isFieldStrideArgument:
dataType = ctypeFromString(arg.dtype, includePointers=False)
baseFieldType = ctypeFromNumpyType(field.dtype)
strides = field.ctypes.strides_as(dataType)
for i in range(len(field.shape)):
assert strides[i] % sizeof(baseFieldType) == 0
strides[i] //= sizeof(baseFieldType)
ctArguments.append(strides)
else:
assert False
else:
param = argumentDict[arg.name]
expectedType = ctypeFromString(arg.dtype)
ctArguments.append(expectedType(param))
return ctArguments
def makePythonFunctionIncompleteParams(kernelFunctionNode, argumentDict):
func = compileAndLoad(kernelFunctionNode)[kernelFunctionNode.functionName]
func.restype = None
parameters = kernelFunctionNode.parameters
def wrapper(**kwargs):
from copy import copy
fullArguments = copy(argumentDict)
fullArguments.update(kwargs)
args = buildCTypeArgumentList(parameters, fullArguments)
func(*args)
return wrapper
def makePythonFunction(kernelFunctionNode, argumentDict={}):
"""
Creates C code from the abstract syntax tree, compiles it and makes it accessible as Python function
The parameters of the kernel are:
- numpy arrays for each field used in the kernel. The keyword argument name is the name of the field
- all symbols which are not defined in the kernel itself are expected as parameters
:param kernelFunctionNode: the abstract syntax tree
:param argumentDict: parameters passed here are already fixed. Remaining parameters have to be passed to the
returned kernel functor.
:return: kernel functor
"""
# build up list of CType arguments
try:
args = buildCTypeArgumentList(kernelFunctionNode.parameters, argumentDict)
except KeyError:
# not all parameters specified yet
return makePythonFunctionIncompleteParams(kernelFunctionNode, argumentDict)
func = compileAndLoad(kernelFunctionNode)[kernelFunctionNode.functionName]
func.restype = None
return lambda: func(*args)
class CachedKernel:
def __init__(self, configDict, ast, parameterValues):
self.configDict = configDict
self.ast = ast
self.parameterValues = parameterValues
self.funcPtr = None
def __compile(self):
self.funcPtr = makePythonFunction(self.ast, self.parameterValues)
def __call__(self, *args, **kwargs):
if self.funcPtr is None:
self.__compile()
self.funcPtr(*args, **kwargs)
def hashToFunctionName(h):
res = "func_%s" % (h,)
return res.replace('-', 'm')
def createLibrary(cachedKernels, libraryFile):
libraryInfoFile = libraryFile + ".info"
with TemporaryDirectory() as tmpDir:
code = ""
infoDict = {}
for cachedKernel in cachedKernels:
s = repr(sorted(cachedKernel.configDict.items()))
configHash = hashlib.sha1(s.encode()).hexdigest()
cachedKernel.ast.functionName = hashToFunctionName(configHash)
kernelCode = generateC(cachedKernel.ast)
code += kernelCode + "\n"
infoDict[configHash] = {'code': kernelCode,
'parameterValues': cachedKernel.parameterValues,
'configDict': cachedKernel.configDict,
'parameterSpecification': cachedKernel.ast.parameters}
compile(code, tmpDir, libraryFile)
pickle.dump(infoDict, open(libraryInfoFile, "wb"))
def loadLibrary(libraryFile):
libraryInfoFile = libraryFile + ".info"
libraryFile = cdll.LoadLibrary(libraryFile)
libraryInfo = pickle.load(open(libraryInfoFile, 'rb'))
def getKernel(**kwargs):
s = repr(sorted(kwargs.items()))
configHash = hashlib.sha1(s.encode()).hexdigest()
if configHash not in libraryInfo:
raise ValueError("No such kernel in library")
func = libraryFile[hashToFunctionName(configHash)]
func.restype = None
def wrapper(**kwargs):
from copy import copy
fullArguments = copy(libraryInfo[configHash]['parameterValues'])
fullArguments.update(kwargs)
args = buildCTypeArgumentList(libraryInfo[configHash]['parameterSpecification'], fullArguments)
func(*args)
wrapper.configDict = libraryInfo[configHash]['configDict']
return wrapper
return getKernel
from pystencils.transformations import makeLoopOverDomain, typingFromSympyInspection, \
typeAllEquations, moveConstantsBeforeLoop, getOptimalLoopOrdering
import pystencils.ast as ast
from pystencils.backends.cbackend import CBackend, CustomSympyPrinter
from pystencils import TypedSymbol
def createKerncraftCode(listOfEquations, typeForSymbol=None, ghostLayers=None):
"""
Creates an abstract syntax tree for a kernel function, by taking a list of update rules.
Loops are created according to the field accesses in the equations.
:param listOfEquations: list of sympy equations, containing accesses to :class:`pystencils.field.Field`.
Defining the update rules of the kernel
:param typeForSymbol: a map from symbol name to a C type specifier. If not specified all symbols are assumed to
be of type 'double' except symbols which occur on the left hand side of equations where the
right hand side is a sympy Boolean which are assumed to be 'bool' .
:param ghostLayers: a sequence of pairs for each coordinate with lower and upper nr of ghost layers
if None, the number of ghost layers is determined automatically and assumed to be equal for a
all dimensions
:return: :class:`pystencils.ast.KernelFunction` node
"""
if not typeForSymbol:
typeForSymbol = typingFromSympyInspection(listOfEquations, "double")
fieldsRead, fieldsWritten, assignments = typeAllEquations(listOfEquations, typeForSymbol)
allFields = fieldsRead.union(fieldsWritten)
optimalLoopOrder = getOptimalLoopOrdering(allFields)
cstyleLoopOrder = list(range(len(optimalLoopOrder)))
body = ast.Block(assignments)
code = makeLoopOverDomain(body, "kerncraft", ghostLayers=ghostLayers, loopOrder=cstyleLoopOrder)
moveConstantsBeforeLoop(code)
loopBody = code.body
printer = CBackend(sympyPrinter=ArraySympyPrinter())
FIXED_SIZES = ("XS", "YS", "ZS", "E1S", "E2S")
result = ""
for field in allFields:
sizesPermutation = [FIXED_SIZES[i] for i in field.layout]
suffix = "".join("[%s]" % (size,) for size in sizesPermutation)
result += "%s%s;\n" % (field.name, suffix)
# add parameter definitions
for s in loopBody.undefinedSymbols:
if isinstance(s, TypedSymbol):
result += "%s %s;\n" % (s.dtype, s.name)
for element in loopBody.args:
result += printer(element)
result += "\n"
return result
class ArraySympyPrinter(CustomSympyPrinter):
def _print_Access(self, fieldAccess):
""""""
Loop = ast.LoopOverCoordinate
coordinateValues = [Loop.getLoopCounterSymbol(i) + offset for i, offset in enumerate(fieldAccess.offsets)]
coordinateValues += list(fieldAccess.index)
permutedCoordinates = [coordinateValues[i] for i in fieldAccess.field.layout]
suffix = "".join("[%s]" % (self._print(a)) for a in permutedCoordinates)
return "%s%s" % (self._print(fieldAccess.field.name), suffix)
import sympy as sp
from pystencils.transformations import resolveFieldAccesses, makeLoopOverDomain, typingFromSympyInspection, \
typeAllEquations, getOptimalLoopOrdering, parseBasePointerInfo, moveConstantsBeforeLoop, splitInnerLoop
from pystencils.types import TypedSymbol
from pystencils.field import Field
import pystencils.ast as ast
def createKernel(listOfEquations, functionName="kernel", typeForSymbol=None, splitGroups=(),
iterationSlice=None, ghostLayers=None):
"""
Creates an abstract syntax tree for a kernel function, by taking a list of update rules.
Loops are created according to the field accesses in the equations.
:param listOfEquations: list of sympy equations, containing accesses to :class:`pystencils.field.Field`.
Defining the update rules of the kernel
:param functionName: name of the generated function - only important if generated code is written out
:param typeForSymbol: a map from symbol name to a C type specifier. If not specified all symbols are assumed to
be of type 'double' except symbols which occur on the left hand side of equations where the
right hand side is a sympy Boolean which are assumed to be 'bool' .
:param splitGroups: Specification on how to split up inner loop into multiple loops. For details see
transformation :func:`pystencils.transformation.splitInnerLoop`
:param iterationSlice: if not None, iteration is done only over this slice of the field
:param ghostLayers: a sequence of pairs for each coordinate with lower and upper nr of ghost layers
if None, the number of ghost layers is determined automatically and assumed to be equal for a
all dimensions
:return: :class:`pystencils.ast.KernelFunction` node
"""
if not typeForSymbol or typeForSymbol == 'double':
typeForSymbol = typingFromSympyInspection(listOfEquations, "double")
elif typeForSymbol == 'float':
typeForSymbol = typingFromSympyInspection(listOfEquations, "float")
def typeSymbol(term):
if isinstance(term, Field.Access) or isinstance(term, TypedSymbol):
return term
elif isinstance(term, sp.Symbol):
return TypedSymbol(term.name, typeForSymbol[term.name])
else:
raise ValueError("Term has to be field access or symbol")
fieldsRead, fieldsWritten, assignments = typeAllEquations(listOfEquations, typeForSymbol)
allFields = fieldsRead.union(fieldsWritten)
readOnlyFields = set([f.name for f in fieldsRead - fieldsWritten])
body = ast.Block(assignments)
loopOrder = getOptimalLoopOrdering(allFields)
code = makeLoopOverDomain(body, functionName, iterationSlice=iterationSlice,
ghostLayers=ghostLayers, loopOrder=loopOrder)
if splitGroups:
typedSplitGroups = [[typeSymbol(s) for s in splitGroup] for splitGroup in splitGroups]
splitInnerLoop(code, typedSplitGroups)
basePointerInfo = [['spatialInner0'], ['spatialInner1']]
basePointerInfos = {field.name: parseBasePointerInfo(basePointerInfo, loopOrder, field) for field in allFields}
resolveFieldAccesses(code, readOnlyFields, fieldToBasePointerInfo=basePointerInfos)
moveConstantsBeforeLoop(code)
return code
def addOpenMP(astNode, schedule="static", numThreads=None):
"""
Parallelizes the outer loop with OpenMP
:param astNode: abstract syntax tree created e.g. by :func:`createKernel`
:param schedule: OpenMP scheduling policy e.g. 'static' or 'dynamic'
:param numThreads: explicitly specify number of threads
"""
assert type(astNode) is ast.KernelFunction
body = astNode.body
threadsClause = "" if numThreads is None else " num_threads(%s)" % (numThreads,)
wrapperBlock = ast.PragmaBlock('#pragma omp parallel' + threadsClause, body.takeChildNodes())
body.append(wrapperBlock)
outerLoops = [l for l in body.atoms(ast.LoopOverCoordinate) if l.isOutermostLoop]
assert outerLoops, "No outer loop found"
assert len(outerLoops) <= 1, "More than one outer loop found. Which one should be parallelized?"
outerLoops[0].prefixLines.append("#pragma omp for schedule(%s)" % (schedule,))
def toDot(expr, graphStyle={}):
"""Show a sympy or pystencils AST as dot graph"""
from pystencils.ast import Node
import graphviz
if isinstance(expr, Node):
from pystencils.backends.dot import dotprint
return graphviz.Source(dotprint(expr, short=True, graph_attr=graphStyle))
else:
from sympy.printing.dot import dotprint
return graphviz.Source(dotprint(expr, graph_attr=graphStyle))
def highlightCpp(code):
"""Highlight the given C/C++ source code with Pygments"""
from IPython.display import HTML, display
from pygments import highlight
from pygments.formatters import HtmlFormatter
from pygments.lexers import CppLexer
display(HTML("""
<style>
{pygments_css}
</style>
""".format(pygments_css=HtmlFormatter().get_style_defs('.highlight'))))
return HTML(highlight(code, CppLexer(), HtmlFormatter()))
# ----------------- Embedding of animations as videos in IPython notebooks ---------------------------------------------
# ------- Version 1: Animation is embedded as an HTML5 Video tag ---------------------------------------
VIDEO_TAG = """<video controls width="100%">
<source src="data:video/x-m4v;base64,{0}" type="video/mp4">
Your browser does not support the video tag.
</video>"""
def __anim_to_html(anim, fps):
from tempfile import NamedTemporaryFile
import base64
if not hasattr(anim, '_encoded_video'):
with NamedTemporaryFile(suffix='.mp4') as f:
anim.save(f.name, fps=fps, extra_args=['-vcodec', 'libx264', '-pix_fmt',
'yuv420p', '-profile:v', 'baseline', '-level', '3.0'])
video = open(f.name, "rb").read()
anim._encoded_video = base64.b64encode(video).decode('ascii')
return VIDEO_TAG.format(anim._encoded_video)
def disp_as_video(anim, fps=30, show=True, **kwargs):
import matplotlib.pyplot as plt
from IPython.display import HTML
try:
plt.close(anim._fig)
res = __anim_to_html(anim, fps)
if show:
return HTML(res)
else:
return HTML("")
except KeyboardInterrupt:
pass
# ------- Version 2: Animation is shown in extra matplotlib window ----------------------------------
def disp_extra_window(animation, *args,**kwargs):
import matplotlib.pyplot as plt
fig = plt.gcf()
try:
fig.canvas.manager.window.raise_()
except Exception:
pass
plt.show()
# ------- Version 3: Animation is shown in images that are updated directly in website --------------
def disp_image_update(animation, iterations=10000, *args, **kwargs):
from IPython import display
import matplotlib.pyplot as plt
try:
fig = plt.gcf()
animation._init_draw()
for i in range(iterations):
display.display(fig)
animation._step()
display.clear_output(wait=True)
except KeyboardInterrupt:
pass
# Dispatcher
animation_display_mode = 'imageupdate'
display_animation_func = None
def disp(*args, **kwargs):
if not display_animation_func:
raise Exception("Call set_display_mode first")
return display_animation_func(*args, **kwargs)
def set_display_mode(mode):
from IPython import get_ipython
ipython = get_ipython()
global animation_display_mode
global display_animation_func
animation_display_mode = mode
if animation_display_mode == 'video':
ipython.magic("matplotlib inline")
display_animation_func = disp_as_video
elif animation_display_mode == 'window':
ipython.magic("matplotlib qt")
display_animation_func = disp_extra_window
elif animation_display_mode == 'imageupdate':
ipython.magic("matplotlib inline")
display_animation_func = disp_image_update
else:
raise Exception("Unknown mode. Available modes 'imageupdate', 'video' and 'window' ")
set_display_mode('video')
# --------------------- Convenience functions --------------------------------------------------------------------------
def makeSurfacePlotAnimation(runFunction, frames=90, interval=30):
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.animation as animation
import matplotlib.pyplot as plt
from matplotlib import cm
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
X, Y, data = runFunction(1)
ax.plot_surface(X, Y, data, rstride=2, cstride=2, color='b', cmap=cm.coolwarm,)
ax.set_zlim(-1.0, 1.0)
def updatefig(*args):
X, Y, data = runFunction(1)
ax.clear()
plot = ax.plot_surface(X, Y, data, rstride=2, cstride=2, color='b', cmap=cm.coolwarm,)
ax.set_zlim(-1.0, 1.0)
return plot,
return animation.FuncAnimation(fig, updatefig, interval=interval, frames=frames, blit=False)
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
#
import datetime
import sphinx_rtd_theme
import os
import re
import sys
sys.path.insert(0, os.path.abspath('.'))
import pystencils
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.doctest',
'sphinx.ext.intersphinx',
'sphinx.ext.mathjax',
'sphinx.ext.napoleon',
'nbsphinx',
'sphinxcontrib.bibtex',
'sphinx_autodoc_typehints',
]
add_module_names = False
templates_path = ['_templates']
source_suffix = '.rst'
master_doc = 'index'
copyright = f'{datetime.datetime.now().year}, Martin Bauer, Markus Holzer, Frederik Hennig'
author = 'Martin Bauer, Markus Holzer, Frederik Hennig'
# The short X.Y version (including .devXXXX, rcX, b1 suffixes if present)
version = re.sub(r'(\d+\.\d+)\.\d+(.*)', r'\1\2', pystencils.__version__)
version = re.sub(r'(\.dev\d+).*?$', r'\1', version)
# The full version, including alpha/beta/rc tags.
release = pystencils.__version__
language = 'en'
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store', '**.ipynb_checkpoints']
default_role = 'any'
pygments_style = 'sphinx'
todo_include_todos = False
# Options for HTML output
html_theme_path = [sphinx_rtd_theme.get_html_theme_path()]
html_theme = 'sphinx_rtd_theme'
htmlhelp_basename = 'pystencilsdoc'
html_sidebars = {'**': ['globaltoc.html', 'relations.html', 'sourcelink.html', 'searchbox.html']}
# NbSphinx configuration
nbsphinx_execute = 'never'
nbsphinx_codecell_lexer = 'python3'
# Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = {'python': ('https://docs.python.org/3.8', None),
'numpy': ('https://docs.scipy.org/doc/numpy/', None),
'matplotlib': ('https://matplotlib.org/', None),
'sympy': ('https://docs.sympy.org/latest/', None),
}
autodoc_member_order = 'bysource'
bibtex_bibfiles = ['sphinx/pystencils.bib']
project = 'pystencils'
html_logo = 'img/logo.png'
This source diff could not be displayed because it is too large. You can view the blob instead.
doc/img/github_repo_card.png

78.4 KiB

doc/img/logo.png

9.88 KiB

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="53.913792mm"
height="53.913792mm"
viewBox="0 0 191.03312 191.03312"
id="svg2"
version="1.1"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="logo.svg"
inkscape:export-filename="/local/bauer/code/lbmpy/pystencils/doc/img/logo.png"
inkscape:export-xdpi="350"
inkscape:export-ydpi="350">
<defs
id="defs4">
<inkscape:path-effect
effect="spiro"
id="path-effect4188"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect4188-5"
is_visible="true" />
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4596">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4598" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4600" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4602" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4604" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4606" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4608">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4610" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4612" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4614" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4616" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4618" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4620">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4622" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4624" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4626" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4628" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4630" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4632">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4634" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4636" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4638" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4640" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4642" />
</filter>
<inkscape:path-effect
effect="spiro"
id="path-effect4188-7"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect4188-5-6"
is_visible="true" />
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4596-6">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4598-6" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4600-9" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4602-1" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4604-4" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4606-3" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4620-1">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4622-1" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4624-4" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4626-8" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4628-5" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4630-7" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4632-1">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4634-9" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4636-8" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4638-7" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4640-6" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4642-5" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4608-0">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4610-2" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4612-5" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4614-7" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4616-6" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4618-9" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="-48.443059"
inkscape:cy="134.59857"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1447"
inkscape:window-height="1154"
inkscape:window-x="2586"
inkscape:window-y="191"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0">
<inkscape:grid
type="xygrid"
id="grid4176"
originx="-375.0827"
originy="-543.01469" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-375.08269,-318.31438)">
<rect
style="opacity:1;fill:#ffffff;fill-opacity:1;stroke:#d2d2d2;stroke-width:1.80409861;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect1396-1"
width="189.22902"
height="189.22902"
x="375.98474"
y="319.21643"
ry="10.417198"
inkscape:export-xdpi="70.669998"
inkscape:export-ydpi="70.669998" />
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:7.49999952px;line-height:125%;font-family:'Latin Modern Mono Light';-inkscape-font-specification:'Latin Modern Mono Light, ';letter-spacing:0px;word-spacing:0px;fill:#252525;fill-opacity:1;stroke:none;stroke-width:0.93749994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="382.84055"
y="485.91989"
id="text1392-1"
inkscape:export-xdpi="70.669998"
inkscape:export-ydpi="70.669998"><tspan
sodipodi:role="line"
id="tspan1390-1"
x="382.84055"
y="485.91989"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:33.75000381px;font-family:'Latin Modern Mono Light';-inkscape-font-specification:'Latin Modern Mono Light, Bold';fill:#252525;fill-opacity:1;stroke-width:0.93749994px">pystencils</tspan></text>
<g
id="g9986"
transform="matrix(1.7743145,0,0,1.7743145,311.73549,345.04841)"
inkscape:export-xdpi="70.669998"
inkscape:export-ydpi="70.669998">
<path
inkscape:connector-curvature="0"
inkscape:original-d="M 60.891002,27.333516 H 118.64865"
inkscape:path-effect="#path-effect4188-7"
id="path4186-6"
d="M 60.891002,27.333516 H 118.64865"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.78799796;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.70388345" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
inkscape:original-d="M 89.922623,-0.47572315 C 31.237244,132.88729 89.846228,36.88339 89.846228,56.13594"
inkscape:path-effect="#path-effect4188-5-6"
id="path4186-3-9"
d="M 89.922623,-0.47572315 89.846228,56.13594"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.78799796;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.70388345" />
<circle
transform="matrix(0.21391721,0,0,0.21391721,27.733834,-23.442344)"
r="34.345188"
cy="108.02044"
cx="291.42902"
id="path4136-76"
style="opacity:1;fill:#e69f00;fill-opacity:1;stroke:none;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter4596-6)" />
<circle
transform="matrix(0.21391721,0,0,0.21391721,27.733834,-23.442344)"
r="34.345188"
cy="365.43817"
cx="290.41885"
id="path4136-6-0"
style="opacity:1;fill:#0072b2;fill-opacity:1;stroke:none;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter4620-1)" />
<circle
transform="matrix(0.21391721,0,0,0.21391721,27.733834,-23.442344)"
r="34.345188"
cy="236.72931"
cx="422.24377"
id="path4136-3-9"
style="opacity:1;fill:#999999;fill-opacity:1;stroke:none;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter4632-1)" />
<circle
transform="matrix(0.21391721,0,0,0.21391721,27.733834,-23.442344)"
r="34.345188"
cy="236.72931"
cx="155.56349"
id="path4136-7-0"
style="opacity:1;fill:#009e73;fill-opacity:1;stroke:none;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter4608-0)" />
</g>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="379.82614mm"
height="189.91307mm"
viewBox="0 0 1345.8407 672.92033"
id="svg2"
version="1.1"
inkscape:version="0.92.3 (2405546, 2018-03-11)"
sodipodi:docname="logo_large.svg"
inkscape:export-filename="/home/martin/code/pycodegen/pystencils/doc/img/github_repo_card.png"
inkscape:export-xdpi="85.599998"
inkscape:export-ydpi="85.599998">
<defs
id="defs4">
<inkscape:path-effect
effect="spiro"
id="path-effect4188"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect4188-5"
is_visible="true" />
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4596">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4598" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4600" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4602" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4604" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4606" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4608">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4610" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4612" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4614" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4616" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4618" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4620">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4622" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4624" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4626" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4628" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4630" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4632">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4634" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4636" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4638" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4640" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4642" />
</filter>
<inkscape:path-effect
effect="spiro"
id="path-effect4188-7"
is_visible="true" />
<inkscape:path-effect
effect="spiro"
id="path-effect4188-5-6"
is_visible="true" />
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4596-6">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4598-6" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4600-9" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4602-1" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4604-4" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4606-3" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4620-1">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4622-1" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4624-4" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4626-8" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4628-5" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4630-7" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4632-1">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4634-9" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4636-8" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4638-7" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4640-6" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4642-5" />
</filter>
<filter
y="-0.25"
height="1.5"
inkscape:menu-tooltip="Darkens the edge with an inner blur and adds a flexible glow"
inkscape:menu="Shadows and Glows"
inkscape:label="Dark And Glow"
style="color-interpolation-filters:sRGB"
id="filter4608-0">
<feGaussianBlur
stdDeviation="5"
result="result6"
id="feGaussianBlur4610-2" />
<feComposite
result="result8"
in="SourceGraphic"
operator="atop"
in2="result6"
id="feComposite4612-5" />
<feComposite
result="result9"
operator="over"
in2="SourceAlpha"
in="result8"
id="feComposite4614-7" />
<feColorMatrix
values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0 "
result="result10"
id="feColorMatrix4616-6" />
<feBlend
in="result10"
mode="normal"
in2="result6"
id="feBlend4618-9" />
</filter>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="0.70000001"
inkscape:cx="545.01294"
inkscape:cy="35.725386"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="3840"
inkscape:window-height="2061"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0">
<inkscape:grid
type="xygrid"
id="grid4176"
originx="267.20477"
originy="315.17846" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(267.20477,-694.6203)">
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:34.78659058px;line-height:125%;font-family:'Latin Modern Mono Light';-inkscape-font-specification:'Latin Modern Mono Light, ';letter-spacing:0px;word-spacing:0px;fill:#252525;fill-opacity:1;stroke:none;stroke-width:4.34832382px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="159.99139"
y="964.43109"
id="text1392-1"
inkscape:export-xdpi="70.669998"
inkscape:export-ydpi="70.669998"><tspan
sodipodi:role="line"
id="tspan1390-1"
x="159.99139"
y="964.43109"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:156.53968811px;font-family:'Latin Modern Mono Light';-inkscape-font-specification:'Latin Modern Mono Light, Bold';fill:#252525;fill-opacity:1;stroke-width:4.34832382px">pystencils</tspan></text>
<g
id="g9986"
transform="matrix(4.1201463,0,0,4.1201463,-399.75066,866.02979)"
inkscape:export-xdpi="70.669998"
inkscape:export-ydpi="70.669998">
<path
inkscape:connector-curvature="0"
inkscape:original-d="M 60.891002,27.333516 H 118.64865"
inkscape:path-effect="#path-effect4188-7"
id="path4186-6"
d="M 60.891002,27.333516 H 118.64865"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.78799796;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.70388345" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
inkscape:original-d="M 89.922623,-0.47572315 C 31.237244,132.88729 89.846228,36.88339 89.846228,56.13594"
inkscape:path-effect="#path-effect4188-5-6"
id="path4186-3-9"
d="M 89.922623,-0.47572315 89.846228,56.13594"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:2.78799796;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.70388345" />
<circle
transform="matrix(0.21391721,0,0,0.21391721,27.733834,-23.442344)"
r="34.345188"
cy="108.02044"
cx="291.42902"
id="path4136-76"
style="opacity:1;fill:#e69f00;fill-opacity:1;stroke:none;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter4596-6)" />
<circle
transform="matrix(0.21391721,0,0,0.21391721,27.733834,-23.442344)"
r="34.345188"
cy="365.43817"
cx="290.41885"
id="path4136-6-0"
style="opacity:1;fill:#0072b2;fill-opacity:1;stroke:none;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter4620-1)" />
<circle
transform="matrix(0.21391721,0,0,0.21391721,27.733834,-23.442344)"
r="34.345188"
cy="236.72931"
cx="422.24377"
id="path4136-3-9"
style="opacity:1;fill:#999999;fill-opacity:1;stroke:none;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter4632-1)" />
<circle
transform="matrix(0.21391721,0,0,0.21391721,27.733834,-23.442344)"
r="34.345188"
cy="236.72931"
cx="155.56349"
id="path4136-7-0"
style="opacity:1;fill:#009e73;fill-opacity:1;stroke:none;stroke-width:3;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;filter:url(#filter4608-0)" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.7668047px;line-height:125%;font-family:'Latin Modern Mono Light';-inkscape-font-specification:'Latin Modern Mono Light, ';letter-spacing:0px;word-spacing:0px;fill:#252525;fill-opacity:0.70629368;stroke:none;stroke-width:1.09585059px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="229.96391"
y="1071.713"
id="text1392-1-3"
inkscape:export-xdpi="70.669998"
inkscape:export-ydpi="70.669998"><tspan
sodipodi:role="line"
id="tspan1390-1-6"
x="229.96391"
y="1071.713"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:62.0406723px;line-height:105.99999428%;font-family:'Latin Modern Mono Light';-inkscape-font-specification:'Latin Modern Mono Light, Bold';fill:#252525;fill-opacity:0.70629368;stroke-width:1.09585059px">speed up stencil </tspan><tspan
sodipodi:role="line"
x="229.96391"
y="1137.4761"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:62.0406723px;line-height:105.99999428%;font-family:'Latin Modern Mono Light';-inkscape-font-specification:'Latin Modern Mono Light, Bold';fill:#252525;fill-opacity:0.70629368;stroke-width:1.09585059px"
id="tspan109">computations on</tspan><tspan
sodipodi:role="line"
x="229.96391"
y="1203.2393"
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:62.0406723px;line-height:105.99999428%;font-family:'Latin Modern Mono Light';-inkscape-font-specification:'Latin Modern Mono Light, Bold';fill:#252525;fill-opacity:0.70629368;stroke-width:1.09585059px"
id="tspan107">numpy arrays</tspan></text>
</g>
</svg>
doc/img/logo_no_text.png

5.42 KiB

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="127.52666mm"
height="154.66043mm"
viewBox="0 0 451.86614 548.0094"
id="svg5381"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="arch_pystencils.svg">
<defs
id="defs5383">
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker4320"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Lend">
<path
transform="matrix(-0.8,0,0,-0.8,-10,0)"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path4322"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Lend"
orient="auto"
refY="0"
refX="0"
id="marker4274"
style="overflow:visible"
inkscape:isstock="true"
inkscape:collect="always">
<path
inkscape:connector-curvature="0"
id="path4276"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker4549-8-0-1"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Lend"
inkscape:collect="always">
<path
transform="matrix(-0.8,0,0,-0.8,-10,0)"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path4551-4-3-0"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker4549-8-0"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Lend">
<path
transform="matrix(-0.8,0,0,-0.8,-10,0)"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path4551-4-3"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker4549-8"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Lend">
<path
transform="matrix(-0.8,0,0,-0.8,-10,0)"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path4551-4"
inkscape:connector-curvature="0" />
</marker>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.979899"
inkscape:cx="296.09126"
inkscape:cy="379.58263"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
fit-margin-top="10"
fit-margin-left="10"
fit-margin-right="10"
fit-margin-bottom="10"
inkscape:window-width="2560"
inkscape:window-height="1403"
inkscape:window-x="4480"
inkscape:window-y="0"
inkscape:window-maximized="1" />
<metadata
id="metadata5386">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(48.790215,-76.703997)">
<rect
y="207.86151"
x="-12.857142"
height="300.71426"
width="380"
id="rect3338-2"
style="opacity:0.403;fill:#52a5ff;fill-opacity:0.65625;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
<text
sodipodi:linespacing="125%"
id="text4140-7"
y="246.44052"
x="89.340813"
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:27.5px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Bold'"
y="246.44052"
x="89.340813"
id="tspan4142-0"
sodipodi:role="line">pystencils</tspan></text>
<text
sodipodi:linespacing="125%"
id="text5052"
y="392.14828"
x="132.17844"
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="392.14828"
x="132.17844"
id="tspan5054"
sodipodi:role="line">Backends</tspan></text>
<text
inkscape:transform-center-y="22.223356"
inkscape:transform-center-x="-30.809653"
sodipodi:linespacing="125%"
id="text5052-7"
y="277.12802"
x="15.323049"
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="277.12802"
x="15.323049"
id="tspan5054-5"
sodipodi:role="line">Transformations</tspan></text>
<text
inkscape:transform-center-y="22.223356"
inkscape:transform-center-x="-30.809653"
sodipodi:linespacing="125%"
id="text5052-7-9"
y="276.52139"
x="190.22662"
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="276.52139"
x="190.22662"
id="tspan5054-5-2"
sodipodi:role="line">Abstract Syntax Tree</tspan></text>
<g
transform="translate(-152.85714,-230.5007)"
id="g5211">
<rect
style="opacity:0.95800003;fill:#528cff;fill-opacity:1;stroke:#000000;stroke-width:0.81148541;stroke-opacity:1"
id="rect5100"
width="56.803982"
height="28.401972"
x="208.96922"
y="638.3288"
ry="11.536892"
rx="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12.17228222px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="218.23126"
y="657.38635"
id="text5102"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5104"
x="218.23126"
y="657.38635">C(++)</tspan></text>
</g>
<g
transform="translate(-152.85714,-230.5007)"
id="g5221">
<rect
style="opacity:0.95800003;fill:#528cff;fill-opacity:1;stroke:#000000;stroke-width:0.81148541;stroke-opacity:1"
id="rect5100-2"
width="56.803982"
height="28.401972"
x="377.63678"
y="638.73236"
ry="11.536892"
rx="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12.17228222px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="390.89883"
y="657.78992"
id="text5102-8"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5104-9"
x="390.89883"
y="657.78992">LLVM</tspan></text>
</g>
<g
transform="translate(-146.85714,-230.5007)"
id="g5226">
<rect
style="opacity:0.95800003;fill:#4cd9fc;fill-opacity:1;stroke:#000000;stroke-width:0.81148541;stroke-opacity:1"
id="rect5100-7"
width="87.969879"
height="26.406517"
x="159.02757"
y="698.0166"
ry="11.536892"
rx="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="169.97716"
y="715.43323"
id="text5142"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5144"
x="169.97716"
y="715.43323">Python JIT</tspan></text>
</g>
<g
transform="translate(-146.85714,-230.5007)"
id="g5236">
<rect
style="opacity:0.95800003;fill:#4cd9fc;fill-opacity:1;stroke:#000000;stroke-width:0.81148541;stroke-opacity:1"
id="rect5100-7-3-2"
width="87.969879"
height="26.406517"
x="390.64432"
y="697.91504"
ry="11.536892"
rx="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="406.13959"
y="708.26062"
id="text5142-6-9"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
x="406.13959"
y="708.26062"
id="tspan5188"
style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.75px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Italic'">C/C++ </tspan><tspan
sodipodi:role="line"
x="406.13959"
y="719.19812"
style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:8.75px;font-family:sans-serif;-inkscape-font-specification:'sans-serif Italic'"
id="tspan4368">output</tspan></text>
</g>
<g
transform="translate(-153.39138,-230.5007)"
id="g5216">
<rect
style="opacity:0.95800003;fill:#528cff;fill-opacity:1;stroke:#000000;stroke-width:0.81148541;stroke-opacity:1"
id="rect5100-2-1"
width="56.803982"
height="28.401972"
x="293.83725"
y="639.13593"
ry="11.536892"
rx="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12.17228222px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="303.0993"
y="658.19348"
id="text5102-8-9"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5104-9-4"
x="303.0993"
y="658.19348">CUDA</tspan></text>
</g>
<g
transform="matrix(0.69960031,0,0,0.69960031,-114.02169,-104.98602)"
id="g4242">
<rect
style="opacity:0.95800003;fill:#c2b600;fill-opacity:1;stroke:#000000;stroke-width:0.81148541;stroke-opacity:1"
id="rect5100-8"
width="101.08154"
height="28.134911"
x="168.91846"
y="564.22729"
ry="11.536892"
rx="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12.17228222px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="178.1805"
y="583.28485"
id="text5102-4"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5104-5"
x="178.1805"
y="583.28485">Array access</tspan></text>
</g>
<g
transform="matrix(0.69960031,0,0,0.69960031,-39.021686,-129.98602)"
id="g4247">
<rect
style="opacity:0.95800003;fill:#c2b600;fill-opacity:1;stroke:#000000;stroke-width:0.81148541;stroke-opacity:1"
id="rect5100-8-0"
width="101.08154"
height="28.134911"
x="170.2814"
y="599.48108"
ry="11.536892"
rx="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12.17228222px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="177.54344"
y="618.53864"
id="text5102-4-3"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5104-5-6"
x="177.54344"
y="618.53864">Loop Splitting</tspan></text>
</g>
<g
transform="matrix(0.69960031,0,0,0.69960031,-196.87883,-96.77172)"
id="g4252">
<rect
style="opacity:0.95800003;fill:#c2b600;fill-opacity:1;stroke:#000000;stroke-width:0.81148541;stroke-opacity:1"
id="rect5100-8-0-3"
width="101.08154"
height="28.134911"
x="288.13855"
y="589.48108"
ry="11.536892"
rx="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12.17228222px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="336.39984"
y="601.75293"
id="text5102-4-3-6"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5104-5-6-7"
x="336.39984"
y="601.75293"
style="font-size:10px;text-align:center;text-anchor:middle">Move Constants</tspan><tspan
sodipodi:role="line"
x="336.39984"
y="614.25293"
id="tspan4240"
style="font-size:10px;text-align:center;text-anchor:middle">before loop</tspan></text>
</g>
<g
transform="matrix(0.69960031,0,0,0.69960031,-38.970926,-103.97587)"
id="g4247-3">
<rect
style="opacity:0.95800003;fill:#c2b600;fill-opacity:1;stroke:#000000;stroke-width:0.81148541;stroke-opacity:1"
id="rect5100-8-0-6"
width="101.08154"
height="28.134911"
x="170.2814"
y="599.48108"
ry="11.536892"
rx="0" />
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:12.17228222px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="194.69612"
y="618.53864"
id="text5102-4-3-7"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5104-5-6-5"
x="194.69612"
y="618.53864">Blocking</tspan></text>
</g>
<g
transform="translate(-150.71428,-266.13054)"
id="g4281">
<rect
style="opacity:0.95800003;fill:#58ff93;fill-opacity:1;stroke:#000000;stroke-width:0.4340325;stroke-opacity:1"
id="rect5100-8-0-62"
width="42.102448"
height="16.517235"
x="392.89755"
y="555.84497"
ry="6.1706414"
rx="0" />
<g
id="g4277">
<text
sodipodi:linespacing="125%"
id="text5102-4-3-9"
y="566.74445"
x="403.47351"
style="font-style:normal;font-weight:normal;font-size:8.51573277px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="566.74445"
x="403.47351"
id="tspan5104-5-6-1"
sodipodi:role="line">Loop</tspan></text>
</g>
</g>
<g
transform="translate(-200.71428,-266.13054)"
id="g4281-2">
<rect
style="opacity:0.95800003;fill:#58ff93;fill-opacity:1;stroke:#000000;stroke-width:0.4340325;stroke-opacity:1"
id="rect5100-8-0-62-7"
width="42.102448"
height="16.517235"
x="392.89755"
y="555.84497"
ry="6.1706414"
rx="0" />
<g
transform="translate(-4,0)"
id="g4277-0">
<text
sodipodi:linespacing="125%"
id="text5102-4-3-9-9"
y="566.74445"
x="403.47351"
style="font-style:normal;font-weight:normal;font-size:8.51573277px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="566.74445"
x="403.47351"
id="tspan5104-5-6-1-3"
sodipodi:role="line">Kernel</tspan></text>
</g>
</g>
<g
transform="translate(-200.35714,-238.98768)"
id="g4281-1">
<rect
style="opacity:0.95800003;fill:#58ff93;fill-opacity:1;stroke:#000000;stroke-width:0.4340325;stroke-opacity:1"
id="rect5100-8-0-62-8"
width="42.102448"
height="16.517235"
x="392.89755"
y="555.84497"
ry="6.1706414"
rx="0" />
<g
transform="translate(-4,0)"
id="g4277-7">
<text
sodipodi:linespacing="125%"
id="text5102-4-3-9-92"
y="566.74445"
x="403.47351"
style="font-style:normal;font-weight:normal;font-size:8.51573277px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="566.74445"
x="403.47351"
id="tspan5104-5-6-1-0"
sodipodi:role="line">Assign</tspan></text>
</g>
</g>
<g
transform="translate(-99.910712,-266.13054)"
id="g4281-1-2">
<rect
style="opacity:0.95800003;fill:#58ff93;fill-opacity:1;stroke:#000000;stroke-width:0.4340325;stroke-opacity:1"
id="rect5100-8-0-62-8-3"
width="42.102448"
height="16.517235"
x="392.89755"
y="555.84497"
ry="6.1706414"
rx="0" />
<g
transform="translate(-1.4125983,0)"
id="g4277-7-7">
<text
sodipodi:linespacing="125%"
id="text5102-4-3-9-92-5"
y="566.74445"
x="407.47351"
style="font-style:normal;font-weight:normal;font-size:8.51573277px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="566.74445"
x="407.47351"
id="tspan5104-5-6-1-0-9"
sodipodi:role="line">Add</tspan></text>
</g>
</g>
<g
transform="translate(-109.73213,-238.09483)"
id="g4281-1-2-2">
<g
transform="translate(12.678571,1.0714286)"
id="g4413">
<rect
rx="0"
ry="6.1706414"
y="554.59497"
x="390.04041"
height="16.517235"
width="42.102448"
id="rect5100-8-0-62-8-3-2"
style="opacity:0.95800003;fill:#58ff93;fill-opacity:1;stroke:#000000;stroke-width:0.4340325;stroke-opacity:1" />
<g
id="g4277-7-7-8"
transform="translate(-4,0)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:8.51573277px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="407.47351"
y="566.74445"
id="text5102-4-3-9-92-5-9"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan5104-5-6-1-0-9-7"
x="407.47351"
y="566.74445">Mul</tspan></text>
</g>
</g>
</g>
<rect
rx="0"
ry="6.1706414"
y="317.03586"
x="242.68098"
height="16.517235"
width="42.102448"
id="rect5100-8-0-62-8-3-2-1"
style="opacity:0.95800003;fill:#58ff93;fill-opacity:1;stroke:#000000;stroke-width:0.4340325;stroke-opacity:1" />
<g
id="g4277-7-7-8-2"
transform="translate(-156.36991,-238.42268)">
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:8.51573277px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="420.12903"
y="566.74445"
id="text5102-4-3-9-92-5-9-9"
sodipodi:linespacing="125%"><tspan
style="font-size:8.12500095px;text-align:center;text-anchor:middle"
sodipodi:role="line"
id="tspan5104-5-6-1-0-9-7-3"
x="420.12903"
y="566.74445">Condition</tspan></text>
</g>
<text
transform="matrix(-0.00884296,0.9999609,-0.9999609,-0.00884296,0,0)"
sodipodi:linespacing="125%"
id="text4449-1"
y="-78.824646"
x="338.3754"
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="-78.824646"
x="338.3754"
id="tspan4451-9"
sodipodi:role="line">...</tspan></text>
<text
transform="matrix(-0.00884296,0.9999609,-0.9999609,-0.00884296,0,0)"
sodipodi:linespacing="125%"
id="text4449-4"
y="-273.88837"
x="336.65042"
style="font-style:normal;font-weight:normal;font-size:15px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
y="-273.88837"
x="336.65042"
id="tspan4451-7"
sodipodi:role="line">...</tspan></text>
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4175-5"
d="m 167.69728,153.37762 1e-5,53.57142"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker4549-8-0-1)" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4175-5-6"
d="m 67.285707,509.45149 1e-5,53.57142"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4274)" />
<path
sodipodi:nodetypes="cc"
inkscape:connector-curvature="0"
id="path4175-5-6-6"
d="M 292.99999,509.16577 293,562.73719"
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4320)" />
<text
sodipodi:linespacing="125%"
id="text4542"
y="125.43295"
x="169.46426"
style="font-style:normal;font-weight:normal;font-size:20px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
style="font-size:17.5px;text-align:center;text-anchor:middle"
y="125.43295"
x="169.46426"
id="tspan4544"
sodipodi:role="line"><tspan
style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:normal;font-family:sans-serif;-inkscape-font-specification:'sans-serif Italic'"
id="tspan4254">sympy</tspan> Equations containing</tspan><tspan
id="tspan4564"
style="font-size:17.5px;text-align:center;text-anchor:middle"
y="147.30795"
x="169.46426"
sodipodi:role="line">fields (neighbor accesses)</tspan></text>
<text
sodipodi:linespacing="125%"
id="text4542-3"
y="585.6402"
x="20.557117"
style="font-style:normal;font-weight:normal;font-size:20px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
id="tspan4570"
style="font-size:17.5px"
y="585.6402"
x="20.557117"
sodipodi:role="line">Python Function</tspan></text>
<text
sodipodi:linespacing="125%"
id="text4542-3-0"
y="585.24951"
x="239.9693"
style="font-style:normal;font-weight:normal;font-size:20px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
xml:space="preserve"><tspan
id="tspan4570-6"
style="font-size:17.5px"
y="585.24951"
x="239.9693"
sodipodi:role="line">C/C++ Code</tspan></text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="46.566666mm"
height="46.566666mm"
viewBox="0 0 165 164.99999"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
inkscape:export-filename="/home/rzlin/im50ibaq/stencil2.png"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90"
sodipodi:docname="pystencils_stencil_four_points_with_arrows.svg">
<defs
id="defs4">
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0"
refX="0"
id="marker10934"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path10936"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:0.66666667"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0"
refX="0"
id="marker10780"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path10782"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:0.66666667"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0"
refX="0"
id="marker10770"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path10772"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:0.66666667"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker10604"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="TriangleOutL">
<path
transform="scale(0.8,0.8)"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:1pt;stroke-opacity:0.66666667"
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
id="path10606"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker10462"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="TriangleOutL">
<path
transform="scale(0.8,0.8)"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:1pt;stroke-opacity:0.66666667"
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
id="path10464"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker10452"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="TriangleOutL">
<path
transform="scale(0.8,0.8)"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:1pt;stroke-opacity:0.66666667"
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
id="path10454"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker10174"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="TriangleOutL">
<path
transform="scale(0.8,0.8)"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:1pt;stroke-opacity:0.66666667"
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
id="path10176"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker10050"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="TriangleOutL">
<path
transform="scale(0.8,0.8)"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:1pt;stroke-opacity:0.66666667"
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
id="path10052"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker10040"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="TriangleOutL">
<path
transform="scale(0.8,0.8)"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:1pt;stroke-opacity:0.66666667"
d="m 5.77,0 -8.65,5 0,-10 8.65,5 z"
id="path10042"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker9800"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2Lend"
inkscape:collect="always">
<path
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:0.66666667"
id="path9802"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker9694"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2Lend">
<path
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:0.66666667"
id="path9696"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker9684"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2Lend">
<path
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:0.66666667"
id="path9686"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker9478"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2Lend">
<path
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:0.66666667"
id="path9480"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker9390"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2Lend">
<path
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:0.66666667"
id="path9392"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker9308"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2Lend">
<path
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:0.66666667"
id="path9310"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0"
refX="0"
id="marker9074"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path9076"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:0.66666667"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0"
refX="0"
id="marker9064"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path9066"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:0.66666667"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow2Lend"
orient="auto"
refY="0"
refX="0"
id="marker8994"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path8996"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:0.66666667"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker8816"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2Lend">
<path
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:0.66666667"
id="path8818"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker8748"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow2Lend">
<path
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:0.66666667"
id="path8750"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker8640"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Lstart">
<path
transform="matrix(0.8,0,0,0.8,10,0)"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:1pt;stroke-opacity:0.66666667"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path8642"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker8600"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Lstart">
<path
transform="matrix(0.8,0,0,0.8,10,0)"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:1pt;stroke-opacity:0.66666667"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path8602"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:isstock="true"
style="overflow:visible"
id="marker8566"
refX="0"
refY="0"
orient="auto"
inkscape:stockid="Arrow1Lstart">
<path
transform="matrix(0.8,0,0,0.8,10,0)"
style="fill:#aa0a00;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:1pt;stroke-opacity:0.66666667"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
id="path8568"
inkscape:connector-curvature="0" />
</marker>
<inkscape:path-effect
effect="construct_grid"
id="path-effect4531"
is_visible="true"
nr_x="5"
nr_y="5" />
<inkscape:path-effect
effect="construct_grid"
id="path-effect4511"
is_visible="true"
nr_x="5"
nr_y="5" />
<marker
inkscape:stockid="DotL"
orient="auto"
refY="0"
refX="0"
id="DotL"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4221"
d="m -2.5,-1 c 0,2.76 -2.24,5 -5,5 -2.76,0 -5,-2.24 -5,-5 0,-2.76 2.24,-5 5,-5 2.76,0 5,2.24 5,5 z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(0.8,0,0,0.8,5.92,0.8)"
inkscape:connector-curvature="0" />
</marker>
<marker
inkscape:stockid="Arrow1Lstart"
orient="auto"
refY="0"
refX="0"
id="Arrow1Lstart"
style="overflow:visible"
inkscape:isstock="true">
<path
id="path4160"
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
transform="matrix(0.8,0,0,0.8,10,0)"
inkscape:connector-curvature="0" />
</marker>
<linearGradient
id="linearGradient4146"
osb:paint="solid">
<stop
style="stop-color:#0000ff;stop-opacity:1;"
offset="0"
id="stop4148" />
</linearGradient>
</defs>
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="1.4"
inkscape:cx="76.245019"
inkscape:cy="-167.05185"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="true"
inkscape:window-width="2560"
inkscape:window-height="1371"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0">
<inkscape:grid
type="xygrid"
id="grid3342"
originx="-49.99998"
originy="-804.99994" />
</sodipodi:namedview>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-49.999981,-82.36222)">
<path
style="fill:#a70000;fill-opacity:0;stroke:#000000;stroke-width:0.36029893;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:"
d="m 214.81983,82.542339 -164.6397,0 m 164.6397,32.927941 -164.6397,0 m 164.6397,32.92794 -164.6397,0 m 164.6397,32.92794 -164.6397,0 m 164.6397,32.92794 -164.6397,0 m 164.6397,32.92794 -164.6397,0 m 164.6397,-164.639701 0,164.639701 m -32.92794,-164.639701 0,164.639701 m -32.92794,-164.639701 0,164.639701 m -32.92794,-164.639701 0,164.639701 M 83.10807,82.542339 l 0,164.639701 M 50.18013,82.542339 l 0,164.639701"
id="rect4513"
inkscape:path-effect="#path-effect4531"
inkscape:original-d="m 181.89189,82.542339 32.92794,0 0,32.927941 -32.92794,0 z"
inkscape:connector-curvature="0" />
<g
id="g11964"
transform="matrix(0.27499997,0,0,0.27499997,69.249999,59.71259)"
inkscape:export-xdpi="90"
inkscape:export-ydpi="90">
<g
id="g8533">
<circle
style="fill:#0f00aa;fill-opacity:0.66666667;stroke:#000000;stroke-width:1.37272894;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path8465"
cx="230"
cy="262.36221"
r="19.813635" />
<circle
style="fill:#aa0a00;fill-opacity:0.66666667;stroke:#000000;stroke-width:1.37272894;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path8465-6"
cx="230"
cy="142.36221"
r="19.813635" />
<circle
style="fill:#aa0a00;fill-opacity:0.66666667;stroke:#000000;stroke-width:1.37272894;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path8465-5"
cx="110"
cy="262.36221"
r="19.813635" />
<circle
style="fill:#aa0a00;fill-opacity:0.66666667;stroke:#000000;stroke-width:1.37272894;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path8465-7-3"
cx="349.99997"
cy="262.36221"
r="19.813635" />
<circle
style="fill:#aa0a00;fill-opacity:0.66666667;stroke:#000000;stroke-width:1.37272894;stroke-linejoin:bevel;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
id="path8465-7-2"
cx="230"
cy="382.36221"
r="19.813635" />
</g>
<path
inkscape:connector-curvature="0"
inkscape:connector-type="polyline"
id="path8546"
d="m 130,262.3622 80,0"
style="fill:none;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:3.0999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.66666667;marker-end:url(#marker10934)" />
<path
inkscape:connector-curvature="0"
inkscape:connector-type="polyline"
id="path8548"
d="m 230,362.3622 0,-80"
style="fill:none;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:3.0999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.66666667;marker-end:url(#marker9800)" />
<path
inkscape:connector-curvature="0"
inkscape:connector-type="polyline"
id="path8550"
d="m 330,262.3622 -80,0"
style="fill:none;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:3.0999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.66666667;marker-end:url(#marker10770)" />
<path
inkscape:connector-curvature="0"
inkscape:connector-type="polyline"
id="path8552"
d="m 230,162.3622 0,80"
style="fill:none;fill-opacity:0.66666667;fill-rule:evenodd;stroke:#aa0a00;stroke-width:3.0999999;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:0.66666667;marker-end:url(#marker10780)" />
</g>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="128.62013mm"
height="127.02013mm"
viewBox="0 0 128.62013 127.02013"
version="1.1"
id="svg8"
sodipodi:docname="staggeredgrid.svg"
inkscape:version="0.91 r13725"
inkscape:export-filename="/home/rzlin/spmabau2/PaperAndDoc/diss/img/staggeredgrid.png"
inkscape:export-xdpi="751.59003"
inkscape:export-ydpi="751.59003">
<defs
id="defs2" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8"
inkscape:cx="109.09973"
inkscape:cy="179.8226"
inkscape:document-units="mm"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1371"
inkscape:window-x="1920"
inkscape:window-y="0"
inkscape:window-maximized="1"
fit-margin-top="0.2"
fit-margin-left="1"
fit-margin-right="1"
fit-margin-bottom="0.2">
<inkscape:grid
type="xygrid"
id="grid4485"
originx="-16.991665"
originy="-148.39503" />
</sodipodi:namedview>
<metadata
id="metadata5">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-16.991667,-21.584832)">
<g
id="g4832"
transform="matrix(0.8,0,0,0.8,3.6776666,9.6848334)"
inkscape:label="Grid"
inkscape:groupmode="layer">
<g
id="g4800"
inkscape:groupmode="layer"
inkscape:label="InnerPart">
<path
style="fill:none;stroke:#000000;stroke-width:1.23914683px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 51.813899,46.542736 92.936021,0"
id="path4487"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.23914683px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 51.813904,77.521413 92.936016,0"
id="path4487-3"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.23914683px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 51.813904,108.50008 92.936016,0"
id="path4487-3-6"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.23914683px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 51.813904,139.47875 92.936016,0"
id="path4487-3-6-7"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.23914683px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 51.813904,46.542736 0,92.936014"
id="path4487-3-5"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.23914683px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 82.792576,46.542736 0,92.936014"
id="path4487-3-5-3"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.23914683px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 113.77125,46.542736 0,92.936014"
id="path4487-3-5-3-5"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:1.23914683px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
d="m 144.74992,46.542736 0,92.936014"
id="path4487-3-5-3-6"
inkscape:connector-curvature="0" />
</g>
<g
id="g4790"
inkscape:label="GhostLayers"
inkscape:groupmode="layer">
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 20.83523,170.45743 154.89336,0"
id="path4585"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 20.83523,15.564066 154.89336,0"
id="path4585-2"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 175.72859,15.564066 0,154.893364"
id="path4585-2-9"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 20.83523,15.564066 0,154.893364"
id="path4585-2-9-1"
inkscape:connector-curvature="0" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 51.813904,139.47875 0,30.97868"
id="path4585-2-9-1-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 51.813904,15.564062 0,30.978674"
id="path4585-2-9-1-2-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 144.74992,15.564066 0,30.978675"
id="path4585-2-9-1-2-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 144.74992,139.47875 0,30.97868"
id="path4585-2-9-1-2-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 113.77125,139.47875 0,30.97868"
id="path4585-2-9-1-2-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 82.792576,139.47875 0,30.97868"
id="path4585-2-9-1-2-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 82.792576,15.564062 0,30.978674"
id="path4585-2-9-1-2-06"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 113.77125,15.564062 0,30.978674"
id="path4585-2-9-1-2-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 175.72859,46.542736 -30.97867,0"
id="path4585-2-9-1-2-2-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 175.72859,77.521413 -30.97867,0"
id="path4585-2-9-1-2-2-6-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 175.72859,108.50008 -30.97867,0"
id="path4585-2-9-1-2-2-6-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 175.72859,139.47875 -30.97867,0"
id="path4585-2-9-1-2-2-6-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 51.813904,139.47875 -30.978674,0"
id="path4585-2-9-1-2-2-6-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 51.813904,108.50008 -30.978674,0"
id="path4585-2-9-1-2-2-6-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 51.813904,77.521413 -30.978674,0"
id="path4585-2-9-1-2-2-6-23"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#000000;stroke-width:0.87813562;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.58823529"
d="m 51.813904,46.542736 -30.978674,0"
id="path4585-2-9-1-2-2-6-75"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc"
inkscape:label="path4585-2-9-1-2-2-6-75" />
</g>
</g>
<g
id="g5504"
inkscape:label="StaggeredX"
transform="matrix(4.6833899,0,0,4.6833899,-66.27032,-80.242034)">
<g
inkscape:label="StaggeredX-Inner"
id="g5065">
<path
style="fill:none;stroke:#ff0000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 23.283333,40.354167 1.058334,0"
id="path4834"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 23.283333,35.0625 1.058334,0"
id="path4834-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 23.283333,29.770833 1.058334,0"
id="path4834-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 28.574999,40.354167 1.058334,0"
id="path4834-28"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 28.574999,35.0625 1.058334,0"
id="path4834-9-9"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 28.574999,29.770833 1.058334,0"
id="path4834-2-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 33.866666,40.354167 1.058334,0"
id="path4834-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 33.866666,35.0625 1.058334,0"
id="path4834-9-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 33.866666,29.770833 1.058334,0"
id="path4834-2-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
<g
inkscape:label="StaggeredX-GhostLayers"
id="g5035">
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 39.158333,40.354167 1.058334,0"
id="path4834-29"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 39.158333,35.0625 1.058334,0"
id="path4834-9-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 39.158333,29.770833 1.058334,0"
id="path4834-2-19"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 17.991667,40.354167 1.058334,0"
id="path4834-29-4"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 17.991667,35.0625 1.058334,0"
id="path4834-9-3-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 17.991667,29.770833 1.058334,0"
id="path4834-2-19-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 17.991666,24.479167 1.058334,0"
id="path4834-29-4-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 23.283334,24.479167 1.058333,0"
id="path4834-29-4-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 28.574999,24.479167 1.058334,0"
id="path4834-29-4-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 33.866666,24.479167 1.058334,0"
id="path4834-29-4-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 39.158333,24.479167 1.058334,0"
id="path4834-29-4-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 17.991666,45.645833 1.058334,0"
id="path4834-29-4-5-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 23.283334,45.645833 1.058333,0"
id="path4834-29-4-0-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 28.574999,45.645833 1.058334,0"
id="path4834-29-4-3-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 33.866666,45.645833 1.058334,0"
id="path4834-29-4-6-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#ff0000;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 39.158333,45.645833 1.058334,0"
id="path4834-29-4-1-0"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
</g>
<g
id="g5475"
inkscape:label="StaggeredY"
transform="matrix(4.6833899,0,0,4.6833899,-66.27032,-80.242034)">
<g
transform="matrix(0,1,-1,0,44.852085,12.572917)"
inkscape:label="StaggeredY-GhostLayers"
id="g5035-6">
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 35.189582,18.393752 1.058334,0"
id="path4834-29-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 35.189582,13.102085 1.058334,0"
id="path4834-9-3-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 35.189582,7.8104186 1.058334,0"
id="path4834-2-19-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 14.022916,18.393752 1.058334,0"
id="path4834-29-4-4"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 14.022916,13.102085 1.058334,0"
id="path4834-9-3-7-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 14.022916,7.8104186 1.058334,0"
id="path4834-2-19-8-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 14.022915,2.5187526 1.058334,0"
id="path4834-29-4-5-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 19.314583,2.5187526 1.058333,0"
id="path4834-29-4-0-69"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 24.606248,2.5187526 1.058334,0"
id="path4834-29-4-3-37"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 29.897915,2.5187526 1.058334,0"
id="path4834-29-4-6-4"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 35.189582,2.5187526 1.058334,0"
id="path4834-29-4-1-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 14.022915,23.685418 1.058334,0"
id="path4834-29-4-5-0-2"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 19.314583,23.685418 1.058333,0"
id="path4834-29-4-0-6-5"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 24.606248,23.685418 1.058334,0"
id="path4834-29-4-3-3-4"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 29.897915,23.685418 1.058334,0"
id="path4834-29-4-6-2-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.15000001;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:0.47058824"
d="m 35.189582,23.685418 1.058334,0"
id="path4834-29-4-1-0-4"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
<g
transform="matrix(0,1,-1,0,43.529167,8.604167)"
inkscape:label="StaggeredY-Inner"
id="g5065-4">
<path
style="fill:none;stroke:#0081ff;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 23.283333,17.070834 1.058334,0"
id="path4834-30"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 23.283333,11.779167 1.058334,0"
id="path4834-9-7"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 23.283333,6.4874997 1.058334,0"
id="path4834-2-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 28.574999,17.070834 1.058334,0"
id="path4834-28-6"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 28.574999,11.779167 1.058334,0"
id="path4834-9-9-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 28.574999,6.4874997 1.058334,0"
id="path4834-2-7-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 33.866666,17.070834 1.058334,0"
id="path4834-3-4"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 33.866666,11.779167 1.058334,0"
id="path4834-9-6-3"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
<path
style="fill:none;stroke:#0081ff;stroke-width:0.2;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
d="m 33.866666,6.4874997 1.058334,0"
id="path4834-2-1-1"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cc" />
</g>
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:19.82634926px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="53.159824"
y="110.05041"
id="text4360"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4362"
x="53.159824"
y="110.05041"
style="font-size:4.13048983px">(1,1)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:19.82634926px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="40.352985"
y="106.97871"
id="text4360-7"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4362-5"
x="40.352985"
y="106.97871"
style="font-size:4.13048983px;fill:#fa0000;fill-opacity:1">(1,1)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:19.82634926px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="65.253937"
y="106.74267"
id="text4360-7-3"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4362-5-5"
x="65.253937"
y="106.74267"
style="font-size:4.13048983px;fill:#fa0000;fill-opacity:1">(2,1)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:19.82634926px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="52.744442"
y="92.935028"
id="text4360-7-3-6"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4362-5-5-2"
x="52.744442"
y="92.935028"
style="font-size:4.13048983px;fill:#1543ff;fill-opacity:1">(1,2)</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:19.82634926px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="52.98048"
y="127.67839"
id="text4360-7-3-6-9"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan4362-5-5-2-1"
x="52.98048"
y="127.67839"
style="font-size:4.13048983px;fill:#1543ff;fill-opacity:1">(1,1)</tspan></text>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="61.653625mm"
height="35.390694mm"
viewBox="0 0 218.45773 125.4001"
id="svg2"
version="1.1"
inkscape:version="0.91 r13725"
sodipodi:docname="walberla_blocks.svg">
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="4"
inkscape:cx="142.40869"
inkscape:cy="26.799911"
inkscape:document-units="px"
inkscape:current-layer="svg2"
showgrid="false"
inkscape:window-width="2560"
inkscape:window-height="1371"
inkscape:window-x="4480"
inkscape:window-y="0"
inkscape:window-maximized="1"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0">
<inkscape:grid
id="grid4136"
type="xygrid"
originx="48.362094"
originy="-864.69997" />
</sodipodi:namedview>
<defs
id="defs4">
<inkscape:path-effect
effect="spiro"
id="path-effect8294"
is_visible="true" />
</defs>
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<g
id="layer1"
inkscape:groupmode="layer"
inkscape:label="Layer 1"
transform="translate(48.362095,-62.262187)" />
<rect
style="opacity:1;fill:#94e2ff;fill-opacity:1;stroke:#000000;stroke-width:0.2;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect8324"
width="10"
height="10"
x="34.781345"
y="1.0154506"
inkscape:tile-cx="15"
inkscape:tile-cy="67.362183"
inkscape:tile-w="10.00001"
inkscape:tile-h="10.00001"
inkscape:tile-x0="9.999995"
inkscape:tile-y0="62.362178" />
<rect
style="opacity:1;fill:#c7c7c7;fill-opacity:1;stroke:#000000;stroke-width:0.30000001;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect8324-2"
width="10"
height="10"
x="34.711391"
y="15.813687"
inkscape:tile-cx="15"
inkscape:tile-cy="67.362183"
inkscape:tile-w="10.00001"
inkscape:tile-h="10.00001"
inkscape:tile-x0="9.999995"
inkscape:tile-y0="62.362178" />
<g
id="g8547"
transform="translate(103.18126,-62.262187)">
<use
style="fill:#ffabab;fill-opacity:1"
height="100%"
width="100%"
transform="translate(-24.781347,61.346736)"
id="use8326"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8328"
transform="translate(-24.781347,71.346746)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8330"
transform="translate(-24.781347,81.346756)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8332"
transform="translate(-24.781347,91.346766)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8334"
transform="translate(-24.781347,101.34678)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8336"
transform="translate(-24.781347,111.34679)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8338"
transform="translate(-14.781337,61.346736)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8348"
transform="translate(-14.781337,111.34679)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8350"
transform="translate(-4.7813269,61.346736)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8360"
transform="translate(-4.7813269,111.34679)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8362"
transform="translate(5.2186831,61.346736)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8372"
transform="translate(5.2186831,111.34679)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8374"
transform="translate(15.218693,61.346736)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8376"
transform="translate(15.218693,71.346746)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8378"
transform="translate(15.218693,81.346756)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8380"
transform="translate(15.218693,91.346766)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8382"
transform="translate(15.218693,101.34678)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8384"
transform="translate(15.218693,111.34679)"
xlink:href="#rect8324"
inkscape:tiled-clone-of="#rect8324"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(-14.711388,56.548511)"
id="use8409"
xlink:href="#rect8324-2"
inkscape:tiled-clone-of="#rect8324-2"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8411"
transform="translate(-14.711388,66.548522)"
xlink:href="#rect8324-2"
inkscape:tiled-clone-of="#rect8324-2"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8413"
transform="translate(-14.711388,76.548532)"
xlink:href="#rect8324-2"
inkscape:tiled-clone-of="#rect8324-2"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8415"
transform="translate(-14.711388,86.548542)"
xlink:href="#rect8324-2"
inkscape:tiled-clone-of="#rect8324-2"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8417"
transform="translate(-4.7113779,56.548512)"
xlink:href="#rect8324-2"
inkscape:tiled-clone-of="#rect8324-2"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8419"
transform="translate(-4.7113779,66.548522)"
xlink:href="#rect8324-2"
inkscape:tiled-clone-of="#rect8324-2"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8421"
transform="translate(-4.7113779,76.548532)"
xlink:href="#rect8324-2"
inkscape:tiled-clone-of="#rect8324-2"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8423"
transform="translate(-4.7113779,86.548542)"
xlink:href="#rect8324-2"
inkscape:tiled-clone-of="#rect8324-2"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8425"
transform="translate(5.2886321,56.548512)"
xlink:href="#rect8324-2"
inkscape:tiled-clone-of="#rect8324-2"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8427"
transform="translate(5.2886321,66.548522)"
xlink:href="#rect8324-2"
inkscape:tiled-clone-of="#rect8324-2"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8429"
transform="translate(5.2886321,76.548532)"
xlink:href="#rect8324-2"
inkscape:tiled-clone-of="#rect8324-2"
y="0"
x="0" />
<use
height="100%"
width="100%"
id="use8431"
transform="translate(5.2886321,86.548542)"
xlink:href="#rect8324-2"
inkscape:tiled-clone-of="#rect8324-2"
y="0"
x="0" />
</g>
<g
id="g8515"
transform="translate(-16.289736,2.5590552)">
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8433"
xlink:href="#use8326"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8435"
xlink:href="#use8328"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8437"
xlink:href="#use8330"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8439"
xlink:href="#use8332"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8441"
xlink:href="#use8334"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8443"
xlink:href="#use8336"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8445"
xlink:href="#use8338"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8447"
xlink:href="#use8348"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8449"
xlink:href="#use8350"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8451"
xlink:href="#use8360"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8453"
xlink:href="#use8362"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8455"
xlink:href="#use8372"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8457"
xlink:href="#use8374"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8459"
xlink:href="#use8376"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8461"
xlink:href="#use8378"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8463"
xlink:href="#use8380"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8465"
xlink:href="#use8382"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8467"
xlink:href="#use8384"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8469"
xlink:href="#use8409"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8471"
xlink:href="#use8411"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8473"
xlink:href="#use8413"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8475"
xlink:href="#use8415"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8477"
xlink:href="#use8417"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8479"
xlink:href="#use8419"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8481"
xlink:href="#use8421"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8483"
xlink:href="#use8423"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8485"
xlink:href="#use8425"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8487"
xlink:href="#use8427"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8489"
xlink:href="#use8429"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8491"
xlink:href="#use8431"
y="0"
x="0" />
</g>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:7.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="-0.28076172"
y="6.4571352"
id="text8493"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan8495"
x="-0.28076172"
y="6.4571352"
style="font-size:5px">Ghost Layer</tspan></text>
<text
xml:space="preserve"
style="font-style:normal;font-weight:normal;font-size:7.5px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
x="14.469238"
y="22.653563"
id="text8493-7"
sodipodi:linespacing="125%"><tspan
sodipodi:role="line"
id="tspan8495-0"
x="14.469238"
y="22.653563"
style="font-size:5px">Inner</tspan></text>
<g
transform="translate(-16.289736,-62.640994)"
id="g8579">
<use
x="0"
y="0"
xlink:href="#use8326"
id="use8581"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8328"
id="use8583"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8330"
id="use8585"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8332"
id="use8587"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8334"
id="use8589"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8336"
id="use8591"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8338"
id="use8593"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8348"
id="use8595"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8350"
id="use8597"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8360"
id="use8599"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8362"
id="use8601"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8372"
id="use8603"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8374"
id="use8605"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8376"
id="use8607"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8378"
id="use8609"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8380"
id="use8611"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8382"
id="use8613"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8384"
id="use8615"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8409"
id="use8617"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8411"
id="use8619"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8413"
id="use8621"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8415"
id="use8623"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8417"
id="use8625"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8419"
id="use8627"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8421"
id="use8629"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8423"
id="use8631"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8425"
id="use8633"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8427"
id="use8635"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8429"
id="use8637"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
<use
x="0"
y="0"
xlink:href="#use8431"
id="use8639"
transform="translate(64.270956,0.37880721)"
width="100%"
height="100%" />
</g>
<g
id="g8641"
transform="translate(38.910304,2.5590552)">
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8643"
xlink:href="#use8326"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8645"
xlink:href="#use8328"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8647"
xlink:href="#use8330"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8649"
xlink:href="#use8332"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8651"
xlink:href="#use8334"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8653"
xlink:href="#use8336"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8655"
xlink:href="#use8338"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8657"
xlink:href="#use8348"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8659"
xlink:href="#use8350"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8661"
xlink:href="#use8360"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8663"
xlink:href="#use8362"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8665"
xlink:href="#use8372"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8667"
xlink:href="#use8374"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8669"
xlink:href="#use8376"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8671"
xlink:href="#use8378"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8673"
xlink:href="#use8380"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8675"
xlink:href="#use8382"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8677"
xlink:href="#use8384"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8679"
xlink:href="#use8409"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8681"
xlink:href="#use8411"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8683"
xlink:href="#use8413"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8685"
xlink:href="#use8415"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8687"
xlink:href="#use8417"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8689"
xlink:href="#use8419"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8691"
xlink:href="#use8421"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8693"
xlink:href="#use8423"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8695"
xlink:href="#use8425"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8697"
xlink:href="#use8427"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8699"
xlink:href="#use8429"
y="0"
x="0" />
<use
height="100%"
width="100%"
transform="translate(64.270956,0.37880721)"
id="use8701"
xlink:href="#use8431"
y="0"
x="0" />
</g>
<use
x="0"
y="0"
xlink:href="#g8547"
id="use8808"
transform="translate(55.176426,1.5980072e-7)"
width="100%"
height="100%" />
</svg>
pystencils
==========
Welcome to the documentation of the pystencils code generation tool for stencil codes.
pystencils can help you to generate blazingly fast code for image processing, numerical simulations or any other task involving numpy arrays.
.. toctree::
:maxdepth: 2
sphinx/tutorials.rst
sphinx/api.rst
.. image:: /img/pystencils_arch_block_diagram.svg
:height: 450px
:align: center
This source diff could not be displayed because it is too large. You can view the blob instead.
%% Cell type:code id: tags:
``` python
from pystencils.session import *
```
%% Cell type:markdown id: tags:
# Tutorial 02: Basic Kernel generation with *pystencils*
Now that you have an [overview of pystencils](01_tutorial_getting_started.ipynb),
this tutorial shows in more detail how to formulate, optimize and run stencil kernels.
## 1) Kernel Definition
### a) Defining kernels with assignment lists and the `kernel` decorator
*pystencils* gets a symbolic formulation of the kernel. This can be either an `Assignment` or a sequence of `Assignment`s that follow a set of restrictions.
Lets first create a kernel that consists of multiple assignments:
%% Cell type:code id: tags:
``` python
src_arr = np.zeros([20, 30])
dst_arr = np.zeros_like(src_arr)
dst, src = ps.fields(dst=dst_arr, src=src_arr)
```
%% Cell type:code id: tags:
``` python
grad_x, grad_y = sp.symbols("grad_x, grad_y")
symbolic_description = [
ps.Assignment(grad_x, (src[1, 0] - src[-1, 0]) / 2),
ps.Assignment(grad_y, (src[0, 1] - src[0, -1]) / 2),
ps.Assignment(dst[0, 0], grad_x + grad_y),
]
kernel = ps.create_kernel(symbolic_description)
symbolic_description
```
%% Output
$\displaystyle \left[ grad_{x} \leftarrow_{} \frac{{src}_{(1,0)}}{2} - \frac{{src}_{(-1,0)}}{2}, \ grad_{y} \leftarrow_{} \frac{{src}_{(0,1)}}{2} - \frac{{src}_{(0,-1)}}{2}, \ {dst}_{(0,0)} \leftarrow_{} grad_{x} + grad_{y}\right]$
⎡ src_E src_W src_N src_S ⎤
⎢gradₓ := ───── - ─────, grad_y := ───── - ─────, dst_C := gradₓ + grad_y⎥
⎣ 2 2 2 2 ⎦
%% Cell type:markdown id: tags:
We created subexpressions, using standard sympy symbols on the left hand side, to split the kernel into multiple assignments. Defining a kernel using a list of `Assignment`s is quite tedious and hard to read.
To simplify the formulation of a kernel, *pystencils* offers the `kernel` decorator, that transforms a normal Python function with `@=` assignments into an assignment list that can be passed to `create_kernel`.
%% Cell type:code id: tags:
``` python
@ps.kernel
def symbolic_description_using_function():
grad_x @= (src[1, 0] - src[-1, 0]) / 2
grad_y @= (src[0, 1] - src[0, -1]) / 2
dst[0, 0] @= grad_x + grad_y
symbolic_description_using_function
```
%% Output
$\displaystyle \left[ grad_{x} \leftarrow_{} \frac{{src}_{(1,0)}}{2} - \frac{{src}_{(-1,0)}}{2}, \ grad_{y} \leftarrow_{} \frac{{src}_{(0,1)}}{2} - \frac{{src}_{(0,-1)}}{2}, \ {dst}_{(0,0)} \leftarrow_{} grad_{x} + grad_{y}\right]$
⎡ src_E src_W src_N src_S ⎤
⎢gradₓ := ───── - ─────, grad_y := ───── - ─────, dst_C := gradₓ + grad_y⎥
⎣ 2 2 2 2 ⎦
%% Cell type:markdown id: tags:
The decorated function can contain any Python code, only the `@=` operator, and the ternary inline `if-else` operator have different meaning.
### b) Ternary 'if' with `Piecewise`
The ternary operator maps to `sympy.Piecewise` functions, that can be used to introduce branching into the kernel. Piecewise defined functions must give a value for every input, i.e. there must be a 'otherwise' clause in the end that is indicated by the condition `True`. Piecewise objects are standard sympy terms that can be integrated into bigger expressions:
%% Cell type:code id: tags:
``` python
sp.Piecewise((1.0, src[0,1] > 0), (0.0, True)) + src[1, 0]
```
%% Output
$\displaystyle {src}_{(1,0)} + \begin{cases} 1.0 & \text{for}\: {src}_{(0,1)} > 0 \\0.0 & \text{otherwise} \end{cases}$
⎛⎧1.0 for src_N > 0⎞
src_E + ⎜⎨ ⎟
⎝⎩0.0 otherwise ⎠
%% Cell type:markdown id: tags:
Piecewise objects are created by the `kernel` decorator for ternary if-else statements.
%% Cell type:code id: tags:
``` python
@ps.kernel
def kernel_with_piecewise():
grad_x @= (src[1, 0] - src[-1, 0]) / 2 if src[-1, 0] > 0 else 0.0
kernel_with_piecewise
```
%% Output
$\displaystyle \left[ grad_{x} \leftarrow_{} \begin{cases} \frac{{src}_{(1,0)}}{2} - \frac{{src}_{(-1,0)}}{2} & \text{for}\: {src}_{(-1,0)} > 0 \\0.0 & \text{otherwise} \end{cases}\right]$
⎡ ⎧src_E src_W ⎤
⎢ ⎪───── - ───── for src_W > 0⎥
⎢gradₓ := ⎨ 2 2 ⎥
⎢ ⎪ ⎥
⎣ ⎩ 0.0 otherwise ⎦
%% Cell type:markdown id: tags:
### c) Assignment level optimizations using `AssignmentCollection`
When the kernels get larger and more complex, it is helpful to organize the list of assignment into a more structured way. The `AssignmentCollection` offers optimizating transformation on a list of assignments. It holds two assignment lists, one for subexpressions and one for the main assignments. Main assignments are typically those that write to an array.
%% Cell type:code id: tags:
``` python
@ps.kernel
def somewhat_longer_dummy_kernel(s):
s.a @= src[0, 1] + src[-1, 0]
s.b @= 2 * src[1, 0] + src[0, -1]
s.c @= src[0, 1] + 2 * src[1, 0] + src[-1, 0] + src[0, -1] - src[0,0]
dst[0, 0] @= s.a + s.b + s.c
ac = ps.AssignmentCollection(main_assignments=somewhat_longer_dummy_kernel[-1:],
subexpressions=somewhat_longer_dummy_kernel[:-1])
ac
```
%% Output
AssignmentCollection: dst_C, <- f(src_C, src_W, src_S, src_N, src_E)
%% Cell type:code id: tags:
``` python
ac.operation_count
```
%% Output
{'adds': 8,
'muls': 2,
'divs': 0,
'sqrts': 0,
'fast_sqrts': 0,
'fast_inv_sqrts': 0,
'fast_div': 0}
%% Cell type:markdown id: tags:
The `pystencils.simp` submodule offers several functions to optimize a collection of assignments.
It also offers functionality to group optimization into strategies and evaluate them.
In this example we reduce the number of operations by reusing existing subexpressions to get rid of two unnecessary floating point additions. For more information about assignment collections and simplifications see the [demo notebook](demo_assignment_collection.ipynb).
%% Cell type:code id: tags:
``` python
opt_ac = ps.simp.subexpression_substitution_in_existing_subexpressions(ac)
opt_ac
```
%% Output
AssignmentCollection: dst_C, <- f(src_C, src_W, src_S, src_N, src_E)
%% Cell type:code id: tags:
``` python
opt_ac.operation_count
```
%% Output
{'adds': 6,
'muls': 1,
'divs': 0,
'sqrts': 0,
'fast_sqrts': 0,
'fast_inv_sqrts': 0,
'fast_div': 0}
%% Cell type:markdown id: tags:
### d) Ghost layers and iteration region
When creating a kernel with neighbor accesses, *pystencils* automatically restricts the iteration region, such that all accesses are safe.
%% Cell type:code id: tags:
``` python
kernel = ps.create_kernel(ps.Assignment(dst[0,0], src[2, 0] + src[-1, 0]))
ps.show_code(kernel)
```
%% Output
%% Cell type:markdown id: tags:
When no additional ghost layer information is given, *pystencils* looks at all neighboring field accesses and introduces the required number of ghost layers **for all directions**. In the example above the largest neighbor accesses was ``src[2, 0]``, so theoretically we would need 2 ghost layers only the the end of the x coordinate.
By default *pystencils* introduces 2 ghost layers at all borders of the domain. The next cell shows how to change this behavior. Be careful with manual ghost layer specification, wrong values may lead to SEGFAULTs.
%% Cell type:code id: tags:
``` python
gl_spec = [(0, 2), # 0 ghost layers at the left, 2 at the right border
(1, 0)] # 1 ghost layer at the lower y, one at the upper y coordinate
kernel = ps.create_kernel(ps.Assignment(dst[0,0], src[2, 0] + src[-1, 0]), ghost_layers=gl_spec)
ps.show_code(kernel)
```
%% Output
%% Cell type:markdown id: tags:
## 2 ) Restrictions
### a) Independence Restriction
*pystencils* only works for kernels where each array element can be updated independently from all other elements. This restriction ensures that the kernels can be easily parallelized and also be run on the GPU. Trying to define kernels where the results depends on the iteration order, leads to a ValueError.
%% Cell type:code id: tags:
``` python
invalid_description = [
ps.Assignment(dst[1, 0], src[1, 0] + src[-1, 0]),
ps.Assignment(dst[0, 0], src[1, 0] - src[-1, 0]),
]
try:
invalid_kernel = ps.create_kernel(invalid_description)
assert False, "Should never be executed"
except ValueError as e:
print(e)
```
%% Output
Field dst is written at two different locations
%% Cell type:markdown id: tags:
The independence restriction makes sure that the kernel can be safely parallelized by checking the following conditions: If a field is modified inside the kernel, it may only be modified at a single spatial position. In that case the field may also only be read at this position. Fields that are not modified may be read at multiple neighboring positions.
Specifically, this rule allows for in-place updates that don't access neighbors.
%% Cell type:code id: tags:
``` python
valid_kernel = ps.create_kernel(ps.Assignment(src[0,0], 2*src[0,0] + 42))
```
%% Cell type:markdown id: tags:
If a field stores multiple values per cell, as in the next example, this restriction only applies for accesses with the same index.
%% Cell type:code id: tags:
``` python
v = ps.fields("v(2): double[2D]")
valid_kernel = ps.create_kernel([ps.Assignment(v[0,0](1), 2*v[0,0](1) + 42),
ps.Assignment(v[0,1](0), 2*v[0,1](0) + 42)])
```
%% Cell type:markdown id: tags:
### b) Static Single Assignment Form
All assignments that don't write to a field must be in SSA form
1. Each sympy symbol may only occur once as a left-hand-side (fields can be written multiple times)
2. A symbol has to be defined before it is used. If it is never defined it is introduced as function parameter
The next cell demonstrates the first SSA restriction:
%% Cell type:code id: tags:
``` python
@ps.kernel
def not_allowed():
a, b = sp.symbols("a b")
a @= src[0, 0]
b @= a + 3
a @= src[-1, 0]
dst[0, 0] @= a + b
try:
ps.create_kernel(not_allowed)
assert False
except ValueError as e:
print(e)
```
%% Output
Assignments not in SSA form, multiple assignments to a
%% Cell type:markdown id: tags:
Also it is not allowed to write a field at the same location
%% Cell type:code id: tags:
``` python
@ps.kernel
def not_allowed():
dst[0, 0] @= src[0, 1] + src[1, 0]
dst[0, 0] @= 2 * dst[0, 0]
try:
ps.create_kernel(not_allowed)
assert False
except ValueError as e:
print(e)
```
%% Output
Field dst is written twice at the same location
%% Cell type:markdown id: tags:
This situation should be resolved by introducing temporary variables
%% Cell type:code id: tags:
``` python
tmp_var = sp.Symbol("a")
@ps.kernel
def allowed():
tmp_var @= src[0, 1] + src[1, 0]
dst[0, 0] @= 2 * tmp_var
ast = ps.create_kernel(allowed)
ps.show_code(ast)
```
%% Output