Skip to content
Snippets Groups Projects
Commit f20841de authored by Stephan Seitz's avatar Stephan Seitz
Browse files

Move walberla app generation files to own repo

parent 8c2c7cb5
Branches
Tags
No related merge requests found
Pipeline #21719 failed
waLBerla_link_files_to_builddir( *.prm )
waLBerla_add_executable ( NAME {{ cmake_target_name }}
FILES {%- for f in files_to_compile %}
{{ f }}
{%- endfor %}
DEPENDS {{depends | join(' ')}})
{% if 'walberla_openvdb' in depends -%}
if (WALBERLA_BUILD_WITH_OPENVDB)
target_link_libraries( {{ cmake_target_name }} tbb boundary openvdb Half IexMath Iex IlmThread Imath)
endif(WALBERLA_BUILD_WITH_OPENVDB)
{%- endif %}
......@@ -107,7 +107,8 @@ class NativeTextureBinding(pystencils.backends.cbackend.CustomCodeNode):
float maxMipmapLevelClamp;
};
""" # noqa
CODE_TEMPLATE_LINEAR = jinja2.Template("""cudaResourceDesc {{resource_desc}}{};
CODE_TEMPLATE_LINEAR = jinja2.Template("""
cudaResourceDesc {{resource_desc}}{};
{{resource_desc}}.resType = cudaResourceTypeLinear;
{{resource_desc}}.res.linear.devPtr = {{device_ptr}};
{{resource_desc}}.res.linear.desc.f = {{cuda_channel_format}};
......@@ -124,6 +125,7 @@ auto {{texture_object}}Destroyer = std::unique_ptr(nullptr, [&](){
""")
CODE_TEMPLATE_PITCHED2D = jinja2.Template(""" !!! TODO!!! """)
CODE_TEMPLATE_CUDA_ARRAY = jinja2.Template("""
# pragma GCC diagnostic ignored "-Wconversion"
auto channel_desc_{{texture_name}} = {{channel_desc}};
{{ create_array }}
{{ copy_array }}
......@@ -139,7 +141,8 @@ std::shared_ptr<void> {{array}}Destroyer(nullptr, [&](...){
cudaFreeArray({{array}});
cudaUnbindTexture({{texture_namespace}}{{texture_name}});
});
""")
# pragma GCC diagnostic pop
""")
def __init__(self, texture, device_data_ptr, use_texture_objects=True, texture_namespace=''):
self._texture = texture
......
......@@ -176,7 +176,8 @@ class GraphDataHandling(pystencils.datahandling.SerialDataHandling):
cpu=True,
gpu=None,
alignment=False,
field_type=FieldType.GENERIC):
field_type=FieldType.GENERIC,
shape=None):
if layout is None:
layout = self.default_layout
......@@ -197,13 +198,22 @@ class GraphDataHandling(pystencils.datahandling.SerialDataHandling):
if len(values_per_cell) == 1 and values_per_cell[0] == 1:
values_per_cell = ()
rtn = self._fields[name] = pystencils.Field.create_generic(name,
self.dim,
dtype,
index_dimensions=len(values_per_cell),
layout=layout,
index_shape=values_per_cell,
field_type=field_type)
if shape:
rtn = self._fields[name] = pystencils.Field.create_fixed_size(name,
shape,
index_dimensions=len(values_per_cell),
layout=layout,
dtype=dtype,
field_type=field_type)
else:
rtn = self._fields[name] = pystencils.Field.create_generic(name,
self.dim,
dtype,
index_dimensions=len(values_per_cell),
layout=layout,
index_shape=values_per_cell,
field_type=field_type)
rtn.latex_name = latex_name
if cpu:
......
#
# Copyright © 2020 Stephan Seitz <stephan.seitz@fau.de>
#
# Distributed under terms of the GPLv3 license.
"""
"""
import itertools
from typing import Dict
from stringcase import camelcase, pascalcase
import lbmpy_walberla
import pystencils
import pystencils_walberla.codegen
from pystencils.astnodes import Block, EmptyLine
from pystencils.cpu.cpujit import get_headers
from pystencils_autodiff.walberla import (
AllocateAllFields, CMakeLists, Communication, DefineKernelObjects, DefinitionsHeader,
FieldCopy, InitBoundaryHandling, LbCommunicationSetup, ResolveUndefinedSymbols, SwapFields,
SweepCreation, SweepOverAllBlocks, TimeLoopNode, UniformBlockforestFromConfig, WalberlaMain,
WalberlaModule, WriteVdb)
WALBERLA_MODULES = ["blockforest",
"boundary",
"communication",
"core",
"cuda",
"domain_decomposition",
"executiontree",
"fft",
"field",
"gather",
"geometry",
"gui",
"lbm",
"mesa_pd",
"mesh",
"pde",
"pe",
"pe_coupling",
"postprocessing",
"python_coupling",
"simd",
"sqlite",
"stencil",
"timeloop",
"vtk",
"walberla_openvdb"]
class Simulation():
def _get_sweep_class_name(prefix='Kernel'):
ctr = 0
while True:
yield f'{prefix}{ctr}'
ctr += 1
def __init__(self,
graph_data_handling,
codegen_context,
boundary_handling: pystencils.boundaries.BoundaryHandling = None,
lb_rule=None,
refinement_scaling=None,
boundary_handling_target='gpu',
cmake_target_name='autogen_app',
write_out_stuff=True):
self._data_handling = graph_data_handling
self._lb_rule = lb_rule
self._refinement_scaling = refinement_scaling
self._block_forest = UniformBlockforestFromConfig()
self.parameter_config_block = 'parameters'
self._codegen_context = codegen_context
self._boundary_handling = boundary_handling
self._lb_model_name = 'GeneratedLatticeModel'
self._flag_field_dtype = 'uint32_t'
self._kernel_class_generator = Simulation._get_sweep_class_name()
self._with_gui = False
self._with_gui_default = False
self._boundary_kernels = {}
self._boundary_handling_target = boundary_handling_target
self._data_handling.merge_swaps_with_kernel_calls()
self._packinfo_class = 'PackInfo'
self.cmake_target_name = cmake_target_name
self._write_out_stuff = write_out_stuff
self._fluid_uid = None
self._debug = None
def _create_helper_files(self) -> Dict[str, str]:
if self._lb_rule:
pystencils_walberla.codegen.generate_pack_info_for_field(
self._codegen_context,
'PackInfo',
pystencils.Field.create_generic(self._data_handling.fields['ldc_pdf'].name,
self._data_handling.fields['ldc_pdf'].spatial_dimensions,
self._data_handling.fields['ldc_pdf'].dtype.numpy_dtype,
self._data_handling.fields['ldc_pdf'].index_dimensions,
index_shape=self._data_handling.fields['ldc_pdf'].index_shape,),
target=self._boundary_handling_target)
lbmpy_walberla.generate_lattice_model(self._codegen_context, self._lb_model_name,
self._lb_rule,
refinement_scaling=self._refinement_scaling)
if self._boundary_handling:
for bc in self.boundary_conditions:
self._boundary_kernels.update({bc.name: lbmpy_walberla.generate_boundary(
self._codegen_context,
pascalcase(bc.name),
bc,
self._lb_rule.method,
target=self._boundary_handling_target)},
)
self._bh_cycler = itertools.cycle(self._boundary_kernels.keys())
def _create_module(self):
if self._lb_rule:
lb_shape = (len(self._lb_rule.method.stencil),)
else:
lb_shape = (-1,)
self._field_allocations = field_allocations = AllocateAllFields(self._block_forest.blocks,
self._data_handling,
lb_shape,
self._lb_model_name)
if self._boundary_handling:
flag_field_id = field_allocations._cpu_allocations[
self._boundary_handling.flag_interface.flag_field_name].symbol
if self._lb_rule:
pdf_field_id = field_allocations._gpu_allocations.get(
'ldc_pdf', field_allocations._cpu_allocations['ldc_pdf']).symbol
else:
pdf_field_id = None
call_nodes = filter(lambda x: x, [self._graph_to_sweep(c) for c in self._data_handling.call_queue])
init_boundary_handling = (InitBoundaryHandling(self._block_forest.blocks,
flag_field_id,
pdf_field_id,
self.boundary_conditions,
self._boundary_kernels,
self._field_allocations)
if self._boundary_handling
else EmptyLine())
if hasattr(init_boundary_handling, 'fluid'):
self._fluid_uid = init_boundary_handling.fluid
module = WalberlaModule(WalberlaMain(Block([
self._block_forest,
ResolveUndefinedSymbols(
Block([
field_allocations,
init_boundary_handling,
LbCommunicationSetup(self._lb_model_name,
pdf_field_id,
self._packinfo_class,
self._boundary_handling_target)
if self._lb_rule else EmptyLine(),
DefineKernelObjects(
Block([*call_nodes])
)
]), self.parameter_config_block
)
])))
if self._debug:
from pystencils_autodiff.framework_integration.printer import DebugFrameworkPrinter
module.printer = DebugFrameworkPrinter()
self._codegen_context.write_file("main.cpp", str(module))
return module
def _create_defintions_header(self):
self._codegen_context.write_file("UserDefinitions.h",
str(DefinitionsHeader(self._lb_model_name if self._lb_rule else None,
self._flag_field_dtype)))
def _create_cmake_file(self, extra_dependencis=[]):
walberla_dependencies = []
import re
regex = re.compile(r'^["<](\w*)/.*[>$"]')
headers = get_headers(self._module)
for h in headers:
match = regex.match(h)
if match:
module = match[1]
if module in WALBERLA_MODULES:
walberla_dependencies.append(module)
dependencies = walberla_dependencies + extra_dependencis
try:
self._codegen_context.write_file("CMakeLists.txt",
str(CMakeLists(self.cmake_target_name,
[f for f in self._codegen_context.files_written()
if f.endswith('.cpp') or f.endswith('.cu')],
depends=dependencies)))
except AttributeError:
self._codegen_context.write_file("CMakeLists.txt",
str(CMakeLists(self.cmake_target_name,
[f for f in self._codegen_context.files.keys()
if f.endswith('.cpp') or f.endswith('.cu')],
depends=dependencies)))
def write_files(self):
self._create_helper_files()
self._module = self._create_module()
self._create_defintions_header()
self._create_cmake_file() # has to be called last
@property
def boundary_conditions(self):
return self._boundary_handling._boundary_object_to_boundary_info.keys()
def _graph_to_sweep(self, c):
from pystencils_autodiff.graph_datahandling import (
KernelCall, TimeloopRun, DataTransferKind, DataTransfer, FieldOutput)
if isinstance(c, KernelCall):
if 'indexField' in [f.name for f in c.kernel.ast.fields_accessed]:
bh = next(self._bh_cycler)
return f'sweep(blocks, {camelcase(bh)});'
sweep_class_name = next(self._kernel_class_generator)
fields_accessed = [f.name for f in c.kernel.ast.fields_accessed]
c.tmp_field_swaps = list(filter(
lambda x: x[0].name in fields_accessed and x[1].name in fields_accessed, c.tmp_field_swaps))
pystencils_walberla.codegen.generate_sweep(
self._codegen_context, sweep_class_name, c.kernel.ast, field_swaps=c.tmp_field_swaps)
rtn = SweepOverAllBlocks(SweepCreation(sweep_class_name,
self._field_allocations,
c.kernel.ast,
parameters_to_ignore=[s[1].name for s in c.tmp_field_swaps]),
self._block_forest.blocks)
elif isinstance(c, TimeloopRun):
sweeps = [self._graph_to_sweep(s) for s in c.timeloop._single_step_asts]
rtn = TimeLoopNode(0, c.time_steps, sweeps)
elif isinstance(c, DataTransfer):
if c.kind == DataTransferKind.HOST_SWAP:
src = self._field_allocations._cpu_allocations[c.field.name].symbol
dst = self._field_allocations._cpu_allocations[c.destination.name].symbol
rtn = SwapFields(src, dst)
elif c.kind == DataTransferKind.DEVICE_SWAP:
src = self._field_allocations._gpu_allocations[c.field.name].symbol
dst = self._field_allocations._gpu_allocations[c.destination.name].symbol
rtn = SwapFields(src, dst)
elif c.kind == DataTransferKind.HOST_TO_DEVICE:
src = self._field_allocations._cpu_allocations[c.field.name].symbol
dst = self._field_allocations._gpu_allocations[c.field.name].symbol
rtn = FieldCopy(self._block_forest.blocks, src, c.field, False, dst, c.field, True)
elif c.kind == DataTransferKind.DEVICE_TO_HOST:
src = self._field_allocations._gpu_allocations[c.field.name].symbol
dst = self._field_allocations._cpu_allocations[c.field.name].symbol
rtn = FieldCopy(self._block_forest.blocks, src, c.field, True, dst, c.field, False)
elif c.kind in (DataTransferKind.DEVICE_COMMUNICATION, DataTransferKind.HOST_COMMUNICATION):
rtn = Communication(self._boundary_handling_target == 'gpu')
else:
rtn = None
elif isinstance(c, FieldOutput):
rtn = WriteVdb(self._block_forest, c.output_path, c.fields, c.flag_field, self._fluid_uid)
else:
rtn = None
return rtn
return rtn
This diff is collapsed.
/*
* Automatically generated waLBerla main
*
*/
{% for header in headers -%}
#include {{ header }}
{% endfor %}
{% for global in globals -%}
{{ global }}
{% endfor %}
{{ main }}
/*
* walberla_user_defintions.tmpl.hpp
* Copyright (C) 2020 Stephan Seitz <stephan.seitz@fau.de>
*
* Distributed under terms of the GPLv3 license.
*/
#pragma once
{% for header in headers -%}
#include {{ header }}
{% endfor %}
namespace walberla_user {
using namespace walberla;
{% if with_lbm %}
using LatticeModel_T = lbm::{{ lb_model_name }};
using Stencil_T = LatticeModel_T::Stencil;
using CommunicationStencil_T = LatticeModel_T::CommunicationStencil;
{% endif %}
using flag_t = {{ flag_field_type }};
using FlagField_T = FlagField<flag_t>;
} // namespace walberla_user
#
# Copyright © 2020 Stephan Seitz <stephan.seitz@fau.de>
#
# Distributed under terms of the GPLv3 license.
"""
"""
import os
import sys
from os.path import dirname, expanduser, join
import numpy as np
import sympy as sp
import pystencils
from pystencils.astnodes import Block, EmptyLine, SympyAssignment
from pystencils.data_types import TypedSymbol, create_type
from pystencils_autodiff._file_io import write_file
from pystencils_autodiff.graph_datahandling import GraphDataHandling
from pystencils_autodiff.simulation import Simulation
from pystencils_autodiff.walberla import (
DefinitionsHeader, FieldAllocation, FlagFieldAllocation, GetParameter, ResolveUndefinedSymbols,
UniformBlockforestFromConfig, WalberlaMain, WalberlaModule)
from pystencils_walberla.cmake_integration import ManualCodeGenerationContext
def test_walberla():
x, y = pystencils.fields('x, y: float32[3d]')
flags = pystencils.fields('flag_field: float32[3d]')
foo_symbol = TypedSymbol('foo', np.bool)
number_symbol = TypedSymbol('number', np.float32)
crazy_plus_one = TypedSymbol('crazy', np.float32)
block_forest = UniformBlockforestFromConfig()
block = Block([
block_forest,
SympyAssignment(foo_symbol, GetParameter('parameters', foo_symbol)),
SympyAssignment(number_symbol, GetParameter('parameters', number_symbol, 1.2)),
SympyAssignment(crazy_plus_one, number_symbol + 1),
EmptyLine(),
FieldAllocation(block_forest.blocks, x, on_gpu=False),
FlagFieldAllocation(block_forest.blocks, flags)
])
module = WalberlaModule(WalberlaMain(block))
code = str(module)
print(code)
write_file('/localhome/seitz_local/projects/walberla/apps/autogen/main.cpp', code)
definitions = DefinitionsHeader(module, 'uint8_t')
write_file('/localhome/seitz_local/projects/walberla/apps/autogen/UserDefinitions.h', str(definitions))
def test_wald_wiesen_simulation():
with ManualCodeGenerationContext() as ctx:
dh = GraphDataHandling((30, 30),
periodicity=False,
default_ghost_layers=1,
default_target='cpu')
dh.add_arrays('x, y')
dh.add_arrays('w, z', gpu=True)
sim = Simulation(dh, ctx)
print(sim._create_module())
def test_wald_wiesen_lbm():
import pytest
pytest.importorskip('lbmpy')
from lbmpy.creationfunctions import create_lb_collision_rule
sys.path.append(dirname(__file__))
with ManualCodeGenerationContext() as ctx:
from test_graph_datahandling import ldc_setup
opt_params = {'target': 'gpu'}
import sympy as sp
lid_velocity = sp.symbols('lid_velocity')
lbm_step = ldc_setup(domain_size=(30, 30), optimization=opt_params,
fixed_loop_sizes=False, lid_velocity=lid_velocity)
del lbm_step.data_handling.gpu_arrays.ldc_pdf_tmp
sim = Simulation(lbm_step.data_handling,
ctx,
lbm_step.boundary_handling,
create_lb_collision_rule(lbm_step.method, optimization=opt_params),
cmake_target_name='autogen')
sim.write_files()
dir = '/localhome/seitz_local/projects/walberla/apps/autogen/'
os.makedirs(dir, exist_ok=True)
for k, v in ctx.files.items():
with open(join(dir, k), 'w') as file:
file.write(v)
def test_projection():
volume = pystencils.fields('volume: float32[3d]')
projections = pystencils.fields('projection: float32[2d]')
spacing, foo = sp.symbols('spacing, foo')
from pystencils_walberla.special_symbols import aabb_min_vector, dx_vector, global_coord
import pystencils_reco.projection
from sympy.matrices.dense import matrix_multiply_elementwise
volume.coordinate_transform = lambda x: aabb_min_vector + matrix_multiply_elementwise(x, dx_vector)
projections.set_coordinate_origin_to_field_center()
projections.coordinate_transform *= spacing
from pystencils.interpolation_astnodes import TextureDeclaration
TextureDeclaration.headers = []
projection_matrix = pystencils_reco.matrix_symbols('T', pystencils.data_types.create_type('float32'), 3, 4)
from pystencils.kernelparameters import FieldPointerSymbol, FieldStrideSymbol
assignments = pystencils_reco.projection.forward_projection(volume, projections, projection_matrix)
assignments.main_assignments.append(pystencils.Assignment(foo, FieldPointerSymbol(
volume.name, volume.dtype, const=True) + FieldStrideSymbol(volume.name, 0) + FieldStrideSymbol(volume.name, 1)))
assignments.subs({a: b for a, b in zip(pystencils.x_vector(3), global_coord)})
assignments.kwargs = {}
print(assignments)
kernel = assignments.compile('gpu')
pystencils.show_code(kernel)
with ManualCodeGenerationContext() as ctx:
dh = GraphDataHandling((300, 300, 300))
volume, projections = dh.add_arrays('volume, projection', gpu=True)
dh.run_kernel(kernel, simulate_only=True)
sim = Simulation(dh, ctx, cmake_target_name='projection')
sim._debug = False
sim.write_files()
dir = '/localhome/seitz_local/projects/walberla/apps/projection/'
os.makedirs(dir, exist_ok=True)
for k, v in ctx.files.items():
with open(join(dir, k), 'w') as file:
file.write(v)
def test_global_idx():
with ManualCodeGenerationContext() as ctx:
from pystencils_walberla.special_symbols import aabb_min_vector, global_coord
dh = GraphDataHandling((20, 30, 40))
my_array = dh.add_array('my_array')
ast = pystencils.create_kernel([pystencils.Assignment(
my_array.center, sum(aabb_min_vector))]).compile()
dh.run_kernel(ast, simulate_only=True)
dh.save_fields('my_array', expanduser('~/foo'))
ast = pystencils.create_kernel([pystencils.Assignment(
my_array.center, sum(global_coord))]).compile()
dh.run_kernel(ast, simulate_only=True)
dh.save_fields('my_array', expanduser('~/foo2'))
# ast = pystencils.create_kernel([pystencils.Assignment(my_array.center, sum(current_global_idx))]).compile()
# dh.run_kernel(ast, simulate_only=True)
sim = Simulation(dh, ctx, cmake_target_name='foo')
sim._debug = False
sim.write_files()
dir = '/localhome/seitz_local/projects/walberla/apps/foo/'
os.makedirs(dir, exist_ok=True)
for k, v in ctx.files.items():
with open(join(dir, k), 'w') as file:
file.write(v)
def test_resolve_parameters():
sym = TypedSymbol('s', create_type('double'))
sym2 = TypedSymbol('t', create_type('double'))
block_forest = UniformBlockforestFromConfig()
module = WalberlaModule(WalberlaMain(Block([
block_forest,
ResolveUndefinedSymbols(
Block([
SympyAssignment(sym, 1 + sym2),
]), 'parameters')
])))
print(module)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment