Блог F-SEPS
Раньше я был уверен, что, возможно, самая крутая в мире 🙂 математическая библиотека Intel MKL – полностью коммерческая и с чистой совестью пользоваться ей можно только купив лицензию у Intel. Однако, разбираясь со свободными (совершенно бесплатными) системами для научных вычислений, я обнаружил, что Intel MKL входит в состав некоторых из них и используется там как основной решатель для СЛАУ, а также других задач. Как минимум, она входит:
в библиотеки NumPy и SciPy в составе дистрибутива Anaconda Python;
в SciLAB (известная MatLAB-подобная свободная система компьютерной математики).
Пойдя на сайт Intel, я увидел, что и оттуда можно скачать MKL совершенно бесплатно. Скачав, я открыл прилагающийся файл о лицензии и прочитал:
- Redistributions must reproduce the above copyright notice and the following terms of use in the Software and in the documentation and/or other materials provided with the distribution.
- Neither the name of Intel nor the names of its suppliers may be used to endorse or promote products derived from this Software without specific prior written permission.
- No reverse engineering, decompilation, or disassembly of this Software is permitted.
Я не юрист, но из этого по-моему следует, что я имею полное право пользоваться MKL и даже ее распространять, если уведомлю в документации на свою программу, что копирайт MKL принадлежит Intel.
Видимо, разработчики Anaconda Python и SciLAB так и делают.
Конечно, если действительно на MKL придется завязать какие-то коммерческие проекты, этот вопрос потребует более глубокого юридического изучения. Для меня подобные юридические вопросы – полные дебри. Тут должны разбираться специальные люди. Но надеюсь, что простое экспериментирование с MKL, так же как и расчеты в NumPy и SciLAB, прав Intel не нарушают. 🙂
Мои «околонаучные» проекты в основном сделаны в GFortran. А Intel MKL для Windows, к сожалению, тесно интегрирована только с Intel Fortran, который уже точно коммерческий и весьма недешевый. (Под Linux MKL официально работает в том числе и с компиляторами GCC).
Подключить Intel MKL к GFortran в Windows на первый взгляд казалось нетривиальной задачей, но, после определенного разбирательства, это у меня получилось. Как – хочу зафиксировать ниже. Если потом все-таки окажется, что юридически это делать нельзя :), Intel MKL всегда можно заменить на OpenBLAS. Как он подключается – тоже запишу здесь для удобства. (Сказанное относится к библиотекам LAPACK и BLAS – больше мне из MKL пока не нужно).
Intel MKL в GFortrаn
Дистрибутив Intel MKL содержит скомпилированные библиотеки .dll , а также библиотеки .lib для компиляции и линковки в Intel Fortran и среде MS Visual Studio.
Мы не используем Visual Studio, а работаем с GFortrаn в составе компиляторов GCC. В принципе, GCC работает и с библиотеками .lib . Однако, корректно подключить все нужные для компиляции MKL .lib к GFortrаn – не получается. Судя по форумам, не у меня одного. Поэтому, чтобы вызывать из нашей программы MKL, попробуем подготовить библиотеки в родном для GCC формате .a и ограничимся динамическим связыванием. В принципе, .a содержит дистрибутив Intel MKL для Linux (я не поленился, установил MKL в Ubuntu), но .a в Ликунсе и в Виндовсе – несовместимы.
Нам надо получить из .dll и .lib библиотеки .a . Это возможно. Оказалось, что проще не использовать для этого .lib вообще. Библиотеки .a можно сделать просто из *.dll . Правда, это будут библиотеки только для динамической компоновки. Т.е. чтобы наша программа работала, в системе должно иметься несколько *.dll с Intel MKL. Кстати, если у нас инсталлирована, например, Anaconda Python, то все необходимые *.dll библиотеки с ней уже установлены.
Итак, у нас есть ряд .dll с Intel MKL. Их можно взять как из Anaconda Python, так и из официального дистрибутива Intel MKL, скачанного с их сайта. Первое, по-моему, даже проще т.к. на сайте Intel нужна регистрация.
Оказалось, что нужные нам функции LAPACK и BLAS в привычном формате вызова содержатся конкретно в файле mkl_rt.dll . Чтобы посмотреть, какие функции входят в *.dll есть разные утилиты. Проще всего воспользоваться утилитой dumpbin.exe из состава Visual Studio:
Она выдает следующее:
Ниже по списку упоминаются привычные функции LAPACK dgesv , dposv и другие.
Чтобы сделать библиотеку *.a из *.dll сначала надо сформировать текстовый файл .def со списком названий функций, т.е. из того, что обведено красным. В начале этого файла надо написать слово EXPORTS . Т.е. файл .def должен выглядеть так:
Файл .def можно сформировать из того, что вывел dumpbin.exe руками, а можно сделать скрипт, например, на питоне (привожу его ниже).
Получив .def , осталось сформировать библиотеку *.a (она должна иметь префикс lib и суффикс .dll ) с помощью утилиты dlltool.exe из состава GCC:
Вот скрипт на Питоне, который делает все описанное. Чтобы он работал в системе должны быть доступны dumpbin.exe и dlltool.exe . Кстати, чтобы это проверить, в Windows можно набрать where dumpbin – система выведет путь, где он лежит, либо скажет, что не находит такого.
Полученный файл *.a надо положить туда, где GCC хранит свои библиотеки, либо в папку с нашими собственными библиотеками, например, C:\gcc\mylibs .
В принципе, это все. Проверим как все работает.
Протестируем MKL на примере из прошлого поста с тестом решения СЛАУ.
Тестовая программа на Фортране (в скоростном варианте с \(LL^T\) -разложением) выглядит так (файл LinTest.f90 ):
Условно статическая компиляция (пусть наша библиотека libmkl_rt.dll.a лежит в C:\gcc\mylibs ):
Запуская программу, получаем:
Время 0,33 с – точно такое же как и у лидера прошлого теста Intel Fortran + MKL .
Размер LinTest.exe получился 595 КБ (компилятор был из GCC 6.3.0 из дистрибутива MinGW64). В него статически прилинковались все библиотеки, кроме .dll -библиотек MKL.
Какие в принципе .dll нужны для работы нашей программы? Если мы хотим, чтобы наша программа работала на другой машине, не имеющей установленную Анаконду или другой вариант MKL, надо будет скопировать и обеспечить доступность 5-ти файлов:
100 МБ – конечно, не мало. Это вариант с последним дистрибутивом MLK с сайта Intel, версия 2017.2.187. Из дистрибутива Анаконды набегает поменьше – «всего» 86 МБ. Современный софт, он такой. 🙂
Полностью динамическая компиляция (убираем ключ -static ):
LinTest.exe получился крошечный – 57 КБ, но теперь для работы потребуются еще три .dll из GCC (данные для версии 6.3.0):
OpenBLAS в GFortrаn
Установить OpenBLAS – куда проще.
Скачиваем с официального сайта уже скомпилированные бинарные файлы в архиве OpenBLAS-v0.2.19-Win64-int32.zip (версия для 64-разрядных машин).
Переписываем файлы libopenblas.a и libopenblas.dll.a туда, где GCC хранит свои библиотеки, либо в папку с нашими собственными библиотеками, например, C:\gcc\mylibs .
Статическая компиляция (пусть наши библиотеки *.a лежат в C:\gcc\mylibs ):
Время на 48% больше, чем с Intel Fortran + MKL , но на самом деле тоже очень достойное.
Размер файла LinTest.exe , правда, громадный: 26 МБ.
Динамическая компиляция (убираем -static и добавляем к -lopenblas суффикс .dll ):