-
Notifications
You must be signed in to change notification settings - Fork 51
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
3 changed files
with
102 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
// Copyright (C) 2022 Intel Corporation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#pragma once | ||
|
||
#include <mutex> | ||
#include <shared_mutex> | ||
|
||
namespace intel { | ||
namespace hexl { | ||
|
||
using Lock = std::shared_mutex; | ||
using WriteLock = std::unique_lock<Lock>; | ||
using ReadLock = std::shared_lock<Lock>; | ||
|
||
class RWLock { | ||
public: | ||
RWLock() = default; | ||
inline ReadLock AcquireRead() { return ReadLock(rw_mutex); } | ||
inline WriteLock AcquireWrite() { return WriteLock(rw_mutex); } | ||
inline ReadLock TryAcquireRead() noexcept { | ||
return ReadLock(rw_mutex, std::try_to_lock); | ||
} | ||
inline WriteLock TryAcquireWrite() noexcept { | ||
return WriteLock(rw_mutex, std::try_to_lock); | ||
} | ||
|
||
private: | ||
RWLock(const RWLock& copy) = delete; | ||
RWLock& operator=(const RWLock& assign) = delete; | ||
Lock rw_mutex{}; | ||
}; | ||
|
||
} // namespace hexl | ||
} // namespace intel |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
// Copyright (C) 2022 Intel Corporation | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#pragma once | ||
|
||
#include "hexl/experimental/seal/locks.hpp" | ||
#include "ntt/ntt-internal.hpp" | ||
|
||
namespace intel { | ||
namespace hexl { | ||
|
||
struct HashPair { | ||
template <class T1, class T2> | ||
std::size_t operator()(const std::pair<T1, T2>& p) const { | ||
auto hash1 = std::hash<T1>{}(p.first); | ||
auto hash2 = std::hash<T2>{}(p.second); | ||
return hash_combine(hash1, hash2); | ||
} | ||
|
||
// Golden Ratio Hashing with seeds | ||
static std::size_t hash_combine(std::size_t lhs, std::size_t rhs) { | ||
lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2); | ||
return lhs; | ||
} | ||
}; | ||
|
||
NTT& GetNTT(size_t N, uint64_t modulus) { | ||
static std::unordered_map<std::pair<uint64_t, uint64_t>, NTT, HashPair> | ||
ntt_cache; | ||
static RWLock ntt_cache_locker; | ||
|
||
std::pair<uint64_t, uint64_t> key{N, modulus}; | ||
|
||
// Enable shared access to NTT already present | ||
{ | ||
ReadLock reader_lock(ntt_cache_locker.AcquireRead()); | ||
auto ntt_it = ntt_cache.find(key); | ||
if (ntt_it != ntt_cache.end()) { | ||
return ntt_it->second; | ||
} | ||
} | ||
|
||
// Deal with NTT not yet present | ||
WriteLock write_lock(ntt_cache_locker.AcquireWrite()); | ||
|
||
// Check ntt_cache for value (may be added by another thread) | ||
auto ntt_it = ntt_cache.find(key); | ||
if (ntt_it == ntt_cache.end()) { | ||
NTT ntt(N, modulus); | ||
ntt_it = ntt_cache.emplace(std::move(key), std::move(ntt)).first; | ||
} | ||
return ntt_it->second; | ||
} | ||
|
||
} // namespace hexl | ||
} // namespace intel |