/
wscript
153 lines (114 loc) · 4.4 KB
/
wscript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
#! /usr/bin/env python
# encoding: utf-8
from waflib.Build import BuildContext
import os
APPNAME = "aybabtu"
VERSION = "4.0.0"
def configure(conf):
conf.set_cxx_std(11)
_set_simd_flags(conf)
def _set_simd_flags(conf):
"""
Sets flags used to compile in SIMD mode
"""
CXX = conf.env.get_flat("CXX")
flags = []
# DEST_CPU should be set explicitly for clang cross-compilers
cpu = conf.env["DEST_CPU"]
# Matches both g++ and clang++
if "g++" in CXX or "clang" in CXX:
# Test different compiler flags based on the target CPU
if cpu == "x86" or cpu == "x86_64":
flags += conf.mkspec_try_flags(
"cxxflags", ["-msse2", "-mssse3", "-msse4.2", "-mavx2"]
)
elif cpu == "arm" or cpu == "thumb":
flags += conf.mkspec_try_flags("cxxflags", ["-mfpu=neon"])
elif "CL.exe" in CXX or "cl.exe" in CXX:
if cpu == "x86" or cpu == "x86_64" or cpu == "amd64":
flags += conf.mkspec_try_flags("cxxflags", ["/arch:AVX2"])
elif "em++" in CXX:
flags = []
else:
conf.fatal("Unknown compiler - no SIMD flags specified")
conf.env["CFLAGS_AYBABTU_SIMD"] = flags
conf.env["CXXFLAGS_AYBABTU_SIMD"] = flags
def build(bld):
optimized_sources = {
"detail/base64_avx2": ["-mavx2", "/arch:AVX2"],
"detail/base64_neon": ["-mfpu=neon"],
"detail/base64_ssse3": ["-mssse3"],
}
libs = ["cpuid", "platform_includes"]
cxxflags = []
compiler_binary = bld.env.get_flat("CXX").lower()
if "g++" in compiler_binary and "clang" not in compiler_binary:
cxxflags += ["-funroll-loops"]
for source, flags in optimized_sources.items():
simd_flags = [f for f in flags if f in bld.env["CXXFLAGS_AYBABTU_SIMD"]]
if "-mavx2" in simd_flags and "clang" not in compiler_binary:
simd_flags += [
"-mno-avx256-split-unaligned-load",
"-mno-avx256-split-unaligned-store",
]
bld.objects(
source="src/aybabtu/" + source + ".cpp",
target=source,
cxxflags=cxxflags + simd_flags,
use=libs,
)
source_files = bld.path.ant_glob(
"src/aybabtu/**/*.cpp",
excl=["src/aybabtu/" + s + ".cpp" for s in optimized_sources],
)
# Build static library if this is top-level, otherwise just .o files
features = ["cxx"]
if bld.is_toplevel():
features += ["cxxstlib"]
bld(
features=features,
source=source_files,
target="aybabtu",
cxxflags=cxxflags,
use=libs + list(optimized_sources.keys()),
install_path="${PREFIX}/lib",
export_includes=["src"],
)
if bld.is_toplevel():
# Only build tests when executed from the top-level wscript,
# i.e. not when included as a dependency
bld.recurse("test")
bld.recurse("examples")
bld.recurse("benchmarks")
class ReleaseContext(BuildContext):
cmd = "prepare_release"
fun = "prepare_release"
def prepare_release(ctx):
"""Prepare a release."""
# Rewrite versions
with ctx.rewrite_file(filename="src/aybabtu/version.hpp") as f:
pattern = r"#define STEINWURF_AYBABTU_VERSION v\d+_\d+_\d+"
replacement = "#define STEINWURF_AYBABTU_VERSION v{}".format(
VERSION.replace(".", "_")
)
f.regex_replace(pattern=pattern, replacement=replacement)
with ctx.rewrite_file(filename="src/aybabtu/version.cpp") as f:
pattern = r'return "\d+\.\d+\.\d+"'
replacement = 'return "{}"'.format(VERSION)
f.regex_replace(pattern=pattern, replacement=replacement)
class PlotContext(BuildContext):
cmd = "plot_benchmarks"
fun = "plot_benchmarks"
def plot_benchmarks(ctx):
venv = ctx.create_virtualenv(name="virtualenv-plots", overwrite=False)
if not os.path.isfile("benchmarks/requirements.txt"):
venv.run("python -m pip install pip-tools")
venv.run("pip-compile benchmarks/requirements.in")
venv.run("python -m pip install -r benchmarks/requirements.txt")
if not os.path.exists("benchmark_results"):
os.mkdir("benchmark_results")
# Block benchmark
venv.run(
"build_current/benchmarks/throughput --benchmark_out='benchmark_results/throughput.json' --benchmark_counters_tabular=true"
)
venv.run("python benchmarks/plot.py -i benchmark_results/throughput.json")