Code Monkey home page Code Monkey logo

symd's Introduction

Symd

C++ header only template library designed to make it easier to write high-performance (vector, multi-threaded), image and data processing code on modern machines. It automatically generates vector (SIMD, SSE, AVX, NEON) code. bfloat16 is supported.

Requirements

C++17 is a requirement.

Compiler

Symd can be used with, g++ and Clang. Visual Studio should be supported but we do not test it for now.

Compiling tests on Ubuntu - g++

To can compile tests with g++ go to tests folder and run:

make

Compiling tests with Clang

If you have Clang installed just got to tests folder and run make clang.

Compiling tests with Visual Studio

  • Start Developer Command Prompt for VS which should come installed with Visual Studio.
  • Navigate to location of Symd project and to tests subfolder.
  • Run make vc.

TBB support

Symd can also be used with Intel's TBB support. To main requirement here is to have TBB installed on your system, which can be achieved in various ways depending on the platform you are on. The next one is setting the TBB switch compile time flag before including the symd library iteself:

#define SYMD_USE_TBB 1
#include "symd.h"
Building tests with TBB on linux

With gcc:

g++ test_symd.cpp test_symd_register.cpp test_stencil_borders.cpp -std=c++17 -ltbb -march=ivybridge -O3 -o test_symd

With clang:

clang++ test_symd.cpp test_symd_register.cpp test_stencil_borders.cpp -std=c++17 -ltbb -mavx -O3 -o test_symd
Building tests with TBB on windows

The easiest way to set up TBB on windows is by using the vcpkg package manager, and then installing TBB library with it. This way no further changes to the build system need to be made in order to run the tests successfully.

CPU

  • Intel or AMD x64 CPU with AVX2 support. Roughly CPUs from 2011 and later.
  • ARM based CPUs with Neon support - still in beta phase.

Usage

Symd is a header-only library. To use Symd in your project you need to:

  • Copy LibSymd/include folder to your project
  • Include symd.h
  • And you are ready to go

Simple map example:

#include <iostream>
#include "../LibSymd/include/symd.h"


void main()
{
    std::vector<int> input = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    std::vector<int> output(input.size());

    symd::map(output, [](auto x) { return x * 2; }, input);

    for (auto x : output)
        std::cout << x << ", ";
}

Output:

2, 4, 6, 8, 10, 12, 14, 16, 18,

Operations on input vetor are performed using SSE, AVX (or Neon TBD).

Can I use 2D inputs?

Yes. You need to wrap your data with 2D data_view. Example:

size_t width = 640;
size_t height = 480;

std::vector<float> input1(width * height);
std::vector<float> input2(input1.size());
std::vector<float> output(input1.size());

auto input1_2d = symd::views::data_view_2d(input1.data(), width, height, width);
auto input2_2d = symd::views::data_view_2d(input2.data(), width, height, width);
auto output_2d = symd::views::data_view_2d(output.data(), width, height, width);

symd::map(output_2d, [&](auto a, auto b) { return a + b; }, input1_2d, input2_2d);

symd::views::data_view is non-owning view of underlying data.

Can I use my own tensor or matrix class as input or output to Symd?

Chances are that you will be using your own tensor/matrix/vector class or some third party class for storing data which are not natively supported by Symd (eg OpenCV matrix). Using such classes as inputs or outputs with Symd is possible. You need to overload methods for getting size of data and accessing elements. Example:

namespace symd::__internal__
{
    template <typename T>
    Dimensions getShape(const MyMatrix<T>& myMatrix)
    {
        return Dimensions({ myMatrix.height(), myMatrix.width() });
    }

    template <typename T>
    Dimensions getPitch(const MyMatrix<T>& myMatrix)
    {
        return  Dimensions({ myMatrix.pitch(), 1 });
    }

    template <typename T>
    T* getDataPtr(MyMatrix<T>& myMatrix, const Dimensions& coords)
    {
        return &myMatrix(coords[1], coords[0]);
    }

    template <typename T>
    const T* getDataPtr(const MyMatrix<T>& myMatrix, const Dimensions& coords)
    {
        return &myMatrix(coords[1], coords[0]);
    }
}

#include "../LibSymd/include/symd.h"


void myMatrixExample()
{
    MyMatrix<float> A(1920, 1080);
    MyMatrix<float> B(1920, 1080);

    MyMatrix<float> res(1920, 1080);

    symd::map(res, [](auto a, auto b) { return a + b;  }, A, B);
}

How can I access nearby elements in the Symd kernel (implement convolution)?

To access nearby elements in Symd kernel, you need to use stencil view (symd::views::stencil). Example:

size_t width = 640;
size_t height = 480;

std::vector<float> input(width * height);
std::vector<float> output(input.size());

auto input_2d = symd::views::data_view_2d(input.data(), width, height, width);
auto output_2d = symd::views::data_view_2d(output.data(), width, height, width);

// Calculate image gradient. We also need 2D stencil view.
symd::map(output_2d, [&](const auto& sv) { return sv(0, 1) - sv(0, -1); },
	symd::views::stencil(input_2d, 3, 3));

How can I perform reduction?

You need to create reduce_view and specify reduce operation. Example:

std::vector<float> input = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18 };

// Reduce operation is summing
auto sum = symd::views::reduce_view(input.size(), 1, 0.0f, [](auto x, auto y)
    {
        return x + y;
    });

After that you map your inputs to reduce_view. That enables you to do some processing of input data prior to reducing.

symd::map(sum, [](auto x) { return x * 2; }, input);

Getting the result of reduction:

float result = sum.getResult();

Maintainers

License

Licensed under the MIT License.

symd's People

Contributors

0508994 avatar nemandza82 avatar nemanjagrujic avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

symd's Issues

Add blocking view

To support operations which take multiple consecutive elements of input collection and/or generate multiple consecutive elements of output collection, Symd bust have something like blocking view.

Examples of such operations are for instance color conversions. Here is example usage of such view:

    size_t width = 1920;
    size_t height = 1080;
    
    std::vector<float> YUV444(width * height * 3);
    std::vector<float> RGB24_mc(YUV444.size());

    symd::map(symd::views::block_view<3,1>(RGB24_mc), [](auto yuv)
          {
                return yuvToRgbKernel(yuv[1], yuv[0], v[2]);

          }, symd::views::block_view<3,1>(YUV444));

symd::views::block_view<3,1>(YUV444) creates block view of input collection where blocks are of 3x1 size.

Optimal implementation could be achieved by implementing block_view, and overriding all necessary view operations (getWidth, getHeight, getPitch, fetchData, fetchVecData, saveData, saveVecData and more).

Fetch and save methods should fetch and save all elements within block so they are accessible within the kernel.

For this we added failing test:

TEST_CASE("Mapping - blocking input YUV444 to RGB")

Which after correct implementation should pass.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.