polybench 0.2.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {polybench-0.2.0 → polybench-0.3.0}/LICENSE +1 -1
- polybench-0.3.0/PKG-INFO +210 -0
- {polybench-0.2.0 → polybench-0.3.0}/README.md +59 -22
- {polybench-0.2.0 → polybench-0.3.0}/polybench/main.py +69 -12
- {polybench-0.2.0 → polybench-0.3.0}/polybench/plot.py +1 -1
- {polybench-0.2.0 → polybench-0.3.0}/polybench/poly.py +21 -6
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solver.py +16 -4
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/__init__.py +3 -1
- polybench-0.3.0/polybench/solvers/flint/CMakeLists.txt +27 -0
- polybench-0.3.0/polybench/solvers/flint/cmake/init-vcpkg.cmake +32 -0
- polybench-0.3.0/polybench/solvers/flint/main.c +267 -0
- polybench-0.3.0/polybench/solvers/flint/vcpkg.json +12 -0
- polybench-0.3.0/polybench/solvers/flint/version.h.in +6 -0
- polybench-0.3.0/polybench/solvers/flint.py +61 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/form.py +3 -3
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/reform/Cargo.toml +1 -1
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/reform.py +1 -1
- polybench-0.3.0/polybench/solvers/symbolica/Cargo.lock +629 -0
- polybench-0.3.0/polybench/solvers/symbolica/Cargo.toml +8 -0
- polybench-0.3.0/polybench/solvers/symbolica/src/main.rs +104 -0
- polybench-0.3.0/polybench/solvers/symbolica.py +53 -0
- {polybench-0.2.0 → polybench-0.3.0}/pyproject.toml +36 -17
- polybench-0.2.0/PKG-INFO +0 -165
- polybench-0.2.0/setup.py +0 -59
- {polybench-0.2.0 → polybench-0.3.0}/polybench/__init__.py +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/__main__.py +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/prob.py +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/py.typed +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/fer.py +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/mma.py +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/reform/Cargo.lock +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/reform/src/main.rs +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/rings/build.gradle +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/rings/config/greclipse.properties +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/rings/gradle/wrapper/gradle-wrapper.jar +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/rings/gradle/wrapper/gradle-wrapper.properties +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/rings/gradlew +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/rings/gradlew.bat +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/rings/src/main/java/com/github/tueda/polybench/rings/App.java +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/rings.py +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/solvers/singular.py +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/util.py +0 -0
- {polybench-0.2.0 → polybench-0.3.0}/polybench/version.py +0 -0
polybench-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: polybench
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: Multivariate polynomial arithmetic benchmark tests.
|
|
5
|
+
Home-page: https://github.com/tueda/polybench
|
|
6
|
+
License: MIT
|
|
7
|
+
Keywords: benchmark,mathematics,multivariate-polynomials
|
|
8
|
+
Author: Takahiro Ueda
|
|
9
|
+
Author-email: t.ueda.od@juntendo.ac.jp
|
|
10
|
+
Requires-Python: >=3.6.1,<4.0.0
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Environment :: Console
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.7
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.8
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
23
|
+
Classifier: Topic :: System :: Benchmark
|
|
24
|
+
Requires-Dist: colorama (>=0.4.5,<0.5.0)
|
|
25
|
+
Requires-Dist: colorlog (>=6.8.2,<7.0.0)
|
|
26
|
+
Requires-Dist: importlib-metadata (>=4.8.3,<5.0.0)
|
|
27
|
+
Requires-Dist: importlib-resources (>=5.4.0,<6.0.0)
|
|
28
|
+
Requires-Dist: kiwisolver (>=1.3.1,<1.4.0) ; python_full_version >= "3.6.1" and python_full_version < "3.7.0"
|
|
29
|
+
Requires-Dist: kiwisolver (>=1.4.5,<2.0.0) ; python_version >= "3.7" and python_version < "3.13"
|
|
30
|
+
Requires-Dist: matplotlib (>=3.3.4,<3.4.0) ; python_full_version >= "3.6.1" and python_full_version < "3.7.0"
|
|
31
|
+
Requires-Dist: matplotlib (>=3.5.3,<3.6.0) ; python_version >= "3.7" and python_version < "3.11"
|
|
32
|
+
Requires-Dist: matplotlib (>=3.9.0,<4.0.0) ; python_version >= "3.11" and python_version < "3.13"
|
|
33
|
+
Requires-Dist: numpy (>=1.19.5,<1.20.0) ; python_full_version >= "3.6.1" and python_full_version < "3.7.0"
|
|
34
|
+
Requires-Dist: numpy (>=1.21.6,<1.22.0) ; python_version >= "3.7" and python_version < "3.11"
|
|
35
|
+
Requires-Dist: numpy (>=2.0.0,<3.0.0) ; python_version >= "3.11" and python_version < "3.13"
|
|
36
|
+
Requires-Dist: pandas (>=1.1.5,<1.2.0) ; python_full_version >= "3.6.1" and python_full_version < "3.7.1"
|
|
37
|
+
Requires-Dist: pandas (>=1.3.5,<1.4.0) ; python_full_version >= "3.7.1" and python_version < "3.11"
|
|
38
|
+
Requires-Dist: pandas (>=2.2.2,<3.0.0) ; python_version >= "3.11" and python_version < "3.13"
|
|
39
|
+
Requires-Dist: pretty-errors (>=1.2.25,<2.0.0)
|
|
40
|
+
Requires-Dist: psutil (>=6.0.0,<7.0.0)
|
|
41
|
+
Requires-Dist: py-cpuinfo (>=9.0.0,<10.0.0)
|
|
42
|
+
Requires-Dist: symengine (>=0.10.0,<0.11.0) ; python_version >= "3.7" and python_version < "3.8"
|
|
43
|
+
Requires-Dist: symengine (>=0.11.0,<0.12.0) ; python_version >= "3.8" and python_version < "3.13"
|
|
44
|
+
Requires-Dist: symengine (>=0.8.1,<0.9.0) ; python_full_version >= "3.6.1" and python_full_version < "3.7.0"
|
|
45
|
+
Requires-Dist: toml (>=0.10.2,<0.11.0)
|
|
46
|
+
Requires-Dist: typing-extensions (>=4.1.1,<5.0.0)
|
|
47
|
+
Project-URL: Repository, https://github.com/tueda/polybench
|
|
48
|
+
Description-Content-Type: text/markdown
|
|
49
|
+
|
|
50
|
+
polybench
|
|
51
|
+
=========
|
|
52
|
+
|
|
53
|
+
[](https://github.com/tueda/polybench/actions?query=branch:master)
|
|
54
|
+
[](https://pypi.org/project/polybench/)
|
|
55
|
+
|
|
56
|
+
Multivariate polynomial arithmetic benchmark tests.
|
|
57
|
+
|
|
58
|
+
Many scientific and engineering applications utilise multivariate polynomial
|
|
59
|
+
arithmetic in their algorithms and solutions. Here we provide a set of
|
|
60
|
+
benchmark tests for often-used operations in multivariate polynomial
|
|
61
|
+
arithmetic:
|
|
62
|
+
|
|
63
|
+
- Greatest common divisor
|
|
64
|
+
- Factorisation
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
Requirements
|
|
68
|
+
------------
|
|
69
|
+
|
|
70
|
+
- [Python](https://www.python.org/) >= 3.6.1
|
|
71
|
+
|
|
72
|
+
You also need at least one or more tools to be benchmarked.
|
|
73
|
+
They are (in alphabetical order):
|
|
74
|
+
|
|
75
|
+
- [Fermat](https://home.bway.net/lewis/)
|
|
76
|
+
- [FLINT](https://flintlib.org/): automatically downloaded via [vcpkg](https://vcpkg.io/)
|
|
77
|
+
(requires [CMake](https://cmake.org/) >= 3.15, a C compiler and the Make utility).
|
|
78
|
+
- [FORM](https://www.nikhef.nl/~form/):
|
|
79
|
+
if not available in the system, then
|
|
80
|
+
a [release binary](https://github.com/vermaseren/form/releases)
|
|
81
|
+
will be automatically downloaded.
|
|
82
|
+
- [Mathematica](https://www.wolfram.com/mathematica/):
|
|
83
|
+
indeed, [Free Wolfram Engine for Developers](https://www.wolfram.com/engine/) is sufficient to run.
|
|
84
|
+
- [reFORM](https://reform.readthedocs.io/en/latest/):
|
|
85
|
+
automatically downloaded
|
|
86
|
+
(requires [Rust](https://www.rust-lang.org/) >= 1.36).
|
|
87
|
+
- [Rings](https://rings.readthedocs.io/en/latest/):
|
|
88
|
+
automatically downloaded
|
|
89
|
+
(requires [JDK](https://www.oracle.com/technetwork/java/) >= 8).
|
|
90
|
+
- [Singular](https://www.singular.uni-kl.de/)
|
|
91
|
+
- [Symbolica](https://symbolica.io/):
|
|
92
|
+
automatically downloaded
|
|
93
|
+
(requires [Rust](https://www.rust-lang.org/) >= 1.73),
|
|
94
|
+
running in [restricted mode](https://symbolica.io/docs/get_started.html#license).
|
|
95
|
+
|
|
96
|
+
|
|
97
|
+
Getting started
|
|
98
|
+
---------------
|
|
99
|
+
|
|
100
|
+
Clone this repository and try to run the `run.sh` script:
|
|
101
|
+
|
|
102
|
+
```sh
|
|
103
|
+
git clone https://github.com/tueda/polybench.git
|
|
104
|
+
cd polybench
|
|
105
|
+
./run.sh --all
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
When starting the script for the first time, it automatically sets up
|
|
109
|
+
a virtual environment for required Python packages so that it will not dirty
|
|
110
|
+
your environment. Some of the tools are provided as libraries registered in
|
|
111
|
+
public package registries, so the first run takes some time to download,
|
|
112
|
+
compile and link them with test binaries. After testing, a CSV file and
|
|
113
|
+
comparison plots will be generated.
|
|
114
|
+
|
|
115
|
+
For practical benchmarking, configuration parameters should be set
|
|
116
|
+
adequately. See the help message shown by
|
|
117
|
+
|
|
118
|
+
```sh
|
|
119
|
+
./run.sh --help
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
You can also use [pip](https://pip.pypa.io/en/stable/),
|
|
123
|
+
[pipx](https://pipxproject.github.io/pipx/),
|
|
124
|
+
[Poetry](https://python-poetry.org/)
|
|
125
|
+
or [Docker](https://www.docker.com/) with this repository.
|
|
126
|
+
Installation with `pip(x) install` or `poetry install` makes a command
|
|
127
|
+
`polybench` available, which acts as the `run.sh` script described above.
|
|
128
|
+
```sh
|
|
129
|
+
pip install polybench
|
|
130
|
+
polybench --all
|
|
131
|
+
python -m polybench --all # alternative way to launch
|
|
132
|
+
```
|
|
133
|
+
```sh
|
|
134
|
+
pipx install polybench
|
|
135
|
+
polybench --all
|
|
136
|
+
```
|
|
137
|
+
```sh
|
|
138
|
+
git clone https://github.com/tueda/polybench.git
|
|
139
|
+
cd polybench
|
|
140
|
+
poetry install
|
|
141
|
+
poetry run polybench --all
|
|
142
|
+
```
|
|
143
|
+
```sh
|
|
144
|
+
docker build -t polybench:latest https://github.com/tueda/polybench.git
|
|
145
|
+
docker run -it --rm polybench:latest
|
|
146
|
+
./run.sh --all
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
Example
|
|
151
|
+
-------
|
|
152
|
+
|
|
153
|
+
| | |
|
|
154
|
+
|----------------|------------------------------------------------------------------------------|
|
|
155
|
+
| platform | Linux-5.15.0-84-generic-x86_64-with-glibc2.29 |
|
|
156
|
+
| python_version | 3.8.10.final.0 (64 bit) |
|
|
157
|
+
| cpu_brand | 12th Gen Intel(R) Core(TM) i9-12900 |
|
|
158
|
+
| cpu_count | 16 (logical: 24) |
|
|
159
|
+
| total_memory | 62.6GB |
|
|
160
|
+
| FLINT | flint 2.9.0, cc (GNU) 10.5.0 |
|
|
161
|
+
| FORM | FORM 4.3.1 (Apr 11 2023, v4.3.1) 64-bits |
|
|
162
|
+
| Mathematica | 14.1.0 for Linux x86 (64-bit) (July 22, 2024) |
|
|
163
|
+
| reFORM | 0.1.0-fix-serialize, rustc 1.81.0 (eeb90cda1 2024-09-04) |
|
|
164
|
+
| Rings | 2.5.8, JVM: 11.0.20.1 (Ubuntu 11.0.20.1+1-post-Ubuntu-0ubuntu120.04) |
|
|
165
|
+
| Singular | Singular for x86_64-Linux version 4.4.0 (44002, 64 bit) May 29 2024 14:14:10 |
|
|
166
|
+
| Symbolica | 0.11.0, rustc 1.81.0 (eeb90cda1 2024-09-04) |
|
|
167
|
+
|
|
168
|
+

|
|
169
|
+
|
|
170
|
+

|
|
171
|
+
|
|
172
|
+
Additional benchmark results are available [here](https://github.com/tueda/polybench-result/tree/main).
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
Development
|
|
176
|
+
-----------
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
# Initialisation
|
|
180
|
+
poetry install
|
|
181
|
+
pre-commit install
|
|
182
|
+
|
|
183
|
+
# Linting and testing
|
|
184
|
+
pre-commit run --all-files
|
|
185
|
+
poetry run pytest
|
|
186
|
+
|
|
187
|
+
# Linting and testing for Cargo subproject
|
|
188
|
+
cd path/to/project
|
|
189
|
+
cargo fmt
|
|
190
|
+
cargo clippy
|
|
191
|
+
cargo test
|
|
192
|
+
|
|
193
|
+
# Linting and testing for Gradle subproject
|
|
194
|
+
cd path/to/project
|
|
195
|
+
./gradlew spotlessApply
|
|
196
|
+
./gradlew check
|
|
197
|
+
|
|
198
|
+
# Test run
|
|
199
|
+
./run.sh <options> # for example, --all
|
|
200
|
+
|
|
201
|
+
# Release a new version
|
|
202
|
+
./scripts/make-release.sh <new_version> # for example, 0.3.0rc1
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
|
|
206
|
+
License
|
|
207
|
+
-------
|
|
208
|
+
|
|
209
|
+
[MIT](https://github.com/tueda/polybench/blob/master/LICENSE)
|
|
210
|
+
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
polybench
|
|
2
2
|
=========
|
|
3
3
|
|
|
4
|
-
[](https://github.com/tueda/polybench/actions?query=branch:master)
|
|
5
5
|
[](https://pypi.org/project/polybench/)
|
|
6
|
-
[](https://lgtm.com/projects/g/tueda/polybench/context:python)
|
|
7
6
|
|
|
8
7
|
Multivariate polynomial arithmetic benchmark tests.
|
|
9
8
|
|
|
@@ -25,6 +24,8 @@ You also need at least one or more tools to be benchmarked.
|
|
|
25
24
|
They are (in alphabetical order):
|
|
26
25
|
|
|
27
26
|
- [Fermat](https://home.bway.net/lewis/)
|
|
27
|
+
- [FLINT](https://flintlib.org/): automatically downloaded via [vcpkg](https://vcpkg.io/)
|
|
28
|
+
(requires [CMake](https://cmake.org/) >= 3.15, a C compiler and the Make utility).
|
|
28
29
|
- [FORM](https://www.nikhef.nl/~form/):
|
|
29
30
|
if not available in the system, then
|
|
30
31
|
a [release binary](https://github.com/vermaseren/form/releases)
|
|
@@ -34,10 +35,14 @@ They are (in alphabetical order):
|
|
|
34
35
|
- [reFORM](https://reform.readthedocs.io/en/latest/):
|
|
35
36
|
automatically downloaded
|
|
36
37
|
(requires [Rust](https://www.rust-lang.org/) >= 1.36).
|
|
37
|
-
- [Rings](https://
|
|
38
|
+
- [Rings](https://rings.readthedocs.io/en/latest/):
|
|
38
39
|
automatically downloaded
|
|
39
40
|
(requires [JDK](https://www.oracle.com/technetwork/java/) >= 8).
|
|
40
41
|
- [Singular](https://www.singular.uni-kl.de/)
|
|
42
|
+
- [Symbolica](https://symbolica.io/):
|
|
43
|
+
automatically downloaded
|
|
44
|
+
(requires [Rust](https://www.rust-lang.org/) >= 1.73),
|
|
45
|
+
running in [restricted mode](https://symbolica.io/docs/get_started.html#license).
|
|
41
46
|
|
|
42
47
|
|
|
43
48
|
Getting started
|
|
@@ -96,25 +101,57 @@ docker run -it --rm polybench:latest
|
|
|
96
101
|
Example
|
|
97
102
|
-------
|
|
98
103
|
|
|
99
|
-
| |
|
|
100
|
-
|
|
101
|
-
| platform | Linux-
|
|
102
|
-
| python_version | 3.
|
|
103
|
-
| cpu_brand | Intel(R)
|
|
104
|
-
| cpu_count |
|
|
105
|
-
| total_memory |
|
|
106
|
-
|
|
|
107
|
-
|
|
|
108
|
-
|
|
|
109
|
-
|
|
|
110
|
-
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
 |
|
|
108
|
+
| cpu_brand | 12th Gen Intel(R) Core(TM) i9-12900 |
|
|
109
|
+
| cpu_count | 16 (logical: 24) |
|
|
110
|
+
| total_memory | 62.6GB |
|
|
111
|
+
| FLINT | flint 2.9.0, cc (GNU) 10.5.0 |
|
|
112
|
+
| FORM | FORM 4.3.1 (Apr 11 2023, v4.3.1) 64-bits |
|
|
113
|
+
| Mathematica | 14.1.0 for Linux x86 (64-bit) (July 22, 2024) |
|
|
114
|
+
| reFORM | 0.1.0-fix-serialize, rustc 1.81.0 (eeb90cda1 2024-09-04) |
|
|
115
|
+
| Rings | 2.5.8, JVM: 11.0.20.1 (Ubuntu 11.0.20.1+1-post-Ubuntu-0ubuntu120.04) |
|
|
116
|
+
| Singular | Singular for x86_64-Linux version 4.4.0 (44002, 64 bit) May 29 2024 14:14:10 |
|
|
117
|
+
| Symbolica | 0.11.0, rustc 1.81.0 (eeb90cda1 2024-09-04) |
|
|
118
|
+
|
|
119
|
+

|
|
120
|
+
|
|
121
|
+

|
|
122
|
+
|
|
123
|
+
Additional benchmark results are available [here](https://github.com/tueda/polybench-result/tree/main).
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
Development
|
|
127
|
+
-----------
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
# Initialisation
|
|
131
|
+
poetry install
|
|
132
|
+
pre-commit install
|
|
133
|
+
|
|
134
|
+
# Linting and testing
|
|
135
|
+
pre-commit run --all-files
|
|
136
|
+
poetry run pytest
|
|
137
|
+
|
|
138
|
+
# Linting and testing for Cargo subproject
|
|
139
|
+
cd path/to/project
|
|
140
|
+
cargo fmt
|
|
141
|
+
cargo clippy
|
|
142
|
+
cargo test
|
|
143
|
+
|
|
144
|
+
# Linting and testing for Gradle subproject
|
|
145
|
+
cd path/to/project
|
|
146
|
+
./gradlew spotlessApply
|
|
147
|
+
./gradlew check
|
|
148
|
+
|
|
149
|
+
# Test run
|
|
150
|
+
./run.sh <options> # for example, --all
|
|
151
|
+
|
|
152
|
+
# Release a new version
|
|
153
|
+
./scripts/make-release.sh <new_version> # for example, 0.3.0rc1
|
|
154
|
+
```
|
|
118
155
|
|
|
119
156
|
|
|
120
157
|
License
|
|
@@ -12,7 +12,7 @@ import sys
|
|
|
12
12
|
import time
|
|
13
13
|
from collections import OrderedDict
|
|
14
14
|
from pathlib import Path
|
|
15
|
-
from typing import Any, Callable, List, Optional, Sequence, Set,
|
|
15
|
+
from typing import Any, Callable, List, NamedTuple, Optional, Sequence, Set, cast
|
|
16
16
|
|
|
17
17
|
import colorama
|
|
18
18
|
import cpuinfo
|
|
@@ -110,6 +110,14 @@ def prepare_solvers(
|
|
|
110
110
|
return tuple(available_solvers)
|
|
111
111
|
|
|
112
112
|
|
|
113
|
+
class SolverResult(NamedTuple):
|
|
114
|
+
"""Result from a solver."""
|
|
115
|
+
|
|
116
|
+
name: str
|
|
117
|
+
res: Sequence[Result]
|
|
118
|
+
output_dir: Path
|
|
119
|
+
|
|
120
|
+
|
|
113
121
|
def run_solvers(
|
|
114
122
|
solvers: Sequence[Solver],
|
|
115
123
|
problems: ProblemSet,
|
|
@@ -140,14 +148,15 @@ def run_solvers(
|
|
|
140
148
|
if len(times) == 1:
|
|
141
149
|
return f" ({times[0]:.3f} sec)"
|
|
142
150
|
mean = statistics.mean(times)
|
|
143
|
-
stdev = statistics.stdev(times)
|
|
151
|
+
stdev = statistics.stdev(times, mean)
|
|
144
152
|
max_t, max_i = max((t, i) for i, t in enumerate(times))
|
|
145
153
|
return (
|
|
146
|
-
f" (
|
|
147
|
-
f"
|
|
154
|
+
f" (mean: {mean:.3f} sec,"
|
|
155
|
+
f" SD: {stdev:.3f} sec,"
|
|
156
|
+
f" slowest: {max_t:.3f} sec on Prob. {max_i + 1 + n_warmups})"
|
|
148
157
|
)
|
|
149
158
|
|
|
150
|
-
results: List[
|
|
159
|
+
results: List[SolverResult] = []
|
|
151
160
|
|
|
152
161
|
for s in solvers:
|
|
153
162
|
s._problem_file = problem_file # Yes, this is ugly.
|
|
@@ -155,40 +164,87 @@ def run_solvers(
|
|
|
155
164
|
r = s.solve(problems)
|
|
156
165
|
t2 = time.time()
|
|
157
166
|
if r and len(r) == len(problems):
|
|
158
|
-
results.append((s.name, r, s._output_dir))
|
|
167
|
+
results.append(SolverResult(s.name, r, s._output_dir))
|
|
159
168
|
s.logger.info(
|
|
160
169
|
f"{t2 - t1:.3f} sec{get_timing_information(r, problems.n_warmups)}"
|
|
161
170
|
)
|
|
162
171
|
else:
|
|
163
172
|
s.logger.error("failed")
|
|
164
173
|
|
|
165
|
-
# Check the consistency.
|
|
174
|
+
# Check the consistency of the obtained results.
|
|
166
175
|
|
|
167
176
|
check_logger = logger.getChild("Check")
|
|
168
177
|
|
|
169
178
|
wrong: Set[str] = set()
|
|
170
179
|
|
|
180
|
+
def count_factors(pp: Sequence[Polynomial]) -> int:
|
|
181
|
+
n = 0
|
|
182
|
+
m = 0
|
|
183
|
+
for p in pp:
|
|
184
|
+
n_terms = len(p)
|
|
185
|
+
if n_terms == 0:
|
|
186
|
+
return 0
|
|
187
|
+
elif n_terms == 1:
|
|
188
|
+
if not p.is_unit:
|
|
189
|
+
m += 1
|
|
190
|
+
else:
|
|
191
|
+
n += 1
|
|
192
|
+
if m >= 1:
|
|
193
|
+
n += 1
|
|
194
|
+
return n
|
|
195
|
+
|
|
171
196
|
if problems.problem_type == "gcd":
|
|
197
|
+
# The GCD must be given as a single polynomial.
|
|
198
|
+
for name, res, _ in results:
|
|
199
|
+
for i, ri in enumerate(res):
|
|
200
|
+
if len(ri.answer) != 1:
|
|
201
|
+
check_logger.error(f"{name}:{i + 1}: wrong answer")
|
|
202
|
+
wrong.add(name)
|
|
203
|
+
# The GCD must be the same up to a multiplicative unit.
|
|
172
204
|
if len(results) >= 2:
|
|
173
205
|
for i in range(len(problems)):
|
|
174
|
-
|
|
206
|
+
pp0 = results[0].res[i].answer
|
|
207
|
+
if len(pp0) != 1:
|
|
208
|
+
continue
|
|
209
|
+
p0 = pp0[0]
|
|
175
210
|
for j in range(1, len(results)):
|
|
176
|
-
|
|
211
|
+
ppj = results[j].res[i].answer
|
|
212
|
+
if len(ppj) != 1:
|
|
213
|
+
continue
|
|
214
|
+
pj = ppj[0]
|
|
177
215
|
if not p0.equals_without_unit(pj):
|
|
178
|
-
name0 = results[0]
|
|
179
|
-
namej = results[j]
|
|
216
|
+
name0 = results[0].name
|
|
217
|
+
namej = results[j].name
|
|
180
218
|
check_logger.error(
|
|
181
219
|
f"{name0}:{namej}:{i + 1}: inconsistent answers"
|
|
182
220
|
)
|
|
183
221
|
wrong.add(name0)
|
|
184
222
|
wrong.add(namej)
|
|
185
223
|
elif problems.problem_type == "factor":
|
|
224
|
+
# The product of the factorized polynomials must equal the original polynomial.
|
|
186
225
|
for name, res, _ in results:
|
|
187
226
|
for i, ri in enumerate(res):
|
|
188
227
|
product = functools.reduce(operator.mul, ri.answer, Polynomial(1))
|
|
189
228
|
if problems[i].p != product:
|
|
190
229
|
check_logger.error(f"{name}:{i + 1}: wrong answer")
|
|
191
230
|
wrong.add(name)
|
|
231
|
+
# The number of factorized polynomials must match,
|
|
232
|
+
# excluding any single-term polynomials.
|
|
233
|
+
if len(results) >= 2:
|
|
234
|
+
for i in range(len(problems)):
|
|
235
|
+
pp0 = results[0].res[i].answer
|
|
236
|
+
n0 = count_factors(pp0)
|
|
237
|
+
for j in range(1, len(results)):
|
|
238
|
+
ppj = results[j].res[i].answer
|
|
239
|
+
nj = count_factors(ppj)
|
|
240
|
+
if n0 != nj:
|
|
241
|
+
name0 = results[0].name
|
|
242
|
+
namej = results[j].name
|
|
243
|
+
check_logger.error(
|
|
244
|
+
f"{name0}:{namej}:{i + 1}: inconsistent answers"
|
|
245
|
+
)
|
|
246
|
+
wrong.add(name0)
|
|
247
|
+
wrong.add(namej)
|
|
192
248
|
|
|
193
249
|
# Remove the solver's output directory only if succeeded.
|
|
194
250
|
|
|
@@ -316,7 +372,7 @@ def main(
|
|
|
316
372
|
)
|
|
317
373
|
parser.add_argument(
|
|
318
374
|
"--max-coeff",
|
|
319
|
-
default=2
|
|
375
|
+
default=2**14,
|
|
320
376
|
type=int,
|
|
321
377
|
help="set the maximum coefficient (default: 2^14)",
|
|
322
378
|
metavar="N",
|
|
@@ -502,6 +558,7 @@ def main(
|
|
|
502
558
|
|
|
503
559
|
if debug:
|
|
504
560
|
logger.setLevel(logging.DEBUG)
|
|
561
|
+
Solver.debug = True
|
|
505
562
|
else:
|
|
506
563
|
logger.setLevel(logging.INFO)
|
|
507
564
|
|
|
@@ -13,7 +13,7 @@ class Polynomial:
|
|
|
13
13
|
def __init__(self, expr: Union[str, int, "Polynomial"] = 0) -> None:
|
|
14
14
|
"""Construct a polynomial."""
|
|
15
15
|
if isinstance(expr, str):
|
|
16
|
-
p = symengine.sympify(expr
|
|
16
|
+
p = symengine.sympify(expr)
|
|
17
17
|
self._raw = symengine.expand(p)
|
|
18
18
|
elif isinstance(expr, int):
|
|
19
19
|
self._raw = symengine.sympify(expr)
|
|
@@ -28,7 +28,17 @@ class Polynomial:
|
|
|
28
28
|
|
|
29
29
|
def __bool__(self) -> bool:
|
|
30
30
|
"""Return ``bool(self)``."""
|
|
31
|
-
return self._raw
|
|
31
|
+
return not self._raw.is_zero
|
|
32
|
+
|
|
33
|
+
def __len__(self) -> int:
|
|
34
|
+
"""Return the number of terms in the polynomial."""
|
|
35
|
+
raw = self._raw
|
|
36
|
+
if raw.is_Add:
|
|
37
|
+
return len(raw.args)
|
|
38
|
+
elif raw.is_zero:
|
|
39
|
+
return 0
|
|
40
|
+
else:
|
|
41
|
+
return 1
|
|
32
42
|
|
|
33
43
|
def __eq__(self, other: object) -> bool:
|
|
34
44
|
"""Return ``self == other``."""
|
|
@@ -46,26 +56,31 @@ class Polynomial:
|
|
|
46
56
|
"""Return ``- self``."""
|
|
47
57
|
result = super().__new__(Polynomial)
|
|
48
58
|
result._raw = symengine.expand(-self._raw)
|
|
49
|
-
return result
|
|
59
|
+
return result
|
|
50
60
|
|
|
51
61
|
def __add__(self, other: "Polynomial") -> "Polynomial":
|
|
52
62
|
"""Return ``self + other``."""
|
|
53
63
|
result = super().__new__(Polynomial)
|
|
54
64
|
result._raw = symengine.expand(self._raw + other._raw)
|
|
55
|
-
return result
|
|
65
|
+
return result
|
|
56
66
|
|
|
57
67
|
def __sub__(self, other: "Polynomial") -> "Polynomial":
|
|
58
68
|
"""Return ``self - other``."""
|
|
59
69
|
result = super().__new__(Polynomial)
|
|
60
70
|
result._raw = symengine.expand(self._raw - other._raw)
|
|
61
|
-
return result
|
|
71
|
+
return result
|
|
62
72
|
|
|
63
73
|
def __mul__(self, other: "Polynomial") -> "Polynomial":
|
|
64
74
|
"""Return ``self * other``."""
|
|
65
75
|
result = super().__new__(Polynomial)
|
|
66
76
|
result._raw = symengine.expand(self._raw * other._raw)
|
|
67
|
-
return result
|
|
77
|
+
return result
|
|
68
78
|
|
|
69
79
|
def equals_without_unit(self, other: "Polynomial") -> bool:
|
|
70
80
|
"""Return `True` if ``self == other`` up to a unit."""
|
|
71
81
|
return self == other or self == -other
|
|
82
|
+
|
|
83
|
+
@property
|
|
84
|
+
def is_unit(self) -> bool:
|
|
85
|
+
"""True if the polynomial is 1 or -1."""
|
|
86
|
+
return len(self) == 1 and (self == 1 or self == -1)
|
|
@@ -30,6 +30,8 @@ class Result(NamedTuple):
|
|
|
30
30
|
class Solver:
|
|
31
31
|
"""Abstract solver."""
|
|
32
32
|
|
|
33
|
+
debug = False
|
|
34
|
+
|
|
33
35
|
# Things that must be overridden in subclasses.
|
|
34
36
|
|
|
35
37
|
_name = "None" # Must be a unique name (without spaces).
|
|
@@ -44,8 +46,8 @@ class Solver:
|
|
|
44
46
|
|
|
45
47
|
def _solve(self, problems: ProblemSet) -> Optional[Sequence[Result]]:
|
|
46
48
|
# Solve the given problems and return the results. If the underlying executable
|
|
47
|
-
# has a programming
|
|
48
|
-
# to generate a program in the
|
|
49
|
+
# has a programming language that is versatile enough, then the easiest way is
|
|
50
|
+
# to generate a program in the language that creates a CSV file for the results
|
|
49
51
|
# and use `parse_csv_log` (example: `MathematicaSolver`). When this method is
|
|
50
52
|
# called, the current working directory is set to `output_dir` and
|
|
51
53
|
# `problem_file` is accessible. One can also use files in `build_dir`.
|
|
@@ -170,11 +172,16 @@ class Solver:
|
|
|
170
172
|
new_args = [str(args)]
|
|
171
173
|
|
|
172
174
|
try:
|
|
175
|
+
if self.debug:
|
|
176
|
+
redirect = None
|
|
177
|
+
else:
|
|
178
|
+
redirect = subprocess.DEVNULL
|
|
179
|
+
|
|
173
180
|
p = subprocess.run( # noqa: S603
|
|
174
181
|
new_args,
|
|
175
182
|
input=input,
|
|
176
|
-
stdout=subprocess.PIPE if capture_output else
|
|
177
|
-
stderr=
|
|
183
|
+
stdout=subprocess.PIPE if capture_output else redirect,
|
|
184
|
+
stderr=redirect,
|
|
178
185
|
universal_newlines=True,
|
|
179
186
|
timeout=timeout,
|
|
180
187
|
)
|
|
@@ -297,6 +304,11 @@ class Solver:
|
|
|
297
304
|
dest_dir.mkdir(parents=True, exist_ok=True)
|
|
298
305
|
shutil.copy2(p, q)
|
|
299
306
|
|
|
307
|
+
@property
|
|
308
|
+
def cmake_command(self) -> Sequence[str]:
|
|
309
|
+
"""Return the CMake command."""
|
|
310
|
+
return [shutil.which("cmake") or "cmake"]
|
|
311
|
+
|
|
300
312
|
@property
|
|
301
313
|
def gradlew_command(self) -> Sequence[str]:
|
|
302
314
|
"""Return the gradlew command."""
|
|
@@ -6,5 +6,7 @@ from pkgutil import iter_modules
|
|
|
6
6
|
|
|
7
7
|
# Load all modules.
|
|
8
8
|
|
|
9
|
-
for
|
|
9
|
+
for _, module_name, _ in iter_modules( # type: ignore[assignment]
|
|
10
|
+
[str(Path(__file__).resolve().parent)]
|
|
11
|
+
):
|
|
10
12
|
import_module(f"{__name__}.{module_name}")
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
cmake_minimum_required(VERSION 3.15)
|
|
2
|
+
include(cmake/init-vcpkg.cmake)
|
|
3
|
+
project(
|
|
4
|
+
polybench-flint
|
|
5
|
+
VERSION 0.1.0
|
|
6
|
+
LANGUAGES C)
|
|
7
|
+
|
|
8
|
+
get_filename_component(COMPILER_NAME ${CMAKE_C_COMPILER} NAME_WE)
|
|
9
|
+
set(COMPILER_VERSION
|
|
10
|
+
"${COMPILER_NAME} (${CMAKE_C_COMPILER_ID}) ${CMAKE_C_COMPILER_VERSION}")
|
|
11
|
+
|
|
12
|
+
configure_file(${CMAKE_SOURCE_DIR}/version.h.in ${CMAKE_BINARY_DIR}/version.h
|
|
13
|
+
@ONLY)
|
|
14
|
+
|
|
15
|
+
find_package(PkgConfig REQUIRED)
|
|
16
|
+
pkg_check_modules(gmp REQUIRED IMPORTED_TARGET gmp)
|
|
17
|
+
pkg_check_modules(mpfr REQUIRED IMPORTED_TARGET mpfr)
|
|
18
|
+
|
|
19
|
+
find_path(FLINT_INCLUDE_DIR flint/flint.h)
|
|
20
|
+
find_library(FLINT_LIBRARY flint)
|
|
21
|
+
|
|
22
|
+
add_executable(polybench-flint main.c)
|
|
23
|
+
|
|
24
|
+
target_include_directories(polybench-flint PRIVATE ${FLINT_INCLUDE_DIR}
|
|
25
|
+
${CMAKE_BINARY_DIR})
|
|
26
|
+
target_link_libraries(polybench-flint PRIVATE m PkgConfig::gmp PkgConfig::mpfr
|
|
27
|
+
${FLINT_LIBRARY})
|