klongpy 0.6.1__py3-none-any.whl → 0.6.2__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/db/sys_fn_db.py CHANGED
@@ -87,6 +87,9 @@ class Table(dict):
87
87
  def insert(self, y):
88
88
  self.buffer.append(y)
89
89
 
90
+ def insertb(self, y):
91
+ self.buffer.extend(y)
92
+
90
93
  def commit(self):
91
94
  if not self.buffer:
92
95
  return
@@ -254,19 +257,25 @@ def eval_sys_fn_insert_table(x, y):
254
257
  Examples:
255
258
 
256
259
  t::.table(d)
257
- .insert(t, [1;2;3])
260
+ .insert(t, [1 2 3])
261
+
262
+ for batch inserts supply an array of arrays:
263
+
264
+ .insert(t, [[1 2 3] [4 5 6]])
258
265
 
259
266
  """
260
267
  if not isinstance(x,Table):
261
268
  raise KlongDbException(x, "Inserts must be applied to a table")
262
- if len(x.columns) > 1:
263
- if not np.isarray(y):
264
- raise KlongDbException(x, "Values to insert must be a list")
265
- elif not np.isarray(y):
266
- y = np.array([y])
267
- if len(y) != len(x.columns):
269
+ if not np.isarray(y):
270
+ raise KlongDbException(x, "Values to insert must be a list")
271
+ batch = len(y.shape) > 1
272
+ y_cols = len(y[0]) if batch else len(y)
273
+ if y_cols != len(x.columns):
268
274
  raise KlongDbException(x, f"Expected {len(x.columns)} values, received {len(y)}")
269
- x.insert(y)
275
+ if batch:
276
+ x.insertb(y)
277
+ else:
278
+ x.insert(y)
270
279
  return x
271
280
 
272
281
 
klongpy/dyads.py CHANGED
@@ -478,14 +478,8 @@ def eval_dyad_integer_divide(a, b):
478
478
 
479
479
 
480
480
  def _arr_to_list(a):
481
- if np.isarray(a):
482
- if a.ndim == 1:
483
- return a
484
- elif a.shape[0] == 1:
485
- return [a.flatten()] # TODO: test squeeze
486
- elif a.shape[0] > 1:
487
- return a
488
- return [a] if not is_list(a) else a
481
+ """ Convert a to a list if it is not already one """
482
+ return a if is_list(a) else [a]# if not is_list(a) else a
489
483
 
490
484
 
491
485
  def eval_dyad_join(a, b):
@@ -0,0 +1,414 @@
1
+ Metadata-Version: 2.1
2
+ Name: klongpy
3
+ Version: 0.6.2
4
+ Summary: High-Performance Klong array language with rich Python integration.
5
+ Author: Brian Guarraci
6
+ License: MIT
7
+ Classifier: Programming Language :: Python :: 3
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Requires-Python: <3.12,>=3.8
10
+ Description-Content-Type: text/markdown
11
+ License-File: LICENSE
12
+ Requires-Dist: numpy ~=1.26.4
13
+ Provides-Extra: cuda102
14
+ Requires-Dist: cupy-cuda102 ; extra == 'cuda102'
15
+ Provides-Extra: cuda110
16
+ Requires-Dist: cupy-cuda110 ; extra == 'cuda110'
17
+ Provides-Extra: cuda111
18
+ Requires-Dist: cupy-cuda111 ; extra == 'cuda111'
19
+ Provides-Extra: cuda11x
20
+ Requires-Dist: cupy-cuda11x ; extra == 'cuda11x'
21
+ Provides-Extra: cuda12x
22
+ Requires-Dist: cupy-cuda12x ; extra == 'cuda12x'
23
+ Provides-Extra: cupy
24
+ Requires-Dist: cupy ; extra == 'cupy'
25
+ Provides-Extra: db
26
+ Requires-Dist: pandas ==2.0.3 ; extra == 'db'
27
+ Requires-Dist: duckdb ==0.8.1 ; extra == 'db'
28
+ Provides-Extra: full
29
+ Requires-Dist: colorama ==0.4.6 ; extra == 'full'
30
+ Requires-Dist: aiohttp ==3.8.5 ; extra == 'full'
31
+ Requires-Dist: pandas ==2.0.3 ; extra == 'full'
32
+ Requires-Dist: duckdb ==0.8.1 ; extra == 'full'
33
+ Requires-Dist: websockets ==11.0.3 ; extra == 'full'
34
+ Provides-Extra: repl
35
+ Requires-Dist: colorama ==0.4.6 ; extra == 'repl'
36
+ Provides-Extra: rocm-4-3
37
+ Requires-Dist: cupy-rocm-4-3 ; extra == 'rocm-4-3'
38
+ Provides-Extra: rocm-5-0
39
+ Requires-Dist: cupy-rocm-5-0 ; extra == 'rocm-5-0'
40
+ Provides-Extra: web
41
+ Requires-Dist: aiohttp ==3.8.5 ; extra == 'web'
42
+ Provides-Extra: ws
43
+ Requires-Dist: websockets ==11.0.3 ; extra == 'ws'
44
+
45
+
46
+ ![Unit Tests](https://github.com/briangu/klongpy/workflows/Unit%20Tests/badge.svg)
47
+ [![Last Commit](https://img.shields.io/github/last-commit/briangu/klongpy)](https://img.shields.io/github/last-commit/briangu/klongpy)
48
+ [![Dependency Status](https://img.shields.io/librariesio/github/briangu/klongpy)](https://libraries.io/github/briangu/klongpy)
49
+ [![Open Issues](https://img.shields.io/github/issues-raw/briangu/klongpy)](https://github.com/briangu/klongpy/issues)
50
+ [![Repo Size](https://img.shields.io/github/repo-size/briangu/klongpy)](https://img.shields.io/github/repo-size/briangu/klongpy)
51
+ [![GitHub star chart](https://img.shields.io/github/stars/briangu/klongpy?style=social)](https://star-history.com/#briangu/klongpy)
52
+
53
+ [![Release Notes](https://img.shields.io/github/release/briangu/klongpy)](https://github.com/briangu/klongpy/releases)
54
+ [![Downloads](https://static.pepy.tech/badge/klongpy/month)](https://pepy.tech/project/klongpy)
55
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
56
+
57
+ [![Twitter](https://img.shields.io/twitter/url/https/twitter.com/klongpy.svg?style=social&label=Follow%20%40KlongPy)](https://twitter.com/klongpy)
58
+
59
+ # KlongPy: High-Performance Array Programming in Python
60
+
61
+ KlongPy is a Python adaptation of the [Klong](https://t3x.org/klong) [array language](https://en.wikipedia.org/wiki/Array_programming), known for its high-performance vectorized operations that leverage the power of NumPy. Embracing a "batteries included" philosophy, KlongPy combines built-in modules with Python's expansive ecosystem, facilitating rapid application development with Klong's succinct syntax.
62
+
63
+ ## Core Features
64
+
65
+ - **Vectorized Operations with NumPy:** At its core, KlongPy uses [NumPy](https://numpy.org/), an [Iverson Ghost](https://analyzethedatanotthedrivel.org/2018/03/31/NumPy-another-iverson-ghost/) descendant from APL, for high-efficiency array manipulations.
66
+ - **CPU and GPU Backend Support:** Incorporating [CuPy](https://github.com/cupy/cupy), KlongPy extends its capabilities to operate on both CPU and GPU backends, ensuring versatile and powerful computing options.
67
+ - **Seamless Integration with Python Ecosystem:** The combination of KlongPy's built-in features with Python's wide-ranging libraries enables developers to build complex applications effortlessly.
68
+
69
+ ## KlongPy's Foundation and Applications
70
+
71
+ - **Inspired by Nils M Holm:** KlongPy is grounded in the work of [Nils M Holm](https://t3x.org), the original creator of Klong, and is further enriched by his [Klong Book](https://t3x.org/klong/book.html).
72
+ - **Ideal for Diverse Fields:** Data scientists, quantitative analysts, researchers, and programming language enthusiasts will find KlongPy especially beneficial for its versatility and performance.
73
+
74
+ KlongPy thus stands as a robust tool, blending the simplicity of Klong with the extensive capabilities of Python, suitable for a wide range of computational tasks.
75
+
76
+ # Quick install
77
+
78
+ ```bash
79
+ pip3 install "klongpy[full]"
80
+ ```
81
+
82
+ # Feature Overview
83
+
84
+ KlongPy is both an Array Language runtime and a set of powerful tools for building high performance data analysis and distributed computing applications. Some of the features include:
85
+
86
+ * [__Array Programming__](https://en.wikipedia.org/wiki/Array_programming): Based on [Klong](https://t3x.org/klong), a concise, expressive, and easy-to-understand array programming language. Its simple syntax and rich feature set make it an excellent tool for data scientists and engineers.
87
+ * [__Speed__](docs/performance.md): Designed for high-speed vectorized computing, enabling you to process large data sets quickly and efficiently on either CPU or GPU.
88
+ * [__Fast Columnar Database__](docs/fast_columnar_database.md): Includes integration with [DuckDb](http://duckdb.org), a super fast in-process columnar store that can operate directly on NumPy arrays with zero-copy.
89
+ * [__Inter-Process Communication (IPC)__](docs/ipc_capabilities.md): Includes built-in support for IPC, enabling easy communication between different processes and systems. Ticker plants and similar pipelines are easy to build.
90
+ * [__Table and Key-Value Store__](docs/table_and_key_value_stores.md): Includes a simple file-backed key value store that can be used to store database tables or raw key/value pairs.
91
+ * [__Python Integration__](docs/python_integration.md): Seamlessly compatible with Python and modules, allowing you to leverage existing Python libraries and frameworks.
92
+ * [__Web server__](docs/web_server.md): Includes a web server, making it easy to build sites backed by KlongPy capabilities.
93
+ * [__Timers__](docs/timer.md): Includes periodic timer facility to periodically perform tasks.
94
+
95
+ # KlongPy Examples
96
+
97
+ Explore KlongPy with these examples. Each snippet highlights a unique aspect of Klong, demonstrating its versatility in various programming scenarios.
98
+
99
+ Before we get started, you may be wondering: *Why is the syntax so terse?*
100
+
101
+ The answer is that it's based on the APL style array language programming and there's a good reason why its compact nature is actually helpful.
102
+
103
+ Array language style lets you describe WHAT you want the computer to do and it lets the computer figure out HOW to do it. This frees you up from the details while letting the computer figure out how to go as fast as possible.
104
+
105
+ Less code to write and faster execution.
106
+
107
+ ---
108
+
109
+ Just so the following examples make more sense when you see the REPL outputs, there are a few quick rules about Klong functions. Functions only take up to 3 parameters and they are ALWAYS called x,y and z.
110
+
111
+ A function with
112
+
113
+ * no parameters is called a nilad
114
+ * one parameter is called a monad (x)
115
+ * two parameters: dyad (x and y)
116
+ * three parameters: a triad (x, y and z)
117
+
118
+ The reason that Klong functions only take up to 3 parameters AND name them for you is both convience and compactness.
119
+
120
+ ---
121
+
122
+ ## 0. Start the REPL
123
+
124
+ ```Bash
125
+ $ rlwrap kgpy
126
+
127
+ Welcome to KlongPy REPL v0.6.0
128
+ Author: Brian Guarraci
129
+ Web: http://klongpy.org
130
+ ]h for help; crtl-d or ]q to quit
131
+
132
+ ?>
133
+ ```
134
+
135
+ ## 1. Basic Arithmetic
136
+
137
+ Let's get started with the basics and build up to some more interesting math. Expressions are evaluated from right to left: 3*2 and then + 5
138
+
139
+ ```kgpy
140
+ ?> 5+3*2
141
+ 11
142
+ ```
143
+
144
+ KlongPy is more about arrays of things, so let's define sum and count functions over an array:
145
+
146
+ ```kgpy
147
+ ?> sum::{+/x} :" sum + over / the array x
148
+ :monad
149
+ ?> sum([1 2 3])
150
+ 6
151
+ ?> count::{#x}
152
+ :monad
153
+ ?> count([1 2 3])
154
+ 3
155
+ ```
156
+
157
+ Now that we know the sum and number of elements we can compute the average:
158
+
159
+ ```kgpy
160
+ ?> avg::{sum(x)%count(x)} :" average is the sum divided by the number of elements
161
+ :monad
162
+ ?> avg([1 2 3])
163
+ 2
164
+ ```
165
+
166
+ ## 2. Math on arrays
167
+
168
+ Let's dig into more interesting operations over array elements. There's really big performance differences in how you approach the problem and it's important to see the difference.
169
+
170
+ For the simple case of squaring numbers in a list, let's try a couple solutions:
171
+
172
+ ```kgpy
173
+ ?> {x*x}'[1 2 3 4 5] :" square each element as we iterate over the array
174
+ [1 4 9 16 25]
175
+ ```
176
+
177
+ The vectorized approach will do an element-wise multiplication in bulk:
178
+
179
+ ```kgpy
180
+ ?> a::[1 2 3 4 5];a*a :" a*a multiplies the arrays
181
+ [1 4 9 16 25]
182
+ ```
183
+
184
+ The vectorized approach is going to be MUCH faster. Let's crank up the size of the array and time it:
185
+
186
+ ```kgpy
187
+ $> .l("time")
188
+ :monad
189
+ $> a::!1000;#a
190
+ 1
191
+ $> fast::{{a*a}'!1000}
192
+ :nilad
193
+ $> slow::{{{x*x}'a}'!1000}
194
+ :nilad
195
+ $> time(fast)
196
+ 0.015867948532104492
197
+ $> time(slow)
198
+ 2.8987138271331787
199
+ ```
200
+
201
+ Vectors win by 182x! Why? Because when you perform a bulk vector operation the CPU can perform the math with much less overhead and do many more operations at a time because it has the entire computation presented to it at once.
202
+
203
+ KlongPy aims to give you tools that let you conveniently exploit this vectorization property - and go FAST!
204
+
205
+ Less code to write AND faster to compute.
206
+
207
+ ## 3. Data Analysis with Python Integration
208
+
209
+ KlongPy integrates seamlessly with Python so that the strenghts of both can be combined. It's easy to use KlongPy from Python and vice versa.
210
+
211
+ For example, let's say we have some data in Python that we want to operate on in KlongPy. We can just directly use the interpreter in Python and run functions on data we put into the KlongPy context:
212
+
213
+ ```python
214
+ from klongpy import KlongInterpreter
215
+ import numpy as np
216
+
217
+ data = np.array([1, 2, 3, 4, 5])
218
+ klong = KlongInterpreter()
219
+ # make the data NumPy array available to KlongPy code by passing it into the interpreter
220
+ # we are creating a symbol in KlongPy called 'data' and assigning the external NumPy array value
221
+ klong['data'] = data
222
+ # define the average function in KlongPY
223
+ klong('avg::{(+/x)%#x}')
224
+ # call the average function with the external data and return the result.
225
+ r = klong('avg(data)')
226
+ print(r) # expected value: 3
227
+ ```
228
+
229
+ It doesn't make sense to write code in Klong that already exists in other libraries. We can directly access them via the python inport functions (.py and .pyf).
230
+
231
+ How about we use the NumPy FFT?
232
+
233
+ ```kgpy
234
+ ?> .pyf("numpy";"fft");fft::.pya(fft;"fft")
235
+ :monad
236
+ ?> signal::[0.0 1.0 0.0 -1.0] :" Example simple signal
237
+ [0.0 1.0 0.0 -1.0]
238
+ ?> result::fft(signal)
239
+ [0j -2j 0j 2j]
240
+ ```
241
+
242
+ Now you can use NumPy or other libraries to provide complex functions while KlongPy lets you quickly prepare and process the vectors.
243
+
244
+ There's a lot more we can do with interop but let's move on for now!
245
+
246
+ ## 4. Database Functionality
247
+
248
+ KlongPy leverages a high-performance columnar store called DuckDb that uses zero-copy NumPy array operations behind the scenes. This database allows fast interop between KlongPy and DuckDb (the arrays are not copied) so that applications can manage arrays in KlongPy and then instantly perform SQL on the data for deeper insights.
249
+
250
+ It's easy to create a table and a db to query:
251
+
252
+ ```kgpy
253
+ ?> .py("klongpy.db")
254
+ ?> t::.table([["name" ["Alice" "Bob"]] ["age" [25 30]]])
255
+ name age
256
+ Alice 25
257
+ Bob 30
258
+ ?> db::.db(:{},"T",t)
259
+ ?> db("select * from T where age > 27")
260
+ name age
261
+ Bob 30
262
+ ```
263
+
264
+ ## 5. IPC, Remote Function Calls and Asynchronous operations
265
+
266
+ Inter Process Communication (IPC) lets you build distributed and interconnected KlongPy programs and services.
267
+
268
+ KlongPy treats IPC connections to servers as functions. These functions let you call the server and ask for things it has in it's memory - they can be other functions or values, etc. For example you can ask for a reference to a remote function and you will get a local function that when you call it runs on teh server with your arguemnts. This general "remote proxy" approach allows you to write your client code in the same way as if all the code were running locally.
269
+
270
+ To see this in action, let's setup a simple scenario where the server has an "avg" function and the client wants to call it.
271
+
272
+ Start a server in one terminal:
273
+
274
+ ```kgpy
275
+ ?> avg::{(+/x)%#x}
276
+ :monad
277
+ ?> .srv(8888)
278
+ 1
279
+ ```
280
+
281
+ Start the client and make the connection to the server as 'f'. In order to pass parameters to a remote function we form an array of the function symbol followed by the parameters (e.g. :avg,,!100)
282
+
283
+ ```kgpy
284
+ ?> f::.cli(8888) :" connect to the server
285
+ remote[localhost:8888]:fn
286
+ ?> f(:avg,,!100) : call the remote function "avg" directly with the paramter !100
287
+ 49.5
288
+ ```
289
+
290
+ Let's get fancy and make a local proxy to the remote function:
291
+
292
+ ```kgpy
293
+ ?> myavg::f(:avg) :" reference the remote function by it's symbol :avg and assign to a local variable called myavg
294
+ remote[localhost:8888]:fn:avg:monad
295
+ ?> myavg(!100) :" this runs on the server with !100 array passed to it as a parameter
296
+ 49.5
297
+ ```
298
+
299
+ Since remote functions may take a while we can wrap them with an async wrapper and have it call our callback when completed:
300
+
301
+ ```kgpy
302
+ ?> afn::.async(myavg;{.d("Avg calculated: ");.p(x)})
303
+ async::monad
304
+ ?> afn(!100)
305
+ Avg calculated: 49.5
306
+ 1
307
+ ```
308
+
309
+ ## 6. Web Server Implementation
310
+
311
+ In addition to IPC we can also expose data via a standard web server. This capability lets you have other ways of serving content that can be either exposing interesting details about some computation or just a simple web server for other reasons.
312
+
313
+ Let's create a file called web.kg with the following code that adds one index handler:
314
+
315
+ ```text
316
+ .py("klongpy.web")
317
+ data::!10
318
+ index::{x; "Hello, Klong World! ",data}
319
+ .web(8888;:{},"/",index;:{})
320
+ .p("ready at http://localhost:8888")
321
+ ```
322
+
323
+ We can run this web server as follows:
324
+
325
+ ```bash
326
+ $ kgpy web.kg
327
+ ready at http://localhost:8888
328
+ ```
329
+
330
+ In another terminal:
331
+
332
+ ```bash
333
+ $ curl http://localhost:8888
334
+ ['Hello, Klong World! ' 0 1 2 3 4 5 6 7 8 9]
335
+ ```
336
+
337
+ ## Conclusion
338
+
339
+ These examples are designed to illustrate the "batteries included" approach, ease of use and diverse applications of KlongPy, making it a versatile choice for various programming needs.
340
+
341
+ [Check out the examples folder for more](https://github.com/briangu/klongpy/tree/main/examples).
342
+
343
+ # Installation
344
+
345
+ ### CPU
346
+
347
+ ```bash
348
+ pip3 install klongpy
349
+ ```
350
+
351
+ ### GPU support
352
+
353
+ Choose your CuPy prebuilt binary or from source. Note, the [ROCM](docs/ROCM.md) support for CuPy is experimental and likely will have issues.
354
+
355
+ 'cupy' => build from source
356
+ 'cuda12x' => "cupy-cuda12x"
357
+ 'cuda11x' => "cupy-cuda11x"
358
+ 'cuda111' => "cupy-cuda111"
359
+ 'cuda110' => "cupy-cuda110"
360
+ 'cuda102' => "cupy-cuda102"
361
+ 'rocm-5-0' => "cupy-rocm-5-0"
362
+ 'rocm-4-3' => "cupy-rocm-4-3"
363
+
364
+ ```bash
365
+ pip3 install "klongpy[cupy]"
366
+ ```
367
+
368
+ ### All application tools (db, web, REPL, etc.)
369
+
370
+ ```bash
371
+ pip3 install "klongpy[full]"
372
+ ```
373
+
374
+ # Status
375
+
376
+ KlongPy is a superset of the Klong array language. It currently passes all of the integration tests provided by klong as well as additional suites.
377
+
378
+ Since CuPy is [not 100% compatible with NumPy](https://docs.cupy.dev/en/stable/user_guide/difference.html), there are currently some gaps in KlongPy between the two backends. Notably, strings are supported in CuPy arrays so KlongPy GPU support currently is limited to math.
379
+
380
+ Primary ongoing work includes:
381
+
382
+ * Additional tools to make KlongPy applications more capable.
383
+ * Additional syntax error help
384
+ * Actively switch between CuPy and NumPy when incompatibilities are present
385
+
386
+ # Differences from Klong
387
+
388
+ KlongPy is effectively a superset of the Klong language, but has some key differences:
389
+
390
+ * Infinite precision: The main difference in this implementation of Klong is the lack of infinite precision. By using NumPy we are restricted to doubles.
391
+ * Python integration: Most notably, the ".py" command allows direct import of Python modules into the current Klong context.
392
+ * KlongPy aims to be more "batteries included" approach to modules and contains additional features such as IPC, Web service, Websockets, etc.
393
+
394
+ # Related
395
+
396
+ * [Klupyter - KlongPy in Jupyter Notebooks](https://github.com/briangu/klupyter)
397
+ * [Visual Studio Code Syntax Highlighting](https://github.com/briangu/klongpy-vscode)
398
+ * [Advent Of Code in KlongPy](https://github.com/briangu/aoc)
399
+
400
+ ## Develop
401
+
402
+ git clone https://github.com/briangu/klongpy.git
403
+ cd klongpy
404
+ python3 setup.py develop
405
+
406
+ ### Running tests
407
+
408
+ ```bash
409
+ python3 -m unittest
410
+ ```
411
+
412
+ # Acknowledgement
413
+
414
+ HUGE thanks to Nils M Holm for his work on Klong and providing the foundations for this interesting project.
@@ -2,7 +2,7 @@ klongpy/__init__.py,sha256=8K0RIIZh2QLdOBA68oym_MeEwO33ffcDOZAU3etJ7kA,107
2
2
  klongpy/adverbs.py,sha256=W6HAL4rxWV6djrILnahRqw8o6-Yq9pUWIUznSJG8-f0,12566
3
3
  klongpy/backend.py,sha256=qA2DulWLVtlOYs3opwJIod0XZVTLCMvqjuttK2_-CHo,2897
4
4
  klongpy/core.py,sha256=40AGWEuYP5AD8E8V4XNzTjsZH8lF6y7vU3jTaBaatFk,27193
5
- klongpy/dyads.py,sha256=pgAePIzILlLiQCTsMZ4xuLD43RzGPNII4pSDTuDzq30,31369
5
+ klongpy/dyads.py,sha256=Fhr2u2PgLKKyBOaiB8ofyDl3-TDceoSmgfrLBj5WyFI,31247
6
6
  klongpy/interpreter.py,sha256=9cd6aZfGVQ7cP1VXDIksxgoHCIReeh62QAxCNfwGQjQ,23792
7
7
  klongpy/monads.py,sha256=6PoLROije2u-ojQZPu2f5FYnRav02Bx8eovrm2C29NY,14158
8
8
  klongpy/sys_fn.py,sha256=cG9IALvpjMmfXE0sQTmqsmF0KDR8tzClDYLrcghEt1I,23727
@@ -14,7 +14,7 @@ klongpy/db/__init__.py,sha256=KUEKYPphDAYLdRfzcRuvj3Mv9ti6x_y9hjIzNh0ufRI,282
14
14
  klongpy/db/df_cache.py,sha256=_2tI3Gv5nzASlQfnFiwnXrkPnZ-mzJzyM0tt_gi3c5o,3325
15
15
  klongpy/db/file_cache.py,sha256=MnSTRB0B8yi8yAHFXGqduqaBqGhllLKxo1rrqMJ6-ik,9294
16
16
  klongpy/db/helpers.py,sha256=vdxSY2W-N13cBF3PUi86WlecGSz0ZkJN0OR7Jb6E9iM,1457
17
- klongpy/db/sys_fn_db.py,sha256=aBGTdWWM69efTxNg3GMlWbGECvaPA_bwENCHjZC-MLI,9047
17
+ klongpy/db/sys_fn_db.py,sha256=R5yfEa8LvCbCdSCV2BrZXfGrh7IbwSK9zuZ7OVRd8UI,9234
18
18
  klongpy/db/sys_fn_kvs.py,sha256=--FTMQyKdn8vBx0qG4mOBzdd2rtBfm0rW4c0AnB0G94,4114
19
19
  klongpy/lib/csv.kg,sha256=w6FvenQmkl0EF2kieQxxloNOFgZbt3M9IMSYSdImJcA,1498
20
20
  klongpy/lib/edt.kg,sha256=aJsjCxAkbfzwxWg8mF9nRDbCCt2fqtCWv0CPsq4SIHw,707
@@ -34,7 +34,7 @@ klongpy/web/__init__.py,sha256=lM_40n_qzwYSx_OFi4RqFwsxQe8GGBtJm3_GLLxn9-8,101
34
34
  klongpy/web/sys_fn_web.py,sha256=En9_8Xh1uIaGz8CRyWsYuwpt0rbpNWvDCKFJ6KZpU5o,4710
35
35
  klongpy/ws/__init__.py,sha256=GKl5804W3XNkDER0mkdFf-4cIVjgeP9M3tfNg_tCv3c,114
36
36
  klongpy/ws/sys_fn_ws.py,sha256=Ba6MmmTS6cWHlruGgNznNXXPQX2zaBQmAEwkz9ge7sk,18300
37
- klongpy-0.6.1.data/scripts/kgpy,sha256=nDF66LclUBK6qILB2dgJ9VKAlGlPKMQfoJ4CvH5d_UQ,12119
37
+ klongpy-0.6.2.data/scripts/kgpy,sha256=nDF66LclUBK6qILB2dgJ9VKAlGlPKMQfoJ4CvH5d_UQ,12119
38
38
  tests/__init__.py,sha256=xdETQVm8SNlASCru27aks1KZwSs2Oh-0NR5zrccSqb0,221
39
39
  tests/gen_join_over.py,sha256=ZiliJS6Lz0rqaZAfAeJFbPOU109PRF0QFE6262a4TPU,3684
40
40
  tests/gen_py_suite.py,sha256=ihXihalZkjN9Poy3m-1FVGdZy_YYWS0CEkY68pDgGso,2495
@@ -53,11 +53,11 @@ tests/perf_vector.py,sha256=p76TVCS5szG0BX7rzquvKb7xikxUQOUmQttvTS0EH44,976
53
53
  tests/test_accel.py,sha256=apKi0PN9l9ztDLTwtdo6esWCl7_Yo97xljfNY0q9hug,6305
54
54
  tests/test_df_cache.py,sha256=vK36B0ENNwTYgv_JvRZimum9EEoPw-qgi4BWQWHRqQQ,3302
55
55
  tests/test_examples.py,sha256=hfpCQlcLR4pjUeSk9uAhtgnsjLEHLc_sfvRRWq8W1iY,2131
56
- tests/test_extra_suite.py,sha256=czwr8hHlI5IpMxHbaeC9fLK_SnNuuFLWiHCIeJMzhm8,12538
56
+ tests/test_extra_suite.py,sha256=WPIA_UcP5BVvZIlkiDMUx_877ts3rYoVLo0grQh4JW8,12967
57
57
  tests/test_file_cache.py,sha256=lkE4bXPR9qp6wRdNHcG0f0Fb_BBB-2oocRttmCbXT7A,7733
58
58
  tests/test_interop.py,sha256=efUVa-IB43TecUhOm1rfTlK9G6kcf0U4q6EEVf06gaE,5837
59
59
  tests/test_kgtests.py,sha256=7lUgKYt9TQiYxAXWqE4VuaZo7frhbzSd9ofa6_pWBLE,2190
60
- tests/test_known_bugs.py,sha256=eEeJc7VXnOyG498nynvJFL3d_iKYxYqUQEjBtirOZ30,6053
60
+ tests/test_known_bugs.py,sha256=shBMW2rwQV0CLtrPZZ54TDFII7W5fxi7AOpZyvbydM8,6481
61
61
  tests/test_prog.py,sha256=8P019M-hiW9jxe9FgQS3Q7wqxoTrkhclMTk6xO4HBWU,3311
62
62
  tests/test_suite.py,sha256=cKTH9ICQUFPyM2xcmQNuS_jueDHLD2ukVMeM_KstTbQ,73051
63
63
  tests/test_suite_file.py,sha256=zZLXK1xEQgUH0OO9J53jkF4j0rjbgIXsWlsNo5puriA,4027
@@ -67,8 +67,8 @@ tests/test_sys_fn_ipc.py,sha256=tV7uCGxXQCHZQ2CkffD4j5h01TYBe1ozC_wImiANyHA,2160
67
67
  tests/test_sys_fn_timer.py,sha256=VUfi1AK9SCzA9g5IgbfpdEMW2AP4-9dgVOpJXhMMQhA,4447
68
68
  tests/test_util.py,sha256=k4UCR0avjWNxo_jO710x32AAMOAePOx79EOt58wL584,7942
69
69
  tests/utils.py,sha256=QrLAR4-WXVSDrC60qhl78_NE-3idp0mgLJmSZ5seyWw,3721
70
- klongpy-0.6.1.dist-info/LICENSE,sha256=Nk1iW-tI7n0z8R2jMqVm9SuFIoa8iukXsFcJoPqQgns,1071
71
- klongpy-0.6.1.dist-info/METADATA,sha256=P6EL66mLvMrNPzZ8GUSGR_oo1coMGdBxiO2dVy7SLMU,10799
72
- klongpy-0.6.1.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
73
- klongpy-0.6.1.dist-info/top_level.txt,sha256=1dsI3MhtibeAZuB7WPW58dpNgyGvXLX5EEHqm46NQYo,14
74
- klongpy-0.6.1.dist-info/RECORD,,
70
+ klongpy-0.6.2.dist-info/LICENSE,sha256=Nk1iW-tI7n0z8R2jMqVm9SuFIoa8iukXsFcJoPqQgns,1071
71
+ klongpy-0.6.2.dist-info/METADATA,sha256=ZAepEk3sKh2IsjRV-FxdQdY3WvKOtJLaEz664BLvJIQ,16602
72
+ klongpy-0.6.2.dist-info/WHEEL,sha256=yQN5g4mg4AybRjkgi-9yy4iQEFibGQmlz78Pik5Or-A,92
73
+ klongpy-0.6.2.dist-info/top_level.txt,sha256=1dsI3MhtibeAZuB7WPW58dpNgyGvXLX5EEHqm46NQYo,14
74
+ klongpy-0.6.2.dist-info/RECORD,,
tests/test_extra_suite.py CHANGED
@@ -12,6 +12,18 @@ class TestExtraCoreSuite(unittest.TestCase):
12
12
  def assert_eval_cmp(self, a, b, klong=None):
13
13
  self.assertTrue(eval_cmp(a, b, klong=klong))
14
14
 
15
+ def test_negate_array_result_type(self):
16
+ """ ensure the result type of negating an array is correct """
17
+ klong = KlongInterpreter()
18
+ r = klong("-1]")
19
+ self.assertTrue(is_integer(r))
20
+ r = klong("-1.0]")
21
+ self.assertTrue(is_float(r))
22
+ r = klong("-[1 2 3]")
23
+ self.assertTrue(r.dtype == int)
24
+ r = klong("-[1.0 2.0 3.0]")
25
+ self.assertTrue(r.dtype == float)
26
+
15
27
  def test_match_empty_array_to_undefined_symbol(self):
16
28
  """ symbol is undefined so does not match the empty array """
17
29
  klong = KlongInterpreter()
tests/test_known_bugs.py CHANGED
@@ -4,11 +4,29 @@ import pandas as pd
4
4
  from utils import *
5
5
 
6
6
  from klongpy import KlongInterpreter
7
- from klongpy.core import KGChar
7
+ from klongpy.core import KGChar, KGSym
8
8
 
9
9
 
10
10
  class TestKnownBugsSuite(unittest.TestCase):
11
11
 
12
+ @unittest.skip
13
+ def test_array_substitution(self):
14
+ # [!10] should eval to [:! 10] but it doesn't
15
+ klong = KlongInterpreter()
16
+ r = klong('[!10]')
17
+ self.assertTrue(kg_equal(r, [KGSym('!'), 10]))
18
+ # [3*a^2] should eval to [3 :* :a :^ 2] but it doesn't
19
+ r = klong('[3*a^2]')
20
+ self.assertTrue(kg_equal(r, [3, KGSym('*'), KGSym('a'), KGSym('^'), 2]))
21
+
22
+ @unittest.skip
23
+ def test_should_fail_parsing(self):
24
+ """
25
+ this is a bug in both original Klong and KlongPy:
26
+ fn::{[a b c]::1;a::1;b::2;c::3} the :: after variable declaration is a syntax error
27
+ """
28
+ pass
29
+
12
30
  @unittest.skip
13
31
  def test_calling_time_with_lambda(self):
14
32
  """
