- PVSM.RU - https://www.pvsm.ru -

Go для больших данных

Go для больших данных - 1

В этом посте мы расскажем об использовании библиотеки ускорения аналитики данных Intel Data Analytics Acceleration Library (Intel DAAL) с языком программирования Go для пакетной, интерактивной и распределенной обработки.

На основе Go [1] построены самые современные инфраструктурные проекты, в том числе Kubernetes [2], Docker [3], Consul [4], etcd [5] и многие другие. Go становится предпочитаемым языком для DevOps, веб-серверов и микрослужб. Этот язык прост в изучении, удобен в развертывании, он очень быстрый, для него есть прекрасный набор инструментов разработки.

Обработка и анализ данных используются в бизнесе все чаще, поэтому приходится внедрять ресурсоемкие вычислительные алгоритмы на всех уровнях инфраструктуры компаний, в том числе и на тех уровнях, где используется язык Go. Возникает закономерный вопрос: как интегрировать такие решения как машинное обучение, распределенное преобразование данных и интерактивный анализ данных в системы на основе Go?

Один из способов надежной, быстрой и масштабируемой обработки данных в Go состоит в использовании библиотеки Intel Data Analytics Acceleration Library [6] (Intel DAAL) в программах Go. Эта библиотека предоставляет алгоритмы пакетной, интерактивной и распределенной обработки для целого ряда полезных задач.

Go для больших данных - 2

Поскольку Go прекрасно взаимодействует с C/C++, можно реализовать эту функциональность в программах Go без особых затруднений. При этом мы существенно выиграем по скорости: эти библиотеки уже оптимизированы для архитектуры Intel. Как показано здесь [7], в определенных операциях, например при анализе основных компонентов, Intel DAAL может работать в семь раз быстрее, чем Spark с MLlib. Это очень здорово! Было бы очень кстати задействовать такую мощь в приложениях Go.

Установка Intel DAAL

Библиотека Intel DAAL доступна в виде открытого исходного кода [8], для ее установки выполните следующие инструкции [9]. На моем компьютере с Linux это было невероятно просто.

  1. Загрузка исходного кода.
  2. Запуск сценария установки.
  3. Настройка необходимых переменных среды (для этого также можно использовать предоставляемый сценарий shell).

Перед интеграцией Intel DAAL в любую программу Go имеет смысл убедиться, что все правильно работает. Для этого можно воспользоваться различными руководствами по началу работы в документации Intel DAAL [9]. В частности, в этих руководствах предоставляется пример приложения Intel DAAL для алгоритма разложения Холецкого [10]. Ниже мы попробуем создать его на языке Go. Исходный пример алгоритма разложения Холецкого на языке C++ выглядит так.

/****************************************************************************
!  Copyright(C) 2014-2017 Intel Corporation. All Rights Reserved.
!
!  The source code, information and material ("Material") contained herein is
!  owned by Intel Corporation or its suppliers or licensors, and title to such
!  Material remains with Intel Corporation or its suppliers or licensors. The
!  Material contains proprietary information of Intel or its suppliers and
!  licensors. The Material is protected by worldwide copyright laws and treaty
!  provisions. No part of the Material may be used, copied, reproduced,
!  modified, published, uploaded, posted, transmitted, distributed or disclosed
!  in any way without Intel's prior express written permission. No license
!  under any patent, copyright or other intellectual property rights in the
!  Material is granted to or conferred upon you, either expressly, by
!  implication, inducement, estoppel or otherwise. Any license under such
!  intellectual property rights must be express and approved by Intel in
!  writing.
!
!  *Third Party trademarks are the property of their respective owners.
!
!  Unless otherwise agreed by Intel in writing, you may not remove or alter
!  this notice or any other notice embedded in Materials by Intel or Intel's
!  suppliers or licensors in any way.
!
!****************************************************************************
!  Content:
!    Cholesky decomposition sample program.
!***************************************************************************/

#include "daal.h"
#include <iostream>

using namespace daal;
using namespace daal::algorithms;
using namespace daal::data_management;
using namespace daal::services;

const size_t dimension = 3;
double inputArray[dimension *dimension] =
{
    1.0, 2.0, 4.0,
    2.0, 13.0, 23.0,
    4.0, 23.0, 77.0
};

