-
-
Notifications
You must be signed in to change notification settings - Fork 13
/
Copy pathgpuowl-wrapper.sh
310 lines (274 loc) · 8.81 KB
/
gpuowl-wrapper.sh
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
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
#!/bin/bash
# Copyright © 2020 Teal Dulcet
# Start the correct version of GpuOwl based on the next assignment in the worktodo file
# Run: ./gpuowl [GpuOwl arguments]...
set -e
# GpuOwl directories
DIR=(
# 1. Current version of GpuOwl (master branch)
# Supports PRP tests and standalone P-1 stage 1 (requires MPrime for stage 2)
[1]="gpuowl-master"
# 2. GpuOwl v7.2-112
# Supports PRP tests combined with P-1
[2]="gpuowl-7.2"
# 3. GpuOwl v6.11 (v6 branch)
# Supports LL and standalone P-1 tests
[3]="gpuowl-6"
)
# GpuOwl arguments
# 1. Current version of GpuOwl (master branch)
ARGS1=(
# -mprimeDir ../mprime
-unsafeMath
# -use STATS
)
# 2. GpuOwl v7.2-112
ARGS2=(
-unsafeMath
-nospin
# -use STATS
)
# 3. GpuOwl v6.11 (v6 branch)
ARGS3=(
-cleanup
-log 10000
-nospin
# -use STATS
)
# GpuOwl version to use for each worktype
# PRP tests that need P-1
GPUOWL_PRP_PM1=2
# PRP tests that do NOT need P-1
GPUOWL_PRP=1
# LL tests
GPUOWL_LL=3
# Standalone P-1 tests
GPUOWL_PM1=3
# worktodo and results files for AutoPrimeNet
WorkFile="worktodo.ini"
ResultsFile="results.ini"
# worktodo and results files for GpuOwl
aWorkFile="worktodo.txt"
aResultsFile="results.txt"
# Limit GpuOwl GPU memory usage (MiB)
# maxAlloc=1024
# Maximum PRP proof power
PROOF_POWER=8
# Device number
DEVICE=0
# GpuOwl arguments for all versions
ARGS=(
-device $DEVICE
# -block 1000
# -results "$aResultsFile"
)
# Automatically restart
RESTART=1
# Ignore-failure
# FAILURE=1
# Time to delay automatic restart after failure (seconds)
TIME=1
# Lock file
LOCK="~lock"
exec 200>"$LOCK"
if ! flock -n 200; then
echo "Error: This script is already running." >&2
exit 1
fi
WORKPATTERN='^(Test|DoubleCheck|PRP(DC)?|P[Ff]actor|Cert)=((([[:xdigit:]]{32})|[Nn]/[Aa]|0),)?(([-+]?([[:digit:]]+(\.[[:digit:]]*)?|\.[[:digit:]]+)|"[[:digit:]]+(,[[:digit:]]+)*")(,|$)){1,9}$'
ARGS+=("$@")
echo
if command -v lspci >/dev/null; then
mapfile -t GPU < <(lspci 2>/dev/null | grep -i 'vga\|3d\|2d' | sed -n 's/^.*: //p')
fi
if [[ -n $GPU ]]; then
echo -e "Graphics Processor (GPU):\t${GPU[0]}$([[ ${#GPU[*]} -gt 1 ]] && printf '\n\t\t\t\t%s' "${GPU[@]:1}")"
# echo -e "Graphics Processor (GPU):\t${GPU[DEVICE]}"
fi
if command -v clinfo >/dev/null; then
mapfile -t TOTAL_GPU_MEM < <(clinfo --raw | sed -n 's/.*CL_DEVICE_GLOBAL_MEM_SIZE *//p')
for i in "${!TOTAL_GPU_MEM[@]}"; do
TOTAL_GPU_MEM[i]=$((TOTAL_GPU_MEM[i] >> 20))
done
elif command -v nvidia-smi >/dev/null && nvidia-smi >/dev/null; then
mapfile -t TOTAL_GPU_MEM < <(nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits | grep -iv 'not supported')
fi
if [[ -n $TOTAL_GPU_MEM ]]; then
# echo -e -n "\tGPU Memory (RAM):\t"
# for i in "${!TOTAL_GPU_MEM[@]}"; do
# echo -n "$( ((i)) && echo ", ")$(printf "%'d" "${TOTAL_GPU_MEM[i]}") MiB ($(numfmt --from=iec --to=iec-i "${TOTAL_GPU_MEM[i]}M")B)"
# done
# echo
echo -e "\tGPU Memory (RAM):\t$(printf "%'d" "${TOTAL_GPU_MEM[DEVICE]}") MiB ($(numfmt --from=iec --to=iec-i "${TOTAL_GPU_MEM[DEVICE]}M")B)"
fi
if [[ -z $maxAlloc ]]; then
if [[ -n $TOTAL_GPU_MEM ]]; then
maxAlloc=${TOTAL_GPU_MEM[DEVICE]}
else
echo "Warning: Could not determine total GPU Memory (RAM), please install clinfo. Assuming 1024 MiB (1 GiB)."
maxAlloc=1024
fi
fi
ARGS+=(-maxAlloc "$(echo "$maxAlloc" | awk '{ printf "%d", $1 * 0.9 }')M")
DISK_USAGE=$(df -k . | tail -n +2)
if [[ -n $DISK_USAGE ]]; then
DISK_MOUNT=$(echo "$DISK_USAGE" | awk '{ print $6 }')
TOTAL_DISK=$(echo "$DISK_USAGE" | awk '{ print $2 }')
AVAILABLE_DISK=$(echo "$DISK_USAGE" | awk '{ print $4 }')
echo -e "Disk space available:\t\t${DISK_MOUNT}: $(numfmt --from=iec --to=iec-i "${AVAILABLE_DISK}K")B / $(numfmt --from=iec --to=iec-i "${TOTAL_DISK}K")B ($(numfmt --from=iec --to=si "${AVAILABLE_DISK}K")B / $(numfmt --from=iec --to=si "${TOTAL_DISK}K")B)"
fi
echo
trap 'trap - INT; kill -INT "$$"' INT
while true; do
date
if [[ -r $aResultsFile ]] && mapfile -t aresults <"$aResultsFile" && ((${#aresults[*]})); then
printf "Found %'d new result(s) in %s. Moving to %s.\n" ${#aresults[*]} "${aResultsFile@Q}" "${ResultsFile@Q}"
for result in "${aresults[@]}"; do
if echo "$result" | grep -q 'gpuowl'; then
if [[ -r $WorkFile ]] && mapfile -t worktodo <"$WorkFile" && ((${#worktodo[*]})); then
if command -v jq >/dev/null; then
exponent=$(echo "$result" | jq -r '.exponent')
worktype=$(echo "$result" | jq -r '.worktype')
status=$(echo "$result" | jq -r '.status')
else
exponent=$(echo "$result" | python3 -c 'import sys, json; print(json.load(sys.stdin)["exponent"])')
worktype=$(echo "$result" | python3 -c 'import sys, json; print(json.load(sys.stdin)["worktype"])')
status=$(echo "$result" | python3 -c 'import sys, json; print(json.load(sys.stdin)["status"])')
fi
RE='^PRP'
if [[ $worktype == 'LL' ]]; then
if [[ $status == 'P' ]]; then
echo 'New Mersenne Prime!!!! M'"$exponent"' is prime!'
fi
elif [[ $worktype =~ $RE ]]; then
if [[ $status == 'P' ]]; then
echo 'New Probable Prime!!!! '"$exponent"' is a probable prime!'
fi
fi
for i in "${!worktodo[@]}"; do
if [[ ${worktodo[i]} =~ $WORKPATTERN ]]; then
work_type=${BASH_REMATCH[1]}
if [[ $work_type == "Test" || $work_type == "DoubleCheck" ]]; then
idx=2
else
idx=4
fi
n=$(echo "${worktodo[i]}" | cut -d, -f $idx)
if [[ $exponent -eq $n ]]; then
if [[ $worktype == 'LL' ]] && [[ $work_type == "Test" || $work_type == "DoubleCheck" ]]; then
unset 'worktodo[i]'
elif [[ $worktype =~ $RE ]] && [[ $work_type == "PRP" || $work_type == "PRPDC" ]]; then
unset 'worktodo[i]'
elif [[ $worktype == 'PM1' ]] && { [[ $work_type == "PFactor" || $work_type == "Pfactor" ]] || [[ $status == 'F' ]]; }; then
unset 'worktodo[i]'
fi
fi
fi
done
printf '%s\n' "${worktodo[@]}" >"$WorkFile"
fi
else
echo "Warning: Unknown result: $result"
fi
done
printf '%s\n' "${aresults[@]}" >>"$ResultsFile"
>"$aResultsFile"
else
echo "No results found."
fi
if ! [[ -r $aWorkFile ]] || ! mapfile -t aworktodo <"$aWorkFile" || ! ((${#worktodo[*]})); then
if [[ -r $WorkFile ]] && mapfile -t worktodo <"$WorkFile" && ((${#worktodo[*]})); then
printf "Found %'d work to do(s) in the %s file. Copying the first one to %s.\n" ${#worktodo[*]} "${WorkFile@Q}" "${aWorkFile@Q}"
printf '%s\n' "${worktodo[0]}" >>"$aWorkFile"
mapfile -t aworktodo <"$aWorkFile"
else
echo "Error: No work to do. Please run AutoPrimeNet or manually add some work to the ${WorkFile@Q} file." >&2
exit 1
fi
else
printf "Found %'d work to do(s) in the %s file.\n" ${#aworktodo[*]} "${aWorkFile@Q}"
fi
for work in "${aworktodo[@]}"; do
if [[ $work =~ $WORKPATTERN ]]; then
work_type=${BASH_REMATCH[1]}
case "$work_type" in
'Test')
work_type_str="Lucas-Lehmer test"
;;
'DoubleCheck')
work_type_str="Double-check"
;;
'PRP')
work_type_str="PRP"
;;
'PRPDC')
work_type_str="PRPDC"
;;
'PFactor' | 'Pfactor')
work_type_str="P-1"
;;
'Cert')
work_type_str="Certify"
;;
esac
if [[ $work_type == "Test" || $work_type == "DoubleCheck" ]]; then
idx=2
else
idx=4
fi
n=$(echo "$work" | cut -d, -f $idx)
printf "Starting %s of the exponent %'d\n" "$work_type_str" "$n"
case "$work_type" in
'Test' | 'DoubleCheck')
temp=$GPUOWL_LL
;;
'PRP' | 'PRPDC')
if (($(echo "$work" | awk -F, '{ print ($7>0) }'))); then
temp=$GPUOWL_PRP_PM1
else
temp=$GPUOWL_PRP
fi
;;
'PFactor' | 'Pfactor')
temp=$GPUOWL_PM1
;;
*)
echo "Error: Unsupported worktype for GpuOwl: $work" >&2
exit 1
;;
esac
dir=${DIR[temp]}
declare -n aargs="ARGS${temp}"
args=("${aargs[@]}" "${ARGS[@]}")
if [[ -n $PROOF_POWER ]]; then
proof_power=$PROOF_POWER
# Best proof powers adapted from Prime95/MPrime
best_power=$((n > 414200000 ? 11 : n > 106500000 ? 10 : n > 26600000 ? 9 : n > 6700000 ? 8 : n > 1700000 ? 7 : n > 420000 ? 6 : n > 105000 ? 5 : 0))
if [[ $proof_power -gt $best_power ]]; then
proof_power=$best_power
fi
args+=(-proof "$proof_power")
fi
echo -e "with GpuOwl $(<"$(if [[ -d ${dir}/src ]]; then echo ${dir}/src/version.inc; else echo ${dir}/version.inc; fi)").\n"
gpuowl=(nice "./${dir}/gpuowl" "${args[@]}")
if [[ -z $RESTART ]]; then
exec "${gpuowl[@]}"
else
"${gpuowl[@]}"
E=$?
if ((E)); then
if [[ -z $FAILURE ]]; then
echo "Error: GpuOwl terminated with non-zero exit code: $E" >&2
echo "If this is a GpuOwl bug, please create an issue: https://github.com/preda/gpuowl/issues" >&2
exit 1
fi
sleep -- "$TIME"
fi
sleep 1
fi
break
else
echo "Warning: Unknown worktype. Line ignored: ${work@Q}"
fi
done
done