Lapack: Требования к процессору для LAPACK

Созданный на 4 июн. 2021  ·  16Комментарии  ·  Источник: Reference-LAPACK/lapack

Мы работаем над переводом LAPACK на .NET. Мы написали компилятор FORTRAN, который успешно транслирует все LAPACK, включая все тесты. На реальных типах данных (почти) все тесты проходят. В отношении сложных данных мы все еще наблюдаем несколько проблем с точностью.

Пример:
XEIGTSTZ <zec.in - сбой из-за потери значимости в ZLAHQR.
Шаги для воспроизведения: ZGET37 -> knt == 31, ZHSEQR -> ZLAHQR -> в конце второго шага QR (ITS == 2) следующий код вызывает недостаточное заполнение (в некоторых регистрах, см. Ниже)

TEMP = H( I, I-1 )
    IF( DIMAG( TEMP ).NE.RZERO ) THEN
        RTEMP = ABS( TEMP)    ! <-- underflow on TEMP = (~1e-0173, ~1e-0173)
        IF (RTEMP .EQ. RZERO) RTEMP = CABS1(TEMP)
        H( I, I-1 ) = RTEMP
        TEMP = TEMP / RTEMP
        IF( I2.GT.I )

Наш компилятор нацелен на .NET CLR. Его JIT решает использовать регистры SSE для ABS (TEMP), что приводит к потере значимости при промежуточном вычислении величины. Ifort (в качестве другого примера) в этой ситуации использует регистры с плавающей запятой, следовательно, не переполняется (из-за своей большей длины: 80 бит). Я пытаюсь получить ясное (э) представление о том, чего ожидать от LAPACK в отношении того, какая точность / диапазон чисел требуется от компилятора / процессора во время выполнения.

Все ли тесты на двойную точность разработаны таким образом, чтобы требовать хотя бы 64-битные регистры? Или они разработаны таким образом, чтобы успешно работать с набором популярных компиляторов FORTRAN, доступных сегодня? (В первом случае проблема, указанная выше (и другие подобные), может потребовать внимания. Должен ли я подавать для них проблему?)

Я искал какую-то спецификацию, но пока не нашел. Любая ссылка также будет оценена. Заранее спасибо!

Question

Все 16 Комментарий

Само по себе недостаточное количество ресурсов не является настоящей проблемой. После потери значимости алгоритм переключается на CABS1, который менее подвержен переполнению. Возникающая проблема состоит в том, что TEMP не будет точно унитарным, что приведет к округлению в Z.

Возможное решение - предварительно масштабировать с помощью CABS1, а затем исправить с помощью ABS (из-за первого масштабирования ABS больше не должна переполняться). (У меня нет переполнения на моей машине, поэтому я не могу проверить это для вас)

IF (RTEMP .EQ. RZERO) THEN
    RTEMP = CABS1(TEMP)
    H( I, I-1 ) = RTEMP
    TEMP = TEMP / RTEMP
    RTEMP = ABS( TEMP)
    H( I, I-1 ) = H( I, I-1 )*RTEMP
    TEMP = TEMP / RTEMP
END IF

Я думаю, что тесты определенно предназначены для успешной работы с набором популярных компиляторов FORTRAN, потому что именно так они запускаются. Предсказать недостаточное / переполнение невероятно сложно. По крайней мере, в моем случае эти подпрограммы разработаны путем простого их тщательного тестирования (с использованием популярных компиляторов) и исправления любых обнаруженных нами переполнений / недостатков.

Спасибо! Это очень полезно.
Мы пытались восстановиться после переполнения с помощью CABS1. Но наша попытка не увенчалась успехом. Ваше предложение, кажется, намного лучше. С использованием ...

