Jump to content

МЛИР (программное обеспечение)

МЛИР
Разработчик(и) Группа разработчиков LLVM
Написано в С++
Операционная система Кросс-платформенный
Тип Компилятор
Веб-сайт млир .llvm .org

MLIR — это объединяющая программная среда для разработки компиляторов . [1] MLIR может оптимально использовать различные вычислительные платформы , такие как графические процессоры , DPU , TPU , FPGA , AI ASICS и системы квантовых вычислений (QPU). [2]

MLIR является подпроектом проекта LLVM Compiler Infrastructure и направлен на создание «многоразовой и расширяемой инфраструктуры компилятора (..) и помощи в объединении существующих компиляторов». [3] [4] [5]

Название проекта расшифровывается как Multi-Level Intermediate Representation , в котором ключевое слово multi-level относится к возможности определения нескольких диалектов и прогрессивных преобразований в сторону машинного кода . Эта возможность позволяет MLIR сохранять информацию на более высоком уровне абстракции и выполнять более точный анализ и преобразования, которым в противном случае пришлось бы иметь дело с представлениями более низкого уровня. [6]

Диалекты

[ редактировать ]

Операции представляют собой основной элемент, вокруг которого строятся диалекты. Они идентифицируются по имени, которое должно быть уникальным в пределах диалекта, к которому они принадлежат, и имеют дополнительные операнды , результаты, атрибуты и регионы . Операнды и результаты соответствуют форме статического одиночного присваивания . Каждый результат также имеет связанный тип. Атрибуты представляют собой знания времени компиляции (например, постоянные значения). Регионы состоят из списка блоков, каждый из которых может иметь входные аргументы и содержать список операций. [7] Несмотря на то, что диалекты созданы на основе формы SSA, узлы PHI не являются частью этой конструкции и вместо этого заменяются входными аргументами блоков в сочетании с операндами операций потока управления . [8]

Общий синтаксис операции следующий:

