3

次の Fortran コードは、2D 配列 x に値 v を入力します。

      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

このアサーションが失敗するのはなぜですか?

4

2 に答える 2

3

intent(inout)x は、呼び出し元に値を返すように宣言する必要があります。

ただし、配列スライスを渡すことは配列に対して機能しないため、これにより別の問題が発生しintent(inout)ます。この簡単な例では、Python から呼び出すことで回避できます。

fill(x, 2.0).

本当にスライスを渡したい場合は、x をインテント (in,out) として宣言し、python から呼び出す必要があります。 x[:,:,0] = fill(x[:,:,0],2.0)

さまざまな属性の説明は、次の場所にあります。

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

于 2010-10-21T03:39:11.587 に答える
0

私はちょうどこの問題を抱えていました。どちらintent(inout)intent(inplace)それを修正しませんでした。問題は明らかに の配列チェック ルーチンarray_from_pyobj()fortranobject.cあります。このルーチンは、ビルドするすべてのモジュールに同梱され、f2pyリンクされています。array_from_pyobj()入力が適切な形状の連続した配列に変換されるようにあらゆる努力を払い、多くのチェックを行います。そのうちの 1 つは、元の配列を処理する代わりにコピーが作成されるなど、単一要素の配列では適切に機能しません。

それを修正することはできますが、...うーん... とにかく、パフォーマンスライブラリへのインターフェースにこのポリモーフィズムのものは必要ありません...すべての引数がすでに保証されているライブラリ呼び出しをラップする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;
}

私の計画はfortranobject.c、Python ラッパー クラスの開発中にオリジナルを使用することです。確かに、ライブラリ関数の呼び出しを間違えるたびにハード クラッシュが発生するのではなく、穏やかなエラー メッセージが表示される方が有利です。すべてのライブラリ呼び出しが機能することを確認したら、カスタムを使用fortranobject.cします。これは、単一要素の配列でも機能します。

于 2013-10-28T19:30:24.067 に答える