Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add NSIMD 2.2 #6790

Merged
merged 14 commits into from
Sep 10, 2021
7 changes: 7 additions & 0 deletions recipes/nsimd/2.x/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
cmake_minimum_required(VERSION 3.1)
project(cmake_wrapper)

include(conanbuildinfo.cmake)
conan_basic_setup()

add_subdirectory("source_subfolder")
4 changes: 4 additions & 0 deletions recipes/nsimd/2.x/conandata.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
sources:
"2.2":
url: "https://github.com/agenium-scale/nsimd/archive/v2.2.tar.gz"
sha256: "7916bec6c8ea9ddc690a5bfc80fb1b9402f9e1b2a4b4bb6b6bb8eb5a07eb018e"
80 changes: 80 additions & 0 deletions recipes/nsimd/2.x/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import os
from conans import ConanFile, CMake, tools

gmeeker marked this conversation as resolved.
Show resolved Hide resolved
required_conan_version = ">=1.33.0"


class NsimdConan(ConanFile):
name = "nsimd"
homepage = "https://github.com/agenium-scale/nsimd"
description = "Agenium Scale vectorization library for CPUs and GPUs"
topics = ("hpc", "neon", "cuda", "avx", "simd", "avx2", "sse2", "aarch64", "avx512", "sse42", "rocm", "sve", "neon128")
url = "https://github.com/conan-io/conan-center-index"
license = "MIT"
exports_sources = ["CMakeLists.txt", "patches/*"]
generators = "cmake"
settings = "os", "compiler", "build_type", "arch"
options = {
"shared": [True, False],
"fPIC": [True, False],
gmeeker marked this conversation as resolved.
Show resolved Hide resolved
# This used only when building the library.
# Most functionality is header only.
"simd": [None, "cpu", "sse2", "sse42", "avx", "avx2", "avx512_knl", "avx512_skylake", "neon128", "aarch64", "sve", "sve128", "sve256", "sve512", "sve1024", "sve2048", "cuda", "rocm"]
}
default_options = {
"shared": False,
"fPIC": True,
"simd": None
}

_cmake = None

@property
def _source_subfolder(self):
return "source_subfolder"

@property
def _build_subfolder(self):
return "build_subfolder"

def config_options(self):
if self.settings.os == "Windows":
del self.options.fPIC

def configure(self):
if self.options.shared:
del self.options.fPIC
# Most of the library is header only.
# cpp files do not use STL.
del self.settings.compiler.libcxx

def source(self):
tools.get(**self.conan_data["sources"][self.version], strip_root=True, destination=self._source_subfolder)

def _configure_cmake(self):
if self._cmake:
return self._cmake
self._cmake = CMake(self)
gmeeker marked this conversation as resolved.
Show resolved Hide resolved
defs = {}
if self.options.simd:
defs["simd"] = self.options.simd
if self.settings.arch == "armv7hf":
defs["NSIMD_ARM32_IS_ARMEL"] = "OFF"
self._cmake.configure(build_folder=self._build_subfolder, defs=defs)
gmeeker marked this conversation as resolved.
Show resolved Hide resolved
return self._cmake

def build(self):
# allow static library (not in patch file to avoid one patch per version)
tools.replace_in_file(os.path.join(self._source_subfolder, "CMakeLists.txt"),
" SHARED ",
" ")
gmeeker marked this conversation as resolved.
Show resolved Hide resolved
cmake = self._configure_cmake()
cmake.build()

def package(self):
self.copy("LICENSE", dst="licenses", src=self._source_subfolder)
cmake = self._configure_cmake()
cmake.install()

def package_info(self):
self.cpp_info.libs = tools.collect_libs(self)
8 changes: 8 additions & 0 deletions recipes/nsimd/2.x/test_package/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
cmake_minimum_required(VERSION 3.1)
project(test_package CXX)

include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()

