Consider making RandomStream
-generated RandomVariable
s update RNGs in-place
#1479
Replies: 4 comments
-
Yes.
I think it's fine to break this NumPy "compatibility" since we're effectively saying that the context for a call includes the state of the RandomStream. NumPy also assumes this, the state is just updated globally. |
Beta Was this translation helpful? Give feedback.
-
Luckily, the end result of this proposed change wouldn't actually change any important user-facing behavior, aside from the way that in-place RNG updating can effectively be disabled by disabling default updates via the relevant |
Beta Was this translation helpful? Give feedback.
-
Here's the primary reason such a change wasn't made earlier: Theano was designed to be "functional", in that its graphs were expected to contain objects with more or less no state (and/or loops). More importantly, the identity of This is the design issue we would need to address. |
Beta Was this translation helpful? Give feedback.
-
Just to be clear, I created this issue so that we can have a record of this approach and some important considerations regarding it. In general, this issue relates directly to many other For instance, going back to the basics of The discussion in #1251 describes the above very well, and some possible improvements to the graph-level representation of RNG updates and N.B. The approach in #1251 does fix some design issues that could help with the usability of chained RNG outputs, though, and that's important. |
Beta Was this translation helpful? Give feedback.
-
@aesara-devs/core, should we make
RandomStream
returnRandomVariable
s withRandomVariable.inplace == True
, instead of settingSharedVariable.default_update
s on the generatedRandomTypeSharedVariable
s?The reason we set
SharedVariable.default_update
is so that theaesara.function
-compiled results will generate different samples between calls, as one would expect in a normal NumPy scenario. To do that, some form of global RNG state is required, and that's provided by theRandomTypeSharedVariable
objects; however, those objects need to be updated in-place each time a sample is drawn, and it's theaesara.function
updates mechanism that provides this in a very general way. In the case ofRandomVariable
Op
s, there's aRandomVariable.inplace
attribute that also provides this and is considerably more efficient to use, because it removes thecopy
performed on the RNG before sampling. Since samples drawn fromRandomStream
are always intended to be updated in-place—albeit using the updates mechanisms—it seems like we should just use theOp
-level in-placing and avoid the additional overhead and fundamentally problematicSharedVariable.default_update
s attribute altogether.(N.B. We have an
aesara.tensor.random.rewriting.basic.random_make_inplace
rewrite that replacesRandomVariable
Op
s with in-placed versions under theFAST_RUN
compilation mode.)The underlying problem is that by setting
SharedVariable.default_update
inRandomStream.gen
, we're adding "state" to theRandomTypeSharedVariable
s we produce (i.e. state that unnecessarily associatesRandomTypeSharedVariable
s with specific sample graphs), and this state makes it difficult to reuse existingRandomTypeSharedVariable
s in rewrites. Plus, it can easily lead to the introduction of old, unwanted update graphs—the end result of which is that we end up compiling and sampling from a completely different graph (i.e. than the one we intended) just to update a shared RNG object. A full illustration of the problem is provided here.In general, we should completely remove
SharedVariable.default_update
, because it severely complicates more than a couple things in Aesara. The only reason we haven't removed it is due to its use in this one case.N.B. This idea has come up once before, but I guess we didn't have an explicit issue for it.
Beta Was this translation helpful? Give feedback.
All reactions