2

私は、Matrix クラスとそれを使用する大量のコードを含む古くて成長した C++ ライブラリを持っています。基本的には

class Matrix {
  double* p;      // the actual data
  int nd;         // number of dimensions
  int d0, d1, d2; // the actual dimensionality

  // ... (a whole lot of functions computing various things, like SVDs, dotproduct etc.
}

ここで、SWIG を使用して Python ラッパーを作成します。Python 側で NumPy 配列を使用して、他の世界との互換性を維持したいと考えています。したがって、実際には C++ Matrix クラスの機能は必要ありませんが、この C++ Matrix を必要とするライブラリの他の部分を使用したいと考えています。したがって、完璧な状況は、NumPy 配列から Matrix クラスに typemap を書き込むことができれば、すべての呼び出しで NumPy 配列を透過的に変換し、メモリを同期した状態に保つことができます。私たちのライブラリにいくつかの関数があるとしましょう。

int some_function(Matrix& in) { /* do some stuff */ }

Pythonで次のようなことができれば素晴らしいでしょう:

a = numpy.array[1,2,3,4]
b = some_function(a)

numpy.i があることは理解していますが、それは関数マッピングと単純な古い C 配列に関するもののようです。また、タイプマップが必要なものを達成する必要があることも理解していますが、numpy データに実際にアクセスする方法がよくわかりません。それを行う(比較的)簡単な方法はありますか?

また、いくつかのチュートリアルへのポインタをいただければ幸いです。

4

1 に答える 1

1

あなたが提供した情報に基づいて、タイプマップが機能します。しかし、断続的な SWIG ユーザーとしての私の経験 (通常、2 週間ほど頻繁に使用した後、次のプロジェクト/フェーズまで中断) は、その機能を理解する時間がある人はほとんどいないということです。

あなたの場合、SWIG タイプマップは要件よりも便利だと思うので、次の 2 つのアプローチのいずれかを使用します。

  1. numpy.array から Matrix への変換を行う Python 関数を作成します (Matrix は SWIG によって C++ から Python にエクスポートされたものです)
  2. 組み込みの numpy.i タイプマップを使用して、そのタイプマップで C++ 型を受け入れる C++ 関数を呼び出し、その関数を定義して呼び出すint some_function(Matrix& in)

オプション 1 の利点は、Python 関数を再バインドすることで変換を自動化できることです。

old_some_func = some_function
def some_function(numpy_array):
    tempMat = Matrix()
    # convert numpy_array to SWIG'd Matrix class
    old_some_func(tempMat)

これを行うことによるパフォーマンスへの影響は無視できる可能性がありますが、テストする必要があります。SWIG を使用しない場合 (つまり、C API を使用している場合)、この手法には、C++ ライブラリを変更する必要がないという追加の利点があります (SWIG の extend ディレクティブを参照してください)。

オプション 2 の利点は、変換が C/C++ レベルであるため、関係する内容によっては、パフォーマンスが向上する可能性があることです。numpy.i typemaps の 1 つが numpy.array を float[numValues] 配列にマップし、C++ マトリックスが単精度浮動小数点値を保持しているとします。その場合、プロジェクトの .i ファイルで C++ some_function(float*, numValues) を定義し、その関数が some_function(Matrix) を呼び出します。C++ Matrix クラスが配列データへのポインターを格納できるかどうかを確認してください。これにより、1 つまたは場合によっては 2 つのレイヤー (Python -> SWIG some_function(array) -> some_function(Matrix)) にわたってデータをコピーすることを回避できます。

しかし、心に留めておいてください: C++ some_function 内での計算では、2 つのオプション間のパフォーマンスの違いは重要ではない可能性があります。テストする必要があります。次に、最も簡単で保守しやすいものを選択します (おそらくオプション 1)。

于 2013-08-13T19:14:46.217 に答える