Авторы Стефан Верховен, Фарук Диблен, Юрриан Х. Спаакс, Адам Беллум и Кристиан Мейер.

Допустим, у вас есть код C ++, который вы хотели бы сделать доступным для более широкой аудитории, разместив его в Интернете как готовый веб-инструмент. До недавнего времени это было довольно сложно, и, возможно, даже потребовалось переопределить программное обеспечение на JavaScript, языке программирования, который используют браузеры.

Разве не было бы замечательно, если бы вы могли запускать существующий код C ++ в Интернете с минимальными усилиями?

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

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

Поиск корня

Итак, сегодняшняя цель - создать простое веб-приложение, которое определяет корень математической функции 2x³ - 4x² + 6, то есть значение x, где y = 0 .

Для этого мы будем использовать итерационный метод, известный как метод поиска корня Ньютона-Рафсона. Помните Ньютона? Спокойный парень, шикарные волосы? Да, тот Ньютон. Принцип работы Ньютона-Рафсона заключается в том, что вы даете ему уравнение, корень которого вы хотите найти, вместе с производной этого уравнения. Затем вы берете initial_guess того, что, по вашему мнению, может быть значение корня, а затем позволяете методу итеративно продвигаться к решению. Решение является приблизительным в пределах tolerance, которое вы также можете установить. В любом случае, алгоритм написан на C ++, но с некоторыми хитростями мы сможем использовать этот код C ++ из браузера, без необходимости сначала его переносить!

Теперь, прежде чем вы скажете Это будет намного медленнее, чем запускать его в исходном коде! или C ++ из браузера? Невозможно! , просто задержите лошадей на секунду. При наличии подходящих инструментов можно запускать код C ++ в браузере с приемлемым снижением производительности. Например, Габриэлю Кувилье удалось запустить видеоигру Doom 3 в браузере. Он смог сделать это, скомпилировав исходный код игры в WebAssembly, низкоуровневый язык, на котором могут работать браузеры. И если он работает для видеоигр, он, вероятно, будет работать и для вашего исследовательского программного обеспечения.

Что нам понадобится

Хорошо, теперь, когда вы полностью согласны с этим, давайте приступим к делу. Вот список того, что нам нужно:

  1. Мы собираемся написать небольшую HTML-страницу, поэтому вам потребуются базовые знания HTML и JavaScript.
  2. Немного кода C ++ для иллюстрации процесса. Мы будем использовать наш код Newton-Raphson C ++.
  3. Программа, которая может взять наш существующий код C ++ и скомпилировать его в модуль WebAssembly. Для этого мы воспользуемся emcc компилятором Emscripten, самым популярным из всех компиляторов C ++ в WebAssembly.
  4. Чтобы использовать функциональность WebAssembly из JavaScript, требуется привязка. Привязка сопоставляет конструкции C ++ с их эквивалентом в JavaScript и обратно. Для этого воспользуемся embind.
  5. Веб-сервер для обслуживания наших файлов. Мы будем использовать http.server Python 3, но и другие веб-серверы работают так же хорошо.

Связывая все вместе

Код C ++

Вот уравнение, корень которого мы хотим найти вместе с его производной, поскольку именно этого требует Ньютон-Рафсон:

В приведенном ниже фрагменте показано содержимое файла newtonraphson.hpp. Это файл заголовка для итеративного алгоритма поиска корня Ньютона-Рафсона. Он определяет класс с именем NewtonRaphson. Помимо метода конструктора NewtonRaphson(float tolerance_in), у NewtonRaphson есть еще один открытый метод, solve, который принимает float и возвращает другой float. Кроме того, NewtonRaphson также имеет закрытый член tolerance типа float, который используется для хранения закрытых данных экземпляра класса.

Файл newtonraphson.cpp содержит соответствующую реализацию:

Исходя из этого определения, экземпляры NewtonRaphson должны быть инициализированы значением tolerance_in, которое затем сохраняется как закрытый член tolerance. После создания экземпляра объекта пользователи могут вызывать его метод solve для итеративного поиска корня equation, при этом equation и его derivative импортируются из problem.hpp через строку include вверху.

Проверить в командной строке

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

Наша программа командной строки может быть скомпилирована с помощью:

g++ -o cli.exe problem.cpp cli.cpp newtonraphson.cpp

При последующем запуске он должен выдать следующий результат:

./cli.exe
The value of the root is : -1.00

Теперь мы готовы перейти к части WebAssembly.

Привязка

Чтобы использовать код Ньютона-Рафсона из JavaScript, нам нужно определить файл привязок. Привязка позволяет вызывать скомпилированный код из JavaScript. Для нашего кода Ньютона-Рафсона файл привязки выглядит так:

В файле привязки используются embind операторы привязки, чтобы раскрыть класс NewtonRaphson, его метод конструктора, а также его открытый метод solve.

Компиляция в WebAssembly

Для начала нам нужно скачать и установить Emscripten, чтобы получить компилятор. Исходный код Newton-Raphson и его привязка могут быть скомпилированы в модуль WebAssembly с помощью компилятора Emscripten emcc следующим образом:

emcc -I. -o newtonraphson.js -Oz -s MODULARIZE=1 \
 -s EXPORT_NAME=createModule --bind \
 problem.cpp newtonraphson.cpp bindings.cpp

Это сгенерирует модуль WebAssembly newtonraphson.wasm вместе с файлом JavaScript newtonraphson.js. Мы также экспортируем функцию createModule JavaScript в команду компиляции, чтобы ее можно было использовать для загрузки и инициализации модуля WebAssembly. Используя библиотеку newtonraphson.js JavaScript, мы можем найти корень математической функции и впоследствии отобразить его значение в следующем HTML-коде:

Размещение приложения на веб-сервере

Нам понадобится веб-сервер для отображения HTML-страницы в веб-браузере. Для этого мы воспользуемся модулем http.server из Python 3 для размещения всех файлов в текущем каталоге на порту 8000, например:

# change to directory with index.html and newtonraphson.* files
python3 -m http.server 8000

На рисунке вверху статьи корень уравнения должен находиться в x = -1.00. Посетите http: // localhost: 8000 /, чтобы узнать, показывает ли ваш браузер правильный результат.

Резюме

  1. Мы написали простой алгоритм на C ++
  2. Мы определили интерфейс JavaScript, написав привязки Emscripten.
  3. Скомпилировали алгоритм и привязки к модулю WebAssembly с помощью компилятора Emscripten.
  4. Мы запустили алгоритм в веб-браузере, используя некоторый JavaScript для взаимодействия с модулем WebAssembly.

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

Свяжись с нами

Этот блог был написан группой обобщения Нидерландского центра электронной науки. В команду входят Стефан Верховен, Фарук Диблен, Юрриан Х. Спаакс, Адам Беллум и Кристиан Мейер. Не стесняйтесь обращаться к группе обобщения по адресу [email protected].

Куда пойти отсюда?

В следующих блогах мы расскажем:

Мы завершим эту серию последним блогом, в котором темы всей серии объединены в полнофункциональное веб-приложение. Если вам интересно, как это будет выглядеть, обязательно посмотрите живую демонстрацию на страницах GitHub.

Если вам понравилась эта статья, оставьте комментарий и аплодируйте нам!

Эти блоги были написаны в рамках проекта Передача XSAMS. Чтобы узнать больше о проекте, загляните на его страницу проекта. Спасибо нашим корректорам Ян ван Дейк, Даан Бур, Лоуренс Вин и Патрик Бос.