Skip to content

Commit 9d5a72c

Browse files
committed
Added install scripts for PRPLL.
1 parent 2fc9fe0 commit 9d5a72c

File tree

6 files changed

+498
-5
lines changed

6 files changed

+498
-5
lines changed

.github/workflows/ci.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,41 @@ jobs:
8181
run: shopt -s globstar; shellcheck -o avoid-nullary-conditions,check-extra-masked-returns,check-set-e-suppressed,deprecate-which,quote-safe-variables,require-double-brackets -s bash **/*.sh
8282
continue-on-error: true
8383

84+
PRPLL:
85+
name: PRPLL
86+
87+
runs-on: ${{ matrix.os }}
88+
strategy:
89+
matrix:
90+
os: [ubuntu-22.04, ubuntu-24.04]
91+
cxx: [g++, clang++]
92+
fail-fast: false
93+
env:
94+
CXX: ${{ matrix.cxx }}
95+
steps:
96+
- uses: actions/checkout@v6
97+
- name: Install
98+
run: |
99+
sudo apt-get update -y
100+
sudo apt-get install -y ocl-icd-opencl-dev pocl-opencl-icd
101+
- name: Before script
102+
run: |
103+
sed -i '/^GPU=/,/^fi/ s/^/# /' prpll.sh
104+
sed -i '/^nohup / s/^/# /' prpll.sh
105+
sed -i '/^python3 -OO / s/^/# /' prpll.sh
106+
$CXX --version
107+
- name: Script
108+
run: bash -e -o pipefail -- prpll.sh ANONYMOUS
109+
- uses: actions/upload-artifact@v4
110+
if: always()
111+
with:
112+
name: ${{ matrix.os }}_${{ matrix.cxx }}_prpll
113+
path: |
114+
prpll/
115+
- name: ShellCheck
116+
run: shopt -s globstar; shellcheck -o avoid-nullary-conditions,check-extra-masked-returns,check-set-e-suppressed,deprecate-which,quote-safe-variables,require-double-brackets -s bash **/*.sh
117+
continue-on-error: true
118+
84119
Mlucas:
85120
name: Mlucas
86121

