Как всегда, я, наверное, здесь упускаю что-то очевидное. Я не могу опубликовать весь исходный код, потому что это связано с работой, но у меня есть шаблон Matrix
класс с 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
Я попытался сделать два значения в MT разные. Я проверил, что, когда мой mulMT для Floats отсутствует, универсальный работает. Я не знаю, почему он делает то, что делает.
Редактировать: Чтобы доказать, что код внутри специализации Float не был проблемой, я прокомментировал это. Все работало Я раскомментировал код. Все еще работает. Я думаю, что, возможно, Visual Studio просто запуталась и не перекомпилировала что-то.
Дальнейшее редактирование: ОК … это очень странно. При отладке, когда я впервые захожу в mulMT, он выводит меня на строку с const bool softmax) {
, Если я попробую F10, я получу исключение. Если я нажму F11, это бросит меня в ChkStk.asm
, Если я выйду из этого файла, я смогу получить доступ к внутренней части функции, и все будет распределено правильно. Фактически, пока я не перекомпилирую свою тестовую программу, я могу проходить или запускать столько раз, сколько мне нравится, без ошибок. Однако, если я внесу изменения в свою тестовую программу и перекомпилирую, поведение вернется.
Я еще больше запутался, чем был на старте.
Редактировать: Хорошо, после двух дней без проблем, это придет снова. Я думаю, что это не то, что, как я думал раньше, связано с изменением ценностей. Вместо этого это происходит до того, как параметры будут созданы. Дело в том, я не знаю, почему до сих пор, кроме того, что это единственная функция, которая у меня есть, которая бросает меня в stkchk.asm
если я ударю F11
после входа в функцию.
Исключение первого шанса в 0x00789adc в UnitTest.exe: 0xC0000005: расположение чтения нарушения доступа 0xabababab. это исключение, которое я получаю. Ранее в функции я делал почти идентичный вызов, меняя только те переменные, которые используются с оператором. Как ни странно, блок try-catch вокруг вызова ничего не делает для предотвращения сбоя программы.
Я понял, что происходит не так. Исключение действительно происходило внутри функции. Visual Studio оптимизировала функцию, поэтому, если бы у меня не было точки останова внутри нее, она просто перешагнула бы через все это. Если функция работает правильно, она работает правильно. Если внутри было какое-то исключение, это не удалось. До сих пор не знаю, почему try
catch
Блок не поймал это, но я не потею.
Спасибо всем за ваши попытки помочь. И спасибо, @JBL за то, что были правы в конце.
Других решений пока нет …