int main(int argc, char *argv[])
{
    /* Create input numeric table from array */
    SharedPtr inputData = SharedPtr(new Matrix(dimension, dimension, inputArray));

    /* Create the algorithm object for computation of the Cholesky decomposition using the default method */
    cholesky::Batch<> algorithm;

    /* Set input for the algorithm */
    algorithm.input.set(cholesky::data, inputData);

    /* Compute Cholesky decomposition */
    algorithm.compute();

    /* Get pointer to Cholesky factor */
    SharedPtr<Matrix > factor =
        staticPointerCast<Matrix, NumericTable>(algorithm.getResult()->get(cholesky::choleskyFactor));

    /* Print the first element of the Cholesky factor */
    std::cout << "The first element of the Cholesky factor: " 
<< (*factor)[0][0];

    return 0;
}

Попробуйте скомпилировать и запустить этот код, чтобы убедиться в успешной установке Intel DAAL. Кроме того, так вы получите представление о том, что мы будем делать на языке Go. Любые вопросы и проблемы, связанные с установкой Intel DAAL, можно обсудить на форуме Intel DAAL [11] (лично для меня этот форум оказался исключительно полезным ресурсом, когда я начал пробовать работать с Intel DAAL).

Использование Intel DAAL в программах на языке Go

Если речь идет об использовании библиотеки Intel DAAL в программах на Go, у нас есть несколько возможных вариантов.

  1. Непосредственный вызов библиотеки Intel DAAL из программы Go через функцию-оболочку.
  2. Создание многократно используемой библиотеки с определенной функциональностью Intel DAAL.

Ниже я демонстрирую оба этих подхода. Весь исходный код доступен здесь [12]. Это лишь один пример. Было бы здорово, если бы со временем удалось добавить и другие примеры программ Go с Intel DAAL в это хранилище. При экспериментах, пожалуйста, отправляйте запросы. Мне было бы очень интересно увидеть, что вы создадите.

Если вы раньше не использовали Go, то перед продолжением работы с этой статьей рекомендую получше ознакомиться с этим языком. Отметим, что Go даже не нужно устанавливать на локальный компьютер, чтобы начать его изучать. Можно воспользоваться ознакомлением с Go в Интернете [13] и сайтом Go Playground [14], а уже потом, когда будете готовы, можно установить Go на локальный компьютер [15].

Вызов библиотеки Intel DAAL непосредственно из Go

Go предоставляет инструмент под названием cgo [16], который дает возможность создавать пакеты Go, вызывающие код C. В этом случае мы будем использовать cgo для организации взаимодействия нашей программы Go с библиотекой Intel DAAL.

Кстати, использование cgo с программами Go сопряжено с определенными ограничениями, которые достаточно подробно обсуждаются в Интернете (в частности, см. обсуждение Дейва Чени [17] (Dave Cheney) или эту статью [18] компании Cockroach Labs). Принимая решение об использовании cgo, всегда принимайте во внимания эти ограничения или хотя бы просто помните о них. В данном случае мы готовы примириться с ограничениями cgo, чтобы воспользоваться преимуществами оптимизированной распределенной библиотеки Intel DAAL: эти ограничения с лихвой окупятся повышением производительности в определенных случаях с высокой вычислительной нагрузкой или с большими объемами данных.

Для интеграции алгоритма разложения Холецкого из Intel DAAL в программу Go потребуется создать следующую структуру папок (в директории $GOPATH [19]).
cholesky`
├── cholesky.go`
├── cholesky.hxx`
└── cholesky.cxx`

Файл cholesky.go — это наша программа Go, которая будет использовать алгоритм разложения Холецкого из библиотеки Intel DAAL. Файлы cholesky.cxx и cholesky.hxx — это определения/объявления C++, включающие Intel DAAL и указывающие компилятору cgo, какую функциональность Intel DAAL мы будем использовать. Рассмотрим каждый из них.
Сначала файл *.cxx.

#include "cholesky.hxx"
#include "daal.h"
#include <iostream>

using namespace daal;
using namespace daal::algorithms;
using namespace daal::data_management;
using namespace daal::services;

