Skip to content

Commit 7ed55b6

Browse files
committed
[query] use a single regionpool per thread
1 parent 0461108 commit 7ed55b6

58 files changed

Lines changed: 1673 additions & 1778 deletions

Some content is hidden

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

hail/hail/src/is/hail/annotations/RegionPool.scala

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,7 @@ final class RegionPool private (strictMemoryCheck: Boolean, threadName: String,
118118
}
119119
}
120120

121-
def getRegion(): Region = getRegion(Region.REGULAR)
122-
123-
def getRegion(size: Int): Region = {
121+
def getRegion(size: Int = Region.REGULAR): Region = {
124122
val r = new Region(size, this)
125123
r.memory = getMemory(size)
126124
r
@@ -154,11 +152,29 @@ final class RegionPool private (strictMemoryCheck: Boolean, threadName: String,
154152

155153
def report(context: String): Unit = {
156154
val inBlocks = bytesInBlocks()
155+
val (chunksAllocated, cacheHits) = chunkCache.getUsage()
157156

158157
logger.info(
159-
s"RegionPool: $context: ${readableBytes(totalAllocatedBytes)} allocated (${readableBytes(inBlocks)} blocks / " +
160-
s"${readableBytes(totalAllocatedBytes - inBlocks)} chunks), regions.size = ${regions.size}, " +
161-
s"$numJavaObjects current java objects, thread $threadID: $threadName"
158+
s"""RegionPool: $context
159+
| thread:
160+
| id: $threadID
161+
| name: $threadName
162+
| objects: $numJavaObjects
163+
| allocations:
164+
| peak: $getHighestTotalUsage
165+
| total: ${readableBytes(totalAllocatedBytes)}
166+
| blocks: ${readableBytes(inBlocks)}
167+
| chunks: ${readableBytes(totalAllocatedBytes - inBlocks)}
168+
| regions:
169+
| total: ${regions.size}
170+
| free: ${freeRegions.size}
171+
| blocks:
172+
| total: ${blocks.sum}
173+
| free: ${freeBlocks.view.map(_.size).sum}
174+
| chunks:
175+
| total: $chunksAllocated
176+
| reused: $cacheHits
177+
| """.stripMargin
162178
)
163179
// logger.info("-----------STACK_TRACES---------")
164180
// val stacks: String = regions.result().toIndexedSeq.flatMap(r => r.stackTrace.map((r.getTotalChunkMemory(), _))).foldLeft("")((a: String, b) => a + "\n" + b.toString())
@@ -170,8 +186,6 @@ final class RegionPool private (strictMemoryCheck: Boolean, threadName: String,
170186
def scopedSmallRegion[T](f: Region => T): T = using(Region(Region.SMALL, pool = this))(f)
171187
def scopedTinyRegion[T](f: Region => T): T = using(Region(Region.TINY, pool = this))(f)
172188

173-
override def finalize(): Unit = close()
174-
175189
private[this] var closed: Boolean = false
176190

177191
override def close(): Unit = {

hail/hail/src/is/hail/backend/Backend.scala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,10 @@
11
package is.hail.backend
22

3-
import is.hail.asm4s.HailClassLoader
43
import is.hail.backend.Backend.PartitionFn
54
import is.hail.backend.spark.SparkBackend
6-
import is.hail.expr.ir.{IR, LoweringAnalyses, SortField, TableIR, TableReader}
5+
import is.hail.expr.ir.{Compiled, IR, LoweringAnalyses, SortField, TableIR, TableReader}
76
import is.hail.expr.ir.lowering.{TableStage, TableStageDependency}
87
import is.hail.io.{BufferSpec, TypedCodecSpec}
9-
import is.hail.io.fs.FS
108
import is.hail.types.RTable
119
import is.hail.types.encoded.EType
1210
import is.hail.types.physical.PTuple
@@ -45,7 +43,7 @@ object Backend {
4543
codec.encode(ctx, elementType, t.loadField(off, 0), os)
4644
}
4745

48-
type PartitionFn = (Array[Byte], Array[Byte], HailTaskContext, HailClassLoader, FS) => Array[Byte]
46+
type PartitionFn = Compiled[(Array[Byte], Array[Byte]) => Array[Byte]]
4947
}
5048

5149
abstract class BroadcastValue[T] { def value: T }

hail/hail/src/is/hail/backend/BackendUtils.scala

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,18 @@ package is.hail.backend
33
import is.hail.annotations.Region
44
import is.hail.asm4s._
55
import is.hail.collection.implicits.toRichIndexedSeq
6+
import is.hail.expr.ir.Compiled
67
import is.hail.expr.ir.analyses.SemanticHash
78
import is.hail.expr.ir.lowering.TableStageDependency
8-
import is.hail.io.fs._
99
import is.hail.utils._
1010

1111
object BackendUtils {
1212
type F = AsmFunction3[Region, Array[Byte], Array[Byte], Array[Byte]]
1313
}
1414

15-
class BackendUtils(
16-
mods: Array[(String, (HailClassLoader, FS, HailTaskContext, Region) => BackendUtils.F)]
17-
) extends Logging {
15+
class BackendUtils(mods: Array[(String, Compiled[BackendUtils.F])]) extends Logging {
1816

19-
import BackendUtils.F
20-
21-
private[this] val loadedModules
22-
: Map[String, (HailClassLoader, FS, HailTaskContext, Region) => F] = mods.toMap
23-
24-
def getModule(id: String): (HailClassLoader, FS, HailTaskContext, Region) => F = loadedModules(id)
17+
private[this] val getModule = mods.toMap
2518

2619
def collectDArray(
2720
ctx: DriverRuntimeContext,
@@ -82,7 +75,7 @@ class BackendUtils(
8275
tsd: Option[TableStageDependency],
8376
): (Option[Throwable], IndexedSeq[(Array[Byte], Int)]) = {
8477

85-
val mod = getModule(modID)
78+
val loadFn = getModule(modID)
8679
val start = System.nanoTime()
8780

8881
val r = rtx.mapCollectPartitions(
@@ -91,10 +84,10 @@ class BackendUtils(
9184
stageName,
9285
tsd,
9386
partitions,
94-
) { (gs, ctx, htc, theHailClassLoader, fs) =>
95-
htc.getRegionPool().scopedRegion { region =>
96-
mod(theHailClassLoader, fs, htc, region)(region, ctx, gs)
97-
}
87+
) {
88+
(hcl, fs, htc, r) =>
89+
val fn = loadFn(hcl, fs, htc, r)
90+
fn(r, _, _)
9891
}
9992

10093
val elapsed = System.nanoTime() - start

hail/hail/src/is/hail/backend/ExecuteContext.scala

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,7 @@ package is.hail.backend
33
import is.hail.HailFeatureFlags
44
import is.hail.annotations.{Region, RegionPool}
55
import is.hail.asm4s.HailClassLoader
6-
import is.hail.backend.local.LocalTaskContext
7-
import is.hail.expr.ir.{BaseIR, CodeCacheKey, CompiledFunction}
6+
import is.hail.expr.ir.{BaseIR, CompileCache, Compiled}
87
import is.hail.expr.ir.LoweredTableReader.LoweredTableReaderCoercer
98
import is.hail.expr.ir.lowering.IrMetadata
109
import is.hail.io.fs.FS
@@ -67,12 +66,12 @@ object ExecuteContext {
6766
flags: HailFeatureFlags,
6867
irMetadata: IrMetadata,
6968
blockMatrixCache: mutable.Map[String, BlockMatrix],
70-
codeCache: mutable.Map[CodeCacheKey, CompiledFunction[_]],
69+
compileCache: CompileCache,
7170
irCache: mutable.Map[Int, BaseIR],
7271
coercerCache: mutable.Map[Any, LoweredTableReaderCoercer],
7372
)(
7473
f: ExecuteContext => T
75-
): T = {
74+
): T =
7675
RegionPool.scoped { pool =>
7776
pool.scopedRegion { region =>
7877
using(new ExecuteContext(
@@ -88,13 +87,12 @@ object ExecuteContext {
8887
flags,
8988
irMetadata,
9089
blockMatrixCache,
91-
codeCache,
90+
compileCache,
9291
irCache,
9392
coercerCache,
9493
))(f(_))
9594
}
9695
}
97-
}
9896

9997
def createTmpPathNoCleanup(tmpdir: String, prefix: String, extension: String = null): String = {
10098
val random = new SecureRandom()
@@ -113,17 +111,17 @@ class ExecuteContext(
113111
val backend: Backend,
114112
val references: Map[String, ReferenceGenome],
115113
val fs: FS,
116-
val r: Region,
114+
override val r: Region,
117115
val timer: ExecutionTimer,
118116
val tempFileManager: TempFileManager,
119117
val theHailClassLoader: HailClassLoader,
120118
val flags: HailFeatureFlags,
121119
val irMetadata: IrMetadata,
122120
val BlockMatrixCache: mutable.Map[String, BlockMatrix],
123-
val CodeCache: mutable.Map[CodeCacheKey, CompiledFunction[_]],
121+
val CompileCache: CompileCache,
124122
val PersistedIrCache: mutable.Map[Int, BaseIR],
125123
val PersistedCoercerCache: mutable.Map[Any, LoweredTableReaderCoercer],
126-
) extends Closeable {
124+
) extends HailTaskContext with Closeable {
127125

128126
val rngNonce: Long =
129127
try
@@ -142,13 +140,14 @@ class ExecuteContext(
142140

143141
val memo: mutable.Map[Any, Any] = new mutable.HashMap[Any, Any]()
144142

145-
val taskContext: HailTaskContext = new LocalTaskContext(0, 0)
143+
private[this] val onCloseTasks = mutable.ArrayBuffer.empty[() => Unit]
144+
override def onClose(f: () => Unit): Unit = onCloseTasks += f
146145

147-
def scopedExecution[T](
148-
f: (HailClassLoader, FS, HailTaskContext, Region) => T
149-
)(implicit E: Enclosing
150-
): T =
151-
using(new LocalTaskContext(0, 0))(tc => time(f(theHailClassLoader, fs, tc, r)))
146+
def run[A](f: Compiled[A])(implicit E: Enclosing): A =
147+
time(f(theHailClassLoader, fs, this, r))
148+
149+
def scopedExecution[T](f: Compiled[T])(implicit E: Enclosing): T =
150+
r.pool.scopedRegion(r => local(r = r)(_.run(f)))
152151

153152
def createTmpPath(prefix: String, extension: String = null, local: Boolean = false): String =
154153
tempFileManager.newTmpPath(if (local) localTmpdir else tmpdir, prefix, extension)
@@ -162,8 +161,8 @@ class ExecuteContext(
162161
def shouldLogIR(): Boolean = !shouldNotLogIR()
163162

164163
override def close(): Unit = {
164+
onCloseTasks.foreach(_())
165165
tempFileManager.close()
166-
taskContext.close()
167166
}
168167

169168
def time[A](block: => A)(implicit E: Enclosing): A =
@@ -182,7 +181,7 @@ class ExecuteContext(
182181
flags: HailFeatureFlags = this.flags,
183182
irMetadata: IrMetadata = this.irMetadata,
184183
blockMatrixCache: mutable.Map[String, BlockMatrix] = this.BlockMatrixCache,
185-
codeCache: mutable.Map[CodeCacheKey, CompiledFunction[_]] = this.CodeCache,
184+
compileCache: CompileCache = this.CompileCache,
186185
persistedIrCache: mutable.Map[Int, BaseIR] = this.PersistedIrCache,
187186
persistedCoercerCache: mutable.Map[Any, LoweredTableReaderCoercer] = this.PersistedCoercerCache,
188187
)(
@@ -201,7 +200,7 @@ class ExecuteContext(
201200
flags,
202201
irMetadata,
203202
blockMatrixCache,
204-
codeCache,
203+
compileCache,
205204
persistedIrCache,
206205
persistedCoercerCache,
207206
))(f)
Lines changed: 20 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,35 @@
11
package is.hail.backend
22

3-
import is.hail.annotations.RegionPool
4-
import is.hail.utils._
3+
import is.hail.annotations.{Region, RegionPool}
4+
import is.hail.utils.using
55

66
import scala.collection.mutable
77

8-
import java.io.Closeable
8+
trait HailTaskContext {
99

10-
class TaskFinalizer {
11-
val closeables = mutable.ArrayBuffer.empty[Closeable]
10+
/** region whose lifetime is at least as long as this task */
11+
def r: Region
1212

13-
def clear(): Unit =
14-
closeables.clear()
15-
16-
def addCloseable(c: Closeable): Unit =
17-
closeables += c
18-
19-
def closeAll(): Unit = closeables.foreach(_.close())
13+
/** register an action that will be called when this task completes */
14+
def onClose(f: () => Unit): Unit
2015
}
2116

22-
abstract class HailTaskContext extends AutoCloseable with Logging {
23-
def stageId(): Int
24-
25-
def partitionId(): Int
26-
27-
def attemptNumber(): Int
28-
29-
private lazy val thePool = RegionPool()
30-
31-
def getRegionPool(): RegionPool = thePool
17+
object HailTaskContext {
18+
def runPartition[A](partId: Int)(f: HailTaskContext => A): A =
19+
using(new PartitionContext(partId))(f)
20+
}
3221

33-
val finalizers = mutable.ArrayBuffer.empty[TaskFinalizer]
22+
class PartitionContext(partId: Int) extends HailTaskContext with AutoCloseable {
23+
private[this] val onCloseTasks = mutable.ArrayBuffer.empty[() => Unit]
3424

35-
def newFinalizer(): TaskFinalizer = {
36-
val f = new TaskFinalizer
37-
finalizers += f
38-
f
39-
}
25+
private[this] val pool = RegionPool()
26+
override val r: Region = Region(pool = pool)
27+
override def onClose(f: () => Unit): Unit = onCloseTasks += f
4028

4129
override def close(): Unit = {
42-
logger.info(
43-
s"TaskReport: stage=${stageId()}, partition=${partitionId()}, attempt=${attemptNumber()}, " +
44-
s"peakBytes=${thePool.getHighestTotalUsage}, peakBytesReadable=${formatSpace(thePool.getHighestTotalUsage)}, " +
45-
s"chunks requested=${thePool.getUsage._1}, cache hits=${thePool.getUsage._2}"
46-
)
47-
finalizers.foreach(_.closeAll())
48-
thePool.close()
30+
onCloseTasks.foreach(_())
31+
r.close()
32+
pool.logStats(s"Partition $partId")
33+
pool.close()
4934
}
5035
}

hail/hail/src/is/hail/backend/driver/BatchQueryDriver.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ object BatchQueryDriver extends HttpLikeRpc with Logging {
113113
flags = env.flags,
114114
irMetadata = new IrMetadata(),
115115
blockMatrixCache = ImmutableMap.empty,
116-
codeCache = ImmutableMap.empty,
116+
compileCache = ImmutableMap.empty,
117117
irCache = ImmutableMap.empty,
118118
coercerCache = ImmutableMap.empty,
119119
)(f)

hail/hail/src/is/hail/backend/driver/Py4JQueryDriver.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import is.hail.io.fs._
1717
import is.hail.io.reference.{IndexedFastaSequenceFile, LiftOver}
1818
import is.hail.sparkextras.implicits._
1919
import is.hail.types.physical.PStruct
20+
import is.hail.types.physical.stypes.SingleCodeType
2021
import is.hail.types.virtual.{TArray, TInterval}
2122
import is.hail.types.virtual.Kinds.{BlockMatrix, Matrix, Table, Value}
2223
import is.hail.utils._
@@ -46,7 +47,10 @@ final class Py4JQueryDriver(backend: Backend) extends Closeable with Logging {
4647
private[this] val hcl = new HailClassLoader(getClass.getClassLoader)
4748
private[this] val references = mutable.Map(ReferenceGenome.builtinReferences().toSeq: _*)
4849
private[this] val blockMatrixCache = mutable.Map[String, linalg.BlockMatrix]()
49-
private[this] val compiledCodeCache = new Cache[CodeCacheKey, CompiledFunction[_]](50)
50+
51+
private[this] val compiledCodeCache =
52+
new Cache[CompileCacheKey, (Option[SingleCodeType], Compiled[_])](50)
53+
5054
private[this] val irCache = mutable.Map[Int, BaseIR]()
5155
private[this] val coercerCache = new Cache[Any, LoweredTableReaderCoercer](32)
5256
private[this] var irID: Int = 0
@@ -347,7 +351,7 @@ final class Py4JQueryDriver(backend: Backend) extends Closeable with Logging {
347351
flags = flags,
348352
irMetadata = new IrMetadata(),
349353
blockMatrixCache = blockMatrixCache,
350-
codeCache = compiledCodeCache,
354+
compileCache = compiledCodeCache,
351355
irCache = irCache,
352356
coercerCache = coercerCache,
353357
)(f)

0 commit comments

Comments
 (0)