*
*        Ensure that H(I,I-1) is real.
*
         TEMP = H( I, I-1 )
         IF( DIMAG( TEMP ).NE.RZERO ) THEN
            RTEMP = ABS( TEMP)
            IF (RTEMP .EQ. RZERO) THEN 
                RTEMP = CABS1(TEMP)
                H( I, I-1 ) = RTEMP
                TEMP = TEMP / RTEMP
                RTEMP = ABS( TEMP)
                H( I, I-1 ) = H( I, I-1 )*RTEMP
            ELSE 
                H( I, I-1 ) = RTEMP
            END IF
            TEMP = TEMP / RTEMP
            IF( I2.GT.I )
     $         CALL ZSCAL( I2-I, DCONJG( TEMP ), H( I, I+1 ), LDH )
            CALL ZSCAL( I-I1, TEMP, H( I1, I ), 1 )
            IF( WANTZ ) THEN
               CALL ZSCAL( NZ, TEMP, Z( ILOZ, I ), 1 )
            END IF
         END IF
*
  130 CONTINUE

... эта итерация завершается успешно (даже при использовании регистров SSE для ABS ()).

Я думаю, что тесты определенно предназначены для успешной работы с набором популярных компиляторов FORTRAN, потому что именно так они запускаются. Предсказать недостаточное / переполнение невероятно сложно. По крайней мере, в моем случае эти подпрограммы разработаны путем простого их тщательного тестирования (с использованием популярных компиляторов) и исправления любых обнаруженных нами переполнений / недостатков.

Набор тестов очень помогает! По моим приблизительным оценкам, менее 1% тестов подвержены этой или подобным проблемам переполнения (при использовании нашего компилятора). Если сделать тесты еще более устойчивыми к недополнению / переполнению, это может помочь перенести LAPACK на большее количество платформ. Наша (неудачная) попытка, приведенная выше, является лишь одним примером, который ясно показывает, что мы вряд ли сможем найти решение со своей стороны. Прежде чем открыть несколько связанных вопросов, я хотел бы начать обсуждение, есть ли интерес в таком путешествии и какой подход будет хорошим.

Спасибо за улучшения @hokb и @thijssteel! Стоит ли писать пиар с модификациями, или ты хочешь, @hokb?

Учитывая мой ограниченный опыт работы с проектом, я был бы признателен за ваши усилия и возможность использовать ваш PR как ориентир для травки. будущие пиарщики от нас ... (если это нормально?)

Привет @hokb!

Я искал какую-то спецификацию, но пока не нашел. Любая ссылка также будет оценена. Заранее спасибо!

Я не уверен, что где-нибудь что-то указано.

Наш компилятор нацелен на .NET CLR. Его JIT решает использовать регистры SSE для ABS (TEMP), что приводит к потере значимости при промежуточном вычислении величины. Ifort (в качестве другого примера) в этой ситуации использует регистры с плавающей запятой, следовательно, не переполняется (из-за своей большей длины: 80 бит). Я пытаюсь получить ясное (э) представление о том, чего ожидать от LAPACK в отношении того, какая точность / диапазон чисел требуется от компилятора / процессора во время выполнения.

Утверждение, выделенное жирным шрифтом: если все вычисления выполняются с использованием 64-разрядной арифметики IEEE, LAPACK должен работать.

LAPACK не ожидает, что 80-битный регистр когда-либо поможет его вычислениям. Алгоритмы разработаны с учетом 64-битной арифметики. Теперь, как упоминалось @thijssteel , LAPACK протестирован с различными компиляторами / архитектурами, и эти компиляторы / архитектуры иногда используют 80-битные регистры, и мы могли бы подумать, что нашим алгоритмам все время требуется только 64-битные, но это не так, и они, по сути, требуют 80-битного.

На нашем пути к решению этих проблем мы не сделали ничего систематического. В общем, мы достаточно счастливы, когда алгоритмы проходят тестовый набор, и, если есть помощь от 80-битного регистра, пусть будет так.

Все ли тесты на двойную точность рассчитаны на использование как минимум 64-битных регистров? Или они разработаны таким образом, чтобы успешно работать с набором популярных компиляторов FORTRAN, доступных сегодня? (В первом случае проблема, указанная выше (и другие подобные), может потребовать внимания. Должен ли я подавать для них проблему?)

