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.