forked from tdulcet/Distributed-Computing-Scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mlucas.sh
196 lines (183 loc) · 7.51 KB
/
mlucas.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
#!/bin/bash
# Teal Dulcet
# wget https://raw.github.com/tdulcet/Distributed-Computing-Scripts/master/mlucas.sh -qO - | bash -s --
# ./mlucas.sh <PrimeNet Password> [PrimeNet User ID] [Type of work] [Idle time to run]
# ./mlucas.sh <PrimeNet Password> "$USER" 100 10
# ./mlucas.sh <PrimeNet Password> ANONYMOUS
DIR2="mlucas_v19"
FILE2="mlucas_v19.txz"
SUM="7c48048cb6d935638447e45e0528fe9c"
if [[ $# -lt 1 || $# -gt 4 ]]; then
echo "Usage: $0 <PrimeNet Password> [PrimeNet User ID] [Type of work] [Idle time to run]" >&2
exit 1
fi
PASSWORD=$1
USERID=${2:-$USER}
TYPE=${3:-100}
TIME=${4:-10}
RE='^[0-9]{3}$'
if ! [[ $TYPE =~ $RE ]]; then
echo "Usage: [Type of work] must be a number" >&2
exit 1
fi
RE='^([0-9]*[.])?[0-9]+$'
if ! [[ $TIME =~ $RE ]]; then
echo "Usage: [Idle time to run] must be a number" >&2
exit 1
fi
echo -e "PrimeNet User ID:\t$USERID"
echo -e "PrimeNet Password:\t$PASSWORD"
echo -e "Type of work:\t\t$TYPE"
echo -e "Idle time to run:\t$TIME minutes\n"
wget https://raw.github.com/tdulcet/Distributed-Computing-Scripts/master/idletime.sh -qO - | bash -s
if [[ -d "$DIR2" ]]; then
echo "Error: Mlucas is already downloaded" >&2
exit 1
fi
if ! command -v make >/dev/null || ! command -v gcc >/dev/null; then
echo -e "Installing Make and the GNU C compiler"
echo -e "Please enter your password when prompted.\n"
sudo apt-get update -y
sudo apt-get install build-essential -y
fi
TIME=$(echo "$TIME" | awk '{ printf "%g", $1 * 60 }')
# Adapted from: https://github.com/tdulcet/Linux-System-Information/blob/master/info.sh
. /etc/os-release
echo -e "Linux Distribution:\t\t${PRETTY_NAME:-$ID-$VERSION_ID}"
KERNEL=$(</proc/sys/kernel/osrelease) # uname -r
echo -e "Linux Kernel:\t\t\t$KERNEL"
mapfile -t CPU < <(sed -n 's/^model name[[:space:]]*: *//p' /proc/cpuinfo | uniq)
if [[ -n "$CPU" ]]; then
echo -e "Processor (CPU):\t\t${CPU[0]}$([[ ${#CPU[*]} -gt 1 ]] && echo; printf '\t\t\t\t%s\n' "${CPU[@]:1}")"
fi
CPU_THREADS=$(nproc --all) # $(lscpu | grep -i '^cpu(s)' | sed -n 's/^.\+:[[:blank:]]*//p')
CPU_CORES=$(( CPU_THREADS / $(lscpu | grep -i '^thread(s) per core' | sed -n 's/^.\+:[[:blank:]]*//p') ))
echo -e "CPU Cores/Threads:\t\t$CPU_CORES/$CPU_THREADS"
ARCHITECTURE=$(getconf LONG_BIT)
echo -e "Architecture:\t\t\t$HOSTTYPE (${ARCHITECTURE}-bit)"
MEMINFO=$(</proc/meminfo)
TOTAL_PHYSICAL_MEM=$(echo "$MEMINFO" | awk '/^MemTotal:/ {print $2}')
echo -e "Total memory (RAM):\t\t$(printf "%'d" $((TOTAL_PHYSICAL_MEM / 1024))) MiB ($(printf "%'d" $((((TOTAL_PHYSICAL_MEM * 1024) / 1000) / 1000))) MB)"
TOTAL_SWAP=$(echo "$MEMINFO" | awk '/^SwapTotal:/ {print $2}')
echo -e "Total swap space:\t\t$(printf "%'d" $((TOTAL_SWAP / 1024))) MiB ($(printf "%'d" $((((TOTAL_SWAP * 1024) / 1000) / 1000))) MB)"
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 ]] && echo; printf '\t\t\t\t%s\n' "${GPU[@]:1}")"
fi
echo -e "\nDownloading Mlucas\n"
wget https://www.mersenneforum.org/mayer/src/C/$FILE2
if [[ ! "$(md5sum $FILE2 | head -c 32)" == "$SUM" ]]; then
echo "Error: md5sum does not match" >&2
echo "Please run \"rm -r $PWD\" and try running this script again" >&2
exit 1
fi
echo -e "\nDecompressing the files\n"
tar -xvf $FILE2
cd "$DIR2"
mkdir obj
cd obj
DIR=$PWD
ARGS=()
echo -e "\nBuilding Mlucas\n"
# for mode in avx512 avx2 avx sse2; do
# if grep -iq "$mode" /proc/cpuinfo; then
# echo -e "The CPU supports the ${mode^^} SIMD build mode.\n"
# ARGS+=( "-DUSE_${mode^^}" )
# break
# fi
# done
if grep -iq 'avx512' /proc/cpuinfo; then
echo -e "The CPU supports the AVX512 SIMD build mode.\n"
ARGS+=( "-DUSE_AVX512" -march=native )
elif grep -iq 'avx2' /proc/cpuinfo; then
echo -e "The CPU supports the AVX2 SIMD build mode.\n"
ARGS+=( "-DUSE_AVX2" -march=native -mavx2 )
elif grep -iq 'avx' /proc/cpuinfo; then
echo -e "The CPU supports the AVX SIMD build mode.\n"
ARGS+=( "-DUSE_AVX" -march=native -mavx )
elif grep -iq 'sse2' /proc/cpuinfo; then
echo -e "The CPU supports the SSE2 SIMD build mode.\n"
ARGS+=( "-DUSE_SSE2" -march=native )
fi
if grep -iq 'asimd' /proc/cpuinfo; then
echo -e "The CPU supports the ASIMD build mode.\n"
ARGS+=( "-DUSE_ARM_V8_SIMD" )
fi
cat << EOF > Makefile
OBJS=\$(patsubst ../src/%.c, %.o, \$(wildcard ../src/*.c))
Mlucas: \$(OBJS)
gcc -Wall -g -o \$@ \$(OBJS) -lm -lpthread -lrt
%.o: ../src/%.c
gcc -Wall -g -c -O3 ${ARGS[@]} -DUSE_THREADS \$<
clean:
rm -f *.o
EOF
make -j "$CPU_THREADS"
make clean
echo -e "\nTesting Mlucas\n"
./Mlucas -fftlen 192 -iters 100 -radset 0
ARGS=()
echo -e "\nOptimizing Mlucas for your computer\nThis may take awhile…\n"
if echo "${CPU[0]}" | grep -iq 'intel'; then
echo -e "The CPU is Intel.\n"
if [[ $CPU_CORES -ne $CPU_THREADS && $CPU_CORES -gt 1 ]]; then
ARGS+=( -cpu "0$(for ((j=CPU_CORES; j<CPU_THREADS; j+=CPU_CORES)); do echo -n ",$j"; done)" )
fi
elif echo "${CPU[0]}" | grep -iq 'amd'; then
echo -e "The CPU is AMD.\n"
if [[ $CPU_CORES -ne $CPU_THREADS && $CPU_THREADS -gt 1 ]]; then
# ARGS+=( -cpu "0:$(( CPU_THREADS - 1 )):$(( CPU_THREADS / CPU_CORES ))" )
ARGS+=( -cpu "0:$(( (CPU_THREADS / CPU_CORES) - 1 ))" )
fi
else
ARGS+=( -cpu "0:$(( CPU_CORES - 1 ))" )
fi
./Mlucas -s m "${ARGS[@]}"
RUNS=()
if echo "${CPU[0]}" | grep -iq 'intel'; then
echo -e "The CPU is Intel."
for ((i=0; i<CPU_CORES; ++i)); do
if [[ $CPU_CORES -ne $CPU_THREADS ]]; then
arg="$i$(for ((j=i+CPU_CORES; j<CPU_THREADS; j+=CPU_CORES)); do echo -n ",$j"; done)"
else
arg=$i
fi
RUNS+=( "$arg" )
done
elif echo "${CPU[0]}" | grep -iq 'amd'; then
echo -e "The CPU is AMD."
for ((i=0; i<CPU_CORES; ++i)); do
if [[ $CPU_CORES -ne $CPU_THREADS ]]; then
temp=$(( CPU_THREADS / CPU_CORES ))
# arg=$(( i * (CPU_THREADS / CPU_CORES) ))
arg="$(( i * temp )):$(( (i * temp) + temp - 1 ))"
else
arg=$i
fi
RUNS+=( "$arg" )
done
else
for ((i=0; i<CPU_CORES; i+=4)); do
arg="$i:$(if [[ $(( i + 3 )) -lt $CPU_CORES ]]; then echo "$(( i + 3 ))"; else echo "$(( CPU_CORES - 1 ))"; fi)"
RUNS+=( "$arg" )
done
fi
for i in "${!RUNS[@]}"; do
echo -e "\nCPU Core $i:"
mkdir "run$i"
pushd "run$i" > /dev/null
ln -s ../mlucas.cfg .
echo -e "\tStarting PrimeNet\n"
nohup python2 ../../src/primenet.py -d -T "$TYPE" -u "$USERID" -p "$PASSWORD" &
sleep 1
echo -e "\n\tStarting Mlucas\n"
nohup nice ../Mlucas -cpu "${RUNS[i]}" &
sleep 1
popd > /dev/null
done
echo -e "\nSetting it to start if the computer has not been used in the specified idle time and stop it when someone uses the computer\n"
#crontab -l | { cat; echo "$(for i in "${!RUNS[@]}"; do echo -n "(cd $DIR/run$i && nohup nice ../Mlucas -cpu \"${RUNS[i]}\" &); "; done)"; } | crontab -
#crontab -l | { cat; echo "$(for i in "${!RUNS[@]}"; do echo -n "(cd $DIR/run$i && nohup python2 ../../src/primenet.py -d -T \"$TYPE\" -u \"$USERID\" -p \"$PASSWORD\" &); "; done)"; } | crontab -
crontab -l | { cat; echo "* * * * * if who -s | awk '{ print \$2 }' | (cd /dev && xargs -r stat -c '\%U \%X') | awk '{if ('\"\${EPOCHSECONDS:-\$(date +\%s)}\"'-\$2<$TIME) { print \$1\"\t\"'\"\${EPOCHSECONDS:-\$(date +\%s)}\"'-\$2; ++count }} END{if (count>0) { exit 1 }}' > /dev/null; then pgrep Mlucas > /dev/null || $(for i in "${!RUNS[@]}"; do echo -n "(cd $DIR/run$i && nohup nice ../Mlucas -cpu \"${RUNS[i]}\" &); "; done) pgrep -f '^python2 \.\./\.\./src/primenet\.py' > /dev/null || $(for i in "${!RUNS[@]}"; do echo -n "(cd $DIR/run$i && nohup python2 ../../src/primenet.py -d -T \"$TYPE\" -u \"$USERID\" -p \"$PASSWORD\" &); "; done) else pgrep Mlucas > /dev/null && killall Mlucas; fi"; } | crontab -