いつものように、ここでは明らかな何かが欠けている可能性があります。仕事に関連しているため、ソースコード全体を投稿することはできませんが、 (行列を行列で乗算する)関数と関数(行列を転置行列で乗算する)を含むテンプレート化さMatrix
れたクラスがあります。それはすでにコードに存在しています。単精度浮動小数点値に特化した関数を追加しようとしています。同じ最初の 2 つの関数パラメーターを共有する同様の特殊化があります。コード例を次に示します。mulMM
mulMT
mulMT
mulMM
#ifdef TARGET_x86_SSE4
template <>
Matrix<Float>& Matrix<Float>::mulMM (const Matrix<Float>& mat1,
const Matrix<Float>& mat2);
template <>
Matrix<Float>& Matrix<Float>::mulMT (const Matrix<Float>& mat1,
const Matrix<Float>& mat2,
const bool softmax);
#endif // no SSE4: use template generic
template <class BT>
Matrix<BT>& Matrix<BT>::mulMM (const Matrix<BT>& mat1,
const Matrix<BT>& mat2) {
// Function code
}
template <class BT>
Matrix<BT>& Matrix<BT>::mulMT (const Matrix<BT>& mat1,
const Matrix<BT>& mat2,
const bool softmax) {
// Function code
}
次に、別のファイルで:
#ifdef TARGET_x86_SSE4
template <>
Matrix<Float>& Matrix<Float>::mulMM (const Matrix<Float>& mat1,
const Matrix<Float>& mat2) {
// Function code
}
template <>
Matrix<Float>& Matrix<Float>::mulMT (const Matrix<Float>& mat1,
const Matrix<Float>& mat2,
const bool softmax) {
// Function code
}
コードを呼び出すと、mulMM は入力行列の値を正しく取得しますが、mulMT を呼び出すと、行列の次元の乱数が発生します。デバッガーを使用すると、関数に入ったときにマトリックスが適切に定義されていることがわかりますが、関数にステップインするとすぐに、値がすべて間違っています。私が使用しているコードの例を次に示します。
MatrixFloat mA(4, 5);
MatrixFloat mB(5, 4);
// Code to initialize mA and mB's values.
MatrixFloat mR = mR.mulMM(mA, mB)
// This works fine and correctly find the values for the product.
MatrixFloat mC(4, 4)
// Code to initialize mC
mR = mR.mulMT(mC, mC)
// This fails with a memory access error and stepping into the function reveals
// that this seems to be because mC has dimensions of 84376 x 1 or thereabouts
2つの値を異なるMTにしてみました。フロート用の mulMT が存在しない場合、汎用の mulMT が機能することを確認しました。なぜこれが何をしているのかわかりません。
編集: Float 特殊化内のコードが問題ではないことを証明するために、コメントアウトしました。すべてが機能しました。コードのコメントを外しました。すべてがまだ機能します。Visual Studio が混乱して何かを再コンパイルしなかったのではないかと考えています。
さらに編集: OK...これは非常に奇妙です。デバッグ時に、最初に mulMT に足を踏み入れると、 の行にドロップされconst bool softmax) {
ます。F10 を試すと、例外が発生します。F11 を押すと、 に落ちますChkStk.asm
。そのファイルを終了すると、関数の内部にアクセスでき、すべてが正しく割り当てられます。実際、テスト プログラムを再コンパイルしない限り、エラーなしで何度でもステップ実行または実行できます。ただし、テスト プログラムを変更して再コンパイルすると、動作が元に戻ります。
私は最初よりもさらに混乱しています。
編集: OK、2 日間問題が発生しなかった後、再び問題が発生しました。前に思ったような、価値観が変わるものではないと思います。代わりに、パラメーターが実際にインスタンス化される前に何かが起こっています。理由はまだわかりませんが、関数に入った後stkchk.asm
にヒットすると、これが私が持っている唯一の関数です。F11
UnitTest.exe の 0x00789adc での初回例外: 0xC0000005: アクセス違反の読み取り場所 0xabababab。私が得る例外です。関数の前半で、演算子で使用する変数を変更するだけで、ほぼ同じ呼び出しを行います。奇妙なことに、呼び出しの周りの try-catch ブロックは、プログラムのクラッシュを防ぐために何もしません。