Torchvision+ Deformable Convolution Networks
========
[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/inspiros/tvdcn/build_wheels.yml)](https://github.com/inspiros/tvdcn/actions)
[![PyPI](https://img.shields.io/pypi/v/tvdcn)](https://pypi.org/project/tvdcn)
[![Downloads](https://static.pepy.tech/badge/tvdcn)](https://pepy.tech/project/tvdcn)
[![GitHub](https://img.shields.io/github/license/inspiros/tvdcn)](LICENSE.txt)
This package contains the PyTorch implementations of the **Deformable Convolution** operation
(the commonly used `torchvision.ops.deform_conv2d`) proposed in https://arxiv.org/abs/1811.11168,
and the **Transposed Deformable Convolution** proposed in https://arxiv.org/abs/2210.09446
(currently without interpolation kernel scaling).
It also supports their **1D** and **3D** equivalences, which are not available in `torchvision` (thus the name).
## Highlights
- **Supported operators:** _(All are implemented in C++/Cuda)_
- `tvdcn.ops.deform_conv1d`
- `tvdcn.ops.deform_conv2d` _(faster than `torchvision.ops.deform_conv2d` by at least 10% during forward pass
on our **Quadro RTX 5000** according to [this test](tests/test_speed.py))_
- `tvdcn.ops.deform_conv3d`
- `tvdcn.ops.deform_conv_transpose1d`
- `tvdcn.ops.deform_conv_transpose2d`
- `tvdcn.ops.deform_conv_transpose3d`
- And the following **supplementary operators** (`mask` activation proposed in https://arxiv.org/abs/2211.05778):
- `tvdcn.ops.mask_softmax1d`
- `tvdcn.ops.mask_softmax2d`
- `tvdcn.ops.mask_softmax3d`
- Both `offset` and `mask` can be turned off, and can be applied in separate groups.
- All the `nn.Module` wrappers for these operators are implemented,
everything is `@torch.jit.script`-able! Please check [Usage](#usage).
**Note:** We don't care much about `onnx` exportation, but if you do, you can check this repo:
https://github.com/masamitsu-murase/deform_conv2d_onnx_exporter.
## Requirements
- `torch>=2.1.0` (``torch>=1.9.0`` if installed from source)
## Installation
#### From PyPI:
[tvdcn](https://pypi.org/project/tvdcn) provides some prebuilt wheels on **PyPI**.
Run this command to install:
```terminal
pip install tvdcn
```
Since **PyTorch** is migrating to Cuda 12 versions,
our Linux and Windows wheels are built with **Cuda 12.1** and won't be compatible with older versions.
| | Linux/Windows | MacOS |
|------------------|:----------------------------------------:|:--------------:|
| Python version: | 3.8-3.11 | 3.8-3.11 |
| PyTorch version: | `torch==2.1.0` | `torch==2.1.0` |
| Cuda version: | 12.1 | - |
| GPU CCs: | `5.0,6.0,6.1,7.0,7.5,8.0,8.6,9.0+PTX` | - |
When the Cuda versions of ``torch`` and ``tvdcn`` mismatch, you will see an error like this:
```terminal
RuntimeError: Detected that PyTorch and Extension were compiled with different CUDA versions.
PyTorch has CUDA Version=11.8 and Extension has CUDA Version=12.1.
Please reinstall the Extension that matches your PyTorch install.
```
If you see this error instead, that means there are other issues related to Python, PyTorch, device arch, e.t.c.
Please proceed to [instructions to build from source](#from-source), all steps are super easy.
```terminal
RuntimeError: Couldn't load custom C++ ops. Recompile C++ extension with:
python setup.py build_ext --inplace
```
#### From Source:
For installing from source, you need a C++ compiler (`gcc`/`msvc`) and a Cuda compiler (`nvcc`) with C++17 features
enabled.
Clone this repo and execute the following command:
```terminal
pip install .
```
Or just compile the binary for inplace usage:
```terminal
python setup.py build_ext --inplace
```
A binary (`.so` file for Unix and `.pyd` file for Windows) should be compiled inside the `tvdcn` folder.
To check if installation is successful, try:
```python
import tvdcn
print('Library loaded successfully:', tvdcn.has_ops())
print('Compiled with Cuda:', tvdcn.with_cuda())
```
**Note:** We use soft Cuda version compatibility checking between the built binary and the installed PyTorch,
which means only major version matching is required.
However, we suggest building the binaries with the same Cuda version with installed PyTorch's Cuda version to prevent
any possible conflict.
## Usage
#### Operators:
Functionally, the package offers 6 functions (listed in [Highlights](#highlights)) much similar to
`torchvision.ops.deform_conv2d`.
However, the order of parameters is slightly different, so be cautious
(check [this comparison](tests/test_compatibility_with_torchvision.py)).
<table>
<tr>
<th>torchvision</th>
<th>tvdcn</th>
</tr>
<tr>
<td>
<sub>
```python
import torch, torchvision
input = torch.rand(4, 3, 10, 10)
kh, kw = 3, 3
weight = torch.rand(5, 3, kh, kw)
offset = torch.rand(4, 2 * kh * kw, 8, 8)
mask = torch.rand(4, kh * kw, 8, 8)
bias = torch.rand(5)
output = torchvision.ops.deform_conv2d(input, offset, weight, bias,
stride=(1, 1),
padding=(0, 0),
dilation=(1, 1),
mask=mask)
print(output)
```
</sub>
<td>
<sub>
```python
import torch, tvdcn
input = torch.rand(4, 3, 10, 10)
kh, kw = 3, 3
weight = torch.rand(5, 3, kh, kw)
offset = torch.rand(4, 2 * kh * kw, 8, 8)
mask = torch.rand(4, kh * kw, 8, 8)
bias = torch.rand(5)
output = tvdcn.ops.deform_conv2d(input, weight, offset, mask, bias,
stride=(1, 1),
padding=(0, 0),
dilation=(1, 1),
groups=1)
print(output)
```
</sub>
</td>
</tr>
</table>
Specifically, the signatures of `deform_conv2d` and `deform_conv_transpose2d` look like these:
```python
def deform_conv2d(
input: Tensor,
weight: Tensor,
offset: Optional[Tensor] = None,
mask: Optional[Tensor] = None,
bias: Optional[Tensor] = None,
stride: Union[int, Tuple[int, int]] = 1,
padding: Union[int, Tuple[int, int]] = 0,
dilation: Union[int, Tuple[int, int]] = 1,
groups: int = 1) -> Tensor:
...
def deform_conv_transpose2d(
input: Tensor,
weight: Tensor,
offset: Optional[Tensor] = None,
mask: Optional[Tensor] = None,
bias: Optional[Tensor] = None,
stride: Union[int, Tuple[int, int]] = 1,
padding: Union[int, Tuple[int, int]] = 0,
output_padding: Union[int, Tuple[int, int]] = 0,
dilation: Union[int, Tuple[int, int]] = 1,
groups: int = 1) -> Tensor:
...
```
If `offset=None` and `mask=None`, the executed operators are identical to conventional convolution.
#### Neural Network Layers:
The `nn.Module` wrappers are:
- `tvdcn.ops.DeformConv1d`
- `tvdcn.ops.DeformConv2d`
- `tvdcn.ops.DeformConv3d`
- `tvdcn.ops.DeformConvTranspose1d`
- `tvdcn.ops.DeformConvTranspose2d`
- `tvdcn.ops.DeformConvTranspose3d`
They are subclasses of the `torch.nn.modules._ConvNd`,
but you have to specify `offset` and optionally `mask` as extra inputs for the `forward` function.
For example:
```python
import torch
from tvdcn import DeformConv2d
input = torch.rand(2, 3, 64, 64)
offset = torch.rand(2, 2 * 3 * 3, 62, 62)
# if mask is None, perform the original deform_conv without modulation (v2)
mask = torch.rand(2, 1 * 3 * 3, 62, 62)
conv = DeformConv2d(3, 16, kernel_size=(3, 3))
output = conv(input, offset, mask)
print(output.shape)
```
Additionally, following many other implementations out there, we also implemented the _packed_ wrappers:
- `tvdcn.ops.PackedDeformConv1d`
- `tvdcn.ops.PackedDeformConv2d`
- `tvdcn.ops.PackedDeformConv3d`
- `tvdcn.ops.PackedDeformConvTranspose1d`
- `tvdcn.ops.PackedDeformConvTranspose2d`
- `tvdcn.ops.PackedDeformConvTranspose3d`
These are easy-to-use classes that contain ordinary convolution layers with appropriate hyperparameters to generate
`offset` (and `mask` if initialized with `modulated=True`);
but that means less customization.
The only tunable hyperparameters that effect these supplementary conv layers are `offset_groups` and `mask_groups`,
which have been decoupled from and behave somewhat similar to `groups`.
To use the softmax activation for mask proposed in [Deformable Convolution v3](https://arxiv.org/abs/2211.05778),
set `mask_activation='softmax'`. `offset_activation` and `mask_activation` also accept any `nn.Module`.
```python
import torch
from tvdcn import PackedDeformConv1d
input = torch.rand(2, 3, 128)
conv = PackedDeformConv1d(3, 16,
kernel_size=5,
modulated=True,
mask_activation='softmax')
# jit scripting
scripted_conv = torch.jit.script(conv)
print(scripted_conv)
output = scripted_conv(input)
print(output.shape)
```
**Note:** For transposed packed modules, we are generating `offset` and `mask` with pointwise convolution
as we haven't found a better way to do it.
Do check the [examples](examples) folder, maybe you can find something helpful.
## Acknowledgements
This _for fun_ project is directly modified and extended from `torchvision.ops.deform_conv2d`.
## License
The code is released under the MIT license. See [`LICENSE.txt`](LICENSE.txt) for details.
Raw data
{
"_id": null,
"home_page": "https://github.com/inspiros/tvdcn",
"name": "tvdcn",
"maintainer": "",
"docs_url": null,
"requires_python": ">=3.8",
"maintainer_email": "",
"keywords": "deform_conv,deform_conv_transposed,deformable_convolution,transposed_deformable_convolution",
"author": "Hoang-Nhat Tran (inspiros)",
"author_email": "hnhat.tran@gmail.com",
"download_url": "https://files.pythonhosted.org/packages/6a/96/7d947180f05248932878211ed665ead5d00ac2bf9320d8a4786913d59a8e/tvdcn-0.5.0.tar.gz",
"platform": null,
"description": "Torchvision+ Deformable Convolution Networks\n========\n[![GitHub Workflow Status](https://img.shields.io/github/actions/workflow/status/inspiros/tvdcn/build_wheels.yml)](https://github.com/inspiros/tvdcn/actions)\n[![PyPI](https://img.shields.io/pypi/v/tvdcn)](https://pypi.org/project/tvdcn)\n[![Downloads](https://static.pepy.tech/badge/tvdcn)](https://pepy.tech/project/tvdcn)\n[![GitHub](https://img.shields.io/github/license/inspiros/tvdcn)](LICENSE.txt)\n\nThis package contains the PyTorch implementations of the **Deformable Convolution** operation\n(the commonly used `torchvision.ops.deform_conv2d`) proposed in https://arxiv.org/abs/1811.11168,\nand the **Transposed Deformable Convolution** proposed in https://arxiv.org/abs/2210.09446\n(currently without interpolation kernel scaling).\nIt also supports their **1D** and **3D** equivalences, which are not available in `torchvision` (thus the name).\n\n## Highlights\n\n- **Supported operators:** _(All are implemented in C++/Cuda)_\n - `tvdcn.ops.deform_conv1d`\n - `tvdcn.ops.deform_conv2d` _(faster than `torchvision.ops.deform_conv2d` by at least 10% during forward pass\n on our **Quadro RTX 5000** according to [this test](tests/test_speed.py))_\n - `tvdcn.ops.deform_conv3d`\n - `tvdcn.ops.deform_conv_transpose1d`\n - `tvdcn.ops.deform_conv_transpose2d`\n - `tvdcn.ops.deform_conv_transpose3d`\n\n- And the following **supplementary operators** (`mask` activation proposed in https://arxiv.org/abs/2211.05778):\n - `tvdcn.ops.mask_softmax1d`\n - `tvdcn.ops.mask_softmax2d`\n - `tvdcn.ops.mask_softmax3d`\n\n- Both `offset` and `mask` can be turned off, and can be applied in separate groups.\n\n- All the `nn.Module` wrappers for these operators are implemented,\n everything is `@torch.jit.script`-able! Please check [Usage](#usage).\n\n**Note:** We don't care much about `onnx` exportation, but if you do, you can check this repo:\nhttps://github.com/masamitsu-murase/deform_conv2d_onnx_exporter.\n\n## Requirements\n\n- `torch>=2.1.0` (``torch>=1.9.0`` if installed from source)\n\n## Installation\n\n#### From PyPI:\n\n[tvdcn](https://pypi.org/project/tvdcn) provides some prebuilt wheels on **PyPI**.\nRun this command to install:\n\n```terminal\npip install tvdcn\n```\n\nSince **PyTorch** is migrating to Cuda 12 versions,\nour Linux and Windows wheels are built with **Cuda 12.1** and won't be compatible with older versions.\n\n| | Linux/Windows | MacOS |\n|------------------|:----------------------------------------:|:--------------:|\n| Python version: | 3.8-3.11 | 3.8-3.11 |\n| PyTorch version: | `torch==2.1.0` | `torch==2.1.0` |\n| Cuda version: | 12.1 | - |\n| GPU CCs: | `5.0,6.0,6.1,7.0,7.5,8.0,8.6,9.0+PTX` | - |\n\nWhen the Cuda versions of ``torch`` and ``tvdcn`` mismatch, you will see an error like this:\n\n```terminal\nRuntimeError: Detected that PyTorch and Extension were compiled with different CUDA versions.\nPyTorch has CUDA Version=11.8 and Extension has CUDA Version=12.1.\nPlease reinstall the Extension that matches your PyTorch install.\n```\n\nIf you see this error instead, that means there are other issues related to Python, PyTorch, device arch, e.t.c.\nPlease proceed to [instructions to build from source](#from-source), all steps are super easy.\n\n```terminal\nRuntimeError: Couldn't load custom C++ ops. Recompile C++ extension with:\n python setup.py build_ext --inplace\n```\n\n#### From Source:\n\nFor installing from source, you need a C++ compiler (`gcc`/`msvc`) and a Cuda compiler (`nvcc`) with C++17 features\nenabled.\nClone this repo and execute the following command:\n\n```terminal\npip install .\n```\n\nOr just compile the binary for inplace usage:\n\n```terminal\npython setup.py build_ext --inplace\n```\n\nA binary (`.so` file for Unix and `.pyd` file for Windows) should be compiled inside the `tvdcn` folder.\nTo check if installation is successful, try:\n\n```python\nimport tvdcn\n\nprint('Library loaded successfully:', tvdcn.has_ops())\nprint('Compiled with Cuda:', tvdcn.with_cuda())\n```\n\n**Note:** We use soft Cuda version compatibility checking between the built binary and the installed PyTorch,\nwhich means only major version matching is required.\nHowever, we suggest building the binaries with the same Cuda version with installed PyTorch's Cuda version to prevent\nany possible conflict.\n\n## Usage\n\n#### Operators:\n\nFunctionally, the package offers 6 functions (listed in [Highlights](#highlights)) much similar to\n`torchvision.ops.deform_conv2d`.\nHowever, the order of parameters is slightly different, so be cautious\n(check [this comparison](tests/test_compatibility_with_torchvision.py)).\n\n\n<table>\n<tr>\n<th>torchvision</th>\n<th>tvdcn</th>\n</tr>\n\n<tr>\n<td>\n<sub>\n\n```python\nimport torch, torchvision\n\ninput = torch.rand(4, 3, 10, 10)\nkh, kw = 3, 3\nweight = torch.rand(5, 3, kh, kw)\noffset = torch.rand(4, 2 * kh * kw, 8, 8)\nmask = torch.rand(4, kh * kw, 8, 8)\nbias = torch.rand(5)\n\noutput = torchvision.ops.deform_conv2d(input, offset, weight, bias,\n stride=(1, 1),\n padding=(0, 0),\n dilation=(1, 1),\n mask=mask)\nprint(output)\n```\n\n</sub>\n<td>\n<sub>\n\n```python\nimport torch, tvdcn\n\ninput = torch.rand(4, 3, 10, 10)\nkh, kw = 3, 3\nweight = torch.rand(5, 3, kh, kw)\noffset = torch.rand(4, 2 * kh * kw, 8, 8)\nmask = torch.rand(4, kh * kw, 8, 8)\nbias = torch.rand(5)\n\noutput = tvdcn.ops.deform_conv2d(input, weight, offset, mask, bias,\n stride=(1, 1),\n padding=(0, 0),\n dilation=(1, 1),\n groups=1)\nprint(output)\n```\n\n</sub>\n</td>\n</tr>\n\n</table>\n\nSpecifically, the signatures of `deform_conv2d` and `deform_conv_transpose2d` look like these:\n\n```python\ndef deform_conv2d(\n input: Tensor,\n weight: Tensor,\n offset: Optional[Tensor] = None,\n mask: Optional[Tensor] = None,\n bias: Optional[Tensor] = None,\n stride: Union[int, Tuple[int, int]] = 1,\n padding: Union[int, Tuple[int, int]] = 0,\n dilation: Union[int, Tuple[int, int]] = 1,\n groups: int = 1) -> Tensor:\n ...\n\n\ndef deform_conv_transpose2d(\n input: Tensor,\n weight: Tensor,\n offset: Optional[Tensor] = None,\n mask: Optional[Tensor] = None,\n bias: Optional[Tensor] = None,\n stride: Union[int, Tuple[int, int]] = 1,\n padding: Union[int, Tuple[int, int]] = 0,\n output_padding: Union[int, Tuple[int, int]] = 0,\n dilation: Union[int, Tuple[int, int]] = 1,\n groups: int = 1) -> Tensor:\n ...\n```\n\nIf `offset=None` and `mask=None`, the executed operators are identical to conventional convolution.\n\n#### Neural Network Layers:\n\nThe `nn.Module` wrappers are:\n\n- `tvdcn.ops.DeformConv1d`\n- `tvdcn.ops.DeformConv2d`\n- `tvdcn.ops.DeformConv3d`\n- `tvdcn.ops.DeformConvTranspose1d`\n- `tvdcn.ops.DeformConvTranspose2d`\n- `tvdcn.ops.DeformConvTranspose3d`\n\nThey are subclasses of the `torch.nn.modules._ConvNd`,\nbut you have to specify `offset` and optionally `mask` as extra inputs for the `forward` function.\nFor example:\n\n```python\nimport torch\n\nfrom tvdcn import DeformConv2d\n\ninput = torch.rand(2, 3, 64, 64)\noffset = torch.rand(2, 2 * 3 * 3, 62, 62)\n# if mask is None, perform the original deform_conv without modulation (v2)\nmask = torch.rand(2, 1 * 3 * 3, 62, 62)\n\nconv = DeformConv2d(3, 16, kernel_size=(3, 3))\n\noutput = conv(input, offset, mask)\nprint(output.shape)\n```\n\nAdditionally, following many other implementations out there, we also implemented the _packed_ wrappers:\n\n- `tvdcn.ops.PackedDeformConv1d`\n- `tvdcn.ops.PackedDeformConv2d`\n- `tvdcn.ops.PackedDeformConv3d`\n- `tvdcn.ops.PackedDeformConvTranspose1d`\n- `tvdcn.ops.PackedDeformConvTranspose2d`\n- `tvdcn.ops.PackedDeformConvTranspose3d`\n\nThese are easy-to-use classes that contain ordinary convolution layers with appropriate hyperparameters to generate\n`offset` (and `mask` if initialized with `modulated=True`);\nbut that means less customization.\nThe only tunable hyperparameters that effect these supplementary conv layers are `offset_groups` and `mask_groups`,\nwhich have been decoupled from and behave somewhat similar to `groups`.\n\nTo use the softmax activation for mask proposed in [Deformable Convolution v3](https://arxiv.org/abs/2211.05778),\nset `mask_activation='softmax'`. `offset_activation` and `mask_activation` also accept any `nn.Module`.\n\n```python\nimport torch\n\nfrom tvdcn import PackedDeformConv1d\n\ninput = torch.rand(2, 3, 128)\n\nconv = PackedDeformConv1d(3, 16,\n kernel_size=5,\n modulated=True,\n mask_activation='softmax')\n# jit scripting\nscripted_conv = torch.jit.script(conv)\nprint(scripted_conv)\n\noutput = scripted_conv(input)\nprint(output.shape)\n```\n\n**Note:** For transposed packed modules, we are generating `offset` and `mask` with pointwise convolution\nas we haven't found a better way to do it.\n\nDo check the [examples](examples) folder, maybe you can find something helpful.\n\n## Acknowledgements\n\nThis _for fun_ project is directly modified and extended from `torchvision.ops.deform_conv2d`.\n\n## License\n\nThe code is released under the MIT license. See [`LICENSE.txt`](LICENSE.txt) for details.\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Torchvision+ Deformable Convolutional Networks",
"version": "0.5.0",
"project_urls": {
"Homepage": "https://github.com/inspiros/tvdcn",
"Source": "https://github.com/inspiros/tvdcn"
},
"split_keywords": [
"deform_conv",
"deform_conv_transposed",
"deformable_convolution",
"transposed_deformable_convolution"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "c0acee17219d7bcd45a3cf20f17c0be29c7c85a7b91e19d50e2f57f97c1af710",
"md5": "9ceece4044f16dc5efbaa052210ea02a",
"sha256": "f58a8affba5c62ff3b4dd266b8b40cc1ebdd5c29d33eda77c4efe2a4388a0671"
},
"downloads": -1,
"filename": "tvdcn-0.5.0-cp310-cp310-macosx_10_9_x86_64.whl",
"has_sig": false,
"md5_digest": "9ceece4044f16dc5efbaa052210ea02a",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.8",
"size": 479463,
"upload_time": "2023-10-14T07:35:32",
"upload_time_iso_8601": "2023-10-14T07:35:32.668800Z",
"url": "https://files.pythonhosted.org/packages/c0/ac/ee17219d7bcd45a3cf20f17c0be29c7c85a7b91e19d50e2f57f97c1af710/tvdcn-0.5.0-cp310-cp310-macosx_10_9_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "90823e7d848d02b3fd10eb04f6a145f967a3f25f6cabf1fb5cc688cb95a46319",
"md5": "370ee0de3adb91cc9055e827c5a579aa",
"sha256": "856e5a9bb231f47da742ce7e949524e24e041f6f3ffa23496e6ed671bf3dff8f"
},
"downloads": -1,
"filename": "tvdcn-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "370ee0de3adb91cc9055e827c5a579aa",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.8",
"size": 32207477,
"upload_time": "2023-10-14T07:35:35",
"upload_time_iso_8601": "2023-10-14T07:35:35.439985Z",
"url": "https://files.pythonhosted.org/packages/90/82/3e7d848d02b3fd10eb04f6a145f967a3f25f6cabf1fb5cc688cb95a46319/tvdcn-0.5.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "5752cfa34d59a21dd1c87831116eadc6fb801b28cbf829243b4f9147d5cb09fd",
"md5": "da2923a24606dcb2abfc09dea0aa560b",
"sha256": "67130e2a83735f71b1d3f02cbbdb2c8f9f3947f2a012440570d62b983da6cad1"
},
"downloads": -1,
"filename": "tvdcn-0.5.0-cp310-cp310-win_amd64.whl",
"has_sig": false,
"md5_digest": "da2923a24606dcb2abfc09dea0aa560b",
"packagetype": "bdist_wheel",
"python_version": "cp310",
"requires_python": ">=3.8",
"size": 8773746,
"upload_time": "2023-10-14T07:35:38",
"upload_time_iso_8601": "2023-10-14T07:35:38.807022Z",
"url": "https://files.pythonhosted.org/packages/57/52/cfa34d59a21dd1c87831116eadc6fb801b28cbf829243b4f9147d5cb09fd/tvdcn-0.5.0-cp310-cp310-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "af91e30719ef0979746ce552f66ade8eca1525b6954176b30ce2f450a5aa08fc",
"md5": "ab5c10895ef6e6dc0ac46ef84a6691cf",
"sha256": "d7c37281c7a70ed375696248fa3c36515150d7bece76943adc6d743041628c84"
},
"downloads": -1,
"filename": "tvdcn-0.5.0-cp311-cp311-macosx_10_9_x86_64.whl",
"has_sig": false,
"md5_digest": "ab5c10895ef6e6dc0ac46ef84a6691cf",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.8",
"size": 479468,
"upload_time": "2023-10-14T07:35:40",
"upload_time_iso_8601": "2023-10-14T07:35:40.903202Z",
"url": "https://files.pythonhosted.org/packages/af/91/e30719ef0979746ce552f66ade8eca1525b6954176b30ce2f450a5aa08fc/tvdcn-0.5.0-cp311-cp311-macosx_10_9_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "7926637f4556ad4956faead3b6a60c780d2ec1febab38faaef41f9f594cb9b24",
"md5": "a91509a680bd74b2782ac8f6b973e863",
"sha256": "ef09d49196a89f119f5237b92552a35ef12aa1ac5476864c1f5b16b3274c67bf"
},
"downloads": -1,
"filename": "tvdcn-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "a91509a680bd74b2782ac8f6b973e863",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.8",
"size": 32207546,
"upload_time": "2023-10-14T07:35:43",
"upload_time_iso_8601": "2023-10-14T07:35:43.803305Z",
"url": "https://files.pythonhosted.org/packages/79/26/637f4556ad4956faead3b6a60c780d2ec1febab38faaef41f9f594cb9b24/tvdcn-0.5.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "8f1a1fef6e57f3001f1df0392ef92834210e3849d2e85939015706bcc82fd1c4",
"md5": "db466d16ea4629867a8952b19e909553",
"sha256": "369a6168abbb1086b3a83ebaef13d3808769b28323954775fdb12055ddb90f1a"
},
"downloads": -1,
"filename": "tvdcn-0.5.0-cp311-cp311-win_amd64.whl",
"has_sig": false,
"md5_digest": "db466d16ea4629867a8952b19e909553",
"packagetype": "bdist_wheel",
"python_version": "cp311",
"requires_python": ">=3.8",
"size": 8773738,
"upload_time": "2023-10-14T07:35:47",
"upload_time_iso_8601": "2023-10-14T07:35:47.070363Z",
"url": "https://files.pythonhosted.org/packages/8f/1a/1fef6e57f3001f1df0392ef92834210e3849d2e85939015706bcc82fd1c4/tvdcn-0.5.0-cp311-cp311-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "832b96d2da7f284ec7a80961609c1ce8756a2ac8341aa2c39b6fc210f38793af",
"md5": "6b253ac14e771c3a130e3b0798b2a046",
"sha256": "bbfc88e01f27ebc22aff9ac4c23e30c5f04c0c0994dbf409f0e733510c5e2368"
},
"downloads": -1,
"filename": "tvdcn-0.5.0-cp38-cp38-macosx_10_9_x86_64.whl",
"has_sig": false,
"md5_digest": "6b253ac14e771c3a130e3b0798b2a046",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 479489,
"upload_time": "2023-10-14T07:35:49",
"upload_time_iso_8601": "2023-10-14T07:35:49.750670Z",
"url": "https://files.pythonhosted.org/packages/83/2b/96d2da7f284ec7a80961609c1ce8756a2ac8341aa2c39b6fc210f38793af/tvdcn-0.5.0-cp38-cp38-macosx_10_9_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "be854b3b4fcde8150ea6c9cb0c8de25e30c3cd7590bfea417b52c8b2546e06af",
"md5": "2209755527c2b1550a72ea8c52181592",
"sha256": "57b02723627659e728a9fa8271e139711ffc597c2efa43550361f659a7c4be48"
},
"downloads": -1,
"filename": "tvdcn-0.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "2209755527c2b1550a72ea8c52181592",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 32207359,
"upload_time": "2023-10-14T07:35:52",
"upload_time_iso_8601": "2023-10-14T07:35:52.399203Z",
"url": "https://files.pythonhosted.org/packages/be/85/4b3b4fcde8150ea6c9cb0c8de25e30c3cd7590bfea417b52c8b2546e06af/tvdcn-0.5.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "a32b52909fe1561c66a1cdfa297cb7d9fab46f0987297910076b291d53b5c171",
"md5": "c5208eea3c275e96bba57c8828a31514",
"sha256": "a909eaca87470b27f1594a9d372320797b877aea7434b5cf1f236fe488a87505"
},
"downloads": -1,
"filename": "tvdcn-0.5.0-cp38-cp38-win_amd64.whl",
"has_sig": false,
"md5_digest": "c5208eea3c275e96bba57c8828a31514",
"packagetype": "bdist_wheel",
"python_version": "cp38",
"requires_python": ">=3.8",
"size": 8773711,
"upload_time": "2023-10-14T07:35:55",
"upload_time_iso_8601": "2023-10-14T07:35:55.398154Z",
"url": "https://files.pythonhosted.org/packages/a3/2b/52909fe1561c66a1cdfa297cb7d9fab46f0987297910076b291d53b5c171/tvdcn-0.5.0-cp38-cp38-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "4169e34a39e4e0808579629fac22954557005ef445bb99af6959ca5b3b618915",
"md5": "191c06de323bff66556427cbc0bbc55a",
"sha256": "e5ed81dc1cbf4f01de9ac8996a8ee81a11309701a38e031c9bd120d6d6a6297c"
},
"downloads": -1,
"filename": "tvdcn-0.5.0-cp39-cp39-macosx_10_9_x86_64.whl",
"has_sig": false,
"md5_digest": "191c06de323bff66556427cbc0bbc55a",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.8",
"size": 479480,
"upload_time": "2023-10-14T07:35:58",
"upload_time_iso_8601": "2023-10-14T07:35:58.130971Z",
"url": "https://files.pythonhosted.org/packages/41/69/e34a39e4e0808579629fac22954557005ef445bb99af6959ca5b3b618915/tvdcn-0.5.0-cp39-cp39-macosx_10_9_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "e41fb0c190ae374e30d3149225bfa19ac008347a958fd81887a0760842d1ca48",
"md5": "b51b946fbc3abb48f6a0767dfdd32680",
"sha256": "d42e6e575968678777a58007d2165c76f320f55b51aa9ca49c47467eb6d2c431"
},
"downloads": -1,
"filename": "tvdcn-0.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"has_sig": false,
"md5_digest": "b51b946fbc3abb48f6a0767dfdd32680",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.8",
"size": 32207379,
"upload_time": "2023-10-14T07:36:00",
"upload_time_iso_8601": "2023-10-14T07:36:00.877430Z",
"url": "https://files.pythonhosted.org/packages/e4/1f/b0c190ae374e30d3149225bfa19ac008347a958fd81887a0760842d1ca48/tvdcn-0.5.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "54a78b9cdb2ece9456b5c470f476f0031e3f80de6fb4d043282eed0268f6c308",
"md5": "821e9b15d927d4c18a20ed512757e9cb",
"sha256": "6c6ce0e9c70725ade60c7597af547f2e0ec40928f17ee66eeea145b0f6340286"
},
"downloads": -1,
"filename": "tvdcn-0.5.0-cp39-cp39-win_amd64.whl",
"has_sig": false,
"md5_digest": "821e9b15d927d4c18a20ed512757e9cb",
"packagetype": "bdist_wheel",
"python_version": "cp39",
"requires_python": ">=3.8",
"size": 8773711,
"upload_time": "2023-10-14T07:36:04",
"upload_time_iso_8601": "2023-10-14T07:36:04.352549Z",
"url": "https://files.pythonhosted.org/packages/54/a7/8b9cdb2ece9456b5c470f476f0031e3f80de6fb4d043282eed0268f6c308/tvdcn-0.5.0-cp39-cp39-win_amd64.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "6a967d947180f05248932878211ed665ead5d00ac2bf9320d8a4786913d59a8e",
"md5": "2b9d7be1cfa45bf2b2c3dca7bef06514",
"sha256": "d74e4b917c4e84fa6becf46fee4d6fd6aae4dc884079f1a8fd284e0118cd899d"
},
"downloads": -1,
"filename": "tvdcn-0.5.0.tar.gz",
"has_sig": false,
"md5_digest": "2b9d7be1cfa45bf2b2c3dca7bef06514",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.8",
"size": 80778,
"upload_time": "2023-10-14T07:36:07",
"upload_time_iso_8601": "2023-10-14T07:36:07.588036Z",
"url": "https://files.pythonhosted.org/packages/6a/96/7d947180f05248932878211ed665ead5d00ac2bf9320d8a4786913d59a8e/tvdcn-0.5.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2023-10-14 07:36:07",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "inspiros",
"github_project": "tvdcn",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"requirements": [],
"lcname": "tvdcn"
}