README.md

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,17 @@ This script follows the recommended instructions on the [Mlucas README](https://
3838
wget -qO - https://raw.github.com/tdulcet/Distributed-Computing-Scripts/master/mlucas.sh | bash -s -- [PrimeNet User ID] [Computer name] [Type of work] [Idle time to run (mins)]
3939
```
4040

41+
### PRPLL
42+
43+
Downloads, builds, sets up and runs [PRPLL-NTT](https://github.com/gwoltman/gpuowl). PRPLL is the successor of GpuOwl and should be much faster. Downloads, sets up and runs [AutoPrimeNet](https://github.com/tdulcet/AutoPrimeNet) for automated PrimeNet assignments. Supports Nvidia, AMD and Intel GPUs supporting OpenCL. Note that PRPLL uses C++20 and thus requires at least the GNU C++ compiler 8. Run: `g++ --version` to output your version.
44+
45+
```
46+
wget -qO - https://raw.github.com/tdulcet/Distributed-Computing-Scripts/master/prpll.sh | bash -s -- [PrimeNet User ID] [Computer name] [Type of work] [Idle time to run (mins)]
47+
```
48+
4149
### GpuOwl
4250

43-
Downloads, builds, sets up and runs the latest version of [GpuOwl](https://github.com/preda/gpuowl) for PRP tests, version 7.2-112 for PRP tests with combined P-1 and the [v6 branch](https://github.com/preda/gpuowl/tree/v6) for LL and standalone P-1 tests. Downloads, sets up and runs [AutoPrimeNet](https://github.com/tdulcet/AutoPrimeNet) for automated PrimeNet assignments. Creates wrapper script to run the correct version of GpuOwl based on the next assignment. Supports Nvidia, AMD and Intel GPUs supporting OpenCL. Note that [GpuOwl uses C++20](https://github.com/preda/gpuowl#build) and thus requires at least the GNU C++ compiler 8. Run: `g++ --version` to output your version.
51+
Downloads, builds, sets up and runs the latest version of [GpuOwl](https://github.com/preda/gpuowl/tree/gpuowl) for PRP tests, version 7.2-112 for PRP tests with combined P-1 and the [v6 branch](https://github.com/preda/gpuowl/tree/v6) for LL and standalone P-1 tests. Downloads, sets up and runs [AutoPrimeNet](https://github.com/tdulcet/AutoPrimeNet) for automated PrimeNet assignments. Creates wrapper script to run the correct version of GpuOwl based on the next assignment. Supports Nvidia, AMD and Intel GPUs supporting OpenCL. Note that [GpuOwl uses C++20](https://github.com/preda/gpuowl/tree/gpuowl#build) and thus requires at least the GNU C++ compiler 8. Run: `g++ --version` to output your version.
4452

4553
```
4654
wget -qO - https://raw.github.com/tdulcet/Distributed-Computing-Scripts/master/gpuowl.sh | bash -s -- [PrimeNet User ID] [Computer name] [Type of work] [Idle time to run (mins)]
@@ -66,6 +74,12 @@ wget -qO - https://raw.github.com/tdulcet/Distributed-Computing-Scripts/master/m
6674
wget -qO - https://raw.github.com/tdulcet/Distributed-Computing-Scripts/master/cudalucas2.sh | bash -s -- <Computer number> [PrimeNet User ID] [Computer name] [Type of work] [Idle time to run]
6775
```
6876

77+
#### PRPLL
78+
79+
```
80+
wget -qO - https://raw.github.com/tdulcet/Distributed-Computing-Scripts/master/prpll2.sh | bash -s -- <Computer number> [PrimeNet User ID] [Computer name] [Type of work] [Idle time to run]
81+
```
82+
6983
#### GpuOwl
7084

7185
```

gpuowl.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ COMPUTER=${2:-$HOSTNAME}
2222
TYPE=${3:-150}
2323
TIME=${4:-10}
2424
DEVICE=0
25-
RE='^([4]|1(0[0124]|5[012345]))$'
25+
RE='^([4]|1(0[01246]|5[012345]))$'
2626
if ! [[ $TYPE =~ $RE ]]; then
2727
echo "Usage: [Type of work] must be a number" >&2
2828
exit 1
@@ -126,6 +126,7 @@ else
126126
wget https://github.com/preda/gpuowl/archive/$BRANCH3.tar.gz
127127
echo -e "\nDecompressing the files\n"
128128
tar -xzvf $BRANCH3.tar.gz
129+
mv -v gpuowl-$BRANCH3/ $DIR3/
129130
if output=$(curl -sf "https://api.github.com/repos/preda/gpuowl/compare/v6.11...$BRANCH3"); then
130131
if command -v jq >/dev/null; then
131132
behind_by=$(echo "$output" | jq '.behind_by')
@@ -146,6 +147,7 @@ else
146147
wget https://github.com/preda/gpuowl/archive/$BRANCH1.tar.gz
147148
echo -e "\nDecompressing the files\n"
148149
tar -xzvf $BRANCH1.tar.gz
150+
mv -v gpuowl-$BRANCH1/ $DIR1/
149151
if output=$(curl -sf 'https://api.github.com/repos/preda/gpuowl/tags?per_page=1'); then
150152
if command -v jq >/dev/null; then
151153
name=$(echo "$output" | jq -r '.[0].name')
@@ -200,7 +202,7 @@ for dir in $DIR1 $DIR2 $DIR3; do
200202
echo
201203
pushd "$dir" >/dev/null
202204
sed -i 's/-Wall -O2/-Wall -g -O3/' Makefile
203-
# sed -i 's/-O3/-O3 -flto -funsafe-math-optimizations -ffinite-math-only/' Makefile
205+
# -funsafe-math-optimizations
204206
sed -i 's/-O3/-O3 -flto -ffinite-math-only/' Makefile
205207
make -j "$(nproc)"
206208
# make clean

gpuowl2.sh

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ if ! [[ $N =~ $RE ]]; then
2828
echo "Usage: <Computer number> must be a number" >&2
2929
exit 1
3030
fi
31-
RE='^([4]|1(0[0124]|5[012345]))$'
31+
RE='^([4]|1(0[01246]|5[012345]))$'
3232
if ! [[ $TYPE =~ $RE ]]; then
3333
echo "Usage: [Type of work] must be a number" >&2
3434
exit 1
@@ -131,6 +131,7 @@ else
131131
wget https://github.com/preda/gpuowl/archive/$BRANCH3.tar.gz
132132
echo -e "\nDecompressing the files\n"
133133
tar -xzvf $BRANCH3.tar.gz
134+
mv -v gpuowl-$BRANCH3/ $DIR3/
134135
if output=$(curl -sf "https://api.github.com/repos/preda/gpuowl/compare/v6.11...$BRANCH3"); then
135136
if command -v jq >/dev/null; then
136137
behind_by=$(echo "$output" | jq '.behind_by')
@@ -151,6 +152,7 @@ else
151152
wget https://github.com/preda/gpuowl/archive/$BRANCH1.tar.gz
152153
echo -e "\nDecompressing the files\n"
153154
tar -xzvf $BRANCH1.tar.gz
155+
mv -v gpuowl-$BRANCH1/ $DIR2/
154156
if output=$(curl -sf 'https://api.github.com/repos/preda/gpuowl/tags?per_page=1'); then
155157
if command -v jq >/dev/null; then
156158
name=$(echo "$output" | jq -r '.[0].name')
@@ -186,7 +188,7 @@ else
186188
echo
187189
pushd "$dir" >/dev/null
188190
sed -i 's/-Wall -O2/-Wall -g -O3/' Makefile
189-
# sed -i 's/-O3/-O3 -flto -funsafe-math-optimizations -ffinite-math-only/' Makefile
191+
# -funsafe-math-optimizations
190192
sed -i 's/-O3/-O3 -flto -ffinite-math-only/' Makefile
191193
make -j "$(nproc)"
192194
# make clean

prpll.sh

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
#!/bin/bash
2+
3+
# Copyright © 2020 Teal Dulcet
4+
# wget -qO - https://raw.github.com/tdulcet/Distributed-Computing-Scripts/master/prpll.sh | bash -s --
5+
# ./prpll.sh [PrimeNet User ID] [Computer name] [Type of work] [Idle time to run (mins)]
6+
# ./prpll.sh "$USER" "$HOSTNAME" 150 10
7+
# ./prpll.sh ANONYMOUS
8+
9+
set -e
10+
11+
DIR="prpll"
12+
BRANCH=master
13+
if [[ $# -gt 4 ]]; then
14+
echo "Usage: $0 [PrimeNet User ID] [Computer name] [Type of work] [Idle time to run (mins)]" >&2
15+
exit 1
16+
fi
17+
USERID=${1:-$USER}
18+
COMPUTER=${2:-$HOSTNAME}
19+
TYPE=${3:-150}
20+
TIME=${4:-10}
21+
DEVICE=0
22+
RE='^1(0[01246]|5[01235])$'
23+
if ! [[ $TYPE =~ $RE ]]; then
24+
echo "Usage: [Type of work] must be a number" >&2
25+
exit 1
26+
fi
27+
RE='^([0-9]*\.)?[0-9]+$'
28+
if ! [[ $TIME =~ $RE ]]; then
29+
echo "Usage: [Idle time to run] must be a number" >&2
30+
exit 1
31+
fi
32+
echo -e "PrimeNet User ID:\t$USERID"
33+
echo -e "Computer name:\t\t$COMPUTER"
34+
echo -e "Type of work:\t\t$TYPE"
35+
echo -e "Idle time to run:\t$TIME minutes\n"
36+
if [[ -e idletime.sh ]]; then
37+
bash -- idletime.sh
38+
else
39+
wget -qO - https://raw.github.com/tdulcet/Distributed-Computing-Scripts/master/idletime.sh | bash -s
40+
fi
41+
if [[ -d $DIR ]]; then
42+
echo "Error: PRPLL is already downloaded" >&2
43+
exit 1
44+
fi
45+
GPU=$(lspci | grep -i 'vga\|3d\|2d')
46+
if ! echo "$GPU" | grep -iq 'amd\|nvidia\|intel'; then
47+
echo -e "Please enter your password if prompted.\n"
48+
sudo update-pciids
49+
GPU=$(lspci | grep -i 'vga\|3d\|2d')
50+
if ! echo "$GPU" | grep -iq 'amd\|nvidia\|intel'; then
51+
echo "$GPU" | sed -n 's/^.*: //p'
52+
echo "Error: This computer does not have an AMD, Nvidia or Intel GPU" >&2
53+
exit 1
54+
fi
55+
fi
56+
if command -v clinfo >/dev/null; then
57+
if [[ $(clinfo --raw | sed -n 's/^#PLATFORMS *//p') -eq 0 ]]; then
58+
clinfo
59+
echo "Error: This computer does not have an OpenCL platform" >&2
60+
exit 1
61+
fi
62+
fi
63+
if ! command -v make >/dev/null || ! command -v g++ >/dev/null; then
64+
echo -e "Installing Make and the GNU C++ compiler"
65+
echo -e "Please enter your password if prompted.\n"
66+
sudo apt-get update -y
67+
sudo apt-get install -y build-essential
68+
fi
69+
if [[ -n $CXX ]] && ! command -v "$CXX" >/dev/null; then
70+
echo "Error: $CXX is not installed." >&2
71+
exit 1
72+
fi
73+
CXX=${CXX:-g++}
74+
VERSION=$("$CXX" -dumpversion)
75+
RE='^g\+\+'
76+
if [[ $CXX =~ $RE && ${VERSION%%.*} -lt 8 ]]; then
77+
echo "Error: PRPLL requires at least the GNU C++ compiler 8 and you have $VERSION" >&2
78+
exit 1
79+
fi
80+
if ! command -v python3 >/dev/null; then
81+
echo "Error: Python 3 is not installed." >&2
82+
exit 1
83+
fi
84+
if ! ldconfig -p | grep -iq 'libOpenCL\.'; then
85+
echo -e "Installing the OpenCL library"
86+
echo -e "Please enter your password if prompted.\n"
87+
sudo apt-get update -y
88+
# sudo apt-get install -y ocl-icd-* opencl-headers clinfo
89+
sudo apt-get install -y ocl-icd-opencl-dev clinfo
90+
fi
91+
TIME=$(echo "$TIME" | awk '{ printf "%g", $1 * 60 }')
92+
if command -v git >/dev/null; then
93+
echo -e "Downloading PRPLL\n"
94+
git clone https://github.com/gwoltman/gpuowl.git "$DIR"
95+
cd "$DIR"
96+
git remote add upstream https://github.com/preda/gpuowl.git
97+
git fetch upstream
98+
sed -i 's/--dirty //' Makefile
99+
sed -i 's/ --match v\/prpll\/\*//' Makefile
100+
else
101+
echo -e "Downloading PRPLL\n"
102+
wget https://github.com/gwoltman/gpuowl/archive/$BRANCH.tar.gz
103+
echo -e "\nDecompressing the files\n"
104+
tar -xzvf $BRANCH.tar.gz
105+
mv -v gpuowl-$BRANCH/ "$DIR"/
106+
cd "$DIR"
107+
if output=$(curl -sf 'https://api.github.com/repos/gwoltman/gpuowl/tags?per_page=1'); then
108+
if command -v jq >/dev/null; then
109+
name=$(echo "$output" | jq -r '.[0].name')
110+
else
111+
name=$(echo "$output" | python3 -c 'import sys, json; print(json.load(sys.stdin)[0]["name"])')
112+
fi
113+
if output=$(curl -sf "https://api.github.com/repos/gwoltman/gpuowl/compare/$BRANCH...$name"); then
114+
if command -v jq >/dev/null; then
115+
behind_by=$(echo "$output" | jq '.behind_by')
116+
sha=$(echo "$output" | jq -r '.base_commit.sha')
117+
else
118+
behind_by=$(echo "$output" | python3 -c 'import sys, json; print(json.load(sys.stdin)["behind_by"])')
119+
sha=$(echo "$output" | python3 -c 'import sys, json; print(json.load(sys.stdin)["base_commit"]["sha"])')
120+
fi
121+
fi
122+
sed -i 's/\\`git describe --tags --long --dirty --always --match v\/prpll\/\*\\`/'"${name}${behind_by:+-${behind_by}${sha:+-g${sha::7}}}"'/' Makefile
123+
fi
124+
fi
125+
DIR=$PWD
126+
echo -e "\nDownloading AutoPrimeNet\n"
127+
if [[ -e ../autoprimenet.py ]]; then
128+
cp -v ../autoprimenet.py .
129+
else
130+
wget -nv https://raw.github.com/tdulcet/AutoPrimeNet/main/autoprimenet.py
131+
fi
132+
chmod +x autoprimenet.py
133+
python3 -OO -m py_compile autoprimenet.py
134+
echo -e "\nInstalling the Requests library\n"
135+
# python3 -m ensurepip --default-pip || true
136+
python3 -m pip install --upgrade pip || true
137+
if ! python3 -m pip install requests; then
138+
if command -v pip3 >/dev/null; then
139+
pip3 install requests
140+
else
141+
echo -e "\nWarning: Python pip3 is not installed and the Requests library may also not be installed\n"
142+
fi
143+
fi
144+
echo -e "\nSetting up PRPLL\n"
145+
echo "-user $USERID -cpu ${COMPUTER//[[:space:]]/_}" >config.txt
146+
sed -i 's/^CXX =/CXX ?=/' Makefile
147+
# -funsafe-math-optimizations
148+
sed -i 's/-O2/-Wall -g -O3 -flto -ffinite-math-only/' Makefile
149+
make -j "$(nproc)"
150+
# make clean
151+
pushd build-release >/dev/null
152+
rm -- *.o
153+
mv -v prpll ..
154+
popd >/dev/null
155+
echo -e "\nRegistering computer with PrimeNet\n"
156+
ARGS=()
157+
if command -v clinfo >/dev/null; then
158+
clinfo=$(clinfo --raw)
159+
mapfile -t GPU < <(echo "$clinfo" | sed -n 's/.*CL_DEVICE_NAME *//p')
160+
ARGS+=(--cpu-model="${GPU[DEVICE]//\[*\]/}")
161+
162+
mapfile -t GPU_FREQ < <(echo "$clinfo" | sed -n 's/.*CL_DEVICE_MAX_CLOCK_FREQUENCY *//p')
163+
ARGS+=(--frequency="${GPU_FREQ[DEVICE]}")
164+
165+
mapfile -t TOTAL_GPU_MEM < <(echo "$clinfo" | sed -n 's/.*CL_DEVICE_GLOBAL_MEM_SIZE *//p')
166+
maxAlloc=$((TOTAL_GPU_MEM[DEVICE] >> 20))
167+
ARGS+=(--memory="$maxAlloc" --max-memory="$(echo "$maxAlloc" | awk '{ printf "%d", $1 * 0.9 }')")
168+
elif command -v nvidia-smi >/dev/null && nvidia-smi >/dev/null; then
169+
mapfile -t GPU < <(nvidia-smi --query-gpu=gpu_name --format=csv,noheader)
170+
ARGS+=(--cpu-model="${GPU[DEVICE]}")
171+
172+
mapfile -t GPU_FREQ < <(nvidia-smi --query-gpu=clocks.max.gr --format=csv,noheader,nounits | grep -iv 'not supported')
173+
if [[ -n $GPU_FREQ ]]; then
174+
ARGS+=(--frequency="${GPU_FREQ[DEVICE]}")
175+
fi
176+
177+
mapfile -t TOTAL_GPU_MEM < <(nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits | grep -iv 'not supported')
178+
if [[ -n $TOTAL_GPU_MEM ]]; then
179+
maxAlloc=${TOTAL_GPU_MEM[DEVICE]}
180+
ARGS+=(--memory="$maxAlloc" --max-memory="$(echo "$maxAlloc" | awk '{ printf "%d", $1 * 0.9 }')")
181+
fi
182+
fi
183+
python3 -OO autoprimenet.py -t 0 -T "$TYPE" -u "$USERID" --prpll -H "$COMPUTER" "${ARGS[@]}"
184+
echo -e "\nStarting AutoPrimeNet\n"
185+
nohup python3 -OO autoprimenet.py >>'autoprimenet.out' &
186+
sleep 1
187+
echo -e "\nTuning PRPLL for your computer and GPU\nThis may take a while…\n"
188+
time ./prpll -device $DEVICE -tune minexp=0
189+
sed -i '/-log/ s/^/# /' config.txt
190+
echo -e "\nStarting PRPLL\n"
191+
nohup ./prpll -device $DEVICE >>"prpll.out" &
192+
sleep 1
193+
#crontab -l | { cat; echo "@reboot cd ${DIR@Q} && nohup ./prpll -device $DEVICE >> 'prpll.out' &"; } | crontab -
194+
#crontab -l | { cat; echo "@reboot cd ${DIR@Q} && nohup python3 -OO autoprimenet.py >> 'autoprimenet.out' &"; } | crontab -
195+
cat <<EOF >prpll.sh
196+
#!/bin/bash
197+
198+
# Copyright © 2020 Teal Dulcet
199+
# Start PRPLL and AutoPrimeNet if the computer has not been used in the specified idle time and stop it when someone uses the computer
200+
# ${DIR@Q}/prpll.sh
201+
202+
NOW=\${EPOCHSECONDS:-\$(date +%s)}
203+
204+
if who -s | awk '{ print \$2 }' | (cd /dev && xargs -r stat -c '%U %X') | awk '{if ('"\$NOW"'-\$2<$TIME) { print \$1"\t"'"\$NOW"'-\$2; ++count }} END{if (count>0) { exit 1 }}' >/dev/null; then
205+
pgrep -x prpll >/dev/null || (cd ${DIR@Q} && exec nohup ./prpll -device $DEVICE >>'prpll.out' &)
206+
pgrep -f '^python3 -OO autoprimenet\.py' >/dev/null || (cd ${DIR@Q} && exec nohup python3 -OO autoprimenet.py >>'autoprimenet.out' &)
207+
else
208+
pgrep -x prpll >/dev/null && killall -g -INT prpll
209+
fi
210+
EOF
211+
chmod +x prpll.sh
212+
echo -e "\nRun this command for it to start if the computer has not been used in the specified idle time and stop it when someone uses the computer:\n"
213+
echo "crontab -l | { cat; echo \"* * * * * ${DIR@Q}/prpll.sh\"; } | crontab -"
214+
echo -e "\nTo edit the crontab, run \"crontab -e\""

0 commit comments

Comments
 (0)