Skip to content

Commit

Permalink
[Φ] Update to phiml==1.5.1
Browse files Browse the repository at this point in the history
  • Loading branch information
holl- committed May 2, 2024
1 parent ca0b675 commit dda6042
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 38 deletions.
2 changes: 1 addition & 1 deletion PhiML
Submodule PhiML updated 53 files
+1 −1 .github/workflows/unit-tests.yml
+20 −3 README.md
+929 −0 docs/Advantages_Data_Types.ipynb
+142 −128 docs/Data_Types.ipynb
+616 −0 docs/Dimension_Names_Types.ipynb
+0 −397 docs/Networks.ipynb
+408 −0 docs/Performance.ipynb
+417 −359 docs/Shapes.ipynb
+145 −119 docs/Tensors.ipynb
+6 −0 docs/index.md
+1 −1 phiml/VERSION
+78 −10 phiml/_troubleshoot.py
+2 −2 phiml/backend/__init__.py
+148 −42 phiml/backend/_backend.py
+127 −0 phiml/backend/_buffer.py
+1 −1 phiml/backend/_dtype.py
+66 −57 phiml/backend/_linalg.py
+39 −18 phiml/backend/_minimize.py
+82 −31 phiml/backend/_numpy_backend.py
+20 −0 phiml/backend/_object.py
+83 −35 phiml/backend/_partition.py
+74 −32 phiml/backend/jax/_jax_backend.py
+21 −18 phiml/backend/jax/stax_nets.py
+198 −112 phiml/backend/tensorflow/_tf_backend.py
+35 −23 phiml/backend/tensorflow/nets.py
+132 −74 phiml/backend/torch/_torch_backend.py
+25 −23 phiml/backend/torch/nets.py
+15 −9 phiml/math/__init__.py
+262 −97 phiml/math/_functional.py
+133 −20 phiml/math/_magic_ops.py
+200 −17 phiml/math/_nd.py
+704 −304 phiml/math/_ops.py
+116 −64 phiml/math/_optimize.py
+159 −65 phiml/math/_shape.py
+517 −139 phiml/math/_sparse.py
+232 −197 phiml/math/_tensors.py
+575 −86 phiml/math/_trace.py
+124 −59 phiml/math/extrapolation.py
+10 −6 phiml/math/magic.py
+43 −41 phiml/nn.py
+2 −1 tests/commit/backend/test__backend.py
+1 −0 tests/commit/backend/test_jax_backend.py
+1 −0 tests/commit/backend/test_tf_backend.py
+1 −0 tests/commit/backend/test_torch_backend.py
+63 −4 tests/commit/math/test__functional.py
+79 −0 tests/commit/math/test__nd.py
+181 −8 tests/commit/math/test__ops.py
+18 −0 tests/commit/math/test__optimize.py
+25 −1 tests/commit/math/test__shape.py
+55 −3 tests/commit/math/test__sparse.py
+12 −0 tests/commit/math/test__tensors.py
+13 −4 tests/commit/math/test__trace.py
+1 −1 tests/commit/math/test_extrapolation.py
4 changes: 2 additions & 2 deletions phi/field/_grid.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ def with_bounds(self, bounds: Box):
return type(self)(self.values, extrapolation=self.extrapolation, bounds=bounds)

def __value_attrs__(self):
return '_values', '_extrapolation'
return '_values',

def __variable_attrs__(self):
return '_values',
return '_values', '_extrapolation'

def __expand__(self, dims: Shape, **kwargs) -> 'Grid':
return self.with_values(math.expand(self.values, dims, **kwargs))
Expand Down
4 changes: 2 additions & 2 deletions phi/field/_point_cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,10 +87,10 @@ def with_bounds(self, bounds: Box):
return PointCloud(elements=self.elements, values=self.values, extrapolation=self.extrapolation, add_overlapping=self._add_overlapping, bounds=bounds)

def __value_attrs__(self):
return '_values', '_extrapolation'
return '_values', '_extrapolation', '_elements'

def __variable_attrs__(self):
return '_values', '_elements'
return '_values', '_elements', '_extrapolation'

def __expand__(self, dims: Shape, **kwargs) -> 'PointCloud':
return self.with_values(expand(self.values, dims, **kwargs))
Expand Down
7 changes: 2 additions & 5 deletions phi/field/_scene.py
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ def at(directory: Union[str, tuple, typing_list, math.Tensor, 'Scene'], id: Unio
id = math.wrap(id)
paths = math.map(lambda d, i: join(d, f"sim_{i:06d}"), directory, id)
# test all exist
for path in math.flatten(paths, flatten_batch=True):
for path in math.flatten(wrap(paths), flatten_batch=True):
if not isdir(path):
raise IOError(f"There is no scene at '{path}'")
return Scene(paths)
Expand All @@ -241,10 +241,7 @@ def single_subpath(path):
return path

result = math.map(single_subpath, self._paths)
if result.rank == 0:
return result.native()
else:
return result
return result

def _init_properties(self):
if self._properties is not None:
Expand Down
3 changes: 3 additions & 0 deletions phi/geom/_sphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ def scaled(self, factor: Union[float, Tensor]) -> 'Geometry':
def __variable_attrs__(self):
return '_center', '_radius'

def __value_attrs__(self):
return '_center', '_radius'

def __getitem__(self, item):
item = slicing_dict(self, item)
return Sphere(self._center[_keep_vector(item)], self._radius[item])
Expand Down
41 changes: 21 additions & 20 deletions phi/geom/_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ class GeometryStack(Geometry):

def __init__(self, geometries: Tensor):
self.geometries = geometries
self._shape = shape_stack(geometries.shape, *[g.shape for g in geometries])
inner_dims = math.merge_shapes(*[g.shape for g in geometries], allow_varying_sizes=True)
self._stack_dim = geometries.shape.without(inner_dims)
self._shape = geometries.shape

def unstack(self, dimension) -> tuple:
if dimension == self.geometries.shape.name:
if dimension == self._stack_dim.name:
return tuple(self.geometries)
else:
# return GeometryStack([g.unstack(dimension) for g in self.geometries], self.geometries.shape)
Expand All @@ -25,7 +27,7 @@ def unstack(self, dimension) -> tuple:
@property
def center(self):
centers = [g.center for g in self.geometries]
return math.stack(centers, self.geometries.shape)
return math.stack(centers, self._stack_dim)

@property
def spatial_rank(self) -> int:
Expand All @@ -37,57 +39,57 @@ def shape(self) -> Shape:

@property
def volume(self) -> math.Tensor:
if self.geometries.shape.type == INSTANCE_DIM:
if self._stack_dim.type == INSTANCE_DIM:
raise NotImplementedError("instance dimensions not yet supported")
return math.stack([g.volume for g in self.geometries], self.geometries.shape)
return math.stack([g.volume for g in self.geometries], self._stack_dim)

@property
def shape_type(self) -> Tensor:
types = [g.shape_type for g in self.geometries]
return math.stack(types, self.geometries.shape)
return math.stack(types, self._stack_dim)

def lies_inside(self, location: math.Tensor):
if self.geometries.shape in location.shape:
location = location.unstack(self.geometries.shape.name)
if self._stack_dim in location.shape:
location = location.unstack(self._stack_dim.name)
else:
location = [location] * len(self.geometries)
inside = [g.lies_inside(loc) for g, loc in zip(self.geometries, location)]
return math.stack(inside, self.geometries.shape)
return math.stack(inside, self._stack_dim)

def approximate_signed_distance(self, location: math.Tensor):
raise NotImplementedError()

def bounding_radius(self):
radii = [expand(g.bounding_radius(), non_channel(g)) for g in self.geometries]
return math.stack(radii, self.geometries.shape)
return math.stack(radii, self._stack_dim)

def bounding_half_extent(self):
values = [expand(g.bounding_half_extent(), non_channel(g)) for g in self.geometries]
return math.stack(values, self.geometries.shape)
return math.stack(values, self._stack_dim)

def at(self, center: Tensor) -> 'Geometry':
geometries = [self.geometries[idx].native().at(center[idx]) for idx in self.geometries.shape.meshgrid()]
return GeometryStack(math.layout(geometries, self.geometries.shape))
geometries = [self.geometries[idx].at(center[idx]) for idx in self._stack_dim.meshgrid()]
return GeometryStack(math.layout(geometries, self._stack_dim))

def rotated(self, angle):
geometries = [g.rotated(angle) for g in self.geometries]
return GeometryStack(math.layout(geometries, self.geometries.shape))
return GeometryStack(math.layout(geometries, self._stack_dim))

def push(self, positions: Tensor, outward: bool = True, shift_amount: float = 0) -> Tensor:
raise NotImplementedError('GeometryStack.push() is not yet implemented.')

def __eq__(self, other):
return isinstance(other, GeometryStack) \
and self._shape == other.shape \
and self.geometries.shape == other.stack_dim \
and self._stack_dim == other.stack_dim \
and self.geometries == other.geometries

def shallow_equals(self, other):
if self is other:
return True
if not isinstance(other, GeometryStack) or self._shape != other.shape:
return False
if self.geometries.shape != other.geometries.shape:
if self._stack_dim != other.geometries.shape:
return False
return all(g1.shallow_equals(g2) for g1, g2 in zip(self.geometries, other.geometries))

Expand All @@ -96,7 +98,6 @@ def __hash__(self):

def __getitem__(self, item):
selected = self.geometries[slicing_dict(self, item)]
if selected.shape.volume > 1:
return GeometryStack(selected)
else:
return next(iter(selected))
if isinstance(selected, Geometry):
return selected
return GeometryStack(selected)
10 changes: 5 additions & 5 deletions phi/vis/_vis.py
Original file line number Diff line number Diff line change
Expand Up @@ -437,28 +437,28 @@ def layout_sub_figures(data: Union[Tensor, SampledField],
dim0 = reduced = data.shape[0]
if dim0.only(overlay):
for overlay_index in dim0.only(overlay).meshgrid(names=True): # overlay these fields
e_rows, e_cols, d_non_reduced, d_reduced = layout_sub_figures(data[overlay_index].native(), row_dims, col_dims, animate, overlay, offset_row, offset_col, positioning, indices, {**base_index, **overlay_index})
e_rows, e_cols, d_non_reduced, d_reduced = layout_sub_figures(data[overlay_index], row_dims, col_dims, animate, overlay, offset_row, offset_col, positioning, indices, {**base_index, **overlay_index})
rows = max(rows, e_rows)
cols = max(cols, e_cols)
non_reduced &= d_non_reduced
reduced = merge_shapes(reduced, d_reduced, allow_varying_sizes=True)
elif dim0.only(animate):
data = math.stack(data.native(), dim0)
data = math.stack(data, dim0)
return layout_sub_figures(data, row_dims, col_dims, animate, overlay, offset_row, offset_col, positioning, indices, base_index)
else:
elements = unstack(data, dim0)
for item_name, e in zip(dim0.get_item_names(dim0.name) or range(dim0.size), elements):
index = dict(base_index, **{dim0.name: item_name})
if dim0.only(row_dims):
e_rows, e_cols, e_non_reduced, e_reduced = layout_sub_figures(e.native(), row_dims, col_dims, animate, overlay, offset_row + rows, offset_col, positioning, indices, index)
e_rows, e_cols, e_non_reduced, e_reduced = layout_sub_figures(e, row_dims, col_dims, animate, overlay, offset_row + rows, offset_col, positioning, indices, index)
rows += e_rows
cols = max(cols, e_cols)
elif dim0.only(col_dims):
e_rows, e_cols, e_non_reduced, e_reduced = layout_sub_figures(e.native(), row_dims, col_dims, animate, overlay, offset_row, offset_col + cols, positioning, indices, index)
e_rows, e_cols, e_non_reduced, e_reduced = layout_sub_figures(e, row_dims, col_dims, animate, overlay, offset_row, offset_col + cols, positioning, indices, index)
cols += e_cols
rows = max(rows, e_rows)
else:
e_rows, e_cols, e_non_reduced, e_reduced = layout_sub_figures(e.native(), row_dims, col_dims, animate, overlay, offset_row, offset_col, positioning, indices, index)
e_rows, e_cols, e_non_reduced, e_reduced = layout_sub_figures(e, row_dims, col_dims, animate, overlay, offset_row, offset_col, positioning, indices, index)
cols = max(cols, e_cols)
rows = max(rows, e_rows)
non_reduced &= e_non_reduced
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
url='https://github.com/tum-pbs/PhiFlow',
include_package_data=True,
install_requires=[
'phiml==1.2.1',
'phiml==1.5.1',
'matplotlib>=3.5.0', # also required by dash for color maps
'packaging',
],
Expand Down
2 changes: 0 additions & 2 deletions tests/commit/geom/test__sphere.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,10 +58,8 @@ def test_reshaping_const_radius(self):
s = expand(s, batch(b=100))
s = rename_dims(s, 'b', 'bat')
s = unpack_dim(s, 'points', spatial(x=10, y=5))
assert not s.radius.shape
assert batch(bat=100) & spatial(x=10, y=5) & channel(vector='x,y') == s.shape
s = pack_dims(s, 'x,y', instance('particles'))
assert not s.radius.shape
assert batch(bat=100) & instance(particles=50) & channel(vector='x,y') == s.shape
s = flatten(s)
assert batch(bat=100) & instance(flat=50) & channel(vector='x,y') == s.shape

0 comments on commit dda6042

Please sign in to comment.