По моим приблизительным оценкам, менее 1% тестов подвержены этой или подобным проблемам переполнения (при использовании нашего компилятора).

О боже. 1%? Это пугающе большое число.

Тесты много тестируют на области недополнения и переполнения, поэтому можно ожидать, что тесты с большей вероятностью вызовут эту проблему, чем код пользователя, но все же.

Если сделать тесты еще более устойчивыми к недополнению / переполнению, это может помочь перенести LAPACK на большее количество платформ.

Переносимость на большее количество платформ действительно является одним из интересов. Другой интерес представляет повышенная точность с помощью такого пакета, как GMP, где, как я понимаю, точность фиксируется на протяжении всего вычисления. (Так, например, у вас 256-битное мышление, и нет 300-битного регистра, который мог бы вам помочь.)

Наша (неудачная) попытка, приведенная выше, является лишь одним примером, который ясно показывает, что мы вряд ли сможем найти решение со своей стороны. Прежде чем открыть несколько связанных вопросов, я хотел бы начать обсуждение, есть ли интерес в таком путешествии и какой подход будет хорошим.

да. Мы заинтересованы. Однако мы можем сделать только так много. И у нас много дел. Так что, возможно, мы рассмотрим одну проблему за раз и посмотрим, как далеко мы зайдем.

В любом случае, публиковать сообщения о проблемах на GitHub - это всегда хорошая идея. Это дает понимание проблемы и помогает собирать помощь и идеи для решения проблем.

Я рад, что мы идем по этому пути, но я бы рекомендовал не торопиться.

Возможно, для gfortran нам стоит компилировать с флагами -mfpmath=sse -msse2 для тестирования. Я думаю, что это заставит все вычисления выполняться с помощью 64-битной арифметики. Хотя я не уверен.

Учитывая мой ограниченный опыт работы с проектом, я был бы признателен за ваши усилия и возможность использовать ваш PR как ориентир для травки. будущие пиарщики от нас ... (если это нормально?)

Конечно! Пожалуйста, смотрите # 577.

@weslleyspereira Замечательно ! Я все еще проверяю, относится ли это к CLAHQR так же. Отправлю свой результат как можно скорее (завтра)

Привет @langou !

Утверждение, выделенное жирным шрифтом: если все вычисления выполняются с использованием 64-разрядной арифметики IEEE, LAPACK должен работать.

Отлично! Я полагаю, что под «работой» мы подразумеваем: при загрузке данных «в определенном диапазоне» они не будут переполняться из-за заданного размера регистра?

LAPACK не ожидает, что 80-битный регистр когда-либо поможет его вычислениям. Алгоритмы разработаны с учетом 64-битной арифметики. Теперь, как упоминалось @thijssteel , LAPACK протестирован с различными компиляторами / архитектурами, и эти компиляторы / архитектуры иногда используют 80-битные регистры, и мы могли бы подумать, что нашим алгоритмам все время требуется только 64-битные, но это не так, и они, по сути, требуют 80-битного.

На нашем пути к решению этих проблем мы не сделали ничего систематического. В общем, мы достаточно счастливы, когда алгоритмы проходят тестовый набор, и, если есть помощь от 80-битного регистра, пусть будет так.

Звучит очень разумно!

По моим приблизительным оценкам, менее 1% тестов подвержены этой или подобным проблемам переполнения (при использовании нашего компилятора).

О боже. 1%? Это пугающе большое число.

Что ж, вероятно, это «намного меньше»;)

Переносимость на большее количество платформ действительно является одним из интересов. Другой интерес представляет повышенная точность с помощью такого пакета, как GMP, где, как я понимаю, точность фиксируется на протяжении всего вычисления. (Так, например, у вас 256-битное мышление, и нет 300-битного регистра, который мог бы вам помочь.)

Звучит интересно, но я не могу это комментировать, так как у меня нет опыта с такими попытками фиксированной точности.

да. Мы заинтересованы. Однако мы можем сделать только так много. И у нас много дел. Так что, возможно, мы рассмотрим одну проблему за раз и посмотрим, как далеко мы зайдем.

