|
| 1 | +--- |
| 2 | +title: PyTorch Conversions |
| 3 | +description: PyTorch Tensor Conversions beta feature in PyKX |
| 4 | +date: January 2025 |
| 5 | +author: KX Systems, Inc., |
| 6 | +tags: PyKX, PyTorch Tensor |
| 7 | +--- |
| 8 | +# PyTorch Conversions |
| 9 | + |
| 10 | +_This page provides an overview of PyTorch Conversions, a beta feature in PyKX._ |
| 11 | + |
| 12 | +!!! Warning |
| 13 | + |
| 14 | + This functionality is provided as a Beta Feature and is subject to change. To enable this functionality for testing please follow the configuration instructions [here](../user-guide/configuration.md) setting `PYKX_BETA_FEATURES='true'`. |
| 15 | + |
| 16 | +## Introduction |
| 17 | + |
| 18 | +Commonly used in the development of complex machine learning algorithms, PyTorch is a machine learning library based on the Torch library and is used in applications such as computer vision and natural language processing. Originally developed by Meta AI it is now widely used in the open-source community for algorithm development. |
| 19 | + |
| 20 | +This beta feature allows PyKX users to convert PyKX Vector/List objects into their PyTorch [Tensor](https://pytorch.org/docs/stable/tensors.html) equivalents. |
| 21 | + |
| 22 | +## Requirements and limitations |
| 23 | + |
| 24 | + |
| 25 | +Before you run this functionality, first you must install `torch>2.1` in your local Python session, by using the following command: |
| 26 | + |
| 27 | +```bash |
| 28 | +pip install pykx[torch] |
| 29 | +``` |
| 30 | + |
| 31 | +## Functional walkthrough |
| 32 | + |
| 33 | +This walkthrough demonstrates the following steps: |
| 34 | + |
| 35 | +1. Convert a PyKX Vector object to a Tensor object. |
| 36 | +1. Convert a PyKX List object to a Tensor object. |
| 37 | +1. Convert a Tensor object to a PyKX equivalent object. |
| 38 | + |
| 39 | +### Vector to Tensor |
| 40 | + |
| 41 | +Use the `*.pt()` methods to convert PyKX numeric data representations to Tensor objects. In the example below we convert PyKX numeric types to their PyTorch Tensor equivalents: |
| 42 | + |
| 43 | +```python |
| 44 | +>>> import os |
| 45 | +>>> os.environ['PYKX_BETA_FEATURES'] = 'True' |
| 46 | +>>> import pykx as kx |
| 47 | +>>> svec = kx.q('1 2 3h') |
| 48 | +>>> lvec = kx.q('1 2 3j') |
| 49 | +>>> rvec = kx.q('1 2 3e') |
| 50 | +>>> fvec = kx.q('1 2 3f') |
| 51 | +>>> svec.pt() |
| 52 | +tensor([1, 2, 3], dtype=torch.int16) |
| 53 | +>>> lvec.pt() |
| 54 | +tensor([1, 2, 3]) |
| 55 | +>>> rvec.pt() |
| 56 | +tensor([1., 2., 3.]) |
| 57 | +>>> fvec.pt() |
| 58 | +tensor([1., 2., 3.], dtype=torch.float64) |
| 59 | +``` |
| 60 | + |
| 61 | +In particular note in the above that the data types are converted to their Tensor size equivalent. |
| 62 | + |
| 63 | +### List to Tensor |
| 64 | + |
| 65 | +To convert PyKX List objects to Tensors, two criteria must be met: |
| 66 | + |
| 67 | +1. The `#!python pykx.List` contains only data of a single type. |
| 68 | +1. The `#!python pykx.List` is an N-Dimensional regularly shaped/rectangular structure. |
| 69 | + |
| 70 | +By default conversions to a `#!python torch.Tensor` object test for these criteria and it throws an error if they are not met as follows: |
| 71 | + |
| 72 | +```python |
| 73 | +>>> import os |
| 74 | +>>> os.environ['PYKX_BETA_FEATURES'] = 'True' |
| 75 | +>>> import pykx as kx |
| 76 | +>>> kx.q('(1 2;2 3f)').pt() |
| 77 | +TypeError: Data must be a singular type "rectangular" matrix |
| 78 | +``` |
| 79 | + |
| 80 | +A working example of this is as follows: |
| 81 | + |
| 82 | +```python |
| 83 | +>>> kx.q('100 100 100#1000000?1f').pt() |
| 84 | +tensor([[[0.3928, 0.5171, 0.5160, ..., 0.3410, 0.8618, 0.5549], |
| 85 | + [0.0617, 0.2858, 0.6685, ..., 0.9234, 0.4016, 0.5619], |
| 86 | + [0.7249, 0.8112, 0.2087, ..., 0.3187, 0.1873, 0.8416], |
| 87 | + ..., |
| 88 | + dtype=torch.float64) |
| 89 | +``` |
| 90 | + |
| 91 | +Having to pre-compute the shape of the data can slow down the processing of large matrices. To avoid this, if you already know the final shape of the tensor, you can specify it using the `#!python reshape` keyword in advance. |
| 92 | + |
| 93 | +```python |
| 94 | +>>> kx.q('100 100 100#1000000?1f').pt(reshape=[100, 100, 100]) |
| 95 | +tensor([[[0.3928, 0.5171, 0.5160, ..., 0.3410, 0.8618, 0.5549], |
| 96 | + [0.0617, 0.2858, 0.6685, ..., 0.9234, 0.4016, 0.5619], |
| 97 | + [0.7249, 0.8112, 0.2087, ..., 0.3187, 0.1873, 0.8416], |
| 98 | + ..., |
| 99 | + dtype=torch.float64) |
| 100 | +``` |
| 101 | + |
| 102 | +While not clear from the above for particularly complex nested `#!python pykx.List` objects setting the data shape can provide significant performance boosts: |
| 103 | + |
| 104 | +```python |
| 105 | +lst = kx.q('100 100 100 100#100000000?1f') |
| 106 | +%timeit lst.pt() |
| 107 | +# 1.22 s ± 24.4 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) |
| 108 | +%timeit lst.pt(reshape=[100, 100, 100, 100]) |
| 109 | +# 265 ms ± 4.96 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) |
| 110 | +``` |
0 commit comments