loaderx 0.2.1__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: loaderx
3
- Version: 0.2.1
3
+ Version: 0.3.0
4
4
  Summary: A record-based data runtime, focused on delivering extreme throughput and low latency
5
5
  Author-email: Ben0i0d <ben0i0d@foxmail.com>
6
6
  License: MIT License
@@ -34,7 +34,7 @@ Classifier: Development Status :: 3 - Alpha
34
34
  Classifier: Intended Audience :: Developers
35
35
  Classifier: License :: OSI Approved :: MIT License
36
36
  Classifier: Programming Language :: Python :: 3
37
- Requires-Python: >=3.10
37
+ Requires-Python: ==3.13
38
38
  Description-Content-Type: text/markdown
39
39
  License-File: LICENSE
40
40
  Requires-Dist: numpy
@@ -45,7 +45,7 @@ Dynamic: license-file
45
45
  # loaderx
46
46
  A record-based data runtime, focused on delivering extreme throughput and low latency
47
47
 
48
- **Important Reminder**: Only support Linux_amd64. This is because we use a dynamic library built with Zig (we build and test it on Debian).
48
+ **Only Python3.13_Linux_amd64**
49
49
 
50
50
  ## Sampler
51
51
  a high-performance sampler implemented in Zig
@@ -1,7 +1,7 @@
1
1
  # loaderx
2
2
  A record-based data runtime, focused on delivering extreme throughput and low latency
3
3
 
4
- **Important Reminder**: Only support Linux_amd64. This is because we use a dynamic library built with Zig (we build and test it on Debian).
4
+ **Only Python3.13_Linux_amd64**
5
5
 
6
6
  ## Sampler
7
7
  a high-performance sampler implemented in Zig
@@ -2,4 +2,4 @@ from .dataset import BaseDataset, NPDataset, ARDataset
2
2
  from .dataloader import DataLoader
3
3
  from .utils import converter
4
4
 
5
- __version__ = "0.2.1"
5
+ __version__ = "0.3.0"
@@ -0,0 +1,69 @@
1
+ import os
2
+ import time
3
+ import ctypes
4
+ import numpy as np
5
+ from typing import Union
6
+
7
+ from lib import libsampler
8
+
9
+ class Sampler:
10
+ class Mode:
11
+ SEQUENTIAL = 0
12
+ IID = 1
13
+
14
+ def __init__(self, length: int, batch_size: int, mode: int, seed: int = 42):
15
+ # sampler
16
+ self.sampler = libsampler.Sampler.init(length, batch_size, mode, seed)
17
+ # indices
18
+ self.indices = np.zeros(batch_size, dtype=np.uint64)
19
+
20
+ # step
21
+ def next(self):
22
+ self.sampler.next(self.indices)
23
+
24
+ # iterator
25
+ def __iter__(self):
26
+ return self
27
+ def __next__(self):
28
+ self.next()
29
+ return self.indices
30
+
31
+ def run():
32
+ from itertools import islice
33
+ length = 10
34
+ batch_size = 4
35
+ n_steps = 5
36
+
37
+ print("=== Sampler SEQUENTIAL ===")
38
+ sampler = Sampler(length, batch_size, Sampler.Mode.SEQUENTIAL)
39
+ for indices in islice(sampler, n_steps):
40
+ print(indices)
41
+
42
+ print("=== Sampler IID ===")
43
+ sampler = Sampler(length, batch_size, Sampler.Mode.IID)
44
+ for indices in islice(sampler, n_steps):
45
+ print(indices)
46
+
47
+ # Benchmark, zig-sampler speeder 2.2x
48
+ def bench():
49
+ length = 1_000_000
50
+ batch_size = 8192
51
+ n_steps = 10_000
52
+
53
+ print("=== NumPy IID ===")
54
+ t0 = time.time()
55
+ batch = np.zeros(batch_size, dtype=np.uint64)
56
+ for _ in range(n_steps):
57
+ batch[:] = np.random.randint(0, length, size=batch_size, dtype=np.uint64)
58
+ print(f"{(time.time() - t0)*1000:.2f} ms")
59
+
60
+ print("=== Sampler IID ===")
61
+ t0 = time.time()
62
+ sampler = Sampler(length, batch_size, Sampler.Mode.IID)
63
+ for _ in range(n_steps):
64
+ sampler.next()
65
+ print(f"{(time.time() - t0)*1000:.2f} ms")
66
+
67
+ if __name__ == "__main__":
68
+ run()
69
+ bench()
@@ -47,8 +47,8 @@ class DataLoader:
47
47
  Sample indices from the dataset and put them into the index queue.
48
48
  """
49
49
  while not self.stop_signal.is_set():
50
- self.sampler.next()
51
- self.indices.put(self.sampler.batch_indices.copy())
50
+ self.sampler.next()
51
+ self.indices.put(self.sampler.indices.copy())
52
52
 
53
53
  def _prefetch(self, transform):
54
54
  """
Binary file
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: loaderx
3
- Version: 0.2.1
3
+ Version: 0.3.0
4
4
  Summary: A record-based data runtime, focused on delivering extreme throughput and low latency
5
5
  Author-email: Ben0i0d <ben0i0d@foxmail.com>
6
6
  License: MIT License
@@ -34,7 +34,7 @@ Classifier: Development Status :: 3 - Alpha
34
34
  Classifier: Intended Audience :: Developers
