Skip to content

Commit

Permalink
Merge pull request #131 from spacemeshos/130-opencl-integration
Browse files Browse the repository at this point in the history
OpenCL initialization integration
  • Loading branch information
fasmat authored May 10, 2023
2 parents d801f75 + c5f1ef5 commit e229cb9
Show file tree
Hide file tree
Showing 27 changed files with 765 additions and 269 deletions.
6 changes: 6 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ jobs:
go-version: ${{ env.go-version }}
- name: setup env
run: make install
- name: Add OpenCL support for Linux
if: ${{ matrix.os == 'ubuntu-latest' }}
run: sudo apt-get update -q && sudo apt-get install -qy ocl-icd-opencl-dev libpocl2 clinfo
- name: Add OpenCL support for Windows
if: ${{ matrix.os == 'windows-latest' }}
run: choco install opencl-intel-cpu-runtime
- name: Clear test cache
run: make clear-test-cache
- name: unit tests
Expand Down
4 changes: 2 additions & 2 deletions .golangci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -366,15 +366,15 @@ linters:
# - gocyclo
# - lll
# - prealloc

# Enable all available linters.
# Default: false
enable-all: false

# Disable specific linter
# https://golangci-lint.run/usage/linters/#disabled-by-default
# disable:

# Run only fast linters from enabled linters set (first run won't be fast)
# Default: false
fast: false
Expand Down
96 changes: 44 additions & 52 deletions Makefile.Inc
Original file line number Diff line number Diff line change
Expand Up @@ -10,61 +10,60 @@ export GOARM
export BIN_DIR

CGO_TEST_LDFLAGS = $(CGO_LDFLAGS) -Wl,-rpath,$(BIN_DIR)
DYLD_LIBRARY_PATH = $(BIN_DIR)

ifeq ($(OS),Windows_NT)
HOST_OS := windows
HOST_OS := windows
else
HOST_OS := $(shell uname | tr [A-Z] [a-z])
HOST_OS := $(shell uname | tr [A-Z] [a-z])
endif

ifeq ($(GOOS),)
GOOS := $(HOST_OS)
GOOS := $(HOST_OS)
endif

ifeq ($(GOARCH),)
GOARCH := $(shell go env GOARCH)
GOARCH := $(shell go env GOARCH)
endif

ifeq ($(GOOS),windows)
platform := windows
export PATH := $(PATH):$(PROJ_DIR)build
EXE := .exe
platform := windows
export PATH := $(PATH):$(PROJ_DIR)build
EXE := .exe
else
TEMP := /tmp
ifeq ($(GOOS),darwin)
ifeq ($(GOARCH),arm64)
platform := macos-m1
else
platform := macos
endif
CGO_LDFLAGS := $(CGO_LDFLAGS) -Wl,-rpath,@loader_path
ULIMIT := ulimit -n 9999;
else
ifeq ($(GOARCH),arm64)
platform := linux-arm64
else
platform := linux
endif
CGO_LDFLAGS := $(CGO_LDFLAGS) -Wl,-rpath,$$ORIGIN
endif
TEMP := /tmp
ifeq ($(GOOS),darwin)
ifeq ($(GOARCH),arm64)
platform := macos-m1
else
platform := macos
endif
CGO_LDFLAGS := $(CGO_LDFLAGS) -Wl,-rpath,@loader_path
ULIMIT := ulimit -n 9999;
else
ifeq ($(GOARCH),arm64)
platform := linux-arm64
else
platform := linux
endif
CGO_LDFLAGS := $(CGO_LDFLAGS) -Wl,-rpath,$$ORIGIN
endif
endif

ifneq ($(VERBOSE),)
$(info "OS: $(OS), HOST_OS: $(HOST_OS), GOOS: $(GOOS), GOARCH: $(GOARCH), BIN_DIR: $(BIN_DIR), platform: $(platform)")
$(info "OS: $(OS), HOST_OS: $(HOST_OS), GOOS: $(GOOS), GOARCH: $(GOARCH), BIN_DIR: $(BIN_DIR), platform: $(platform)")
endif

GPU_SETUP_REV = 0.1.29
GPU_SETUP_ZIP = libgpu-setup-$(platform)-$(GPU_SETUP_REV).zip
GPU_SETUP_URL_ZIP = https://github.com/spacemeshos/gpu-post/releases/download/v$(GPU_SETUP_REV)/$(GPU_SETUP_ZIP)
ifeq ($(platform), windows)
GPU_SETUP_LIBS = gpu-setup.dll gpu-setup.lib libgpu-setup.a api.h
GPU_SETUP_LIBS = gpu-setup.dll gpu-setup.lib libgpu-setup.a api.h
else
ifeq ($(platform), $(filter $(platform), macos macos-m1))
GPU_SETUP_LIBS = libgpu-setup.dylib libMoltenVK.dylib libvulkan.1.dylib MoltenVK_icd.json api.h
else
GPU_SETUP_LIBS = libgpu-setup.so api.h
endif
ifeq ($(platform), $(filter $(platform), macos macos-m1))
GPU_SETUP_LIBS = libgpu-setup.dylib libMoltenVK.dylib libvulkan.1.dylib MoltenVK_icd.json api.h
else
GPU_SETUP_LIBS = libgpu-setup.so api.h
endif
endif

