

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# WDL 工作流程定義詳細資訊
<a name="workflow-languages-wdl"></a>

下列主題提供有關 HealthOmics 中 WDL 工作流程定義可用的類型和指令的詳細資訊。

**Topics**
+ [WDL lenient 中的隱含類型轉換](#workflow-wdl-type-conversion)
+ [input.json 中的命名空間定義](#workflow-wdl-namespace-defn)
+ [WDL 中的主要類型](#workflow-wdl-primitive-types)
+ [WDL 中的複雜類型](#workflow-wdl-complex-types)
+ [WDL 中的指令](#workflow-wdl-directives)
+ [其他支援的執行期屬性](#workflow-wdl-other-runtime-attributes)
+ [WDL 中的任務中繼資料](#workflow-wdl-task-metadata)
+ [WDL 工作流程定義範例](#wdl-example)

## WDL lenient 中的隱含類型轉換
<a name="workflow-wdl-type-conversion"></a>

HealthOmics 支援 input.json 檔案和工作流程定義的隱含類型轉換。若要使用隱含類型轉換，請在建立工作流程時將工作流程引擎指定為 WDL 寬鬆。WDL lenient 包含所有標準 WDL 功能，以及專為從 Cromwell 遷移的工作流程設計的其他相容性行為。它支援客戶 Cromwell 指令和一些不符合的邏輯。

WDL lenient 支援 WDL [有限例外](https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md#-limited-exceptions)清單中下列項目的類型轉換：
+ 浮動至 Int，其中強制不會導致精確度損失 （例如 1.0 映射至 1)。
+ Int/Float 字串，其中強制不會導致精確度損失。
+ Map【W， X】 到 Array【Pair【Y， Z】】，如果 W 可強制使用 Y，而 X 可強制使用 Z。
+ Array【Pair【W， X】】 到 Map【Y， Z】，如果 W 可強制 Y，X 可強制 Z （例如 1.0 映射至 1)。

若要使用隱含類型轉換，請在建立工作流程或工作流程版本時，將工作流程引擎指定為 WDL\_LENIENT。

在 主控台中，工作流程引擎參數名為**語言**。在 API 中，工作流程引擎參數名為**引擎**。如需詳細資訊，請參閱 [建立私有工作流程](create-private-workflow.md) 或 [建立工作流程版本](workflows-version-create.md) 。

## input.json 中的命名空間定義
<a name="workflow-wdl-namespace-defn"></a>

HealthOmics 在 input.json 中支援完整變數。例如，如果您在工作流程 **SumWorkflow** 中宣告兩個名為 number1 和 number2 的輸入變數：

```
workflow SumWorkflow {
  input {
    Int number1
    Int number2
  }
}
```

 您可以在 input.json 中使用它們做為完整變數：

```
{
    "SumWorkflow.number1": 15,
    "SumWorkflow.number2": 27
}
```

## WDL 中的主要類型
<a name="workflow-wdl-primitive-types"></a>

下表顯示 WDL 中的輸入如何對應至相符的基本類型。HealthOmics 提供類型強制的有限支援，因此我們建議您設定明確類型。


**基本類型**  

| WDL 類型 | JSON 類型 | 範例 WDL | 範例 JSON 金鑰和值 | 備註 | 
| --- | --- | --- | --- | --- | 
| Boolean | boolean | Boolean b | "b": true | 值必須是小寫且沒有引號。 | 
| Int | integer | Int i | "i": 7 | 必須取消引號。 | 
| Float | number | Float f | "f": 42.2 | 必須取消引號。 | 
| String | string | String s | "s": "characters" | 做為 URI 的 JSON 字串必須映射至要匯入的 WDL 檔案。 | 
| File | string | File f | "f": "s3://amzn-s3-demo-bucket1/path/to/file" | 只要為工作流程提供的 IAM 角色具有這些物件的讀取存取權，Amazon S3 和 HealthOmics 儲存 URIs 就會匯入。不支援其他 URI 結構描述 （例如 file://、 https://和 ftp://)。URI 必須指定 物件。它不能是目錄，表示它不能以 結尾/。 | 
| Directory | string | Directory d | "d": "s3://bucket/path/" | Directory 類型不包含在 WDL 1.0 或 1.1 中，因此您需要將 version development新增至 WDL 檔案的 標頭。URI 必須是 Amazon S3 URI，且字首結尾為 '/'。目錄的所有內容都會以單一下載方式遞迴複製到工作流程。Directory 應該只包含與工作流程相關的檔案。 | 

## WDL 中的複雜類型
<a name="workflow-wdl-complex-types"></a>

下表顯示 WDL 中的輸入如何對應至相符的複雜 JSON 類型。WDL 中的複雜類型是由基本類型組成的資料結構。清單等資料結構將轉換為陣列。


**複雜類型**  

| WDL 類型 | JSON 類型 | 範例 WDL | 範例 JSON 金鑰和值 | 備註 | 
| --- | --- | --- | --- | --- | 
| Array | array | Array[Int] nums | “nums": [1, 2, 3] | 陣列的成員必須遵循 WDL 陣列類型的格式。 | 
| Pair | object | Pair[String, Int] str\_to\_i | “str\_to\_i": {"left": "0", "right": 1} | 配對的每個值都必須使用其相符 WDL 類型的 JSON 格式。WDL 對 JSON 表示法中的字串索引鍵名稱不區分大小寫。例如，當還原序列化為配對類型時，{"left"： "0"、"right"： 1} 和 {"LEFT"： "0"、"Right"： 1} 被視為相等。 | 
| Map | object | Map[Int, String] int\_to\_string | "int\_to\_string": { 2: "hello", 1: "goodbye" } | 映射中的每個項目都必須使用其相符 WDL 類型的 JSON 格式。 | 
| Struct | object | <pre>struct SampleBamAndIndex { <br />  String sample_name <br />  File bam <br />  File bam_index <br />} SampleBamAndIndex b_and_i</pre>  |  <pre>"b_and_i": { <br />   "sample_name": "NA12878", <br />   "bam": "s3://amzn-s3-demo-bucket1/NA12878.bam", <br />   "bam_index": "s3://amzn-s3-demo-bucket1/NA12878.bam.bai" <br />}           </pre>  | 結構成員的名稱必須與 JSON 物件金鑰的名稱完全相符。每個值必須使用相符 WDL 類型的 JSON 格式。 | 
| Object | N/A | N/A | N/A | WDL Object類型已過期，Struct應該在所有情況下取代為 。 | 

## WDL 中的指令
<a name="workflow-wdl-directives"></a>

HealthOmics 在 HealthOmics 支援的所有 WDL 版本中支援下列指令。

### 設定 GPU 資源
<a name="workflow-wdl-directive-gpu"></a>

HealthOmics 支援執行期屬性**acceleratorCount**，**acceleratorType**以及所有支援的 [GPU 執行個體](https://docs.aws.amazon.com/omics/latest/dev/task-accelerators.html)。HealthOmics 也支援名為 **gpuType**和 的別名**gpuCount**，其功能與其加速器相同。如果 WDL 定義包含兩個指令，HealthOmics 會使用加速器值。

下列範例示範如何使用這些指令：

```
runtime {
    gpuCount: 2
    gpuType: "nvidia-tesla-t4"
}
```

### 使用 設定資源備用 **omicsResourceFallbackOrder**
<a name="workflow-wdl-directive-fallback"></a>

HealthOmics 支援**omicsResourceFallbackOrder**執行時間指令，以定義任務的加速器 （或 GPU) 和 CPU 資源設定檔的排序清單。當請求的加速器類型無法使用時，HealthOmics 會自動進入清單中的下一個設定檔。您可以包含僅限 CPU 的設定檔做為最終選項。

下列範例會`nvidia-l40s`先嘗試 ，然後 `nvidia-l4`，如果沒有可用的加速器，最後會回到 CPU：

```
runtime {
    docker: "my-registry/align-multi-arch:latest"
    omicsResourceFallbackOrder: [
        {"acceleratorType": "nvidia-l40s", "acceleratorCount": 1, "cpu": 8, "memory": "32 GiB", "omicsResourceWaitTimeoutInMin": 45},
        {"acceleratorType": "nvidia-l4",   "acceleratorCount": 1, "cpu": 8, "memory": "32 GiB"},
        {"cpu": 32, "memory": "128 GiB"}
    ]
}
```

HealthOmics 會在容器中自動設定**AWS\_HEALTHOMICS\_RESOURCE\_TYPE**環境變數。其值為作用中設定檔的加速器類型 （例如 `nvidia-l40s`)，或僅限 CPU 設定檔`cpu`的值。當 GPU 和 CPU 程式碼路徑不同時，請使用它來分支命令。

如果清單中的每個設定檔都用盡，則任務會失敗，原因為 `ALL_PROFILES_INSTANCE_RESERVATION_FAILED`。OOM 和服務錯誤重試會在目前的設定檔中運作，不會繼續進行下一個設定檔。

如需詳細資訊，請參閱 [進階資源組態](advanced-resource-configuration.md) 和 以取得支援的加速器類型，請參閱 [HealthOmics 工作流程定義中的任務加速器](task-accelerators.md)。

### 設定任務重試是否有服務錯誤
<a name="workflow-wdl-task-retry"></a>

HealthOmics 最多可為因服務錯誤 (5XX HTTP 狀態碼） 而失敗的任務支援兩次重試。您可以設定重試次數上限 (1 或 2)，也可以選擇不重試服務錯誤。根據預設，HealthOmics 最多會嘗試兩次重試。

下列範例會設定 `preemptible`以選擇不重試服務錯誤：

```
{
  preemptible: 0 
}
```

如需 HealthOmics 中任務重試的詳細資訊，請參閱 [任務重試](monitoring-runs.md#run-status-task-retries)。

### 設定記憶體不足的任務重試
<a name="workflow-wdl-retries"></a>

HealthOmics 支援因記憶體不足而失敗的任務重試 （容器結束碼 137、4XX HTTP 狀態碼）。HealthOmics 會將每次重試嘗試的記憶體量加倍。

根據預設，HealthOmics 不會針對此類型的失敗重試。使用 `maxRetries`指令來指定重試次數上限。

下列範例`maxRetries`會將 設為 3，讓 HealthOmics 嘗試完成任務最多四次 （初次嘗試加上三次重試）：

```
runtime {
    maxRetries: 3
}
```

**注意**  
記憶體不足的任務重試需要 GNU findutils 4.2.3\+。預設 HealthOmics 映像容器包含此套件。如果您在 WDL 定義中指定自訂映像，請確定映像包含 GNU findutils 4.2.3\+。

### 設定傳回碼
<a name="workflow-wdl-directive-returnCodes"></a>

**returnCodes** 屬性提供指定傳回碼或一組傳回碼的機制，表示任務成功執行。WDL 引擎會遵守您在 WDL 定義**執行時間**區段中指定的傳回代碼，並相應地設定任務狀態。

```
runtime {
    returnCodes: 1
}
```

HealthOmics 也支援名為 **continueOnReturnCode** 的別名，其功能與 **returnCodes** 相同。如果您指定這兩個屬性，HealthOmics 會使用 **returnCodes** 值。

### 支援的 WDL `disks`表單
<a name="workflow-wdl-disks-forms"></a>

HealthOmics 接受所有標準 WDL 1.1 `disks`表單。掛載路徑和磁碟類型指標 (`SSD`、`HDD`) 會被忽略，只會擷取數值大小。如果宣告多個項目，大小會加總為單一`/tmp`配置。


| 接受的表單 | 範例 | 已解決的大小 | 
| --- | --- | --- | 
| Integer | disks: 700 | 700 GiB | 
| String | disks: "700" | 700 GiB | 
| 具有單位的字串 | disks: "700 GiB" 或 "700 GB" | 700 GiB | 
| 具有路徑和類型的 Cromwell 樣式 | disks: "local-disk 700 SSD" | 700 GiB （忽略路徑和類型） | 
| 逗號分隔的項目 | disks: "local-disk 300 SSD, /scratch 200 SSD" | 500 GiB （加總） | 
| 字串陣列 | disks: ["/tmp 300 GiB", "/scratch 200 GiB"] | 500 GiB （加總） | 

HealthOmics 會將所有暫時性儲存掛載到 `/tmp`。如果您的工作流程定義宣告多個`disks`項目，則會加總大小，並將總計佈建為單一`/tmp`磁碟區。如需 WDL `disks`執行時間屬性的詳細資訊，請參閱 [WDL 1.1 規格。](https://github.com/openwdl/wdl/blob/wdl-1.1/SPEC.md#disks)

## 其他支援的執行期屬性
<a name="workflow-wdl-other-runtime-attributes"></a>

### 使用`omicsTimeout`執行時間屬性設定任務層級逾時
<a name="workflow-wdl-omics-timeout"></a>

HealthOmics `omicsTimeout` 提供自訂屬性，可在工作流程中設定任務持續時間上限。使用下列一或多個單位，將逾時持續時間指定為整數 （秒） 或字串：`s`、`h`、 `m`或 `d`。例如，`"40m"`、`"1h30m"` 或 `"1m3s"`。

下列範例顯示如何在 WDL 任務定義的 `runtime`區段中指定 `omicsTimeout` 屬性。此範例會設定逾時 40 分鐘。

```
    runtime {
        omicsTimeout: "40m"
    }
```

HealthOmics 為 WDL `omicsTimeout`執行期屬性提供下列支援：

1. HealthOmics 支援逾時值的 1 分鐘精細程度。您可以指定介於 60 秒和最大執行持續時間值之間的值。

1. 如果您輸入的值小於 60，HealthOmics 會四捨五入至 60 秒。對於 60 以上的值，HealthOmics 會四捨五入到最接近的分鐘。

1. 如果任務逾時，HealthOmics 會取消任務。此操作的持續時間可以是 1 到 2 分鐘。

1. 在任務逾時時，HealthOmics 會將執行和任務狀態設定為失敗，並取消執行中的其他任務 （適用於處於啟動、待定或執行狀態的任務）。HealthOmics 會將逾時之前完成的任務輸出匯出至您指定的 S3 輸出位置。

1. 任務花費在待定狀態的時間不會計入任務持續時間。

1. 如果執行是執行群組的一部分，且執行群組比任務計時器快逾時，則執行和任務會轉換為失敗狀態。

所有執行都有可調整配額[HealthOmics 服務配額](service-quotas.md)控制的最大持續時間。您可以請求提高此配額。

## WDL 中的任務中繼資料
<a name="workflow-wdl-task-metadata"></a>

HealthOmics 支援 WDL 任務的下列中繼資料選項。

### 使用揮發性屬性停用任務層級快取
<a name="workflow-wdl-volatile-attribute"></a>

**揮發**性屬性可讓您停用 WDL 工作流程中特定任務的呼叫快取。當任務標示為揮發性時，即使為執行啟用快取，也會一律執行且永遠不會使用快取的結果。

將**揮發性**屬性新增至任務定義的**中繼**區段：

```
task my_volatile_task {
    meta {
        volatile: true
    }
    
    input {
        String input_file
    }
    
    command {
        echo "Processing ${input_file}" > output.txt
    }
    
    output {
        File result = "output.txt"
    }
}
```

## WDL 工作流程定義範例
<a name="wdl-example"></a>

下列範例顯示用於在 WDL `CRAM``BAM`中從 轉換為 的私有工作流程定義。`CRAM` 工作流程的 `BAM`定義了兩個任務，並使用容器中的工具`genomes-in-the-cloud`，如範例所示，並且可公開使用。

下列範例示範如何將 Amazon ECR 容器包含為參數。這可讓 HealthOmics 在啟動執行之前驗證容器的存取許可。

```
{
   ...
   "gotc_docker":"<account_id>.dkr.ecr.<region>.amazonaws.com/genomes-in-the-cloud:2.4.7-1603303710"
}
```

下列範例顯示當檔案位於 Amazon S3 儲存貯體時，如何指定要在執行中使用的檔案。

```
{
    "input_cram": "s3://amzn-s3-demo-bucket1/inputs/NA12878.cram",
    "ref_dict": "s3://amzn-s3-demo-bucket1/inputs/Homo_sapiens_assembly38.dict",
    "ref_fasta": "s3://amzn-s3-demo-bucket1/inputs/Homo_sapiens_assembly38.fasta",
    "ref_fasta_index": "s3://amzn-s3-demo-bucket1/inputs/Homo_sapiens_assembly38.fasta.fai",
    "sample_name": "NA12878"
}
```

如果您想要從序列存放區指定檔案，請指出 ，如下列範例所示，使用序列存放區的 URI。

```
{
    "input_cram": "omics://429915189008.storage.us-west-2.amazonaws.com/111122223333/readSet/4500843795/source1",
    "ref_dict": "s3://amzn-s3-demo-bucket1/inputs/Homo_sapiens_assembly38.dict",
    "ref_fasta": "s3://amzn-s3-demo-bucket1/inputs/Homo_sapiens_assembly38.fasta",
    "ref_fasta_index": "s3://amzn-s3-demo-bucket1/inputs/Homo_sapiens_assembly38.fasta.fai",
    "sample_name": "NA12878"
}
```

然後，您可以在 WDL 中定義工作流程，如下列範例所示。

```
 version 1.0
workflow CramToBamFlow {
    input {
        File ref_fasta
        File ref_fasta_index
        File ref_dict
        File input_cram
        String sample_name
        String gotc_docker = "<account>.dkr.ecr.us-west-2.amazonaws.com/genomes-in-the-
cloud:latest"
    }
    #Converts CRAM to SAM to BAM and makes BAI.
    call CramToBamTask{
         input:
            ref_fasta = ref_fasta,
            ref_fasta_index = ref_fasta_index,
            ref_dict = ref_dict,
            input_cram = input_cram,
            sample_name = sample_name,
            docker_image = gotc_docker,
     }
     #Validates Bam.
     call ValidateSamFile{
        input:
           input_bam = CramToBamTask.outputBam,
           docker_image = gotc_docker,
     }
     #Outputs Bam, Bai, and validation report to the FireCloud data model.
     output {
         File outputBam = CramToBamTask.outputBam
         File outputBai = CramToBamTask.outputBai
         File validation_report = ValidateSamFile.report
      }
}
#Task definitions.
task CramToBamTask {
    input {
       # Command parameters
       File ref_fasta
       File ref_fasta_index
       File ref_dict
       File input_cram
       String sample_name
       # Runtime parameters
       String docker_image
    }
   #Calls samtools view to do the conversion.
   command {
       set -eo pipefail

       samtools view -h -T ~{ref_fasta} ~{input_cram} |
       samtools view -b -o ~{sample_name}.bam -
       samtools index -b ~{sample_name}.bam
       mv ~{sample_name}.bam.bai ~{sample_name}.bai
    }
    
    #Runtime attributes:
    runtime {
        docker: docker_image
    }

    #Outputs a BAM and BAI with the same sample name
     output {
         File outputBam = "~{sample_name}.bam"
         File outputBai = "~{sample_name}.bai"
    }
}

#Validates BAM output to ensure it wasn't corrupted during the file conversion.
task ValidateSamFile {
   input {
      File input_bam
      Int machine_mem_size = 4
      String docker_image
   }
   String output_name = basename(input_bam, ".bam") + ".validation_report"
   Int command_mem_size = machine_mem_size - 1
   command {
       java -Xmx~{command_mem_size}G -jar /usr/gitc/picard.jar \
       ValidateSamFile \
       INPUT=~{input_bam} \
       OUTPUT=~{output_name} \
       MODE=SUMMARY \
       IS_BISULFITE_SEQUENCED=false
    }
    runtime {
    docker: docker_image
    }
   #A text file is generated that lists errors or warnings that apply.
    output {
        File report = "~{output_name}"
    }
}
```