Pytorch: 複雑なテンソルの統合

作成日 2017年02月16日  ·  128コメント  ·  ソース: pytorch/pytorch

@ezyangからの新しい説明:

https://github.com/Roger-luo/pytorch-complexで作業が進行中です

組織の原則

  • 複雑なテンソルのサポートはPyTorchにとって重要であり、複雑なサポートを追加するために少量のコードを追加するパッチをコアに受け入れます。
  • 複雑なものを追加するには、多くの新しいカーネルとコードを作成する必要があります。このコードは最初はリポジトリから実行されるため、PyTorchのメインコードレビュープロセスを実行しなくても、ユーザーはそれらをすばやく簡単に繰り返すことができます。 短期的には大規模な新しいカーネルのレビューを確約するつもりはありませんが、最終的にはすべてのカーネルをPyTorchに戻すことを望んでいます。
  • 外部ライブラリはPyTorchとは別に構築できるため、PyTorchとマージすることなく(そしてマージの競合の負荷に対処することなく)、それを別個のリポジトリとして維持することができます。

    • PyTorchは、C++APIに重大な変更を加える場合があります。 あなたがこれらを私たちの注意を引くならば、私たちはこれらの問題を解決するのを助けるために全力を尽くします。

  • これに必要なフックはPyTorch1.0には付属していませんが、それほど遠くない将来にリリースされたバージョンのPyTorchに付属します。

複雑なカーネルでどのように作業しますか?

定常状態でのワークフローは次のようになります。

PyTorchには、複雑なdtypeを参照するためのAPIがネイティブに含まれていますが、デフォルトでは何も実行されません。 PyTorchは、複雑なテンソルを参照するtorch.complex64とtorch.complex128を定義します。 ただし、この方法でテンソルを作成しようとすると、デフォルトでPyTorchはエラーになります。

>>> torch.zeros({2,2}, dtype=torch.complex64)
RuntimeError: complex64 not supported by PyTorch

@ezyangは、これらのdtypeをPyTorchに追加するパッチを提供しました。 https://github.com/pytorch/pytorch/pull/11173

中期的には、PyTorchでネイティブにサポートされる基本機能(ゼロのテンソルの割り当てなど)のサポートを統合します。 サポートが「基本的」であるための合理的なプロキシは、CPUハーフテンソル(非常に貧弱)に対するPyTorchのネイティブサポートです。

