cotengrust 0.1.2__tar.gz → 0.1.4__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.
@@ -0,0 +1,18 @@
1
+ # To get started with Dependabot version updates, you'll need to specify which
2
+ # package ecosystems to update and where the package manifests are located.
3
+ # Please see the documentation for all configuration options:
4
+ # https://docs.github.com/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
5
+
6
+ version: 2
7
+ updates:
8
+ # Enable Dependabot for GitHub Actions
9
+ - package-ecosystem: "github-actions"
10
+ directory: "/" # Location of your workflows, typically the root folder
11
+ schedule:
12
+ interval: "daily" # Frequency of update checks (daily, weekly, or monthly)
13
+
14
+ # Enable Dependabot for Rust dependencies
15
+ - package-ecosystem: "cargo"
16
+ directory: "/" # Location of your Cargo.toml file, typically the root folder
17
+ schedule:
18
+ interval: "weekly" # Frequency of update checks (daily, weekly, or monthly)
@@ -0,0 +1,169 @@
1
+ # This file is autogenerated by maturin v1.7.1
2
+ # To update, run
3
+ #
4
+ # maturin generate-ci github
5
+ #
6
+ name: CI
7
+
8
+ on:
9
+ push:
10
+ branches:
11
+ - main
12
+ - master
13
+ tags:
14
+ - '*'
15
+ pull_request:
16
+ workflow_dispatch:
17
+
18
+ permissions:
19
+ contents: read
20
+
21
+ jobs:
22
+ linux:
23
+ runs-on: ${{ matrix.platform.runner }}
24
+ strategy:
25
+ matrix:
26
+ platform:
27
+ - runner: ubuntu-latest
28
+ target: x86_64
29
+ - runner: ubuntu-latest
30
+ target: x86
31
+ - runner: ubuntu-latest
32
+ target: aarch64
33
+ - runner: ubuntu-latest
34
+ target: armv7
35
+ - runner: ubuntu-latest
36
+ target: s390x
37
+ - runner: ubuntu-latest
38
+ target: ppc64le
39
+ steps:
40
+ - uses: actions/checkout@v4
41
+ - uses: actions/setup-python@v5
42
+ with:
43
+ python-version: 3.x
44
+ - name: Build wheels
45
+ uses: PyO3/maturin-action@v1
46
+ with:
47
+ target: ${{ matrix.platform.target }}
48
+ args: --release --out dist --find-interpreter
49
+ sccache: 'true'
50
+ manylinux: auto
51
+ - name: Upload wheels
52
+ uses: actions/upload-artifact@v4
53
+ with:
54
+ name: wheels-linux-${{ matrix.platform.target }}
55
+ path: dist
56
+
57
+ musllinux:
58
+ runs-on: ${{ matrix.platform.runner }}
59
+ strategy:
60
+ matrix:
61
+ platform:
62
+ - runner: ubuntu-latest
63
+ target: x86_64
64
+ - runner: ubuntu-latest
65
+ target: x86
66
+ - runner: ubuntu-latest
67
+ target: aarch64
68
+ - runner: ubuntu-latest
69
+ target: armv7
70
+ steps:
71
+ - uses: actions/checkout@v4
72
+ - uses: actions/setup-python@v5
73
+ with:
74
+ python-version: 3.x
75
+ - name: Build wheels
76
+ uses: PyO3/maturin-action@v1
77
+ with:
78
+ target: ${{ matrix.platform.target }}
79
+ args: --release --out dist --find-interpreter
80
+ sccache: 'true'
81
+ manylinux: musllinux_1_2
82
+ - name: Upload wheels
83
+ uses: actions/upload-artifact@v4
84
+ with:
85
+ name: wheels-musllinux-${{ matrix.platform.target }}
86
+ path: dist
87
+
88
+ windows:
89
+ runs-on: ${{ matrix.platform.runner }}
90
+ strategy:
91
+ matrix:
92
+ platform:
93
+ - runner: windows-latest
94
+ target: x64
95
+ - runner: windows-latest
96
+ target: x86
97
+ steps:
98
+ - uses: actions/checkout@v4
99
+ - uses: actions/setup-python@v5
100
+ with:
101
+ python-version: 3.x
102
+ architecture: ${{ matrix.platform.target }}
103
+ - name: Build wheels
104
+ uses: PyO3/maturin-action@v1
105
+ with:
106
+ target: ${{ matrix.platform.target }}
107
+ args: --release --out dist --find-interpreter
108
+ sccache: 'true'
109
+ - name: Upload wheels
110
+ uses: actions/upload-artifact@v4
111
+ with:
112
+ name: wheels-windows-${{ matrix.platform.target }}
113
+ path: dist
114
+
115
+ macos:
116
+ runs-on: ${{ matrix.platform.runner }}
117
+ strategy:
118
+ matrix:
119
+ platform:
120
+ - runner: macos-12
121
+ target: x86_64
122
+ - runner: macos-14
123
+ target: aarch64
124
+ steps:
125
+ - uses: actions/checkout@v4
126
+ - uses: actions/setup-python@v5
127
+ with:
128
+ python-version: 3.x
129
+ - name: Build wheels
130
+ uses: PyO3/maturin-action@v1
131
+ with:
132
+ target: ${{ matrix.platform.target }}
133
+ args: --release --out dist --find-interpreter
134
+ sccache: 'true'
135
+ - name: Upload wheels
136
+ uses: actions/upload-artifact@v4
137
+ with:
138
+ name: wheels-macos-${{ matrix.platform.target }}
139
+ path: dist
140
+
141
+ sdist:
142
+ runs-on: ubuntu-latest
143
+ steps:
144
+ - uses: actions/checkout@v4
145
+ - name: Build sdist
146
+ uses: PyO3/maturin-action@v1
147
+ with:
148
+ command: sdist
149
+ args: --out dist
150
+ - name: Upload sdist
151
+ uses: actions/upload-artifact@v4
152
+ with:
153
+ name: wheels-sdist
154
+ path: dist
155
+
156
+ release:
157
+ name: Release
158
+ runs-on: ubuntu-latest
159
+ if: startsWith(github.ref, 'refs/tags/')
160
+ needs: [linux, musllinux, windows, macos, sdist]
161
+ steps:
162
+ - uses: actions/download-artifact@v4
163
+ - name: Publish to PyPI
164
+ uses: PyO3/maturin-action@v1
165
+ env:
166
+ MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
167
+ with:
168
+ command: upload
169
+ args: --non-interactive --skip-existing wheels-*/*
@@ -10,24 +10,18 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
10
10
 
11
11
  [[package]]
12
12
  name = "bit-set"
13
- version = "0.5.3"
13
+ version = "0.8.0"
14
14
  source = "registry+https://github.com/rust-lang/crates.io-index"
15
- checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
15
+ checksum = "08807e080ed7f9d5433fa9b275196cfc35414f66a0c79d864dc51a0d825231a3"
16
16
  dependencies = [
17
17
  "bit-vec",
18
18
  ]
19
19
 
20
20
  [[package]]
21
21
  name = "bit-vec"
22
- version = "0.6.3"
22
+ version = "0.8.0"
23
23
  source = "registry+https://github.com/rust-lang/crates.io-index"
24
- checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
25
-
26
- [[package]]
27
- name = "bitflags"
28
- version = "1.3.2"
29
- source = "registry+https://github.com/rust-lang/crates.io-index"
30
- checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
24
+ checksum = "5e764a1d40d510daf35e07be9eb06e75770908c27d411ee6c92109c9840eaaf7"
31
25
 
32
26
  [[package]]
33
27
  name = "cfg-if"
@@ -37,7 +31,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
37
31
 
38
32
  [[package]]
39
33
  name = "cotengrust"
40
- version = "0.1.2"
34
+ version = "0.1.4"
41
35
  dependencies = [
42
36
  "bit-set",
43
37
  "ordered-float",
@@ -59,9 +53,9 @@ dependencies = [
59
53
 
60
54
  [[package]]
61
55
  name = "heck"
62
- version = "0.4.1"
56
+ version = "0.5.0"
63
57
  source = "registry+https://github.com/rust-lang/crates.io-index"
64
- checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
58
+ checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
65
59
 
66
60
  [[package]]
67
61
  name = "indoc"
@@ -75,16 +69,6 @@ version = "0.2.147"
75
69
  source = "registry+https://github.com/rust-lang/crates.io-index"
76
70
  checksum = "b4668fb0ea861c1df094127ac5f1da3409a82116a4ba74fca2e58ef927159bb3"
77
71
 
78
- [[package]]
79
- name = "lock_api"
80
- version = "0.4.10"
81
- source = "registry+https://github.com/rust-lang/crates.io-index"
82
- checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
83
- dependencies = [
84
- "autocfg",
85
- "scopeguard",
86
- ]
87
-
88
72
  [[package]]
89
73
  name = "memoffset"
90
74
  version = "0.9.0"
@@ -111,36 +95,13 @@ checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
111
95
 
112
96
  [[package]]
113
97
  name = "ordered-float"
114
- version = "4.2.0"
98
+ version = "4.2.2"
115
99
  source = "registry+https://github.com/rust-lang/crates.io-index"
116
- checksum = "a76df7075c7d4d01fdcb46c912dd17fba5b60c78ea480b475f2b6ab6f666584e"
100
+ checksum = "4a91171844676f8c7990ce64959210cd2eaef32c2612c50f9fae9f8aaa6065a6"
117
101
  dependencies = [
118
102
  "num-traits",
119
103
  ]
120
104
 
121
- [[package]]
122
- name = "parking_lot"
123
- version = "0.12.1"
124
- source = "registry+https://github.com/rust-lang/crates.io-index"
125
- checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
126
- dependencies = [
127
- "lock_api",
128
- "parking_lot_core",
129
- ]
130
-
131
- [[package]]
132
- name = "parking_lot_core"
133
- version = "0.9.8"
134
- source = "registry+https://github.com/rust-lang/crates.io-index"
135
- checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
136
- dependencies = [
137
- "cfg-if",
138
- "libc",
139
- "redox_syscall",
140
- "smallvec",
141
- "windows-targets",
142
- ]
143
-
144
105
  [[package]]
145
106
  name = "portable-atomic"
146
107
  version = "1.6.0"
@@ -155,24 +116,24 @@ checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
155
116
 
156
117
  [[package]]
157
118
  name = "proc-macro2"
158
- version = "1.0.66"
119
+ version = "1.0.86"
159
120
  source = "registry+https://github.com/rust-lang/crates.io-index"
160
- checksum = "18fb31db3f9bddb2ea821cde30a9f70117e3f119938b5ee630b7403aa6e2ead9"
121
+ checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77"
161
122
  dependencies = [
162
123
  "unicode-ident",
163
124
  ]
164
125
 
165
126
  [[package]]
166
127
  name = "pyo3"
167
- version = "0.21.1"
128
+ version = "0.22.3"
168
129
  source = "registry+https://github.com/rust-lang/crates.io-index"
169
- checksum = "a7a8b1990bd018761768d5e608a13df8bd1ac5f678456e0f301bb93e5f3ea16b"
130
+ checksum = "15ee168e30649f7f234c3d49ef5a7a6cbf5134289bc46c29ff3155fa3221c225"
170
131
  dependencies = [
171
132
  "cfg-if",
172
133
  "indoc",
173
134
  "libc",
174
135
  "memoffset",
175
- "parking_lot",
136
+ "once_cell",
176
137
  "portable-atomic",
177
138
  "pyo3-build-config",
178
139
  "pyo3-ffi",
@@ -182,9 +143,9 @@ dependencies = [
182
143
 
183
144
  [[package]]
184
145
  name = "pyo3-build-config"
185
- version = "0.21.1"
146
+ version = "0.22.3"
186
147
  source = "registry+https://github.com/rust-lang/crates.io-index"
187
- checksum = "650dca34d463b6cdbdb02b1d71bfd6eb6b6816afc708faebb3bac1380ff4aef7"
148
+ checksum = "e61cef80755fe9e46bb8a0b8f20752ca7676dcc07a5277d8b7768c6172e529b3"
188
149
  dependencies = [
189
150
  "once_cell",
190
151
  "target-lexicon",
@@ -192,9 +153,9 @@ dependencies = [
192
153
 
193
154
  [[package]]
194
155
  name = "pyo3-ffi"
195
- version = "0.21.1"
156
+ version = "0.22.3"
196
157
  source = "registry+https://github.com/rust-lang/crates.io-index"
197
- checksum = "09a7da8fc04a8a2084909b59f29e1b8474decac98b951d77b80b26dc45f046ad"
158
+ checksum = "67ce096073ec5405f5ee2b8b31f03a68e02aa10d5d4f565eca04acc41931fa1c"
198
159
  dependencies = [
199
160
  "libc",
200
161
  "pyo3-build-config",
@@ -202,9 +163,9 @@ dependencies = [
202
163
 
203
164
  [[package]]
204
165
  name = "pyo3-macros"
205
- version = "0.21.1"
166
+ version = "0.22.3"
206
167
  source = "registry+https://github.com/rust-lang/crates.io-index"
207
- checksum = "4b8a199fce11ebb28e3569387228836ea98110e43a804a530a9fd83ade36d513"
168
+ checksum = "2440c6d12bc8f3ae39f1e775266fa5122fd0c8891ce7520fa6048e683ad3de28"
208
169
  dependencies = [
209
170
  "proc-macro2",
210
171
  "pyo3-macros-backend",
@@ -214,9 +175,9 @@ dependencies = [
214
175
 
215
176
  [[package]]
216
177
  name = "pyo3-macros-backend"
217
- version = "0.21.1"
178
+ version = "0.22.3"
218
179
  source = "registry+https://github.com/rust-lang/crates.io-index"
219
- checksum = "93fbbfd7eb553d10036513cb122b888dcd362a945a00b06c165f2ab480d4cc3b"
180
+ checksum = "1be962f0e06da8f8465729ea2cb71a416d2257dff56cbe40a70d3e62a93ae5d1"
220
181
  dependencies = [
221
182
  "heck",
222
183
  "proc-macro2",
@@ -227,9 +188,9 @@ dependencies = [
227
188
 
228
189
  [[package]]
229
190
  name = "quote"
230
- version = "1.0.33"
191
+ version = "1.0.36"
231
192
  source = "registry+https://github.com/rust-lang/crates.io-index"
232
- checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae"
193
+ checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7"
233
194
  dependencies = [
234
195
  "proc-macro2",
235
196
  ]
@@ -264,38 +225,17 @@ dependencies = [
264
225
  "getrandom",
265
226
  ]
266
227
 
267
- [[package]]
268
- name = "redox_syscall"
269
- version = "0.3.5"
270
- source = "registry+https://github.com/rust-lang/crates.io-index"
271
- checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
272
- dependencies = [
273
- "bitflags",
274
- ]
275
-
276
228
  [[package]]
277
229
  name = "rustc-hash"
278
- version = "1.1.0"
279
- source = "registry+https://github.com/rust-lang/crates.io-index"
280
- checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
281
-
282
- [[package]]
283
- name = "scopeguard"
284
- version = "1.2.0"
285
- source = "registry+https://github.com/rust-lang/crates.io-index"
286
- checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
287
-
288
- [[package]]
289
- name = "smallvec"
290
- version = "1.11.0"
230
+ version = "2.0.0"
291
231
  source = "registry+https://github.com/rust-lang/crates.io-index"
292
- checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9"
232
+ checksum = "583034fd73374156e66797ed8e5b0d5690409c9226b22d87cb7f19821c05d152"
293
233
 
294
234
  [[package]]
295
235
  name = "syn"
296
- version = "2.0.32"
236
+ version = "2.0.74"
297
237
  source = "registry+https://github.com/rust-lang/crates.io-index"
298
- checksum = "239814284fd6f1a4ffe4ca893952cdd93c224b6a1571c9a9eadd670295c0c9e2"
238
+ checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7"
299
239
  dependencies = [
300
240
  "proc-macro2",
301
241
  "quote",
@@ -304,9 +244,9 @@ dependencies = [
304
244
 
305
245
  [[package]]
306
246
  name = "target-lexicon"
307
- version = "0.12.11"
247
+ version = "0.12.16"
308
248
  source = "registry+https://github.com/rust-lang/crates.io-index"
309
- checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a"
249
+ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
310
250
 
311
251
  [[package]]
312
252
  name = "unicode-ident"
@@ -325,60 +265,3 @@ name = "wasi"
325
265
  version = "0.11.0+wasi-snapshot-preview1"
326
266
  source = "registry+https://github.com/rust-lang/crates.io-index"
327
267
  checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
328
-
329
- [[package]]
330
- name = "windows-targets"
331
- version = "0.48.5"
332
- source = "registry+https://github.com/rust-lang/crates.io-index"
333
- checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c"
334
- dependencies = [
335
- "windows_aarch64_gnullvm",
336
- "windows_aarch64_msvc",
337
- "windows_i686_gnu",
338
- "windows_i686_msvc",
339
- "windows_x86_64_gnu",
340
- "windows_x86_64_gnullvm",
341
- "windows_x86_64_msvc",
342
- ]
343
-
344
- [[package]]
345
- name = "windows_aarch64_gnullvm"
346
- version = "0.48.5"
347
- source = "registry+https://github.com/rust-lang/crates.io-index"
348
- checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
349
-
350
- [[package]]
351
- name = "windows_aarch64_msvc"
352
- version = "0.48.5"
353
- source = "registry+https://github.com/rust-lang/crates.io-index"
354
- checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
355
-
356
- [[package]]
357
- name = "windows_i686_gnu"
358
- version = "0.48.5"
359
- source = "registry+https://github.com/rust-lang/crates.io-index"
360
- checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
361
-
362
- [[package]]
363
- name = "windows_i686_msvc"
364
- version = "0.48.5"
365
- source = "registry+https://github.com/rust-lang/crates.io-index"
366
- checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
367
-
368
- [[package]]
369
- name = "windows_x86_64_gnu"
370
- version = "0.48.5"
371
- source = "registry+https://github.com/rust-lang/crates.io-index"
372
- checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
373
-
374
- [[package]]
375
- name = "windows_x86_64_gnullvm"
376
- version = "0.48.5"
377
- source = "registry+https://github.com/rust-lang/crates.io-index"
378
- checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
379
-
380
- [[package]]
381
- name = "windows_x86_64_msvc"
382
- version = "0.48.5"
383
- source = "registry+https://github.com/rust-lang/crates.io-index"
384
- checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
@@ -1,6 +1,6 @@
1
1
  [package]
2
2
  name = "cotengrust"
3
- version = "0.1.2"
3
+ version = "0.1.4"
4
4
  edition = "2021"
5
5
 
6
6
  # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
@@ -9,11 +9,11 @@ name = "cotengrust"
9
9
  crate-type = ["cdylib"]
10
10
 
11
11
  [dependencies]
12
- bit-set = "0.5"
12
+ bit-set = "0.8"
13
13
  ordered-float = "4.2"
14
- pyo3 = "0.21"
14
+ pyo3 = "0.22"
15
15
  rand = "0.8"
16
- rustc-hash = "1.1"
16
+ rustc-hash = "2.0"
17
17
 
18
18
  [profile.release]
19
19
  codegen-units = 1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: cotengrust
3
- Version: 0.1.2
3
+ Version: 0.1.4
4
4
  Classifier: Programming Language :: Rust
5
5
  Classifier: Programming Language :: Python :: Implementation :: CPython
6
6
  Classifier: Programming Language :: Python :: Implementation :: PyPy
@@ -19,9 +19,14 @@ are:
19
19
  - `optimize_optimal(inputs, output, size_dict, **kwargs)`
20
20
  - `optimize_greedy(inputs, output, size_dict, **kwargs)`
21
21
 
22
- The optimal algorithm is an optimized version of the `opt_einsum` 'dp'
22
+ The optimal algorithm is an optimized version of the `opt_einsum` 'dp'
23
23
  path - itself an implementation of https://arxiv.org/abs/1304.6112.
24
24
 
25
+ There is also a variant of the greedy algorithm, which runs `ntrials` of greedy,
26
+ randomized paths and computes and reports the flops cost (log10) simultaneously:
27
+
28
+ - `optimize_random_greedy_track_flops(inputs, output, size_dict, **kwargs)`
29
+
25
30
 
26
31
  ## Installation
27
32
 
@@ -32,7 +37,7 @@ path - itself an implementation of https://arxiv.org/abs/1304.6112.
32
37
  pip install cotengrust
33
38
  ```
34
39
 
35
- or if you want to develop locally (which requires [pyo3](https://github.com/PyO3/pyo3)
40
+ or if you want to develop locally (which requires [pyo3](https://github.com/PyO3/pyo3)
36
41
  and [maturin](https://github.com/PyO3/maturin)):
37
42
 
38
43
  ```bash
@@ -46,8 +51,8 @@ maturin develop --release
46
51
  ## Usage
47
52
 
48
53
  If `cotengrust` is installed, then by default `cotengra` will use it for its
49
- greedy and optimal subroutines, notably subtree reconfiguration. You can also
50
- call the routines directly:
54
+ greedy, random-greedy, and optimal subroutines, notably subtree
55
+ reconfiguration. You can also call the routines directly:
51
56
 
52
57
  ```python
53
58
  import cotengra as ctg
@@ -171,7 +176,7 @@ def optimize_greedy(
171
176
  When assessing local greedy scores how much to weight the size of the
172
177
  tensors removed compared to the size of the tensor added::
173
178
 
174
- score = size_ab - costmod * (size_a + size_b)
179
+ score = size_ab / costmod - (size_a + size_b) * costmod
175
180
 
176
181
  This can be a useful hyper-parameter to tune.
177
182
  temperature : float, optional
@@ -237,6 +242,77 @@ def optimize_simplify(
237
242
  """
238
243
  ...
239
244
 
245
+ def optimize_random_greedy_track_flops(
246
+ inputs,
247
+ output,
248
+ size_dict,
249
+ ntrials=1,
250
+ costmod=(0.1, 4.0),
251
+ temperature=(0.001, 1.0),
252
+ seed=None,
253
+ simplify=True,
254
+ use_ssa=False,
255
+ ):
256
+ """Perform a batch of random greedy optimizations, simulteneously tracking
257
+ the best contraction path in terms of flops, so as to avoid constructing a
258
+ separate contraction tree.
259
+
260
+ Parameters
261
+ ----------
262
+ inputs : tuple[tuple[str]]
263
+ The indices of each input tensor.
264
+ output : tuple[str]
265
+ The indices of the output tensor.
266
+ size_dict : dict[str, int]
267
+ A dictionary mapping indices to their dimension.
268
+ ntrials : int, optional
269
+ The number of random greedy trials to perform. The default is 1.
270
+ costmod : (float, float), optional
271
+ When assessing local greedy scores how much to weight the size of the
272
+ tensors removed compared to the size of the tensor added::
273
+
274
+ score = size_ab / costmod - (size_a + size_b) * costmod
275
+
276
+ It is sampled uniformly from the given range.
277
+ temperature : (float, float), optional
278
+ When asessing local greedy scores, how much to randomly perturb the
279
+ score. This is implemented as::
280
+
281
+ score -> sign(score) * log(|score|) - temperature * gumbel()
282
+
283
+ which implements boltzmann sampling. It is sampled log-uniformly from
284
+ the given range.
285
+ seed : int, optional
286
+ The seed for the random number generator.
287
+ simplify : bool, optional
288
+ Whether to perform simplifications before optimizing. These are:
289
+
290
+ - ignore any indices that appear in all terms
291
+ - combine any repeated indices within a single term
292
+ - reduce any non-output indices that only appear on a single term
293
+ - combine any scalar terms
294
+ - combine any tensors with matching indices (hadamard products)
295
+
296
+ Such simpifications may be required in the general case for the proper
297
+ functioning of the core optimization, but may be skipped if the input
298
+ indices are already in a simplified form.
299
+ use_ssa : bool, optional
300
+ Whether to return the contraction path in 'single static assignment'
301
+ (SSA) format (i.e. as if each intermediate is appended to the list of
302
+ inputs, without removals). This can be quicker and easier to work with
303
+ than the 'linear recycled' format that `numpy` and `opt_einsum` use.
304
+
305
+ Returns
306
+ -------
307
+ path : list[list[int]]
308
+ The best contraction path, given as a sequence of pairs of node
309
+ indices.
310
+ flops : float
311
+ The flops (/ contraction cost / number of multiplications), of the best
312
+ contraction path, given log10.
313
+ """
314
+ ...
315
+
240
316
  def ssa_to_linear(ssa_path, n=None):
241
317
  """Convert a SSA path to linear format."""
242
318
  ...
@@ -7,9 +7,14 @@ are:
7
7
  - `optimize_optimal(inputs, output, size_dict, **kwargs)`
8
8
  - `optimize_greedy(inputs, output, size_dict, **kwargs)`
9
9
 
10
- The optimal algorithm is an optimized version of the `opt_einsum` 'dp'
10
+ The optimal algorithm is an optimized version of the `opt_einsum` 'dp'
11
11
  path - itself an implementation of https://arxiv.org/abs/1304.6112.
12
12
 
13
+ There is also a variant of the greedy algorithm, which runs `ntrials` of greedy,
14
+ randomized paths and computes and reports the flops cost (log10) simultaneously:
15
+
16
+ - `optimize_random_greedy_track_flops(inputs, output, size_dict, **kwargs)`
17
+
13
18
 
14
19
  ## Installation
15
20
 
@@ -20,7 +25,7 @@ path - itself an implementation of https://arxiv.org/abs/1304.6112.
20
25
  pip install cotengrust
21
26
  ```
22
27
 
23
- or if you want to develop locally (which requires [pyo3](https://github.com/PyO3/pyo3)
28
+ or if you want to develop locally (which requires [pyo3](https://github.com/PyO3/pyo3)
24
29
  and [maturin](https://github.com/PyO3/maturin)):
25
30
 
26
31
  ```bash
@@ -34,8 +39,8 @@ maturin develop --release
34
39
  ## Usage
35
40
 
36
41
  If `cotengrust` is installed, then by default `cotengra` will use it for its
37
- greedy and optimal subroutines, notably subtree reconfiguration. You can also
38
- call the routines directly:
42
+ greedy, random-greedy, and optimal subroutines, notably subtree
43
+ reconfiguration. You can also call the routines directly:
39
44
 
40
45
  ```python
41
46
  import cotengra as ctg
@@ -159,7 +164,7 @@ def optimize_greedy(
159
164
  When assessing local greedy scores how much to weight the size of the
160
165
  tensors removed compared to the size of the tensor added::
161
166
 
162
- score = size_ab - costmod * (size_a + size_b)
167
+ score = size_ab / costmod - (size_a + size_b) * costmod
163
168
 
164
169
  This can be a useful hyper-parameter to tune.
165
170
  temperature : float, optional
@@ -225,6 +230,77 @@ def optimize_simplify(
225
230
  """
226
231
  ...
227
232
 
233
+ def optimize_random_greedy_track_flops(
234
+ inputs,
235
+ output,
236
+ size_dict,
237
+ ntrials=1,
238
+ costmod=(0.1, 4.0),
239
+ temperature=(0.001, 1.0),
240
+ seed=None,
241
+ simplify=True,
242
+ use_ssa=False,
243
+ ):
244
+ """Perform a batch of random greedy optimizations, simulteneously tracking
245
+ the best contraction path in terms of flops, so as to avoid constructing a
246
+ separate contraction tree.
247
+
248
+ Parameters
249
+ ----------
250
+ inputs : tuple[tuple[str]]
251
+ The indices of each input tensor.
252
+ output : tuple[str]
253
+ The indices of the output tensor.
254
+ size_dict : dict[str, int]
255
+ A dictionary mapping indices to their dimension.
256
+ ntrials : int, optional
257
+ The number of random greedy trials to perform. The default is 1.
258
+ costmod : (float, float), optional
259
+ When assessing local greedy scores how much to weight the size of the
260
+ tensors removed compared to the size of the tensor added::
261
+
262
+ score = size_ab / costmod - (size_a + size_b) * costmod
263
+
264
+ It is sampled uniformly from the given range.
265
+ temperature : (float, float), optional
266
+ When asessing local greedy scores, how much to randomly perturb the
267
+ score. This is implemented as::
268
+
269
+ score -> sign(score) * log(|score|) - temperature * gumbel()
270
+
271
+ which implements boltzmann sampling. It is sampled log-uniformly from
272
+ the given range.
273
+ seed : int, optional
274
+ The seed for the random number generator.
275
+ simplify : bool, optional
276
+ Whether to perform simplifications before optimizing. These are:
277
+
278
+ - ignore any indices that appear in all terms
279
+ - combine any repeated indices within a single term
280
+ - reduce any non-output indices that only appear on a single term
281
+ - combine any scalar terms
282
+ - combine any tensors with matching indices (hadamard products)
283
+
284
+ Such simpifications may be required in the general case for the proper
285
+ functioning of the core optimization, but may be skipped if the input
286
+ indices are already in a simplified form.
287
+ use_ssa : bool, optional
288
+ Whether to return the contraction path in 'single static assignment'
289
+ (SSA) format (i.e. as if each intermediate is appended to the list of
290
+ inputs, without removals). This can be quicker and easier to work with
291
+ than the 'linear recycled' format that `numpy` and `opt_einsum` use.
292
+
293
+ Returns
294
+ -------
295
+ path : list[list[int]]
296
+ The best contraction path, given as a sequence of pairs of node
297
+ indices.
298
+ flops : float
299
+ The flops (/ contraction cost / number of multiplications), of the best
300
+ contraction path, given log10.
301
+ """
302
+ ...
303
+
228
304
  def ssa_to_linear(ssa_path, n=None):
229
305
  """Convert a SSA path to linear format."""
230
306
  ...
@@ -0,0 +1,258 @@
1
+ # This file is automatically generated by pyo3_stub_gen
2
+ # ruff: noqa: E501, F401
3
+
4
+ import typing
5
+
6
+ def find_subgraphs(
7
+ inputs: typing.Sequence[typing.Sequence[str]],
8
+ output: typing.Sequence[str],
9
+ size_dict: typing.Mapping[str, float],
10
+ ) -> list[list[int]]:
11
+ r"""
12
+ Find all disconnected subgraphs of a specified contraction.
13
+ """
14
+ ...
15
+
16
+ def optimize_greedy(
17
+ inputs: typing.Sequence[typing.Sequence[str]],
18
+ output: typing.Sequence[str],
19
+ size_dict: typing.Mapping[str, float],
20
+ costmod: typing.Optional[float] = None,
21
+ temperature: typing.Optional[float] = None,
22
+ seed: typing.Optional[int] = None,
23
+ simplify: typing.Optional[bool] = None,
24
+ use_ssa: typing.Optional[bool] = None,
25
+ ) -> list[list[int]]:
26
+ r"""
27
+ Find a contraction path using a (randomizable) greedy algorithm.
28
+
29
+ Parameters
30
+ ----------
31
+ inputs : Sequence[Sequence[str]]
32
+ The indices of each input tensor.
33
+ output : Sequence[str]
34
+ The indices of the output tensor.
35
+ size_dict : dict[str, int]
36
+ A dictionary mapping indices to their dimension.
37
+ costmod : float, optional
38
+ When assessing local greedy scores how much to weight the size of the
39
+ tensors removed compared to the size of the tensor added::
40
+
41
+ score = size_ab / costmod - (size_a + size_b) * costmod
42
+
43
+ This can be a useful hyper-parameter to tune.
44
+ temperature : float, optional
45
+ When asessing local greedy scores, how much to randomly perturb the
46
+ score. This is implemented as::
47
+
48
+ score -> sign(score) * log(|score|) - temperature * gumbel()
49
+
50
+ which implements boltzmann sampling.
51
+ simplify : bool, optional
52
+ Whether to perform simplifications before optimizing. These are:
53
+
54
+ - ignore any indices that appear in all terms
55
+ - combine any repeated indices within a single term
56
+ - reduce any non-output indices that only appear on a single term
57
+ - combine any scalar terms
58
+ - combine any tensors with matching indices (hadamard products)
59
+
60
+ Such simpifications may be required in the general case for the proper
61
+ functioning of the core optimization, but may be skipped if the input
62
+ indices are already in a simplified form.
63
+ use_ssa : bool, optional
64
+ Whether to return the contraction path in 'single static assignment'
65
+ (SSA) format (i.e. as if each intermediate is appended to the list of
66
+ inputs, without removals). This can be quicker and easier to work with
67
+ than the 'linear recycled' format that `numpy` and `opt_einsum` use.
68
+
69
+ Returns
70
+ -------
71
+ path : list[list[int]]
72
+ The contraction path, given as a sequence of pairs of node indices. It
73
+ may also have single term contractions if `simplify=True`.
74
+ """
75
+ ...
76
+
77
+ def optimize_optimal(
78
+ inputs: typing.Sequence[typing.Sequence[str]],
79
+ output: typing.Sequence[str],
80
+ size_dict: typing.Mapping[str, float],
81
+ minimize: typing.Optional[str] = None,
82
+ cost_cap: typing.Optional[float] = None,
83
+ search_outer: typing.Optional[bool] = None,
84
+ simplify: typing.Optional[bool] = None,
85
+ use_ssa: typing.Optional[bool] = None,
86
+ ) -> list[list[int]]:
87
+ r"""
88
+ Find an optimal contraction ordering.
89
+
90
+ Parameters
91
+ ----------
92
+ inputs : Sequence[Sequence[str]]
93
+ The indices of each input tensor.
94
+ output : Sequence[str]
95
+ The indices of the output tensor.
96
+ size_dict : dict[str, int]
97
+ The size of each index.
98
+ minimize : str, optional
99
+ The cost function to minimize. The options are:
100
+
101
+ - "flops": minimize with respect to total operation count only
102
+ (also known as contraction cost)
103
+ - "size": minimize with respect to maximum intermediate size only
104
+ (also known as contraction width)
105
+ - 'write' : minimize the sum of all tensor sizes, i.e. memory written
106
+ - 'combo' or 'combo={factor}` : minimize the sum of
107
+ FLOPS + factor * WRITE, with a default factor of 64.
108
+ - 'limit' or 'limit={factor}` : minimize the sum of
109
+ MAX(FLOPS, alpha * WRITE) for each individual contraction, with a
110
+ default factor of 64.
111
+
112
+ 'combo' is generally a good default in term of practical hardware
113
+ performance, where both memory bandwidth and compute are limited.
114
+ cost_cap : float, optional
115
+ The maximum cost of a contraction to initially consider. This acts like
116
+ a sieve and is doubled at each iteration until the optimal path can
117
+ be found, but supplying an accurate guess can speed up the algorithm.
118
+ search_outer : bool, optional
119
+ If True, consider outer product contractions. This is much slower but
120
+ theoretically might be required to find the true optimal 'flops'
121
+ ordering. In practical settings (i.e. with minimize='combo'), outer
122
+ products should not be required.
123
+ simplify : bool, optional
124
+ Whether to perform simplifications before optimizing. These are:
125
+
126
+ - ignore any indices that appear in all terms
127
+ - combine any repeated indices within a single term
128
+ - reduce any non-output indices that only appear on a single term
129
+ - combine any scalar terms
130
+ - combine any tensors with matching indices (hadamard products)
131
+
132
+ Such simpifications may be required in the general case for the proper
133
+ functioning of the core optimization, but may be skipped if the input
134
+ indices are already in a simplified form.
135
+ use_ssa : bool, optional
136
+ Whether to return the contraction path in 'single static assignment'
137
+ (SSA) format (i.e. as if each intermediate is appended to the list of
138
+ inputs, without removals). This can be quicker and easier to work with
139
+ than the 'linear recycled' format that `numpy` and `opt_einsum` use.
140
+
141
+ Returns
142
+ -------
143
+ path : list[list[int]]
144
+ The contraction path, given as a sequence of pairs of node indices. It
145
+ may also have single term contractions if `simplify=True`.
146
+ """
147
+ ...
148
+
149
+ def optimize_random_greedy_track_flops(
150
+ inputs: typing.Sequence[typing.Sequence[str]],
151
+ output: typing.Sequence[str],
152
+ size_dict: typing.Mapping[str, float],
153
+ ntrials: int,
154
+ costmod: typing.Optional[tuple[float, float]] = None,
155
+ temperature: typing.Optional[tuple[float, float]] = None,
156
+ seed: typing.Optional[int] = None,
157
+ simplify: typing.Optional[bool] = None,
158
+ use_ssa: typing.Optional[bool] = None,
159
+ ) -> tuple[list[list[int]], float]:
160
+ r"""
161
+ Perform a batch of random greedy optimizations, simulteneously tracking
162
+ the best contraction path in terms of flops, so as to avoid constructing a
163
+ separate contraction tree.
164
+
165
+ Parameters
166
+ ----------
167
+ inputs : tuple[tuple[str]]
168
+ The indices of each input tensor.
169
+ output : tuple[str]
170
+ The indices of the output tensor.
171
+ size_dict : dict[str, int]
172
+ A dictionary mapping indices to their dimension.
173
+ ntrials : int, optional
174
+ The number of random greedy trials to perform. The default is 1.
175
+ costmod : (float, float), optional
176
+ When assessing local greedy scores how much to weight the size of the
177
+ tensors removed compared to the size of the tensor added::
178
+
179
+ score = size_ab / costmod - (size_a + size_b) * costmod
180
+
181
+ It is sampled uniformly from the given range.
182
+ temperature : (float, float), optional
183
+ When asessing local greedy scores, how much to randomly perturb the
184
+ score. This is implemented as::
185
+
186
+ score -> sign(score) * log(|score|) - temperature * gumbel()
187
+
188
+ which implements boltzmann sampling. It is sampled log-uniformly from
189
+ the given range.
190
+ seed : int, optional
191
+ The seed for the random number generator.
192
+ simplify : bool, optional
193
+ Whether to perform simplifications before optimizing. These are:
194
+
195
+ - ignore any indices that appear in all terms
196
+ - combine any repeated indices within a single term
197
+ - reduce any non-output indices that only appear on a single term
198
+ - combine any scalar terms
199
+ - combine any tensors with matching indices (hadamard products)
200
+
201
+ Such simpifications may be required in the general case for the proper
202
+ functioning of the core optimization, but may be skipped if the input
203
+ indices are already in a simplified form.
204
+ use_ssa : bool, optional
205
+ Whether to return the contraction path in 'single static assignment'
206
+ (SSA) format (i.e. as if each intermediate is appended to the list of
207
+ inputs, without removals). This can be quicker and easier to work with
208
+ than the 'linear recycled' format that `numpy` and `opt_einsum` use.
209
+
210
+ Returns
211
+ -------
212
+ path : list[list[int]]
213
+ The best contraction path, given as a sequence of pairs of node
214
+ indices.
215
+ flops : float
216
+ The flops (/ contraction cost / number of multiplications), of the best
217
+ contraction path, given log10.
218
+ """
219
+ ...
220
+
221
+ def optimize_simplify(
222
+ inputs: typing.Sequence[typing.Sequence[str]],
223
+ output: typing.Sequence[str],
224
+ size_dict: typing.Mapping[str, float],
225
+ use_ssa: typing.Optional[bool] = None,
226
+ ) -> list[list[int]]:
227
+ r"""
228
+ Find the (partial) contracton path for simplifiactions only.
229
+
230
+ Parameters
231
+ ----------
232
+ inputs : Sequence[Sequence[str]]
233
+ The indices of each input tensor.
234
+ output : Sequence[str]
235
+ The indices of the output tensor.
236
+ size_dict : dict[str, int]
237
+ A dictionary mapping indices to their dimension.
238
+ use_ssa : bool, optional
239
+ Whether to return the contraction path in 'single static assignment'
240
+ (SSA) format (i.e. as if each intermediate is appended to the list of
241
+ inputs, without removals). This can be quicker and easier to work with
242
+ than the 'linear recycled' format that `numpy` and `opt_einsum` use.
243
+
244
+ Returns
245
+ -------
246
+ path : list[list[int]]
247
+ The contraction path, given as a sequence of pairs of node indices. It
248
+ may also have single term contractions.
249
+ """
250
+ ...
251
+
252
+ def ssa_to_linear(
253
+ ssa_path: typing.Sequence[typing.Sequence[int]], n: typing.Optional[int] = None
254
+ ) -> list[list[int]]:
255
+ r"""
256
+ Convert a SSA path to linear format.
257
+ """
258
+ ...
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "cotengrust"
3
- version = "0.1.2"
3
+ version = "0.1.4"
4
4
  description = "Fast contraction ordering primitives for tensor networks."
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.8"
@@ -34,6 +34,7 @@ struct ContractionProcessor {
34
34
  ssa_path: SSAPath,
35
35
  track_flops: bool,
36
36
  flops: Score,
37
+ flops_limit: Score,
37
38
  }
38
39
 
39
40
  /// given log(x) and log(y) compute log(x + y), without exponentiating both
@@ -195,6 +196,7 @@ impl ContractionProcessor {
195
196
  let ssa = nodes.len() as Node;
196
197
  let ssa_path: SSAPath = Vec::with_capacity(2 * ssa as usize - 1);
197
198
  let flops: Score = 0.0;
199
+ let flops_limit: Score = Score::INFINITY;
198
200
 
199
201
  ContractionProcessor {
200
202
  nodes,
@@ -205,6 +207,7 @@ impl ContractionProcessor {
205
207
  ssa_path,
206
208
  track_flops,
207
209
  flops,
210
+ flops_limit,
208
211
  }
209
212
  }
210
213
 
@@ -415,7 +418,7 @@ impl ContractionProcessor {
415
418
  costmod: Option<f32>,
416
419
  temperature: Option<f32>,
417
420
  seed: Option<u64>,
418
- ) {
421
+ ) -> bool {
419
422
  let coeff_t = temperature.unwrap_or(0.0);
420
423
  let log_coeff_a = f32::ln(costmod.unwrap_or(1.0));
421
424
 
@@ -435,7 +438,7 @@ impl ContractionProcessor {
435
438
  } else {
436
439
  0.0 as f32
437
440
  };
438
- logsub(sab, log_coeff_a + logadd(sa, sb)) - gumbel
441
+ logsub(sab - log_coeff_a, logadd(sa, sb) + log_coeff_a) - gumbel
439
442
  };
440
443
 
441
444
  // cache all current nodes sizes as we go
@@ -483,6 +486,12 @@ impl ContractionProcessor {
483
486
 
484
487
  // perform contraction:
485
488
  let k = self.contract_nodes_given_legs(i, j, klegs.clone());
489
+
490
+ if self.track_flops && self.flops >= self.flops_limit {
491
+ // stop if we have reached the flops limit
492
+ return false;
493
+ }
494
+
486
495
  node_sizes.insert(k, ksize);
487
496
 
488
497
  for l in self.neighbors(k) {
@@ -498,6 +507,8 @@ impl ContractionProcessor {
498
507
  c -= 1;
499
508
  }
500
509
  }
510
+ // success
511
+ return true;
501
512
  }
502
513
 
503
514
  /// Optimize the contraction order of all terms using a greedy algorithm
@@ -854,6 +865,7 @@ impl ContractionProcessor {
854
865
  // --------------------------- PYTHON FUNCTIONS ---------------------------- //
855
866
 
856
867
  #[pyfunction]
868
+ #[pyo3(signature = (ssa_path, n=None))]
857
869
  fn ssa_to_linear(ssa_path: SSAPath, n: Option<usize>) -> SSAPath {
858
870
  let n = match n {
859
871
  Some(n) => n,
@@ -891,6 +903,7 @@ fn find_subgraphs(
891
903
  }
892
904
 
893
905
  #[pyfunction]
906
+ #[pyo3(signature = (inputs, output, size_dict, use_ssa=None))]
894
907
  fn optimize_simplify(
895
908
  inputs: Vec<Vec<char>>,
896
909
  output: Vec<char>,
@@ -908,6 +921,7 @@ fn optimize_simplify(
908
921
  }
909
922
 
910
923
  #[pyfunction]
924
+ #[pyo3(signature = (inputs, output, size_dict, costmod=None, temperature=None, seed=None, simplify=None, use_ssa=None))]
911
925
  fn optimize_greedy(
912
926
  py: Python,
913
927
  inputs: Vec<Vec<char>>,
@@ -939,20 +953,30 @@ fn optimize_greedy(
939
953
  }
940
954
 
941
955
  #[pyfunction]
956
+ #[pyo3(signature = (inputs, output, size_dict, ntrials, costmod=None, temperature=None, seed=None, simplify=None, use_ssa=None))]
942
957
  fn optimize_random_greedy_track_flops(
943
958
  py: Python,
944
959
  inputs: Vec<Vec<char>>,
945
960
  output: Vec<char>,
946
961
  size_dict: Dict<char, f32>,
947
962
  ntrials: usize,
948
- costmod: Option<f32>,
949
- temperature: Option<f32>,
963
+ costmod: Option<(f32, f32)>,
964
+ temperature: Option<(f32, f32)>,
950
965
  seed: Option<u64>,
951
966
  simplify: Option<bool>,
952
967
  use_ssa: Option<bool>,
953
968
  ) -> (Vec<Vec<Node>>, Score) {
954
969
  py.allow_threads(|| {
955
- let temperature = temperature.unwrap_or(0.01);
970
+ let (costmod_min, costmod_max) = costmod.unwrap_or((0.1, 4.0));
971
+ let costmod_diff = (costmod_max - costmod_min).abs();
972
+ let is_const_costmod = costmod_diff < Score::EPSILON;
973
+
974
+ let (temp_min, temp_max) = temperature.unwrap_or((0.001, 1.0));
975
+ let log_temp_min = Score::ln(temp_min);
976
+ let log_temp_max = Score::ln(temp_max);
977
+ let log_temp_diff = (log_temp_max - log_temp_min).abs();
978
+ let is_const_temp = log_temp_diff < Score::EPSILON;
979
+
956
980
  let mut rng = match seed {
957
981
  Some(seed) => rand::rngs::StdRng::seed_from_u64(seed),
958
982
  None => rand::rngs::StdRng::from_entropy(),
@@ -971,14 +995,35 @@ fn optimize_random_greedy_track_flops(
971
995
 
972
996
  for seed in seeds {
973
997
  let mut cp = cp0.clone();
998
+
999
+ // uniform sample for costmod
1000
+ let costmod = if is_const_costmod {
1001
+ costmod_min
1002
+ } else {
1003
+ costmod_min + rng.gen::<f32>() * costmod_diff
1004
+ };
1005
+
1006
+ // log-uniform sample for temperature
1007
+ let temperature = if is_const_temp {
1008
+ temp_min
1009
+ } else {
1010
+ f32::exp(log_temp_min + rng.gen::<f32>() * log_temp_diff)
1011
+ };
1012
+
974
1013
  // greedily contract each connected subgraph
975
- cp.optimize_greedy(costmod, Some(temperature), Some(seed));
1014
+ let success = cp.optimize_greedy(Some(costmod), Some(temperature), Some(seed));
1015
+
1016
+ if !success {
1017
+ continue;
1018
+ }
1019
+
976
1020
  // optimize any remaining disconnected terms
977
1021
  cp.optimize_remaining_by_size();
978
1022
 
979
1023
  if cp.flops < best_flops {
980
- best_flops = cp.flops;
981
1024
  best_path = Some(cp.ssa_path);
1025
+ best_flops = cp.flops;
1026
+ cp0.flops_limit = cp.flops;
982
1027
  }
983
1028
  }
984
1029
 
@@ -994,6 +1039,7 @@ fn optimize_random_greedy_track_flops(
994
1039
  }
995
1040
 
996
1041
  #[pyfunction]
1042
+ #[pyo3(signature = (inputs, output, size_dict, minimize=None, cost_cap=None, search_outer=None, simplify=None, use_ssa=None))]
997
1043
  fn optimize_optimal(
998
1044
  py: Python,
999
1045
  inputs: Vec<Vec<char>>,
@@ -1,162 +0,0 @@
1
- # This file is autogenerated by maturin v1.2.3
2
- # To update, run
3
- #
4
- # maturin generate-ci github --pytest
5
- #
6
- name: CI
7
-
8
- on:
9
- push:
10
- branches:
11
- - main
12
- - master
13
- tags:
14
- - '*'
15
- pull_request:
16
- workflow_dispatch:
17
-
18
- permissions:
19
- contents: read
20
-
21
- jobs:
22
- linux:
23
- runs-on: ubuntu-latest
24
- strategy:
25
- matrix:
26
- target: [x86_64, x86, aarch64, armv7, s390x, ppc64le]
27
- steps:
28
- - uses: actions/checkout@v3
29
- - uses: actions/setup-python@v4
30
- with:
31
- python-version: '3.10'
32
- - name: Build wheels
33
- uses: PyO3/maturin-action@v1
34
- with:
35
- target: ${{ matrix.target }}
36
- args: --release --out dist --find-interpreter
37
- sccache: 'true'
38
- manylinux: auto
39
- - name: Upload wheels
40
- uses: actions/upload-artifact@v3
41
- with:
42
- name: wheels
43
- path: dist
44
- - name: pytest
45
- if: ${{ startsWith(matrix.target, 'x86_64') }}
46
- shell: bash
47
- run: |
48
- set -e
49
- ls dist/*
50
- pip install cotengrust --find-links dist --force-reinstall
51
- pip install pytest numpy cotengra
52
- pytest --verbose
53
- - name: pytest
54
- if: ${{ !startsWith(matrix.target, 'x86') && matrix.target != 'ppc64' }}
55
- uses: uraimo/run-on-arch-action@v2.5.0
56
- with:
57
- arch: ${{ matrix.target }}
58
- distro: ubuntu22.04
59
- githubToken: ${{ github.token }}
60
- install: |
61
- apt-get update
62
- apt-get install -y --no-install-recommends python3 python3-pip
63
- pip3 install -U pip pytest # numpy cotengra
64
- run: |
65
- set -e
66
- pip3 install cotengrust --find-links dist --force-reinstall
67
- pytest --verbose
68
-
69
- windows:
70
- runs-on: windows-latest
71
- strategy:
72
- matrix:
73
- target: [x64, x86]
74
- steps:
75
- - uses: actions/checkout@v3
76
- - uses: actions/setup-python@v4
77
- with:
78
- python-version: '3.10'
79
- architecture: ${{ matrix.target }}
80
- - name: Build wheels
81
- uses: PyO3/maturin-action@v1
82
- with:
83
- target: ${{ matrix.target }}
84
- args: --release --out dist --find-interpreter
85
- sccache: 'true'
86
- - name: Upload wheels
87
- uses: actions/upload-artifact@v3
88
- with:
89
- name: wheels
90
- path: dist
91
- - name: pytest
92
- if: ${{ !startsWith(matrix.target, 'aarch64') }}
93
- shell: bash
94
- run: |
95
- set -e
96
- ls dist/*
97
- pip install cotengrust --find-links dist --force-reinstall
98
- pip install pytest numpy cotengra
99
- pytest --verbose
100
-
101
- macos:
102
- runs-on: macos-latest
103
- strategy:
104
- matrix:
105
- target: [x86_64, aarch64]
106
- steps:
107
- - uses: actions/checkout@v3
108
- - uses: actions/setup-python@v4
109
- with:
110
- python-version: '3.10'
111
- - name: Build wheels
112
- uses: PyO3/maturin-action@v1
113
- with:
114
- target: ${{ matrix.target }}
115
- args: --release --out dist --find-interpreter
116
- sccache: 'true'
117
- - name: Upload wheels
118
- uses: actions/upload-artifact@v3
119
- with:
120
- name: wheels
121
- path: dist
122
- - name: pytest
123
- if: ${{ !startsWith(matrix.target, 'aarch64') }}
124
- shell: bash
125
- run: |
126
- set -e
127
- ls dist/*
128
- pip install cotengrust --find-links dist --force-reinstall
129
- pip install pytest numpy cotengra
130
- pytest --verbose
131
-
132
- sdist:
133
- runs-on: ubuntu-latest
134
- steps:
135
- - uses: actions/checkout@v3
136
- - name: Build sdist
137
- uses: PyO3/maturin-action@v1
138
- with:
139
- command: sdist
140
- args: --out dist
141
- - name: Upload sdist
142
- uses: actions/upload-artifact@v3
143
- with:
144
- name: wheels
145
- path: dist
146
-
147
- release:
148
- name: Release
149
- runs-on: ubuntu-latest
150
- if: startsWith(github.ref, 'refs/tags/')
151
- needs: [linux, windows, macos, sdist]
152
- steps:
153
- - uses: actions/download-artifact@v3
154
- with:
155
- name: wheels
156
- - name: Publish to PyPI
157
- uses: PyO3/maturin-action@v1
158
- env:
159
- MATURIN_PYPI_TOKEN: ${{ secrets.PYPI_API_TOKEN }}
160
- with:
161
- command: upload
162
- args: --non-interactive --skip-existing *
File without changes
File without changes