/
main.go
132 lines (112 loc) · 3.95 KB
/
main.go
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
package main
import (
"io/ioutil"
"os"
"runtime"
"runtime/pprof"
"sync"
"time"
"github.com/alecthomas/kingpin"
gpuminer "github.com/gurupras/go-cryptonight-miner/gpu-miner"
amdgpu "github.com/gurupras/go-cryptonight-miner/gpu-miner/amd"
"github.com/gurupras/go-cryptonight-miner/gpu-miner/gpucontext"
miner "github.com/gurupras/go-cryptonight-miner/miner"
mineros "github.com/gurupras/go-cryptonight-miner/miner-os"
stratum "github.com/gurupras/go-stratum-client"
colorable "github.com/mattn/go-colorable"
log "github.com/sirupsen/logrus"
yaml "gopkg.in/yaml.v2"
)
var (
app = kingpin.New("cpuminer", "CPU Cryptonight miner")
config = app.Flag("config-file", "YAML config file").Short('c').Required().String()
verbose = app.Flag("verbose", "Enable verbose log messages").Short('v').Bool()
debug = app.Flag("debug", "Enable miner debugging log messages").Short('d').Default("false").Bool()
useC = app.Flag("use C", "Use C functions to intialize OpenCL rather than Golang").Short('C').Default("false").Bool()
cpuprofile = app.Flag("cpuprofile", "Run CPU profiler").String()
)
func main() {
kingpin.MustParse(app.Parse(os.Args[1:]))
if runtime.GOOS == "windows" {
log.SetFormatter(&log.TextFormatter{ForceColors: true})
log.SetOutput(colorable.NewColorableStdout())
}
amdgpu.UseC = *useC
if *verbose {
log.SetLevel(log.DebugLevel)
}
if *cpuprofile != "" {
f, err := os.Create(*cpuprofile)
if err != nil {
log.Fatalf("Failed to create cpuprofile file: %v", err)
}
if err := pprof.StartCPUProfile(f); err != nil {
log.Fatalf("Failed to start CPU profile: %v", err)
}
log.Infof("Starting CPU profiling")
defer pprof.StopCPUProfile()
}
// Parse config file and extract necessary fields
configData, err := ioutil.ReadFile(*config)
if err != nil {
log.Fatalf("Failed to read config file: %v", err)
}
var config miner.Config
if err := yaml.Unmarshal(configData, &config); err != nil {
log.Fatalf("Failed to parse yaml into valid config: %v", err)
}
sc := stratum.New()
hashrateChan := make(chan *miner.HashRate, 10)
go miner.RunDefaultHashRateTrackers(hashrateChan)
numMiners := len(config.Threads)
miners := make([]miner.Interface, numMiners)
gpuContexts := make([]*gpucontext.GPUContext, numMiners)
for i := 0; i < numMiners; i++ {
threadInfo := config.Threads[i]
if threadInfo.DeviceIndex != nil {
// We need to figure out the Index for this thread via OpenCL using
// something akin to clinfo to find the BDF (Bus, Device, Function)
instanceId := config.DeviceInstanceIDs[*threadInfo.DeviceIndex]
// First get the PCI Bus, Device, Function from the system for this instance
topology, err := mineros.GetPCITopology(instanceId)
if err != nil {
log.Fatalf("Failed to get topology information for device-instance-id: '%v'", instanceId)
}
// Now call OpenCL commands to find the device that matches this topology
idx, err := amdgpu.FindIndexMatchingTopology(topology)
if err != nil {
log.Fatalf("%v", err)
}
threadInfo.Index = idx
}
miner := gpuminer.NewGPUMiner(sc, threadInfo.Index, threadInfo.Intensity, threadInfo.WorkSize)
miner.RegisterHashrateListener(hashrateChan)
gpuContexts[i] = miner.Context
miners[i] = miner
miner.SetDebug(*debug)
}
if err := amdgpu.InitOpenCL(gpuContexts, numMiners, config.OpenCLPlatform); err != nil {
log.Fatalf("Failed to initialize OpenCL: %v", err)
}
go gpuminer.RunHashChecker()
wg := sync.WaitGroup{}
wg.Add(1)
for i := 0; i < numMiners; i++ {
go miners[i].Run()
}
// responseChan := make(chan *stratum.Response)
//
// sc.RegisterResponseListener(responseChan)
pool := config.Pools[0]
if err := sc.Connect(pool.Url); err != nil {
log.Fatalf("Failed to connect to url :%v - %v", pool.Url, err)
}
if err := sc.Authorize(pool.User, pool.Pass); err != nil {
log.Fatalf("Failed to authorize with server: %v", err)
}
if *cpuprofile != "" {
time.Sleep(300 * time.Second)
} else {
wg.Wait() // blocks forever
}
}