-
Notifications
You must be signed in to change notification settings - Fork 114
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #141 from avolkov1/cusignal_example
Cusignal nodes for Greenflow.
- Loading branch information
Showing
42 changed files
with
4,166 additions
and
154 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
## Greenflow Cusignal Plugin | ||
|
||
Greenflow plugin that includes a set of nodes for Cusignal library. | ||
|
||
|
||
### Install the greenflowlab JupyterLab plugin | ||
|
||
First create a Python enviroment or use one with RAPIDS cuSignal library. Tip, | ||
use mamba to resolve dependencies quicker. | ||
```bash | ||
conda create -n rapids_cusignal -c conda-forge mamba python=3.8 | ||
|
||
conda activate rapids_cusignal | ||
|
||
mamba install -c rapidsai -c nvidia -c conda-forge \ | ||
cusignal=21.06 python=3.8 cudatoolkit=11.2 | ||
``` | ||
|
||
Then install `greenflowlab` JupyterLab plugin, make sure `nodejs` of version | ||
[12^14^15] is installed. E.g: | ||
```bash | ||
mamba install -c conda-forge python-graphviz nodejs=12.4.0 pydot | ||
``` | ||
Then install the `greenflowlab`: | ||
```bash | ||
pip install greenflowlab | ||
``` | ||
Or install `greenflowlab` at the greenflowlab directory: | ||
```bash | ||
pip install . | ||
``` | ||
|
||
### Install the cusignal plugin | ||
Install the plugin directly from the plugin diretory. | ||
```bash | ||
pip install . | ||
``` |
Empty file.
5 changes: 5 additions & 0 deletions
5
gQuant/plugins/cusignal_plugin/greenflow_cusignal_plugin/convolution/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
from .convolve import * | ||
from .correlate import * | ||
from .fftconvolve import * | ||
from .convolve2d import * | ||
from .correlate2d import * |
129 changes: 129 additions & 0 deletions
129
gQuant/plugins/cusignal_plugin/greenflow_cusignal_plugin/convolution/convolve.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
import numpy as np | ||
import cupy as cp | ||
|
||
from cusignal.convolution import convolve as cuconv | ||
from scipy.signal import convolve as siconv | ||
|
||
from greenflow.dataframe_flow import (Node, PortsSpecSchema, ConfSchema) | ||
from greenflow.dataframe_flow.template_node_mixin import TemplateNodeMixin | ||
|
||
__all__ = ['CusignalConvolveNode'] | ||
|
||
_CONV_DESC = '''Convolve two N-dimensional arrays. | ||
Convolve `in1` and `in2`, with the output size determined by the | ||
`mode` argument. | ||
Returns: | ||
convolve : array | ||
An N-dimensional array containing a subset of the discrete linear | ||
convolution of `in1` with `in2`. | ||
''' | ||
|
||
_CONV_MODE_DESC = '''mode : str {'full', 'valid', 'same'}, optional | ||
A string indicating the size of the output: | ||
``full`` | ||
The output is the full discrete linear convolution | ||
of the inputs. (Default) | ||
``valid`` | ||
The output consists only of those elements that do not | ||
rely on the zero-padding. In 'valid' mode, either `in1` or `in2` | ||
must be at least as large as the other in every dimension. | ||
``same`` | ||
The output is the same size as `in1`, centered | ||
with respect to the 'full' output. | ||
''' | ||
|
||
_CONV_METHOD_DESC = '''method : str {'auto', 'direct', 'fft'}, optional | ||
A string indicating which method to use to calculate the convolution. | ||
``direct`` | ||
The convolution is determined directly from sums, the definition of | ||
convolution. | ||
``fft`` | ||
The Fourier Transform is used to perform the convolution by calling | ||
`fftconvolve`. | ||
``auto`` | ||
Automatically chooses direct or Fourier method based on an estimate | ||
of which is faster (default). | ||
''' | ||
|
||
|
||
class CusignalConvolveNode(TemplateNodeMixin, Node): | ||
def init(self): | ||
TemplateNodeMixin.init(self) | ||
|
||
port_type = PortsSpecSchema.port_type | ||
inports = { | ||
'in1': {port_type: [cp.ndarray, np.ndarray]}, | ||
'in2': {port_type: [cp.ndarray, np.ndarray]} | ||
} | ||
outports = { | ||
'convolve': {port_type: [cp.ndarray, np.ndarray]}, | ||
} | ||
self.template_ports_setup(in_ports=inports, out_ports=outports) | ||
|
||
meta_outports = {'convolve': {}} | ||
self.template_meta_setup(out_ports=meta_outports) | ||
|
||
def conf_schema(self): | ||
mode_enum = ['full', 'valid', 'same'] | ||
method_enum = ['direct', 'fft', 'auto'] | ||
json = { | ||
'title': 'Cusignal Convolution Node', | ||
'type': 'object', | ||
'description': _CONV_DESC, | ||
'properties': { | ||
'mode': { | ||
'type': 'string', | ||
'description': _CONV_MODE_DESC, | ||
'enum': mode_enum, | ||
'default': 'full' | ||
}, | ||
'method': { | ||
'type': 'string', | ||
'description': _CONV_METHOD_DESC, | ||
'enum': method_enum, | ||
'default': 'auto' | ||
}, | ||
'normalize': { | ||
'type': 'boolean', | ||
'description': 'Scale convolutioni by in2 (typically a ' | ||
'window) i.e. convolve(in1, in2) / sum(in2). ' | ||
'Default False.', | ||
'default': False | ||
}, | ||
'use_cpu': { | ||
'type': 'boolean', | ||
'description': 'Use CPU for computation via ' | ||
'scipy::signal.convolve. Default is False and runs on ' | ||
'GPU via cusignal.', | ||
'default': False | ||
}, | ||
}, | ||
} | ||
return ConfSchema(json=json) | ||
|
||
def process(self, inputs): | ||
mode = self.conf.get('mode', 'full') | ||
method = self.conf.get('method', 'auto') | ||
normalize = self.conf.get('normalize', False) | ||
use_cpu = self.conf.get('use_cpu', False) | ||
|
||
in1 = inputs['in1'] | ||
in2 = inputs['in2'] | ||
|
||
if use_cpu: | ||
conv = siconv(in1, in2, mode=mode, method=method) | ||
if normalize: | ||
scale = np.sum(in2) | ||
else: | ||
conv = cuconv(in1, in2, mode=mode, method=method) | ||
if normalize: | ||
scale = cp.sum(in2) | ||
|
||
if normalize: | ||
conv = conv if scale == 1 else conv / scale | ||
|
||
return {'convolve': conv} |
Oops, something went wrong.