int choleskyDecompose(int dimension, double inputArray[]) {

    /* Create input numeric table from array */
    SharedPtr inputData = SharedPtr(new Matrix(dimension, dimension, inputArray));

    /* Create the algorithm object for computation of the Cholesky decomposition using the default method */
    cholesky::Batch<> algorithm;

    /* Set input for the algorithm */
    algorithm.input.set(cholesky::data, inputData);

    /* Compute Cholesky decomposition */
    algorithm.compute();

    /* Get pointer to Cholesky factor */
    SharedPtr<Matrix > factor =
        staticPointerCast<Matrix, NumericTable>(algorithm.getResult()->get(cholesky::choleskyFactor));

    /* Return the first element of the Cholesky factor */
    return (*factor)[0][0];
}

Теперь файл *.hxx.


#ifndef CHOLESKY_H
#define CHOLESKY_H

// __cplusplus gets defined when a C++ compiler processes the file.
// extern "C" is needed so the C++ compiler exports the symbols w/out name issues.
#ifdef __cplusplus
extern "C" {
#endif

int choleskyDecompose(int dimension, double inputArray[]);

#ifdef __cplusplus
}
#endif

#endif

Эти файлы определяют функцию-оболочку choleskyDecompose на C++, использующую алгоритм разложения Холецкого Intel DAAL для разложения входной матрицы и вывода первого элемента множителя Холецкого (как в примере, приведенном в руководстве по началу работы с Intel DAAL). Обратите внимание, что в этом случае наши входные данные — это массив длины размерности матрицы (т. е. матрица 3 х 3 соответствует входному массиву длиной 9). Нужно включить extern “C” в файл *.hxx. В этом случае компилятор C++ будет «знать», что нужно экспортировать соответствующие имена, определенные в наших файлах C++.

После определения функции-оболочки разложения Холецкого в файлах *.cxx и *.hxx можно вызвать эту функцию напрямую из Go. cholesky.go выглядит так.

package main

// #cgo CXXFLAGS: -I$DAALINCLUDE
// #cgo LDFLAGS: -L$DAALLIB -ldaal_core -ldaal_sequential -lpthread -lm
// #include "cholesky.hxx"
import "C"

import (
	"fmt"
	"unsafe"
)

func main() {

	// Define the input matrix as an array.
	inputArray := [9]float64{
		1.0, 2.0, 4.0,
		2.0, 13.0, 23.0,
		4.0, 23.0, 77.0,
	}

	// Get the first Cholesky decomposition factor.
	data := (*C.double)(unsafe.Pointer(&inputArray[0]))
	factor := C.choleskyDecompose(3, data)

	// Output the first Cholesky dcomposition factor to stdout.
	fmt.Printf("The first Cholesky decomp. factor is: %dn", factor)
}

Давайте разберем этот процесс поэтапно, чтобы понять, что же тут происходит. Сначала нужно сообщить программе Go, что нужно использовать cgo при компиляции программы, а также нужно компилировать с определенными флагами.

// #cgo CXXFLAGS: -I$DAALINCLUDE
// #cgo LDFLAGS: -L$DAALLIB -ldaal_core -ldaal_sequential -lpthread -lm
// #include "cholesky.hxx"
import "C"

Чтобы использовать, требуется import “C”: это псевдоупаковка, сообщающая об использовании cgo. Если непосредственно перед командой импорта «C» стоит комментарий, то этот комментарий (он называется преамбулой) будет использован в качестве заголовка при компиляции компонентов C++ этого пакета.

С помощью CXXFLAGS и LDFLAGS можно указать флаги компиляции и компоновки, которые cgo должен использовать при компиляции, а нашу функцию C++ можно добавить, используя // #include «cholesky.hxx”. Для компиляции этого примера я использовал Linux и gcc, что и указано выше с помощью соответствующих флагов. Впрочем, можно следовать этому руководству, чтобы определить, как скомпоновать приложение с Intel DAAL.

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

// Define the input matrix as an array.
inputArray := [9]float64{
	1.0, 2.0, 4.0,
	2.0, 13.0, 23.0,
	4.0, 23.0, 77.0,
}

// Get the first Cholesky decomposition factor.
data := (*C.double)(unsafe.Pointer(&inputArray[0]))
factor := C.choleskyDecompose(3, data)

// Output the first Cholesky dcomposition factor to stdout.
fmt.Printf("The first Cholesky decomp. factor is: %dn", factor)

