Skip to content

Commit 09ad749

Browse files
cmccarthy1dmorgankxDianeod
authored
v2.0.0 (#79)
* Handling of null datetimes in pandas dataframes, pandas > 1.0 now default for support * removal of error trap * Minor change to structure of dt_convert * unneccesary conversion to timestamp * wording update * addition of missing xval folder from releases * updated ksdistrib to correspond with scipy * sanity check for scipy version within select.q added * new grid/random/sobol searching methods * sobol requirements * requirement updates for sobol * check for number of random hps * sobol check fix * gs/rs tests * addition of 1st pass graph/pipeline code * initial pass at graphing tests * Increased testing, covering base functionality * update to account for testing and packaging of graph functionality * updated tab2df to account for list of char being passed * addition of most basic modules to ml toolkit (loading/saving data) * addition of loading and saving modules to ml graph library (most basic generally useful module) * update to graph functionality to handle generic dictionaries * minor update to graph.t to increase converage and explicitly test the output error not just that function errors * addition of node update failing functions * added labelencode function and tests to preproc * update to labelencode functionality and addition of application function for this * addition of time series and optimization functionality for oct 7th release * update to tests to correctly load data * update to README to add in reference to optimization, graphing and time series * added README for timeseries * changed time series to lower case * first pass at optimization tests * addition of datasets for testing * update to test data path * update to tests to handle discrepencies between q versions * update to optimize test and addition of dictCheck tests * revert of prediction functionality as tests are already covered * removal of sobol-seq from from requirements due to lack of conda install and issues with using this and conda * reintroduction of requirements file * trigger build * reordering of requirements to trigger build * stationality -> stationarity as this is the correct term * renaming of dataset for stationarity * movement from conda to pip install with docker * fixed windowed feat function * full coverage of failing tests for graph library * updated appveyor files * addition of width parameter to autocorrelation plot * addition of timeseries and optimization tests * included optimization files and fixed cluster test * added saved input files for optim func * restructure * restructure and addition of windows data * restructure and addition of windows data * separate windows and linux folders * updated optim tests for windows/linux Co-authored-by: dmorgankx <44678213+dmorgankx@users.noreply.github.com> Co-authored-by: Deanna Morgan <dmorgan1@kx.com> Co-authored-by: Dianeod <40861871+Dianeod@users.noreply.github.com> Co-authored-by: Dianeod <dodonoghue@kx.com>
1 parent 3405543 commit 09ad749

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

134 files changed

+2696
-68
lines changed

.travis.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,11 +36,11 @@ beforescript:
3636
script:
3737
- (cd clust && make && make install && make clean)
3838
- echo "Preparing version $TRAVIS_BRANCH-$TRAVIS_COMMIT"
39-
- tar czf ml_$TRAVIS_OS_NAME-$TRAVIS_BRANCH.tgz *.q fresh/ xval/ util/ clust/ requirements.txt LICENSE README.md
39+
- tar czf ml_$TRAVIS_OS_NAME-$TRAVIS_BRANCH.tgz *.q fresh/ xval/ util/ clust/ graph/ timeseries/ optimize/ requirements.txt LICENSE README.md
4040
- echo "Packaged as ml_$TRAVIS_OS_NAME-$TRAVIS_BRANCH.zip"
4141
- if [[ "x$QLIC_KC" != "x" ]]; then
4242
curl -fsSL -o test.q https://github.com/KxSystems/embedpy/raw/master/test.q;
43-
q test.q fresh/tests/ util/tests/ xval/tests clust/tests/ -q;
43+
q test.q fresh/tests/ util/tests/ xval/tests clust/tests/ graph/tests/ timeseries/tests/ optimize/tests/ -q;
4444

4545
else
4646
echo No kdb+, no tests;

README.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,12 @@ The machine learning toolkit is at the core of kdb+/q centered machine learning
77
* An implementation of the FRESH (FeatuRe Extraction and Scalable Hypothesis testing) algorithm for use in the extraction of features from time series data and the reduction in the number of features through statistical testing.
88
* Cross validation and grid-search functions allowing for testing of the stability of models to changes in the volume of data or the specific subsets of data used in training.
99
* Clustering algorithms used to group data points and to identify patterns in their distributions. The algorithms make use of a k-dimensional tree to store points and scoring functions to analyze how well they performed.
10+
* Statistical time series models and feature extraction techniques used for the application of machine learning to time series problems. These models allow for the forecasting of the future behaviour of a system under various conditions.
11+
* Numerical optimization techniques used for calculating the optimal parameters for an objective function.
12+
* A graphing and pipeline library for the creation of modularized executable workflow based on a structure described by a mathematical directed graph.
1013
* Utility functions relating to areas including statistical analysis, data preprocessing and array manipulation.
1114

12-
These sections are explained in greater depth within the [FRESH](https://code.kx.com/v2/ml/toolkit/fresh/), [Cross Validation](https://code.kx.com/v2/ml/toolkit/xval), [Clustering](https://code.kx.com/v2/ml/toolkit/clustering/algos/) and [Utilities](https://code.kx.com/v2/ml/toolkit/utilities/metric) documentation.
15+
These sections are explained in greater depth within the [FRESH](https://code.kx.com/v2/ml/toolkit/fresh/), [cross validation](https://code.kx.com/v2/ml/toolkit/xval), [clustering](https://code.kx.com/v2/ml/toolkit/clustering/algos/), [time series](https://code.kx.com/v2/ml/toolkit/timeseries), [optimization](https://code.kx.com/v2/ml/toolkit/optimize/), [graph/pipeline](https://code.kx.com/v2/ml/toolkit/graph) and [utilities](https://code.kx.com/v2/ml/toolkit/utilities/metric) documentation.
1316

1417
## Requirements
1518

@@ -27,6 +30,7 @@ or via conda:
2730
conda install --file requirements.txt
2831
```
2932

33+
3034
## Installation
3135

3236
Place the `ml` library in `$QHOME` and load into a q instance using `ml/ml.q`
@@ -46,6 +50,7 @@ Examples showing implementations of several components of this toolkit can be fo
4650
* Cross validation and grid search capabilities
4751
* Results Scoring functionality
4852
* Clustering methods applied to datasets
53+
* Time series modeling examples
4954

5055
## Documentation
5156

build/buildscript.bat

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,20 @@ if "%APPVEYOR_REPO_TAG%"=="true" (
44
set ML_VERSION=%APPVEYOR_REPO_BRANCH%_%APPVEYOR_REPO_COMMIT%
55
)
66
set PATH=C:\Perl;%PATH%
7-
perl -p -i.bak -e s/TOOLKITVERSION/`\$\"%ML_VERSION%\"/g ml.q
7+
perl -p -i.bak -e s/MLVERSION/`\$\"%ML_VERSION%\"/g ml.q
8+
89

910
if not defined QLIC_KC (
1011
goto :nokdb
1112
)
12-
call "build\getkdb.bat" || goto :error
1313

14-
set PATH=C:\Miniconda3-x64;C:\Miniconda3-x64\Scripts;%PATH%
15-
mkdir embedpy
16-
cd embedpy
17-
echo getembedpy"latest" | q ..\build\getembedpy.q -q || goto :error
18-
cd ..
19-
echo p)print('embedpy runs') | q -q || goto :error
2014

21-
cd clust/build
22-
call "build.bat" 2017
23-
cd ../..
15+
set PATH=C:\Miniconda3-x64;C:\Miniconda3-x64\Scripts;%PATH%
16+
conda config --set always_yes yes --set changeps1 no
17+
call "build\getkdb.bat" || goto :error
2418

2519
exit /b 0
2620

27-
2821
:error
2922
echo failed with error
3023
exit /b

build/getembedpy.q

Lines changed: 0 additions & 11 deletions
This file was deleted.

build/getkdb.bat

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
curl -fsSOJL %W64%
1+
conda install -c kx embedPy
22
mkdir q
3-
7z x w64.zip -oq
3+
xcopy /E C:\Miniconda3-x64\q q
44
echo|set /P =%QLIC_KC% >q\kc.lic.enc
55
certutil -decode q\kc.lic.enc q\kc.lic
66
set QHOME=%cd%\q
77
set PATH=%QHOME%\w64;%PATH%
8-
where q
9-
echo .z.K | q -q
8+
echo show .z.K;show .z.k;exit 0 | q -q

build/package.bat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
7z a ml_windows-%ML_VERSION%.zip *.q fresh util xval clust requirements.txt LICENSE README.md
1+
7z a ml_windows-%ML_VERSION%.zip *.q fresh util xval clust graph timeseries optimize requirements.txt LICENSE README.md
22
appveyor PushArtifact ml_windows-%ML_VERSION%.zip
33
exit /b 0

build/test.bat

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@ if defined QLIC_KC (
22
pip -q install -r requirements.txt
33
echo getting test.q from embedpy
44
curl -fsSL -o test.q https://github.com/KxSystems/embedpy/raw/master/test.q
5-
q test.q fresh/tests/ util/tests/ xval/tests/ clust/tests/ -q
5+
q test.q fresh/tests/ util/tests/ xval/tests/ clust/tests/ graph/tests/ timeseries/tests/ optimize/tests/ -q
66
)

clust/tests/util.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ info:.ml.clust.i.apinit[d1;`e2dist;max]
2828
.ml.clust.kd.newtree[d2;3][`parent]~0N 0 0
2929
.ml.clust.kd.newtree[d2;3][`idxs]~(0#0;til 5;5+til 5)
3030
.ml.clust.kd.nn[tree;d1;`edist;0;d2[;2]][`closestPoint]~2
31-
.ml.clust.kd.nn[tree;d1;`mdist;1 2 3 4;d1[;1]][`closestPoint`closestDist]~(0;2f)
31+
all .ml.clust.kd.nn[tree;d1;`mdist;1 2 3 4;d1[;1]][`closestPoint`closestDist]=(0;2f)
3232
.ml.clust.kd.nn[tree;d1;`mdist;1;7 9f][`closestPoint`closestDist]~(4;8f)
3333
.ml.clust.kd.nn[tree2;d2;`edist;1 2 3;d1[;1]][`closestPoint]~0
3434
.ml.clust.kd.nn[tree2;d2;`edist;1 5 2;d1[;3]][`closestPoint]~3

docker/Dockerfile

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ COPY fresh /opt/kx/ml/fresh
1313
COPY util /opt/kx/ml/util
1414
COPY xval /opt/kx/ml/xval
1515
COPY clust /opt/kx/ml/clust
16+
COPY graph /opt/kx/ml/graph
17+
COPY timeseries /opt/kx/ml/timeseries
18+
COPY optimize /opt/kx/ml/optimize
1619

1720
ARG VCS_REF=dev
1821
ARG BUILD_DATE=dev
@@ -32,13 +35,15 @@ LABEL org.label-schema.schema-version="0.1" \
3235
RUN chown -R kx:kx /opt/kx/ml
3336
RUN mkdir /opt/kx/q/ml
3437
RUN find /opt/kx/ml -maxdepth 1 -type f -name '*.q' | xargs ln -s -t /opt/kx/q/ml \
35-
&& ln -s -t /opt/kx/q/ml /opt/kx/ml/fresh /opt/kx/ml/utils /opt/kx/ml/xval /opt/kx/ml/clust
38+
&& ln -s -t /opt/kx/q/ml /opt/kx/ml/fresh /opt/kx/ml/utils /opt/kx/ml/xval /opt/kx/ml/clust \
39+
/opt/kx/ml/graph /opt/kx/ml/timeseries /opt/kx/ml/optimize
3640

3741
USER kx
3842

3943
RUN . /opt/conda/etc/profile.d/conda.sh \
4044
&& conda activate kx \
41-
&& conda install -c conda-forge --file /opt/kx/ml/requirements.txt \
45+
&& pip install pip==9.0.1 \
46+
&& pip install -r /opt/kx/ml/requirements.txt \
4247
&& conda clean -y --all
4348

4449
USER root

graph/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# Graphing and Pipeline interface
2+
3+
The functionality contained in this folder surrounds the implementation of a graph and pipeline execution structural form of kdb+. This functionality is intended to provide a common structural template and execution mechanism for complex code bases require ease of modification which is common within machine learning use cases.
4+
5+
## Functionality
6+
7+
Within this folder are two scripts that contains the entirity of this graph and pipeline functionality. These scripts are:
8+
9+
1. graph.q: This contains all functionality required for the creation, deletion and update of nodes and edges within the graph structure.
10+
2. pipeline.q: This contains functionality for both the compilation and execution of a user generated graph.
11+
12+
## Requirements
13+
14+
- kdb+ > 3
15+
16+
## Installation
17+
18+
Place the `ml` library in `$QHOME` and load into a q instance using `ml/ml.q`
19+
20+
### Load
21+
22+
The following will load the graphing and pipeline functionality into the `.ml` namespace
23+
```q
24+
q)\l ml/ml.q
25+
q).ml.loadfile`:graph/init.q
26+
```
27+
28+
## Documentation
29+
30+
Documentation is available on the [Graph](https://code.kx.com/q/ml/toolkit/graph/) homepage.
31+
32+
## Status
33+
34+
The graph-pipeline library is still in development and is available here as a beta release. Further functionality and improvements will be made to the library in the coming months.
35+
36+
If you have any issues, questions or suggestions, please write to ai@kx.com.

graph/graph.q

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
\d .ml
2+
3+
createGraph:{[]
4+
nodes:1!enlist`nodeId``function`inputs`outputs!(`;::;::;::;::);
5+
edges:2!enlist`dstNode`dstName`srcNode`srcName`valid!(`;`;`;`;0b);
6+
`nodes`edges!(nodes;edges)}
7+
8+
addNode:{[graph;nodeId;node]
9+
node,:(1#`)!1#(::);
10+
if[nodeId in exec nodeId from graph`nodes;'"invalid nodeId"];
11+
if[not``function`inputs`outputs~asc key node;'"invalid node"];
12+
if[(::)~node`inputs;node[`inputs]:(0#`)!""];
13+
if[-10h=type node`inputs;node[`inputs]:(1#`input)!enlist node`inputs];
14+
if[99h<>type node`inputs;'"invalid inputs"];
15+
if[-10h=type node`outputs;
16+
node[`outputs]:(1#`output)!enlist node`outputs;
17+
node[`function]:((1#`output)!enlist@)node[`function]::;
18+
];
19+
if[99h<>type node`outputs;'"invalid outputs"];
20+
graph:@[graph;`nodes;,;update nodeId from node];
21+
edges:flip`dstNode`dstName`srcNode`srcName`valid!(nodeId;key node`inputs;`;`;0b);
22+
graph:@[graph;`edges;,;edges];
23+
graph}
24+
25+
updNode:{[graph;nodeId;node]
26+
node,:(1#`)!1#(::);
27+
if[not nodeId in 1_exec nodeId from graph`nodes;'"invalid nodeId"];
28+
if[count key[node]except``function`inputs`outputs;'"invalid node"];
29+
oldnode:graph[`nodes]nodeId;
30+
if[`inputs in key node;
31+
if[(::)~node`inputs;node[`inputs]:(0#`)!""];
32+
if[-10h=type node`inputs;node[`inputs]:(1#`input)!enlist node`inputs];
33+
if[99h<>type node`inputs;'"invalid inputs"];
34+
inputEdges:select from graph[`edges]where dstNode=nodeId,dstName in key oldnode`inputs;
35+
graph:@[graph;`edges;key[inputEdges]_];
36+
inputEdges:flip[`dstNode`dstName!(nodeId;key node`inputs)]#inputEdges;
37+
graph:@[graph;`edges;,;inputEdges];
38+
inputEdges:select from inputEdges where not null srcNode;
39+
graph:{[graph;edge]connectEdge[graph]. edge`srcNode`srcName`dstNode`dstName}/[graph;0!inputEdges];
40+
];
41+
if[`outputs in key node;
42+
if[-10h=type node`outputs;
43+
node[`outputs]:(1#`output)!enlist node`outputs;
44+
];
45+
if[99h<>type node`outputs;'"invalid outputs"];
46+
outputEdges:select from graph[`edges]where srcNode=nodeId,srcName in key oldnode`outputs;
47+
graph:@[graph;`edges;key[outputEdges]_];
48+
outputEdges:select from outputEdges where srcName in key node`outputs;
49+
graph:@[graph;`edges;,;outputEdges];
50+
outputEdges:select srcNode,srcName,dstNode,dstName from outputEdges;
51+
graph:{[graph;edge]connectEdge[graph]. edge`srcNode`srcName`dstNode`dstName}/[graph;0!outputEdges];
52+
];
53+
if[`function in key node;
54+
if[(1#`output)~key graph[`nodes;nodeId]`outputs;node[`function]:((1#`output)!enlist@)node[`function]::];
55+
];
56+
graph:@[graph;`nodes;,;update nodeId from node];
57+
graph}
58+
59+
delNode:{[graph;nodeId]
60+
if[not nodeId in 1_exec nodeId from graph`nodes;'"invalid nodeId"];
61+
graph:@[graph;`nodes;_;nodeId];
62+
inputEdges:select from graph[`edges]where dstNode=nodeId;
63+
graph:@[graph;`edges;key[inputEdges]_];
64+
outputEdges:select from graph[`edges]where srcNode=nodeId;
65+
graph:@[graph;`edges;,;update srcNode:`,srcName:`,valid:0b from outputEdges];
66+
graph}
67+
68+
addCfg:{[graph;nodeId;cfg]addNode[graph;nodeId]``function`inputs`outputs!(::;@[;cfg];::;"!")}
69+
updCfg:{[graph;nodeId;cfg]updNode[graph;nodeId](1#`function)!enlist cfg}
70+
delCfg:delNode
71+
72+
connectEdge:{[graph;srcNode;srcName;dstNode;dstName]
73+
if[99h<>type srcOutputs:graph[`nodes;srcNode;`outputs];'"invalid srcNode"];
74+
if[99h<>type dstInputs:graph[`nodes;dstNode;`inputs];'"invalid dstNode"];
75+
if[not srcName in key srcOutputs;'"invalid srcName"];
76+
if[not dstName in key dstInputs;'"invalid dstName"];
77+
edge:(1#`valid)!1#srcOutputs[srcName]~dstInputs[dstName];
78+
graph:@[graph;`edges;,;update dstNode,dstName,srcNode,srcName from edge];
79+
graph}
80+
81+
disconnectEdge:{[graph;dstNode;dstName]
82+
if[not(dstNode;dstName)in key graph`edges;'"invalid edge"];
83+
edge:(1#`valid)!1#0b;
84+
graph:@[graph;`edges;,;update dstNode,dstName,srcName:`,srcNode:` from edge];
85+
graph}
86+

graph/init.q

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.ml.loadfile`:graph/graph.q
2+
.ml.loadfile`:graph/pipeline.q
3+
.ml.loadfile`:graph/modules/saving.q
4+
.ml.loadfile`:graph/modules/loading.q

graph/modules/loading.q

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
\d .ml
2+
3+
i.loadfname:{[cfg]
4+
file:hsym`$$[`dir in key cfg;cfg`key;"."],"/",cfg fname;
5+
if[()~key file;'"file does not exist"];
6+
file}
7+
8+
i.loadfunc.splay:loadfunc.binary:{[cfg]get i.loadfname cfg}
9+
i.loadfunc.csv:{[cfg](cfg`schema;enlist cfg`separator)0: i.loadfname cfg}
10+
i.loadfunc.json:{[cfg].j.k first read0 i.loadfname cfg}
11+
i.loadfunc.hdf5:{[cfg]
12+
if[not`hdf5 in key`;@[system;"l hdf5.q";{'"unable to load hdf5 lib"}]];
13+
if[not .hdf5.ishdf5 fname:i.loadfname cfg;'"file is not an hdf5 file"];
14+
if[not .hdf5.isObject[fpath;cfg`dname];'"hdf5 dataset does not exist"];
15+
.hdf5.readData[fpath;cfg`dname]}
16+
i.loadfunc.ipc:{[cfg]
17+
h:@[hopen;cfg`prt;{'"error opening connection"}];
18+
ret:@[h;cfg`select;{'"error executing query"}];
19+
@[hclose;h;{}];
20+
ret}
21+
i.loadfunc.process:{[cfg]if[not `data in key cfg;'"Data to be used must be defined"];cfg[`data]}
22+
23+
i.loaddset:{[cfg]
24+
if[null func:i.loadfunc cfg`typ;'"dataset type not supported"];
25+
func cfg}
26+
27+
loaddset:`function`inputs`outputs!(i.loaddset;"!";"+")

graph/modules/saving.q

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
\d .ml
2+
3+
i.savefname:{[cfg]
4+
file:hsym`$$[`dir in key cfg;cfg`key;"."],"/",cfg fname;
5+
if[not ()~key file;'"file exists"];
6+
file}
7+
8+
i.savedset.txt:{[cfg;dset]i.savefname[cfg]0:.h.tx[cfg`typ;dset];}
9+
i.savedset[`csv`xml`xls]:i.savedset.txt
10+
i.savedset.binary:{[cfg;dset]i.savefname[cfg]set dset;}
11+
i.savedset.json:{[cfg;dset]
12+
h:hopen i.savefname cfg;
13+
h @[.j.j;dset;{'"error converting to json"}];
14+
hclose h;}
15+
i.savedset.hdf5:{[cfg;dset]
16+
if[not`hdf5 in key`;@[system;"l hdf5.q";{'"unable to load hdf5 lib"}]];
17+
.hdf5.createFile fname:i.savefname cfg;
18+
.hdf5.writeData[fname;cfg`dname;dset];
19+
}
20+
i.savedset.splay:{[cfg;dset]
21+
dname:first` vs fname:i.savefname cfg;
22+
fname:` sv fname,`;
23+
fname set .Q.en[dname]dset;}
24+
25+
i.savefunc:{[cfg;dset]
26+
if[null func:i.savedset cfg`typ;'"dataset type not supported"];
27+
func dset}
28+
29+
savedset:`function`inputs`outputs!(i.savefunc;`cfg`dset!"!+";" ")

graph/pipeline.q

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
\d .ml
2+
3+
// Execution of a pipeline will not default to enter q debug mode but should be possible to overwrite
4+
graphDebug:0b
5+
updDebug:{[x]graphDebug::not graphDebug}
6+
7+
createPipeline:{[graph]
8+
if[not all exec 1_valid from graph`edges;'"disconnected edges"];
9+
outputs:ungroup select srcNode:nodeId,srcName:key each outputs from 1_graph`nodes;
10+
endpoints:exec distinct srcNode from outputs except select srcNode,srcName from graph`edges;
11+
optimalpath:distinct raze paths idesc count each paths:i.getOptimalPath[graph]each endpoints;
12+
pipeline:([]nodeId:optimalpath)#graph`nodes;
13+
nodeinputs:key each exec inputs from pipeline;
14+
pipeline:update inputs:count[i]#enlist(1#`)!1#(::),outputtypes:outputs,inputorder:nodeinputs from pipeline;
15+
pipeline:select nodeId,complete:0b,error:`,function,inputs,outputs:inputs,outputtypes,inputorder from pipeline;
16+
pipeline:pipeline lj select outputmap:([]srcName;dstNode;dstName)by nodeId:srcNode from graph`edges;
17+
1!pipeline}
18+
19+
execPipeline:{[pipeline]i.execCheck i.execNext/pipeline}
20+
21+
22+
// Pipeline creation utilities
23+
i.getDeps:{[graph;node]exec distinct srcNode from graph[`edges]where dstNode=node}
24+
i.getAllDeps:{[graph;node]$[count depNodes:i.getDeps[graph]node;distinct node,raze .z.s[graph]each depNodes;node]}
25+
i.getAllPaths:{[graph;node]$[count depNodes:i.getDeps[graph]node;node,/:raze .z.s[graph]each depNodes;raze node]}
26+
i.getLongestPath:{[graph;node]paths first idesc count each paths:reverse each i.getAllPaths[graph;node]}
27+
i.getOptimalPath:{[graph;node]distinct raze reverse each i.getAllDeps[graph]each i.getLongestPath[graph;node]}
28+
29+
i.execNext:{[pipeline]
30+
node:first 0!select from pipeline where not complete;
31+
-1"Executing node: ",string node`nodeId;
32+
if[not count inputs:node[`inputs]node[`inputorder];inputs:1#(::)];
33+
res:`complete`error`outputs!$[graphDebug;
34+
.[(1b;`;)node[`function]::;inputs];
35+
.[(1b;`;)node[`function]::;inputs;{[err](0b;`$err;::)}]
36+
];
37+
/ compare outputs to outputtypes ?
38+
if[not null res`error;-2"Error: ",string res`error];
39+
if[res`complete;
40+
res[`inputs]:(1#`)!1#(::);
41+
outputmap:update data:res[`outputs]srcName from node`outputmap;
42+
res[`outputs]:((1#`)!1#(::)),(exec distinct srcName from outputmap)_ res`outputs;
43+
pipeline:{[pipeline;map]pipeline[map`dstNode;`inputs;map`dstName]:map`data;pipeline}/[pipeline;outputmap];
44+
];
45+
pipeline,:update nodeId:node`nodeId from res;
46+
pipeline}
47+
48+
i.execCheck:{[pipeline]
49+
if[any not null exec error from pipeline;:0b];
50+
if[all exec complete from pipeline;:0b];
51+
1b}

0 commit comments

Comments
 (0)