@@ -31,13 +49,6 @@ class TestKnownBugsSuite(unittest.TestCase):
31
49
  r = klong('T@"col1"')
32
50
  self.assertTrue(kg_equal(r, data['col1']))
33
51
 
34
- @unittest.skip
35
- def test_join_nested_array(self):
36
- klong = KlongInterpreter()
37
- r = klong("a::!10;k::3;c::(,,,1#a),k")
38
- # currently this flattens to [[0], 3]
39
- self.assertTrue(kg_equal(r,[[[[0]]],3]))
40
-
41
52
  @unittest.skip
42
53
  def test_extra_spaces(self):
43
54
  klong = KlongInterpreter()
@@ -1,305 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: klongpy
3
- Version: 0.6.1
4
- Summary: High-Performance Klong array language with rich Python integration.
5
- Author: Brian Guarraci
6
- License: MIT
7
- Classifier: Programming Language :: Python :: 3
8
- Classifier: License :: OSI Approved :: MIT License
9
- Requires-Python: <3.12,>=3.8
10
- Description-Content-Type: text/markdown
11
- License-File: LICENSE
12
- Requires-Dist: numpy ~=1.24.4
13
- Provides-Extra: cuda102
14
- Requires-Dist: cupy-cuda102 ; extra == 'cuda102'
15
- Provides-Extra: cuda110
16
- Requires-Dist: cupy-cuda110 ; extra == 'cuda110'
17
- Provides-Extra: cuda111
18
- Requires-Dist: cupy-cuda111 ; extra == 'cuda111'
19
- Provides-Extra: cuda11x
20
- Requires-Dist: cupy-cuda11x ; extra == 'cuda11x'
21
- Provides-Extra: cuda12x
22
- Requires-Dist: cupy-cuda12x ; extra == 'cuda12x'
23
- Provides-Extra: cupy
24
- Requires-Dist: cupy ; extra == 'cupy'
25
- Provides-Extra: db
26
- Requires-Dist: pandas ==2.0.3 ; extra == 'db'
27
- Requires-Dist: duckdb ==0.8.1 ; extra == 'db'
28
- Provides-Extra: full
29
- Requires-Dist: colorama ==0.4.6 ; extra == 'full'
30
- Requires-Dist: aiohttp ==3.8.5 ; extra == 'full'
31
- Requires-Dist: pandas ==2.0.3 ; extra == 'full'
32
- Requires-Dist: duckdb ==0.8.1 ; extra == 'full'
33
- Requires-Dist: websockets ==11.0.3 ; extra == 'full'
34
- Provides-Extra: repl
35
- Requires-Dist: colorama ==0.4.6 ; extra == 'repl'
36
- Provides-Extra: rocm-4-3
37
- Requires-Dist: cupy-rocm-4-3 ; extra == 'rocm-4-3'
38
- Provides-Extra: rocm-5-0
39
- Requires-Dist: cupy-rocm-5-0 ; extra == 'rocm-5-0'
40
- Provides-Extra: web
41
- Requires-Dist: aiohttp ==3.8.5 ; extra == 'web'
42
- Provides-Extra: ws
43
- Requires-Dist: websockets ==11.0.3 ; extra == 'ws'
44
-
45
-
46
- ![Unit Tests](https://github.com/briangu/klongpy/workflows/Unit%20Tests/badge.svg)
47
- [![Last Commit](https://img.shields.io/github/last-commit/briangu/klongpy)](https://img.shields.io/github/last-commit/briangu/klongpy)
48
- [![Dependency Status](https://img.shields.io/librariesio/github/briangu/klongpy)](https://libraries.io/github/briangu/klongpy)
49
- [![Open Issues](https://img.shields.io/github/issues-raw/briangu/klongpy)](https://github.com/briangu/klongpy/issues)
50
- [![Repo Size](https://img.shields.io/github/repo-size/briangu/klongpy)](https://img.shields.io/github/repo-size/briangu/klongpy)
51
- [![GitHub star chart](https://img.shields.io/github/stars/briangu/klongpy?style=social)](https://star-history.com/#briangu/klongpy)
52
-
53
- [![Release Notes](https://img.shields.io/github/release/briangu/klongpy)](https://github.com/briangu/klongpy/releases)
54
- [![Downloads](https://static.pepy.tech/badge/klongpy/month)](https://pepy.tech/project/klongpy)
55
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
56
-
57
- [![Twitter](https://img.shields.io/twitter/url/https/twitter.com/klongpy.svg?style=social&label=Follow%20%40KlongPy)](https://twitter.com/klongpy)
58
- <!-- [![Discord]](https://discord.gg/z2vvTvxa) -->
59
-
60
- # KlongPy
61
-
62
- KlongPy is a Python adaptation of the [Klong](https://t3x.org/klong) [array language](https://en.wikipedia.org/wiki/Array_programming), offering high-performance vectorized operations. It prioritizes compatibility with Python, thus allowing seamless integration of Python's expansive ecosystem while retaining Klong's succinctness. With the inclusion of [CuPy](https://github.com/cupy/cupy), KlongPy can operate using both CPU and GPU backends. It utilizes [NumPy](https://numpy.org/), an [Iverson Ghost](https://analyzethedatanotthedrivel.org/2018/03/31/NumPy-another-iverson-ghost/) descendant from APL, as its core. This means its runtime can target either GPU or CPU backends. The framework's foundation lies in [Nils M Holm](https://t3x.org)'s work, the original developer of Klong, who has authored a [Klong Book](https://t3x.org/klong/book.html). KlongPy is especially useful for data scientists, quantitative analysts, researchers, and programming language aficionados.
63
-
64
- # Quick install
65
-
66
- ```bash
67
- pip3 install "klongpy[full]"
68
- ```
69
-
70
- # Overview
71
-
72
- KlongPy is both an Array Language runtime and a set of powerful tools for building high performance data analysis and distributed computing applications. Some of the features include:
73
-
74
- * [__Array Programming__](https://en.wikipedia.org/wiki/Array_programming): Based on [Klong](https://t3x.org/klong), a concise, expressive, and easy-to-understand array programming language. Its simple syntax and rich feature set make it an excellent tool for data scientists and engineers.
75
- * [__Speed__](docs/performance.md): Designed for high-speed vectorized computing, enabling you to process large data sets quickly and efficiently on either CPU or GPU.
76
- * [__Fast Columnar Database__](docs/fast_columnar_database.md): Includes integration with [DuckDb](http://duckdb.org), a super fast in-process columnar store that can operate directly on NumPy arrays with zero-copy.
77
- * [__Inter-Process Communication (IPC)__](docs/ipc_capabilities.md): Includes built-in support for IPC, enabling easy communication between different processes and systems. Ticker plants and similar pipelines are easy to build.
78
- * [__Table and Key-Value Store__](docs/table_and_key_value_stores.md): Includes a simple file-backed key value store that can be used to store database tables or raw key/value pairs.
79
- * [__Python Integration__](docs/python_integration.md): Seamlessly compatible with Python and modules, allowing you to leverage existing Python libraries and frameworks.
80
- * [__Web server__](docs/web_server.md): Includes a web server, making it easy to build sites backed by KlongPy capabilities.
81
- * [__Timers__](docs/timer.md): Includes periodic timer facility to periodically perform tasks.
82
-
83
- # Examples
84
-
85
- ```
86
-
87
- ```
88
-
89
- Consider this simple Klong expression that computes an array's average: `(+/a)%#a`. Decoded, it means "sum of 'a' divided by the length of 'a'", as read from right to left.
90
-
91
- Below, we define the function 'avg' and apply it to the array of 1 million integers (as defined by !1000000)
92
-
93
- Let's try this in the KlongPy REPL:
94
-
95
- ```Bash
96
- $ rlwrap kgpy
97
-
98
- Welcome to KlongPy REPL v0.6.0
99
- Author: Brian Guarraci
100
- Web: http://klongpy.org
101
- ]h for help; crtl-d or ]q to quit
102
-
103
- ?> avg::{(+/x)%#x}
104
- :monad
105
- ?> avg(!1000000)
106
- 499999.5
107
- ```
108
-
109
- Now let's time it (first, right it once, then 100 times):
110
-
111
- ```
112
- ?> ]T avg(!1000000)
113
- total: 0.0032962500117719173 per: 0.0032962500117719173
114
- ?> ]T:100 avg(!1000000)
115
- total: 0.10882879211567342 per: 0.0010882879211567343
116
- ```
117
-
118
- We can also import Python custom or standard modules to use directly in Klong language.
119
-
120
- ```
121
- ?> .pyf("math";"pi")
122
- 1
123
- ?> pi
124
- 3.141592653589793
125
- ```
126
-
127
- Here we import the fsum function from standard Python math library and redefine avg to use 'fsum':
128
-
129
- ```
130
- ?> .pyf("math";"fsum")
131
- 1
132
- ?> favg::{fsum(x)%#x}
133
- :monad
134
- ?> favg(!1000000)
135
- 499999.5
136
- ```
137
-
138
- Notice that using fsum is slower than using Klong '+/'. This is because the '+/' operation is vectorized while fsum is not.
139
-
140
- ```
141
- ?> ]T favg(!1000000)
142
- total: 0.050078875152394176 per: 0.050078875152394176
143
- ?> ]T:100 favg(!1000000)
144
- total: 2.93945804098621 per: 0.029394580409862103
145
- ```
146
-
147
- To use KlongPy within Python, here's a basic outline:
148
-
149
- ```python
150
- from klongpy import KlongInterpreter
151
-
152
- # instantiate the KlongPy interpeter
153
- klong = KlongInterpreter()
154
-
155
- # define average function in Klong (Note the '+/' (sum over) uses np.add.reduce under the hood)
156
- klong('avg::{(+/x)%#x}')
157
-
158
- # create a billion random uniform values [0,1)
159
- data = np.random.rand(10**9)
160
-
161
- # reference the 'avg' function in Klong interpeter and call it directly from Python.
162
- r = klong['avg'](data)
163
-
164
- print(f"avg={np.round(r,6)}")
165
- ```
166
-
167
- And let's run a performance comparison between CPU and GPU backends:
168
-
169
- ```python
170
- import time
171
- from klongpy.backend import np
172
- from klongpy import KlongInterpreter
173
-
174
- klong = KlongInterpreter()
175
- klong('avg::{(+/x)%#x}')
176
-
177
- data = np.random.rand(10**9)
178
-
179
- start = time.perf_counter_ns()
180
- r = klong['avg'](data)
181
- stop = time.perf_counter_ns()
182
-
183
- print(f"avg={np.round(r,6)} in {round((stop - start) / (10**9), 6)} seconds")
184
- ```
185
-
186
- Run (CPU)
187
-
188
- $ python3 tests/perf_avg.py
189
- avg=0.5 in 0.16936 seconds
190
-
191
- Run (GPU)
192
-
193
- $ USE_GPU=1 python3 tests/perf_avg.py
194
- avg=0.500015 in 0.027818 seconds
195
-
196
- # Installation
197
-
198
- ### CPU
199
-
200
- $ pip3 install klongpy
201
-
202
- ### GPU support
203
-
204
- Choose your CuPy prebuilt binary or from source. Note, the [ROCM](docs/ROCM.md) support for CuPy is experimental and likely will have issues.
205
-
206
- 'cupy' => build from source
207
- 'cuda12x' => "cupy-cuda12x"
208
- 'cuda11x' => "cupy-cuda11x"
209
- 'cuda111' => "cupy-cuda111"
210
- 'cuda110' => "cupy-cuda110"
211
- 'cuda102' => "cupy-cuda102"
212
- 'rocm-5-0' => "cupy-rocm-5-0"
213
- 'rocm-4-3' => "cupy-rocm-4-3"
214
-
215
- $ pip3 install klongpy[cupy]
216
-
217
- ### All application tools (db, web, REPL, etc.)
218
-
219
- $ pip3 install "klongpy[full]"
220
-
221
-
222
- # REPL
223
-
224
- KlongPy has a REPL similar to Klong's REPL.
225
-
226
- ```bash
227
- $ pip3 install klongpy[repl]
228
- $ rlwrap kgpy
229
-
230
- Welcome to KlongPy REPL
231
- author: Brian Guarraci
232
- repo : https://github.com/briangu/klongpy
233
- crtl-c to quit
234
-
235
- ?> 1+1
236
- 2
237
- >? "hello, world!"
238
- hello, world!
239
- ?> prime::{&/x!:\2+!_x^1%2}
240
- :monad
241
- ?> prime(4)
242
- 0
243
- ?> prime(251)
244
- 1
245
- ?> ]T prime(251)
246
- total: 0.0004914579913020134 per: 0.0004914579913020134
247
- ```
248
-
249
- Read about the [prime example here](https://t3x.org/klong/prime.html).
250
-
251
-
252
- # Status
253
-
254
- KlongPy aims to be a complete implementation of klong. It currently passes all of the integration tests provided by klong as well as additional suites.
255
-
256
- Since CuPy is [not 100% compatible with NumPy](https://docs.cupy.dev/en/stable/user_guide/difference.html), there are currently some gaps in KlongPy between the two backends. Notably, strings are supported in CuPy arrays so KlongPy GPU support currently is limited to math.
257
-
258
- Primary ongoing work includes:
259
-
260
- * Additional tools to make KlongPy applications more capable.
261
- * Additional syntax error help
262
- * Actively switch between CuPy and NumPy when incompatibilities are present
263
- * Work on CuPy kernels is in this branch: _cupy_reduce_kernels
264
-
265
- # Differences from Klong
266
-
267
- KlongPy is effectively a superset of the Klong language, but has some key differences:
268
-
269
- * Infinite precision: The main difference in this implementation of Klong is the lack of infinite precision. By using NumPy we are restricted to doubles.
270
- * Python integration: Most notably, the ".py" command allows direct import of Python modules into the current Klong context.
271
- * IPC - KlongPy supports IPC between KlongPy processes.
272
-
273
- # Related
274
-
275
- * [Klupyter - KlongPy in Jupyter Notebooks](https://github.com/briangu/klupyter)
276
- * [Advent Of Code '22](https://github.com/briangu/aoc/tree/main/22)
277
-
278
-
279
- # Unused operators
280
-
281
- The following operators are yet to be used:
282
-
283
- ```
284
- :! :& :, :< :> :?
285
- ```
286
-
287
- # Contribute
288
-
289
- ### Develop
290
-
291
- $ git clone https://github.com/briangu/klongpy.git
292
- $ cd klongpy
293
- $ python3 setup.py develop
294
-
295
- ### Running tests
296
-
297
- ```bash
298
- python3 -m unittest
299
- ```
300
-
301
-
302
- # Acknowledgement
303
-
304
- HUGE thanks to Nils M Holm for his work on Klong and providing the foundations for this interesting project.
305
-
File without changes