process {
  // Default resources for components that hardly do any processing
  memory = { 2.GB * task.attempt }
  cpus = 1

  // Retry for exit codes that have something to do with memory issues
  errorStrategy = { task.exitStatus in 137..140 ? 'retry' : 'terminate' }
  maxRetries = 3

  // The memory a task is assinged increases with each attempt
  // uncomment the line below and adjust the value to set a global upper limit on the memory.
  // resourceLimits = [ memory: 240.Gb ] 

  // CPU resources
  withLabel: singlecpu { cpus = 1 }
  withLabel: lowcpu { cpus = 4 }
  withLabel: midcpu { cpus = 10 }
  withLabel: highcpu { cpus = 20 }
  
  // Memory resources
  withLabel: lowmem { memory = { task?.resourceLimits?.memory && task?.maxRetries && task.attempt >= task.maxRetries ? task.resourceLimits.memory : 4.GB * task.attempt } }
  withLabel: midmem { memory = { task?.resourceLimits?.memory && task?.maxRetries && task.attempt >= task.maxRetries ? task.resourceLimits.memory : 25.GB * task.attempt } }
  withLabel: highmem { memory = { task?.resourceLimits?.memory && task?.maxRetries && task.attempt >= task.maxRetries ? task.resourceLimits.memory : 50.GB * task.attempt } }
  withLabel: veryhighmem { memory = { task?.resourceLimits?.memory && task?.maxRetries && task.attempt >= task.maxRetries ? task.resourceLimits.memory : 75.GB * task.attempt } }

  // Disk space
  withLabel: lowdisk {
    disk = {process.disk ? process.disk : null}
  }
  withLabel: middisk {
    disk = {process.disk ? process.disk : null}
  }
  withLabel: highdisk {
    disk = {process.disk ? process.disk : null}
  }
  withLabel: veryhighdisk {
    disk = {process.disk ? process.disk : null}
  }
  
  // NOTE: The above labels intentionally do not have an effect by default.
  // The user should set the disk space requirements by adding the following
  // to the compute environment:
  //
  // withLabel: lowdisk { disk = { 20.GB * task.attempt } }
  // withLabel: middisk { disk = { 100.GB * task.attempt } }
  // withLabel: highdisk { disk = { 200.GB * task.attempt } }
  // withLabel: veryhighdisk { disk = { 500.GB * task.attempt } }
}