BINDIR_GPU_SETUP_LIBS = $(foreach X,$(GPU_SETUP_LIBS),$(BIN_DIR)$(X))
Expand All @@ -79,35 +78,30 @@ $(PROJ_DIR)$(GPU_SETUP_ZIP):
get-gpu-setup: $(PROJ_DIR)$(GPU_SETUP_ZIP) $(BINDIR_GPU_SETUP_LIBS)
.PHONY: get-gpu-setup


####################################################
# post-rs (https://github.com/spacemeshos/post-rs) #
####################################################
POSTRS_SETUP_REV = 0.1.8
POSTRS_SETUP_ZIP = libpost-$(platform)-v$(POSTRS_SETUP_REV).zip
POSTRS_SETUP_URL_ZIP ?= https://github.com/spacemeshos/post-rs/releases/download/v$(POSTRS_SETUP_REV)/$(POSTRS_SETUP_ZIP)
ifeq ($(platform), windows)
POSTRS_SETUP_LIBS = prover.h post.dll
POSTRS_SETUP_LIBS = prover.h post.dll
else
ifeq ($(platform), $(filter $(platform), macos macos-m1))
POSTRS_SETUP_LIBS = prover.h libpost.dylib
else
POSTRS_SETUP_LIBS = prover.h libpost.so
endif
ifeq ($(platform), $(filter $(platform), macos macos-m1))
POSTRS_SETUP_LIBS = prover.h libpost.dylib
else
POSTRS_SETUP_LIBS = prover.h libpost.so
endif
endif

POSTRS_SETUP_REV = 0.1.7
POSTRS_SETUP_ZIP = libpost-$(platform)-v$(POSTRS_SETUP_REV).zip
POSTRS_SETUP_URL_ZIP ?= https://github.com/spacemeshos/post-rs/releases/download/v$(POSTRS_SETUP_REV)/$(POSTRS_SETUP_ZIP)

BINDIR_POSTRS_SETUP_LIBS = $(foreach X,$(POSTRS_SETUP_LIBS),$(BIN_DIR)$(X))
$(BINDIR_POSTRS_SETUP_LIBS): $(PROJ_DIR)$(POSTRS_SETUP_ZIP)
unzip -o -j "$(PROJ_DIR)$(POSTRS_SETUP_ZIP)" -d "$(BIN_DIR)" "**/$(notdir $@)"
mkdir -p $(dir $@)
unzip -o -j $(PROJ_DIR)$(POSTRS_SETUP_ZIP) -d $(dir $@) "**/$(notdir $@)"
touch $@

$(PROJ_DIR)$(POSTRS_SETUP_ZIP):
curl -L $(POSTRS_SETUP_URL_ZIP) -o $(PROJ_DIR)$(POSTRS_SETUP_ZIP)

get-postrs-lib: $(PROJ_DIR)$(POSTRS_SETUP_ZIP) $(BINDIR_POSTRS_SETUP_LIBS)