Уникальная особенность в этом случае (она обусловлена использованием cgo) состоит в том, что нужно преобразовать указатель на первый элемент нашего среза float64 в небезопасный указатель, который затем можно будет явным образом преобразовать в указатель *C.double (совместимый с C++) на нашу функцию choleskyDecompose. Упаковка в небезопасный указатель позволяет нам обойти ограничения безопасности типов, действующие в программах Go.
Отлично! Итак, у нас есть программа Go, которая вызвала алгоритм разложения Холецкого из библиотеки Intel DAAL. Теперь пора собрать и запустить эту программу. Это можно сделать обычным образом с помощью go build.

$ ls
cholesky.cxx  cholesky.go  cholesky.hxx
$ go build
$ ls
cholesky  cholesky.cxx  cholesky.go  cholesky.hxx
$ ./cholesky 
The first Cholesky decomp. factor is: 1
$ 

И результат готов! Разумеется, первый множитель разложения Холецкого равен 1. Мы успешно воспользовались библиотекой Intel DAAL непосредственно из Go. Впрочем, наша программа на Go выглядит достаточно странно с небезопасными указателями и фрагментами кода C. Кроме того, это одноразовое решение. Теперь попробуем реализовать эту же функциональность в виде многократно используемого пакета Go, который можно будет импортировать точно так же, как и любой другой пакет Go.

Создание многократно используемого пакета Go с Intel DAAL

Чтобы создать пакет Go, содержащий функциональность Intel DAAL, мы воспользуемся программой SWIG [20]. В Go, помимо использования cgo, можно вызывать SWIG при сборке, чтобы компилировать пакеты Go, реализующие функциональность C/C++. Для такой сборки потребуется создать следующую структуру папок.

choleskylib
├── cholesky.go
├── cholesky.hxx
├── cholesky.cxx
└── cholesky.swigcxx

При этом файлы оболочек *.cxx и *.hxx могут остаться такими же. Но теперь нужно добавить файл *.swigcxx. Этот файл выглядит так.

%{
#include "cholesky.hxx"
%}

%include "cholesky.hxx"

Теперь программа SWIG создает код-оболочку для функции разложения Холецкого, что позволит использовать этот код в качестве пакета Go.

Кроме того, мы создаем пакет Go, пригодный для многократного использования (а не отдельное приложение), поэтому файл *.go может не включать package main или function main. Он должен просто определять имя нашего пакета. В данном случае назовем его cholesky. Теперь cholesky.go будет выглядеть так.

package cholesky

// #cgo CXXFLAGS: -I$DAALINCLUDE
// #cgo LDFLAGS: -L$DAALLIB -ldaal_core -ldaal_sequential -lpthread -lm
import "C"

(Снова указываем файлы в заголовке.)

Теперь можно собрать пакет и установить его локально.

$ ls
cholesky.cxx  cholesky.go  cholesky.hxx  cholesky.swigcxx
$ go install
$ 

Эта команда компилирует все необходимые двоичные файлы и библиотеки, к которым обращается программа Go, использующая этот пакет. Go «видит», что в нашей папке есть файл *.swigcxx, и автоматически использует SWIG для сборки пакета.
Великолепно! Теперь у нас есть пакет Go, использующий Intel DAAL. Посмотрим, как сработают импорт и использование пакета.

package main

import (
	"fmt"

	"github.com/dwhitena/daal-go/choleskylib"
)

func main() {

	// Define the input matrix as an array.
	inputArray := [9]float64{
		1.0, 2.0, 4.0,
		2.0, 13.0, 23.0,
		4.0, 23.0, 77.0,
	}

	// Get the first Cholesky decomposition factor.
	factor := cholesky.CholeskyDecompose(3, &inputArray[0])

	// Output the first Cholesky dcomposition factor to stdout.
	fmt.Printf("The first Cholesky decomp. factor is: %dn", factor)
}

Класс! Такой код намного чище по сравнению с прямым использованием Intel DAAL. Можно импортировать пакет алгоритма Холецкого, как и любой другой пакет Go, и вызвать заключенную в оболочку функцию как cholesky.CholeskyDecompose(...). Кроме того, в SWIG были автоматически обработаны и все небезопасные компоненты. Теперь можно просто передать адрес первого элемента нашего исходного среза float64 в cholesky.CholeskyDecompose(...).