PyTorchは、複雑なテンソルの実装を登録するためのインターフェイスを公開しています。 実装はTypeDefaultクラス(https://github.com/pytorch/pytorch/pull/11013)を継承し、このクラスのメソッドをオーバーライドして、複雑な実装を持つ関数の実装を定義します。 次のようになります。

struct CPUComplexFloatType final : public TypeDefault {
  virtual Tensor add(const Tensor & self, const Tensor & other, Scalar alpha=1) const override {
    // Your implementation of add for complex tensors
  }
  // ...
}

このクラスは、complexでサポートされているタイプを正確にオーバーライドします。 他のすべての実装はTypeDefaultによって提供され、デフォルトでエラーになります。

PyTorchソースリポジトリにチェックインされる自動生成ファイルとして、Type(インターフェイス全体)でサポートされているメソッドの正規のリストがあります。 APIの変更をdiffでこのファイルに通知します。 一般に、メソッドはPyTorchフロントエンドの対応する名前と1対1で対応しています。

一般に、まだ実装していない操作を使用する場合は、

警告:新しい操作のオープン登録もサポートする新しいシステムにTypeをリファクタリングする予定です(サポートする可能性のあるすべてのメソッドを定義する単一のスーパークラスがある場合、これは明らかに機能しません)。 したがって、Typeをサブクラスとして記述するという特定の実装戦略に縛られすぎないようにしてください。

新しい複雑な操作のみを公開するには、C++拡張APIを使用します。 C ++拡張APIは、 https: //pytorch.org/tutorials/advanced/cpp_extension.htmlに記載されています。基本的に、次のようなC++関数を記述できます。

at::Tensor imag(at::Tensor z) {
  ...
}

次に、C ++拡張APIがPythonバインディングを生成するため、Pythonからこの関数を呼び出すことができます。

一部の操作は、現在のPyTorchに「簡単に」統合できます。 たとえば、二項演算の実装では、BinaryOpsKernel.cppのadd_kernelを拡張して、複合型を介してディスパッチする方がおそらく理にかなっています(std :: complexは加算を実装しているため、無料で入手できます)。 これらのパッチが小さく、自己完結型である限り、タイムリーにマージすることをお約束します。

既存のインフラストラクチャを使用する代わりにTypeにオーバーライドを記述し、リベラルなコピー貼り付けを行うことで、ブロックを解除できるはずです。 しかし、それが簡単なときは避けましょう!

オートグラード。 すでに導関数式が定義されている操作に取り組んでいる限り、derivatives.yamlからの後方実装で呼び出されるすべての構成関数の複雑なサポートを実装している限り、autogradサポートを「自動的に」取得します。 。

場合によっては、複素数で機能するようにautograd式を調整する必要があります。 たとえば、「abs」の勾配は「grad」ではありません。 self.sign()'。 このような場合、必要なのは、「abs」のautograd式を「abs_backward」に変更するアップストリーム修正です。これは、オーバーライドできる関数です。

一般的な複素数値のバックプロパゲーションについては、いくつかの参照があります。

  1. アキラの「複雑な価値のあるニューラルネットワーク」。
  2. https://giggleliu.github.io/2018/02/01/complex_bp.html

ほとんどの場合、実数値関数の導関数(損失)のみを計算するため、通常、autogradを変更する必要はありません。

作業計画

今日、必要な部品の多くが用意されていますが、それらはエンドツーエンドの方法でまとめられていません。 これが何をする必要があるかです。

  • [X] Codemod TH to not ifdef real https://github.com/pytorch/pytorch/pull/11163
  • [X]torch.complex64およびtorch.complex128dtypesの組み込みサポート。 https://github.com/pytorch/pytorch/pull/11173
  • [X] CPUComplexTypeなどを登録するためのインターフェース。この実装は、dtype = torch.complex64で複雑なテンソルを要求したとき、または複雑なテンソルで操作を行ったときに呼び出されます。
  • [X]土地https://github.com/pytorch/pytorch/pull/11013
  • [X] libtorchに対してリンクし、前述のインターフェースを使用して複雑なテンソル割り当てを実装する、個別にコンパイル可能なC ++プログラムの、作業ビルドシステムを含むエンドツーエンドの例。

短期統合計画。 これらの操作は実装が「簡単」であるため、できるだけ早くPyTorchでメインライン化する必要があります。

  • [X]基本的なテンソルファクトリ:torch.empty、torch.zeros、torch.ones
  • [] CPU二項演算:add、sub、mul、div#11641
  • [] FFT
  • [] ???

カーネルの実装:

TODO: https://github.com/Roger-luo/TH/blob/master/ChangeLog.mdに基づいてリストを生成します

その他の複雑な関連タスク:

  • []複雑なテンソルの型昇格規則を理解し、promoteTypes#11641に実装します

歴史的な問題の内容

@PhilippPelzからの元のコメント

複雑なテンソルをpytorchに組み込むことに関心があるかどうか疑問に思いました。
CPUサポートにはztorchがあり、私は少し前にz-cutorch(https://github.com/PhilippPelz/z-cutorch)を作成しました。 これは、CudaHalfTensorのリファクタリング前の分岐点です(ハードウェアはまだありません)。
あまり手間がかからない場合は、ゆっくりとpytorchと統合したいと思います。 私はfb.ptyhonを介してプロットするためにmatplotlibを使用していますが、システムを再インストールする(すべての依存関係をコンパイルする)たびに大きな苦痛があります。さらに、実験用PCの1つであるWindowsでもpytorchがすぐに機能するようです。
複雑なグラデーションも必要になるので、遅かれ早かれautogradにも触れます。
tfはそれ自体が複雑なテンソルをサポートしていますが、多くのopsはまだサポートしていないようです(https://github.com/tensorflow/tensorflow/issues/2255)。さらに、私の目的では少し重いようです。

歓迎すべきアイデアであれば、誰かがこれをどこからどのように始めるかについて、いくつかの言葉を言うことができるかもしれません。

feature complex triaged

最も参考になるコメント

@ sunilkpai@ boeddeker@ Randl

複雑なデリバティブに関するレポートをありがとう。 私はそれに従おうとします、そして私は来週これに戻ります。 ここにいくつかのリンクを追加して、プロジェクトのステータスを説明しようと思いました。

複素数のステータスは非公式にサポートされており、PyTorchExtensionを介して追加する必要があります。

各拡張機能には2つのものが含まれています。

  • 必要な数学カーネル登録を含む.cpp
  • pytorchテストスクリプトの非常に単純化されたバージョンを含むtest/フォルダー。
    テストスクリプトを調べて、サポートされているカーネル(および他のカーネルがサポートされていない理由)を確認します。

複雑なテンソルをコンソールに印刷できないのはなぜですか?

  • Tensor pythonオブジェクトには、サポートされていないいくつかの関数を呼び出すきれいな印刷フォーマットがあります。

    • tensor.pyの内容を変更して、印刷フォーマットをバイパスできます。

    • または、PytorchテンソルをNumpy配列に変換してから印刷することもできます。

現在のプロジェクトステータス:

  • CPUカバレッジはかなり良いです。

    • カーネルは、PyTorch内の'aten / src / ATen / native / cpu / </li> <li>Complex number specific code is under 'aten/src/ATen/native/cpu/zmath.hの下に実装されています。

    • IntelAVX256アクセラレーションは'aten/ src / ATen / cpu /vec256/`の下にあります



      • @sunilkpai :expの最適化を知りませんでした。 これは、それを追加するフォルダーです。


      • 変更に問題がないかどうかお知らせください。



  • GPUのカバレッジは、バイナリおよび単項演算に制限されています。

    • カーネルは、PyTorch内の'aten / src / ATen / native / cuda / * </li> <li>Complex number specific code is under 'aten/src/ATen/native/cuda/zmath.cuhの下に実装されています。

    • thrust::complex<T>データ型が使用され、最適化されたカーネルが含まれます。

現在の開発:

  • CベースのTHカーネルがC++ATenフォルダーに移植されるのを待っています。

    • テストケースをpytorchの内部テストに移植するには、rand()関数が必要です。

    • 一部のインデックス作成操作は現在移植されていません。

    • 現在、THからATenに移植する必要のある168/1300の数学カーネル(10月の230から減少)があります。

  • これらのカーネルがATenで利用可能になったら、複素数のサポートを追加しようと思います。

-

全てのコメント128件

複雑なテンソルのオプションのサポートを追加することに興味があると思います。 最良の方法は、 torch/libのCライブラリをフォークして作業することです。 これはマスターとの競合がないはずなので、これを長期間行うことができます。 libsを使用可能な状態にしたら、バインディングの作成を開始できます。ここで、その時点での競合を回避する方法についてのガイダンスを提供できます。

複雑な型をコンパイルするTHがあります。 Python統合のために何を追加する必要がありますか?

@PhilippPelzは次のような意味ですか: https ://github.com/facebook/ztorch/tree/master/lib/THZ? または、複雑なタイプを可能にする独自のTHフォークを作成しましたか?

@killeentは、THがPythonにどのようにバインドされているかについていくつかのメモを持っています、彼はそれらを共有することができます。

一般に、複雑なテンソルを取り込むには、テストなどがあるTHZを使用します。

複雑なTensors用のCUDAバックエンドを構築することは、かなり大きな努力ですが、私たちはそれを始めていません。

少し前にz-cutorch(https://github.com/PhilippPelz/z-cutorch)を書きました。 これは、CudaHalfTensorのリファクタリング前の分岐点です(ハードウェアはまだありません)。

これは素晴らしい。 私はあなたがすでにその方向に大きな努力を押したと思います:)

@soumith私は複雑なタイプでTHのフォークをしました。 基本的に、THGenerateComplexTypes.h+追加されたBLAS+ LAPACKルーチンは、残りはほとんど無料でした。 THZのどの部分に互換性があるかを確認してからコピーして貼り付けるよりも、作業がはるかに少ないように思えました。

私は今THPPをコンパイルするのに行き詰まっていて、次のようなコンパイラメッセージを理解しています

/home/philipp/projects/pytorch/torch/lib/tmp_install/include/TH/generic/THBlas.h:6:40:エラー:「*」トークンの前に「、」または「...」が必要です
TH_API void THBlas_(swap)(long n、real *、long incx、real *、long incy);

少し注意が必要です。

Python統合を有効にする方法についてのヘルプをいただければ幸いです。 CUDAバックエンドは、ほとんどがz-cutorchからのコピーペーストである必要があります。

@PhilippPelzは、PyTorchがTHをラップすることに関するいくつかのメモです: https ://gist.github.com/killeent/4675635b40b61a45cac2f95a285ce3c0

@killeentありがとう、とても役に立ちそうです。 lib / build_all.shは現在コンパイル中です、私はcsrcディレクトリを見ることができると思います。

これが実行されます:

トーチをthとしてインポート
numpyをnpとしてインポートします

a = np.array([1 + 1j、2 + 2j])
b = np.array([3 + 3j、4 + 4j])
ath = th.from_numpy(a)
bth = th.from_numpy(b)
ath_cuda = ath.cuda()
ath_cuda + = bth.cuda()
ath = ath_cuda.cpu()
print(ath.numpy())

アウト:[4. + 4.j 6. + 6.j]

ほとんどの数学関数と一緒に。
今後数週間で便利な関数とfftsを追加します。 これをマージする前に、すべてをテストする必要があると思います。 複雑なテンソルに興味があり、テストの作成に貢献してくれる人を知っているなら、それは素晴らしいことです。 この論文は頭に浮かびます: Deep Complex Networks 、多分それらの人は興味があるでしょう。
すべてのテストを自分で書く時間はありません。

@PhilippPelzコメントありがとうございます。 私はあなたの実装をチェックしています。 そして最初に、私はあなたのgerの実装についてよくわかりません。 生成ヘッダーでGERをzger_およびcger_として定義したように、一部の複雑なblas関数はTHBlas.cに含まれていませんが、generic/THBlas.cにcger_を含むblas関数はありません。 。 しかし、私はあなたのgemvと他のいくつかの機能を使うことができます。 そしてIMOは多分あなたは.gitignoreに.gchを追加するべきですか? すべての拡張機能をフォークにプッシュしましたか? 最初に、実装に基づいてマスターにプルリクエストを行うことができます。

そして、 DOTの場合、おそらく複雑なベクトルの場合、ドットのdotcルーチンがより一般的ですか?

はい、 realを使用するだけで実装が簡単になるとしたら、 realが実際には複雑なのに、私は奇妙に感じていました...

そして、テストについては、THの以前のテストは見られませんでした。 それらのテストはどこに書くべきですか? または、Pythonテストを作成するだけです

はい、申し訳ありませんが、必要なものがすべてプッシュされていない可能性があります。 月曜日にまたチェックします。 いくつかの宣言が欠落しています。 zgerとcger

私がcdotcとzdotcを使用しているDOTの場合、それらが欠落しているようです。来週更新します。

pytorchのメンテナに、実際にどのような名前を付けるかを確認してください。 私はあなたのバージョンがもっと好きです、ただまだ努力をしていませんでした。

はい、Pythonは数学をテストします。 ほとんどの関数で簡単に変更して、強制番号チェックも含める必要があります。

あなたもこれを調べているのはクールです!

わかりました、私はいくつかの変更をプッシュしました。 THblasルーチンは今や複雑なもののためにあります

@PhilippPelzリポジトリにプルリクエストを送信しました。 また、複雑な線形レイヤーやその他の演算子の場合。 多くのエルミート演算(複雑な線形層のbpなど)が存在する可能性があります。 多分テンソルのためのいくつかの関数を追加しますか? THNNの部分をチェックしましたか?

はい、エルミートは便利です。 cudafftは現在機能しています。 cpufftはnumpyからラップできます。 THNNやTHCUNNにはまだ触れていません。

@PhilippPelzPRに簡単なエルミートを追加しました。 そして、あなたはそれをレビューできますか? したがって、これらの変更が適切かどうかを確認し、次のステップに進むことができます。 ありがとう! PS。 いくつかのヘッダーを見逃したようですが、それと他のいくつかの警告も修正します。 実際の出力を持つ複雑な関数の場合、複雑なテンソルではなく実際のテンソルを返す必要がありますか? 複雑なタイプと実際のタイプの間にコピーメソッドを実装したので、それは可能です。

レビュー後にすべてのコミットをリベースします。

@PhilippPelzこんにちは、私はあなたが実装したTHPPの部分についてかなり混乱しています。 なぜTraits.hppの推力に依存しているのですか? これにより、cudaなしでコンパイルするとエラーが発生します。 のようにしか使用できませんかまたTraits.hpp ? 私はそれを理解していません。 多分あなたはいくつかの手がかりを提供することができますか?

@ Roger-luoはい、他の場所でも問題が発生しています。 使用している複合型は、complex.hまたはstd::complexのいずれかである必要があります。 THPPはC++ラッパーであるため、おそらくstd::complexの方が適切です。 変えて頂けますか?

推力はまた、cffi拡張機能を構築しようとするときにまったく同じ理由で問題を引き起こしています。 現在、回避策を実行していますが、適切な方法は、THCで複合型をcuFloatComplex/cuDoubleComplexに変更することです。 cffiコンパイラが文句を言わないようにします。 今すぐ研究を続けたいのですが、時間がかかりすぎています:(。時間があればやってください。

また、カスタムカーネル呼び出しを使用してcffi拡張機能を構築するのは非常に面倒です。これは、常にnvccでコンパイルされた追加のライブラリを作成し、それをcffiラッパーにリンクする必要があるためです。 他に方法はないと思います。 cffiをABIモードで使用することもできますが、Webサイトには、「APIモードは、代わりに、ターゲット関数を直接呼び出すCPython Cラッパーをコンパイルします。比較的高速です(libffiよりも優れた動作をします)。」

@PhilippPelz多分reinterpret_castが解決策になるでしょうか? cuComplexに変更し、THPPでreinterpret_castを使用する必要があると思います。 最初に試してみます...

はい、cudaをインストールせずにTHPPをビルドしたい場合は、reinterpret_cast以外の方法はないと思います。

@PhilippPelzお手伝いしたいです。 どこかにやることリストはありますか?

THNNとTHCUNNは、複合型に対して有効にする必要があります。 @ roger-luoとコーディネートできますか? また、マスターとの統合を目指す場合は、すべての複雑なメソッドに対して単体テストを作成する必要があります。

@elbamos THNNでの作業のほとんどは、既存のレイヤーごとに新しい複雑な逆伝播メソッドを実装することです。 フィリップのフォークにはWIPPRがあります。 私はいくつかの参考文献をリストしました。

@apaszke @soumith @PhilippPelzそして2つの質問があります:

  • THSに別のGenerateXXXTypes.hファイルがある理由を誰かが知っていますか? THのものと同じように見えます。

  • byte_order.cppの次のコードは何ですか?

void THP_decodeFloatBuffer(float* dst, const uint8_t* src, THPByteOrder order, size_t len)
{
  for (size_t i = 0; i < len; i++) {
    union { uint32_t x; float f; };
    x = (order == THP_BIG_ENDIAN ? decodeUInt32BE(src) : decodeUInt32LE(src));
    dst[i] = f;
    src += sizeof(float);
  }
}

void THP_decodeDoubleBuffer(double* dst, const uint8_t* src, THPByteOrder order, size_t len)
{
  for (size_t i = 0; i < len; i++) {
    union { uint64_t x; double d; };
    x = (order == THP_BIG_ENDIAN ? decodeUInt64BE(src) : decodeUInt64LE(src));
    dst[i] = d;
    src += sizeof(double);
  }
}

関連する複雑なバージョンの実装に関する提案はありますか? 次の実装が正しいかどうかはわかりません...

void THP_decodeZFloatBuffer(std::complex<float>* dst, const uint8_t* src, THPByteOrder order, size_t len)
{
  for (size_t i = 0; i < len; i++) {
    union { uint64_t x; std::complex<float> cf;};
    x = (order == THP_BIG_ENDIAN ? decodeUInt64BE(src) : decodeUInt64LE(src));
    dst[i] = cf;
    src += sizeof(std::complex<float>);
  }
}

void THP_decodeDoubleBuffer(std::complex<double>* dst, const uint8_t* src, THPByteOrder order, size_t len)
{
  for (size_t i = 0; i < len; i++) {
    union { uint128_t x; std::complex<double> df;};
    x = (order == THP_BIG_ENDIAN ? decodeUInt128BE(src) : decodeUInt128LE(src));
    dst[i] = df;
    src += sizeof(std::complex<double>);
  }
}

以前のdecodeUInt128XEは次のように宣言されています

static inline uint128_t decodeUInt128LE(const uint8_t *data) {
  return (((uint128_t)data[ 0])<<  0) | (((uint128_t)data[ 1])<<  8)|
         (((uint128_t)data[ 2])<< 16) | (((uint128_t)data[ 3])<< 24)|
         (((uint128_t)data[ 4])<< 32) | (((uint128_t)data[ 5])<< 40)|
         (((uint128_t)data[ 6])<< 48) | (((uint128_t)data[ 7])<< 56)|
         (((uint128_t)data[ 8])<< 64) | (((uint128_t)data[ 9])<< 72)|
         (((uint128_t)data[10])<< 80) | (((uint128_t)data[11])<< 88)|
         (((uint128_t)data[12])<< 96) | (((uint128_t)data[13])<<104)|
         (((uint128_t)data[14])<<112) | (((uint128_t)data[15])<<120);
}

static inline uint128_t decodeUInt128BE(const uint8_t *data) {
  return (((uint128_t)data[15])<<  0) | (((uint128_t)data[14])<<  8)|
         (((uint128_t)data[13])<< 16) | (((uint128_t)data[12])<< 24)|
         (((uint128_t)data[11])<< 32) | (((uint128_t)data[10])<< 40)|
         (((uint128_t)data[ 9])<< 48) | (((uint128_t)data[ 8])<< 56)|
         (((uint128_t)data[ 7])<< 64) | (((uint128_t)data[ 6])<< 72)|
         (((uint128_t)data[ 5])<< 80) | (((uint128_t)data[ 4])<< 88)|
         (((uint128_t)data[ 3])<< 96) | (((uint128_t)data[ 2])<<104)|
         (((uint128_t)data[ 1])<<112) | (((uint128_t)data[ 0])<<120);
}

現在、 THPPT _Complex std::complex<T>を使用しています。 これがPythonで使用できるかどうかはまだわかりません。 または、cタイプT _ComplexのみがPythonに使用できます。 したがって、ここでのdstのタイプはstd::complex<T>です。

そして、私がこの実装に正しければ、おそらくhttps://github.com/calccrypto/uint128_tのようなuint128_tの実装が必要ですか? すべてのコンパイラが128ビット整数をサポートしているわけではないようです(gccにはint128_tとuint128_tがあります)。

@PhilippPelzフォークで問題が有効になっていないことに気づきました-プロジェクトのステータスはどうですか? 複雑なテンソルがpytorchのロードマップに含まれていないことに少し不満があります

@ el3ment CPU用の複雑なバックエンドを追加しましたhttps://github.com/pytorch/pytorch/pull/4899しかし、まだレビューされていません...そしてPRに対するコメントを受け取っていないので、使用するようになりました最近のJuliaプログラミング言語...

前回@PhilippPelzにメールを送りましたが、彼のリポジトリはまだv0.1未満であり、9月まで論文で忙しいと思いますか? そして、私はv0.3の新しいCUDAバックエンドに取り組んでいましたが、これらすべてのバインディングを単独で完了する時間はありません。 map / reduce関数は、いくつかの最適化を備えたv0.1とは異なりますが、複素数をサポートするように簡単に変換することはできません。 喜んで手伝ってくれる人がいれば嬉しいです...

喜んでお手伝いさせていただきます。

2018年4月10日午後10時52分、 Rogerluonotifications @github.comは次のように書いています。

@ el3ment CPU#4899用の複雑なバックエンドを追加しました

前回@PhilippPelzにメールを送りましたが、彼のリポジトリはまだv0.1未満であり、9月まで論文で忙しいと思いますか? そして、私はv0.3の新しいCUDAバックエンドに取り組んでいましたが、これらすべてのバインディングを単独で完了する時間はありません。 map / reduce関数は、いくつかの最適化を備えたv0.1とは異なりますが、複素数をサポートするように簡単に変換することはできません。 喜んで手伝ってくれる人がいれば嬉しいです...


あなたが言及されたので、あなたはこれを受け取っています。
このメールに直接返信するか、GitHubで表示するか、スレッドをミュートしてください。

@elbamosかっこいい、pytorchチームは分離された実装を好むようです。 後で他の部分のためにフォークを後で更新します。 しかし、私は実際にこれに取り組む時間がありません。これはpytorchの大きな拡張になるため、pytorchチームからの計画があるときに作業を開始する必要があると思います。

こんにちは、私のコードはv0.2以降のコミットにあります

すべてのテンソルコードをAtenに移動するかなり大きなリファクタリングがあることを私は見ました。 これは、私のフォークを現在のバージョンに簡単にマージすることができず、さらにいくつかの作業が必要になる可能性があることを意味します。

私はまだ博士号を書いていますが、VariableとTensorのマージがリリースされるまでとにかく0.4を待つことを計画していました。 リファクタリングが多すぎて追いつかないのではないかと心配しています。

@elbamos必要に応じて、フォークに何かを追加し始めることができます。それをマージします。代わりに、実行しているプロジェクトに必要なものを実装します。 TH(CU)NNはかなり大きなインターフェースであり、大きなワークロードになります。

@el3ment他の人の問題に取り組む時間がありません。 ただし、そこにないものを実装する必要がある場合は、それらをマージします。

箱から出して複素数で動作するものが必要な場合は、テンソルフローを強くお勧めします。

コンパイルの問題がある場合にもお手伝いします。

ポスドクを続けると、いつかこれらすべてのものを現在のバージョンに移植します。 Facebookがこれをサポートしたくないのは本当に悲しいことです。 :((

@PhilippPelz同意しました、それは本当に悲しいことであり、実際にはテンソルフローは量子物理学のすべての演算子をサポートしていません...私はジュリアを使い始めてPythonを放棄しました。

@ Roger-luo興味深いですが、特定のjuliaパッケージを使用していますか、それともすべて自作のコードですか?

@PhilippPelz私はジュリアで量子多体ツールキットを開発しています(PyTorch PR以降)。これには、複雑なニューラルネットワークに関する以前の論文に基づいた複雑な/実際のニューラルネットワークの実装が含まれています。メタプログラミング。 私は現在それをQMTK.jlに入れました、それはまだ進行中であり、私は私が望むすべてを終えていません。 PyTorchは確かに私に多くのインスピレーションを与えてくれますが、複雑なサポートには本当に申し訳ありません...

しかし、将来的にはニューラルネットワークの単一パッケージに分離する計画があります(現時点で複数のリポジトリを維持したくないだけです)。 そして、CASの物理学研究所からより多くの人々が開発に参加するでしょう。 最初のタグ付きバージョン(数週間以内)の後にPRを受け入れます。

あなたがその開発に興味があるなら、あなたはそれを見ることができます。

PyTorchチームが今後も複雑なサポートを計画している場合は、喜んでお手伝いします。

かっこいい、見守っていきます!

こんにちは、この問題が発生してから回答がないことをお詫び申し上げます。

ここに2つの事実があります:

  1. PyTorchには複雑なサポートが必要であることに完全に同意します。
  2. すべての複雑な操作に必要なロングテールを適切に埋める人材がありません。 (これの証拠については、マスターにあり、足を引きずっているスパースサポートを見てください。)

この問題は2017年に公開されて以来、複雑なサポートの実装を少し簡単にする可能性のあるいくつかの重要な点が変更されました。 1つ目は、テンソルを操作するための人間工学に基づいたC++ライブラリであるATenが用意されたことです。 これは、TH / THCコードの巨大なスワスをコピーし貼り付ける必要がなく、すべての手動参照が正しく行われていることを願っています。PythonのようにC ++コードを記述でき、高速に実行されます。 2つ目は、C10と呼ばれる新しいバージョンのATenに取り組んでいることです。これは、ATen(閉じたもの)よりもオープンバックエンドの方がはるかに真剣であり、複雑なサポートでの作業が容易になるはずです。コードの新しいディレクトリを追加するだけで、実際にPyTorchをフォークする必要があります。

ですから、@ Roger-luoと@PhilippPelzは、複雑なバックエンドを実現するためにあなたの助けを借りたいと思っていますが、それを将来にわたって持続的に維持するのに役立つ方法を見つけたいと思っています。 ご意見をお聞かせください。

@ezyangマンパワーが足りない場合は、将来的に複雑なテンソル部分を維持することができます。博士号を取得したばかりです(実際にはギャップイヤーです)。したがって、論文を書くのに問題はありません。少なくとも近年。 しかし、pytorchチームからのフィードバックがなければ、私は本当に貢献し続けることはできません。 この大きな拡張のロードマップがあるべきだと思います。 また、複雑なサポートをスムーズに追加できるため、大規模なPRを確認する必要がなく、マスターブランチの追跡に関する開発者の作業が容易になります。

まず、複雑なサポートの主な問題はCUDAの部分だと思います。 ATenやその他のライブラリでCPUパーツをサポートするのは非常に簡単です。フィードバックがあれば、わずか数日でCPUパーツを書き直すことができます。 CUDAの部分に関して私が懸念するかもしれないいくつかの問題があり、これは2つの異なるアプローチにつながる可能性があると思います。

  1. float2などを使用して、CUDA部分でcuComplexのように単一の複素数値をシミュレートします。
  2. 既存のFloatTensorDoubleTensorを使用して、ATenのC++部分の複雑なテンソルをシミュレートします。

2番目のアプローチの理由は、 THCでは、pytorchがいくつかのトリックを使用してmap / reduce操作を高速化し、 cuComplexが実際にはfloat2であるため、 cuComplexには自明ではないためです。 float2ですが、 __shfl_xxx関数はfloat2をネイティブにサポートしていません。 現時点では、このような関数をfloat2で効率的にシミュレートする方法がわかりません。

2番目のアプローチは、ハードウェアを気にする必要がないため、より簡単になります。また、古いデバイスでの新しい複雑な拡張機能の動作をはるかに簡単にすることができます。 ただし、これにより、メモリアドレスが連続していないためにオーバーヘッドが発生する可能性があります。

さらに、複素数をATenに統合するには、ハードウェアで実際に同じである4つの異なるタイプを処理する必要がある場合があることがわかりました: std::complexthrust::complexcuComplexfloat2これは時々危険かもしれません。 (実際、私は昨年この問題に遭遇し、 reinterpreter_castが解決策でした)。

個人的には、すべてをもっとネイティブに書きたいと思っています。

そして、おそらくタイムフレームまたはロードマップが必要だと思います。それぞれの小さな部分をピックアップして一緒に作業できるので、マスターを自分で追跡する必要はありません。これは完全に不可能です...

CPUバックエンドを実装しようとしたときにChangeLogがありましたが、ログ内の複素数に対して関数を変更する必要があると分類しました。 このログに基づいてロードマップを作成できます。

その上、私のビザが(オーストラリアによって)拒否されたばかりなので、ギャップイヤーを開始する必要があります。誰かがこれに取り組み続ける必要がある場合は、インターンシップに申し込むことができます。

昨日はこれについてよく考えました。 ロジャーの努力をそのまま統合できなかったのは少し悲しいですが、私は自分自身に思いました

「メンテナンスのオーバーヘッドを低く抑えながら、複雑なTensorサポートを構築するにはどうすればよいでしょうか?」

これは、上記の目標から効果的な計画として私が提示しているものです。

  • 複雑なテンソルは、 sparseテンソルのような基本的な新しいテンソルタイプであってはなりません。 基本タイプを追加すると、多くのメンテナンスオーバーヘッドと分野横断的な変更が発生します。 メンテナンスのオーバーヘッドは「誰が複雑なビットを維持するか」ではなく、「基本的な変更やATenの変更などを行うときに、すべてのコア開発者がこの複雑なタイプを認識している必要があります」。

    • 代わりに、それらは常に[Tensor Shapex2]または[2xTensorShape]である必要があります。つまり、Tensorにはサイズ2の1つの追加の次元が必要です。

  • Complex Tensorsは、ATenTensorAPIの上に構築された単純なC++の約2,000行の小さなファイル/フォルダーである必要があります。

    • たとえば、 https://github.com/pytorch/pytorch/issues/6514が示唆しているように、複素数の乗算はtorch.stack([real1 * real2 - imag1 * imag2, real1 * imag2 + imag1 * real2], dim = -1)として実装する必要があります。ここでreal1 = input1[:, :, :, ..., 0]

    • これはパフォーマンスを低下させます。はい、すべてをインライン化する場合ほどパフォーマンスは得られません。 しかし、問題は「いくらですか?」です。 健全でフル機能の+維持された複雑なサポートと引き換えに、パフォーマンスを20%低くすることを目指すべきだと思います。

    • 最もよく使用される複雑な関数は専用のカーネルを取得し始める可能性があるため、頻繁に使用される関数でパフォーマンスが20%を超えるヒットを記録している場合は、介入します。

BLAS、cublas、およびMAGMAはすべて、float2とバイト互換性のある独自の複合型を想定しているため、[Tensor Shapex2]である必要があります。 また、blas、cublas、magmaの呼び出しは、Pythonレベルでは処理できません。
複素数の乗算では20%になるとは思いませんが、実数部と画像部の計算に加えて、4つのフルコピー操作がありませんか?
とにかく、マスターからの変更を継続的にマージする必要がなければ、私はまだ幸せです。

@PhilippPelzに同意します。BLAS 、cublas、MAGMAからの複雑なサポートが失われるため、パフォーマンスが大幅に低下する可能性があります。 しかし、それについてはよくわかりません。 ただし、明確にするために、複雑なテンソルはスパーステンソルとは完全に異なりますscipy.sparse SparseArraysようなほとんどのライブラリは、スパース配列を基本的な多次元配列の合成として扱います。 しかし、2つの実数配列を合成することで複雑な型の多次元配列を扱う人は誰もいません...(ここでは、テンソルフロー、arrayfire、numpy、Juliaを意味する人は誰もいません)。 MXNetでは、FFTは実際に2つの実際のテンソルの合成によって実現されますが、複雑なものはサポートしていません...テンソルフローはcomplex64complex128を含む異なるネットタイプのラッパーとしてDataTypeを実装したようですtypes.protoを参照

性能低下について

まず、要素ごとの関数(関数はmap / reduceを呼び出します)のパフォーマンスが大幅に低下することはありません(少なくとも、これらの操作のメモリは連続しています)。 ただし、最初にいくつかのBLAS関数のベンチマークを試して、 FloatTensorの構成がGPUのComplex64Tensorと同様のパフォーマンスを発揮するかどうか、およびドラフト実装、次のように:

  • gemm
  • gemv

合成された複雑なテンソルは次のようになります(または単にshared_ptrを使用します):

class ComplexTensor {
    FloatTensor *real;
    FloatTensor *imag;
};

ただし、最初のアプローチの欠点で述べたように、これをよりネイティブに実行したい場合、 __shfl_xxxのような関数も障害のように見えます。

現在、 torch.fftは、形状[dim1, ..., dimN, 2]の単一のfloatテンソルを返します。

@ezyang C10リリースの時間枠は何ですか? これは、マスターブランチでcomplexのサポートを開始するための非常に合理的なポイントのように思えます。

@PhilippPelz0.4では絶対にありません。 私たちは内部的に6月をターゲットにしています。それが長く待たないことを願っています。

@ezyangは6月に言及しましたが、PyTorchに複素数のサポートを追加することができましたか?

彼は複雑なサポートではなく、C10を意味していると思います。 C10を使用すると、複雑なものを簡単に追加できます。 それが私がそれを理解した方法です。

はい、C10はTensorのタイプと機能の両方をオープン登録します。 したがって、複雑なタイプを個別のパッケージとして追加する方がはるかに簡単です。

複素数に関するETAはありますか? 「はるかに簡単」とは「おそらく迅速に行われる」という意味ですか?

@themightyoarfishの方がはるかに簡単です。つまり、pytorchマスターにプッシュできるものがブロックされないということです。 ETAは設定していません。 PyTorchへのオープン登録ができたら、作業の範囲を限定します。

@soumithまだこれに取り組む人が必要ですか(複素数)? PyTorchチームは複素数をサポートしますか? QuCumberを保守するので、9月に必要に応じて、これにいつか取り組むことができます(複素数を多用します)

@Roger-luoはい。 PyTorchバックエンドでオープン登録が利用可能になったら連絡したいと思います。詳細を確認できます。
@ezyangは9月までにオープンタイプ登録をしますか?

@soumithクール、あなたのサービスで。

私たちはそれを実現することができます。 (「完全な」新しいシステムは導入されませんが、リファクタリング可能なように設定されている限り、新しい開発が行われるたびにシステムを動かし続けることができます。これは、新しいオープンの良いテストケースになります。登録。これが確実に行われるようにすることができます。)

@ezyang今までに何かメモはありますか? 私はそれに取り組む前にそれを読むことができました。 前回から大きく変わったようです。

@Roger-luo@ PhilippPelz複雑なテンソルの実装についてもお手伝いしたいと思います。 博士号の調査にも必要です。

@alexgomezalanisたぶん、たるみについて話し合うためのチャネルを持つことができます。私は#complex-numbersというチャネル呼び出しを作成しました。 しかし、私は9月までそれに取り組み始めません(それでも私のJuliaコードのいくつかに取り組む必要があります...)

ところで、前回から大きく変わったようです。 手に入れる前に、少し時間をかけて追いつきます。

@alexgomezalanisできません。 最初にslackでpytorchのワークスペースに参加する必要があります。 私はあなたを見つけられません。 招待状を受け取るには、アドレス[email protected]にメールを送信してください。

@Roger-luo@ alexgomezalanis複雑なテンソルの問題で再び人生を見るのは素晴らしいことです。 私も参加を申し出ることができますが、現実的にはこれは9月の終わり/10月の初めまで起こりません。 この問題に関するかなりの数のコメント者に関しては、複雑なテンソルサポートが私の博士号プロジェクトに非常に役立ちます。

昨年も研究を保存しようとしていました😏…しかし今は、古い1w+locコードを復活させたいと思っています。 🤣S​​lackでチャットしましょう!

:)ええ、たるみについてチャットしましょう。 メールフォルダで招待状を見つけました。

進行中のプラグイン(短期間のCPUのみ)はここにあります: https ://github.com/Roger-luo/pytorch-complex

問題とPRをお気軽にお願いします。

この号の冒頭に、どのように複雑な実装が実行されるかについてのメモを投稿しました。

私は最近PyTorchを使い始めましたが、絶対に気に入っています。TensorFlowよりもずっと使いやすいです。 ただし、複雑なテンソルのサポートは、私の研究(光ニューラルネットワーク)にとって非常に重要です。 これはまだ積極的に取り組んでいますか? もしそうなら、誰かが複雑なテンソルサポートの(緩い)時間枠を知っていますか?

できる限りこれに取り組むのを手伝いたいのですが、私はPyTorchに比較的慣れていないので、この機能の取り組みの大きさについてはまだよくわかりません。 私のラボメイトの何人かは、複雑なテンソルサポート(物理学では、これを追加すると、TorchがNumPyのほぼドロップインGPUで高速化された代替品になる可能性があります)にも強い関心を示しており、近い将来。

こんにちは@bencbartlett

私はまだゆっくりと取り組んでいます....しかし、私は現在、学生でもあります(非常に不安定な状況です)。つまり、このフルタイムで作業することはできず、空き時間でしか作業できません。 (私は昨年からJuliaで研究関連のコードを実装しています。つまり、トーチからのより優れた複素数サポートが必要なのはレガシーパッケージだけです。)

複素数が重要であり、トーチを使用することが急務である場合は、これを試してみることをお勧めします。

https://github.com/PIQuIL/QuCumber/blob/master/qucumber/utils/cplx.py

それは超遅いです...しかし、それは少なくとも動作します。 または、古いTHスタイルのCバージョンがありました。

これは、数日で実行できる小さなプロジェクトではありません。 したがって、CPUまたはCUDAで複雑な値を持つ完全な機能サポートの特定の時間枠を保証することはできません。

しかし、私はあなたがこれについて一緒に私と一緒に働くのを手伝いたいです。 拡張リポジトリに投稿した問題を解決することから始めることをお勧めします。 また、ご不明な点がございましたら、Slackまたはメールまたは問題でお気軽にお問い合わせください(まだドキュメントが少ないため)。

残念ながら、まだPyTorchSlackにアクセスできません。 (招待状を求めるメールを2回送信しましたが、返信がありません。)誰かが私を招待してくれませんか。 ([email protected]

@ Roger-luo間違いなくあなたのフォークを調べますが、私が大いに役立つとは約束できません-私のC ++は錆びており、あなたが指摘したように、これに取り組む時間を見つけるのは難しいです学生。 QuCumberユーティリティは素晴らしいですが、残念ながら私にとってはそれほど役に立ちません。複雑なテンソルがGPUでサポートされるか、autogradとtorch.nnでサポートされるまで、NumPyが提供できる以上のユーティリティは提供されません。

@soumith @ezyang PyTorchチームからこれにもっと注目を集めるのは素晴らしいことです! 複雑なサポートは、一般的なテンソルライブラリにとって重要な機能のように見えます。これは物理学では事実上不可欠であり、特に過去数年間のML内では、複雑な値のモデルへの関心が急速に高まっています。

@bencbartlett QuCumberのアプローチはADを備えたGPUで使用できます...それは非常に遅いです...つまり、そのADが必要な場合は、それを使用できる可能性があります。

ええ、率直に言って、私はhttps://github.com/FluxML/Flux.jlのわずかに変更されたバージョンと、研究のためにJuliaにある独自のパッケージを使用しています(状況によっては、テンソルを備えたGPU上の複雑なADが必要です) )。 source2source ADパッケージZygote.jlは、複雑なテンソルでADを実行できますが、非常に初期の段階であり、セグメント障害が発生している可能性があります。 生態系はまだトーチと比較してそれほど安定していません、私は時々それらの実装を自己使用のために少しハックしなければなりません...しかしそれは基本的に私が量子物理学の研究に必要なもののために働きます。 GPUでも複雑なテンソルを使用できます。

torch.nnの複素数値のサポートは必要ないと思います。複素テンソルが機能したら、 autogradの定義をいくつか追加する必要があるかもしれません。これは、線形層などが同じままであるためです。 。 そして、いくつかの活性化関数はヒルベルト空間で標準的な拡張を持っていないかもしれません...(あなたは私の協力者@GiggleLiuのブログ投稿をチェックすることができます)

pytorch-complex拡張機能の場合、GPU上のADでいつ完全なサポートを利用できるかわかりません...これはまだ私にはかなり遠いようです。 CPU実装は、メインツリーにパッチを必要とする期間(たとえば、タイププロモーション、simdサポートなど)を経ると思います。これは、C ++での今後のATen実装に関連し、THなどを取り除く可能性もあります。そうすれば、複雑なテンソルの演算子をより速く追加できるようになります。

春にインターンシップに応募できます( @ezyangに聞いたところです)。 ですから、博士号を取得する前に、このフルタイムで数か月間働くことができるかもしれません。 どれどれ。

その間に、私は自分のバージョンの虚数乗法を実装しました。 ただし、プロファイルを作成すると、次のようにかなりの時間がかかることがあります。torch._C _._ cuda_isDriverSufficient

image

理由はわかりますか? 虚数乗法のより良い実装を知っているなら、私に知らせてください。 どういうわけか、私のバージョン(乗算の数に最適化されていても:4ではなく3)は比較的遅いようです。たとえば、アウトテンソルのirfftは、要素ごとの乗算よりも10倍高速です。 虚数乗法はPyTorchのC++レベルでサポートされていますか?

def complex_mul(x, y, out):
    uavc = x[..., 0] * (y[..., 0] + y[..., 1])
    out[..., 0] = uavc - (x[..., 0] + x[..., 1]) * y[..., 1]
    out[..., 1] = (x[..., 1] - x[..., 0]) * y[..., 0] + uavc
def test_complex_mul_out_tensor(self):
        N, C, H, W, I = 128, 3, 32, 32, 2
        K = 16  # number of filter banks
        repetitions = 1000
        dtype = torch.float
        if torch.cuda.is_available():
            device = torch.device("cuda")
        else:
            device = torch.device("cpu")
        x = torch.randn(N, 1, C, H, W, I, dtype=dtype, device=device)
        y = torch.randn(K, C, H, W, I, dtype=dtype, device=device)
        start_mul_time = time.time()
        out = torch.empty(N, K, C, H, W, I, dtype=dtype, device=device)
        for _ in range(repetitions):
            complex_mul(x, y, out)
        print("multiplication time: ", time.time() - start_mul_time)

C++からサポートしようとしています。 上部の投稿を参照してください。 拡張機能をコンパイルできれば、少なくとも現時点ではスカラー乗法で機能するはずです。

あなたの実装は、QuCumberにあるものと似ています。 複素数の正しいcudaカーネルを呼び出さないと、余分なGPUスレッドが呼び出される可能性があります。 また、PythonでサポートされているC ++バックエンドがないと、SIMDが失われる可能性があります。

詳細を取得するには、 nvprofを実行することをお勧めします。

@ Roger-luo@ apaszke @ soumithこのスレッドをありがとう。 torch.Tensorのサブクラス化から一緒にハッキングされた基本的な複雑なテンソルを実装しました。

私は前半を実数、後半を虚数として扱い、独自の基本的な算術演算と、研究に必要なその他の演算を実装しました。

Tensorflowとnumpyに対して検証しました。 グラデーションと実装したすべての操作は、それらの出力と一致します。

これは、PTが複雑なテンソルを完全にサポートするまでのホールドオーバーとして意図されています。

特徴:

  1. 実装されたテスト。
  2. サポートされているPypi(つまり、pip install)
pip install pytorch-complex-tensor

https://github.com/williamFalcon/pytorch-complex-tensor

ありがとう@williamFalcon

これを更新しますか? 複雑なタイプのサポートをpytorchに統合する計画があるかどうか疑問に思っています。

こんにちは、 @ whmrtm

@ezyanghttps://github.com/Roger-luo/pytorch-complex/issues/4に取り組んでいます。または、これに興味のある人は誰でも私たちがそれを実行するのを手伝ってくれるでしょう。 この問題は、いくつかの基本的なブロードキャストの問題を解決します(この問題が解決された後、多くの機能を使用できます)。 遠慮なくPRを行うか、コラボレーターとしてあなたを追加するように私に依頼してください。

私は夏まで何にも取り組むことができません、私たち自身のパッケージのために新しいリリースを終えなければなりません。

こんにちは、@ whmrtm

@ezyangRoger-luo/pytorch-complex#4に取り組んでいます。または、これに興味のある人は誰でも私たちがそれを実行するのを手伝ってくれるでしょう。 この問題は、いくつかの基本的なブロードキャストの問題を解決します(この問題が解決された後、多くの機能を使用できます)。 遠慮なくPRを行うか、コラボレーターとしてあなたを追加するように私に依頼してください。

私は夏まで何にも取り組むことができません、私たち自身のパッケージのために新しいリリースを終えなければなりません。

アップデートしてくれてありがとう、私に何ができるか見ていきます。

こんにちは@Roger-luo

複雑なテンソルサポートトピック([email protected])に関連するSlackチャネルにアクセスできますか? 招待状をメールで送信しましたが、まだ何も起こりませんでした。 今、私はこの問題に貢献し始めるポイントを見つけようとしています。 https://github.com/Roger-luo/pytorch-complex/issues/4が現在のエントリポイントだと思いますか?

@beconstantはい、それが出発点です。これにより、ブロードキャスト機能が機能するはずですが、なぜcudaでタイププロモーションエラーがスローされるのかわかりません。CPUで機能していました。 (そもそもcudaをサポートするつもりはありませんが、これはビルドの失敗を引き起こします)

招待メールを送信できません(アクセスできません)。 slackに参加するには、pytorchの公式ガイドに従う必要があると思います。 しかし、私たちはいつでも問題/PRで話し合うことができます。

@ Roger-luoわかりました、わかりました:)

助けが必要な場合はお知らせください。 まず、指定されたpytorchバージョンを作成します。 pytorch-complex / issues / 4の進捗状況はありますか?

助けが必要な場合はお知らせください。 まず、指定されたpytorchバージョンを作成します。 pytorch-complex / issues / 4の進捗状況はありますか?

@dylanbespalkoこんにちは、Complex-valuedバージョンで実装されたpytorchが緊急に必要です。
貢献していただきありがとうございます。

よろしくお願いします、
Zellar209

こんにちは@Zellar209

@ezyangがより大きな問題の1つ( pytorch-complex / issues / 4 )に懸命に取り組んでいるように感じています。 現在AMDシステムと3週間でNvidiaシステムを使用しており、GPUサポートを強化するために使用できます。

問題は、元のタイプのプロモーションの変更がCUDAを壊すことにあると思います。そのPRが解決されている限り、少なくとも一部のオペレーターがCPUで動作し、CUDAはまだサポートされていません...

私見私たちはCPUに焦点を合わせ、最初に物事を機能させ、次にGPUを検討する必要があると思います。

CPUのみのサポートは問題ありません。 このタイプのプロモーションの問題( pytorch-complex / issues / 4はfbによって内部的に処理されていますか?外部で作業しても大丈夫ですか?

こんにちは@dylanbespalko; 私は@Roger-luoにそれを調べるつもりだと伝えましたが(おそらく問題が何であるかを理解するのに最適な場所だったので)、まだ調べる時間がありませんでした。 問題の解決方法を検討したい場合は、喜んでアドバイスさせていただきます。

こんにちは@Zellar209

@ezyangがより大きな問題の1つ( pytorch-complex / issues / 4 )に懸命に取り組んでいるように感じています。 現在AMDシステムと3週間でNvidiaシステムを使用しており、GPUサポートを強化するために使用できます。

はい、GPUは必要ありません。MACシステムを使用しています。 しかし、このプロジェクトを構築するときにいくつかのエラーが発生しました。

こんにちは@Zellar209 、pytorch-complexの問題で得たものを投稿できますか? Macの新しいXcodeに何か問題があり、ビルドが難しいと思います。 しかし、その理由を理解するには、さらにエラーメッセージが必要になります。

OSとエラーメッセージについて聞いたのですが、返事がありませんでした...

こんにちは@dylanbespalko; 私は@Roger-luoにそれを調べるつもりだと伝えましたが(おそらく問題が何であるかを理解するのに最適な場所だったので)、まだ調べる時間がありませんでした。 問題の解決方法を検討したい場合は、喜んでアドバイスさせていただきます。

お早めにご返信いただきありがとうございます。

1. gcc(デフォルト)を使用して「pythonsetup.py install」を実行すると、次のようなエラーが発生します。

'torch_complex.cpp'拡張機能の構築
gcc -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I / anaconda3 / include -arch x86_64 -I / anaconda3 / include -arch x86_64 -I / anaconda3 / lib / python3.6 / site-packages / torch / include -I / anaconda3 / lib / python3.6 / site-packages / torch / include / torch / csrc / api / include -I / anaconda3 / lib/python3。 6 / site-packages / torch / include / TH -I / anaconda3 / lib / python3.6 / site-packages / torch / include / THC -I / anaconda3 / include / python3.6m -c src / module.cpp -o build / temp.macosx-10.7-x86_64-3.6 / src / module.o -g -stdlib = libc ++ -std = c ++ 11 -DTORCH_API_INCLUDE_EXTENSION_H -DTORCH_EXTENSION_NAME = cpp
gcc:エラー:認識されないコマンドラインオプション'-stdlib = libc ++'

エラー:コマンド'gcc'が終了ステータス1で失敗しました

2. clangを使用してコンパイルすると、エラーは次のようになります。

src/moduleからインクルードされたファイル。 cpp:2
src / CPUComplexType.h:60からインクルードされたファイル:
src / CPUComplexTypeImpl.h:102:105:警告:「IntList」は非推奨です[-Wdeprecated-declarations]
Tensor&CPUComplexType :: set_(Tensor&self、ストレージソース、int64_t storage_offset、IntListサイズ、IntListストライド)const {
^
/anaconda3/lib/python3.6/site-packages/torch/include/c10/util/ArrayRef.h:273:7:注:「IntList」はここで非推奨として明示的にマークされています
IntListを使用C10_DEPRECATED_USING=ArrayRef;
^
src/moduleからインクルードされたファイル。 cpp:2
src / CPUComplexType.h:60からインクルードされたファイル:
src / CPUComplexTypeImpl.h:105:76:エラー:名前空間'at'に'scalarTypeToDataType'という名前のメンバーがありません
auto source_ =checked_storage(source、 "source"、2、DeviceType :: CPU、at ::scalarTypeToDataType(CPUComplexTypeInfo ::scalar_type));
~~~~ ^
7つの警告と2つのエラーが生成されました。

エラー:コマンド'clang'が終了ステータス1で失敗しました

直せません。 あなたが私を助けてくれることを本当に願っています!

やあみんな、

ご意見をいただきありがとうございます。 私はこれを調べて一週間を過ごすことができると思います。 これまでにコンパイルしたのは、@Roger-luoのpytorch-complexを次のようにコンパイルしたことです。

@ Zellar209 :macOS10.13で実行されている環境変数を添付しました。

  1. 次のように既存のpytorchディストリビューションを削除します
    condaアンインストールpytorch
    pipアンインストールトーチ
    pip Uninstall torch#このコマンドを2回実行します
    python setup.py clean
    pythonsite-packagesフォルダーにあるtorchフォルダーが存在する場合は削除します。
    以前のpytorchソースフォルダーの名前を変更(または削除)します(何かがそれを参照していました)。

  2. PyTorchリビジョン6cb593b88cb0c411690b4957850058329526d87bをインストールします。

    git clone [email protected]:pytorch/pytorch.git
    git checkout 6cb593b88cb0c411690b4957850058329526d87b
    git submodule update --init —recursive
    export CMAKE_PREFIX_PATH=${CONDA_PREFIX:-"$(dirname $(which conda))/../“}
    MACOSX_DEPLOYMENT_TARGET=10.13 CC=clang CXX=clang++ python setup.py develop
    python
>>> import torch
  1. pytorch-complexをインストールします
    python setup.py install
    python setup.py build
    python setup.py test
    # ERROR: test (unittest.loader._FailedTest)
    # ERROR: test_scalar_binary_op (tests.test_tensor.TestComplexTensor)
  1. 複雑なテンソルを作成する
   from torch_complex import torch
   a = torch.ones(3, dtype=torch.complex128)
   a*a  
   RuntimeError: promoteTypes with complex numbers is not handled yet; figure out what the correct rules should be

@ ezyang 、@ Roger-luo:

テンソル操作の型昇格のすべては、 c10 / core/ScalarType.hで行われているようです。
エラーAT_ERROR("promoteTypes with complex numbers is not handled yet; figure out what the correct rules should be”);を見つけました
このテーブル内にc8とc16のエントリを追加する必要があるようです。
これは9515と関係がありますか? これは、numpy関数を呼び出すためだけのものだと思います。
それは始めるのに良い場所ですか?

9515は無関係です。 ただし、ScalarType.hでこのコードパスを修正することから始めるのがよいでしょう。

ScalarType.hのコードパスを修正しました
BinaryOps(add、sub、mul、div)は機能しますが、両方の引数がテンソルである場合に限ります。
他のいくつかの奇妙な問題ですが、私はそれをもう少し見る必要があります。

@dylanbespalkoここにタイププロモーションを追加しました: https ://github.com/pytorch/pytorch/pull/11641

それをコピーすることもできますが、問題はこれがCUDAを何らかの形で壊してしまうことです。

IIRC、gccバージョンによるワイヤバグがありました。 そこでいくつかの回避策がありました。

ああ、@Roger-luoに感謝します。 #11641のコメントを見ていました。 私は明日コードをコピーするより良い仕事をします。

CUDAデバイスを持っていないときにCUDAが壊れたことをどのように知ることができますか? CIが教えてくれると思いますか?

はい、PRを送信すると、どちらが壊れているかがわかります。 そして、すべてがうまくいけば、それをマージして機能させることができます。

それでは、PRの提出を開始して、いつ発生するかを確認します。

@dylanbespalkoこんにちは、あなたの環境にはまだいくつかのエラーがあるようですか?
修正したら、私たちと共有してください。 どうもありがとう。

やあみんな、

@ Roger-luoのコミットをいくつかコピーした後、いくつかのPRを実行してみました。 残念ながら、私は現在CUDA GPUを持っておらず、CUDAを備えたCIマシンは初期化されていません。 現在、CUDAテストの失敗を再現できないため、そのGPUでローカルに実行できるようになると、数週間後にこれに戻ります。 少なくとも有望に見えます。

@ ezyang 、@ Roger-luo

私はロジャーのPR #11641を見ました:

  • CUDA9.0マシンでビルドして実行します
  • CUDA9.0を実行しているCIマシンでのビルドに失敗します

最近のPyTorchの開発についても見てきました。

  • カスタムデバイス/レイアウト/dtypeを定義できるC++/CUDA拡張機能の記述方法を説明する@ezyangからのプレゼンテーション

    • 「ComplexHooksInterfaceを削除する」が、pytorch / test / cpp_extensions /complex_registration_extension.cppにある複素数C++拡張機能を定義する最新のPR #21964

新しい「ツリー外」拡張機能が開発されているように見えます。これにより、残りのpytorchを壊すことなく、複素数のサポートを調査できます。 私の目標は次のとおりです。

  1. AVXなしで複雑なCPUサポートを定義します。
  2. Thrustを使用して複雑なCUDAサポートを定義します。

@ezyang
提示したこのツリー外のデバイス/レイアウト/dtype拡張機能の予想されるタイムラインを提供できますか? 今後3か月でこの機能を期待できますか?

@ezyang

AVX / SSEサポートなしでCPUの複素数サポートをマージできますか? 以下を個別のマージリクエストで送信する予定です。

  • []CPUBinaryOpカーネルの複雑なサポートを追加しました
  • []CPUTensorFactoriesの複雑なサポートを追加しました
  • []CPUFillKernelsの複雑なサポートを追加しました
  • []CPURangeカーネルの複雑なサポートを追加しました
  • []CPUUnaryカーネルの複雑なサポートを追加しました
  • []CPUCompareカーネルの複雑なサポートが追加されました
  • []CPUTensorCompareカーネルの複雑なサポートが追加されました
  • []CPUReduceOpカーネルの複雑なサポートを追加しました
  • []CPUPointwiseOpsカーネルの複雑なサポートを追加しました
  • []CPUlearpOpsカーネルの複雑なサポートを追加しました
  • []CPULinearAlgebraOpsカーネルの複雑なサポートを追加しました
  • []CPUSpectralOpsカーネルの複雑なサポートを追加しました

今後数日で、Intel /ArmCPU全体でこれをテストする予定です。

@ezyang

fft()var()のような操作を調べています。ここで、複素数の実装では、テンソルデータを形状の二重テンソルに変換する必要があります: (complex_shape, 2) 。 これは、既存のテンソル法では機能しません。

  1. 'tensor.to(torch.float64):実数部のみを保持し、同じ形状のテンソルを返します。
  2. 'tensor.view(new_shape):新しい形状には同じ数の要素が必要です。

明らかに、私は次のような非効率的なことをすることができます:

def to_float(tensor):
    return th.stack((tensor.real().type(th.float64), tensor.imag().type(th.float64)), -1)

def to_complex(tensor):
    tensor = tensor.type(th.complex128) 
    return tensor[..., 0] + 1j*tensor[..., 1]

明らかに、それはコピーを作成することです。必要なのはstatic_cast<double>で、テンソルの形状を(old_shape, 2)に変更することだけです。 これを行う方法について何か提案はありますか?

また、これを可能にするnumpyのハックがあります:

a = np.array([1 + 1j], dtype=np.complex128)
a.dtype = np.float64  ## This works

a = torch.tensor([1 + 1j], dtype=torch.complex128)
a.dtype = torch.float64  ## This does not work

dtypeを設定する機能は、この状況で実際に機能しますが、予測できない可能性があります。

複素数を実数の長さ2の配列として解釈することに関するいくつかの追加情報。 以下はC++11で有効です。

複素数pの配列の要素および有効な配列インデックスiへのポインターの場合、reinterpret_cast(p)[2 i]は、複素数p [i]の実数部であり、reinterpret_cast(p)[2 i + 1]は、複素数p[i]の虚数部です。 (C ++ 11以降)

これは、complex_tensorをshape(complex_shape、2)のreal_tensorに変換してから、新しいメモリを割り当てたreal()imag()を呼び出さずに操作を実行できることを意味すると思います。

@dylanbespalkoあなたがこれについて尋ねるとき、私は恐れていました:) std::complex保証は、データポインタstd::complex<float>*があれば、それをfloat*に安全にキャストできることを意味します(厳密なエイリアシングをつぶやく)次に、使用しているfftのものにそれを渡します。 この低レベルの担当者を渡すことができるfft/varのみを実装する必要がある場合は、それが最も簡単です。

ただし、複雑なテンソルを文字通りフロートテンソルとして見直す必要がある場合は、今日のPyTorchには前例がないため、少し厄介です。 Storagedtypeは常にTensordtypeと一致しています。 したがって、複雑なストレージを作成する場合、それをフロートストレージとして確認する方法はありません。

私が持っていた1つの考えは、おそらくこの不変条件を緩和する必要があるということです。 アイデアは次のとおりです。

  1. 問題の「ベクトル化されていない」タイプとして、常にストレージを割り当てます。 だから複雑なフロートテンソルを割り当てます。
  2. テンソルdtypeは、ストレージdtypeと一致しないことが許可されていますが、基になるタイプのベクトル化されたバリアントとしてのみ許可されます。

ただし、この不変条件を実現するために変更する必要のあるコードの量はわかりません。

@ezyang

はい、これは避けられませんでした...

この低レベルの担当者を渡すことができるfft/varのみを実装する必要がある場合は、それが最も簡単です。

はい、これは多くの場合可能です。 テンソルデータをstd::vectorとして解釈する方法のコードスニペットを提供できますか?

ただし、複雑なテンソルを文字通りフロートテンソルとして再表示する必要がある場合は、...。

別のdtypeを使用してテンソルを表示することはめったにないと思います。 Tensorset_dtype()メソッドを実装しましたが、いくつかのエラーが発生しました。 また、形状の変化を反映するためにストライドを更新しませんでした。 dtypeの設定がnumpyで機能する理由はわかりませんが(偶然ですか?)、データをデジタル-アナログコンバーター(DAC)にアップロードすると、実数/虚数のデータがインターリーブされることがよくあります。 おそらくそれは、あなたが提案したように、テンソルdtypeをストレージdtypeから分離する必要性を動機付けるでしょう。

今のところこれは避けます。 私には他にもパフォーマンスのボトルネックがあると確信しています。

はい、これは多くの場合可能です。 テンソルデータをstd::vectorとして解釈する方法のコードスニペットを提供できますか?

正確にはstd::vectorではありませんが、私は次のようなものを想像しています:

Tensor complex_tensor;
assert(complex_tensor.is_contiguous());
std::complex<float>* cp = complex_tensor.data_ptr<std::complex<float>>();
float* fp = reinterpret_cast<float*>(cp);
auto num_floats = complex_tensor.numel() * 2;

Tensorにset_dtype()メソッドを実装しましたが、いくつかのエラーが発生しました。 また、形状の変化を反映するためにストライドを更新しませんでした。

ええ、ストライドも修正しないのであれば、これはおそらく悪い考えです。 また、私は他のdtypeに変換するテンソルの大ファンではありません。 すべてを場違いで行う方が良いです:)

ただし、データをデジタル-アナログコンバーター(DAC)にアップロードする場合、実数/虚数のデータがインターリーブされることを期待することがよくあります。 おそらくそれは、あなたが提案したように、テンソルdtypeをストレージdtypeから分離する必要性を動機付けるでしょう。

はい、最終的にはこれが正しいことですが、今はこれを行わない方が簡単であることに同意します。

@ezyang

複素数のCUDAサポートをいじり始めています。

2つのバイナリ互換オプションがあります。

  1. cuComplex :非常に基本的なadd、sub、mul、div、real、imagのサポート。
  2. 推力::複雑:ホストとデバイスのメモリ割り当てをサポートするstd::complexの代わりにドロップイン。

推力::複雑なコンテナは行く方法のようです。 Thrust :: Complex APIは、 thrust::complex<T>コンテナをホストとデバイスのメモリに割り当てることができるのに対し、 std::complex<T>はホストメモリにのみ割り当てることができることを示しています。

__host__ __device__     thrust::complex< T >::complex (const complex< T > &z)  //thrust container
__host__    thrust::complex< T >::complex (const std::complex< T > &z) //stl container.
  1. これは、AT_DISPATCH_COMPLEX_TYPESがusing scalar_t = std::complex<double> $ではなくusing scalar_t = thrust::complex<double>を設定する必要があることを示唆していますか?

  2. Pytorchは、実際のデータ型に対してstd::logに相当するCUDAを自動的に呼び出すにはどうすればよいですか? 数学カーネルに相当するCUDAがあることをどうやって知ることができますか?

  1. CPUとCUDAにthrust::complex<double>を普遍的に使用することの難しさは、CPUのみをビルドする場合、実際には推力に対してビルドしないことだと思います。 たくさんのオプションがあると思います。 std::complex<>は特定のバイナリレイアウトを持つように定義されているため、独自の複合型をロールすることも(独自のハーフタイプをロールする方法と同様)、勝利への道を再解釈することもできます。 それはあなた次第ですが、今のところ、タイプ間のキャストを再解釈する方が簡単なようです。
  2. THCNumerics.cuhに数学のオーバーロードがありますが、それはあなたの質問に答えますか?

@iotamudeltaは、#29547でC++11準拠の問題を提起しました

std::realはC++14のconstexprのみです

私が正しく理解している場合、hccコンパイラが__device__の命令をコンパイルできるように、 std::real()constexprである必要があります。

可能な解決策:

  1. complex<double>doubleに変換する別のメソッドまたは関数を見つけます:
  1. 関数をラップする方法を見つけます。

    • std :: realへのほとんどの呼び出しは、 aten/src/ATen/native/cpu/zmath.hで行われます。 例: inline constexpr置き換えます:

      inline VALUE_TYPE real_impl (SCALAR_TYPE z) ->
      constexpr VALUE_TYPE real_impl (SCALAR_TYPE z)

      inline std::complex<float> real_impl <std::complex<float>> (std::complex<float> z) -> constexpr std::complex<float> real_impl <std::complex<float>> (std::complex<float> z)

      inline std::complex<float> real_impl <std::complex<double>> (std::complex<float> z) -> constexpr std::complex<float> real_impl <std::complex<double>> (std::complex<float> z)

constexpr std::real()へのネストされた呼び出しがまだあるため、これはコンパイルされません。

3. std::complexを使用する場合std :: real()の代わりに:: real()これはC++11に準拠しているようです。

  1. 私が何をしても、このコードはC++14まではUBだと言っていると思います。 要件を満たすstd::complex<double>doubleに変換する他の方法はありますか?

@iotamudelta@ bddppq@ ezyang

CUDAスラスト::複雑なAPIで複雑なUnaryOpsとBinaryOpsのサポートを追加しましたが、送信する前にいくつか質問する必要があります。

複素数を処理するときにthrust::complexデータ型を使用できるようにするテンプレート関数を定義しました。
aten/src/ATen/native/cuda/zmath.cuh

#pragma once

#include <complex>
#include <thrust/complex.h>

namespace at { namespace native {
namespace {

template <typename TYPE>
struct ztype_cuda {
  using value_t = TYPE; // Complex template type
  using thrust_t = TYPE; // Equivalent thrust type
};

template <>
struct ztype_cuda<std::complex<float>> {
  using value_t = float;
  using thrust_t = thrust::complex<float>;
};

template <>
struct ztype_cuda<std::complex<double>> {
  using value_t = double;
  using thrust_t = thrust::complex<double>;
};

} // end namespace
}} //end at::native

次にaten/src/ATen/native/cuda/BinaryOpsKernel.cu
交換:

void add_kernel_cuda(TensorIterator& iter, Scalar alpha_scalar) {
  AT_DISPATCH_ALL_TYPES_AND2(kHalf, kBool, iter.common_dtype(), "add_cuda/sub_cuda", [&]() {
    auto alpha = alpha_scalar.to<scalar_t>();
    gpu_kernel_with_scalars(iter, [alpha]GPU_LAMBDA(scalar_t a, scalar_t b) -> scalar_t {
      return a + alpha * b;
    });
  });
}

と:

void add_kernel_cuda(TensorIterator& iter, Scalar alpha_scalar) {
  AT_DISPATCH_ALL_TYPES_AND_COMPLEX_AND2(kHalf, kBool, iter.dtype(), "add_cuda/sub_cuda", [&]() {
    using thrust_t = typename ztype_cuda<scalar_t>::thrust_t;
    auto alpha = thrust_t(alpha_scalar.to<scalar_t>());
    gpu_kernel_with_scalars(iter, [alpha]GPU_LAMBDA(thrust_t a, thrust_t b) -> thrust_t {
      return a + alpha * b;
    });
  });
}

質問

  1. @ezyang :非複素数の場合、scalar_tとthrust_tは同じタイプです。 たぶん、変数名thrust_tを、 scalar_t_cなどの非複素数にわかりやすい名前に置き換えることができますか?
  2. スラストライブラリは、コードで広く参照されているようです。
    a) @bddppqthrust::complex cuComplexを使用する必要がある理由はありますか?
    b) @iotamudelta :ヒップスラストはROCm2.7で削除されました。 代わりにhip_complexを使用する必要がありますか?
    推力::複合体はcuComplexより多くの機能をサポートしているようです。

ご意見をお聞かせください。

@iotamudelta

std :: real()に関するディスカッションを更新しました。 std::complexを確認できますか:: real()は問題を修正します。

こんにちは@dylanbespalko

@iotamudeltaが不満を言っているのは、複合型のcast_and_storeC10_HOST_DEVICEがないことだと思います。これは、そのコードパスがGPUで実行された場合のUBになります。

現在、この動的キャストユーティリティはGPU TensorIteratorでのみ使用されており、タイププロモーションがある場合にのみ使用されます。 複合体は現在GPUでサポートされていないため、複合型のcast_and_storeには現在C10_HOST_DEVICE修飾子がなく、$ std::realを使用しています。これはホストにとってはまったく問題ありません-機能のみ。 使用されておらず、心配する必要がないため、ここにはUBはありません。

ただし、complexのサポートをGPUに追加する必要があるため、 https://github.com/pytorch/pytorch/blob/master/c10/core/ScalarType.h#L398で確認できるように、complexはタイププロモーションによってサポートされます。 L420、このコードパスには細心の注意を払う必要があり、それを機能させるために必要な変更がいくつかあります。

もちろん、 @ iotamudeltahttps://github.com/pytorch/pytorch/pull/29547で行っているように、 C10_HOST_DEVICEを追加する必要がありますが、 C10_HOST_DEVICEを追加するだけなので、それだけでは不十分です。 @iotamudeltaで言及されているように、他の変更がなくてもC ++ 11ではUBであるため、適切な解決策は、あなたが言及したものである可能性があります。 std::complex::real()を使用してstd::real $を置き換えます。

しかし、それを超えて、ファイルhttps://github.com/pytorch/pytorch/blob/master/c10/util/TypeCast.hを見ると、 fetch_and_castの中に、次のようなものがあります。

#ifndef C10_HOST_DEVICE
    AT_FORALL_COMPLEX_TYPES(FETCH_AND_CAST_COMPLEX_CASE)
#endif

このコードパスはGPUでは無効になっています。 それを有効にして機能させる必要があります。

また、 fetch_and_castcast_and_store $内で$ complex<float>complex<double>の間の変換は見られませんでした。 そのための変換を追加する必要がある場合もあります。 すべてのdtypeのこれらの関数のカバレッジを徹底的にテストしてください。

cc: @ezyang@bddppq

また、 @ dylanbespalko 、PRでTypeCast.hに変更を加える場合は、私にccしてください。

OK、ARMのtorch.real()torch.imag()で修正する小さなことがいくつかあるので、 TypeCast.hと他のいくつかを修正します。 私はあなたたちをPRにccします。

コメントでドライブ: @smessmerは私たちをC ++ 14に移行させており、その時点ではUBにはなりません。 これはもうすぐ来るので、UBが実際の問題を引き起こしていないのであれば、私はそれについてあまり心配しません。

@ezyang :知っておくといいですね。 Eigenのようなサードパーティのもののほとんどはまだstd::real()非常に寛大に呼び出します。

非複素数の場合、scalar_tとthrust_tは同じタイプです。 たぶん、変数名thrust_tを、scalar_t_cなどの非複素数にわかりやすい名前に置き換えることができますか?

よくわかりませんが、 scalar_t_cthrust_tよりも少しわかりにくいようです(とにかくcはどういう意味ですか?)ここで問題になっているタイプは非常に具体的です。そのため、意図を直接表す名前を使用する方がよいようです。

OK、 thrust_tを使い続けます。 誰かがztype_cuda<>()に飛び込んだ場合、それらはscalar_tが非複雑なタイプのthrust_tであることを即座に理解する必要があります。

皆さんこんにちは! pytorchに複雑なサポートを追加することに向けて順調に進んでいるようです! これに率先して取り組み、CUDAサポートも追加してくれた@dylanbespalkoに感謝します! 大まかに言えば、複雑なサポートの現在の進捗状況を知りたいと思います。 私は主に、複雑なテンソル(バイナリ演算)を追加および乗算するためのCUDAサポートを持つための大まかなタイムラインに興味があります。 ありがとう!

こんにちは@sunilkpai

CUDAのバイナリおよび単項演算をサポートするオープンPRがあります:#30295。

もう1つの問題は、後方伝搬に関するものです。 複素数abs()の導関数は、実数とは異なる方法で定義されていると思います。 それについてどうしたらよいかわかりませんが、導関数はtools/autograd/derivatives.yamlで定義されています

複素数の場合/dz abs(z) = z/abs(z)だと思います。 これは実数にも使用できますが、 sgn(z)よりも遅くなる可能性があります

@dylanbespalko私のレポートhttps://arxiv.org/pdf/1701.00392.pdfの表4.1、4.2、4.3は、派生物を定義するのに役立つかもしれません。

複雑な導関数(wirtinger計算)には、2つのオプションがあります。
zまたはz共役の導関数を計算します。
私は個人的に微分wrtz共役がもっと好きです。
行列演算の方が自然で、勾配の更新に共役は必要ありません。
それらの定義は次のとおりです。

  • $#$ 1 $#$の導関数wrt z z = x + jydJ/dz = dJ/dx -j dJ/dy
  • z = x + jyのデリバティブwrt z.conj $: dJ/dz.conj = dJ/dx + j dJ/dy

あなたのコメントから、私の仮定は、あなたが現時点でzの導関数を計算するということです。
この場合、導関数はd abs(z) / d z = z.conj / abs(z)です。 他の定義を取るときは、 @Randlの提案に従うことができます。

もっと説明する必要があるかどうか教えてください。 また、複雑なデリバティブの実装もいくつかあります。

(特に複素数のサポートを必要とする物理空間のプロジェクトで)役立つもう1つの操作は、 exp()演算子のハンドラーです。 テンソルフローには、 tf.exp(x + iy) = tf.exp(x) * (tf.cos(y) + 1j * tf.sin(y))があります。 これはpytorchにも簡単に実装できますか?

@ sunilkpai@ boeddeker@ Randl

複雑なデリバティブに関するレポートをありがとう。 私はそれに従おうとします、そして私は来週これに戻ります。 ここにいくつかのリンクを追加して、プロジェクトのステータスを説明しようと思いました。

複素数のステータスは非公式にサポートされており、PyTorchExtensionを介して追加する必要があります。

各拡張機能には2つのものが含まれています。

  • 必要な数学カーネル登録を含む.cpp
  • pytorchテストスクリプトの非常に単純化されたバージョンを含むtest/フォルダー。
    テストスクリプトを調べて、サポートされているカーネル(および他のカーネルがサポートされていない理由)を確認します。

複雑なテンソルをコンソールに印刷できないのはなぜですか?

  • Tensor pythonオブジェクトには、サポートされていないいくつかの関数を呼び出すきれいな印刷フォーマットがあります。

    • tensor.pyの内容を変更して、印刷フォーマットをバイパスできます。

    • または、PytorchテンソルをNumpy配列に変換してから印刷することもできます。

現在のプロジェクトステータス:

  • CPUカバレッジはかなり良いです。

    • カーネルは、PyTorch内の'aten / src / ATen / native / cpu / </li> <li>Complex number specific code is under 'aten/src/ATen/native/cpu/zmath.hの下に実装されています。

    • IntelAVX256アクセラレーションは'aten/ src / ATen / cpu /vec256/`の下にあります



      • @sunilkpai :expの最適化を知りませんでした。 これは、それを追加するフォルダーです。


      • 変更に問題がないかどうかお知らせください。



  • GPUのカバレッジは、バイナリおよび単項演算に制限されています。

    • カーネルは、PyTorch内の'aten / src / ATen / native / cuda / * </li> <li>Complex number specific code is under 'aten/src/ATen/native/cuda/zmath.cuhの下に実装されています。

    • thrust::complex<T>データ型が使用され、最適化されたカーネルが含まれます。

現在の開発:

  • CベースのTHカーネルがC++ATenフォルダーに移植されるのを待っています。

    • テストケースをpytorchの内部テストに移植するには、rand()関数が必要です。

    • 一部のインデックス作成操作は現在移植されていません。

    • 現在、THからATenに移植する必要のある168/1300の数学カーネル(10月の230から減少)があります。

  • これらのカーネルがATenで利用可能になったら、複素数のサポートを追加しようと思います。

-

ご参考までに。 複雑なデリバティブに関しては、Juliaで長い議論があり、その実装は現在、 ChainRules (http://www.juliadiff.org/ChainRules.jl/dev/api.html#ChainRulesCore.Wirtingerも参照)とZygoteで行われています。 。 一般的に、人々は必要なだけです
勾配として\partial L/\partial adjoint(z) (定義上、最も速い減少方向です)が、導関数は\partial L/\partial zとは異なります。複素数ADを完全にサポートする場合は、追加のインターフェイスを追加する必要があります。 。 詳細なルールについては、 ChainRulesまたはZygote/libに実装されているものを確認できます(一般的なルールしかないため、ほとんどの演算子に複素数の個別のルールはありません。 matmulのように、一般的な定義で書かれています。例: adjoint(A) * B

複雑なテンソルをコンソールに印刷できないのはなぜですか?
Tensor pythonオブジェクトには、サポートされていないいくつかの関数を呼び出すきれいな印刷フォーマットがあります。
tensor.pyの内容を変更して、印刷フォーマットをバイパスすることができます。
または、PytorchテンソルをNumpy配列に変換してから印刷することもできます。

そもそもデバッグなどのためにhttps://github.com/Roger-luo/pytorch-complexの印刷の少なくとも一部を修正したと思いますが、マスターが過去に大きく変更されたため、これが役立つかどうかはわかりません年。 それが役に立ったらあなたはそれを取ることができます、私はこれ以上これに取り組むつもりはありません。

@dylanbespalko私は学び始めましたが、pytorchの内部については比較的経験が浅いです! aten/src/ATen/cpu/vec256/*に表示されている内容に基づいて、std :: exp(std :: complex)のデフォルトの動作が正確に私が述べたものであることを考えると、それが必要かどうかはわかりませんが、おそらくこの変更を試みることができます。私の以前のコメントで: https ://en.cppreference.com/w/cpp/numeric/complex/expのメモを参照してください。 また、これがCUDAでこれらの操作を実装することにどのように変換されるかわかりません(現在、real、imag、conj、angleに制限されているようです)。

@sunilkpai

提供された式を使用して、 exp()のAVXサポートを追加しました。

また、PyTorchの最近の変更により、いくつかのものが壊れていることに気づきました。 これらは#30871で修正しました。

@dylanbespalko

THからATenへの移植のタイムラインはありますか?
pytorchの内部動作に精通していないという事実を踏まえて、貢献できる方法はありますか?

arxivの複雑なsvdのバックプロパゲーションの式を見つけ、それを実装できます。

あなたの仕事をありがとう!

@Jakob-揚げ物なし

https://github.com/pytorch/pytorch/wiki/TH-to-ATen-porting-guide

THカーネルはCで実装されており、固有の参照カウントの問題がすべてあるため、そこに複雑なサポートを追加することにはほとんど関心がありません。 各カーネルが登録されているaten/src/ATen/native/native_functions.yamlで進行状況を追跡できます。

legacy::cpu::_thを検索し、その数を3で割って古いTHカーネルの数を求めます。
legacy::cpu::_thnnを検索し、その数を3で割って、古いTHニューラルネットワークカーネルの数を求めます。

各カーネルは通常、3つの異なる方法で登録されます。
1.通常のカーネルy=add(a、b)
2.インプレースカーネルa=add_(a、b)
3.出力カーネルadd_out(a、b、out = y)
実際の実装は常に出力カーネルにあり、他の2つはその関数を呼び出します。

nnカーネルは、依存するカーネルが少ないため、移植が容易になる傾向があります。 したがって、実装方法とは逆の順序でカーネルを移植できる場合は、全体的な作業が少なくなります。

移植追跡の問題を確認するhttps://github.com/pytorch/pytorch/issues/24507、cc @VitalyFedyunin

#32437で要求された複素数サポートのステータス更新は次のとおりです。 今日はCPU関連のサポートに戻っています。

Autogradサポート

  • 私はこれのために多くの時間を持っていませんでした。
  • angle()real()imag()conj()がすべて実装されました。
  • abs()は、複素数に対して個別の実装が必要になります。 (上記の@boeddeker@Randlからのメモを参照してください)

ハードウェアサポート

複素数のサポートは現在、ツリー外で実装されています。 これが意味することです:

ツリー内コード

  • 数学演算は実際にはツリー内(PyTorchソースコード内)に実装されています。
  • ツリー内のPytorchテストはいずれも、複素数のサポートを検証しません(したがって、問題が発生する傾向があります)。
  • PyTorchはTHからATen(#24507)に移行しています。
    -THに実装されている数学カーネルは、複素数をサポートしていません。
    -ATenに実装されているカーネルのみが複素数をサポートできます。
  • 複雑なdtypeを有効にするには、PyTorch拡張機能をインストールする必要があります。

ツリー外コード

  • いくつかのPyTorch拡張機能が実装されており、将来的に簡単に内部化できます。
  • 各拡張子には、重要な4つのファイルがあります。

    • setup.py:pytorch拡張機能をビルドしてインストールします。

    • [CPU / CUDA / FPGA] ComplexType.cpp:CPUType.cppまたはCUDAType.cppに類似した数学カーネル登録

    • test / test_torch.py​​: ATenのサポートによって制限されている、動作しているカーネルを示す非常に醜いテストケース。

    • test / test_autograd.py:autograd機能をテストします。

ツリー外のPyTorch拡張機能

  1. cpu_strided_complex
    -[x] CopyKernel
    -[] TensorFactories(th_random、th_uniform、th_normal)
    -[x] RangeFactories
    -[x] BinaryOpKernals
    -[x] UnaryOpKernels
    -[x] CompareOpKernels
    -[x] PowKernels
    -[x] ReduceOpKernels(th_min、th_max、一部のノルムは複素共役を計算しません)
    -[] IndexOpKernels(th_masked_select_bool、th_set、th_gather、th_cat)
    -[x] PointwiseOps
    -[x] Lerp Ops
    -[] BlasOps(th_mv、th_mm、th_fmod、th_eig)
    -[] LinpackOps(Blasを使用)
    -[] SpectralOps(サポートされていますが、作業が必要です)

    1. cuda_strided_complex



      • [x] CopyKernel


      • [] TensorFactories(CPUの問題を参照)


      • [x] BinaryOpKernals


      • [x] UnaryOpKernels(Todo:角度、実数、画像、接続詞を追加)


      • [] CompareOpKernels(Todo)


      • [] ReduceOpKernels(WARP_SIZEに関するエラーメッセージ)


      • GPUはポイント単位の計算を超えて困難になりますが、追加の機能をサポートできます



  2. vitis_​​strided_complex

    • ザイリンクスVitisは、サーバーおよび組み込みデバイスをサポートするFPGA高位合成プラットフォームです。

    • 2019年10月にリリースされました(デバイスのサポートが制限されている可能性があります)。

    • SDAccel(サーバー)とVIvado HLS(組み込み)を組み合わせます。

    • [] BinaryOpKernals(1月末)

    • [] UnaryOpKernels(1月末)

    • [] ReduceOpKernels(2月末)。

    • FPGAで最近追加されたベクトル化されたオブジェクトは、Vec256PyTorchテンプレートクラスと同様のサポートを提供します

    • Vec256は、CPUに複雑なサポートが追加された方法であり、$C$または$R^N$テンソル空間を実装するためのより自然な方法のようです。

この問題に関するその他の更新: https ://github.com/pytorch/pytorch/issues/33152

これは別の問題に値する場合とそうでない場合がありますが、「現在、pytorchが複素数でどのように機能するか」を説明するものをドキュメントに含めることが、現在、実際に重要であると考えています。 別名は、足し算、掛け算、ある種の規範、複雑な重みなどを行うことはできません。これらはすべて、意図された高レベルの現在の動作を説明する数行のドキュメントで要約できます。

これは別の問題に値する場合とそうでない場合がありますが、「現在、pytorchが複素数でどのように機能するか」を説明するものをドキュメントに含めることが、現在、実際に重要であると考えています。 別名は、足し算、掛け算、ある種の規範、複雑な重みなどを行うことはできません。これらはすべて、意図された高レベルの現在の動作を説明する数行のドキュメントで要約できます。

こんにちは@redwrasseフィードバックをありがとう! 現在、マスター上の複素テンソルでサポートされているいくつかのトーチの基礎と複素関数について説明している複素数に関するメモがあります。
(そのほとんどは1.6リリースに含まれています) https://pytorch.org/docs/master/complex_numbers.html?highlight=complex。 他に興味のある機能を教えてください。 現在のサポートと今後のリリースの計画について詳しくお話しします。

これは別の問題に値する場合とそうでない場合がありますが、「現在、pytorchが複素数でどのように機能するか」を説明するものをドキュメントに含めることが、現在、実際に重要であると考えています。 別名は、足し算、掛け算、ある種の規範、複雑な重みなどを行うことはできません。これらはすべて、意図された高レベルの現在の動作を説明する数行のドキュメントで要約できます。

こんにちは@redwrasseフィードバックをありがとう! 現在、マスター上の複素テンソルでサポートされているいくつかのトーチの基礎と複素関数について説明している複素数に関するメモがあります。
(そのほとんどは1.6リリースに含まれています) https://pytorch.org/docs/master/complex_numbers.html?highlight=complex。 他に興味のある機能を教えてください。 現在のサポートと今後のリリースの計画について詳しくお話しします。

@ anjali411に感謝します。このドキュメントを見るのは素晴らしいことですが、以前は気づいていませんでした。 必要なのは、数行の「複雑なニューラルネットワークのサポートの現状」の前面と中央にあると思いますが、それを見てみましょう...

複雑なオートグラードに興味がある人は、 https://github.com/pytorch/pytorch/issues/41857に興味があるかもしれません。これは、PyTorchが従う規則(JAXまたはTF)に触れています。

このページは役に立ちましたか?
0 / 5 - 0 評価