Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

workflow level ResourceRequirements unable to access workflow level inputs #1330

Open
mr-c opened this issue Jul 24, 2020 · 5 comments · May be fixed by #1703
Open

workflow level ResourceRequirements unable to access workflow level inputs #1330

mr-c opened this issue Jul 24, 2020 · 5 comments · May be fixed by #1703
Assignees
Labels

Comments

@mr-c
Copy link
Member

mr-c commented Jul 24, 2020

#!/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
{}
@mr-c
Copy link
Member Author

mr-c commented Jul 24, 2020

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

@mr-c
Copy link
Member Author

mr-c commented Jul 24, 2020

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

@mr-c
Copy link
Member Author

mr-c commented Jul 24, 2020

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

@kinow
Copy link
Member

kinow commented Jun 2, 2022

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: []

@mr-c
Copy link
Member Author

mr-c commented Jun 2, 2022

@kinow Yep, but this is a major bug that the wrong inputs object is being used to evaluate expressions in workflow level hints/reqs

mr-c pushed a commit to common-workflow-language/cwl-v1.2 that referenced this issue Aug 17, 2023
mr-c pushed a commit to common-workflow-language/cwl-v1.2 that referenced this issue Aug 17, 2023
mr-c pushed a commit to common-workflow-language/cwl-v1.2 that referenced this issue Aug 17, 2023
mr-c pushed a commit to common-workflow-language/cwl-v1.2 that referenced this issue Aug 17, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants