2010-01-29 53 views
3

以下Fortran代碼填充的2D陣列X具有值vF2PY:傳遞單元件陣列到Fortran

 subroutine fill(x,v,m,n) 
     real*8 x(m,n),v 
     integer m,n,i 
cf2py intent(in) :: x,v,m,n 
     forall(i=1:m,j=1:n) x(i,j) = v 
     end 

當Python調用此函數:

x = numpy.array([[[0.0]]],order='F') 
fill(x[:,:,0],2.0) 
assert(x[0,0,0]==2.0) # Assertion failed 

爲什麼這個斷言故障?

+0

嗯......'copy(x,y)'你是指'copy(x,y,1)'? – dmckee 2010-01-29 02:17:47

回答

3

如果您希望將值傳遞給調用者,則應將x聲明爲intent(inout)

但是,這會導致一個額外的問題,因爲傳遞陣列切片不適用於intent(inout)陣列。在這個簡單的例子中,你可以通過從python調用它來解決它:

fill(x, 2.0)

如果你真的想通過一個片,那麼你需要聲明x作爲意圖(IN,OUT),並從蟒蛇撥打:

x[:,:,0] = fill(x[:,:,0],2.0)

不同屬性的描述,可以發現

http://cens.ioc.ee/projects/f2py2e/usersguide/index.html#attributes

0

我剛纔有這個問題。 intent(inout)intent(inplace)都沒有修復它。這個問題顯然在陣列檢查例程array_from_pyobj()fortranobject.c中,它與f2py一起提供,並與每個構建的模塊鏈接。 array_from_pyobj()盡一切努力將任何輸入轉換爲適當形狀的連續數組,並進行許多檢查。其中之一對單元素數組無法正常工作,例如複製而不是在原始數組上工作。

有人可以解決這個問題,但是......好吧......我不想在性能庫的接口中使用這種多態性東西......我有一個Python類包裝已經保證的庫調用所有參數都正確傳遞。

所以我的修復是使fortranobject.c我自己的副本,只需通過下面的虛擬版本替換array_from_pyobj()

extern PyArrayObject * 
array_from_pyobj(const int type_num, npy_intp *dims, 
       const int rank, const int intent, PyObject *obj) { 

    int i; 
    PyArrayObject *arr = (PyArrayObject *)obj; 

    for (i=0; i<arr->nd; ++i) 
     dims[i] = arr->dimensions[i]; 
    return arr; 
} 

我的計劃是我的Python包裝類的開發過程中使用原始fortranobject.c其中誠然每次出現調用庫函數的錯誤時,獲取溫和的錯誤消息而不是硬性崩潰是一個優點。一旦我確定所有庫函數都可以工作,我將使用我的自定義fortranobject.c,它也適用於單元素數組。