Skip to content

Commit 61ffe63

Browse files
author
Teseo Schneider
committed
package install itself and new unit tests
1 parent 68fcdba commit 61ffe63

File tree

10 files changed

+297
-156
lines changed

10 files changed

+297
-156
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
build/
12
bin/
23
bin_rel/
34
3rdparty/

setup.py

Lines changed: 71 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,86 @@
1-
import setuptools
1+
import os
2+
import re
3+
import sys
4+
# import sysconfig
5+
import platform
6+
import subprocess
7+
8+
from distutils.version import LooseVersion
9+
from setuptools import setup, Extension, find_packages
10+
from setuptools.command.build_ext import build_ext
11+
12+
13+
class CMakeExtension(Extension):
14+
def __init__(self, name, sourcedir=''):
15+
Extension.__init__(self, name, sources=[])
16+
self.sourcedir = os.path.abspath(sourcedir)
17+
18+
19+
class CMakeBuild(build_ext):
20+
def run(self):
21+
try:
22+
out = subprocess.check_output(['cmake', '--version'])
23+
except OSError:
24+
raise RuntimeError(
25+
"CMake must be installed to build the following extensions: , ".join(e.name for e in self.extensions))
26+
27+
# if platform.system() == "Windows":
28+
cmake_version = LooseVersion(re.search(r'version\s*([\d.]+)', out.decode()).group(1))
29+
if cmake_version < '3.1.0':
30+
raise RuntimeError("CMake >= 3.1.0 is required on Windows")
31+
32+
for ext in self.extensions:
33+
self.build_extension(ext)
34+
35+
36+
def build_extension(self, ext):
37+
extdir = os.path.join(os.path.abspath(os.path.dirname(self.get_ext_fullpath(ext.name))),"polyfempy")
38+
39+
cmake_args = ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' + extdir, '-DPYTHON_EXECUTABLE=' + sys.executable, '-DENABLE_PARDISO=OFF']
40+
41+
cfg = 'Debug' if self.debug else 'Release'
42+
build_args = ['--config', cfg]
43+
44+
if platform.system() == "Windows":
45+
cmake_args += ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(cfg.upper(), extdir)]
46+
if sys.maxsize > 2**32:
47+
cmake_args += ['-A', 'x64']
48+
build_args += ['--', '/m']
49+
else:
50+
cmake_args += ['-DCMAKE_BUILD_TYPE=' + cfg]
51+
build_args += ['--', '-j2']
52+
53+
env = os.environ.copy()
54+
env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format(env.get('CXXFLAGS', ''),self.distribution.get_version())
55+
56+
if not os.path.exists(self.build_temp):
57+
os.makedirs(self.build_temp)
58+
subprocess.check_call(['cmake', ext.sourcedir] + cmake_args, cwd=self.build_temp, env=env)
59+
60+
subprocess.check_call(['cmake', '--build', '.'] + build_args, cwd=self.build_temp)
61+
62+
print() # Add an empty line for cleaner output
63+
264

365
with open("README.md", "r") as fh:
466
long_description = fh.read()
567

