forked from SevenChords/CipesAtHome
-
Notifications
You must be signed in to change notification settings - Fork 0
/
configuration_rng.mk
258 lines (228 loc) · 10.5 KB
/
configuration_rng.mk
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
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
# RNG_IMPLEMENTATION= : Choose which random number generator algorithm to use. If unset, then it chooses an unspecified default,
# possibly depending on platform, architecture, and optimization flags.
# The random number generator chosen has a surprisingly outsized influence on the throughput of recipesAtHome, which is why there
# are so many options available
# Supported values are: default, system, lehmer, wyhash, xoshiro, lcg, mersenne_twister, subtract_with_carry, pcg, pcg_cpp
# For furhter documentation, see RNG_Options.txt
# "canonical" name is always the first one
RECOGNIZED_SYSTEM_RNG_OPTIONS:=system sys rand builtin stdlib
RECOGNIZED_LEHMER_RNG_OPTIONS:=lehmer lehmer64
RECOGNIZED_WYHASH_RNG_OPTIONS:=wyhash wyhash64 wyhash-lemire wyhash64-lemire wyrand wyrand-lemire
RECOGNIZED_XOSHIRO_RNG_OPTIONS:=xoshiro xoshiro_cpp xoshiro-cpp
RECOGNIZED_LCG_RNG_OPTIONS:=lcg lcg-cpp linear_congruential_engine linear_congruential_engine-cpp
RECOGNIZED_MERSENNE_TWISTER_OPTIONS:=mersenne_twister mersenne_twister-cpp mersenne_twister_engine mersenne_twister_engine_cpp
RECOGNIZED_SUBTRACT_WITH_CARRY_OPTIONS:=subtract_with_carry subtract_with_carry-cpp subtract_with_carry_engine subtract_with_carry_engine-cpp lagged_fibonacci lagged_fibonacci-cpp
RECOGNIZED_PCG_OPTIONS:=pcg pcg_c pcg-c pcg-random
RECOGNIZED_PCG_CPP_OPTIONS:=pcg_cpp pcg-cpp pcg-random-cpp
_RECOGNIZED_RNG_OPTIONS_VARIABLES:=RECOGNIZED_SYSTEM_RNG_OPTIONS RECOGNIZED_LEHMER_RNG_OPTIONS RECOGNIZED_WYHASH_RNG_OPTIONS RECOGNIZED_XOSHIRO_RNG_OPTIONS RECOGNIZED_LCG_RNG_OPTIONS RECOGNIZED_MERSENNE_TWISTER_OPTIONS RECOGNIZED_SUBTRACT_WITH_CARRY_OPTIONS RECOGNIZED_PCG_OPTIONS RECOGNIZED_PCG_CPP_OPTIONS
_RECOGNIZED_RNG_OPTIONS_CANONICAL_NAMES:=$(foreach rng_option_var, $(_RECOGNIZED_RNG_OPTIONS_VARIABLES), $(firstword $($(rng_option_var))))
# The reason we have to mangle these is that we need these to be single words for the pariwise lookup to work.
# Wildcards would expand to multiple words, and "empty" would be 0 words.
# We expand these later into their actual usable values later (see _normalize_mangled_header defined below)
_RECOGNIZED_RNG_OPTIONS_HEADERS:=
_RECOGNIZED_RNG_OPTIONS_HEADERS+=NO_INSERT # system
_RECOGNIZED_RNG_OPTIONS_HEADERS+=internal/random_headers/lehmer64_cipes.h #lehmer
_RECOGNIZED_RNG_OPTIONS_HEADERS+=internal/random_headers/wyrand_cipes.h #wyhash
_RECOGNIZED_RNG_OPTIONS_HEADERS+=Xoshiro-cpp/XoshiroCpp.hpp # xoshiro
_RECOGNIZED_RNG_OPTIONS_HEADERS+=NO_INSERT # lcg
_RECOGNIZED_RNG_OPTIONS_HEADERS+=NO_INSERT # mersenne_twister
_RECOGNIZED_RNG_OPTIONS_HEADERS+=NO_INSERT # subtract_with_carry
_RECOGNIZED_RNG_OPTIONS_HEADERS+=pcg-c-basic/pcg_basic.h # pcg
_RECOGNIZED_RNG_OPTIONS_HEADERS+=WILDCARD_pcg-cpp/include/*.h # pcg-cpp
_RECOGNIZED_RNG_OPTIONS_NO_INCLUDE=system lcg mersenne_twister subtract_with_carry
_RECOGNIZED_RNG_OPTIONS_NEED_CPP=xoshiro lcg mersenne_twister subtract_with_carry pcg_cpp
_EMPTY:=
_normalize_mangled_header=$(if $(findstring NO_INSERT,$(firstword $1)),$(_EMPTY),$(if $(findstring WILDCARD_,$1),$(wildcard $(1:WILDCARD_)),$1))
_PRINT_RNG_HELP=Available options for RNG_IMPLEMENTATION: $(_RECOGNIZED_RNG_OPTIONS_CANONICAL_NAMES)
ifeq (help,$(RNG_IMPLEMENTATION))
$(info _PRINT_RNG_HELP)
$(error Stopping due to "help" for RNG_IMPLEMENTATION)
endif
-include gmsl
ifeq (T,$(true))
ifeq ($(true),$(call gmsl_compatible,1 1 8))
_HAS_GMSL=1
else
$(warning Incompatible GMSL version, tested against 1.1.8 but current version is $(gmsl_version). Unable to use GMSL, some configuration options will be limited)
_HAS_GMSL=0
endif
else
$(warning No GMSL (Gnu Make Standard Library) found, some configuration options will be limited)
_HAS_GMSL=0
endif
ORIGINAL_RNG_IMPLEMENTATION:=$(RNG_IMPLEMENTATION)
# Process defaults
ifeq (,$(RNG_IMPLEMENTATION))
RNG_IMPLEMENTATION=default
endif
ifeq ("",$(RNG_IMPLEMENTATION))
RNG_IMPLEMENTATION=default
endif
ifeq (default,$(RNG_IMPLEMENTATION))
# ifeq (1,$(IS_WINDOWS))
RNG_IMPLEMENTATION=lcg
# else
# RNG_IMPLEMENTATION=system
# endif
_FOUND_RNG_IMPLEMENTATION=$(RNG_IMPLEMENTATION)
else ifeq (1,$(_HAS_GMSL)) # Has GMSL
# The idea behind this is to find which canonical RNG mode the input RNG mode matches.
# Then from there, pariwise match per-RNG-mode properties and configure as needed.
# Populate the mapping from canonical_name -> name_of_variable_with_aliases
_add_to_rng_set=$(call set,_RECOGNIZED_RNG_OPTIONS_MAP,$1,$2)
$(call pairmap,_add_to_rng_set,$(_RECOGNIZED_RNG_OPTIONS_CANONICAL_NAMES),$(_RECOGNIZED_RNG_OPTIONS_VARIABLES))
# Find the first key where $(RNG_IMPLEMENTATION) matches one of the elements of the mapped variable name
_find_str_in_indirect_options=$(filter $1,$($2))
_indirect_lookup=$(call _find_str_in_indirect_options,$1,$(call get,_RECOGNIZED_RNG_OPTIONS_MAP,$2))
_POSSIBLE_MATCHES:=$(foreach key,$(_RECOGNIZED_RNG_OPTIONS_CANONICAL_NAMES),\
$(if $(call _indirect_lookup,$(RNG_IMPLEMENTATION),$(key)),$(key)))
_FOUND_RNG_IMPLEMENTATION:=$(firstword $(_POSSIBLE_MATCHES))
RNG_IMPLEMENTATION:=$(_FOUND_RNG_IMPLEMENTATION)
# Handle header files
_add_to_rng_headers=$(call set,_RECOGNIZED_RNG_OPTIONS_HEADERS_MAP,$1,$2)
$(call pairmap,_add_to_rng_headers,$(_RECOGNIZED_RNG_OPTIONS_CANONICAL_NAMES),$(_RECOGNIZED_RNG_OPTIONS_VARIABLES))
_RNG_HEADER_MANGLED:=$(call get,_RECOGNIZED_RNG_OPTIONS_HEADERS_MAP,$(RNG_IMPLEMENTATION))
# Verify that those in _RECOGNIZED_RNG_OPTIONS_NO_INCLUDE really are mapped to NO_INSERT
_verify_no_insert=$(call assert,$(filter NO_INSERT,$1))
$(foreach no_include_key,$(_RECOGNIZED_RNG_OPTIONS_NO_INCLUDE),$(call _verify_no_insert,$(call get,_RECOGNIZED_RNG_OPTIONS_HEADERS_MAP,$(no_include_key))))
else # No GSML
$(warning Can't lookup RNG_IMPLEMENTATION values using GMSL - only matching the canonical names, not the aliases)
RNG_IMPLEMENTATION:=$(filter $(RNG_IMPLEMENTATION),$(_RECOGNIZED_RNG_OPTIONS_CANONICAL_NAMES))
ifneq (,$(filter $(RNG_IMPLEMENTATION),$(_RECOGNIZED_RNG_OPTIONS_NO_INCLUDE)))
_RNG_HEADER_MANGLED:=NO_INCLUDE
else
$(warning Can't use automatic deps generation due to unknown header needed for random number selection, from no GMSL. Falling back to rebuilding on any RNG related header change)
RANDOM_HEADERS:=$(foreach raw_header,$(_RECOGNIZED_RNG_OPTIONS_HEADERS),$(call _normalize_mangled_header,$(raw_header)))
endif
endif
ifeq (,$(filter $(_FOUND_RNG_IMPLEMENTATION),$(_RECOGNIZED_RNG_OPTIONS_CANONICAL_NAMES)))
$(error Invalid value for RNG_IMPLEMENTATION, "$(ORIGINAL_RNG_IMPLEMENTATION)". $(_PRINT_RNG_HELP))
endif
CFLAGS_BASE+=-D_USE_$(RNG_IMPLEMENTATION)_RANDOM=1 -D_RANDOM_IMPL_STR=$(RNG_IMPLEMENTATION)
ifneq (,$(filter $(RNG_IMPLEMENTATION),$(_RECOGNIZED_RNG_OPTIONS_NEED_CPP)))
NEEDS_CPP=1
CFLAGS_BASE+=-D_USE_CPP_RANDOM=1
endif
# Flags needed for individual implementations
ifeq (xoshiro,$(RNG_IMPLEMENTATION))
# Suggested to get vecotorization to work well by https://prng.di.unimi.it/#remarks
RANDOM_FLAGS+=-fdisable-tree-cunrolli
ifeq (1,$(USE_LTO))
_NEED_MULTI_STAGE_FINAL_LINK_FOR_RANDOM=1
endif
ifeq (1,$(PERFORMANCE_PROFILING))
# For consistent profiling results: https://prng.di.unimi.it/#speed
RANDOM_FLAGS+=-fno-move-loop-invariants -fno-unroll-loops
endif
else ifeq (pcg,$(RNG_IMPLEMENTATION))
RANDOM_BASEDIR=pcg-c-basic
RANDOM_SRCS+=pcg-c-basic/pcg_basic.c
RANDOM_OBJS+=pcg-c-basic/pcg_basic.o
else ifeq (pcg-cpp,$(RNG_IMPLEMENTATION))
RANDOM_FLAGS+=-Ipcg-cpp/include
endif
ifeq (1,$(RNG_ALWAYS_USE_32_BIT_CHOICE))
BASE_CFLAGS+=-D_RNG_ALWAYS_USE_32_BIT_CHOICE=1
endif
ifndef RANDOM_HEADERS
NORMALIZED_RANDOM_HEADERS=$(call _normalize_mangled_header,$(_RNG_HEADER_MANGLED))
endif
ifneq (,NORMALIZED_RANDOM_HEADERS)
RANDOM_HEADERS:=$(NORMALIZED_RANDOM_HEADERS)
endif
# ifeq ($(firstword $(RECOGNIZED_SYSTEM_RNG_OPTIONS)), $(findstring $(RNG_IMPLEMENTATION),$(RECOGNIZED_SYSTEM_RNG_OPTIONS)))
#MULTILINE=A=a; \
# echo $${A}
#
#$(info $(MULTILINE))
#$(info $(shell $(MULTILINE)))
#
#IS_WINDOWS_HOST=0
## A crude metric, but it should work unless a user is doing something weird
#ifeq (${OS}, Windows_NT)
# IS_WINDOWS_HOST=1
#endif
#
##_CURRENT_SHELL=${SHELL}
##ifeq (,$(_CURRENT_SHELL))
## _ALREADY_IN_SH_LIKE=0
##else
## _ALREADY_IN_SH_LIKE=1
##endif
##
##ifeq $
##_HAS_SH=$(sh -c "echo hi")
#_HAS_BASH=$(shell bash -c "echo 1")
#_HAS_ZSH=$(shell zsh -c "echo 1")
##ifeq (hi,$(findstring hi,$(HAS_SH) $(HAS_BASH) $(HAS_ZSH)))
## HAS_SH_LIKE=
#
#
#_SHELL_END=
#
#$(info '_test_a=("a" "b c"); echo $${_test_a[@]} $${#_test_a[@]}')
#_ARRAY_TEST_OUTPUT:=$(shell _test_a=("a" "b c"); echo $${_test_a[@]} $${\#_test_a[@]})
#$(info $(_ARRAY_TEST_OUTPUT))
#ifeq (a b c 2,$(_ARRAY_TEST_OUTPUT))
# _SHELL_SUPPORTS_ARRAY_SYNTAX=1
#else
#ifeq (Darwin 1,$(shell uname) $(_HAS_ZSH))
# _SHELL_PREFIX:=$(shell which zsh) -c '
#else ifeq (1,$(_HAS_BASH))
# _SHELL_PREFIX :=$(shell which bash) -c '
#else ifeq (1,$(_HAS_ZSH))
# _SHELL_PREFIX :=$(shell which zsh) -c '
#endif
#$(info $(_SHELL_PREFIX))
#ifneq (,$(_SHELL_PREFIX))
#_SHELL_END:='
#$(info $(_SHELL_END))
#$(info $(_SHELL_PREFIX) _test_a=("a" "b c"); echo $${_test_a[@]} $${#_test_a[@]} $(_SHELL_END))
#_ARRAY_TEST_OUTPUT:=$(shell $(_SHELL_PREFIX) _test_a=("a" "b c"); echo $${_test_a[@]} $${\#_test_a[@]} $(_SHELL_END))
#$(info $(_ARRAY_TEST_OUTPUT))
#endif
#ifeq (a b c 2,$(_ARRAY_TEST_OUTPUT))
# _SHELL_SUPPORTS_ARRAY_SYNTAX=1
#else
#$(warning The current shell does not support array variables. Can't lookup RNG_IMPLEMENTATION values using aliases - only matching canonical names)
#_SHELL_SUPPORTS_ARRAY_SYNTAX=0
#endif
#endif
#
#quote_surround="$(1)"
#
#def_sh_var=$(1)=($($(1)))
#
#ifeq (1,$(_SHELL_SUPPORTS_ARRAY_SYNTAX))
#_MATCHED_RNG_OPTION_COMMAND=_RNG_CANONICAL_NAMES=($(_RECOGNIZED_RNG_OPTIONS_CANONICAL_NAMES)); \
#_RNG_OPTIONS_VARIABLES=($(_RECOGNIZED_RNG_OPTIONS_VARIABLES)); \
#_TO_MATCH="$(RNG_IMPLEMENTATION)"; \
#$(foreach v,$(_RECOGNIZED_RNG_OPTIONS_VARIABLES),$(call def_sh_var,$v);) \
#is_in_arr() { \
# local search_str="$${1}"; local arr_name="$${2}"; \
# for s in eval "echo \$${$$2[@]}"; do \
# if [ "$$search_str" = "$$s" ]; then return 0; fi; \
# done; \
# return 1 \
#}; \
#for i in $$(seq 0 $${\\\#_RNG_CANONICAL_NAMES[@]}); do \
# if is_in_arr "$$_TO_MATCH" "$${_RECOGNIZED_RNG_OPTIONS_VARIABLES[@]}"; then \
# echo "$${_RECOGNIZED_RNG_OPTIONS_CANONICAL_NAMES[$$i]}"; \
# _FOUND="1"; \
# break; \
# fi; \
# if [ "$${_FOUND}" != "1" ]; then \
# echo "unrecognized"; \
# false; \
# else \
# true; \
# fi; \
#done
#$(info $(_MATCHED_RNG_OPTION_COMMAND))
#_MATCHED_RNG_OPTION=$(shell $(_SHELL_PREFIX) $(_MATCHED_RNG_OPTION_COMMAND) $(_SHELL_END))
#else
#_MATCHED_RNG_OPTION=$(findstring $(RNG_IMPLEMENTATION),$(_RECOGNIZED_RNG_OPTIONS_CANONICAL_NAMES))
#endif
#
#$(info $(_MATCHED_RNG_OPTION))
#$(info $(_MATCHED_RNG_OPTION_COMMAND))