2013-03-01 88 views
16

我有一個R包,它使用大量Fortran子例程來遞歸線性代數計算的嵌套循環(很大程度上取決於BLAS和LAPACK例程)。作爲Fortran的接口,我使用了.Fortran函數。我剛剛讀了Jonathan Callahan's blog post關於使用.Call而不是.C來編寫用C/C++編寫的子程序,它讓我想到在使用Fortran子程序時,使用.Call接口會更好一些,方法是在C中編寫一個簡單的包裝器, Fortran子程序?如上所述,我的Fortran代碼非常簡單,因爲我只是玩類型double或integer的多維數組。但我已經瞭解到,我必須在R端編寫相當多的檢查以確保一切都不會因爲我不小心忘記將某些矩陣的存儲模式更改爲整數或某些矩陣的維數發生變化而崩潰。R:使用帶有.Call和C/C++包裝器的Fortran子程序代替.Fortran的優點?

子程序寫爲F90/95。

+1

似乎合理的使用.Call()和一些C函數,然後你可以從C代碼中調用你的Fortran子程序,這是相對容易的(或者如果你真的不需要Fortran,甚至可以用C語言來做所有事情)。 – steabert 2013-03-29 13:02:59

+0

是的,但如果有的話會帶來什麼樣的好處?我可以完全切換到C,但是那樣會太麻煩,我懷疑它會有用,因爲我會從C調用Fortran BLAS函數。 – 2013-03-31 21:05:20

+0

可能是相關的:http://www.ualberta.ca/AICT/RESEARCH/LinuxClusters/doc/ifc91/main_for/mergedProjects/bldaps_for/pgsclmix.htm – KLDavenport 2013-03-31 22:26:08

回答

3

如果您正在處理大型數據集,可能會有優勢。 。呼叫可以更快,因爲每次調用該函數時都不復制數據。對於這個問題所描述的情況下,將不會有這樣的優點,因爲將R 2.15.1釋放注意到狀態

.C()和.Fortran()少做複製:論據是原始的,邏輯的整數,實數或複數向量,且未命名不會在調用之前複製,並且(調用或不調用)在調用之後不會被複制。列表不再被複制(它們應該在C代碼中以只讀方式使用)。

切換到.Call意味着您放棄.Fortran界面的便利性。您將SEXP傳遞到C代碼中,使用(可怕且沒有很好記錄的)R API對數據進行任何檢查/操作,然後從C中調用Fortran函數。任何使用您的代碼的人都必須瞭解R API和C/Fortran互操作。

+0

是的複製似乎是一個明顯的好處,雖然從R 2.15.1的差異稍微減少:「'.C()'和'.Fortran()'做少複製:參數是原始的,邏輯的,整數,真正的或複雜的載體,並且未命名不會在調用之前被複制,並且在調用之後不會複製(已命名或未被複制)。「 (來自R News)。 – 2013-04-04 06:16:14

+0

看起來在我的應用程序中,複製的效果並不顯着;我使用'DUP = FALSE'和'DUP = TRUE'測試了用'.Fortran'調用我的代碼,儘管我使用的是包含數百萬個元素的數組,但幾乎沒有任何區別。 – 2013-04-04 11:35:04

+0

我沒有意識到這些功能的行爲發生了變化。我編輯了這個問題來反映它。 – user2225804 2013-04-04 20:04:30