Я все еще не уверен, какой будет хороший общий подход. Откройтесь мне, если мое понимание слишком наивно. Но не всегда ли переполнение / недостаточное заполнение зависит как от входных данных, так и от алгоритма? Значит, вместо того, чтобы заливать код новыми проверками условий и новым кодом для восстановления после них, мы могли бы вместо этого уменьшить «допустимый диапазон» для входных данных? Однако у меня нет необходимого понимания усилий, требуемых для любого подхода. Поэтому я не могу судить, что было бы более осуществимо.

В любом случае, публиковать сообщения о проблемах на GitHub - это всегда хорошая идея. Это дает понимание проблемы и помогает собирать помощь и идеи для решения проблем.

Хороший. Мы будем регистрировать проблемы по ходу дела. Я понимаю, что будет сложно придумать исправление, не имея возможности воспроизвести недополнение. Итак, какую информацию мы можем предоставить, чтобы прояснить проблему? Помогает ли спуск к бетонному отливу? То есть: предоставление количества итераций, текущих значений локальных переменных вместе с именами файлов и т. Д.?

Я рад, что мы идем по этому пути, но я бы рекомендовал не торопиться.

То же самое и здесь! :)

Одним из результатов # 577 является то, что LAPACK полагается на компилятор FORTRAN для реализации достаточно надежного (недостаточного / переполненного) сложного деления и ABS (). Интересно, стоит ли нам начать вести документ, собирая такие-то и подобные требования? Они будут одинаково важны и полезны для всех, кто хочет использовать LAPACK с другими / новыми компиляторами, для разработчиков компиляторов и для переноса части или всех алгоритмов LAPACK на другие языки?

Конечно! Было бы хорошо, если бы эта информация была хорошо задокументирована.

Для начала я потратил некоторое время на отслеживание (возможно) всех разделов в файлах LAPACK/SRC/z*.f (СЛОЖНЫЕ * 16 алгоритмов) формы

 REAL / COMPLEX   or   COMPLEX / COMPLEX

Всего я нашел 53 файла. См. Прикрепленный файл: complexDivisionFound.code-search

  • Для этого я использовал выражение REGEX в коде Visual Studio:

    \ n. * / ^ 0-9 (?! DBLE) (?! REAL) (?! MIN) (?! MAX) [^ 0-9]

Возможно, для gfortran нам стоит компилировать с флагами -mfpmath=sse -msse2 для тестирования. Я думаю, что это заставит все вычисления выполняться с помощью 64-битной арифметики. Хотя я не уверен.

Да, это должно быть при использовании GCC, но этот флаг также должен быть установлен по умолчанию на x86-64. Приведенный ниже отрывок из документации относится к GCC 11, но гораздо более старые версии GCC должны демонстрировать такое же поведение. Использование коллекции компиляторов GNU (GCC): 3.19.59 Параметры x86

sse

Используйте скалярные инструкции с плавающей запятой, присутствующие в наборе инструкций SSE. Этот набор команд поддерживается процессорами Pentium III и более новыми, а в линейке AMD - процессорами Athlon-4, Athlon XP и Athlon MP. Более ранняя версия набора инструкций SSE поддерживает только арифметические операции с одинарной точностью, поэтому арифметические операции с двойной и увеличенной точностью по-прежнему выполняются с использованием 387. Более поздняя версия, представленная только в процессорах Pentium 4 и AMD x86-64, поддерживает арифметические операции с двойной точностью. тоже.

Для компилятора x86-32 необходимо использовать переключатели -march=cpu-type , -msse или -msse2 чтобы включить расширения SSE и сделать этот параметр эффективным. Для компилятора x86-64 эти расширения включены по умолчанию.

Результирующий код должен быть значительно быстрее в большинстве случаев и избегать проблем числовой нестабильности кода 387, но может нарушить некоторый существующий код, который ожидает, что временные файлы будут 80-битными.

Это выбор по умолчанию для компилятора x86-64, целей Darwin x86-32 и выбор по умолчанию для целей x86-32 с набором инструкций SSE2, когда включен -ffast-math .

