Skip to content

Commit

Permalink
Add binding for LabeledAxisAccessor
Browse files Browse the repository at this point in the history
  • Loading branch information
hugary1995 committed Feb 25, 2024
1 parent b125e39 commit 98968c7
Show file tree
Hide file tree
Showing 4 changed files with 164 additions and 2 deletions.
12 changes: 10 additions & 2 deletions python/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,22 @@ file(GLOB_RECURSE tensors_srcs neml2_wrap/tensors/*.cxx)
pybind11_add_module(tensors ${tensors_srcs})
target_include_directories(tensors PUBLIC ${NEML2_SOURCE_DIR}/python ${NEML2_BINARY_DIR}/python)
target_link_libraries(tensors PUBLIC neml2 ${LIBTORCH_PYTHON})
set_target_properties(tensors PROPERTIES INSTALL_RPATH "${PYNEML2_INSTALL_RPATH}")
set_target_properties(tensors
PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${NEML2_BINARY_DIR}/python/neml2
INSTALL_RPATH "${PYNEML2_INSTALL_RPATH}"
)
install(TARGETS tensors LIBRARY DESTINATION neml2)

# Define submodule math
pybind11_add_module(math neml2_wrap/misc/math.cxx)
target_include_directories(math PUBLIC ${NEML2_SOURCE_DIR}/python ${NEML2_BINARY_DIR}/python)
target_link_libraries(math PUBLIC neml2 ${LIBTORCH_PYTHON})
set_target_properties(math PROPERTIES INSTALL_RPATH "${PYNEML2_INSTALL_RPATH}")
set_target_properties(math
PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${NEML2_BINARY_DIR}/python/neml2
INSTALL_RPATH "${PYNEML2_INSTALL_RPATH}"
)
install(TARGETS math LIBRARY DESTINATION neml2)

# Install python files
Expand Down
58 changes: 58 additions & 0 deletions python/neml2_wrap/tensors/LabeledAxisAccessor.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2023, UChicago Argonne, LLC
// All Rights Reserved
// Software Name: NEML2 -- the New Engineering material Model Library, version 2
// By: Argonne National Laboratory
// OPEN SOURCE LICENSE (MIT)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

#include <pybind11/pybind11.h>

#include "neml2/tensors/LabeledAxisAccessor.h"
#include "neml2/misc/utils.h"

namespace py = pybind11;
using namespace neml2;

void
def_LabeledAxisAccessor(py::module_ & m)
{
auto c = py::class_<LabeledAxisAccessor>(m, "LabeledAxisAccessor");

// Ctors
c.def(py::init<>())
.def(py::init<const std::string &>())
.def(py::init<const std::string &, const std::string &>())
.def(py::init<const std::string &, const std::string &, const std::string &>())
.def(py::init<const std::vector<std::string> &>())
.def(py::init<const LabeledAxisAccessor &>())
.def("empty", &LabeledAxisAccessor::empty)
.def("size", &LabeledAxisAccessor::size)
.def("with_suffix", &LabeledAxisAccessor::with_suffix)
.def("append", &LabeledAxisAccessor::append)
.def("on", &LabeledAxisAccessor::on)
.def("start_with", &LabeledAxisAccessor::start_with);

// Operators
c.def("__repr__", [](const LabeledAxisAccessor & self) { return utils::stringify(self); })
.def("__eq__",
[](const LabeledAxisAccessor & a, const LabeledAxisAccessor & b) { return a == b; })
.def("__ne__",
[](const LabeledAxisAccessor & a, const LabeledAxisAccessor & b) { return a == b; });
}
4 changes: 4 additions & 0 deletions python/neml2_wrap/tensors/tensors.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ using namespace neml2;
// Forward declarations
#define TENSOR_CUSTOM_DEF_FWD(T) void def_##T(py::class_<T> &)
FOR_ALL_BATCHTENSORBASE(TENSOR_CUSTOM_DEF_FWD);
void def_LabeledAxisAccessor(py::module_ & m);

PYBIND11_MODULE(tensors, m)
{
Expand Down Expand Up @@ -77,4 +78,7 @@ PYBIND11_MODULE(tensors, m)
// Tensor specific methods
#define TENSOR_CUSTOM_DEF(T) def_##T(c_##T);
FOR_ALL_BATCHTENSORBASE(TENSOR_CUSTOM_DEF);

// Labeled tensors
def_LabeledAxisAccessor(m);
}
92 changes: 92 additions & 0 deletions tests/python/tensors/test_LabeledAxisAccessor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
# Copyright 2023, UChicago Argonne, LLC
# All Rights Reserved
# Software Name: NEML2 -- the New Engineering material Model Library, version 2
# By: Argonne National Laboratory
# OPEN SOURCE LICENSE (MIT)
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.

import pytest

from neml2.tensors import LabeledAxisAccessor


@pytest.mark.it("Constructors")
def test_ctors():
A = LabeledAxisAccessor()
assert str(A) == ""

A = LabeledAxisAccessor("state")
assert str(A) == "state"

A = LabeledAxisAccessor("force")
assert str(A) == "force"

A = LabeledAxisAccessor("state", "stress")
assert str(A) == "state/stress"

A = LabeledAxisAccessor("state", "internal", "gamma")
assert str(A) == "state/internal/gamma"


@pytest.mark.it("empty")
def test_empty():
A = LabeledAxisAccessor()
B = LabeledAxisAccessor("state", "stress")
assert A.empty()
assert not B.empty()


@pytest.mark.it("size")
def test_size():
A = LabeledAxisAccessor()
B = LabeledAxisAccessor("state", "stress")
assert A.size() == 0
assert B.size() == 2


@pytest.mark.it("with_suffix")
def test_with_suffix():
A = LabeledAxisAccessor("state", "stress")
B = LabeledAxisAccessor("state", "stress_foo")
assert A.with_suffix("_foo") == B


@pytest.mark.it("append")
def test_append():
A = LabeledAxisAccessor("state")
B = LabeledAxisAccessor("foo", "bar")
C = LabeledAxisAccessor("state", "foo", "bar")
assert A.append(B) == C


@pytest.mark.it("on")
def test_on():
A = LabeledAxisAccessor("stress")
B = LabeledAxisAccessor("residual", "stress")
assert A.on(LabeledAxisAccessor("residual")) == B


@pytest.mark.it("start_with")
def test_start_with():
A = LabeledAxisAccessor("internal", "stress", "foo")
B = LabeledAxisAccessor("internal", "stress")
C = LabeledAxisAccessor("residual", "stress")
assert A.start_with(B)
assert not A.start_with(C)

0 comments on commit 98968c7

Please sign in to comment.