%res:2 = "mydialect.morph"(%input#3) ({            ^bb0(%arg0: !mydialect<"custom_type"> loc("mysource.cc":10:8)):                // nested operations         }) { some.attribute = true, other_attribute = 1.5 }         : (!mydialect<"custom_type">) -> (!mydialect<"other_type">, !mydialect<"other_type">)         loc(callsite("foo" at "mysource.cc":10:8))

В примере показана операция с именем morph , принадлежащая диалекту mydialect , принимающая один входной операнд и выдающая два результата. Входной аргумент имеет связанный тип с именем custom_type , а оба результата имеют типother_type , причем оба типа снова принадлежат диалекту mydialect . У операции также есть два связанных атрибута — с именами some.attribute иother_attribute и область, содержащая один блок. Наконец, с помощью ключевого слова loc добавляются местоположения для целей отладки . [9]

Синтаксис операций, типов и атрибутов также можно настроить в соответствии с предпочтениями пользователя путем реализации соответствующих синтаксического анализа и печати функций в определении операции. [10]

Основные диалекты

[ редактировать ]

Экосистема диалектов MLIR открыта и расширяема, а это означает, что конечные пользователи могут свободно создавать новые диалекты, отражающие необходимую им семантику. Тем не менее, кодовая база MLIR уже предоставляет конечным пользователям доступ к различным типам диалектов. Каждый из них направлен на рассмотрение определенного аспекта, который часто проявляется в промежуточных представлениях , но делает это автономным образом. Например, диалект арифита поддерживает простые математические операции над целочисленными значениями и значениями с плавающей запятой , а диалект memref содержит операции по управлению памятью. [11]

Следующий код определяет функцию, которая принимает две матрицы с плавающей запятой и выполняет суммирование значений в одних и тех же позициях:

func.func @matrix_add(%arg0: memref<10x20xf32>, %arg1: memref<10x20xf32>) -> memref<10x20xf32> {    %result = memref.alloc() : memref<10x20xf32>	affine.for %i = 0 to 10 {		affine.for %j = 0 to 20 {			%lhs = memref.load %arg0[%i, %j] : memref<10x20xf32>			%rhs = memref.load %arg1[%i, %j] : memref<10x20xf32>			%sum = arith.addf %lhs, %rhs : f32			memref.store %sum, %result[%i, %j] : memref<10x20xf32>		}	}        func.return %result : memref<10x20xf32>}

Для достижения одного и того же результата могут использоваться разные диалекты, и каждый из них может подразумевать разные уровни абстракции. В этом примере аффинный диалект был выбран для повторного использования существующих анализов и оптимизаций для многогранной компиляции . [11]

Одним из соответствующих основных диалектов является LLVM. Его цель — предоставить однозначное отображение LLVM-IR — промежуточного представления, используемого LLVM, — чтобы обеспечить возможность повторного использования всех его промежуточных и внутренних преобразований, включая генерацию машинного кода. [12]

Спецификация определения операции

[ редактировать ]

Операции диалекта можно определить с помощью языка C++ , а также более удобным и надежным способом с помощью спецификации определения операции (ODS). [13] Используя TableGen, можно автоматически генерировать код C++ для объявлений и определений. [14]

Автоматически сгенерированный код может включать методы синтаксического анализа и печати, которые основаны на простом сопоставлении строк со структурой желаемого текстового представления, вместе со всем шаблонным кодом для доступа к полям и выполнения общих действий, таких как проверка семантики каждой операции, канонизация или свертывание. . [15]

Тот же механизм объявления можно использовать и для типов и атрибутов, которые являются двумя другими категориями элементов, составляющих диалект. [15]

В следующем примере показано, как указать ассемблерный формат операции, ожидающей вариативное количество операндов и дающей нулевые результаты. Текстовое представление состоит из необязательного списка атрибутов, за которым следует необязательный список операндов, двоеточие и типы операндов. [13]

let assemblyFormat = "attr-dict ($operands^ `:` type($operands))?";

Преобразования

[ редактировать ]

Преобразования всегда можно выполнять непосредственно на IR, не полагаясь на встроенные механизмы координации. Однако, чтобы упростить внедрение и обслуживание, MLIR предоставляет инфраструктуру для перезаписи IR, состоящую из различных драйверов перезаписи. Каждый драйвер получает набор объектов , называемых шаблонами , каждый из которых имеет собственную внутреннюю логику для сопоставления операций с определенными свойствами. При совпадении операции выполняется процесс перезаписи, и IR изменяется в соответствии с логикой шаблона. [16]

Драйвер преобразования диалектов

[ редактировать ]

Этот драйвер действует в соответствии с законностью существующих операций. Это означает, что драйвер получает набор правил, определяющих, какие операции следует считать незаконными , и ожидает, что шаблоны совпадут и преобразуют их в законные . Логика этих правил может быть сколь угодно сложной: она может основываться только на диалекте, к которому принадлежат операции, но также может проверять более конкретные свойства, такие как атрибуты или вложенные операции. [17]

Как следует из названия, этот драйвер обычно используется для преобразования операций одного диалекта в операции, принадлежащие другому диалекту. В этом сценарии весь исходный диалект будет помечен как незаконный, а целевой — как легальный, и будут предоставлены шаблоны для операций с исходным диалектом. Платформа преобразования диалектов также обеспечивает поддержку преобразования типов, которое необходимо выполнить для операндов и результатов, чтобы преобразовать их в систему типов целевого диалекта. [17]

MLIR позволяет использовать несколько путей преобразования. Учитывая пример суммы матриц, возможной стратегией понижения может быть создание циклов for, принадлежащих диалекту scf , с получением кода для выполнения на процессорах :

#map = affine_map<(d0, d1) -> (d0, d1)>module {    func.func @avg(%arg0: memref<10x20xf32>, %arg1: memref<10x20xf32>) -> memref<10x20xf32> {        %alloc = memref.alloc() : memref<10x20xf32>        %c0 = arith.constant 0 : index        %c10 = arith.constant 10 : index        %c1 = arith.constant 1 : index                scf.for %arg2 = %c0 to %c10 step %c1 {            %c0_0 = arith.constant 0 : index            %c20 = arith.constant 20 : index            %c1_1 = arith.constant 1 : index                        scf.for %arg3 = %c0_0 to %c20 step %c1_1 {                %0 = memref.load %arg0[%arg2, %arg3] : memref<10x20xf32>                %1 = memref.load %arg1[%arg2, %arg3] : memref<10x20xf32>                %2 = arith.addf %0, %1 : f32                memref.store %2, %alloc[%arg2, %arg3] : memref<10x20xf32>            }        }                return %alloc : memref<10x20xf32>    }}

Однако другой возможной стратегией могло бы быть использование диалекта графического процессора для генерации кода для графических процессоров :

#map = affine_map<(d0, d1) -> (d0, d1)>module {    func.func @avg(%arg0: memref<10x20xf32>, %arg1: memref<10x20xf32>) -> memref<10x20xf32> {        %alloc = memref.alloc() : memref<10x20xf32>        %c0 = arith.constant 0 : index        %c10 = arith.constant 10 : index        %0 = arith.subi %c10, %c0 : index        %c1 = arith.constant 1 : index        %c0_0 = arith.constant 0 : index        %c20 = arith.constant 20 : index        %1 = arith.subi %c20, %c0_0 : index        %c1_1 = arith.constant 1 : index        %c1_2 = arith.constant 1 : index                gpu.launch blocks(%arg2, %arg3, %arg4) in (%arg8 = %0, %arg9 = %c1_2, %arg10 = %c1_2) threads(%arg5, %arg6, %arg7) in (%arg11 = %1, %arg12 = %c1_2, %arg13 = %c1_2) {            %2 = arith.addi %c0, %arg2 : index            %3 = arith.addi %c0_0, %arg5 : index            %4 = memref.load %arg0[%2, %3] : memref<10x20xf32>            %5 = memref.load %arg1[%2, %3] : memref<10x20xf32>            %6 = arith.addf %4, %5 : f32            memref.store %4, %alloc[%2, %3] : memref<10x20xf32>            gpu.terminator        }                return %alloc : memref<10x20xf32>    }}

Драйвер перезаписи жадного шаблона

[ редактировать ]

Драйвер жадно применяет предоставленные шаблоны в соответствии с их выгодой, пока не будет достигнута фиксированная точка или не будет достигнуто максимальное количество итераций. Преимущество шаблона присваивается самому себе. В случае равенства используется относительный порядок в списке шаблонов. [16]

Особенности и интерфейсы

[ редактировать ]

MLIR позволяет применять существующие оптимизации (например, устранение общих подвыражений , перемещение кода, инвариантного к циклу ) к пользовательским диалектам с помощью признаков и интерфейсов. Эти два механизма позволяют проходам преобразования работать с операциями, не зная их фактической реализации, полагаясь только на некоторые свойства, предоставляемые типажами или интерфейсами. [18] [19]

Трейты предназначены для прикрепления к операциям без необходимости какой-либо дополнительной реализации. Их цель — указать, что операция удовлетворяет определенным свойствам (например, имеет ровно два операнда). [18] Вместо этого интерфейсы представляют собой более мощный инструмент, с помощью которого можно запросить операцию о каком-то конкретном аспекте, значение которого может меняться между экземплярами операции одного и того же типа. Примером интерфейса является представление эффектов памяти: к каждой операции, которая работает с памятью, может быть прикреплен такой интерфейс, но фактические эффекты могут зависеть от реальных операндов (например, вызов функции с аргументами, которые могут быть константами или ссылками на память). [19]

Приложения

[ редактировать ]

Свобода моделирования промежуточных представлений позволяет использовать MLIR в широком диапазоне сценариев. Сюда входят традиционные языки программирования, [20] но и синтез высокого уровня , [21] [22] квантовые вычисления [23] и гомоморфное шифрование . [24] [25] [26] Приложения машинного обучения также используют преимущества встроенных методов многогранной компиляции вместе с диалектами, ориентированными на ускорители и другие гетерогенные системы . [27] [28] [29] [30] [31]

См. также

[ редактировать ]
  1. ^ Ахо, Альфред В.; Сетхи, Рави; Уллман, Джеффри Д. (2002). Составители: принципы, методы и инструменты . Серия Аддисона-Уэсли по информатике (перепечатано с корр., [36. Драк] под ред.). Ридинг, Массачусетс: Аддисон-Уэсли. ISBN  978-0-201-10088-4 .
  2. ^ «Почему Моджо» . docs.modular.com . Модульная Инк. 2023 . Проверено 28 августа 2023 г. Сильной стороной MLIR является его способность создавать компиляторы для конкретной предметной области, особенно для странных областей, которые не являются традиционными процессорами и графическими процессорами, таких как AI ASICS, системы квантовых вычислений, FPGA и специальные микросхемы.
  3. ^ «Инфраструктура компилятора LLVM» . ЛЛВМ . Проверено 1 октября 2023 г. Подпроект MLIR — это новый подход к созданию повторно используемой и расширяемой инфраструктуры компилятора. MLIR направлен на решение проблемы фрагментации программного обеспечения, улучшение компиляции для гетерогенного оборудования, значительное снижение стоимости создания компиляторов для конкретной предметной области и помощь в объединении существующих компиляторов.
  4. ^ Латтнер, Крис; Амини, Мехди; Бондугула, Удай; Коэн, Альберт; Дэвис, Энди; Пиенаар, Жак; Риддл, Река; Шпейсман, Татьяна; Василаче, Николя; Зиненко, Александр (2021). «MLIR: инфраструктура масштабируемого компилятора для вычислений в конкретной области». Международный симпозиум IEEE/ACM по генерации и оптимизации кода (CGO) 2021 года . стр. 2–14. дои : 10.1109/CGO51591.2021.9370308 . ISBN  978-1-7281-8613-9 .
  5. ^ Мерник, Марьян; Хиринг, Ян; Слоан, Энтони М. (декабрь 2005 г.). «Когда и как разрабатывать предметно-ориентированные языки» . Обзоры вычислительной техники ACM . 37 (4): 316–344. дои : 10.1145/1118890.1118892 . ISSN   0360-0300 . S2CID   207158373 .
  6. ^ Зайдль, Гельмут; Вильгельм, Рейнхард; Хак, Себастьян (2012). Проектирование компилятора: анализ и преобразование . Берлин Нью-Йорк: Спрингер. ISBN  978-3-642-17548-0 .
  7. ^ «Справочник по языку MLIR — MLIR» . mlir.llvm.org . Проверено 5 июля 2023 г.
  8. ^ «Обоснование MLIR – MLIR» . mlir.llvm.org . Проверено 5 июля 2023 г.
  9. ^ Мехди, Амини; Река, Риддл. «Учебное пособие по MLIR» (PDF) .
  10. ^ Страуструп, Бьярне (2015). Язык программирования C++: C++ 11 (4-е изд., 4-е печатное изд.). Река Аппер-Сэддл, Нью-Джерси: Аддисон-Уэсли. ISBN  978-0-321-56384-2 .
  11. ^ Перейти обратно: а б «Диалекты – МЛИР» . mlir.llvm.org . Проверено 7 июля 2023 г.
  12. ^ «Справочное руководство по языку LLVM — документация LLVM 17.0.0git» . llvm.org . Проверено 5 июля 2023 г.
  13. ^ Перейти обратно: а б «Спецификация определения операции (ODS) — MLIR» . mlir.llvm.org . Проверено 5 июля 2023 г.
  14. ^ «Обзор TableGen — документация LLVM 17.0.0git» . llvm.org . Проверено 5 июля 2023 г.
  15. ^ Перейти обратно: а б «Определение диалектов – MLIR» . mlir.llvm.org . Проверено 7 июля 2023 г.
  16. ^ Перейти обратно: а б «Переписывание шаблонов: общее переписывание DAG-to-DAG — MLIR» . mlir.llvm.org . Проверено 6 июля 2023 г.
  17. ^ Перейти обратно: а б «Преобразование диалектов – МЛИР» . mlir.llvm.org . Проверено 6 июля 2023 г.
  18. ^ Перейти обратно: а б «Черты – МЛИР» . mlir.llvm.org . Проверено 5 июля 2023 г.
  19. ^ Перейти обратно: а б «Интерфейсы — МЛИР» . mlir.llvm.org . Проверено 5 июля 2023 г.
  20. ^ Моисей, Уильям С.; Челини, Лоренцо; Чжао, Руйжэ; Зиненко, Александр (2021). Полигейст: повышение C до многогранного MLIR . 30-я Международная конференция по параллельным архитектурам и методам компиляции (PACT). стр. 45–59. дои : 10.1109/PACT52795.2021.00011 . ISBN  978-1-6654-4278-7 .
  21. ^ Агостини, Николя Бом; Керзель, Серена; Аматья, Винай; Тан, Ченг; Минуты, Марко; Кастеллана, Вито Джованни; Мансано, Джозеф; Каэли, Дэвид; Тумео, Антонино (30 октября 2022 г.). «Блок-компилятор на основе MLIR для проектирования на системном уровне и аппаратного ускорения» . Материалы 41-й Международной конференции IEEE/ACM по компьютерному проектированию . Ассоциация вычислительной техники. стр. 1–9. дои : 10.1145/3508352.3549424 . ISBN  978-1-4503-9217-4 .
  22. ^ Руйжэ, Чжао; Цзяньи, Ченг (2021). «Физма: многогранный синтез высокого уровня в MLIR». arXiv : 2103.15103 [ cs.PL ].
  23. ^ Маккаски, Александр; Нгуен, Тьен (октябрь 2021 г.). «Диалект MLIR для квантовых языков ассемблера». Международная конференция IEEE по квантовым вычислениям и инженерии (QCE) 2021 года . IEEE. стр. 255–264. arXiv : 2101.11365 . дои : 10.1109/QCE52317.2021.00043 . ISBN  978-1-6654-1691-7 . S2CID   231718965 .
  24. ^ Пак, Сунджэ; Сон, Усон; Нам, Сынхён; Ким, Хёнъю; Шин, Джунбум; Ли, Джунён (6 июня 2023 г.). «HEaaN.MLIR: оптимизирующий компилятор для быстрого кольцевого гомоморфного шифрования» . Труды ACM по языкам программирования . 7 (ПЛДИ): 196–220. дои : 10.1145/3591228 . ISSN   2475-1421 .
  25. ^ Говиндараджан, Санат; Мозес, Уильям С. «SyFER-MLIR: интеграция полностью гомоморфного шифрования в структуру компилятора MLIR» (PDF) .
  26. ^ «НАСЛЕДНИК: Промежуточное представление гомоморфного шифрования» . Гитхаб . Проверено 5 сентября 2023 г.
  27. ^ Джин, Дин; Берча, Джордж-Теодор; Ле, Тунг Д.; Чен, Тонг; Су, Гонг; Имаи, Харуки; Негиси, Ясуси; Леу, Ань; О'Брайен, Кевин; Кавачия, Киёкуни; Эйхенбергер, Александр Э. (2020). «Компиляция моделей нейронных сетей ONNX с использованием MLIR». arXiv : 2008.08272 [ cs.PL ].
  28. ^ Пиенаар, Жак (2020), MLIR в экосистеме TensorFlow , получено 6 июля 2023 г.
  29. ^ Ху, Пэнчао; Лу, Человек; Ван, Лей; Цзян, Гоюэ (2022). «ТПУ-MLIR: компилятор для ТПУ с использованием MLIR». arXiv : 2210.15016 [ cs.PL ].
  30. ^ Катель, Навдип; Хандельвал, Вивек; Бондугула, Удай (19 марта 2022 г.). «Генерация кода на основе MLIR для тензорных ядер графического процессора». Материалы 31-й Международной конференции ACM SIGPLAN по построению компиляторов . АКМ. стр. 117–128. дои : 10.1145/3497776.3517770 . ISBN  978-1-4503-9183-2 . S2CID   247522110 .
  31. ^ Бик, Аарт; Коанантакул, Пенпорн; Шпейсман, Татьяна; Василаче, Николя; Чжэн, Бися; Кьёлстад, Фредрик (31 декабря 2022 г.). «Поддержка компилятора для разреженных тензорных вычислений в MLIR» . Транзакции ACM по оптимизации архитектуры и кода . 19 (4): 1–25. arXiv : 2202.04305 . дои : 10.1145/3544559 . ISSN   1544-3566 . S2CID   246680261 .
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: 1812520af5fa7aeef20de4de892592f1__1719055380
URL1:https://arc.ask3.ru/arc/aa/18/f1/1812520af5fa7aeef20de4de892592f1.html
Заголовок, (Title) документа по адресу, URL1:
MLIR (software) - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)