tinybrain 1.7.0__tar.gz → 1.8.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.
Files changed (31) hide show
  1. {tinybrain-1.7.0 → tinybrain-1.8.0}/.github/workflows/build_wheel.yml +4 -8
  2. {tinybrain-1.7.0 → tinybrain-1.8.0}/.github/workflows/run_tests.yml +2 -2
  3. {tinybrain-1.7.0 → tinybrain-1.8.0}/ChangeLog +13 -0
  4. {tinybrain-1.7.0 → tinybrain-1.8.0}/PKG-INFO +1 -1
  5. {tinybrain-1.7.0 → tinybrain-1.8.0}/automated_test.py +15 -0
  6. {tinybrain-1.7.0 → tinybrain-1.8.0}/perf.py +47 -0
  7. {tinybrain-1.7.0 → tinybrain-1.8.0}/tinybrain/__init__.py +1 -1
  8. {tinybrain-1.7.0 → tinybrain-1.8.0}/tinybrain/accelerated.hpp +14 -7
  9. {tinybrain-1.7.0 → tinybrain-1.8.0}/tinybrain/downsample.py +9 -0
  10. {tinybrain-1.7.0 → tinybrain-1.8.0}/tinybrain.egg-info/PKG-INFO +1 -1
  11. tinybrain-1.8.0/tinybrain.egg-info/pbr.json +1 -0
  12. tinybrain-1.7.0/tinybrain.egg-info/pbr.json +0 -1
  13. {tinybrain-1.7.0 → tinybrain-1.8.0}/AUTHORS +0 -0
  14. {tinybrain-1.7.0 → tinybrain-1.8.0}/LICENSE +0 -0
  15. {tinybrain-1.7.0 → tinybrain-1.8.0}/README.md +0 -0
  16. {tinybrain-1.7.0 → tinybrain-1.8.0}/build_linux.sh +0 -0
  17. {tinybrain-1.7.0 → tinybrain-1.8.0}/manylinux1.Dockerfile +0 -0
  18. {tinybrain-1.7.0 → tinybrain-1.8.0}/manylinux2010.Dockerfile +0 -0
  19. {tinybrain-1.7.0 → tinybrain-1.8.0}/manylinux2014.Dockerfile +0 -0
  20. {tinybrain-1.7.0 → tinybrain-1.8.0}/pyproject.toml +0 -0
  21. {tinybrain-1.7.0 → tinybrain-1.8.0}/requirements.txt +0 -0
  22. {tinybrain-1.7.0 → tinybrain-1.8.0}/requirements_dev.txt +0 -0
  23. {tinybrain-1.7.0 → tinybrain-1.8.0}/setup.cfg +0 -0
  24. {tinybrain-1.7.0 → tinybrain-1.8.0}/setup.py +0 -0
  25. {tinybrain-1.7.0 → tinybrain-1.8.0}/tinybrain/accelerated.pyx +0 -0
  26. {tinybrain-1.7.0 → tinybrain-1.8.0}/tinybrain.egg-info/SOURCES.txt +0 -0
  27. {tinybrain-1.7.0 → tinybrain-1.8.0}/tinybrain.egg-info/dependency_links.txt +0 -0
  28. {tinybrain-1.7.0 → tinybrain-1.8.0}/tinybrain.egg-info/not-zip-safe +0 -0
  29. {tinybrain-1.7.0 → tinybrain-1.8.0}/tinybrain.egg-info/requires.txt +0 -0
  30. {tinybrain-1.7.0 → tinybrain-1.8.0}/tinybrain.egg-info/top_level.txt +0 -0
  31. {tinybrain-1.7.0 → tinybrain-1.8.0}/tox.ini +0 -0
@@ -6,7 +6,7 @@ on:
6
6
  tags:
7
7
  - '*'
8
8
  env:
9
- CIBW_SKIP: pp* *-musllinux*
9
+ CIBW_SKIP: pp* cp315t*
10
10
 
11
11
  jobs:
12
12
  build_wheels:
@@ -14,21 +14,17 @@ jobs:
14
14
  runs-on: ${{ matrix.os }}
15
15
  strategy:
16
16
  matrix:
17
- os: [ubuntu-latest, windows-2019, macos-latest]
17
+ os: [ubuntu-latest, macos-latest, windows-latest]
18
18
  arch: [auto]
19
19
  include:
20
- - os: ubuntu-latest
20
+ - os: ubuntu-24.04-arm
21
21
  arch: aarch64
22
22
 
23
23
  steps:
24
24
  - uses: actions/checkout@v4
25
25
 
26
- - name: Set up QEMU
27
- if: ${{ matrix.arch == 'aarch64' }}
28
- uses: docker/setup-qemu-action@v1
29
-
30
26
  - name: Build wheels
