Skip to content

Commit

Permalink
Merge branch 'develop' into 'main'
Browse files Browse the repository at this point in the history
Update main branch

See merge request ricos/machine_learning/phlower!46
  • Loading branch information
riku-sakamoto committed Nov 20, 2024
2 parents 55f81cd + 5747c75 commit b3ee320
Show file tree
Hide file tree
Showing 178 changed files with 10,505 additions and 1,262 deletions.
23 changes: 22 additions & 1 deletion .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
stages:
- test
- document_test
- deploy

default:
Expand Down Expand Up @@ -37,6 +38,14 @@ pytest:
- no-gpu
- GenuineIntel

gpu_test:
image: pytorch/pytorch:2.5.0-cuda12.4-cudnn9-runtime
stage: test
script:
- make gpu_test
tags:
- gpu

e2e_test:
stage: test
script:
Expand All @@ -45,15 +54,27 @@ e2e_test:
- no-gpu
- GenuineIntel

pages_test:
stage: document_test
script:
- make document
tags:
- no-gpu
- GenuineIntel
artifacts:
paths:
- docs/build/html/

pages:
stage: deploy
script:
- make document
- mkdir public
- cp -r docs/build/html/* public/
artifacts:
paths:
- public
dependencies:
- pages_test
only:
- main
- develop
Expand Down
14 changes: 10 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,28 @@ mypy:

.PHONY: format
format:
poetry run python3 -m ruff check --select I --fix
poetry run python3 -m ruff format
poetry run python3 -m ruff check --fix

.PHONY: test
test:
poetry run pytest tests -m "not e2e_test" --cov=src --cov-report term-missing --durations 5
poetry run pytest tests -m "not e2e_test and not gpu_test" --cov=src --cov-report term-missing --durations 5


.PHONY: test
.PHONY: e2e_test
e2e_test:
poetry run pytest tests -m "e2e_test"


.PHONY: gpu_test
gpu_test:
poetry run pytest tests -m "gpu_test"


.PHONY: lint
lint:
poetry run python3 -m ruff check --diff
poetry run python3 -m ruff check --output-format=full
poetry run python3 -m ruff format --diff
# $(MAKE) mypy

.PHONY: dev-install
Expand Down
15 changes: 11 additions & 4 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "phlower"
version = "0.1.1"
version = "0.2.0"
description = "This is a Python package which helps you handle GNN especially for physics problems."
authors = ["sakamoto <[email protected]>"]
readme = "README.md"
Expand All @@ -22,13 +22,14 @@ pipe = "^2.2"
pyvista = "^0.43.10"
tqdm = "^4.66.4"
pandas = "^2.2.2"
einops = "^0.8.0"

[tool.poetry.group.dev.dependencies]
pytest = "^8.0.2"
mypy = "^1.8.0"
pytest-cov = "^4.1.0"
ruff = "^0.4.10"
hypothesis = "^6.108.2"
hypothesis = {extras = ["numpy"], version = "^6.115.3"}


[tool.poetry.group.docs.dependencies]
Expand All @@ -44,6 +45,7 @@ addopts = [
]
markers = [
"e2e_test: marks tests as End-to-End test (deselect with '-m not e2e_test')",
"gpu_test: marks tests as test using GPUs (deselect with '-m not gpu_test')",
"need_multicore: marks tests which need multiple cores"
]

Expand All @@ -52,7 +54,7 @@ requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

[tool.ruff]
src = ["src", "tests"]
include = ["pyproject.toml", "src/**/*.py", "tests/**/*.py"]

