Skip to content

Commit 316b94b

Browse files
cmmarslenderrostislavsean-snSchaffHub
authored
HW VDF (#148)
Co-authored-by: Rostislav <[email protected]> Co-authored-by: sean-sn <[email protected]> Co-authored-by: Mike Schaffstein <[email protected]>
1 parent 89d4912 commit 316b94b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+14371
-147
lines changed

.github/workflows/hw-build.yml

+103
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
name: HW Build
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
release:
8+
types: [published]
9+
pull_request:
10+
branches:
11+
- '**'
12+
workflow_dispatch:
13+
14+
concurrency:
15+
# SHA is added to the end if on `main` to let all main workflows run
16+
group: ${{ github.ref }}-${{ github.workflow }}-${{ github.event_name }}-${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release/') || startsWith(github.ref, 'refs/heads/long_lived/')) && github.sha || '' }}
17+
cancel-in-progress: true
18+
19+
permissions:
20+
contents: write
21+
22+
jobs:
23+
build-hw:
24+
name: Build HW VDF Client
25+
runs-on: [ubuntu-latest]
26+
steps:
27+
- name: Checkout code
28+
uses: actions/checkout@v3
29+
with:
30+
fetch-depth: 0
31+
32+
- name: Set Env
33+
uses: Chia-Network/actions/setjobenv@main
34+
env:
35+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
36+
37+
- name: Install deps
38+
run: |
39+
sudo apt-get update
40+
sudo apt-get install -y build-essential cmake libgmp-dev libboost-system-dev
41+
42+
- name: Download USB drivers
43+
run: |
44+
mkdir libft4222
45+
cd libft4222
46+
wget https://download.chia.net/vdf/libft4222-linux-1.4.4.170.tgz
47+
tar -xvzf libft4222-linux-1.4.4.170.tgz
48+
ln -s ${{ github.workspace }}/libft4222 ${{ github.workspace }}/src/hw/libft4222
49+
ln -s ${{ github.workspace }}/libft4222/build-x86_64/libft4222.so.1.4.4.170 ${{ github.workspace }}/libft4222/build-x86_64/libft4222.so
50+
51+
- name: Compile
52+
working-directory: "${{ github.workspace }}/src"
53+
run: make -f Makefile.vdf-client emu_hw_test hw_test emu_hw_vdf_client hw_vdf_client
54+
55+
- name: Upload Artifacts
56+
uses: actions/upload-artifact@v3
57+
with:
58+
name: hw-vdf
59+
path: |
60+
${{ github.workspace }}/src/emu_hw_test
61+
${{ github.workspace }}/src/hw_test
62+
${{ github.workspace }}/src/hw_vdf_client
63+
${{ github.workspace }}/src/emu_hw_vdf_client
64+
${{ github.workspace }}/src/hw/libft4222/build-x86_64/libft4222.so
65+
66+
- name: Assemble .deb
67+
env:
68+
INSTALLER_VERSION: "${{ env.RELEASE_TAG || format('0.0.1-{0}', github.run_id) }}"
69+
PLATFORM: "amd64"
70+
run: |
71+
pip install j2cli
72+
CLI_DEB_BASE="chiavdf-hw_$INSTALLER_VERSION-1_$PLATFORM"
73+
mkdir -p "dist/$CLI_DEB_BASE/usr/bin"
74+
mkdir -p "dist/$CLI_DEB_BASE/usr/lib"
75+
mkdir -p "dist/$CLI_DEB_BASE/DEBIAN"
76+
mkdir -p "dist/$CLI_DEB_BASE/etc/udev/rules.d"
77+
j2 -o "dist/$CLI_DEB_BASE/DEBIAN/control" assets/deb/control.j2
78+
79+
cp ${{ github.workspace }}/src/emu_hw_test dist/$CLI_DEB_BASE/usr/bin/
80+
cp ${{ github.workspace }}/src/hw_test dist/$CLI_DEB_BASE/usr/bin/
81+
cp ${{ github.workspace }}/src/hw_vdf_client dist/$CLI_DEB_BASE/usr/bin/
82+
cp ${{ github.workspace }}/src/emu_hw_vdf_client dist/$CLI_DEB_BASE/usr/bin/
83+
cp ${{ github.workspace }}/src/hw/libft4222/build-x86_64/libft4222.so dist/$CLI_DEB_BASE/usr/lib/
84+
echo 'SUBSYSTEM=="usb", ATTRS{idVendor}=="0403", ATTRS{idProduct}=="601c", MODE="0666"' > dist/$CLI_DEB_BASE/etc/udev/rules.d/99-chiavdf.rules
85+
dpkg-deb --build --root-owner-group "dist/$CLI_DEB_BASE"
86+
87+
echo "DEB_NAME=$CLI_DEB_BASE.deb" >> $GITHUB_ENV
88+
89+
- name: Upload Installer
90+
uses: actions/upload-artifact@v3
91+
with:
92+
name: installer
93+
path: |
94+
${{ github.workspace }}/dist/${{ env.DEB_NAME }}
95+
96+
- name: Upload release artifacts
97+
if: env.RELEASE == 'true'
98+
env:
99+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
100+
run: |
101+
gh release upload \
102+
$RELEASE_TAG \
103+
dist/${{ env.DEB_NAME }}

.gitignore

+7
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ src/vdf_client
2525
src/1weso_test
2626
src/2weso_test
2727
src/prover_test
28+
src/emu_hw_test
29+
src/hw_test
30+
src/emu_hw_vdf_client
31+
src/hw_vdf_client
2832
/verifier
2933
/verifier_test
3034
/build/*
@@ -33,6 +37,9 @@ src/prover_test
3337
*.o
3438
*.s
3539

40+
# external library
41+
/src/hw/libft4222
42+
3643
# pyenv
3744
.python-version
3845
.eggs

README_ASIC.md

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
# ASIC timelord user guide
2+
3+
## Initial setup
4+
5+
Download and unpack LibFT4222 library:
6+
```bash
7+
# in chiavdf directory
8+
wget https://ftdichip.com/wp-content/uploads/2022/06/libft4222-linux-1.4.4.170.tgz
9+
mkdir src/hw/libft4222
10+
tar -C src/hw/libft4222 -xf libft4222-linux-1.4.4.170.tgz
11+
ln -s libft4222.so.1.4.4.170 src/hw/libft4222/build-x86_64/libft4222.so
12+
```
13+
14+
Build binaries:
15+
```bash
16+
cd src
17+
make -f Makefile.vdf-client emu_hw_test hw_test emu_hw_vdf_client hw_vdf_client
18+
```
19+
20+
Connect the Chia VDF ASIC device and verify that it is detected:
21+
```bash
22+
# in chiavdf/src/ directory
23+
LD_LIBRARY_PATH=hw/libft4222/build-x86_64 ./hw_vdf_client --list
24+
```
25+
26+
If the device is shown in the list, check if it's working:
27+
```bash
28+
LD_LIBRARY_PATH=hw/libft4222/build-x86_64 ./hw_test
29+
```
30+
31+
Output should contain lines similar to the following:
32+
```
33+
VDF 0: 1000000 HW iters done in 2s, HW speed: 714720 ips
34+
```
35+
36+
## Running
37+
38+
You should have a Chia full node running and synced.
39+
40+
Start timelord (but not timelord-launcher) in chia-blockchain:
41+
```bash
42+
chia start timelord-only
43+
```
44+
45+
Start hardware VDF client (`8000` specifies timelord's port number):
46+
```bash
47+
# in chiavdf/src/ directory
48+
LD_LIBRARY_PATH=hw/libft4222/build-x86_64 ./hw_vdf_client 8000
49+
```
50+
51+
The VDF client accepts a number of options:
52+
```
53+
Usage: ./hw_vdf_client [OPTIONS] PORT [N_VDFS]
54+
List of options [default, min - max]:
55+
--freq N - set ASIC frequency [1100, 200 - 2200]
56+
--voltage N - set board voltage [0.88, 0.7 - 1.0]
57+
--ip A.B.C.D - timelord IP address [localhost]
58+
Allows connecting to a timelord running on a remote host. Useful when running multiple machines with VDF hardware connecting to a single timelord.
59+
--vdfs-mask N - mask for enabling VDF engines [7, 1 - 7]
60+
The ASIC has 3 VDF engines numbered 0, 1, 2. If not running all 3 engines, the mask can be specified to enable specific engines. It must be the result of bitwise OR of the engine bits (1, 2, 4 for engines 0, 1, 2).
61+
--vdf-threads N - number of software threads per VDF engine [4, 2 - 64]
62+
Number of software threads computing intermediate values and proofs per VDF engine.
63+
--proof-threads N - number of proof threads per VDF engine
64+
Number of software threads only computing proofs per VDF engine. Must be less than --vdf-threads.
65+
--auto-freq-period N - auto-adjust frequency every N seconds [0, 10 - inf]
66+
--list - list available devices and exit
67+
```
68+
69+
## Shutting down
70+
71+
Stop timelord:
72+
```bash
73+
chia stop timelord-only
74+
```
75+
76+
Stop the VDF client by pressing Control-C or killing the process with `SIGTERM`.

assets/deb/control.j2

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Package: chiavdf-hw
2+
Version: {{ INSTALLER_VERSION }}
3+
Architecture: {{ PLATFORM }}
4+
Maintainer: Chia Network Inc <hello@chia.net>
5+
Description: Hardware VDF Client
6+
Depends: libgmp-dev, libboost-system-dev

src/Makefile.vdf-client

+25-6
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@ else
66
NOPIE = -no-pie
77
endif
88

9-
LDFLAGS += -flto $(NOPIE)
9+
LDFLAGS += -flto $(NOPIE) -g
1010
LDLIBS += -lgmpxx -lgmp -lboost_system -pthread
1111
CXXFLAGS += -flto -std=c++1z -D VDF_MODE=0 -D FAST_MACHINE=1 -pthread $(NOPIE) -fvisibility=hidden
1212
ifeq ($(UNAME),Darwin)
1313
CXXFLAGS += -D CHIAOSX=1
1414
endif
1515

16-
OPT_CFLAGS = -O3
16+
OPT_CFLAGS = -O3 -g
1717

1818
ifneq ($(ASAN),)
1919
LDFLAGS += -fsanitize=address -fsanitize=undefined
@@ -27,15 +27,16 @@ endif
2727

2828
.PHONY: all clean
2929

30-
all: vdf_client prover_test 1weso_test 2weso_test vdf_bench
30+
BINS = vdf_client prover_test 1weso_test 2weso_test vdf_bench
31+
all: $(BINS)
3132

3233
clean:
33-
rm -f *.o vdf_client prover_test 1weso_test 2weso_test compile_asm vdf_bench
34+
rm -f *.o hw/*.o $(BINS) compile_asm emu_hw_test hw_test hw_vdf_client emu_hw_vdf_client
3435

35-
vdf_client vdf_bench prover_test 1weso_test 2weso_test avx512_test: %: %.o lzcnt.o asm_compiled.o avx2_asm_compiled.o avx512_asm_compiled.o
36+
$(BINS) avx512_test: %: %.o lzcnt.o asm_compiled.o avx2_asm_compiled.o avx512_asm_compiled.o
3637
$(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS)
3738

38-
vdf_client.o vdf_bench.o prover_test.o 1weso_test.o 2weso_test.o avx512_test.o: CXXFLAGS += $(OPT_CFLAGS)
39+
$(addsuffix .o,$(BINS)) avx512_test.o: CXXFLAGS += $(OPT_CFLAGS)
3940

4041
lzcnt.o: refcode/lzcnt.c
4142
$(CC) -c refcode/lzcnt.c
@@ -51,3 +52,21 @@ avx512_asm_compiled.s: compile_asm
5152

5253
compile_asm: compile_asm.o
5354
$(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS)
55+
56+
HW_OBJS = $(addprefix hw/,hw_util.o hw_proof.o hw_interface.o chia_driver.o ftdi_driver.o vdf_driver.o pll_freqs.o) vdf_base.o lzcnt.o
57+
EMU_OBJS = hw/emu_funcs.o hw/emu_runner.o
58+
HW_LIB = hw/libft4222/build-x86_64/libft4222.so
59+
60+
hw_test: hw/hw_test.o $(HW_OBJS) $(HW_LIB) hw/real_hw.o
61+
$(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS)
62+
63+
emu_hw_test: hw/hw_test.o $(HW_OBJS) $(EMU_OBJS)
64+
$(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS)
65+
66+
hw_vdf_client: hw/hw_vdf_client.o $(HW_OBJS) $(HW_LIB) hw/real_hw.o
67+
$(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS)
68+
69+
emu_hw_vdf_client: hw/hw_vdf_client.o $(HW_OBJS) $(EMU_OBJS)
70+
$(CXX) $(LDFLAGS) -o $@ $^ $(LDLIBS)
71+
72+
hw/hw_test.o hw/hw_vdf_client.o $(HW_OBJS) $(EMU_OBJS): CXXFLAGS += -I. -Ihw -Ihw/libft4222 $(OPT_CFLAGS) -Wall

src/Reducer.h

+2-2
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ class alignas(64) Reducer {
6464
/**
6565
* @brief run - runs reduction algorithm for cg context params
6666
*/
67-
inline void run() {
67+
void run() {
6868
while (!isReduced()) {
6969
int_fast64_t a, b, c;
7070
{
@@ -229,7 +229,7 @@ bool bLZCHasHW=false;
229229

230230
// The condition (abs(v_) | abs(x_)) <= THRESH protects against
231231
// overflow
232-
below_threshold = (abs(v_) | abs(x_)) <= THRESH ? 1 : 0;
232+
below_threshold = (labs(v_) | labs(x_)) <= THRESH ? 1 : 0;
233233
} while (below_threshold && a > c && c > 0);
234234

235235
if (below_threshold) {

src/bqfc.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ enum BQFC_FLAGS {
161161
*/
162162
int bqfc_serialize_only(uint8_t *out_str, const struct qfb_c *c, size_t d_bits)
163163
{
164-
size_t offset, bytes, size, g_size;
164+
size_t offset, g_size;
165165

166166
d_bits = (d_bits + 31) & ~(size_t)31;
167167

src/bqfc.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ int bqfc_serialize_only(uint8_t *out_str, const struct qfb_c *c, size_t d_bits);
2727
int bqfc_deserialize_only(struct qfb_c *out_c, const uint8_t *str, size_t d_bits);
2828

2929
int bqfc_serialize(uint8_t *out_str, mpz_t a, mpz_t b, size_t d_bits);
30-
int bqfc_deserialize(mpz_t out_a, mpz_t out_b, const mpz_t D, const uint8_t *str, size_t d_bits);
30+
int bqfc_deserialize(mpz_t out_a, mpz_t out_b, const mpz_t D, const uint8_t *str, size_t size, size_t d_bits);
3131

3232
#endif // BQFC_H

src/hw/chia_driver.cpp

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include "chia_driver.hpp"
2+
3+
void ChiaDriver::SerializeJob(uint8_t *buf,
4+
uint32_t job_id,
5+
uint64_t iteration_count,
6+
mpz_t a,
7+
mpz_t f,
8+
mpz_t d,
9+
mpz_t l) {
10+
size_t offset = 0;
11+
const size_t reg_size = REG_BYTES;
12+
offset += write_bytes(reg_size, offset, buf, job_id);
13+
offset += write_bytes(2 * reg_size, offset, buf, iteration_count);
14+
offset += write_bytes(reg_size * CHIA_VDF_CMD_A_MULTIREG_COUNT,
15+
offset, buf, a, NUM_2X_COEFFS);
16+
offset += write_bytes(reg_size * CHIA_VDF_CMD_F_MULTIREG_COUNT,
17+
offset, buf, f, NUM_2X_COEFFS);
18+
offset += write_bytes(reg_size * CHIA_VDF_CMD_D_MULTIREG_COUNT,
19+
offset, buf, d, NUM_4X_COEFFS);
20+
offset += write_bytes(reg_size * CHIA_VDF_CMD_L_MULTIREG_COUNT,
21+
offset, buf, l, NUM_1X_COEFFS);
22+
// The last word is 0x1 to start the job
23+
offset += write_bytes(reg_size, offset, buf, (uint32_t)0x1);
24+
}
25+
26+
void ChiaDriver::DeserializeJob(uint8_t *buf,
27+
uint32_t &job_id,
28+
uint64_t &iteration_count,
29+
mpz_t a,
30+
mpz_t f) {
31+
size_t offset = 0;
32+
const size_t reg_size = REG_BYTES;
33+
offset += read_bytes(reg_size, offset, buf, job_id);
34+
offset += read_bytes(2 * reg_size, offset, buf, iteration_count);
35+
offset += read_bytes(reg_size * CHIA_VDF_STATUS_A_MULTIREG_COUNT,
36+
offset, buf, a, NUM_2X_COEFFS);
37+
offset += read_bytes(reg_size * CHIA_VDF_STATUS_F_MULTIREG_COUNT,
38+
offset, buf, f, NUM_2X_COEFFS);
39+
}

src/hw/chia_driver.hpp

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#ifndef CHIA_DRIVER_HPP
2+
#define CHIA_DRIVER_HPP
3+
4+
#include <gmp.h>
5+
6+
#include "vdf_driver.hpp"
7+
#include "chia_registers.hpp"
8+
9+
class ChiaDriver : public VdfDriver {
10+
public:
11+
const static unsigned NUM_1X_COEFFS = 18;
12+
const static unsigned NUM_2X_COEFFS = 34;
13+
const static unsigned NUM_3X_COEFFS = 52;
14+
const static unsigned NUM_4X_COEFFS = 68;
15+
16+
ChiaDriver() :
17+
VdfDriver(16 /*WORD_BITS*/, 19 /*REDUNDANT_BITS*/, true) {
18+
}
19+
20+
virtual size_t CmdSize() {
21+
return (CHIA_VDF_CMD_START_REG_OFFSET -
22+
CHIA_VDF_CMD_JOB_ID_REG_OFFSET + REG_BYTES);
23+
}
24+
25+
virtual size_t StatusSize() {
26+
return (CHIA_VDF_STATUS_END_REG_OFFSET -
27+
CHIA_VDF_STATUS_ITER_0_REG_OFFSET);
28+
}
29+
30+
void SerializeJob(uint8_t *buf,
31+
uint32_t job_id,
32+
uint64_t iteration_count,
33+
mpz_t a,
34+
mpz_t f,
35+
mpz_t d,
36+
mpz_t l);
37+
38+
void DeserializeJob(uint8_t *buf,
39+
uint32_t &job_id,
40+
uint64_t &iteration_count,
41+
mpz_t a,
42+
mpz_t f);
43+
};
44+
#endif

0 commit comments

Comments
 (0)