cwltool
cwltool copied to clipboard
workflow level ResourceRequirements unable to access workflow level inputs
#!/usr/bin/env cwl-runner
cwlVersion: v1.0
class: Workflow
requirements:
InlineJavascriptRequirement: {} # shouldn't need this, but makes the error more interesting
hints:
ResourceRequirement:
coresMax: $(inputs.threads_max)
inputs:
threads_max:
type: int
default: 4
steps:
one:
in: []
run:
class: CommandLineTool
inputs: []
baseCommand: echo
arguments: [ $(runtime.cores) ]
outputs: []
out: []
outputs: []
$ cwltool workflow-dyn-res.cwl
INFO /home/michael/cwltool/env3.8/bin/cwltool 3.0.20200724083110
INFO Resolved 'workflow-dyn-res.cwl' to 'file:///home/michael/cwltool/workflow-dyn-res.cwl'
INFO [workflow ] start
INFO [workflow ] starting step one
INFO [step one] start
ERROR Expecting value: line 1 column 1 (char 0)
script was:
01 "use strict";
02 var inputs = {};
03 var self = null;
04 var runtime = {
05 "tmpdir": "/tmp/tmpcb9aom_8",
06 "outdir": "/tmp/nx2jmuji"
07 };
08 (function(){return ((inputs.threads_max));})()
stdout was: 'undefined'
stderr was: ''
Traceback (most recent call last):
File "/home/michael/cwltool/cwltool/sandboxjs.py", line 411, in execjs
return cast(CWLOutputType, json.loads(stdout))
File "/usr/lib/python3.8/json/__init__.py", line 357, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.8/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.8/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "cwltool/expression.py", line 377, in do_eval
return interpolate(
File "cwltool/expression.py", line 293, in interpolate
e = evaluator(
File "cwltool/expression.py", line 250, in evaluator
return execjs(
File "/home/michael/cwltool/cwltool/sandboxjs.py", line 413, in execjs
raise JavascriptException(
cwltool.sandboxjs.JavascriptException: Expecting value: line 1 column 1 (char 0)
script was:
01 "use strict";
02 var inputs = {};
03 var self = null;
04 var runtime = {
05 "tmpdir": "/tmp/tmpcb9aom_8",
06 "outdir": "/tmp/nx2jmuji"
07 };
08 (function(){return ((inputs.threads_max));})()
stdout was: 'undefined'
stderr was: ''
ERROR Exception on step 'one'
ERROR [step one] Cannot make job: Expression evaluation error:
Expecting value: line 1 column 1 (char 0)
script was:
01 "use strict";
02 var inputs = {};
03 var self = null;
04 var runtime = {
05 "tmpdir": "/tmp/tmpcb9aom_8",
06 "outdir": "/tmp/nx2jmuji"
07 };
08 (function(){return ((inputs.threads_max));})()
stdout was: 'undefined'
stderr was: ''
INFO [workflow ] completed permanentFail
{}
Full traceback
Traceback (most recent call last):
File "/home/michael/cwltool/cwltool/workflow_job.py", line 852, in job
for newjob in step.iterable:
File "/home/michael/cwltool/cwltool/workflow_job.py", line 771, in try_make_job
for j in jobs:
File "/home/michael/cwltool/cwltool/workflow_job.py", line 78, in job
for j in self.step.job(joborder, output_callback, runtimeContext):
File "cwltool/workflow.py", line 439, in job
for tool in self.embedded_tool.job(
File "cwltool/command_line_tool.py", line 788, in job
File "cwltool/process.py", line 952, in _init_job
if self.tool["class"] != "Workflow":
File "cwltool/process.py", line 990, in evalResources
Union[int, float],
File "cwltool/process.py", line 549, in eval_resource
if isinstance(resource_req, str) and expression.needs_parsing(resource_req):
File "cwltool/builder.py", line 639, in do_eval
return expression.do_eval(
File "cwltool/expression.py", line 402, in do_eval
raise WorkflowException("Expression evaluation error:\n%s" % str(e)) from e
When I modify the example to have an input for the CommandLineTool
it shows that the wrong inputs object is being used to evaluated the Workflow level dynamic ResourceRequirement
#!/usr/bin/env cwl-runner
cwlVersion: v1.0
class: Workflow
requirements:
InlineJavascriptRequirement: {}
hints:
ResourceRequirement:
coresMax: $(inputs.threads_max)
inputs:
threads_max:
type: int
default: 4
steps:
one:
in: []
run:
class: CommandLineTool
inputs:
other_input:
type: int
default: 8
baseCommand: echo
arguments: [ $(runtime.cores) ]
outputs: []
out: []
outputs: []
$ cwltool workflow-dyn-res.cwl
INFO /home/michael/cwltool/env3.8/bin/cwltool 3.0.20200724083110
INFO Resolved 'workflow-dyn-res.cwl' to 'file:///home/michael/cwltool/workflow-dyn-res.cwl'
INFO [workflow ] start
INFO [workflow ] starting step one
INFO [step one] start
ERROR Expecting value: line 1 column 1 (char 0)
script was:
01 "use strict";
02 var inputs = {
03 "other_input": 8
04 };
05 var self = null;
06 var runtime = {
07 "tmpdir": "/tmp/tmpneb1x4qe",
08 "outdir": "/tmp/vts9yg_3"
09 };
10 (function(){return ((inputs.threads_max));})()
stdout was: 'undefined'
stderr was: ''
Traceback (most recent call last):
File "/home/michael/cwltool/cwltool/sandboxjs.py", line 411, in execjs
return cast(CWLOutputType, json.loads(stdout))
File "/usr/lib/python3.8/json/__init__.py", line 357, in loads
return _default_decoder.decode(s)
File "/usr/lib/python3.8/json/decoder.py", line 337, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python3.8/json/decoder.py", line 355, in raw_decode
raise JSONDecodeError("Expecting value", s, err.value) from None
json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
The above exception was the direct cause of the following exception:
Traceback (most recent call last):
File "cwltool/expression.py", line 377, in do_eval
return interpolate(
File "cwltool/expression.py", line 293, in interpolate
e = evaluator(
File "cwltool/expression.py", line 250, in evaluator
return execjs(
File "/home/michael/cwltool/cwltool/sandboxjs.py", line 413, in execjs
raise JavascriptException(
cwltool.sandboxjs.JavascriptException: Expecting value: line 1 column 1 (char 0)
script was:
01 "use strict";
02 var inputs = {
03 "other_input": 8
04 };
05 var self = null;
06 var runtime = {
07 "tmpdir": "/tmp/tmpneb1x4qe",
08 "outdir": "/tmp/vts9yg_3"
09 };
10 (function(){return ((inputs.threads_max));})()
stdout was: 'undefined'
stderr was: ''
ERROR Exception on step 'one'
ERROR [step one] Cannot make job: Expression evaluation error:
Expecting value: line 1 column 1 (char 0)
script was:
01 "use strict";
02 var inputs = {
03 "other_input": 8
04 };
05 var self = null;
06 var runtime = {
07 "tmpdir": "/tmp/tmpneb1x4qe",
08 "outdir": "/tmp/vts9yg_3"
09 };
10 (function(){return ((inputs.threads_max));})()
stdout was: 'undefined'
stderr was: ''
INFO [workflow ] completed permanentFail
{}
WARNING Final process status is permanentFail
FYI, the expected is
$ cwltool workflow-dyn-res.cwl
INFO /home/michael/cwltool/env3.8/bin/cwltool 3.0.20200724083110
INFO Resolved 'workflow-dyn-res.cwl' to 'file:///home/michael/cwltool/workflow-dyn-res.cwl'
INFO [workflow ] start
INFO [workflow ] starting step one
INFO [step one] start
INFO [job one] /tmp/ywftv8yg$ echo \
4
4
INFO [job one] completed success
INFO [step one] completed success
INFO [workflow ] completed success
{}
INFO Final process status is success
Here's a workaround that works for the example workflow above, with the downside that it is annoying to have to duplicate inputs.
#!/usr/bin/env cwl-runner
cwlVersion: v1.0
class: Workflow
hints:
ResourceRequirement:
coresMax: $(inputs.threads_max)
inputs:
threads_max:
type: int
default: 4
steps:
one:
in:
threads_max: threads_max
run:
class: CommandLineTool
inputs:
threads_max:
type: int
baseCommand: echo
arguments: [ $(runtime.cores) ]
outputs: []
out: []
outputs: []
@kinow Yep, but this is a major bug that the wrong inputs object is being used to evaluate expressions in workflow level hints/reqs