add_executable(${PROJECT_NAME} test_package.cpp)
target_link_libraries(${PROJECT_NAME} ${CONAN_LIBS})
gmeeker marked this conversation as resolved.
Show resolved Hide resolved
18 changes: 18 additions & 0 deletions recipes/nsimd/2.x/test_package/conanfile.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import os

from conans import ConanFile, CMake, tools


class NsimdTestConan(ConanFile):
settings = "os", "compiler", "build_type", "arch"
generators = "cmake"
gmeeker marked this conversation as resolved.
Show resolved Hide resolved

def build(self):
cmake = CMake(self)
cmake.configure()
cmake.build()

def test(self):
if not tools.cross_building(self):
bin_path = os.path.join("bin", "test_package")
self.run(bin_path, run_environment=True)
102 changes: 102 additions & 0 deletions recipes/nsimd/2.x/test_package/test_package.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
/* Tutorial from NSIMD library, modified to use a constant string */

#include <nsimd/nsimd-all.hpp>

#include <string>
#include <vector>
#include <iostream>

#include <string.h>

template <typename T>
void uppercase_scalar(T *dst, const T *src, int n) {
for (int i = 0; i < n; i++) {
if (src[i] >= 'a' && src[i] <= 'z') {
dst[i] = src[i] + ('A' - 'a');
} else {
dst[i] = src[i];
}
}
}

template <typename T>
void uppercase_simd(T *dst, const T *src, int n) {
using namespace nsimd;
typedef pack<T> p_t;
typedef packl<T> pl_t;
int l = len<p_t>();

int i;
for (i = 0; i + l <= n; i += l) {
p_t text = loadu<p_t>(src + i);
pl_t mask = text >= 'a' && text <= 'z';
p_t then_pack = text + ('A' - 'a');
p_t TEXT = if_else(mask, then_pack, text);
storeu(dst + i, TEXT);
}

pl_t mask = mask_for_loop_tail<pl_t>(i, n);
p_t text = maskz_loadu(mask, src + i);
p_t TEXT = if_else(text >= 'a' && text <= 'z', text + ('A' - 'a'), text);
mask_storeu(mask, dst + i, TEXT);
}

int test_uppercase_simd() {
std::string input("The quick brown fox jumps over the lazy dog");

std::cout << "Original text : " << input << std::endl;

std::vector<i8> dst_scalar(input.size() + 1);
uppercase_scalar(&dst_scalar[0], (i8 *)input.c_str(), (int)input.size());
std::cout << "Scalar uppercase text: " << &dst_scalar[0] << std::endl;

std::vector<i8> dst_simd(input.size() + 1);
uppercase_simd(&dst_simd[0], (i8 *)input.c_str(), (int)input.size());
std::cout << "NSIMD uppercase text : " << &dst_simd[0] << std::endl;

if (memcmp(&dst_scalar[0], &dst_simd[0], dst_simd.size()) != 0) {
std::cerr << "ERROR: SIMD results don't match!" << std::endl;
return 1;
}

return 0;
}

// From nsimd-all.cpp

int test_unroll() {
using namespace nsimd;
const int unroll = 3;
typedef pack<float, unroll> upack;

const int n_max = unroll * NSIMD_MAX_LEN(f32);
const int n = len(upack());
float buf[n_max];

for(int i = 0; i < n; i++) {
buf[i] = float(i);
}

upack p = loadu<upack>(buf);
p = -(p * p) + 1.0f;
storeu(buf, p);

for (int i = 0; i < n; i++) {
fprintf(stdout, "%f vs %f\n", double(buf[i]), double(-i * i));
}

for (int i = 0; i < n; i++) {
if (buf[i] != float(-(i * i) + 1)) {
return 1;
}
}

return 0;
}

int main() {
if (test_uppercase_simd() || test_unroll())
return 1;

return 0;
}
3 changes: 3 additions & 0 deletions recipes/nsimd/config.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
versions:
"2.2":
folder: 2.x