diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 19c552a..d82d81a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -34,16 +34,8 @@ jobs: environment-file: environment.yaml environment-name: myenv - - name: Configure - run: cmake -Bbuild - - name: Build - working-directory: build - run: make - - - name: Copy - run: cp example.py build/ + run: python -m pip install . - name: Run - working-directory: build run: python example.py diff --git a/.gitignore b/.gitignore index b6e4761..727f65a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ +_skbuild + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/CMakeLists.txt b/CMakeLists.txt index 61db670..5a5bfff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,16 +1,23 @@ cmake_minimum_required(VERSION 3.18..3.21) -project(mymodule) +project("_mymodule") -find_package(GooseFEM REQUIRED) +find_package(xtensor REQUIRED) set(CMAKE_BUILD_TYPE Release) find_package(pybind11 REQUIRED CONFIG) - -find_package(Python REQUIRED COMPONENTS Interpreter Development) +find_package(NumPy REQUIRED) pybind11_add_module(${PROJECT_NAME} main.cpp) target_compile_definitions(${PROJECT_NAME} PUBLIC VERSION_INFO="1.0") -target_link_libraries(${PROJECT_NAME} PUBLIC GooseFEM pybind11::module) +target_include_directories(${PROJECT_NAME} PUBLIC ${NumPy_INCLUDE_DIRS}) +target_link_libraries(${PROJECT_NAME} PUBLIC xtensor) + +if(APPLE) + set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH "@loader_path/${CMAKE_INSTALL_LIBDIR}") +else() + set_target_properties(${PROJECT_NAME} PROPERTIES INSTALL_RPATH "$ORIGIN/${CMAKE_INSTALL_LIBDIR}") +endif() +install(TARGETS ${PROJECT_NAME} DESTINATION .) diff --git a/environment.yaml b/environment.yaml index 0d8018a..6c4af47 100644 --- a/environment.yaml +++ b/environment.yaml @@ -2,8 +2,9 @@ channels: - conda-forge dependencies: - cmake -- goosefem - python -- python-goosefem - pybind11 -- pybind11-abi +- xtensor +- xtensor-python +- ninja +- scikit-build diff --git a/example.py b/example.py index a3e8f80..e503f65 100644 --- a/example.py +++ b/example.py @@ -1,6 +1,7 @@ -import GooseFEM +import numpy as np import mymodule -a = mymodule.Myclass(3) -v = a.vector() -print(v) +A = np.random.random((10, 5)) +i = mymodule.myfunc(A) +j = np.unravel_index(np.argmin(A), A.shape) +assert i == list(j) diff --git a/main.cpp b/main.cpp index dbafe35..b72b097 100644 --- a/main.cpp +++ b/main.cpp @@ -1,34 +1,28 @@ +#include +#include +#include #include #include -#include + +#define FORCE_IMPORT_ARRAY +#include +#include namespace py = pybind11; -class Myclass +template +std::vector myfunc(const T& scale) { -public: - Myclass() = default; - - Myclass(size_t n) { - m_mesh = GooseFEM::Mesh::Quad4::Regular(n, n); - m_vector = GooseFEM::Vector(m_mesh.conn(), m_mesh.dofs()); - } - - const GooseFEM::Vector& vector() const - { - return m_vector; - } - -private: - GooseFEM::Mesh::Quad4::Regular m_mesh; - GooseFEM::Vector m_vector; -}; + auto index = xt::unravel_index(xt::argmin(xt::abs(scale))(), scale.shape()); + size_t e = index[0]; + size_t q = index[1]; + return std::vector{e, q}; +} -PYBIND11_MODULE(mymodule, m) +PYBIND11_MODULE(_mymodule, m) { m.doc() = "Foo"; - py::class_ cls(m, "Myclass"); - cls.def(py::init(), "Myclass", py::arg("n")); - cls.def("vector", &Myclass::vector, "vector"); + xt::import_numpy(); + m.def("myfunc", &myfunc>, "myfunc"); } diff --git a/python/mymodule/__init__.py b/python/mymodule/__init__.py new file mode 100644 index 0000000..131faa4 --- /dev/null +++ b/python/mymodule/__init__.py @@ -0,0 +1 @@ +from ._mymodule import * diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..55ddcc0 --- /dev/null +++ b/setup.py @@ -0,0 +1,12 @@ +from skbuild import setup + +project_name = "mymodule" + +setup( + name=project_name, + version="0.0", + packages=[f"{project_name}"], + package_dir={"": "python"}, + cmake_install_dir=f"python/{project_name}", + cmake_minimum_required_version="3.13...3.21", +)