Как создать общую или статическую библиотеку с SYCL с помощью DPC++

Я пытаюсь создать общую библиотеку Linux, которую можно будет распространять и связывать, как любую обычную общую библиотеку. Недавно мы перенесли наши процедуры HPC GPU с CUDA на SYCL, чтобы обеспечить кросс-вендорный подход и создать единый код для GPU и CPU. До сих пор мы использовали DPC++.

Однако нам не удалось заставить DPC++ выполнить фактическую компиляцию перед этапом компоновки. В созданном файле .so отсутствуют все ядра, и его нельзя связать другим компилятором.

Ответ, найденный в этой теме от 2021 года, предполагает, что для создания окончательного двоичного файла следует использовать DPC++:

Создайте статическую или общую библиотеку из программы sycl с помощью dpc++

Однако это нежизнеспособное предложение по нескольким причинам:

  1. Мы не можем требовать от наших конечных пользователей установки проприетарных пакетов компиляторов для связи с нашим кодом.
  2. Это делает невозможным распространение и обновление общей библиотеки (нашего продукта) отдельно от программ, которые ее используют (продуктов наших пользователей).
  3. Поскольку ядра не генерируются до момента компоновки, время компиляции в сотни раз замедляется даже для нашего собственного программного обеспечения (сотни небольших модульных тестов и прикладных программ, которые раньше компоновались за миллисекунды, теперь каждый из которых вызывает перекомпиляцию нашей огромной библиотеки, как .so — это всего лишь оболочка.

В общем, «общие библиотеки», которые мы можем создать с помощью DPC++, вообще не являются разделяемыми библиотеками.

Мы хотим просто сгенерировать фактический окончательный код (ядра хоста+устройства для выбора целей графического процессора и параллельного процессора) в общую библиотеку с API-интерфейсом только для хоста, который никоим образом не раскрывает SYCL (т. е. нет необходимости в компоновщик, чтобы узнать о SYCL). Можно ли создать общую библиотеку, содержащую код SYCL, но являющуюся реальной распространяемой общей библиотекой с полностью скомпилированными ядрами?

Я не могу поверить, что Khronos или Intel разработают флагманский стандарт кросс-платформенных вычислений будущего, который сделает невозможным внедрение общих библиотек. Но ни я, ни мои коллеги не смогли найти способ заставить это работать.

Есть ли способ создать настоящие общие библиотеки с помощью SYCL? Мы уже проделали большую работу по переносу нашего кода на SYCL, прежде чем обнаружили эту кирпичную стену, и нам не хотелось бы тратить все эти усилия на отказ от SYCL и перенос всего на третью модель программирования. Но сейчас это действительно похоже на остановку шоу.

Если невозможно создать распространяемую (разделяемую или статическую) библиотеку, содержащую ядра SYCL, с помощью DPC++, но это можно сделать с помощью другой реализации, такой как AdaptiveCpp, мне также очень интересно узнать, как это сделать.

Огромное спасибо за любую помощь, которую вы можете предложить!

Минимальный пример:

тест.хх:

void hello();

нормальная-lib.cc:

#include "test.hh"

void hello(){ }

sycl-lib.cc:

#include <sycl/sycl.hpp>
#include "test.hh"

void hello(){
    sycl::queue q;
   
    q.submit([](sycl::handler &cgh){
        cgh.single_task([](){
            // We don't need to do anything to trigger the failure,
            // it happens as soon as any SYCL kernel is defined. 
        });
    }).wait();
}

тест-main.cc:

#include "test.hh"

int main() {
    hello();
    return 0;
}

Как воспроизвести:

$ icpx -fPIC -fsycl -fsycl-unnamed-lambda -c sycl-lib.cc 
$ c++ -shared normal-lib.o -o libnormal-lib.so
$ c++ -o normal-test test-main.cc -L. -lnormal-lib
$ ./normal-test 
$ # Perfect, no problem here. Normal libraries work.
$ icpx -fPIC -fsycl -c sycl-lib.cc 
$ icpx -shared sycl-lib.o -o libsycl-lib.so
$ c++ -o sycl-test test-main.cc -L. -lsycl-lib -lsycl
$ ./sycl-test 2>&1 | c++filt
terminate called after throwing an instance of 'sycl::_V1::runtime_error'
  what():  No kernel named typeinfo name for hello()::{lambda(sycl::_V1::handler&)#1}::operator()(sycl::_V1::handler&) const::{lambda()#1} was found -46 (PI_ERROR_INVALID_KERNEL_NAME)
# Problem is here: Why was the kernel code not generated when building the shared library with "icpx -shared"?

Проверяли ли вы официальную документацию Используйте общую библиотеку SYCL со сторонними приложениями? там упоминается как минимум флаг -fsycl-link=image.

dewaffled 06.05.2024 14:16

Спасибо, я прочитал эту ссылку, но -fsycl-link=image — это флаг FPGA, и мы развертываем его на графическом процессоре.

James 06.05.2024 23:16
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
2
136
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Мне удалось воспроизвести вашу проблему, используя компиляторы oneAPI версии 2024.0. Однако, просто изменив команды компиляции и компоновки, все работает как положено:

$ icpx -fPIC -c -fsycl sycl-lib.cc
$ icpx -fsycl -shared sycl-lib.o -o libsycl-lib.so
$ g++ -o sycl-test test-main.cc -L. -lsycl-lib
$ ./sycl-test

Единственное существенное отличие от вашего примера — это замена -lsycl в команде связывания общей библиотеки на -fsycl.

Это замечательно. Я попробую сегодня и отмечу ваш вопрос как ответ, если получится.

James 08.05.2024 10:04

Некоторое объяснение здесь: icpx выполняет несколько дополнительных шагов во время связывания с кодом обработки устройства (GPU). -fsycl инструктирует icpx сделать это, а -lsycl просто связывает библиотеку времени выполнения SYCL.

aland 09.05.2024 04:23

Другие вопросы по теме