SUBDIRS_LVL1 := $(foreach X,$(wildcard $(dir $(PROJ_DIR))*/.), $(lastword $(subst /, ,$(dir $(X)))))
SUBDIRS_ONLY := $(sort \
$(foreach X,$(SUBDIRS_LVL1),\
Expand Down Expand Up @@ -150,11 +144,9 @@ go-env-test: get-gpu-setup
.PHONY: go-env-test

print-env: get-gpu-setup
@echo CGO_CFLAGS="$(CGO_CFLAGS)"
@echo CGO_LDFLAGS="$(CGO_LDFLAGS)"
@echo CGO_CFLAGS="\"$(CGO_CFLAGS)\"" CGO_LDFLAGS="\"$(CGO_LDFLAGS)\""
.PHONY: print-env

print-test-env: get-gpu-setup
@echo CGO_CFLAGS="$(CGO_CFLAGS)"
@echo CGO_TEST_LDFLAGS="$(CGO_TEST_LDFLAGS)"
@echo CGO_CFLAGS="\"$(CGO_CFLAGS)\"" CGO_LDFLAGS="\"$(CGO_TEST_LDFLAGS)\""
.PHONY: print-test-env
12 changes: 8 additions & 4 deletions cmd/postcli/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (
"github.com/davecgh/go-spew/spew"

"github.com/spacemeshos/post/config"
"github.com/spacemeshos/post/gpu"
"github.com/spacemeshos/post/initialization"
"github.com/spacemeshos/post/internal/postrs"
"github.com/spacemeshos/post/proving"
"github.com/spacemeshos/post/shared"
"github.com/spacemeshos/post/verifying"
Expand All @@ -42,7 +42,7 @@ func parseFlags() {
flag.BoolVar(&genProof, "genproof", false, "generate proof as a sanity test, after initialization")
flag.StringVar(&opts.DataDir, "datadir", opts.DataDir, "filesystem datadir path")
flag.Uint64Var(&opts.MaxFileSize, "maxFileSize", opts.MaxFileSize, "max file size")
flag.IntVar(&opts.ComputeProviderID, "provider", opts.ComputeProviderID, "compute provider id (required)")
flag.IntVar(&opts.ProviderID, "provider", opts.ProviderID, "compute provider id (required)")
flag.Uint64Var(&cfg.LabelsPerUnit, "labelsPerUnit", cfg.LabelsPerUnit, "the number of labels per unit")
flag.BoolVar(&reset, "reset", false, "whether to reset the datadir before starting")
flag.StringVar(&idHex, "id", "", "miner's id (public key), in hex (will be auto-generated if not provided)")
Expand All @@ -54,7 +54,7 @@ func parseFlags() {
}

func processFlags() error {
if opts.ComputeProviderID < 0 {
if opts.ProviderID < 0 {
return errors.New("-provider flag is required")
}

Expand Down Expand Up @@ -90,7 +90,11 @@ func main() {
parseFlags()

if printProviders {
spew.Dump(gpu.Providers())
providers, err := postrs.OpenCLProviders()
if err != nil {
log.Panic("cli: failed to get OpenCL providers: %v", err)
}
spew.Dump(providers)
return
}

Expand Down
26 changes: 13 additions & 13 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,12 @@ func DefaultConfig() Config {
}

type InitOpts struct {
DataDir string
NumUnits uint32
MaxFileSize uint64
ComputeProviderID int
Throttle bool
Scrypt ScryptParams
DataDir string
NumUnits uint32
MaxFileSize uint64
ProviderID int
Throttle bool
Scrypt ScryptParams
// ComputeBatchSize must be greater than 0
ComputeBatchSize uint64
}
Expand Down Expand Up @@ -112,13 +112,13 @@ const BestProviderID = -1

func DefaultInitOpts() InitOpts {
return InitOpts{
DataDir: DefaultDataDir,
NumUnits: defaultMinNumUnits + 1,
MaxFileSize: defaultMaxFileSize,
ComputeProviderID: BestProviderID,
Throttle: false,
Scrypt: DefaultLabelParams(),
ComputeBatchSize: DefaultComputeBatchSize,
DataDir: DefaultDataDir,
NumUnits: defaultMinNumUnits + 1,
MaxFileSize: defaultMaxFileSize,
ProviderID: BestProviderID,
Throttle: false,
Scrypt: DefaultLabelParams(),
ComputeBatchSize: DefaultComputeBatchSize,
}
}

Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ require (
github.com/klauspost/cpuid/v2 v2.2.1 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
golang.org/x/sys v0.7.0 // indirect
golang.org/x/sys v0.8.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ github.com/zeebo/pcg v1.0.1/go.mod h1:09F0S9iiKrwn9rlI5yjLkmrug154/YRW6KnnXVDM/l
golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.7.0 h1:3jlCCIQZPdOYu1h8BkNvLz8Kgwtae2cagcG/VamtZRU=
golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
Expand Down
30 changes: 30 additions & 0 deletions initialization/benchmark.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package initialization

import (
"time"

"github.com/spacemeshos/post/internal/postrs"
)

// Benchmark returns the hashes per second the selected compute provider achieves on the current machine.
func Benchmark(p ComputeProvider) (int, error) {
endPosition := uint64(1 << 14)
if p.DeviceType == postrs.ClassCPU {
endPosition = uint64(1 << 12)
}

start := time.Now()
_, err := postrs.ScryptPositions(
postrs.WithProviderID(p.ID),
postrs.WithCommitment(make([]byte, 32)),
postrs.WithStartAndEndPosition(1, endPosition),
postrs.WithScryptN(8192),
)
elapsed := time.Since(start)
if err != nil {
return 0, err
}

hashesPerSecond := float64(endPosition) / elapsed.Seconds()
return int(hashesPerSecond), nil
}
18 changes: 18 additions & 0 deletions initialization/benchmark_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package initialization

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestBenchmark(t *testing.T) {
providers, err := OpenCLProviders()
require.NoError(t, err)

for _, p := range providers {
hashes, err := Benchmark(p)
require.NoError(t, err)
require.Greater(t, hashes, 0)
}
}
Loading

0 comments on commit e229cb9

Please sign in to comment.