klongpy 0.6.8__py3-none-any.whl → 0.7.0__py3-none-any.whl
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.
- klongpy/__init__.py +19 -1
- klongpy/adverbs.py +5 -5
- klongpy/autograd.py +308 -0
- klongpy/backend.py +167 -99
- klongpy/backends/__init__.py +94 -0
- klongpy/backends/base.py +320 -0
- klongpy/backends/numpy_backend.py +122 -0
- klongpy/backends/torch_backend.py +995 -0
- klongpy-0.6.8.data/scripts/kgpy → klongpy/cli.py +65 -88
- klongpy/core.py +228 -106
- klongpy/db/sys_fn_db.py +4 -3
- klongpy/dyads.py +173 -32
- klongpy/interpreter.py +31 -3
- klongpy/lib/help.kg +2 -2
- klongpy/monads.py +49 -12
- klongpy/repl.py +91 -0
- klongpy/sys_fn.py +129 -18
- klongpy/sys_fn_autograd.py +290 -0
- klongpy/sys_fn_ipc.py +18 -7
- klongpy/sys_fn_timer.py +13 -3
- klongpy/web/sys_fn_web.py +28 -6
- klongpy-0.7.0.dist-info/METADATA +493 -0
- klongpy-0.7.0.dist-info/RECORD +48 -0
- {klongpy-0.6.8.dist-info → klongpy-0.7.0.dist-info}/WHEEL +1 -1
- klongpy-0.7.0.dist-info/entry_points.txt +2 -0
- {klongpy-0.6.8.dist-info → klongpy-0.7.0.dist-info}/top_level.txt +0 -1
- klongpy-0.6.8.dist-info/METADATA +0 -412
- klongpy-0.6.8.dist-info/RECORD +0 -72
- tests/__init__.py +0 -6
- tests/gen_join_over.py +0 -119
- tests/gen_py_suite.py +0 -77
- tests/gen_test_fn.py +0 -259
- tests/perf_async.py +0 -25
- tests/perf_avg.py +0 -18
- tests/perf_duckdb.py +0 -32
- tests/perf_gen.py +0 -38
- tests/perf_ipc_overhead.py +0 -34
- tests/perf_join.py +0 -53
- tests/perf_load.py +0 -17
- tests/perf_prog.py +0 -18
- tests/perf_serdes.py +0 -52
- tests/perf_sys_fn_db.py +0 -263
- tests/perf_vector.py +0 -40
- tests/test_accel.py +0 -227
- tests/test_df_cache.py +0 -85
- tests/test_examples.py +0 -64
- tests/test_extra_suite.py +0 -382
- tests/test_file_cache.py +0 -185
- tests/test_interop.py +0 -181
- tests/test_kgtests.py +0 -65
- tests/test_known_bugs.py +0 -206
- tests/test_prog.py +0 -107
- tests/test_suite.py +0 -1479
- tests/test_suite_file.py +0 -153
- tests/test_sys_fn.py +0 -420
- tests/test_sys_fn_db.py +0 -88
- tests/test_sys_fn_ipc.py +0 -587
- tests/test_sys_fn_timer.py +0 -133
- tests/test_util.py +0 -233
- tests/utils.py +0 -126
- {klongpy-0.6.8.dist-info → klongpy-0.7.0.dist-info/licenses}/LICENSE +0 -0
tests/perf_sys_fn_db.py
DELETED
|
@@ -1,263 +0,0 @@
|
|
|
1
|
-
import time
|
|
2
|
-
import unittest
|
|
3
|
-
|
|
4
|
-
from utils import *
|
|
5
|
-
|
|
6
|
-
from klongpy import KlongInterpreter
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def run_lines(s, klong=None):
|
|
10
|
-
klong = klong or KlongInterpreter()
|
|
11
|
-
for line in s.splitlines():
|
|
12
|
-
r = klong(line)
|
|
13
|
-
return r
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
def time_sql(klong, sql):
|
|
17
|
-
start_t = time.time()
|
|
18
|
-
try:
|
|
19
|
-
return klong(sql)
|
|
20
|
-
finally:
|
|
21
|
-
print(sql, " : ", time.time() - start_t)
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def perf_single_col_no_pre_alloc():
|
|
25
|
-
s = """
|
|
26
|
-
.py("klongpy.db")
|
|
27
|
-
a::[]
|
|
28
|
-
|
|
29
|
-
e::[]
|
|
30
|
-
e::e,,"a",,a
|
|
31
|
-
t::.table(e)
|
|
32
|
-
|
|
33
|
-
q:::{}
|
|
34
|
-
q,"T",,t
|
|
35
|
-
db::.db(q)
|
|
36
|
-
"""
|
|
37
|
-
klong = KlongInterpreter()
|
|
38
|
-
klong(s)
|
|
39
|
-
klong("tfn::{[t0];t0::.pc();x@[];.pc()-t0}")
|
|
40
|
-
klong("afn::{{.insert(t; x)}'!10000}")
|
|
41
|
-
r = klong("tfn(afn)")
|
|
42
|
-
pr = r / 10000
|
|
43
|
-
print("single col (no index) (no pre alloc)", r, pr, int(1/pr))
|
|
44
|
-
r = time_sql(klong, 'db("select count(*) from T")')
|
|
45
|
-
assert r == 10000
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
def perf_single_index_no_pre_alloc():
|
|
49
|
-
s = """
|
|
50
|
-
.py("klongpy.db")
|
|
51
|
-
a::[]
|
|
52
|
-
|
|
53
|
-
e::[]
|
|
54
|
-
e::e,,"a",,a
|
|
55
|
-
t::.table(e)
|
|
56
|
-
|
|
57
|
-
.index(t;["a"])
|
|
58
|
-
|
|
59
|
-
q:::{}
|
|
60
|
-
q,"T",,t
|
|
61
|
-
db::.db(q)
|
|
62
|
-
"""
|
|
63
|
-
klong = KlongInterpreter()
|
|
64
|
-
klong(s)
|
|
65
|
-
klong("tfn::{[t0];t0::.pc();x@[];.pc()-t0}")
|
|
66
|
-
klong("afn::{{.insert(t; x)}'!10000}")
|
|
67
|
-
r = klong("tfn(afn)")
|
|
68
|
-
pr = r / 10000
|
|
69
|
-
print("single col (index) (no pre alloc)", r, pr, int(1/pr))
|
|
70
|
-
r = time_sql(klong, 'db("select count(*) from T")')
|
|
71
|
-
assert r == 10000
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
def perf_single_col_index_pre_alloc():
|
|
75
|
-
s = """
|
|
76
|
-
.py("klongpy.db")
|
|
77
|
-
a::!10000
|
|
78
|
-
|
|
79
|
-
e::[]
|
|
80
|
-
e::e,,"a",,a
|
|
81
|
-
t::.table(e)
|
|
82
|
-
|
|
83
|
-
.index(t;["a"])
|
|
84
|
-
|
|
85
|
-
q:::{}
|
|
86
|
-
q,"T",,t
|
|
87
|
-
db::.db(q)
|
|
88
|
-
"""
|
|
89
|
-
klong = KlongInterpreter()
|
|
90
|
-
klong(s)
|
|
91
|
-
klong("tfn::{[t0];t0::.pc();x@[];.pc()-t0}")
|
|
92
|
-
klong("afn::{{.insert(t; x)}'!10000}")
|
|
93
|
-
r = klong("tfn(afn)")
|
|
94
|
-
pr = r / 10000
|
|
95
|
-
print("single col (index) (pre alloc)", r, pr, int(1/pr))
|
|
96
|
-
r = time_sql(klong, 'db("select count(*) from T")')
|
|
97
|
-
assert r == 10000
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
def perf_multi_col():
|
|
101
|
-
s = """
|
|
102
|
-
.py("klongpy.db")
|
|
103
|
-
a::[]
|
|
104
|
-
b::[]
|
|
105
|
-
c::[]
|
|
106
|
-
|
|
107
|
-
e::[]
|
|
108
|
-
e::e,,"a",,a
|
|
109
|
-
e::e,,"b",,b
|
|
110
|
-
e::e,,"c",,c
|
|
111
|
-
t::.table(e)
|
|
112
|
-
|
|
113
|
-
q:::{}
|
|
114
|
-
q,"T",,t
|
|
115
|
-
db::.db(q)
|
|
116
|
-
"""
|
|
117
|
-
klong = KlongInterpreter()
|
|
118
|
-
klong(s)
|
|
119
|
-
klong("tfn::{[t0];t0::.pc();x@[];.pc()-t0}")
|
|
120
|
-
klong("afn::{{.insert(t; x,x,x)}'!10000}")
|
|
121
|
-
r = klong("tfn(afn)")
|
|
122
|
-
pr = r / 10000
|
|
123
|
-
print("multi col (no index) (no pre alloc)", r, pr, int(1/pr))
|
|
124
|
-
r = time_sql(klong, 'db("select count(*) from T")')
|
|
125
|
-
assert r == 10000
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
def perf_multi_col_single_index():
|
|
129
|
-
s = """
|
|
130
|
-
.py("klongpy.db")
|
|
131
|
-
a::[]
|
|
132
|
-
b::[]
|
|
133
|
-
c::[]
|
|
134
|
-
|
|
135
|
-
e::[]
|
|
136
|
-
e::e,,"a",,a
|
|
137
|
-
e::e,,"b",,b
|
|
138
|
-
e::e,,"c",,c
|
|
139
|
-
t::.table(e)
|
|
140
|
-
|
|
141
|
-
.index(t;["a"])
|
|
142
|
-
|
|
143
|
-
q:::{}
|
|
144
|
-
q,"T",,t
|
|
145
|
-
db::.db(q)
|
|
146
|
-
"""
|
|
147
|
-
klong = KlongInterpreter()
|
|
148
|
-
klong(s)
|
|
149
|
-
klong("tfn::{[t0];t0::.pc();x@[];.pc()-t0}")
|
|
150
|
-
klong("afn::{{.insert(t; x,x,x)}'!10000}")
|
|
151
|
-
klong("bfn::{{.insert(t; x,x,x)}'10000+!10}")
|
|
152
|
-
r = klong("tfn(afn)")
|
|
153
|
-
pr = r / 10000
|
|
154
|
-
print("multi col (single index) (no pre alloc)", r, pr, int(1/pr))
|
|
155
|
-
r = time_sql(klong, 'db("select count(*) from T")')
|
|
156
|
-
assert r == 10000
|
|
157
|
-
r = klong("tfn(bfn)")
|
|
158
|
-
pr = r / 10
|
|
159
|
-
print("multi col (single index) (no pre alloc) [10]", r, pr, int(1/pr))
|
|
160
|
-
r = time_sql(klong, 'db("select count(*) from T")')
|
|
161
|
-
assert r == 10010
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
def perf_multi_col_single_index_pre_alloc():
|
|
166
|
-
s = """
|
|
167
|
-
.py("klongpy.db")
|
|
168
|
-
a::!10000
|
|
169
|
-
b::!10000
|
|
170
|
-
c::!10000
|
|
171
|
-
|
|
172
|
-
e::[]
|
|
173
|
-
e::e,,"a",,a
|
|
174
|
-
e::e,,"b",,b
|
|
175
|
-
e::e,,"c",,c
|
|
176
|
-
t::.table(e)
|
|
177
|
-
|
|
178
|
-
.index(t;["a"])
|
|
179
|
-
|
|
180
|
-
q:::{}
|
|
181
|
-
q,"T",,t
|
|
182
|
-
db::.db(q)
|
|
183
|
-
"""
|
|
184
|
-
klong = KlongInterpreter()
|
|
185
|
-
klong(s)
|
|
186
|
-
klong("tfn::{[t0];t0::.pc();x@[];.pc()-t0}")
|
|
187
|
-
klong("afn::{{.insert(t; x,x,x)}'!10000}")
|
|
188
|
-
r = klong("tfn(afn)")
|
|
189
|
-
pr = r / 10000
|
|
190
|
-
print("multi col (single index) (pre alloc)", r, pr, int(1/pr))
|
|
191
|
-
r = time_sql(klong, 'db("select count(*) from T")')
|
|
192
|
-
assert r == 10000
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
def perf_multi_col_multi_index():
|
|
196
|
-
s = """
|
|
197
|
-
.py("klongpy.db")
|
|
198
|
-
a::[]
|
|
199
|
-
b::[]
|
|
200
|
-
c::[]
|
|
201
|
-
|
|
202
|
-
e::[]
|
|
203
|
-
e::e,,"a",,a
|
|
204
|
-
e::e,,"b",,b
|
|
205
|
-
e::e,,"c",,c
|
|
206
|
-
t::.table(e)
|
|
207
|
-
|
|
208
|
-
.index(t;["a" "b"])
|
|
209
|
-
|
|
210
|
-
q:::{}
|
|
211
|
-
q,"T",,t
|
|
212
|
-
db::.db(q)
|
|
213
|
-
"""
|
|
214
|
-
klong = KlongInterpreter()
|
|
215
|
-
klong(s)
|
|
216
|
-
klong("tfn::{[t0];t0::.pc();x@[];.pc()-t0}")
|
|
217
|
-
klong("afn::{{.insert(t; x,x,x)}'!10000}")
|
|
218
|
-
r = klong("tfn(afn)")
|
|
219
|
-
pr = r / 10000
|
|
220
|
-
print("multi col (multi index) (no pre alloc)", r, pr, int(1/pr))
|
|
221
|
-
r = time_sql(klong, 'db("select count(*) from T")')
|
|
222
|
-
assert r == 10000
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
def perf_multi_col_multi_index_pre_alloc():
|
|
226
|
-
s = """
|
|
227
|
-
.py("klongpy.db")
|
|
228
|
-
a::!10000
|
|
229
|
-
b::!10000
|
|
230
|
-
c::!10000
|
|
231
|
-
|
|
232
|
-
e::[]
|
|
233
|
-
e::e,,"a",,a
|
|
234
|
-
e::e,,"b",,b
|
|
235
|
-
e::e,,"c",,c
|
|
236
|
-
t::.table(e)
|
|
237
|
-
|
|
238
|
-
.index(t;["a" "b"])
|
|
239
|
-
|
|
240
|
-
q:::{}
|
|
241
|
-
q,"T",,t
|
|
242
|
-
db::.db(q)
|
|
243
|
-
"""
|
|
244
|
-
klong = KlongInterpreter()
|
|
245
|
-
klong(s)
|
|
246
|
-
klong("tfn::{[t0];t0::.pc();x@[];.pc()-t0}")
|
|
247
|
-
klong("afn::{{.insert(t; x,x,x)}'!10000}")
|
|
248
|
-
r = klong("tfn(afn)")
|
|
249
|
-
pr = r / 10000
|
|
250
|
-
print("multi col (multi index) (pre alloc)", r, pr, int(1/pr))
|
|
251
|
-
r = time_sql(klong, 'db("select count(*) from T")')
|
|
252
|
-
assert r == 10000
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
if __name__ == "__main__":
|
|
256
|
-
perf_single_col_no_pre_alloc()
|
|
257
|
-
perf_single_index_no_pre_alloc()
|
|
258
|
-
perf_single_col_index_pre_alloc()
|
|
259
|
-
perf_multi_col()
|
|
260
|
-
perf_multi_col_single_index()
|
|
261
|
-
perf_multi_col_single_index_pre_alloc()
|
|
262
|
-
perf_multi_col_multi_index()
|
|
263
|
-
perf_multi_col_multi_index_pre_alloc()
|
tests/perf_vector.py
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import timeit
|
|
3
|
-
|
|
4
|
-
import numpy as np
|
|
5
|
-
|
|
6
|
-
from klongpy import KlongInterpreter
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
def numpy_vec(number=100):
|
|
10
|
-
r = timeit.timeit(lambda: np.multiply(np.add(np.arange(10000000), 1), 2), number=number)
|
|
11
|
-
return r/number
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
def klong_vec(number=100):
|
|
15
|
-
klong = KlongInterpreter()
|
|
16
|
-
r = timeit.timeit(lambda: klong("2*1+!10000000"), number=number)
|
|
17
|
-
return r/number
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
def python_vec(number=100):
|
|
21
|
-
r = timeit.timeit(lambda: [2 * (1 + x) for x in range(10000000)], number=number)
|
|
22
|
-
return r/number
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
if __name__ == "__main__":
|
|
26
|
-
number = 1000
|
|
27
|
-
print("Python: ", end='')
|
|
28
|
-
pr = python_vec(number=number)
|
|
29
|
-
print(f"{round(pr,6)}s")
|
|
30
|
-
|
|
31
|
-
print(f"KlongPy USE_GPU={os.environ.get('USE_GPU')}: ", end='')
|
|
32
|
-
kr = klong_vec(number=number)
|
|
33
|
-
print(f"{round(kr,6)}s")
|
|
34
|
-
|
|
35
|
-
print("Numpy: ", end='')
|
|
36
|
-
nr = numpy_vec(number=number)
|
|
37
|
-
print(f"{round(nr,6)}s")
|
|
38
|
-
|
|
39
|
-
print(f"Python / KlongPy => {round(pr/kr,6)}")
|
|
40
|
-
print(f"Numpy / KlongPy => {round(nr/kr,6)}")
|
tests/test_accel.py
DELETED
|
@@ -1,227 +0,0 @@
|
|
|
1
|
-
import unittest
|
|
2
|
-
from klongpy import KlongInterpreter
|
|
3
|
-
from utils import *
|
|
4
|
-
from klongpy.backend import np
|
|
5
|
-
import numpy
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Executed:
|
|
9
|
-
def __init__(self, fn):
|
|
10
|
-
self.fn = fn
|
|
11
|
-
self.executed = False
|
|
12
|
-
|
|
13
|
-
def __call__(self, *args, **kwargs):
|
|
14
|
-
self.executed = True
|
|
15
|
-
return self.fn(*args, **kwargs)
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
class ExecutedReduce:
|
|
19
|
-
def __init__(self, fn):
|
|
20
|
-
self.fn = fn
|
|
21
|
-
self.executed = False
|
|
22
|
-
|
|
23
|
-
def reduce(self, *args, **kwargs):
|
|
24
|
-
self.executed = True
|
|
25
|
-
return self.fn.reduce(*args, **kwargs)
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
def get_rnd_nested_array():
|
|
29
|
-
return np.asarray([np.random.rand(100), np.random.rand(100)])
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
def get_rnd_array():
|
|
33
|
-
return np.random.rand(100)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
def get_reduce_data(data):
|
|
37
|
-
return data if isinstance(data, numpy.ndarray) else data.get()
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
# This approach isn't great because any usage of the thunked method will pass
|
|
41
|
-
# We need a way to intercept the real call
|
|
42
|
-
class TestAccelerate(unittest.TestCase):
|
|
43
|
-
"""
|
|
44
|
-
Verify that we are actually running the adverb_over accelerated paths for cases that we can.
|
|
45
|
-
"""
|
|
46
|
-
|
|
47
|
-
# TODO: this is not parallel test safe
|
|
48
|
-
# add ability to intercept calls in interpeter
|
|
49
|
-
def test_over_add_nested_array(self):
|
|
50
|
-
klong = KlongInterpreter()
|
|
51
|
-
e = ExecutedReduce(np.add)
|
|
52
|
-
data = get_rnd_nested_array()
|
|
53
|
-
try:
|
|
54
|
-
np.add = e
|
|
55
|
-
klong['data'] = data
|
|
56
|
-
r = klong('+/data')
|
|
57
|
-
finally:
|
|
58
|
-
np.add = e.fn
|
|
59
|
-
self.assertTrue(kg_equal(r, numpy.add.reduce(get_reduce_data(data))))
|
|
60
|
-
self.assertTrue(e.executed)
|
|
61
|
-
|
|
62
|
-
def test_over_add_array(self):
|
|
63
|
-
klong = KlongInterpreter()
|
|
64
|
-
e = ExecutedReduce(np.add)
|
|
65
|
-
data = get_rnd_array()
|
|
66
|
-
try:
|
|
67
|
-
np.add = e
|
|
68
|
-
klong['data'] = data
|
|
69
|
-
r = klong('+/data')
|
|
70
|
-
finally:
|
|
71
|
-
np.add = e.fn
|
|
72
|
-
self.assertTrue(np.isclose(r, numpy.add.reduce(get_reduce_data(data))))
|
|
73
|
-
self.assertTrue(e.executed)
|
|
74
|
-
|
|
75
|
-
####### Subtract
|
|
76
|
-
|
|
77
|
-
def test_over_subtract_nested_array(self):
|
|
78
|
-
klong = KlongInterpreter()
|
|
79
|
-
e = ExecutedReduce(np.subtract)
|
|
80
|
-
data = get_rnd_nested_array()
|
|
81
|
-
try:
|
|
82
|
-
np.subtract = e
|
|
83
|
-
klong['data'] = data
|
|
84
|
-
r = klong('-/data')
|
|
85
|
-
finally:
|
|
86
|
-
np.subtract = e.fn
|
|
87
|
-
self.assertTrue(kg_equal(r, numpy.subtract.reduce(get_reduce_data(data))))
|
|
88
|
-
self.assertTrue(e.executed)
|
|
89
|
-
|
|
90
|
-
def test_over_subtract(self):
|
|
91
|
-
klong = KlongInterpreter()
|
|
92
|
-
e = ExecutedReduce(np.subtract)
|
|
93
|
-
data = get_rnd_array()
|
|
94
|
-
try:
|
|
95
|
-
np.subtract = e
|
|
96
|
-
klong['data'] = data
|
|
97
|
-
r = klong('-/data')
|
|
98
|
-
finally:
|
|
99
|
-
np.subtract = e.fn
|
|
100
|
-
self.assertTrue(numpy.isclose(r, numpy.subtract.reduce(get_reduce_data(data))))
|
|
101
|
-
self.assertTrue(e.executed)
|
|
102
|
-
|
|
103
|
-
####### Multiply
|
|
104
|
-
|
|
105
|
-
def test_over_multiply_nested_array(self):
|
|
106
|
-
klong = KlongInterpreter()
|
|
107
|
-
e = ExecutedReduce(np.multiply)
|
|
108
|
-
data = get_rnd_nested_array()
|
|
109
|
-
try:
|
|
110
|
-
np.multiply = e
|
|
111
|
-
klong['data'] = data
|
|
112
|
-
r = klong('*/data')
|
|
113
|
-
finally:
|
|
114
|
-
np.multiply = e.fn
|
|
115
|
-
self.assertTrue(kg_equal(r, numpy.multiply.reduce(get_reduce_data(data))))
|
|
116
|
-
self.assertTrue(e.executed)
|
|
117
|
-
|
|
118
|
-
def test_over_multipy(self):
|
|
119
|
-
klong = KlongInterpreter()
|
|
120
|
-
e = ExecutedReduce(np.multiply)
|
|
121
|
-
data = get_rnd_array()
|
|
122
|
-
try:
|
|
123
|
-
np.multiply = e
|
|
124
|
-
klong['data'] = data
|
|
125
|
-
r = klong('*/data')
|
|
126
|
-
finally:
|
|
127
|
-
np.multiply = e.fn
|
|
128
|
-
self.assertTrue(numpy.isclose(r, numpy.multiply.reduce(get_reduce_data(data))))
|
|
129
|
-
self.assertTrue(e.executed)
|
|
130
|
-
|
|
131
|
-
####### Divide
|
|
132
|
-
|
|
133
|
-
def test_over_divide_nested_array(self):
|
|
134
|
-
klong = KlongInterpreter()
|
|
135
|
-
e = ExecutedReduce(np.divide)
|
|
136
|
-
data = get_rnd_nested_array()
|
|
137
|
-
try:
|
|
138
|
-
np.divide = e
|
|
139
|
-
klong['data'] = data
|
|
140
|
-
r = klong('%/data')
|
|
141
|
-
finally:
|
|
142
|
-
np.divide = e.fn
|
|
143
|
-
self.assertTrue(kg_equal(r, numpy.divide.reduce(get_reduce_data(data))))
|
|
144
|
-
self.assertTrue(e.executed)
|
|
145
|
-
|
|
146
|
-
def test_over_divide(self):
|
|
147
|
-
if np != numpy:
|
|
148
|
-
return
|
|
149
|
-
if not hasattr(np.divide, "reduce"):
|
|
150
|
-
return
|
|
151
|
-
klong = KlongInterpreter()
|
|
152
|
-
e = ExecutedReduce(np.divide)
|
|
153
|
-
data = get_rnd_array()
|
|
154
|
-
try:
|
|
155
|
-
np.divide = e
|
|
156
|
-
klong['data'] = data
|
|
157
|
-
r = klong('%/data')
|
|
158
|
-
finally:
|
|
159
|
-
np.divide = e.fn
|
|
160
|
-
self.assertTrue(numpy.isclose(r, numpy.divide.reduce(get_reduce_data(data))))
|
|
161
|
-
self.assertTrue(e.executed)
|
|
162
|
-
|
|
163
|
-
####### Min
|
|
164
|
-
|
|
165
|
-
def test_over_min_nested_arrays(self):
|
|
166
|
-
klong = KlongInterpreter()
|
|
167
|
-
e = Executed(np.min)
|
|
168
|
-
try:
|
|
169
|
-
np.min = e
|
|
170
|
-
r = klong('&/[[1 2 3] [4 5 6]]')
|
|
171
|
-
finally:
|
|
172
|
-
np.min = e.fn
|
|
173
|
-
self.assertTrue(kg_equal(r, [1,2,3]))
|
|
174
|
-
self.assertFalse(e.executed)
|
|
175
|
-
|
|
176
|
-
def test_over_min(self):
|
|
177
|
-
klong = KlongInterpreter()
|
|
178
|
-
e = Executed(np.min)
|
|
179
|
-
try:
|
|
180
|
-
np.min = e
|
|
181
|
-
r = klong('&/[1 2 3 4]')
|
|
182
|
-
finally:
|
|
183
|
-
np.min = e.fn
|
|
184
|
-
self.assertEqual(r, 1)
|
|
185
|
-
self.assertTrue(e.executed)
|
|
186
|
-
|
|
187
|
-
####### Max
|
|
188
|
-
|
|
189
|
-
def test_over_max_nested_arrays(self):
|
|
190
|
-
klong = KlongInterpreter()
|
|
191
|
-
e = Executed(np.max)
|
|
192
|
-
try:
|
|
193
|
-
np.max = e
|
|
194
|
-
r = klong('|/[[1 2 3] [4 5 6]]')
|
|
195
|
-
finally:
|
|
196
|
-
np.max = e.fn
|
|
197
|
-
self.assertTrue(kg_equal(r, [4,5,6]))
|
|
198
|
-
self.assertFalse(e.executed)
|
|
199
|
-
|
|
200
|
-
def test_over_max(self):
|
|
201
|
-
klong = KlongInterpreter()
|
|
202
|
-
e = Executed(np.max)
|
|
203
|
-
try:
|
|
204
|
-
np.max = e
|
|
205
|
-
r = klong('|/[1 2 3 4]')
|
|
206
|
-
finally:
|
|
207
|
-
np.max = e.fn
|
|
208
|
-
self.assertEqual(r, 4)
|
|
209
|
-
self.assertTrue(e.executed)
|
|
210
|
-
|
|
211
|
-
####### Join
|
|
212
|
-
|
|
213
|
-
@unittest.skip
|
|
214
|
-
def test_over_join(self):
|
|
215
|
-
if np != numpy:
|
|
216
|
-
return
|
|
217
|
-
klong = KlongInterpreter()
|
|
218
|
-
e = Executed(np.concatenate)
|
|
219
|
-
try:
|
|
220
|
-
np.concatenate = e
|
|
221
|
-
r = klong(',/:~[[1] [2] [3]]')
|
|
222
|
-
finally:
|
|
223
|
-
np.concatenate = e.fn
|
|
224
|
-
self.assertTrue(kg_equal(r, [1,2,3]))
|
|
225
|
-
self.assertTrue(e.executed)
|
|
226
|
-
|
|
227
|
-
|
tests/test_df_cache.py
DELETED
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
import platform
|
|
3
|
-
import tempfile
|
|
4
|
-
import threading
|
|
5
|
-
import unittest
|
|
6
|
-
|
|
7
|
-
import pandas as pd
|
|
8
|
-
|
|
9
|
-
from klongpy.db.df_cache import PandasDataFrameCache
|
|
10
|
-
|
|
11
|
-
# TODO: add MacOS RAM disk
|
|
12
|
-
# hdiutil attach -nomount ram://$((2 * 1024 * 100))
|
|
13
|
-
# diskutil eraseVolume HFS+ RAMDisk /dev/disk3
|
|
14
|
-
# https://stackoverflow.com/questions/1854/how-to-identify-which-os-python-is-running-on
|
|
15
|
-
tmp_dir = "/dev/shm" if platform.system() == "Linux" else None
|
|
16
|
-
|
|
17
|
-
class TestPandasDataFrameCache(unittest.TestCase):
|
|
18
|
-
def setUp(self):
|
|
19
|
-
self.test_file_1 = tempfile.NamedTemporaryFile(delete=False, dir=tmp_dir)
|
|
20
|
-
self.df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}, index=[1, 2, 3])
|
|
21
|
-
self.cache = PandasDataFrameCache(max_memory=1024)
|
|
22
|
-
self.cache.update(self.test_file_1.name, self.df)
|
|
23
|
-
|
|
24
|
-
def test_get_dataframe(self):
|
|
25
|
-
start = 2
|
|
26
|
-
end = 3
|
|
27
|
-
result = self.cache.get_dataframe(self.test_file_1.name, start, end)
|
|
28
|
-
expected = self.df.loc[start:end]
|
|
29
|
-
pd.testing.assert_frame_equal(result, expected)
|
|
30
|
-
|
|
31
|
-
def test_append(self):
|
|
32
|
-
new_df = pd.DataFrame({'A': [4, 5, 6], 'B': [7, 8, 9]}, index=[4, 5, 6])
|
|
33
|
-
result = self.cache.update(self.test_file_1.name, new_df)
|
|
34
|
-
expected = pd.concat([self.df, new_df]).sort_index().drop_duplicates()
|
|
35
|
-
pd.testing.assert_frame_equal(result, expected)
|
|
36
|
-
|
|
37
|
-
def test_file_not_found(self):
|
|
38
|
-
with self.assertRaises(FileNotFoundError):
|
|
39
|
-
self.cache.get_file('not_found.pickle')
|
|
40
|
-
|
|
41
|
-
def test_memory_error(self):
|
|
42
|
-
with self.assertRaises(MemoryError):
|
|
43
|
-
self.cache = PandasDataFrameCache(max_memory=1)
|
|
44
|
-
self.cache.update(self.test_file_1.name, self.df)
|
|
45
|
-
|
|
46
|
-
def tearDown(self):
|
|
47
|
-
os.unlink(self.test_file_1.name)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
class TestMultithreadedPandasDataFrameCache(unittest.TestCase):
|
|
51
|
-
def setUp(self):
|
|
52
|
-
self.test_file_1 = tempfile.NamedTemporaryFile(delete=False, dir=tmp_dir)
|
|
53
|
-
self.test_file_2 = tempfile.NamedTemporaryFile(delete=False, dir=tmp_dir)
|
|
54
|
-
self.cache = PandasDataFrameCache(max_memory=2**30)
|
|
55
|
-
|
|
56
|
-
def test_append_concurrently(self):
|
|
57
|
-
def run_append_1(cache, start_i):
|
|
58
|
-
values = list(range(start_i, start_i+100))
|
|
59
|
-
new_df = pd.DataFrame({'A': values, 'B': values}, index=values)
|
|
60
|
-
cache.update(self.test_file_1.name, new_df)
|
|
61
|
-
def run_append_2(cache, start_i):
|
|
62
|
-
values = list(range(start_i, start_i+100))
|
|
63
|
-
new_df = pd.DataFrame({'C': values, 'D': values}, index=values)
|
|
64
|
-
cache.update(self.test_file_2.name, new_df)
|
|
65
|
-
|
|
66
|
-
threads = []
|
|
67
|
-
for i in range(100):
|
|
68
|
-
thread = threading.Thread(target=run_append_1, args=(self.cache, i*100))
|
|
69
|
-
thread.start()
|
|
70
|
-
threads.append(thread)
|
|
71
|
-
for i in range(150):
|
|
72
|
-
thread = threading.Thread(target=run_append_2, args=(self.cache, i*100))
|
|
73
|
-
thread.start()
|
|
74
|
-
threads.append(thread)
|
|
75
|
-
for thread in threads:
|
|
76
|
-
thread.join()
|
|
77
|
-
|
|
78
|
-
result = self.cache.get_file(self.test_file_1.name)
|
|
79
|
-
self.assertEqual(len(result), 10000)
|
|
80
|
-
result = self.cache.get_file(self.test_file_2.name)
|
|
81
|
-
self.assertEqual(len(result), 15000)
|
|
82
|
-
|
|
83
|
-
def tearDown(self):
|
|
84
|
-
os.remove(self.test_file_1.name)
|
|
85
|
-
os.remove(self.test_file_2.name)
|
tests/test_examples.py
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import glob
|
|
2
|
-
import math
|
|
3
|
-
import os
|
|
4
|
-
import unittest
|
|
5
|
-
|
|
6
|
-
from utils import *
|
|
7
|
-
from unittest.mock import MagicMock
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
class TestExamples(unittest.TestCase):
|
|
11
|
-
|
|
12
|
-
def test_load_lib(self):
|
|
13
|
-
"""
|
|
14
|
-
Verify we can at least load the library.
|
|
15
|
-
"""
|
|
16
|
-
ran_nstat = False
|
|
17
|
-
try:
|
|
18
|
-
cwd = os.getcwd()
|
|
19
|
-
os.chdir(os.path.join("klongpy","lib"))
|
|
20
|
-
for x in glob.glob("./**/*.kg", recursive=True):
|
|
21
|
-
fname = os.path.basename(x)
|
|
22
|
-
print(f"loading {fname}")
|
|
23
|
-
klong = None
|
|
24
|
-
if fname != "help.kg":
|
|
25
|
-
klong, _ = run_file("help.kg")
|
|
26
|
-
klong, _ = run_file(x, klong=klong)
|
|
27
|
-
if fname == "nstat.kg":
|
|
28
|
-
ran_nstat = True
|
|
29
|
-
r = klong("sqr2pi(2)")
|
|
30
|
-
self.assertTrue(np.isclose(r, math.sqrt(math.pi*2)))
|
|
31
|
-
finally:
|
|
32
|
-
os.chdir(cwd)
|
|
33
|
-
self.assertTrue(ran_nstat)
|
|
34
|
-
|
|
35
|
-
@unittest.skip("TODO: need to mock out the web server")
|
|
36
|
-
def test_load_examples(self):
|
|
37
|
-
"""
|
|
38
|
-
Verify we can at least load the example examples.
|
|
39
|
-
"""
|
|
40
|
-
ran_dfs = False
|
|
41
|
-
try:
|
|
42
|
-
cwd = os.getcwd()
|
|
43
|
-
os.chdir("examples")
|
|
44
|
-
for x in glob.glob("./**/*.kg", recursive=True):
|
|
45
|
-
fname = os.path.basename(x)
|
|
46
|
-
if fname == "update_data.kg":
|
|
47
|
-
# requires polygon module
|
|
48
|
-
continue
|
|
49
|
-
print(f"loading example {fname}")
|
|
50
|
-
klong = KlongInterpreter()
|
|
51
|
-
klong['.system'] = {}
|
|
52
|
-
klong['.system']['ioloop'] = MagicMock()
|
|
53
|
-
klong['.system']['klongloop'] = MagicMock()
|
|
54
|
-
klong['.system']['closeEvent'] = MagicMock()
|
|
55
|
-
try:
|
|
56
|
-
run_file(x, klong=klong)
|
|
57
|
-
except Exception as e:
|
|
58
|
-
print(f"failed to load example {fname} with error {e}")
|
|
59
|
-
raise e
|
|
60
|
-
if fname == "dfs.kg":
|
|
61
|
-
ran_dfs = True
|
|
62
|
-
finally:
|
|
63
|
-
os.chdir(cwd)
|
|
64
|
-
self.assertTrue(ran_dfs)
|