/
_primesieve.pyx
205 lines (168 loc) · 7.02 KB
/
_primesieve.pyx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
# cython: language_level=3
import array
from libc.stdint cimport uint64_t, int64_t
from libcpp.string cimport string
import sys
from primesieve cimport cpp_primesieve
__all__ = [
'Iterator',
'arr_type',
'count_primes',
'count_quadruplets',
'count_quintuplets',
'count_sextuplets',
'count_triplets',
'count_twins',
'get_max_stop',
'get_num_threads',
'get_sieve_size',
'n_primes',
'nth_prime',
'primes',
'primesieve_version',
'print_primes',
'print_quadruplets',
'print_quintuplets',
'print_sextuplets',
'print_triplets',
'print_twins',
'set_num_threads',
'set_sieve_size',
]
cdef extern from "primesieve.h":
cdef enum:
INT64_PRIMES
ULONG_PRIMES
ULONGLONG_PRIMES
cdef extern from 'errno.h':
int errno
cdef int is_py3 = sys.version_info >= (3,)
arr_type = ("Q" if is_py3 else "L")
cdef size_t item_size = (sizeof(unsigned long long) if is_py3 else sizeof(unsigned long))
cdef int primes_type = (ULONGLONG_PRIMES if is_py3 else ULONG_PRIMES)
cdef c_to_array_array(void* ptr, size_t N):
"""Create a python array from a C array."""
arr = array.array(arr_type, (<char*>ptr)[:(N*item_size)])
return arr
cpdef primes(uint64_t from_limit, uint64_t to_limit = 0) except +:
"""Generate a primes array from from_limit to to_limit (or up to
from_limit if to_limit is unspecified or 0.)"""
from_limit = max(from_limit, 0)
to_limit = max(to_limit, 0)
if to_limit == 0:
(from_limit,to_limit) = (0,from_limit)
# Rest errno
global errno
errno = 0
cdef size_t size = 0
cdef void* c_primes = cpp_primesieve.primesieve_generate_primes(from_limit, to_limit, &size, primes_type)
if errno != 0:
raise RuntimeError("Failed to generate primes, most likely due to insufficient memory.")
primes = c_to_array_array(c_primes, size)
cpp_primesieve.primesieve_free(c_primes)
return primes
cpdef n_primes(uint64_t n, uint64_t start = 0) except +:
"""List the first n primes >= start."""
n = max(n, 0)
start = max(start, 0)
# Rest errno
global errno
errno = 0
cdef void* c_primes = cpp_primesieve.primesieve_generate_n_primes(n, start, primes_type)
if errno != 0:
raise RuntimeError("Failed to generate primes, most likely due to insufficient memory.")
primes = c_to_array_array(c_primes, n)
cpp_primesieve.primesieve_free(c_primes)
return primes
cpdef uint64_t nth_prime(int64_t n, uint64_t start = 0) except +:
"""Find the nth prime > start"""
return cpp_primesieve.nth_prime(n, start)
cpdef uint64_t count_primes(uint64_t from_limit, uint64_t to_limit = 0) except +:
"""Count the prime numbers from from_limit to to_limit (or up to
from_limit if to_limit is unspecified or 0.)"""
if to_limit == 0:
(from_limit,to_limit) = (0,from_limit)
return cpp_primesieve.count_primes(from_limit, to_limit)
cpdef uint64_t count_twins(uint64_t from_limit, uint64_t to_limit = 0) except +:
"""Count twin primes """
if to_limit == 0:
(from_limit,to_limit) = (0,from_limit)
return cpp_primesieve.count_twins(from_limit, to_limit)
cpdef uint64_t count_triplets(uint64_t from_limit, uint64_t to_limit = 0) except +:
"""Count prime triplets """
if to_limit == 0:
(from_limit,to_limit) = (0,from_limit)
return cpp_primesieve.count_triplets(from_limit, to_limit)
cpdef uint64_t count_quadruplets(uint64_t from_limit, uint64_t to_limit = 0) except +:
"""Count prime quadruplets """
if to_limit == 0:
(from_limit,to_limit) = (0,from_limit)
return cpp_primesieve.count_quadruplets(from_limit, to_limit)
cpdef uint64_t count_quintuplets(uint64_t from_limit, uint64_t to_limit = 0) except +:
"""Count prime quintuplets """
if to_limit == 0:
(from_limit,to_limit) = (0,from_limit)
return cpp_primesieve.count_quintuplets(from_limit, to_limit)
cpdef uint64_t count_sextuplets(uint64_t from_limit, uint64_t to_limit = 0) except +:
"""Count prime sextuplets """
if to_limit == 0:
(from_limit,to_limit) = (0,from_limit)
return cpp_primesieve.count_sextuplets(from_limit, to_limit)
cpdef void print_primes(uint64_t from_limit, uint64_t to_limit = 0) except +:
"""Print prime numbers to stdout"""
if to_limit == 0:
(from_limit,to_limit) = (0,from_limit)
cpp_primesieve.print_primes(from_limit, to_limit)
cpdef void print_twins(uint64_t from_limit, uint64_t to_limit = 0) except +:
"""Print twin primes to stdout"""
if to_limit == 0:
(from_limit,to_limit) = (0,from_limit)
cpp_primesieve.print_twins(from_limit, to_limit)
cpdef void print_triplets(uint64_t from_limit, uint64_t to_limit = 0) except +:
"""Print prime triplets to stdout"""
if to_limit == 0:
(from_limit,to_limit) = (0,from_limit)
cpp_primesieve.print_triplets(from_limit, to_limit)
cpdef void print_quadruplets(uint64_t from_limit, uint64_t to_limit = 0) except +:
"""Print prime quadruplets to stdout"""
if to_limit == 0:
(from_limit,to_limit) = (0,from_limit)
cpp_primesieve.print_quadruplets(from_limit, to_limit)
cpdef void print_quintuplets(uint64_t from_limit, uint64_t to_limit = 0) except +:
"""Print prime quintuplets to stdout"""
if to_limit == 0:
(from_limit,to_limit) = (0,from_limit)
cpp_primesieve.print_quintuplets(from_limit, to_limit)
cpdef void print_sextuplets(uint64_t from_limit, uint64_t to_limit = 0) except +:
"""Print prime sextuplets to stdout"""
if to_limit == 0:
(from_limit,to_limit) = (0,from_limit)
cpp_primesieve.print_sextuplets(from_limit, to_limit)
cpdef uint64_t get_max_stop() except +:
"""Returns the largest valid stop number for primesieve. 2^64-1 (UINT64_MAX)"""
return cpp_primesieve.get_max_stop()
cpdef int get_sieve_size() except +:
"""Get the current set sieve size in KiB"""
return cpp_primesieve.get_sieve_size()
cpdef int get_num_threads() except +:
"""Get the currently set number of threads"""
return cpp_primesieve.get_num_threads()
cpdef void set_sieve_size(int sieve_size) except +:
"""Set the sieve size in KiB (kibibyte). The best sieving performance is achieved with a sieve size of your CPU's L1 or L2 cache size (per core)."""
cpp_primesieve.set_sieve_size(sieve_size)
cpdef void set_num_threads(int threads) except +:
"""Set the number of threads for sieving"""
cpp_primesieve.set_num_threads(threads)
cpdef string primesieve_version() except +:
"""Get the primesieve version number"""
return cpp_primesieve.primesieve_version()
cdef class Iterator:
cdef cpp_primesieve.iterator _iterator
def __cinit__(self):
self._iterator = cpp_primesieve.iterator()
cpdef void skipto(self, uint64_t start, uint64_t stop_hint = 2**62) except +:
cpp_primesieve.iterator_jumpto(self._iterator, start+1, stop_hint)
cpdef uint64_t next_prime(self) except +:
return self._iterator.next_prime()
cpdef uint64_t prev_prime(self) except +:
return self._iterator.prev_prime()