Эту программу, как и любую другую программу на языке Go, можно скомпилировать и запустить командой go build:

$ ls
main.go
$ go build
$ ls
example  main.go
$ ./example 
The first Cholesky decomp. factor is: 1
$ 

Ура! Все правильно. Теперь можно использовать этот пакет в других программах Go, если нам потребуется алгоритм разложения Холецкого.

Выводы и ресурсы

С помощью Intel DAAL, cgo и SWIG нам удалось встроить оптимизированный алгоритм разложения Холецкого в программы на языке Go. Разумеется, возможности не ограничиваются только этим алгоритмом. Аналогичным образом можно создавать программы и пакеты на языке Go, использующие любые алгоритмы, реализованные в Intel DAAL. Можно создавать нейросети с пакетной, интерактивной и распределенной обработкой, кластеризацией, ускорением, совместной фильтрацией и другими возможностями непосредственно в приложениях Go.

Весь использованный выше код доступен здесь [12].

Ресурсы по языку программирования Go

  • Присоединяйтесь к Gophers on Slack [21] и поговорите с другими участниками канала #data-science, которые занимаются большими данными, анализом данных, машинным обучением и прочими аналогичными решениями с помощью Go.
  • Посетите сайт организации GopherData [22], где пользователи взаимодействуют с разработчиками средств управления данными, обработки, анализа, машинного обучения и визуализации данных на языке Go.
  • Отслеживайте GopherData [23] в Twitter.
  • Используйте (и пополняйте) растущий перечень инструментов для Go [24].

Ресурсы по DAAL

Об авторе

Go для больших данных - 3Дэниэл (@dwhitena) — доктор наук, опытный исследователь данных, он работает в компании Pachyderm (@pachydermIO). Он занимается разработкой современных распределенных конвейеров данных, включающих предсказательные модели, визуализацию данных, статистический анализ и другие возможности. Он выступал на конференциях в разных странах мира (ODSC, Spark Summit, Datapalooza, DevFest Siberia, GopherCon b lheubt), преподает исследование и анализ данных в компании Ardan Labs (@ardanlabs), поддерживает ядро Go для Jupyter и активно участвует в развитии различных проектов по интеллектуальному исследованию данных с открытым исходным кодом.

Автор: Виктор Гурылев

Источник [27]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/programmirovanie/264173

Ссылки в тексте:

[1] Go: https://golang.org/

[2] Kubernetes: https://kubernetes.io/

[3] Docker: https://github.com/docker/docker

[4] Consul: https://www.consul.io/

[5] etcd: https://github.com/coreos/etcd

[6] Intel Data Analytics Acceleration Library: https://software.intel.com/en-us/intel-daal

[7] здесь: https://software.intel.com/en-us/blogs/daal

[8] открытого исходного кода: https://01.org/daal

[9] следующие инструкции: https://software.intel.com/en-us/intel-daal-support/documentation

[10] алгоритма разложения Холецкого: https://en.wikipedia.org/wiki/Cholesky_decomposition

[11] форуме Intel DAAL: https://software.intel.com/en-us/forums/intel-data-analytics-acceleration-library

[12] здесь: https://github.com/dwhitena/daal-go

[13] ознакомлением с Go в Интернете: https://tour.golang.org/welcome/1

[14] Go Playground: https://play.golang.org/

[15] установить Go на локальный компьютер: https://golang.org/doc/install

[16] cgo: https://golang.org/cmd/cgo/

[17] обсуждение Дейва Чени: https://dave.cheney.net/2016/01/18/cgo-is-not-go

[18] эту статью: https://www.cockroachlabs.com/blog/the-cost-and-complexity-of-cgo/

[19] $GOPATH: https://golang.org/doc/code.html#GOPATH

[20] SWIG: http://www.swig.org/

[21] Gophers on Slack: https://invite.slack.golangbridge.org/

[22] GopherData: http://gopherdata.io/

[23] GopherData: https://twitter.com/GopherDataIO

[24] инструментов для Go: https://github.com/gopherdata/resources/tree/master/tooling

[25] документацией: https://software.intel.com/en-us/intel-daal/documentation

[26] учебными материалами: https://software.intel.com/en-us/intel-daal-support/training

[27] Источник: https://habrahabr.ru/post/338002/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best