@@ -8,6 +8,7 @@ import java.io.{File, RandomAccessFile}
8
8
import java .net .InetSocketAddress
9
9
import java .nio .ByteBuffer
10
10
import java .nio .charset .StandardCharsets
11
+ import java .nio .channels .FileChannel
11
12
import java .util .concurrent .atomic .AtomicInteger
12
13
13
14
import org .apache .commons .cli .{GnuParser , HelpFormatter , Options }
@@ -21,7 +22,7 @@ import org.apache.spark.util.ShutdownHookManager
21
22
object UcxPerfBenchmark extends App with Logging {
22
23
23
24
case class PerfOptions (remoteAddress : InetSocketAddress , numBlocks : Int , blockSize : Long ,
24
- numIterations : Int , file : File , numOutstanding : Int )
25
+ numIterations : Int , files : Array [ File ] , numOutstanding : Int )
25
26
26
27
private val HELP_OPTION = " h"
27
28
private val ADDRESS_OPTION = " a"
@@ -47,7 +48,7 @@ object UcxPerfBenchmark extends App with Logging {
47
48
" number of iterations. Default: 1" )
48
49
options.addOption(OUTSTANDING_OPTION , " num-outstanding" , true ,
49
50
" number of outstanding requests. Default: 1" )
50
- options.addOption(FILE_OPTION , " file " , true , " File to transfer" )
51
+ options.addOption(FILE_OPTION , " files " , true , " Files to transfer" )
51
52
options
52
53
}
53
54
@@ -68,17 +69,27 @@ object UcxPerfBenchmark extends App with Logging {
68
69
null
69
70
}
70
71
71
- val file = if (cmd.hasOption(FILE_OPTION )) {
72
- new File (cmd.getOptionValue(FILE_OPTION ))
73
- } else {
74
- null
72
+ var files = Array [File ]()
73
+ if (cmd.hasOption(FILE_OPTION )) {
74
+ for (name <- cmd.getOptionValue(FILE_OPTION ).split(" ," )) {
75
+ val f = new File (name)
76
+ if (! f.exists()) {
77
+ System .err.println(s " File $name does not exist. " )
78
+ System .exit(- 1 )
79
+ }
80
+ files +:= f
81
+ }
82
+ }
83
+ if (files.size == 0 ) {
84
+ System .err.println(s " No file. " )
85
+ System .exit(- 1 )
75
86
}
76
87
77
88
PerfOptions (inetAddress,
78
89
Integer .parseInt(cmd.getOptionValue(NUM_BLOCKS_OPTION , " 1" )),
79
90
JavaUtils .byteStringAsBytes(cmd.getOptionValue(SIZE_OPTION , " 1m" )),
80
91
Integer .parseInt(cmd.getOptionValue(ITER_OPTION , " 1" )),
81
- file ,
92
+ files ,
82
93
Integer .parseInt(cmd.getOptionValue(OUTSTANDING_OPTION , " 1" )))
83
94
}
84
95
@@ -101,7 +112,9 @@ object UcxPerfBenchmark extends App with Logging {
101
112
for (b <- 0 until options.numBlocks by options.numOutstanding) {
102
113
requestInFlight.set(options.numOutstanding)
103
114
for (o <- 0 until options.numOutstanding) {
104
- blocks(o) = UcxShuffleBockId (0 , 0 , (b+ o) % options.numBlocks)
115
+ val fileIdx = (b+ o) % options.files.size
116
+ val blockIdx = (b+ o) / options.files.size
117
+ blocks(o) = UcxShuffleBockId (0 , fileIdx, blockIdx)
105
118
callbacks(o) = (result : OperationResult ) => {
106
119
result.getData.close()
107
120
val stats = result.getStats.get
@@ -126,17 +139,21 @@ object UcxPerfBenchmark extends App with Logging {
126
139
ucxTransport.init()
127
140
val currentThread = Thread .currentThread()
128
141
129
- val channel = new RandomAccessFile (options.file, " rw" ).getChannel
142
+ var channels = Array [FileChannel ]()
143
+ options.files.foreach(channels +:= new RandomAccessFile (_, " r" ).getChannel)
130
144
131
145
ShutdownHookManager .addShutdownHook(()=> {
132
146
currentThread.interrupt()
133
147
ucxTransport.close()
134
148
})
135
149
136
150
for (b <- 0 until options.numBlocks) {
137
- val blockId = UcxShuffleBockId (0 , 0 , b)
151
+ val fileIdx = b % options.files.size
152
+ val blockIdx = b / options.files.size
153
+ val blockId = UcxShuffleBockId (0 , fileIdx, blockIdx)
138
154
val block = new Block {
139
- private val fileOffset = b * options.blockSize
155
+ private val channel = channels(fileIdx)
156
+ private val fileOffset = blockIdx * options.blockSize
140
157
141
158
override def getMemoryBlock : MemoryBlock = {
142
159
val startTime = System .nanoTime()
0 commit comments