2015-04-15 48 views
3

我正在編寫一些R模擬代碼,但希望利用Fortran的swift線性代數庫來替換核心迭代循環。到目前爲止,我主要着眼於使用.Fortran調用鏈接的F95子例程的顯而易見的選項;我想我應該優化內存使用(我傳遞非常大的數組),然後設置DUP=FALSE,但之後我在手冊中閱讀了關於此方法及其在R 3.1.0中的折舊和R 3.2.0中的禁用的危險的警告。現在手冊建議切換到.Call,但該功能本身不提供Fortran支持。在R中有效調用F95:使用.Fortran還是.Call?

我的谷歌搜索已經產生a stackoverflow question其探索到C代碼鏈接的Fortran子程序並使用.Call主叫它的一種方法。在我看來,這種事情可以像魅力或詛咒一樣工作。因此,我的問題:

  1. 瞄準速度和魯棒性,什麼是通過.Fortran,並通過.Call調用Fortran的風險和收益?
  2. 使用.Call來調用Fortran子例程有沒有更優雅/更高效的方法?
  3. 是否還有其他選擇?
+1

最常見* Fortran的快速線性代數庫*實際上是BLAS(或其派生之一)。 R不使用BLAS嗎? –

+0

一個粗略的搜索,它似乎確實使用這些庫,據我所知(任何人都可以證明/證明這一點?),Fortran可以實現的速度仍然無法達到。我發現[這篇文章](http://blog.nguyenvq.com/blog/2014/11/10/optimized-r-and-python-standard-blas-vs-atlas-vs-openblas-vs-mkl/)使用不同的庫對R進行基準測試版本,似乎使用英特爾MKL的[RRO](http://projects.revolutionanalytics.com/rro/)是勝利者。但是,我希望這個代碼最終成爲一個包,所以我必須堅持使用未修改的上游文件R. – Ixxie

+0

您鏈接的文章比較了BLAS的各種實現的性能。從Fortran與BLAS的各種實現的比較中可以得到非常類似的信息。結論會非常相似 - 在目前的架構上,英特爾的MKL可能是BLAS的最快實施。簡單地將Fortran放在R和慢BLAS之間不會改變任何事情。 –

回答

2

這裏的情況而我的想法:

.Call是一般首選接口。它直接爲您提供了一個指向底層R數據對象(a SEXP)的指針,所以所有的內存管理都是您的決定。您可以尊重NAMED字段並根據需要複製數據,或者忽略它(如果您知道您不會修改數據,或因爲其他原因而覺得舒服)

.Fortran嘗試自動從R SEXP對象向Fortran子例程提供適當的數據類型;然而,它的使用通常是不鼓勵的(因爲我不完全清楚,說實話)

你應該有一些運氣從C/C++例程調用編譯的Fortran代碼。給定一個名爲fortran_subroutine的Fortran子程序,您應該能夠在您的C/C++代碼中提供前向聲明,例如, (注意:您需要一個領導extern "C"的C++代碼):

void fortran_subroutine_(<args>); 

注意在函數名尾隨下劃線 - 這是多麼Fortran編譯器(即我所熟悉的,例如gfortran)「軋車'符號名稱,所以可用的符號將具有尾部下劃線。

此外,您需要確保您選擇的<args>從相應的C類型映射到相應的Fortran類型。幸運的是,R-exts提供了這樣的表格。

最後,R的R CMD build會自動促進R包的編譯+鏈接過程。因爲我顯然是一個懲罰貪婪的人,所以我爲produced an example package提供了足夠的信息,讓你瞭解綁定在這裏的工作方式。