35
35
  Classifier: License :: OSI Approved :: MIT License
36
36
  Classifier: Programming Language :: Python :: 3
37
- Requires-Python: >=3.10
37
+ Requires-Python: ==3.13
38
38
  Description-Content-Type: text/markdown
39
39
  License-File: LICENSE
40
40
  Requires-Dist: numpy
@@ -45,7 +45,7 @@ Dynamic: license-file
45
45
  # loaderx
46
46
  A record-based data runtime, focused on delivering extreme throughput and low latency
47
47
 
48
- **Important Reminder**: Only support Linux_amd64. This is because we use a dynamic library built with Zig (we build and test it on Debian).
48
+ **Only Python3.13_Linux_amd64**
49
49
 
50
50
  ## Sampler
51
51
  a high-performance sampler implemented in Zig
@@ -7,7 +7,7 @@ name = "loaderx"
7
7
  dynamic = ["version"]
8
8
  description = "A record-based data runtime, focused on delivering extreme throughput and low latency"
9
9
  readme = "README.md"
10
- requires-python = ">=3.10"
10
+ requires-python = "==3.13"
11
11
  authors = [
12
12
  {name = "Ben0i0d", email = "ben0i0d@foxmail.com"},
13
13
  ]
@@ -1,114 +0,0 @@
1
- import os
2
- import time
3
- import ctypes
4
- import numpy as np
5
- from typing import Union
6
-
7
- class Sampler:
8
-
9
- class Mode:
10
- SEQUENTIAL = 0
11
- IID = 1
12
-
13
- # lazy import
14
- _lib = None
15
- @classmethod
16
- def _load_lib(cls):
17
- if cls._lib is None:
18
- # linux/windows/macos
19
- names = ['lib/libsampler.so', 'lib/sampler.dll', 'lib/libsampler.dylib']
20
- lib_paths = [os.path.join(os.path.dirname(__file__), name) for name in names]
21
-
22
- for path in lib_paths:
23
- if os.path.exists(path):
24
- cls._lib = ctypes.CDLL(path)
25
- cls._setup_function_signatures()
26
- return cls._lib
27
-
28
- @classmethod
29
- def _setup_function_signatures(cls):
30
- lib = cls._lib
31
-
32
- # init
33
- lib.init.argtypes = [
34
- ctypes.c_void_p, # sampler
35
- ctypes.c_uint64, # length
36
- ctypes.c_uint64, # batch_size
37
- ctypes.c_uint8, # mode
38
- ctypes.c_uint64 # seed
39
- ]
40
- lib.init.restype = None
41
-
42
- # size
43
- lib.size.restype = ctypes.c_size_t
44
-
45
- # next
46
- lib.next.argtypes = [
47
- ctypes.c_void_p, # sampler
48
- ctypes.c_void_p # batch_indices
49
- ]
50
- lib.next.restype = None
51
-
52
- def __init__(self, length: int, batch_size: int, mode: int, seed: int = 42):
53
- # import lib
54
- self.lib = self._load_lib()
55
-
56
- # sampler
57
- self.sampler = ctypes.create_string_buffer(self.lib.size())
58
- self.sampler_ptr = ctypes.cast(self.sampler, ctypes.c_void_p)
59
- self.lib.init(self.sampler_ptr, length, batch_size, mode, seed)
60
-
61
- # batch_indices
62
- self.indices = np.zeros(batch_size, dtype=np.uint64)
63
- self.indices_ptr = self.indices.ctypes.data
64
-
65
- # step
66
- def next(self):
67
- self.lib.next(self.sampler_ptr, self.indices_ptr)
68
-
69
- # iterator
70
- def __iter__(self):
71
- return self
72
- def __next__(self):
73
- self.next()
74
- return self.indices
75
-
76
- def run():
77
- from itertools import islice
78
- length = 10
79
- batch_size = 4
80
- n_steps = 5
81
-
82
- print("=== Sampler SEQUENTIAL ===")
83
- sampler = Sampler(length, batch_size, Sampler.Mode.SEQUENTIAL)
84
- for indices in islice(sampler, n_steps):
85
- print(indices)
86
-
87
- print("=== Sampler IID ===")
88
- sampler = Sampler(length, batch_size, Sampler.Mode.IID)
89
- for indices in islice(sampler, n_steps):
90
- print(indices)
91
-
92
- # Benchmark, zig-sampler speeder 2.2x
93
- def bench():
94
- length = 1_000_000
95
- batch_size = 8192
96
- n_steps = 10_000
97
-
98
- print("=== NumPy IID ===")
99
- t0 = time.time()
100
- batch = np.zeros(batch_size, dtype=np.uint64)
101
- for _ in range(n_steps):
102
- batch[:] = np.random.randint(0, length, size=batch_size, dtype=np.uint64)
103
- print(f"{(time.time() - t0)*1000:.2f} ms")
104
-
105
- print("=== Sampler IID ===")
106
- t0 = time.time()
107
- sampler = Sampler(length, batch_size, Sampler.Mode.IID)
108
- for _ in range(n_steps):
109
- sampler.next()
110
- print(f"{(time.time() - t0)*1000:.2f} ms")
111
-
112
- if __name__ == "__main__":
113
- run()
114
- bench()
Binary file
File without changes
File without changes
File without changes
File without changes