2017-03-15 26 views
2

オペレーション中に出力テンソルの基礎となる記憶域を変更したい。C++の生ポインタデータからtensorflow :: Tensorを構築する方法

私は新しいデータの生ポインタ(float *)を持っています。カーネルを起動して戻る前に、この新しいデータに出力テンソルを設定して、この操作をハイジャックすることができます。

しかし、私はいつテンソル構造が浅いコピーのように見えるので、生のポインタを削除すべきかと混同しています。このテンソルの使用がすべて終了した後でしか、生ポインタを削除することはできません。しかし、どうすればこれを知らせることができますか?

答えて

2

ありTensorFlowランタイム内でこれを行うためのパブリックAPIはありませんが、次のシグネチャを持つC APIメソッドTF_NewTensor()を使用して、生のポインタからテンソルオブジェクトを作成することが可能である:

// Return a new tensor that holds the bytes data[0,len-1]. 
// 
// The data will be deallocated by a subsequent call to TF_DeleteTensor via: 
//  (*deallocator)(data, len, deallocator_arg) 
// Clients must provide a custom deallocator function so they can pass in 
// memory managed by something like numpy. 
extern TF_Tensor* TF_NewTensor(TF_DataType, const int64_t* dims, int num_dims, 
           void* data, size_t len, 
           void (*deallocator)(void* data, size_t len, 
                void* arg), 
           void* deallocator_arg); 

内部的には、参照カウントのTensorBufferオブジェクトが生ポインタの所有権を取得します。参照カウントがゼロまで低下すると(残念ながら、唯一のC APIは、これはopen issueある。直接TensorBufferからtensorflow::Tensorを作成するfriend accessを有する。)deallocator関数はdatalendellocator_argの値と呼ばれます。

+0

私の生ポインタを 'output_tensor-> getTensorBuffer() - > data() 'にmemcpyして、生ポインタを削除することができます。 –

+0

[this memcpy](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/framework/tensor_util.cc#L35)と同様のものです。私のTFはAndroid CPU上で動作しています。 –

+0

既に割り当てられている 'TensorBuffer'にあなたのデータを' memcpy() 'した場合、生のポインタを削除することができます(あなたのコードが所有者であると仮定します)。私の答えで示唆されたアプローチはあなたがコピーを避けることができます。 – mrry

1

残念ながら、これはあなたに正確な回答を与えるにはあまりにも少ない情報です。可能であれば、ポインタを削除することさえできません!

float* gf = nullptr; // global pointer (just for illustration) 

void calculate() 
{ 
    float f; 
    gf = &f; 
    doSomething(); 
    gf = nullptr; 
} 

いくつかのクラスの静的またはグローバル変数への質問のポイントであなたのポインタならば同じことが、適用されます。

はこのようなものを想像してみてください。

あなたは、この例のように、(通常は)非常にローカルで処理することができ、あなたは任意のより多くのそれを必要としないわかっている場合、それを削除し、ヒープ上の変数を作成した場合:

class C 
{ 
    std::vector<float>values; 

    C(size_t num) : values(num, 0.0f) { } 
    ~C() { } // data deleted automatically with vector 

    void function() 
    { 
     for(float& f : values) 
     { 
      gf = &f; 
      doSomething(); 
     } 
     gf = nullptr; 
    } 
}; 

operator delete[]への明示的な呼び出しがありませんか?さて、このベクトルは暗黙のうちに私のために処理するので、私は気にする必要はありません。生ポインタを使用することを余儀なくされたとしても、eを使用して削除を明示的に回避することができます。 g。 std::unique_ptr ...ベクタに注意してください:新しい要素をベクタに追加したり、ベクタに含まれている要素を削除すると、ポインタが無効になることがあります。

私の例では、ポインタを明示的にnullptrに設定していますので、浮動小数点値が使用されていないかどうかを調べることができます。ハイジャック時にチェックする必要があります。マルチスレッド環境では、競合状態に対してポインタを保護する可能性があります。

関連する問題