6-
setuptools.setup(
68+
69+
setup(
770
name="polyfempy",
871
version="0.0.1",
972
author="Teseo Schneider",
10-
author_email="email@email.com",
73+
author_email="",
1174
description="Polyfem Python Bindings",
1275
long_description=long_description,
1376
long_description_content_type="text/markdown",
1477
url="https://polyfem.github.io/",
15-
packages=setuptools.find_packages(),
78+
ext_modules=[CMakeExtension('polyfempy')],
79+
cmdclass=dict(build_ext=CMakeBuild),
80+
packages=find_packages(),
1681
classifiers=[
1782
"Programming Language :: Python :: 3",
18-
"License :: OSI Approved :: MIT License",
19-
"Operating System :: OS Independent",
83+
"License :: OSI Approved :: MIT License"
2084
],
85+
test_suite="tests"
2186
)

src/binding.cpp

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,14 @@
22
#include <polyfem/AssemblerUtils.hpp>
33
#include <polyfem/Logger.hpp>
44

5+
#include <geogram/basic/command_line.h>
6+
#include <geogram/basic/command_line_args.h>
7+
8+
#ifdef USE_TBB
9+
#include <tbb/task_scheduler_init.h>
10+
#include <thread>
11+
#endif
12+
513
#include <pybind11/pybind11.h>
614
#include <pybind11/eigen.h>
715

@@ -10,6 +18,39 @@ namespace py = pybind11;
1018
class ScalarAssemblers { };
1119
class TensorAssemblers { };
1220

21+
22+
23+
namespace {
24+
void init_globals()
25+
{
26+
static bool initialized = false;
27+
28+
if(!initialized)
29+
{
30+
#ifndef WIN32
31+
setenv("GEO_NO_SIGNAL_HANDLER", "1", 1);
32+
#endif
33+
34+
GEO::initialize();
35+
36+
#ifdef USE_TBB
37+
const size_t MB = 1024*1024;
38+
const size_t stack_size = 64 * MB;
39+
unsigned int num_threads = std::max(1u, std::thread::hardware_concurrency());
40+
tbb::task_scheduler_init scheduler(num_threads, stack_size);
41+
#endif
42+
43+
// Import standard command line arguments, and custom ones
44+
GEO::CmdLine::import_arg_group("standard");
45+
GEO::CmdLine::import_arg_group("pre");
46+
GEO::CmdLine::import_arg_group("algo");
47+
48+
initialized = true;
49+
}
50+
}
51+
52+
}
53+
1354
PYBIND11_MODULE(polyfempy, m) {
1455
const auto &sa = py::class_<ScalarAssemblers>(m, "ScalarFormulations");
1556
for(auto &a : polyfem::AssemblerUtils::instance().scalar_assemblers())
@@ -26,37 +67,46 @@ PYBIND11_MODULE(polyfempy, m) {
2667
py::class_<polyfem::State>(m, "Solver")
2768
.def(py::init<>())
2869
.def("settings", [](polyfem::State &s, const std::string &json) {
70+
init_globals();
2971
s.init(json::parse(json));
3072
}, "load PDE and problem parameters from the settings")
3173

3274
.def("set_log_level", [](polyfem::State &s, int log_level) {
75+
init_globals();
3376
log_level = std::max(0, std::min(6, log_level));
3477
spdlog::set_level(static_cast<spdlog::level::level_enum>(log_level));
3578
}, "sets polyfem log level, valid value between 0 (all logs) and 6 (no logs)")
3679

3780
.def("load_mesh", [](polyfem::State &s) {
81+
init_globals();
3882
s.load_mesh();
3983
}, "Loads a mesh from the 'mesh' field of the json and 'bc_tag' if any bc tags")
4084
.def("load_mesh", [](polyfem::State &s, std::string &path) {
85+
init_globals();
4186
s.args["mesh"] = path;
4287
s.load_mesh();
4388
}, "Loads a mesh from the path and 'bc_tag' from the json if any bc tags")
4489
.def("load_mesh", [](polyfem::State &s, std::string &path, std::string &bc_tag) {
90+
init_globals();
4591
s.args["mesh"] = path;
4692
s.args["bc_tag"] = bc_tag;
4793
s.load_mesh();
4894
}, "Loads a mesh and bc_tags from path")
4995

5096
.def("set_rhs", [](polyfem::State &s, std::string &path) {
97+
init_globals();
5198
s.args["rhs_path"] = path;
5299
}, "Loads the rhs from a file")
53100
.def("set_rhs", [](polyfem::State &s, const Eigen::MatrixXd &rhs) {
101+
init_globals();
54102
s.rhs_in = rhs;
55103
}, "Sets the rhs")
56104

57105

58106

59107
.def("solve", [](polyfem::State &s) {
108+
init_globals();
109+
60110
s.compute_mesh_stats();
61111

62112
s.build_basis();

test/bending.py

Lines changed: 0 additions & 37 deletions
This file was deleted.

test/inflation.py

Lines changed: 0 additions & 72 deletions
This file was deleted.

test/torsion.py

Lines changed: 0 additions & 41 deletions
This file was deleted.

tests/__init__.py

Whitespace-only changes.

0 commit comments

Comments
 (0)