aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--README.md4
-rwxr-xr-xbuild151
3 files changed, 90 insertions, 68 deletions
diff --git a/.gitignore b/.gitignore
index 4a9c4dd..f696f7c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,8 +18,11 @@ test/.DS_Store
18test/run 18test/run
19test/run.DSYM 19test/run.DSYM
20runtest 20runtest
21runcpp
21runtest.js 22runtest.js
22runtest.wasm 23runtest.wasm
24wasm/*.wasm
25wasm/nissy_raw_module.js
23runtool 26runtool
24tools/.DS_Store 27tools/.DS_Store
25run.DSYM 28run.DSYM
diff --git a/README.md b/README.md
index 1f7d1f6..384d217 100644
--- a/README.md
+++ b/README.md
@@ -174,10 +174,10 @@ implementation file `nissy.cpp`. This interface wraps the calls to the
174C functions in an object-oriented C++ interface for more convenient use. 174C functions in an object-oriented C++ interface for more convenient use.
175 175
176The `cpp/examples` folder contains some examples for how to use this 176The `cpp/examples` folder contains some examples for how to use this
177interface. You can build them with e.g. 177interface. You can build them and run them with the build tool, for example:
178 178
179``` 179```
180g++ -std=c++20 cpp/nissy.cpp cpp/examples/solve_h48h3k2.cpp nissy.o 180./build cpp cpp/examples/solve_h48h3k2.cpp
181``` 181```
182 182
183NOTE: If you prefer to use a C-style API, you'll have to write 183NOTE: If you prefer to use a C-style API, you'll have to write
diff --git a/build b/build
index 2348cc8..de340f5 100755
--- a/build
+++ b/build
@@ -24,26 +24,33 @@
24# 24#
25# And the empty string value will take precedence. 25# And the empty string value will take precedence.
26 26
27# Specify the compiler to use. 27# Specify the C compiler to use.
28# The default value is "cc". 28CC=${CC-${NISSY_BUILD_CC:-"cc"}}
29CC=${CC-${NISSY_BUILD_CC}}
30 29
31# Specify the compiler to use when building WASM target. 30# Specify the C++ compiler for the C++ examples.
32# The default value is "emcc". 31CXX=${CXX-${NISSY_BUILD_CXX:-"c++"}}
33EMCC=${EMCC-${NISSY_BUILD_EMCC}}
34 32
35# Specify the nodejs command for running tests for the WASM target. 33# Specify the compiler to use when building for WASM.
36# The default value is "node". 34EMCC=${EMCC-${NISSY_BUILD_EMCC:-"emcc"}}
37NODE=${NODE-${NISSY_BUILD_NODE}} 35
36# Specify the nodejs command for running tests for WASM.
37NODE=${NODE-${NISSY_BUILD_NODE:-"node"}}
38 38
39# The maximum number of threads to use for multi-threaded operations. 39# The maximum number of threads to use for multi-threaded operations.
40# This is also used as default value in case an operation allows 40# This is also used as default value in case an operation allows
41# specifying how many threads to use. 41# specifying how many threads to use.
42# The number n must be between 1 and 128. 42# The number n must be between 1 and 128.
43# The default value is 16. 43# The default value is 16.
44# (TODO: in the future this will be determined base on the system).
45THREADS=${THREADS-${NISSY_BUILD_THREADS}} 44THREADS=${THREADS-${NISSY_BUILD_THREADS}}
46 45
46detectthreads() {
47 # TODO: detect based on system
48 # Is 'getconf NPROCESSORD_ONLN' portable? Is it threads or cores?
49 echo "16"
50}
51
52[ -z "$THREADS" ] && THREADS="$(detectthreads)"
53
47# You can use this variable to build for a different architecture, for example 54# You can use this variable to build for a different architecture, for example
48# if you want to cross-compile or to use the portable version. 55# if you want to cross-compile or to use the portable version.
49# The value must be one of "AVX2", "NEON", "PORTABLE". If the value is not 56# The value must be one of "AVX2", "NEON", "PORTABLE". If the value is not
@@ -51,22 +58,6 @@ THREADS=${THREADS-${NISSY_BUILD_THREADS}}
51# system. The architecture "PORTABLE" will work on any system. 58# system. The architecture "PORTABLE" will work on any system.
52ARCH=${ARCH-${NISSY_BUILD_ARCH}} 59ARCH=${ARCH-${NISSY_BUILD_ARCH}}
53 60
54# SANITIZE="option1,option2,..." adds the options "-fsanitize=option1",
55# "-fsanitize=option2", ... to the C compiler command in debug mode.
56# By default none is used because these options are not available on all
57# systems. It is advisable to set the NISSY_BUILD_SANITIZE options in your
58# shell's configuration file if your system does support them.
59SANITIZE=${SANITIZE-${NISSY_BUILD_SANITIZE}}
60
61# Optimization flags. By default, -O3 is used.
62OPTIMIZE=${OPTIMIZE-${NISSY_BUILD_OPTIMIZE}}
63
64detectthreads() {
65 # TODO: detect based on system
66 # Is 'getconf NPROCESSORD_ONLN' portable? Is it threads or cores?
67 echo "16"
68}
69
70greparch() { 61greparch() {
71 $CC -march=native -dM -E - </dev/null 2>/dev/null | grep "$1" 62 $CC -march=native -dM -E - </dev/null 2>/dev/null | grep "$1"
72} 63}
@@ -75,34 +66,44 @@ detectarch() {
75 [ -n "$(greparch __AVX2__)" ] && detected="AVX2" 66 [ -n "$(greparch __AVX2__)" ] && detected="AVX2"
76 [ -n "$(greparch __ARM_NEON)" ] && detected="NEON" 67 [ -n "$(greparch __ARM_NEON)" ] && detected="NEON"
77 [ -z "$detected" ] && detected="PORTABLE" 68 [ -z "$detected" ] && detected="PORTABLE"
78
79 echo "$detected" 69 echo "$detected"
80} 70}
81 71
82validatecc() { 72[ -z "$ARCH" ] && ARCH="$(detectarch)"
83 if ! (command -v "$CC" >/dev/null 2>&1) ; then 73
84 echo "Error: compiler '$CC' not found" 74# SANITIZE="option1,option2,..." adds the options "-fsanitize=option1",
75# "-fsanitize=option2", ... to the C compiler command in debug mode.
76# By default none is used because these options are not available on all
77# systems. It is advisable to set the NISSY_BUILD_SANITIZE options in your
78# shell's configuration file if your system does support them.
79SANITIZE=${SANITIZE-${NISSY_BUILD_SANITIZE:-""}}
80
81# Optimization flags.
82OPTIMIZE=${OPTIMIZE-${NISSY_BUILD_OPTIMIZE:-"-O3"}}
83
84validate_command() {
85 command="$1"
86 if ! (command -v "$command" >/dev/null 2>&1) ; then
87 echo "Error: command '$command' not found"
85 exit 1 88 exit 1
86 fi 89 fi
87} 90}
88 91
89validatethreads() { 92validate_threads() {
90 if [ "$THREADS" -le 0 ] || [ "$THREADS" -gt 128 ]; then 93 threads="$1"
94 if [ "$threads" -le 0 ] || [ "$threads" -gt 128 ]; then
91 echo "Error: number of threads must be between 1 and 128" 95 echo "Error: number of threads must be between 1 and 128"
92 exit 1 96 exit 1
93 fi 97 fi
94} 98}
95 99
96validatearch() { 100validate_arch() {
97 case "$ARCH" in 101 arch="$1"
102 case "$arch" in
98 AVX2|NEON|PORTABLE) 103 AVX2|NEON|PORTABLE)
99 ;; 104 ;;
100 "")
101 ARCH=$(detectarch)
102 echo "Selected architecture '$ARCH'"
103 ;;
104 *) 105 *)
105 echo "Error: architecture '$ARCH' not supported" 106 echo "Error: architecture '$arch' not supported"
106 echo "Supported architectures: AVX2, NEON, PORTABLE" 107 echo "Supported architectures: AVX2, NEON, PORTABLE"
107 exit 1 108 exit 1
108 ;; 109 ;;
@@ -116,27 +117,20 @@ parsesanitize() {
116 done 117 done
117} 118}
118 119
119# Set variables to default values if unset 120# Build flags
120CC=${CC:-"cc"}
121EMCC=${EMCC:-"emcc"}
122NODE=${NODE:-"node"}
123THREADS=${THREADS:-"$(detectthreads)"}
124ARCH=${ARCH:-"$(detectarch)"}
125OPTIMIZE=${OPTIMIZE:-"-O3"}
126
127# Validate variales
128validatecc
129validatethreads
130validatearch
131
132CFLAGS="-std=c11 -fPIC -D_POSIX_C_SOURCE=199309L -lpthread" 121CFLAGS="-std=c11 -fPIC -D_POSIX_C_SOURCE=199309L -lpthread"
133[ "$ARCH" = "AVX2" ] && CFLAGS="$CFLAGS -mavx2" 122[ "$ARCH" = "AVX2" ] && CFLAGS="$CFLAGS -mavx2"
134WFLAGS="-pedantic -Wall -Wextra -Wno-unused-parameter -Wno-unused-function" 123WFLAGS="-pedantic -Wall -Wextra -Wno-unused-parameter -Wno-unused-function"
135OFLAGS="$OPTIMIZE" 124OFLAGS="$OPTIMIZE"
136DFLAGS="-DDEBUG -g3 $(parsesanitize "$SANITIZE")" 125DFLAGS="-DDEBUG -g3 $(parsesanitize "$SANITIZE")"
137MFLAGS="-DTHREADS=$THREADS -D$ARCH" 126MFLAGS="-DTHREADS=$THREADS -D$ARCH"
127CPPFLAGS="-std=c++20"
128
129# Build flags for emscripten (WASM target)
138WASMCFLAGS="-std=c11 -fPIC -D_POSIX_C_SOURCE=199309L" 130WASMCFLAGS="-std=c11 -fPIC -D_POSIX_C_SOURCE=199309L"
139WASMMFLAGS="-DTHREADS=$THREADS -DWASMSIMD" 131WASMMFLAGS="-DTHREADS=$THREADS -DWASMSIMD"
132WASMLINKFLAGS="--no-entry -sEXPORT_NAME='Nissy' -sMODULARIZE \
133 -sLINKABLE -sEXPORT_ALL -sEXPORTED_RUNTIME_METHODS=cwrap"
140 134
141if (command -v "python3-config" >/dev/null 2>&1) ; then 135if (command -v "python3-config" >/dev/null 2>&1) ; then
142 PYTHON3_INCLUDES="$(python3-config --includes)" 136 PYTHON3_INCLUDES="$(python3-config --includes)"
@@ -147,13 +141,12 @@ else
147fi 141fi
148 142
149build_help() { 143build_help() {
150 echo "Build system for nissy" 144 echo "Build system for nissy. Usage:"
151 echo "" 145 echo ""
152 echo "usage:"
153 echo "$0 TARGET # build the given TARGET" 146 echo "$0 TARGET # build the given TARGET"
154 echo "$0 # same as '$0 nissy'" 147 echo "$0 # same as '$0 nissy'"
155 echo "$0 test [PATTERN] # run unit tests (matching PATTERN)" 148 echo "$0 test [PATTERN] # run unit tests (matching PATTERN)"
156 echo "$0 wasmtest [PATTERN] # same as test, but for WASM target" 149 echo "$0 webtest [PATTERN] # same as test, but for WASM build"
157 echo "$0 tool PATTERN # run the tool matching PATTERN" 150 echo "$0 tool PATTERN # run the tool matching PATTERN"
158 echo "" 151 echo ""
159 echo "targets:" 152 echo "targets:"
@@ -163,7 +156,8 @@ build_help() {
163 echo "sharedlib Build the shared library libnissy.so" 156 echo "sharedlib Build the shared library libnissy.so"
164 echo "python Build the Python module for nissy" 157 echo "python Build the Python module for nissy"
165 echo "shell Build a basic nissy shell (./run)" 158 echo "shell Build a basic nissy shell (./run)"
166 echo "wasm Build the WebAssembly module for nissy" 159 echo "web Build the WebAssembly / JavaScript module for nissy"
160 echo "cpp FILES Build and run the given FILES including cpp/nissy.h"
167 echo "" 161 echo ""
168 echo "help Show this help message" 162 echo "help Show this help message"
169 echo "config Show build configuration and exit" 163 echo "config Show build configuration and exit"
@@ -195,10 +189,15 @@ odflags() {
195} 189}
196 190
197build_clean() { 191build_clean() {
198 run rm -rf -- *.o *.so *.a run runtest runtool 192 run rm -rf -- *.o *.so *.a run runtest runtool runcpp \
193 web/nissy_web_module.*
199} 194}
200 195
201build_nissy() { 196build_nissy() {
197 validate_command "$CC"
198 validate_threads "$THREADS"
199 validate_arch "$ARCH"
200
202 run $CC $CFLAGS $WFLAGS $MFLAGS $(odflags) -c -o nissy.o src/nissy.c 201 run $CC $CFLAGS $WFLAGS $MFLAGS $(odflags) -c -o nissy.o src/nissy.c
203} 202}
204 203
@@ -208,6 +207,10 @@ build_lib() {
208} 207}
209 208
210build_sharedlib() { 209build_sharedlib() {
210 validate_command "$CC"
211 validate_threads "$THREADS"
212 validate_arch "$ARCH"
213
211 run $CC $CFLAGS $WFLAGS $MFLAGS $(odflags) -shared -c -o nissy.o \ 214 run $CC $CFLAGS $WFLAGS $MFLAGS $(odflags) -shared -c -o nissy.o \
212 src/nissy.c 215 src/nissy.c
213} 216}
@@ -228,9 +231,28 @@ build_python() {
228 -o nissy_pthon_module.so nissy.o python/nissy_module.c 231 -o nissy_pthon_module.so nissy.o python/nissy_module.c
229} 232}
230 233
231build_wasm() { 234build_cpp() {
235 validate_command "$CXX"
236 if [ -z "$@" ]; then
237 echo "Please provide one or more valid C++ source files"
238 echo "usage: ./build cpp FILES"
239 fi
240
241 build_nissy
242 run $CXX -std=c++20 -o runcpp cpp/nissy.cpp nissy.o $@
243 run ./runcpp
244}
245
246build_web() {
247 validate_command "$EMCC"
248 validate_threads "$THREADS"
249 validate_arch "$ARCH"
250
232 run $EMCC $WASMCFLAGS $WFLAGS $WASMMFLAGS $(odflags) -c \ 251 run $EMCC $WASMCFLAGS $WFLAGS $WASMMFLAGS $(odflags) -c \
233 -o nissy.o src/nissy.c 252 -o nissy.o src/nissy.c
253 run $EMCC -lembind $CPPFLAGS $(odflags) $WASMLINKFLAGS \
254 -o web/nissy_web_module.mjs \
255 cpp/nissy.cpp web/wrapper.cpp nissy.o
234} 256}
235 257
236dotest() { 258dotest() {
@@ -285,8 +307,8 @@ build_test() {
285 rm runtest 307 rm runtest
286} 308}
287 309
288build_wasmtest() { 310build_webtest() {
289 obj="wasm" 311 obj="web"
290 testobj="runtest.js" 312 testobj="runtest.js"
291 testbuild="$EMCC $WASMCFLAGS $WFLAGS $WASMMFLAGS $DFLAGS -o $testobj" 313 testbuild="$EMCC $WASMCFLAGS $WFLAGS $WASMMFLAGS $DFLAGS -o $testobj"
292 testrun="$NODE $testobj" 314 testrun="$NODE $testobj"
@@ -294,15 +316,12 @@ build_wasmtest() {
294 rm -f runtest.js runtest.wasm 316 rm -f runtest.js runtest.wasm
295} 317}
296 318
297tool_usage() {
298 echo "usage: ./build tool PATTERN"
299}
300
301build_tool() { 319build_tool() {
302 pattern="$1" 320 pattern="$1"
303 321
304 if [ -z "$pattern" ]; then 322 if [ -z "$pattern" ]; then
305 tool_usage 323 echo "Please provide a valid PATTERN to select a tool"
324 echo "usage: ./build tool PATTERN"
306 exit 1 325 exit 1
307 fi 326 fi
308 shift 327 shift
@@ -361,7 +380,7 @@ fi
361 380
362case "$target" in 381case "$target" in
363help|config|clean|\ 382help|config|clean|\
364nissy|lib|sharedlib|shell|python|wasm|test|wasmtest|tool) 383nissy|lib|sharedlib|shell|python|cpp|web|test|webtest|tool)
365 mkdir -p tables tools/results 384 mkdir -p tables tools/results
366 (build_"$target" $@) || exit 1 385 (build_"$target" $@) || exit 1
367 exit 0 386 exit 0

Generated with cgit - Back to sebastiano.tronto.net