nextflow icon indicating copy to clipboard operation
nextflow copied to clipboard

Dynamic directive : Label directive is not working

Open grafitos opened this issue 3 years ago • 9 comments

Bug report

Hello,

From this script example:

vepVersionCh = Channel.from(1,2,3)

process vep {

        label { "vep${version}" }

        input:
        val(version) from vepVersionCh

        """
        echo ${version}
        """
}

Dynamic directive on label is not working as expected (https://www.nextflow.io/docs/latest/process.html#dynamic-directives).

Here the error:

Cannot cast object 'Script_d60a4a02$_runScript_closure1$_closure2@71e9a896' with class 'Script_d60a4a02$_runScript_closure1$_closure2' to class 'java.util.List'

Here the stack trace:

org.codehaus.groovy.runtime.typehandling.GroovyCastException: Cannot cast object 'Script_d60a4a02$_runScript_closure1$_closure2@71e9a896' with class 'Script_d60a4a02$_runScript_closure1$_closure2' to class 'java.util.List'
        at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnSAM(DefaultTypeTransformation.java:415)
        at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnNumber(DefaultTypeTransformation.java:329)
        at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.continueCastOnCollection(DefaultTypeTransformation.java:277)
        at org.codehaus.groovy.runtime.typehandling.DefaultTypeTransformation.castToType(DefaultTypeTransformation.java:230)
        at org.codehaus.groovy.runtime.ScriptBytecodeAdapter.castToType(ScriptBytecodeAdapter.java:615)
        at nextflow.script.ProcessConfig.getLabels(ProcessConfig.groovy:679)
        at nextflow.script.ProcessConfig.applyConfig(ProcessConfig.groovy:366)
        at nextflow.script.ProcessConfig$applyConfig$0.callCurrent(Unknown Source)

I would like to use different process configurations depending on a input channel value (using "withLabel" in config file).

  • Nextflow version: 20.04.1
  • Java version: 1.8
  • Operating system: Linux

grafitos avatar Nov 06 '20 15:11 grafitos

Please format code and error stack trace when reporting issues.

pditommaso avatar Nov 07 '20 15:11 pditommaso

Related to #894

pditommaso avatar Nov 07 '20 15:11 pditommaso

I'm encountering the same error and stack trace. Tried to determine a label dynamically from a param:

label { params.phase1.model == "mlp-tf" ? "gpu" : "cpu" }

bentsherman avatar Jun 10 '21 15:06 bentsherman

If there is an ongoing discussion on whether the label directive can/should be made dynamic, then for now it should be added to the list of directives that aren't dynamic:

https://www.nextflow.io/docs/latest/process.html#dynamic-directives

bentsherman avatar Jun 10 '21 15:06 bentsherman

I am attempting to do something similar with labels. Specifically, change the label for a process based on task.attempt, so that when I retry, I can use more resources. For example:

process foo {
  label { getLabel('small', task.attempt) }
	
  ...
}

The getLabel function would return small, medium, large for attempts 1, 2, and 3 etc. However when trying this I get the same exact error as the original issue post (cannot cast object to List...).

I rewrote the process to have no real logic, just a closure:

process bar {
  label { 'small' }

  ...
}

And I get the exact same error (cannot cast object to list). It is the closure that is causing this specific error message, not necessarily the dynamic logic.

The label works as expected with a bare string:

process baz {
  label 'small'

  ...
}

mjhipp avatar Oct 20 '21 23:10 mjhipp

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Mar 22 '22 04:03 stale[bot]

Has any progress been made on this issue? Has anyone discovered a workaround for using dynamic label directives? I am attempting to request memory dynamically using a label directive as follows:

label "ram_${(8 * Math.pow(2, task.attempt - 1)).toInteger()}g"
errorStrategy { task.exitStatus == 137 ? 'retry' : 'terminate' }
maxRetries 2

I need to request memory using a label directive because the standard memory directive unfortunately does not work on my cluster. My config file defines the labels ram_8g, ram_16g, and ram_32g.

process {
    executor = 'sge'

    // special labels for jobs with different RAM requirements
    withLabel: ram_8g {
      clusterOptions = '-l m_mem_free=8G''
    }
    withLabel: ram_16g {
      clusterOptions = '-l m_mem_free=16G'
    }
    withLabel: ram_32g {
      clusterOptions = '-l m_mem_free=32G''
    }
}

Here, -l m_mem_free is an option to the scheduler specifying the amount of RAM to request.

Does anyone know of a strategy that could get this working? Thanks.

timothy-barry avatar Apr 16 '22 22:04 timothy-barry

See https://github.com/nextflow-io/nextflow/issues/894#issuecomment-429737996 for previous discussion about why this issue is stuck for the time being.

bentsherman avatar Apr 18 '22 13:04 bentsherman

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Sep 20 '22 20:09 stale[bot]