# Exclude a variety of commonly ignored directories.
exclude = [
Expand Down Expand Up @@ -103,8 +105,9 @@ select = [
"B", # flake8-bugbear
"C4", # flake8-comprehensions
"UP", # pyupgrade
"ANN", # flake8-annotations
]
ignore = []
ignore = ["ANN003", "ANN101", "ANN102", "ANN204"]

# Allow fix for all enabled rules (when `--fix`) is provided.
fixable = ["ALL"]
Expand All @@ -113,8 +116,12 @@ unfixable = []
# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"

[tool.ruff.lint.flake8-annotations]
suppress-none-returning = true

[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["F401"]
"src/phlower/_base/**/*.py" = ["ANN401"]

[tool.ruff.format]
# Like Black, use double quotes for strings.
Expand Down
2 changes: 2 additions & 0 deletions src/phlower/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from phlower import nn
from phlower._base import (
PhlowerDimensionTensor,
PhlowerTensor,
Expand All @@ -6,6 +7,7 @@
phlower_tensor,
)
from phlower._base.array import IPhlowerArray
from phlower._fields import ISimulationField
from phlower.version import __version__

__all__ = ["__version__"]
9 changes: 4 additions & 5 deletions src/phlower/_base/_dimension.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from __future__ import annotations

from typing import Annotated, Any
from typing import Annotated

from pydantic import (
PlainSerializer,
Expand All @@ -13,13 +13,12 @@
from phlower.utils.exceptions import InvalidDimensionError


def _validate(v: Any, info: ValidationInfo):
def _validate(v: dict, info: ValidationInfo) -> PhysicalDimensions:
if not isinstance(v, dict):
raise TypeError(f"Expected dictionary, but got {type(v)}")

try:
ans = PhysicalDimensions(v)
return ans
return PhysicalDimensions(v)
except Exception as ex:
raise TypeError("Validation for physical dimension is failed.") from ex

Expand Down Expand Up @@ -78,7 +77,7 @@ def to_list(self) -> list[float]:

return _list

def to_dict(self):
def to_dict(self) -> dict:
return self._dimensions


Expand Down
4 changes: 2 additions & 2 deletions src/phlower/_base/_functionals/_check.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
from phlower._base.tensors._interface import IPhlowerTensor


def is_same_layout(tensors: Sequence[IPhlowerTensor]):
def is_same_layout(tensors: Sequence[IPhlowerTensor]) -> bool:
is_sparse_flags: set[bool] = set(tensors | select(lambda x: x.is_sparse))

return len(is_sparse_flags) == 1


def is_same_dimensions(tensors: Sequence[IPhlowerTensor]):
def is_same_dimensions(tensors: Sequence[IPhlowerTensor]) -> bool:
if len(tensors) == 0:
return True

Expand Down
8 changes: 6 additions & 2 deletions src/phlower/_base/_functionals/_concatenate.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@
from ._check import is_same_dimensions, is_same_layout


def concatenate(tensors: Sequence[IPhlowerTensor], dense_dim: int = 0):
def concatenate(
tensors: Sequence[IPhlowerTensor], dense_dim: int = 0
) -> IPhlowerTensor:
if not is_same_layout(tensors):
raise ValueError("Cannot concatenate dense tensor and sparse tensor")

Expand All @@ -25,7 +27,9 @@ def concatenate(tensors: Sequence[IPhlowerTensor], dense_dim: int = 0):
return _dense_concatenate(tensors, dim=dense_dim)


def _dense_concatenate(tensors: Sequence[IPhlowerTensor], dim: int = 0):
def _dense_concatenate(
tensors: Sequence[IPhlowerTensor], dim: int = 0
) -> IPhlowerTensor:
return torch.concatenate(tensors, dim=dim)


Expand Down
2 changes: 1 addition & 1 deletion src/phlower/_base/_functionals/_to_batch.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ def to_batch(

def _create_batch_info(
tensors: Sequence[IPhlowerTensor], dense_concat_dim: int
):
) -> GraphBatchInfo:
_shapes = list(tensors | select(lambda x: x.shape))

if tensors[0].is_sparse:
Expand Down
32 changes: 28 additions & 4 deletions src/phlower/_base/array/__init__.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,43 @@
# flake8: noqa
from logging import getLogger
from typing import get_args

import numpy as np

from phlower._base import PhysicalDimensions
from phlower._base.array import dense, sparse
from phlower._base.array._interface_wrapper import IPhlowerArray
from phlower.utils.typing import ArrayDataType, DenseArrayType, SparseArrayType

_logger = getLogger(__name__)


def phlower_array(data: ArrayDataType | IPhlowerArray) -> IPhlowerArray:
def phlower_array(
data: ArrayDataType | IPhlowerArray,
is_time_series: bool = False,
is_voxel: bool = False,
dimensions: PhysicalDimensions | None = None,
) -> IPhlowerArray:
if isinstance(data, IPhlowerArray):
_logger.warning(
"phlower_array function is called for PhlowerArray."
"time_series and is_voxel in arguments are ignored."
)
return data

if isinstance(data, DenseArrayType):
return dense.NdArrayWrapper(data)
return dense.NdArrayWrapper(
data,
is_time_series=is_time_series,
is_voxel=is_voxel,
dimensions=dimensions,
)

if isinstance(data, get_args(SparseArrayType)):
return sparse.SparseArrayWrapper(data)
if is_time_series or is_voxel:
raise ValueError(
"Sparse Array cannot have time series flag and voxel flag."
)

return sparse.SparseArrayWrapper(data, dimensions=dimensions)

raise ValueError(f"Unsupported data type: {data.__class__}, {type(data)}")
10 changes: 8 additions & 2 deletions src/phlower/_base/array/_interface_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@

class IPhlowerArray(metaclass=abc.ABCMeta):
@abc.abstractmethod
def __init__(self, data: ArrayDataType) -> None: ...
def __init__(
self, data: ArrayDataType, dimensions: PhysicalDimensions
) -> None: ...

@property
@abc.abstractmethod
Expand All @@ -20,6 +22,10 @@ def is_time_series(self) -> int | None: ...
@abc.abstractmethod
def is_sparse(self) -> bool: ...

@property
@abc.abstractmethod
def is_voxel(self) -> bool: ...

@property
@abc.abstractmethod
def shape(self) -> tuple[int]: ...
Expand Down Expand Up @@ -71,7 +77,7 @@ def to_phlower_tensor(
self,
device: str | torch.device | None = None,
non_blocking: bool = False,
dimension: PhysicalDimensions | None = None,
disable_dimensions: bool = False,
) -> PhlowerTensor: ...

@abc.abstractmethod
Expand Down
23 changes: 19 additions & 4 deletions src/phlower/_base/array/dense/_ndarray_wrapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,17 @@


class NdArrayWrapper(IPhlowerArray):
def __init__(self, data: np.ndarray, is_timeseries: bool = False):
def __init__(
self,
data: np.ndarray,
is_time_series: bool = False,
is_voxel: bool = False,
dimensions: PhysicalDimensions | None = None,
):
self.data = data
self._is_time_series = is_timeseries
self._is_time_series = is_time_series
self._is_voxel = is_voxel
self._dimensions = dimensions

@property
def shape(self) -> tuple[int]:
Expand All @@ -22,6 +30,10 @@ def shape(self) -> tuple[int]:
def is_time_series(self) -> bool:
return self._is_time_series

@property
def is_voxel(self) -> bool:
return self._is_voxel

@property
def is_sparse(self) -> bool:
return False
Expand Down Expand Up @@ -63,10 +75,13 @@ def to_phlower_tensor(
self,
device: str | torch.device | None = None,
non_blocking: bool = False,
dimension: PhysicalDimensions | None = None,
disable_dimensions: bool = False,
) -> PhlowerTensor:
_tensor = phlower_tensor(
tensor=torch.from_numpy(self.data), dimension=dimension
tensor=torch.from_numpy(self.data),
dimension=None if disable_dimensions else self._dimensions,
is_time_series=self._is_time_series,
is_voxel=self._is_voxel,
)
_tensor.to(device=device, non_blocking=non_blocking)
return _tensor
Expand Down
Loading

0 comments on commit b3ee320

Please sign in to comment.