Skip to content
GitLab
Projects
Groups
Snippets
/
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Tom Harke
pystencils
Commits
0e2c793a
Commit
0e2c793a
authored
Jan 06, 2018
by
Martin Bauer
Browse files
Removed flag array support
because boundary handling does its own flag management
parent
032f1be5
Changes
3
Hide whitespace changes
Inline
Side-by-side
datahandling.py
View file @
0e2c793a
...
...
@@ -4,7 +4,6 @@ from abc import ABC, abstractmethod, abstractproperty
from
collections
import
defaultdict
from
contextlib
import
contextmanager
from
lbmpy.boundaries.periodicityhandling
import
PeriodicityHandling
from
lbmpy.stencils
import
getStencil
from
pystencils
import
Field
,
makeSlice
from
pystencils.parallel.blockiteration
import
BlockIterationInfo
...
...
@@ -16,62 +15,6 @@ try:
except
ImportError
:
gpuarray
=
None
class
WalberlaFlagInterface
:
def
__init__
(
self
,
flagField
):
self
.
flagField
=
flagField
def
registerFlag
(
self
,
flagName
):
return
self
.
flagField
.
registerFlag
(
flagName
)
def
flag
(
self
,
flagName
):
return
self
.
flagField
.
flag
(
flagName
)
def
flagName
(
self
,
flag
):
return
self
.
flagField
.
flagName
(
flag
)
@
property
def
flags
(
self
):
return
self
.
flagField
.
flags
class
PythonFlagInterface
:
def
__init__
(
self
):
self
.
nameToFlag
=
{}
self
.
flagToName
=
{}
self
.
nextFreeBit
=
0
def
registerFlag
(
self
,
flagName
):
assert
flagName
not
in
self
.
nameToFlag
flag
=
1
<<
self
.
nextFreeBit
self
.
nextFreeBit
+=
1
self
.
flagToName
[
flag
]
=
flagName
self
.
nameToFlag
[
flagName
]
=
flag
return
flag
def
flag
(
self
,
flagName
):
return
self
.
nameToFlag
[
flagName
]
def
flagName
(
self
,
flag
):
return
self
.
flagToName
[
flag
]
@
property
def
flags
(
self
):
return
tuple
(
self
.
nameToFlag
.
keys
())
class
FlagArray
(
np
.
ndarray
):
def
__new__
(
cls
,
inputArray
,
flagInterface
):
obj
=
np
.
asarray
(
inputArray
).
view
(
cls
)
obj
.
flagInterface
=
flagInterface
assert
inputArray
.
dtype
.
kind
in
(
'u'
,
'i'
),
"FlagArrays can only be created from integer arrays"
return
obj
def
__array_finalize__
(
self
,
obj
):
if
obj
is
None
:
return
self
.
flagInterface
=
getattr
(
obj
,
'flagInterface'
,
None
)
class
DataHandling
(
ABC
):
"""
Manages the storage of arrays and maps them to a symbolic field.
...
...
@@ -113,6 +56,12 @@ class DataHandling(ABC):
:param gpu: allocate field on the GPU
"""
@
abstractmethod
def
hasData
(
self
,
name
):
"""
Returns true if a field or custom data element with this name was added
"""
@
abstractmethod
def
addLike
(
self
,
name
,
nameOfTemplateField
,
latexName
=
None
,
cpu
=
True
,
gpu
=
False
):
"""
...
...
@@ -124,13 +73,6 @@ class DataHandling(ABC):
:param gpu: see 'add' method
"""
def
addFlagArray
(
self
,
name
,
dtype
=
np
.
int32
,
latexName
=
None
,
ghostLayers
=
None
):
"""
Adds a flag array (of integer type) where each bit is interpreted as a boolean
Flag arrays additionally store a mapping of name to bit nr, which is accessible as arr.flagInterface.
For parameter documentation see 'add()' function.
"""
@
property
@
abstractmethod
def
fields
(
self
):
...
...
@@ -297,13 +239,10 @@ class SerialDataHandling(DataHandling):
self
.
fields
[
name
]
=
Field
.
createFixedSize
(
latexName
,
shape
=
kwargs
[
'shape'
],
indexDimensions
=
indexDimensions
,
dtype
=
kwargs
[
'dtype'
],
layout
=
kwargs
[
'order'
])
def
addFlagArray
(
self
,
name
,
dtype
=
np
.
int32
,
latexName
=
None
,
ghostLayers
=
None
):
self
.
add
(
name
,
1
,
dtype
,
latexName
,
ghostLayers
,
layout
=
'AoS'
,
cpu
=
True
,
gpu
=
False
)
self
.
cpuArrays
[
name
]
=
FlagArray
(
self
.
cpuArrays
[
name
],
PythonFlagInterface
())
def
hasData
(
self
,
name
):
return
name
in
self
.
fields
def
addLike
(
self
,
name
,
nameOfTemplateField
,
latexName
=
None
,
cpu
=
True
,
gpu
=
False
):
if
hasattr
(
self
.
fields
[
nameOfTemplateField
],
'flagInterface'
):
raise
ValueError
(
"addLike() does not work for flag arrays"
)
self
.
add
(
name
,
latexName
=
latexName
,
cpu
=
cpu
,
gpu
=
gpu
,
**
self
.
_fieldInformation
[
nameOfTemplateField
])
def
access
(
self
,
name
,
sliceObj
=
None
,
outerGhostLayers
=
'all'
,
**
kwargs
):
...
...
field.py
View file @
0e2c793a
...
...
@@ -465,7 +465,7 @@ def layoutStringToTuple(layoutStr, dim):
elif
layoutStr
==
'zyxf'
or
layoutStr
==
'aos'
:
assert
dim
<=
4
return
tuple
(
reversed
(
range
(
dim
-
1
)))
+
(
dim
-
1
,)
elif
layoutStr
==
'f'
or
layoutStr
==
'reverse
N
umpy'
:
elif
layoutStr
==
'f'
or
layoutStr
==
'reverse
n
umpy'
:
return
tuple
(
reversed
(
range
(
dim
)))
elif
layoutStr
==
'c'
or
layoutStr
==
'numpy'
:
return
tuple
(
range
(
dim
))
...
...
parallel/datahandling.py
View file @
0e2c793a
import
numpy
as
np
from
pystencils
import
Field
,
makeSlice
from
pystencils.datahandling
import
DataHandling
,
FlagArray
,
WalberlaFlagInterface
from
pystencils.datahandling
import
DataHandling
from
pystencils.parallel.blockiteration
import
slicedBlockIteration
from
pystencils.utils
import
DotDict
import
waLBerla
as
wlb
...
...
@@ -42,14 +42,51 @@ class ParallelDataHandling(DataHandling):
return
self
.
_fields
def
add
(
self
,
name
,
fSize
=
1
,
dtype
=
np
.
float64
,
latexName
=
None
,
ghostLayers
=
None
,
layout
=
None
,
cpu
=
True
,
gpu
=
False
):
return
self
.
_add
(
name
,
fSize
,
dtype
,
latexName
,
ghostLayers
,
layout
,
cpu
,
gpu
,
flagField
=
False
)
if
ghostLayers
is
None
:
ghostLayers
=
self
.
defaultGhostLayers
if
layout
is
None
:
layout
=
self
.
defaultLayout
if
latexName
is
None
:
latexName
=
name
if
len
(
self
.
blocks
)
==
0
:
raise
ValueError
(
"Data handling expects that each process has at least one block"
)
if
hasattr
(
dtype
,
'type'
):
dtype
=
dtype
.
type
if
name
in
self
.
blocks
[
0
]
or
self
.
GPU_DATA_PREFIX
+
name
in
self
.
blocks
[
0
]:
raise
ValueError
(
"Data with this name has already been added"
)
def
addLike
(
self
,
name
,
nameOfTemplateField
,
latexName
=
None
,
cpu
=
True
,
gpu
=
False
):
assert
not
self
.
_fieldInformation
[
nameOfTemplateField
][
'flagField'
]
self
.
_add
(
name
,
latexName
=
latexName
,
cpu
=
cpu
,
gpu
=
gpu
,
**
self
.
_fieldInformation
[
nameOfTemplateField
])
self
.
_fieldInformation
[
name
]
=
{
'ghostLayers'
:
ghostLayers
,
'fSize'
:
fSize
,
'layout'
:
layout
,
'dtype'
:
dtype
}
def
addFlagArray
(
self
,
name
,
dtype
=
np
.
int32
,
latexName
=
None
,
ghostLayers
=
None
):
return
self
.
_add
(
name
,
dtype
=
dtype
,
latexName
=
latexName
,
ghostLayers
=
ghostLayers
,
flagField
=
True
)
layoutMap
=
{
'fzyx'
:
wlb
.
field
.
Layout
.
fzyx
,
'zyxf'
:
wlb
.
field
.
Layout
.
zyxf
,
'SoA'
:
wlb
.
field
.
Layout
.
fzyx
,
'AoS'
:
wlb
.
field
.
Layout
.
zyxf
}
if
cpu
:
wlb
.
field
.
addToStorage
(
self
.
blocks
,
name
,
dtype
,
fSize
=
fSize
,
layout
=
layoutMap
[
layout
],
ghostLayers
=
ghostLayers
)
if
gpu
:
wlb
.
cuda
.
addGpuFieldToStorage
(
self
.
blocks
,
self
.
GPU_DATA_PREFIX
+
name
,
dtype
,
fSize
=
fSize
,
usePitchedMem
=
False
,
ghostLayers
=
ghostLayers
,
layout
=
layoutMap
[
layout
])
if
cpu
and
gpu
:
self
.
_cpuGpuPairs
.
append
((
name
,
self
.
GPU_DATA_PREFIX
+
name
))
blockBB
=
self
.
blocks
.
getBlockCellBB
(
self
.
blocks
[
0
])
shape
=
tuple
(
s
+
2
*
ghostLayers
for
s
in
blockBB
.
size
)
indexDimensions
=
1
if
fSize
>
1
else
0
if
indexDimensions
==
1
:
shape
+=
(
fSize
,
)
assert
all
(
f
.
name
!=
latexName
for
f
in
self
.
fields
.
values
()),
"Symbolic field with this name already exists"
self
.
fields
[
name
]
=
Field
.
createFixedSize
(
latexName
,
shape
,
indexDimensions
,
dtype
,
layout
)
def
hasData
(
self
,
name
):
return
name
in
self
.
_fields
def
addLike
(
self
,
name
,
nameOfTemplateField
,
latexName
=
None
,
cpu
=
True
,
gpu
=
False
):
self
.
add
(
name
,
latexName
=
latexName
,
cpu
=
cpu
,
gpu
=
gpu
,
**
self
.
_fieldInformation
[
nameOfTemplateField
])
def
swap
(
self
,
name1
,
name2
,
gpu
=
False
):
if
gpu
:
...
...
@@ -68,8 +105,6 @@ class ParallelDataHandling(DataHandling):
for
iterInfo
in
slicedBlockIteration
(
self
.
blocks
,
sliceObj
,
innerGhostLayers
,
outerGhostLayers
):
arr
=
wlb
.
field
.
toArray
(
iterInfo
.
block
[
name
],
withGhostLayers
=
innerGhostLayers
)[
iterInfo
.
localSlice
]
if
fieldInfo
[
'flagField'
]:
arr
=
FlagArray
(
arr
,
WalberlaFlagInterface
(
iterInfo
.
block
[
name
]))
if
self
.
fields
[
name
].
indexDimensions
==
0
:
arr
=
arr
[...,
0
]
if
self
.
dim
==
2
:
...
...
@@ -107,55 +142,6 @@ class ParallelDataHandling(DataHandling):
def
synchronizationFunctionGPU
(
self
,
names
,
stencil
=
None
,
buffered
=
True
,
**
kwargs
):
return
self
.
_synchronizationFunction
(
names
,
stencil
,
buffered
,
'gpu'
)
def
_add
(
self
,
name
,
fSize
=
1
,
dtype
=
np
.
float64
,
latexName
=
None
,
ghostLayers
=
None
,
layout
=
None
,
cpu
=
True
,
gpu
=
False
,
flagField
=
False
):
if
ghostLayers
is
None
:
ghostLayers
=
self
.
defaultGhostLayers
if
layout
is
None
:
layout
=
self
.
defaultLayout
if
latexName
is
None
:
latexName
=
name
if
len
(
self
.
blocks
)
==
0
:
raise
ValueError
(
"Data handling expects that each process has at least one block"
)
if
hasattr
(
dtype
,
'type'
):
dtype
=
dtype
.
type
if
name
in
self
.
blocks
[
0
]
or
self
.
GPU_DATA_PREFIX
+
name
in
self
.
blocks
[
0
]:
raise
ValueError
(
"Data with this name has already been added"
)
self
.
_fieldInformation
[
name
]
=
{
'ghostLayers'
:
ghostLayers
,
'fSize'
:
fSize
,
'layout'
:
layout
,
'dtype'
:
dtype
,
'flagField'
:
flagField
}
layoutMap
=
{
'fzyx'
:
wlb
.
field
.
Layout
.
fzyx
,
'zyxf'
:
wlb
.
field
.
Layout
.
zyxf
,
'SoA'
:
wlb
.
field
.
Layout
.
fzyx
,
'AoS'
:
wlb
.
field
.
Layout
.
zyxf
}
if
flagField
:
assert
not
gpu
assert
np
.
dtype
(
dtype
).
kind
in
(
'u'
,
'i'
),
"FlagArrays can only be created from integer arrays"
nrOfBits
=
np
.
dtype
(
dtype
).
itemsize
*
8
wlb
.
field
.
addFlagFieldToStorage
(
self
.
blocks
,
name
,
nrOfBits
,
ghostLayers
)
else
:
if
cpu
:
wlb
.
field
.
addToStorage
(
self
.
blocks
,
name
,
dtype
,
fSize
=
fSize
,
layout
=
layoutMap
[
layout
],
ghostLayers
=
ghostLayers
)
if
gpu
:
wlb
.
cuda
.
addGpuFieldToStorage
(
self
.
blocks
,
self
.
GPU_DATA_PREFIX
+
name
,
dtype
,
fSize
=
fSize
,
usePitchedMem
=
False
,
ghostLayers
=
ghostLayers
,
layout
=
layoutMap
[
layout
])
if
cpu
and
gpu
:
self
.
_cpuGpuPairs
.
append
((
name
,
self
.
GPU_DATA_PREFIX
+
name
))
blockBB
=
self
.
blocks
.
getBlockCellBB
(
self
.
blocks
[
0
])
shape
=
tuple
(
s
+
2
*
ghostLayers
for
s
in
blockBB
.
size
)
indexDimensions
=
1
if
fSize
>
1
else
0
if
indexDimensions
==
1
:
shape
+=
(
fSize
,
)
assert
all
(
f
.
name
!=
latexName
for
f
in
self
.
fields
.
values
()),
"Symbolic field with this name already exists"
self
.
fields
[
name
]
=
Field
.
createFixedSize
(
latexName
,
shape
,
indexDimensions
,
dtype
,
layout
)
def
_synchronizationFunction
(
self
,
names
,
stencil
,
buffered
,
target
):
if
stencil
is
None
:
stencil
=
'D3Q27'
if
self
.
dim
==
3
else
'D2Q9'
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment