Skip to content

Commit 86c06d9

Browse files
committed
rewrite big_new to big_alloc
1 parent 7045e1d commit 86c06d9

File tree

7 files changed

+80
-73
lines changed

7 files changed

+80
-73
lines changed

cp-algo/math/cvector.hpp

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
#define CP_ALGO_MATH_CVECTOR_HPP
33
#include "../util/complex.hpp"
44
#include "../util/checkpoint.hpp"
5-
#include "../util/new_big.hpp"
5+
#include "../util/big_alloc.hpp"
66
#include <experimental/simd>
77
#include <ranges>
88

@@ -18,28 +18,20 @@ namespace cp_algo::math::fft {
1818
static constexpr vpoint vi = {vz, vz + 1};
1919

2020
struct cvector {
21-
vpoint *r;
22-
size_t sz;
21+
std::vector<vpoint, big_alloc<vpoint>> r;
2322
cvector(size_t n) {
24-
sz = std::max(flen, std::bit_ceil(n));
25-
r = new_big<vpoint>(sz / flen);
23+
n = std::max(flen, std::bit_ceil(n));
24+
r.resize(n / flen);
2625
checkpoint("cvector create");
2726
}
2827
cvector(cvector const& t) {
29-
sz = t.sz;
30-
r = new_big<vpoint>(sz / flen);
31-
memcpy(r, t.r, (sz / flen) * sizeof(vpoint));
32-
checkpoint("cvector copy");
33-
}
34-
cvector(cvector&& t) noexcept {
35-
sz = t.sz;
36-
r = std::exchange(t.r, nullptr);
37-
}
38-
~cvector() noexcept {
39-
if(r) {
40-
delete_big(r, sz / flen);
28+
r.resize(t.r.size());
29+
for(size_t i = 0; i < r.size(); i++) {
30+
r[i] = {vftype(t.r[i].real()), vftype(t.r[i].imag())};
4131
}
32+
checkpoint("cvector copy");
4233
}
34+
cvector(cvector&& t) = delete;
4335

4436
vpoint& at(size_t k) {return r[k / flen];}
4537
vpoint at(size_t k) const {return r[k / flen];}
@@ -62,7 +54,7 @@ namespace cp_algo::math::fft {
6254
}
6355

6456
size_t size() const {
65-
return sz;
57+
return flen * r.size();
6658
}
6759
static size_t eval_arg(size_t n) {
6860
if(n < pre_evals) {
@@ -90,15 +82,15 @@ namespace cp_algo::math::fft {
9082
}
9183
}
9284
static void exec_on_roots(size_t n, size_t m, auto &&callback) {
93-
point cur;
85+
point cur = {1, 0};
9486
point arg = root(n, 1);
9587
for(size_t i = 0; i < m; i++) {
96-
if(i % 32 == 0) {
97-
cur = root(n / 32, i / 32);
88+
callback(i, cur);
89+
if(i % 64 == 63) {
90+
cur = root(n / 64, i / 64 + 1);
9891
} else {
9992
cur *= arg;
10093
}
101-
callback(i, cur);
10294
}
10395
}
10496
template<int step = 1>
@@ -207,7 +199,7 @@ namespace cp_algo::math::fft {
207199
}
208200
checkpoint("fft");
209201
}
210-
static constexpr size_t pre_roots = 1 << 15;
202+
static constexpr size_t pre_roots = 1 << 14;
211203
static constexpr size_t pre_evals = 1 << 16;
212204
static constexpr std::array<point, pre_roots> roots = []() {
213205
std::array<point, pre_roots> res = {};

cp-algo/math/fft.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,8 +165,8 @@ namespace cp_algo::math::fft {
165165
std::min(k, size(a)) + std::min(k, size(b)) - 1
166166
) / 2);
167167
auto A = dft<base>(a | std::views::take(k), n);
168-
a.resize(k);
169-
checkpoint("resize a");
168+
a.assign(k, 0);
169+
checkpoint("reset a");
170170
if(&a == &b) {
171171
A.mul(A, a, k);
172172
} else {

cp-algo/math/poly.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@
1313
#include <vector>
1414
#include <list>
1515
namespace cp_algo::math {
16-
template<typename T>
16+
template<typename T, class Alloc = big_alloc<T>>
1717
struct poly_t {
1818
using base = T;
19-
std::vector<T> a;
19+
std::vector<T, Alloc> a;
2020

2121
poly_t& normalize() {
2222
while(deg() >= 0 && lead() == base(0)) {
@@ -27,8 +27,8 @@ namespace cp_algo::math {
2727

2828
poly_t(){}
2929
poly_t(T a0): a{a0} {normalize();}
30-
poly_t(std::vector<T> const& t): a(t) {normalize();}
31-
poly_t(std::vector<T>&& t): a(std::move(t)) {normalize();}
30+
poly_t(auto const& t): a(t.begin(), t.end()) {normalize();}
31+
poly_t(std::vector<T, Alloc> &&t): a(std::move(t)) {normalize();}
3232

3333
poly_t& negate_inplace() {
3434
std::ranges::transform(a, begin(a), std::negate{});

cp-algo/util/big_alloc.hpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#ifndef CP_ALGO_UTIL_big_alloc_HPP
2+
#define CP_ALGO_UTIL_big_alloc_HPP
3+
4+
#include <cstddef>
5+
#include <iostream>
6+
7+
// Single macro to detect POSIX platforms (Linux, Unix, macOS)
8+
#if defined(__linux__) || defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
9+
# define CP_ALGO_USE_MMAP 1
10+
# include <sys/mman.h>
11+
#else
12+
# define CP_ALGO_USE_MMAP 0
13+
#endif
14+
15+
namespace cp_algo {
16+
template <typename T>
17+
class big_alloc: public std::allocator<T> {
18+
public:
19+
using value_type = T;
20+
using base = std::allocator<T>;
21+
22+
big_alloc() noexcept = default;
23+
24+
template <typename U>
25+
big_alloc(const big_alloc<U>&) noexcept {}
26+
27+
#if CP_ALGO_USE_MMAP
28+
[[nodiscard]] T* allocate(std::size_t n) {
29+
if(n * sizeof(T) < 4 * 1024 * 1024) {
30+
return base::allocate(n);
31+
}
32+
n *= sizeof(T);
33+
void* raw = mmap(nullptr, n,
34+
PROT_READ | PROT_WRITE,
35+
MAP_PRIVATE | MAP_ANONYMOUS,
36+
-1, 0);
37+
madvise(raw, n, MADV_HUGEPAGE);
38+
madvise(raw, n, MADV_POPULATE_WRITE);
39+
return static_cast<T*>(raw);
40+
}
41+
#endif
42+
43+
#if CP_ALGO_USE_MMAP
44+
void deallocate(T* p, std::size_t n) noexcept {
45+
if(n * sizeof(T) < 4 * 1024 * 1024) {
46+
return base::deallocate(p, n);
47+
}
48+
if(p) {
49+
munmap(p, n * sizeof(T));
50+
}
51+
}
52+
#endif
53+
};
54+
}
55+
#endif // CP_ALGO_UTIL_big_alloc_HPP

cp-algo/util/complex.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ namespace cp_algo {
88
struct complex {
99
using value_type = T;
1010
T x, y;
11-
constexpr complex() {}
11+
constexpr complex(): x(), y() {}
1212
constexpr complex(T x): x(x), y() {}
1313
constexpr complex(T x, T y): x(x), y(y) {}
1414
complex& operator *= (T t) {x *= t; y *= t; return *this;}

cp-algo/util/new_big.hpp

Lines changed: 0 additions & 40 deletions
This file was deleted.

verify/poly/wildcard.test.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,15 @@ string matches(string const& A, string const& B, char wild = '*') {
5454
project[1][i] = conj(project[0][i]);
5555
}
5656
}
57-
project[0][wild] = project[1][wild] = 0;
57+
project[0][(int)wild] = project[1][(int)wild] = 0;
5858
vector<cvector> P;
5959
P.emplace_back(size(A));
6060
P.emplace_back(size(A));
6161
for(auto [i, c]: A | views::enumerate) {
62-
P[0].set(i, project[0][c]);
62+
P[0].set(i, project[0][(int)c]);
6363
}
6464
for(auto [i, c]: B | views::reverse | views::enumerate) {
65-
P[1].set(i, project[1][c]);
65+
P[1].set(i, project[1][(int)c]);
6666
}
6767
cp_algo::checkpoint("cvector fill");
6868
semicorr(P[0], P[1]);

0 commit comments

Comments
 (0)