31
- uses: joerick/cibuildwheel@v2.22.0
27
+ uses: joerick/cibuildwheel@v4.2.0
32
28
  # to supply options, put them in 'env', like:
33
29
  env:
34
30
  CIBW_BEFORE_BUILD: pip install numpy pybind11 setuptools wheel pkginfo twine
@@ -15,7 +15,7 @@ jobs:
15
15
  strategy:
16
16
  matrix:
17
17
  os: [ubuntu-latest, macos-latest, windows-latest]
18
- python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
18
+ python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"]
19
19
 
20
20
  steps:
21
21
  - name: Set up Python ${{ matrix.python-version }}
@@ -23,7 +23,7 @@ jobs:
23
23
  with:
24
24
  python-version: ${{ matrix.python-version }}
25
25
 
26
- - uses: actions/checkout@v2
26
+ - uses: actions/checkout@v7
27
27
 
28
28
  - name: Install dependencies
29
29
  run: |
@@ -1,6 +1,19 @@
1
1
  CHANGES
2
2
  =======
3
3
 
4
+ 1.8.0
5
+ -----
6
+
7
+ * ci: skip building cp315t
8
+ * release(1.8.0): support boolean images, faster 2x2x2 mode downsampling
9
+ * ci: update build
10
+ * fix: error and missing optimization
11
+ * test: add compliance test for end of 2x2x2
12
+ * docs: update performance numbers for 2x2x2 mode
13
+ * perf: faster 2x2x2 mode downsampling
14
+ * feat: support mode pooling for boolean images
15
+ * test: update benchmark with Macbook Pro M3 + add pillow, opencv
16
+
4
17
  1.7.0
5
18
  -----
6
19
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybrain
3
- Version: 1.7.0
3
+ Version: 1.8.0
4
4
  Summary: Image pyramid generation specialized for connectomics data types and procedures.
5
5
  Home-page: https://github.com/seung-lab/tinybrain/
6
6
  Author: William Silversmith
@@ -700,6 +700,21 @@ def test_sparse_2x2x2_mode_downsampling(dtype):
700
700
  assert res[0][0][0] == 0
701
701
  assert res.shape == (1,1,1)
702
702
 
703
+ test7 = np.array([
704
+ [
705
+ [1,2],
706
+ [3,4],
707
+ ],
708
+ [
709
+ [5,6],
710
+ [7,8],
711
+ ],
712
+ ], dtype=dtype, order='F')
713
+
714
+ res = tinybrain.accelerated.mode_pooling_2x2x2(test7, sparse=True)[0]
715
+ assert res[0][0][0] == 1
716
+ assert res.shape == (1,1,1)
717
+
703
718
  # test7 = np.array([
704
719
  # [
705
720
  # [1,0,1],
@@ -27,6 +27,26 @@
27
27
  # 2x2x2 1 mip sparse: 0.656s, 2041.96 MVx/sec, N=10
28
28
  # 2x2x2 2 mip sparse: 0.762s, 1758.42 MVx/sec, N=10
29
29
 
30
+ # Results on a 2023 Macbook Pro M3
31
+ # AVG POOLING ((2048, 2048, 64), uint8)
32
+ # 2x2 1 mip: 0.084s, 31954.51 MVx/sec, N=10
33
+ # 2x2 2 mip: 0.223s, 11995.13 MVx/sec, N=10
34
+ # 2x2x2 1 mip: 0.042s, 63958.66 MVx/sec, N=10
35
+ # 2x2x2 2 mip: 0.218s, 12303.19 MVx/sec, N=10
36
+ # 2x2x2 1 mip sparse: 0.581s, 4612.79 MVx/sec, N=10
37
+ # 2x2x2 2 mip sparse: 0.686s, 3908.00 MVx/sec, N=10
38
+ # 2x2 1 mip pillow: 10.526s, 254.61 MVx/sec, N=10
39
+ # 2x2 1 mip opencv: 5.352s, 500.79 MVx/sec, N=10
40
+ # MODE POOLING ((2048, 2048, 64), uint64)
41
+ # 2x2 1 mip: 1.030s, 2602.65 MVx/sec, N=10
42
+ # 2x2 2 mip: 1.181s, 2269.54 MVx/sec, N=10
43
+ # 2x2 1 mip sparse: 14.294s, 187.49 MVx/sec, N=10
44
+ # 2x2 2 mip sparse: 25.615s, 104.63 MVx/sec, N=10
45
+ # 2x2x2 1 mip: 3.171s, 845.10 MVx/sec, N=10
46
+ # 2x2x2 2 mip: 3.479s, 770.30 MVx/sec, N=10
47
+ # 2x2x2 1 mip sparse: 3.461s, 774.31 MVx/sec, N=10
48
+ # 2x2x2 2 mip sparse: 3.916s, 684.42 MVx/sec, N=10
49
+
30
50
  import numpy as np