Пример:
XEIGTSTZ <zec.in - сбой из-за потери значимости в ZLAHQR.
Шаги для воспроизведения: ZGET37 -> knt == 31, ZHSEQR -> ZLAHQR -> в конце второго шага QR (ITS == 2) следующий код вызывает недостаточное заполнение (в некоторых регистрах, см. Ниже)

TEMP = H( I, I-1 )
    IF( DIMAG( TEMP ).NE.RZERO ) THEN
        RTEMP = ABS( TEMP)    ! <-- underflow on TEMP = (~1e-0173, ~1e-0173)
        IF (RTEMP .EQ. RZERO) RTEMP = CABS1(TEMP)
        H( I, I-1 ) = RTEMP
        TEMP = TEMP / RTEMP
        IF( I2.GT.I )

Наш компилятор нацелен на .NET CLR. Его JIT решает использовать регистры SSE для ABS (TEMP), что приводит к потере значимости при промежуточном вычислении величины. Ifort (в качестве другого примера) в этой ситуации использует регистры с плавающей запятой, следовательно, не переполняется (из-за своей большей длины: 80 бит). Я пытаюсь получить ясное (э) представление о том, чего ожидать от LAPACK в отношении того, какая точность / диапазон чисел требуется от компилятора / процессора во время выполнения.

Резюмируем:

  • Вы перевели полмиллиона строк Fortran77 на C #.
  • Тестирование транспилированного кода завершается неудачей при использовании JIT-компилятора .NET.
  • Тестирование ванильного кода LAPACK проходит успешно при использовании компилятора Intel Fortran (ifort).
  • Наблюдаемая разница между этими двумя случаями заключается в использовании 80-битных промежуточных продуктов ifort, что позволяет избежать потери значимости.

Верный?

По умолчанию GCC генерирует только код для 64-битных регистров с плавающей запятой на x86-64, и на моих машинах обычно проходят все тесты LAPACK, кроме одного или двух.

Проходит ли набор тестов Netlib LAPACK при компиляции с GCC?

изменить: разрешено https://github.com/Reference-LAPACK/lapack/pull/577#issuecomment -859496175

Возможно, для gfortran мы должны компилировать с флагами -mfpmath = sse -msse2 в целях тестирования. Я думаю, что это заставит все вычисления выполняться с помощью 64-битной арифметики. Хотя я не уверен.

Я пробовал -mfpmath=sse -msse2 с GCC 11 как на MacOS, так и на Linux: https://github.com/weslleyspereira/lapack/actions/runs/966071530. По сравнению с рабочим процессом без этих флагов дополнительных ошибок не было: https://github.com/Reference-LAPACK/lapack/actions/runs/945060330. См. № 591

@hokb , не могли бы вы воспроизвести проблемы переполнения, упомянутые в https://github.com/Reference-LAPACK/lapack/issues/575#issuecomment -855880000, с GCC с использованием флагов SSE? Вы можете мне с этим помочь?

@weslleyspereira Я даже не пробовал GCC. Все, что у меня есть, - это ifort в Windows. Мне потребовалось бы несколько дней, чтобы запустить GCC через cygwin для тестирования (особенно из моего текущего номера в отеле для отдыха ...: |) Дайте мне знать, если вам нужно, чтобы я принял этот вызов!
По крайней мере, согласно https://godbolt.org/z/YYv5oPxe9, использование флагов не влияет на код, сгенерированный gfortran. Но, конечно, только тестовый прогон точно скажет ...

Я не использую окна, но они у меня есть. Я начну с тестирования LAPACK с ifort на моем Ubuntu и посмотрю, что произойдет. Насладиться праздником!

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

5tefan picture 5tefan  ·  3Комментарии

christoph-conrads picture christoph-conrads  ·  26Комментарии

miroi picture miroi  ·  10Комментарии

h-vetinari picture h-vetinari  ·  8Комментарии

pablosanjose picture pablosanjose  ·  41Комментарии