Skip to content

Commit d1688ad

Browse files
committed
Address review
1 parent 325cab5 commit d1688ad

13 files changed

+155
-260
lines changed

cmd/curio/calc.go

+36-126
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,11 @@ var calcCmd = &cli.Command{
2525

2626
var calcBatchCpuCmd = &cli.Command{
2727
Name: "batch-cpu",
28-
Usage: "See layout of batch sealer threads",
28+
Usage: "Analyze and display the layout of batch sealer threads",
29+
Description: `Analyze and display the layout of batch sealer threads on your CPU.
30+
31+
It provides detailed information about CPU utilization for batch sealing operations, including core allocation, thread
32+
distribution for different batch sizes.`,
2933
Flags: []cli.Flag{
3034
&cli.BoolFlag{Name: "dual-hashers", Value: true},
3135
},
@@ -61,157 +65,59 @@ var calcBatchCpuCmd = &cli.Command{
6165
printForBatchSize := func(batchSize int) {
6266
fmt.Printf("Batch Size: %s sectors\n", color.CyanString("%d", batchSize))
6367
fmt.Println()
64-
fmt.Printf("Required Threads: %d\n", batchSize/sectorsPerThread)
65-
requiredCCX := (batchSize + sectorsPerCCX - 1) / sectorsPerCCX
66-
fmt.Printf("Required CCX: %d\n", requiredCCX)
6768

68-
requiredCores := requiredCCX + batchSize/sectorsPerThread/info.ThreadsPerCore
69-
fmt.Printf("Required Cores: %d hasher (+4 minimum for non-hashers)\n", requiredCores)
69+
config, err := sealsupra.GenerateSupraSealConfig(*info, cctx.Bool("dual-hashers"), batchSize, nil)
70+
if err != nil {
71+
fmt.Printf("Error generating config: %s\n", err)
72+
return
73+
}
7074

71-
enoughCores := requiredCores <= info.CoreCount
75+
fmt.Printf("Required Threads: %d\n", config.RequiredThreads)
76+
fmt.Printf("Required CCX: %d\n", config.RequiredCCX)
77+
fmt.Printf("Required Cores: %d hasher (+4 minimum for non-hashers)\n", config.RequiredCores)
78+
79+
enoughCores := config.RequiredCores <= info.CoreCount
7280
if enoughCores {
7381
fmt.Printf("Enough cores available for hashers %s\n", color.GreenString("✔"))
7482
} else {
7583
fmt.Printf("Not enough cores available for hashers %s\n", color.RedString("✘"))
7684
return
7785
}
7886

79-
coresLeftover := info.CoreCount - requiredCores
80-
fmt.Printf("Non-hasher cores: %d\n", coresLeftover)
81-
82-
const minOverheadCores = 4
83-
84-
type CoreNum = int // core number, 0-based
85-
86-
var (
87-
// core assignments for non-hasher work
88-
// defaults are the absolutely worst case of just 4 cores available
89-
90-
pc1writer CoreNum = 1
91-
pc1reader CoreNum = 2
92-
pc1orchestrator CoreNum = 3
93-
94-
pc2reader CoreNum = 0
95-
pc2hasher CoreNum = 1
96-
pc2hasher_cpu CoreNum = 0
97-
pc2writer CoreNum = 0
98-
99-
c1reader CoreNum = 0
100-
101-
pc2writer_cores int = 1
102-
)
103-
104-
if coresLeftover < minOverheadCores {
105-
fmt.Printf("Not enough cores for coordination %s\n", color.RedString("✘"))
106-
return
107-
} else {
108-
fmt.Printf("Enough cores for coordination %s\n", color.GreenString("✔"))
109-
}
110-
111-
nextFreeCore := minOverheadCores
87+
fmt.Printf("Non-hasher cores: %d\n", info.CoreCount-config.RequiredCores)
11288

113-
// first move pc2 to individual cores
114-
if coresLeftover > nextFreeCore {
115-
pc2writer = nextFreeCore
116-
nextFreeCore++
117-
} else {
89+
if config.P2WrRdOverlap {
11890
color.Yellow("! P2 writer will share a core with P2 reader, performance may be impacted")
11991
}
120-
121-
if coresLeftover > nextFreeCore {
122-
pc2hasher = nextFreeCore
123-
nextFreeCore++
124-
} else {
92+
if config.P2HsP1WrOverlap {
12593
color.Yellow("! P2 hasher will share a core with P1 writer, performance may be impacted")
12694
}
127-
128-
if coresLeftover > nextFreeCore {
129-
pc2hasher_cpu = nextFreeCore
130-
nextFreeCore++
131-
} else {
95+
if config.P2HcP2RdOverlap {
13296
color.Yellow("! P2 hasher_cpu will share a core with P2 reader, performance may be impacted")
13397
}
13498

135-
if coresLeftover > nextFreeCore {
136-
// might be fine to sit on core0, but let's not do that
137-
pc2reader = nextFreeCore
138-
c1reader = nextFreeCore
139-
nextFreeCore++
140-
}
141-
142-
// add p2 writer cores, up to 8 total
143-
if coresLeftover > nextFreeCore {
144-
// swap pc2reader with pc2writer
145-
pc2writer, pc2reader = pc2reader, pc2writer
146-
147-
for i := 0; i < 7; i++ {
148-
if coresLeftover > nextFreeCore {
149-
pc2writer_cores++
150-
nextFreeCore++
151-
}
152-
}
153-
}
154-
15599
fmt.Println()
156-
fmt.Printf("pc1 writer: %d\n", pc1writer)
157-
fmt.Printf("pc1 reader: %d\n", pc1reader)
158-
fmt.Printf("pc1 orchestrator: %d\n", pc1orchestrator)
100+
fmt.Printf("pc1 writer: %d\n", config.Topology.PC1Writer)
101+
fmt.Printf("pc1 reader: %d\n", config.Topology.PC1Reader)
102+
fmt.Printf("pc1 orchestrator: %d\n", config.Topology.PC1Orchestrator)
159103
fmt.Println()
160-
fmt.Printf("pc2 reader: %d\n", pc2reader)
161-
fmt.Printf("pc2 hasher: %d\n", pc2hasher)
162-
fmt.Printf("pc2 hasher_cpu: %d\n", pc2hasher_cpu)
163-
fmt.Printf("pc2 writer: %d\n", pc2writer)
164-
fmt.Printf("pc2 writer_cores: %d\n", pc2writer_cores)
104+
fmt.Printf("pc2 reader: %d\n", config.Topology.PC2Reader)
105+
fmt.Printf("pc2 hasher: %d\n", config.Topology.PC2Hasher)
106+
fmt.Printf("pc2 hasher_cpu: %d\n", config.Topology.PC2HasherCPU)
107+
fmt.Printf("pc2 writer: %d\n", config.Topology.PC2Writer)
108+
fmt.Printf("pc2 writer_cores: %d\n", config.Topology.PC2WriterCores)
165109
fmt.Println()
166-
fmt.Printf("c1 reader: %d\n", c1reader)
110+
fmt.Printf("c1 reader: %d\n", config.Topology.C1Reader)
167111
fmt.Println()
168112

169-
unoccupiedCores := coresLeftover - nextFreeCore
170-
fmt.Printf("Unoccupied Cores: %d\n\n", unoccupiedCores)
171-
172-
var ccxCores []CoreNum // first core in each CCX
173-
for i := 0; i < info.CoreCount; i += info.CoresPerL3 {
174-
ccxCores = append(ccxCores, i)
175-
}
176-
177-
type sectorCoreConfig struct {
178-
core CoreNum // coordinator core
179-
hashers CoreNum // number of hasher cores
180-
}
181-
var coreConfigs []sectorCoreConfig
182-
183-
for i := requiredCores; i > 0; {
184-
firstCCXCoreNum := ccxCores[len(ccxCores)-1]
185-
toAssign := min(i, info.CoresPerL3)
186-
187-
// shift up the first core if possible so that cores on the right are used first
188-
coreNum := firstCCXCoreNum + info.CoresPerL3 - toAssign
189-
190-
coreConfigs = append(coreConfigs, sectorCoreConfig{
191-
core: coreNum,
192-
hashers: (toAssign - 1) * info.ThreadsPerCore,
193-
})
194-
195-
i -= toAssign
196-
if toAssign == info.CoresPerL3 {
197-
ccxCores = ccxCores[:len(ccxCores)-1]
198-
if len(ccxCores) == 0 {
199-
break
200-
}
201-
}
202-
}
203-
204-
// reverse the order
205-
for i, j := 0, len(coreConfigs)-1; i < j; i, j = i+1, j-1 {
206-
coreConfigs[i], coreConfigs[j] = coreConfigs[j], coreConfigs[i]
207-
}
113+
fmt.Printf("Unoccupied Cores: %d\n\n", config.UnoccupiedCores)
208114

209115
fmt.Println("{")
210116
fmt.Printf(" sectors = %d;\n", batchSize)
211117
fmt.Println(" coordinators = (")
212-
for i, config := range coreConfigs {
213-
fmt.Printf(" { core = %d;\n hashers = %d; }", config.core, config.hashers)
214-
if i < len(coreConfigs)-1 {
118+
for i, coord := range config.Topology.SectorConfigs[0].Coordinators {
119+
fmt.Printf(" { core = %d;\n hashers = %d; }", coord.Core, coord.Hashers)
120+
if i < len(config.Topology.SectorConfigs[0].Coordinators)-1 {
215121
fmt.Println(",")
216122
} else {
217123
fmt.Println()
@@ -235,6 +141,10 @@ var calcBatchCpuCmd = &cli.Command{
235141
var calcSuprasealConfigCmd = &cli.Command{
236142
Name: "supraseal-config",
237143
Usage: "Generate a supra_seal configuration",
144+
Description: `Generate a supra_seal configuration for a given batch size.
145+
146+
This command outputs a configuration expected by SupraSeal. Main purpose of this command is for debugging and testing.
147+
The config can be used directly with SupraSeal binaries to test it without involving Curio.`,
238148
Flags: []cli.Flag{
239149
&cli.BoolFlag{
240150
Name: "dual-hashers",

commit-phase1-output

-10.5 MB
Binary file not shown.

deps/config/types.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -478,11 +478,13 @@ type CurioSealConfig struct {
478478
// Set to false for older CPUs (Zen 2 and before).
479479
SingleHasherPerThread bool
480480

481-
// LayerNVMEDevices is a list of pcie device addresses that should be used for layer storage.
481+
// LayerNVMEDevices is a list of pcie device addresses that should be used for SDR layer storage.
482482
// The required storage is 11 * BatchSealBatchSize * BatchSealSectorSize * BatchSealPipelines
483483
// Total Read IOPS for optimal performance should be 10M+.
484484
// The devices MUST be NVMe devices, not used for anything else. Any data on the devices will be lost!
485485
//
486+
// It's recommend to define these settings in a per-machine layer, as the devices are machine-specific.
487+
//
486488
// Example: ["0000:01:00.0", "0000:01:00.1"]
487489
LayerNVMEDevices []string
488490
}

lib/proof/porep_vproof_bin_decode.go

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import (
66
"io"
77
)
88

9+
// This file contains a bincode decoder for Commit1OutRaw.
10+
// This is the format output by the C++ supraseal C1 implementation.
11+
// bincode - https://github.com/bincode-org/bincode
12+
913
func ReadLE[T any](r io.Reader) (T, error) {
1014
var out T
1115
err := binary.Read(r, binary.LittleEndian, &out)

lib/proof/porep_vproof_bin_test.go

+22-2
Original file line numberDiff line numberDiff line change
@@ -2,22 +2,42 @@ package proof
22

33
import (
44
"bytes"
5+
"compress/gzip"
56
"encoding/json"
7+
"io"
68
"os"
79
"testing"
810

911
"github.com/filecoin-project/filecoin-ffi/cgo"
1012
)
1113

1214
func TestDecode(t *testing.T) {
15+
if os.Getenv("EXPENSIVE_TESTS") == "" {
16+
t.Skip()
17+
}
18+
1319
//binFile := "../../extern/supra_seal/demos/c2-test/resources/test/commit-phase1-output"
14-
binFile := "../../commit-phase1-output"
20+
binFile := "../../commit-phase1-output.gz"
1521

16-
rawData, err := os.ReadFile(binFile)
22+
gzData, err := os.ReadFile(binFile)
23+
if err != nil {
24+
t.Fatal(err)
25+
}
26+
27+
gzReader, err := gzip.NewReader(bytes.NewReader(gzData))
1728
if err != nil {
1829
t.Fatal(err)
1930
}
2031

32+
rawData, err := io.ReadAll(gzReader)
33+
if err != nil {
34+
t.Fatal(err)
35+
}
36+
37+
if err := gzReader.Close(); err != nil {
38+
t.Fatal(err)
39+
}
40+
2141
dec, err := DecodeCommit1OutRaw(bytes.NewReader(rawData))
2242
if err != nil {
2343
t.Fatal(err)

lib/proof/porep_vproof_challenges.go

+3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ import (
77
"github.com/minio/sha256-simd"
88
)
99

10+
// TODO: This file is a placeholder with links to the original implementation in Rust. Eventually we want to
11+
// have our own implementation for generating PoRep vanilla proofs in Go.
12+
1013
// https://github.com/filecoin-project/rust-fil-proofs/blob/8f5bd86be36a55e33b9b293ba22ea13ca1f28163/storage-proofs-porep/src/stacked/vanilla/challenges.rs#L21
1114

1215
func DeriveInteractiveChallenges(

lib/proof/porep_vproof_types.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package proof
22

3-
// This file contains some type definitions from
3+
// This file contains PoRep vanilla proof type definitions from
44
// - https://github.com/filecoin-project/rust-fil-proofs/tree/master/storage-proofs-core/src/merkle
55
// - https://github.com/filecoin-project/rust-fil-proofs/tree/master/storage-proofs-porep/src/stacked/vanilla
66
// - https://github.com/filecoin-project/rust-filecoin-proofs-api/tree/master/src
7+
// The json representation of those matches the representation expected by rust-fil-proofs.
78

89
// core
910

lib/proof/porep_vproof_vanilla.go

+3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package proof
22

3+
// TODO: This file is a placeholder with links to the original implementation in Rust. Eventually we want to
4+
// have our own implementation for generating PoRep vanilla proofs in Go.
5+
36
// https://github.com/filecoin-project/rust-fil-proofs/blob/8f5bd86be36a55e33b9b293ba22ea13ca1f28163/storage-proofs-porep/src/stacked/vanilla/proof_scheme.rs#L60
47
func ProveAllPartitions() {
58

0 commit comments

Comments
 (0)