31
51
  import tinybrain
32
52
  import time
@@ -80,6 +100,33 @@ def benchmark_avg_pooling():
80
100
  end = time.time()
81
101
  result("2x2x2 2 mip sparse", end - start, data, N)
82
102
 
103
+ try:
104
+ from PIL import Image
105
+ s = time.time()
106
+ out = np.zeros([1024,1024,64], dtype=np.uint8, order="F")
107
+ for _ in range(N):
108
+ for z in range(data.shape[2]):
109
+ pilimg = Image.fromarray(data[:,:,z])
110
+ out[:,:,z] = pilimg.resize( (1024, 1024) )
111
+ end = time.time()
112
+ result("2x2 1 mip pillow", end - start, data, N)
113
+ del out
114
+ except ImportError:
115
+ print("Pillow not installed.")
116
+
117
+ try:
118
+ import cv2
119
+ start = time.time()
120
+ out = np.zeros(shape=(1024,1024,64))
121
+ for _ in range(N):
122
+ for z in range(data.shape[2]):
123
+ out[:,:,z] = cv2.resize(data[:,:,z], dsize=(1024, 1024) )
124
+ end = time.time()
125
+ result("2x2 1 mip opencv", end - start, data, N)
126
+ del out
127
+ except ImportError:
128
+ print("opencv not installed.")
129
+
83
130
  def benchmark_mode_pooling():
84
131
  data = np.random.randint(1000,1255, size=(2048,2048,64), dtype=np.uint64)
85
132
  data = np.asfortranarray(data)
@@ -7,4 +7,4 @@ from .downsample import (
7
7
  DimensionError
8
8
  )
9
9
 
10
- __version__ = '1.4.1'
10
+ __version__ = '1.8.0'
@@ -1114,19 +1114,26 @@ inline void _mode_pooling_2x2x2(
1114
1114
  continue;
1115
1115
  }
1116
1116
 
1117
- max_ct = 0;
1118
- max_val = 0;
1119
- for (short int t = 0; t < 8; t++) {
1117
+ if (sparse && vals[0] == 0) {
1118
+ max_ct = 0;
1119
+ max_val = 0;
1120
+ }
1121
+ else {
1122
+ max_ct = 1;
1123
+ max_val = vals[0];
1124
+ }
1125
+
1126
+ // no need to evaluate t=0, as if max_ct
1127
+ // is 1 at the last entry, it can't go higher than
1128
+ // 1, so we'll just take the last entry as good
1129
+ for (short int t = 7; t >= 1; t--) {
1120
1130
  cur_val = vals[t];
1121
1131
  if (sparse && cur_val == 0) {
1122
1132
  continue;
1123
1133
  }
1124
1134
 
1125
1135
  cur_ct = 1;
1126
- for (short int p = 0; p < t; p++) {
1127
- cur_ct += (cur_val == vals[p]);
1128
- }
1129
- for (short int p = t + 1; p < 8; p++) {
1136
+ for (short int p = t-1; p >= 0; p--) {
1130
1137
  cur_ct += (cur_val == vals[p]);
1131
1138
  }
1132
1139
 
@@ -230,6 +230,11 @@ def downsample_segmentation(img, factor, sparse=False, num_mips=1):
230
230
  if np.all(np.array(factor, int) == 1):
231
231
  return [ img ] * num_mips
232
232
 
233
+ binary_image = isinstance(img, (bool, np.bool_))
234
+
235
+ if binary_image:
236
+ img = img.view(np.uint8)
237
+
233
238
  if tuple(factor) in ( (2,2), (2,2,1), (2,2,1,1) ) and not sparse:
234
239
  return tinybrain.accelerated.mode_pooling_2x2(img, num_mips=num_mips)
235
240
  elif tuple(factor) in ( (2,2,2), (2,2,2,1) ):
@@ -244,6 +249,10 @@ def downsample_segmentation(img, factor, sparse=False, num_mips=1):
244
249
  results.append(img)
245
250
 
246
251
  results = [ squeeze_dims(img, ndim) for img in results ]
252
+
253
+ if binary_image:
254
+ results = [ mip_img.view(bool) for mip_img in results ]
255
+
247
256
  return results
248
257
 
249
258
  def _downsample_segmentation(data, factor, sparse=False):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: tinybrain
3
- Version: 1.7.0
3
+ Version: 1.8.0
4
4
  Summary: Image pyramid generation specialized for connectomics data types and procedures.
5
5
  Home-page: https://github.com/seung-lab/tinybrain/
6
6
  Author: William Silversmith
@@ -0,0 +1 @@
1
+ {"git_version": "c656201", "is_release": true}
@@ -1 +0,0 @@
1
- {"git_version": "860d1fd", "is_release": true}
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes