Cuneiform是用於大規模科學數據分析的開源工作流程語言英語Scientific workflow system[2][3]。 它是促進並行計算靜態類型純函數式編程語言。它的特徵是有個全功能的外界函數接口英語foreign function interface,允許用戶集成來自很多外部編程語言的軟件。Cuneiform在組織層面上提供了一些設施,如條件分支通用遞歸,使其具有圖靈完備性

Cuneiform
編程範型純函數式, 數據流程
設計者Jörgen Brandt
面市時間2013年,​11年前​(2013
當前版本
  • 3.0.5(2022年5月27日)[1]
編輯維基數據鏈接
型態系統簡單類型
實作語言Erlang
操作系統Linux, Mac OS
許可證Apache許可證 2.0
文件擴展名.cfl
網站cuneiform-lang.org
啟發語言
Swift (並行腳本語言)英語Swift (parallel scripting language)

概述

編輯

Cuneiform嘗試拉近在科學工作流程系統如Apache Taverna英語Apache TavernaKNIME英語KNIMEGalaxy,與大規模數據分析程序模型如MapReducePig Latin之間的間隙,同時提供函數式編程語言的通用性。

Cuneiform是用分布式Erlang實現的。如果運行在分布式模態下,它導出一個遵循POSIX分布式文件系統,如GlusterCeph英語Ceph (software)#CephFS(用FUSE集成某個其他文件系統例如HDFS)。作為替代選擇,Cuneiform腳本可以執行在HTCondor英語HTCondorApache Hadoop頂上[4][5][6][7]

Cuneiform受到了Peter Kelly的工作的影響,他提議函數式編程作為科學工作流程執行的模型[8]。 故而,Cuneiform不同於其他的基於數據流程編程的工作流程語言,如並行腳本語言Swift英語Swift (parallel scripting language)[9]

擴展軟件集成

編輯

外部工具和庫(比如RPython庫)是通過外界函數接口英語foreign function interface來集成的。通過它可以組合,比如允許通過snippet節點使用外部軟件的KNIME英語KNIME,或為集成Java軟件提供BeanShell英語BeanShell服務的Apache Taverna英語Apache Taverna。通過定義採用外界語言的任務,就可能使用一個外部工具或庫的API。這種方式下,工具可以直接集成而不需要寫包裝器或重新實現工具[10]

目前支持的外界編程語言有:

計劃增加外界語言AWKgnuplot

類型系統

編輯

Cuneiform提供簡單的、靜態檢查的類型系統[11]。雖然Cuneiform提供列表作為複合數據類型,它省略了傳統的列表訪問子(headtail),以避免在訪問空列表時,可能引起的運行時間錯誤的可能性。轉而列表只能通過在其上mapfold,以全有或全無方式訪問。此外,Cuneiform(在組織層面)省略了算術,這排除了除以零的可能性。省略任何的部份定義運算,允許保證運行時間錯誤只能在外界代碼中引發。

基礎數據類型

編輯

Cuneiform提供的基礎數據類型有布爾值字符串文件。這裡的文件被用來以任意格式在外界函數之間交換數據。

記錄和模式匹配

編輯

Cuneiform提供記錄(結構)作為複合數據類型。下面的例子展示定義一個變量r,作為有兩個字段a1a2的記錄,第一個是字符串,而第二個是布爾值:

let r : <a1 : Str, a2 : Bool> =
  <a1 = "my string", a2 = true>;

記錄可以要麼通過投影(projection)要麼通過模式匹配來訪問。下面的例子從記錄r,提取兩個字段a1a2

let a1 : Str = ( r|a1 );

let <a2 = a2 : Bool> = r;

列表和列表處理

編輯

進一步的,Cuneiform提供列表作為複合數據類型。下面的例子展示定義一個變量xs,作為一個有三個元素的一個文件:

let xs : [File] =
  ['a.txt', 'b.txt', 'c.txt' : File];

列表可以通過forfold算子來處理。這裡的for算子可以接受多個列表,來逐個元素的處置列表(類似於Racket中的for/listCommon Lisp中的mapcarErlang中的zipwith)。

下面的例子展示如何在一個單一的列表上map,結果是一個文件列表:

for x <- xs do
  process-one( arg1 = x )
  : File
end;

下面的例子展示如何zip兩個列表,結果也是一個文件列表:

for x <- xs, y <- ys do
  process-two( arg1 = x, arg2 = y )
  : File
end;

最後,列表可以使用fold算子來做聚集。下面的例子合計一個列表的元素:

  fold acc = 0, x <- xs do
    add( a = acc, b = x )
  end;

並行執行

編輯

Cuneiform是純函數式語言,就是說它不支持可變引用。作為結論,它可以使用獨立子項,將一個程序分解成可並行的各部份。Cuneiform調度器分布這些部份到做工節點。此外,Cuneiform採用傳名調用求值策略,值只在它對計算結果有貢獻時計算。最後,外界函數應用是記憶化的,用來加速包含以前推導結果的計算。

例如,下列Cuneiform程序允許fg的應用平行的運行,而h是有依賴的,它只在fg二者完成的時候可以開始:

let output-of-f : File = f();
let output-of-g : File = g();

h( f = output-of-f, g = output-of-g );

下列Cuneiform程序通過將函數f映射到一個三元素列表,創建了三個並行應用:

let xs : [File] =
  ['a.txt', 'b.txt', 'c.txt' : File];

for x <- xs do
  f( x = x )
  : File
end;

類似的,在記錄r的構造中,fg的應用是獨立的,因此可以並行運行:

let r : <a : File, b : File> =
  <a = f(), b = g()>;

例子

編輯

下面是一個hello-world腳本:

def greet( person : Str ) -> <out : Str>
in Bash *{
  out="Hello $person"
}*

( greet( person = "world" )|out );

這個腳本定義了採用Bash的一個任務greet,它對其字符串實際參數person預加上"Hello "。這個函數產生具有一個單一字符串字段的記錄out。應用greet,綁定實際參數person到字符串"world",產生記錄<out = "Hello world">。將這個記錄投影為它的字段out,求值出字符串"Hello world"

可以通過定義採用Bash的一個任務來集成命令行工具:

def samtoolsSort( bam : File ) -> <sorted : File>
in Bash *{
  sorted=sorted.bam
  samtools sort -m 2G $bam -o $sorted
}*

在這個例子中定義了任務samtoolsSort。它調用了工具SAMtools英語SAMtools,處置一個BAM格式的輸入文件,並產生一個排序了也是BAM格式的輸出文件。

發行歷史

編輯
版本 出現日期 實現語言 發布平台 外界語言
1.0.0 2014年5月 Java Apache Hadoop Bash, Common Lisp, GNU Octave, Perl, Python, R, Scala
2.0.x 2015年3月 Java HTCondor英語HTCondor, Apache Hadoop Bash, BeanShell英語BeanShell, Common Lisp, MATLAB, GNU Octave, Perl, Python, R, Scala
2.2.x 2016年4月 Erlang HTCondor英語HTCondor, Apache Hadoop Bash, Perl, Python, R
3.0.x 2018年2月 Erlang 分布式Erlang Bash, Erlang, Java, MATLAB, GNU Octave, Perl, Python, R, Racket

在2016年4月,Cuneiform的實現語言從Java切換成了Erlang,並且在2018年2月,它的主要發布執行平台從Apache Hadoop變更為分布式Erlang。此外,從2015年到2018年,HTCondor英語HTCondor曾被作為可替代執行平台來維護。

Cuneiform的外表語法修訂過兩次,這反映在主版本號上。

版本1

編輯

在2014年5月發布的最初草案中,Cuneiform密切關聯於Make,它構造解釋器在執行期間要遍歷的靜態數據依賴圖。與後來版本的主要區別,是缺乏條件、遞歸或靜態類型檢查。區分文件和字符串,是通過同波浪號~形成一個單一引用的字符串。腳本的查詢表達式,通過target關鍵字來介入。Bash是缺省外界語言。函數應用必須使用apply形式來完成,它接受task作為第一個關鍵字實際參數。一年之後,這種外表語法被一種精簡卻類似的版本所替代。

下面的例子腳本從一個FTP服務器下載一個參考genome:

declare download-ref-genome;

deftask download-fa( fa : ~path ~id ) *{
    wget $path/$id.fa.gz
    gunzip $id.fa.gz
    mv $id.fa $fa
}*

ref-genome-path = ~'ftp://hgdownload.cse.ucsc.edu/goldenPath/hg19/chromosomes';
ref-genome-id = ~'chr22';

ref-genome = apply(
    task : download-fa
    path : ref-genome-path
    id : ref-genome-id
);

target ref-genome;

版本2

編輯
 
基於Swing的編輯器和Cuneiform 2.0.3的REPL

Cuneiform外表語法的第二個草案,首次發表於2015年3月,在Cuneiform的實現語言從JavaErlang的遷移期間,持續使用了三年。求值不同於早期方式,解釋器歸約一個表達式,而非遍歷一個靜態圖。在外表語法保持使用這段時期,解釋器被形式化和簡化,這導致了第一個Cuneiform的語義規定。語法特徵是有了條件。但是,布爾值被編碼為列表,再度利用空列表為布爾值false,非空列表為布爾值true。遞歸後來作為形式化的副產品而增加。但是,靜態類型檢查,只在後來的版本3中介入。

下列腳本解壓一個壓縮文件,並把它分解為大小均勻的劃分:

deftask unzip( <out( File )> : zip( File ) ) in bash *{
  unzip -d dir $zip
  out=`ls dir | awk '{print "dir/" $0}'`
}*

deftask split( <out( File )> : file( File ) ) in bash *{
  split -l 1024 $file txt
  out=txt*
}*

sotu = "sotu/stateoftheunion1790-2014.txt.zip";
fileLst = split( file: unzip( zip: sotu ) );

fileLst;

版本3

編輯

Cuneiform外表語法的當前版本,比較於早期的草案,是嘗試拉近與主流函數式編程語言的間隙。它的特徵是簡單的靜態檢查的類型系統,並在列表之外介入記錄作為第二個複合數據結構類型。布爾值獨立為基礎數據類型。

下列腳本解包一個文件,結果為一個文件列表:

def untar( tar : File ) -> <fileLst : [File]>
in Bash *{
  tar xf $tar
  fileLst=`tar tf $tar`
}*

let hg38Tar : File =
  'hg38/hg38.tar';

let <fileLst = faLst : [File]> =
  untar( tar = hg38Tar );

faLst;

引用

編輯
  1. ^ Release 3.0.5. 2022年5月27日 [2023年3月19日]. 
  2. ^ 存档副本. [2021-03-03]. (原始內容存檔於2021-03-18). 
  3. ^ Brandt, Jörgen; Bux, Marc N.; Leser, Ulf. Cuneiform: A functional language for large scale scientific data analysis (PDF). Proceedings of the Workshops of the EDBT/ICDT. 2015, 1330: 17–26 [2021-03-03]. (原始內容 (PDF)存檔於2020-02-17). 
  4. ^ Scalable Multi-Language Data Analysis on Beam: The Cuneiform Experience by Jörgen Brandt. Erlang Central. [28 October 2016]. (原始內容存檔於2 October 2016). 
  5. ^ Bux, Marc; Brandt, Jörgen; Lipka, Carsten; Hakimzadeh, Kamal; Dowling, Jim; Leser, Ulf. SAASFEE: scalable scientific workflow execution engine (PDF). Proceedings of the VLDB Endowment. 2015, 8 (12): 1892–1895 [2021-03-03]. doi:10.14778/2824032.2824094. (原始內容 (PDF)存檔於2020-11-25). 
  6. ^ Bessani, Alysson; Brandt, Jörgen; Bux, Marc; Cogo, Vinicius; Dimitrova, Lora; Dowling, Jim; Gholami, Ali; Hakimzadeh, Kamal; Hummel, Michael; Ismail, Mahmoud; Laure, Erwin; Leser, Ulf; Litton, Jan-Eric; Martinez, Roxanna; Niazi, Salman; Reichel, Jane; Zimmermann, Karin. Biobankcloud: a platform for the secure storage, sharing, and processing of large biomedical data sets (PDF). The First International Workshop on Data Management and Analytics for Medicine and Healthcare (DMAH 2015). 2015 [2021-03-03]. (原始內容 (PDF)存檔於2018-10-01). 
  7. ^ Scalable Multi-Language Data Analysis on Beam: The Cuneiform Experience. Erlang-factory.com. [28 October 2016]. (原始內容存檔於2020-07-12). 
  8. ^ Kelly, Peter M.; Coddington, Paul D.; Wendelborn, Andrew L. Lambda calculus as a workflow model. Concurrency and Computation: Practice and Experience. 2009, 21 (16): 1999–2017. doi:10.1002/cpe.1448.  Barseghian, Derik; Altintas, Ilkay; Jones, Matthew B.; Crawl, Daniel; Potter, Nathan; Gallagher, James; Cornillon, Peter; Schildhauer, Mark; Borer, Elizabeth T.; Seabloom, Eric W. Workflows and extensions to the Kepler scientific workflow system to support environmental sensor data access and analysis (PDF). Ecological Informatics. 2010, 5 (1): 42–50 [2021-03-03]. doi:10.1016/j.ecoinf.2009.08.008. (原始內容 (PDF)存檔於2022-02-25). 
  9. ^ Di Tommaso, Paolo; Chatzou, Maria; Floden, Evan W; Barja, Pablo Prieto; Palumbo, Emilio; Notredame, Cedric. Nextflow enables reproducible computational workflows. Nature Biotechnology. 2017, 35 (4): 316–319. PMID 28398311. doi:10.1038/nbt.3820. 
  10. ^ A Functional Workflow Language Implementation in Erlang (PDF). [28 October 2016]. (原始內容 (PDF)存檔於2022-02-25). 
  11. ^ Brandt, Jörgen; Reisig, Wolfgang; Leser, Ulf. Computation semantics of the functional scientific workflow language Cuneiform. Journal of Functional Programming. 2017, 27. S2CID 6128299. doi:10.1017/S0956796817000119.