Skip to content

Commit

Permalink
Merge pull request #332 from fboemer/fboemer/seal-pr
Browse files Browse the repository at this point in the history
fboemer/hexl-1.1.0
  • Loading branch information
Wei Dai committed May 11, 2021
2 parents 8f4a4c2 + d83c0ec commit cbd1cbe
Show file tree
Hide file tree
Showing 8 changed files with 150 additions and 9 deletions.
10 changes: 7 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ if(SEAL_USE_INTEL_HEXL)
message(STATUS "Intel HEXL: download ...")
seal_fetch_thirdparty_content(ExternalIntelHEXL)
else()
find_package(HEXL 1.0.1)
find_package(HEXL 1.1.0)
if (NOT TARGET HEXL::hexl)
FATAL_ERROR("Intel HEXL: not found")
endif()
Expand Down Expand Up @@ -461,8 +461,12 @@ else()
endif()

if(SEAL_USE_INTEL_HEXL)
target_include_directories(seal_shared PRIVATE $<BUILD_INTERFACE:${hexl_SOURCE_DIR}/hexl/include>)
target_link_libraries(seal_shared PRIVATE hexl)
get_target_property(
HEXL_INCLUDE_DIR
HEXL::hexl
INTERFACE_INCLUDE_DIRECTORIES)
target_include_directories(seal_shared PUBLIC ${HEXL_INCLUDE_DIR})
target_link_libraries(seal_shared PRIVATE HEXL::hexl)
endif()
endif()

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ The optional dependencies and their tested versions (other versions may work as

| Optional dependency | Tested version | Use |
| ------------------------------------------------------ | -------------- | ------------------------------------------------ |
| [Intel HEXL](https://github.com/intel/hexl) | 1.0.1 | Acceleration of low-level kernels |
| [Intel HEXL](https://github.com/intel/hexl) | 1.1.0 | Acceleration of low-level kernels |
| [Microsoft GSL](https://github.com/microsoft/GSL) | 3.1.0 | API extensions |
| [ZLIB](https://github.com/madler/zlib) | 1.2.11 | Compressed serialization |
| [Zstandard](https://github.com/facebook/zstd) | 1.4.5 | Compressed serialization (much faster than ZLIB) |
Expand Down
4 changes: 2 additions & 2 deletions cmake/ExternalIntelHEXL.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
FetchContent_Declare(
hexl
PREFIX hexl
GIT_REPOSITORY https://github.com/intel/hexl.git
GIT_TAG v1.0.1
GIT_REPOSITORY https://github.com/intel/hexl
GIT_TAG c28943d # v1.1.0
)
FetchContent_GetProperties(hexl)

Expand Down
111 changes: 110 additions & 1 deletion native/src/seal/util/intel_seal_ext.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,119 @@
#pragma once

#ifdef SEAL_USE_INTEL_HEXL
#include "seal/memorymanager.h"
#include "seal/util/locks.h"
#include <unordered_map>
#include "hexl/hexl.hpp"

namespace intel
{
namespace hexl
{
// Single threaded SEAL allocator adapter
template <>
struct NTT::AllocatorAdapter<seal::MemoryPoolHandle>
: public AllocatorInterface<NTT::AllocatorAdapter<seal::MemoryPoolHandle>>
{
AllocatorAdapter(seal::MemoryPoolHandle handle) : handle_(std::move(handle))
{}

~AllocatorAdapter()
{}

// interface implementations
void *allocate_impl(std::size_t bytes_count)
{
cache_.push_back(static_cast<seal::util::MemoryPool &>(handle_).get_for_byte_count(bytes_count));
return cache_.back().get();
}

void deallocate_impl(void *p, std::size_t n)
{
(void)n;
auto it = std::remove_if(
cache_.begin(), cache_.end(),
[p](const seal::util::Pointer<seal::seal_byte> &seal_pointer) { return p == seal_pointer.get(); });

#ifdef SEAL_DEBUG
if (it == cache_.end())
{
throw std::logic_error("Inconsistent single-threaded allocator cache");
}
#endif
cache_.erase(it, cache_.end());
}

private:
seal::MemoryPoolHandle handle_;
std::vector<seal::util::Pointer<seal::seal_byte>> cache_;
};

// Thread safe policy
struct SimpleThreadSafePolicy
{
SimpleThreadSafePolicy() : m_ptr(std::make_unique<std::mutex>())
{}

std::unique_lock<std::mutex> locker()
{
return std::unique_lock<std::mutex>{ *m_ptr };
};

private:
std::unique_ptr<std::mutex> m_ptr;
};

// Multithreaded SEAL allocator adapter
template <>
struct NTT::AllocatorAdapter<seal::MemoryPoolHandle, SimpleThreadSafePolicy>
: public AllocatorInterface<NTT::AllocatorAdapter<seal::MemoryPoolHandle, SimpleThreadSafePolicy>>
{
AllocatorAdapter(seal::MemoryPoolHandle handle, SimpleThreadSafePolicy &&policy)
: handle_(std::move(handle)), policy_(std::move(policy))
{}

~AllocatorAdapter()
{}
// interface implementations
void *allocate_impl(std::size_t bytes_count)
{
{
// to prevent inline optimization with deadlock
auto accessor = policy_.locker();
cache_.push_back(static_cast<seal::util::MemoryPool &>(handle_).get_for_byte_count(bytes_count));
return cache_.back().get();
}
}

void deallocate_impl(void *p, std::size_t n)
{
(void)n;
{
// to prevent inline optimization with deadlock
auto accessor = policy_.locker();
auto it = std::remove_if(
cache_.begin(), cache_.end(), [p](const seal::util::Pointer<seal::seal_byte> &seal_pointer) {
return p == seal_pointer.get();
});

#ifdef SEAL_DEBUG
if (it == cache_.end())
{
throw std::logic_error("Inconsistent multi-threaded allocator cache");
}
#endif
cache_.erase(it, cache_.end());
}
}

private:
seal::MemoryPoolHandle handle_;
SimpleThreadSafePolicy policy_;
std::vector<seal::util::Pointer<seal::seal_byte>> cache_;
};
} // namespace hexl

namespace seal_ext
{
struct HashPair
Expand Down Expand Up @@ -61,7 +168,9 @@ namespace intel
auto ntt_it = ntt_cache_.find(key);
if (ntt_it == ntt_cache_.end())
{
ntt_it = ntt_cache_.emplace(std::move(key), intel::hexl::NTT(N, modulus, root)).first;
intel::hexl::NTT ntt(
N, modulus, root, seal::MemoryManager::GetPool(), intel::hexl::SimpleThreadSafePolicy{});
ntt_it = ntt_cache_.emplace(std::move(key), std::move(ntt)).first;
}
return ntt_it->second;
}
Expand Down
8 changes: 8 additions & 0 deletions native/src/seal/util/polyarithsmallmod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,14 @@ namespace seal
}
#endif

#ifdef SEAL_USE_INTEL_HEXL
intel::hexl::EltwiseAddMod(result, poly, scalar, coeff_count, modulus.value());
#else
SEAL_ITERATE(iter(poly, result), coeff_count, [&](auto I) {
const uint64_t x = get<0>(I);
get<1>(I) = add_uint_mod(x, scalar, modulus);
});
#endif
}

void sub_poly_scalar_coeffmod(
Expand All @@ -65,10 +69,14 @@ namespace seal
}
#endif

#ifdef SEAL_USE_INTEL_HEXL
intel::hexl::EltwiseSubMod(result, poly, scalar, coeff_count, modulus.value());
#else
SEAL_ITERATE(iter(poly, result), coeff_count, [&](auto I) {
const uint64_t x = get<0>(I);
get<1>(I) = sub_uint_mod(x, scalar, modulus);
});
#endif
}

void multiply_poly_scalar_coeffmod(
Expand Down
10 changes: 10 additions & 0 deletions native/src/seal/util/polyarithsmallmod.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,13 @@ namespace seal
throw std::invalid_argument("modulus");
}
#endif

#ifdef SEAL_USE_INTEL_HEXL
intel::hexl::EltwiseReduceMod(result, poly, coeff_count, modulus.value(), 0, 1);
#else
SEAL_ITERATE(
iter(poly, result), coeff_count, [&](auto I) { get<1>(I) = barrett_reduce_64(get<0>(I), modulus); });
#endif
}

inline void modulo_poly_coeffs(
Expand Down Expand Up @@ -314,7 +319,11 @@ namespace seal
throw std::invalid_argument("result");
}
#endif

const uint64_t modulus_value = modulus.value();
#ifdef SEAL_USE_INTEL_HEXL
intel::hexl::EltwiseSubMod(result, operand1, operand2, coeff_count, modulus_value);
#else
SEAL_ITERATE(iter(operand1, operand2, result), coeff_count, [&](auto I) {
#ifdef SEAL_DEBUG
if (get<0>(I) >= modulus_value)
Expand All @@ -330,6 +339,7 @@ namespace seal
std::int64_t borrow = sub_uint64(get<0>(I), get<1>(I), &temp_result);
get<2>(I) = temp_result + (modulus_value & static_cast<std::uint64_t>(-borrow));
});
#endif
}

inline void sub_poly_coeffmod(
Expand Down
6 changes: 6 additions & 0 deletions native/tests/seal/modulus.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,13 @@ namespace sealtest
stringstream stream;

Modulus mod;
#ifdef SEAL_USE_ZLIB
compr_mode_type compr_mode = compr_mode_type::zlib;
#elif defined(SEAL_USE_ZSTD)
compr_mode_type compr_mode = compr_mode_type::zstd;
#else
compr_mode_type compr_mode = compr_mode_type::none;
#endif
mod.save(stream, compr_mode);

Modulus mod2;
Expand Down
8 changes: 6 additions & 2 deletions native/tests/seal/serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,15 @@ namespace sealtest
Serialization::SEALHeader header;
ASSERT_TRUE(Serialization::IsValidHeader(header));

header.compr_mode = (compr_mode_type)0x01;
#ifdef SEAL_USE_ZLIB
header.compr_mode = compr_mode_type::zlib;
ASSERT_TRUE(Serialization::IsValidHeader(header));
#endif

header.compr_mode = (compr_mode_type)0x02;
#ifdef SEAL_USE_ZSTD
compr_mode_type compr_mode = compr_mode_type::zstd;
ASSERT_TRUE(Serialization::IsValidHeader(header));
#endif

Serialization::SEALHeader invalid_header;
invalid_header.magic = 0x1212;
Expand Down

0 comments on commit cbd1cbe

Please sign in to comment.