Bugzilla – Bug 1962
RandomVariableStream::GetStream returns -1 for all automatically assigned streams
Last modified: 2015-01-20 15:46:07 EST
Created attachment 1866 [details]
patch to src/core/model/random-variable-stream.cc affecting SetStream()
Summary says it all:
For automatically assigned streams, RandomVariableStream::SetStream() records -1 as the stream number, instead of the actual stream number that was assigned. Subsequent calls to GetStream() then have to report -1 since the real stream number was discarded.
I think the correct behavior is to store the actual stream number which was assigned, so GetStream returns the correct value. This would make it possible to initialize an object in one run with automatic stream number, report it correctly, then use that stream number explicitly in a subsequent run.
Note that this means SetStream has to accept negative stream numbers.
I seem to recall that there was a reason that these automatically set stream numbers were not recorded (i.e. the -1 is a design choice) but I can't remember the reason if so, and I agree with your reasoning and suggested use case.
Now that I've thought about it a little bit more, I'd like to modify the goals:
GetStream() should report the actually assigned stream (as requested above).
SetStream() should probably refuse (with an error, as now) to accept negative stream numbers.
There is a difficulty in allowing SetStream() to accept automatic (negative) stream numbers: there is no way to guarantee that the desired negative stream number hasn't already been assigned, which would lead to undesirable correlations between independent objects.
For example, suppose on the first run a model object Foo does
m_rng = SetStream (-1);
Then the user saves the stream number to reuse later:
int64_t fooRng = Foo.GetStream ();
std::cout << "Foo rng stream: " << fooRng << std::endl;
On a subsequent run, the user wants Foo to repeat, so he does
but the user's code has changed, so some rng initialized earlier has the same value as fooRng desired by the user. Now two objects are using the same stream. The user has no way to detect this, and no way to fix it except by ad hoc altering initialization order in his code, hoping to get things in the right order. If the conflicting object is a result of static initialization, then there is no fix possible: the desired stream is assigned before the user can do anything.
One partial workaround we could implement is:
- In the case that the next automatic stream is earlier than fooRng, SetStream could do the assignment, but set the next automatic stream to fooRng - 1. (Remember automatic stream numbers grow negative.)
- In the case that the next automatic stream is later than fooRng, SetStream should error, since something else already claimed fooRng.
A more involved partial workaround would be to allow the user to reserve a set of negative stream numbers at the beginning of main(), so automatic assignment won't use them. (But this still doesn't address static initialization.)
So I'm talking myself around to a. report the assigned stream and b. refuse negative streams. Obviously we should document this dilemma: GetStream on automatically assigned is only useful for information purposes. If you want to repeat an aspect of a run, you have to explicitly assign streams to those components.
This seems to be a big shift (or watering down) of goals. Is just being able to know what automatic assignments occurred a good enough outcome here?
I'm not sure I understand the tenor of your question:
> Is just being able to know what automatic assignments occurred
> a good enough outcome here?
Do you think that is sufficient? or insufficient?
It's certainly watered down from what I originally requested:
- record (and report) actual stream number
- support explicit assignment of automatic stream numbers (streams < 0)
Doing the first item is straightforward. My subsequent comments illustrate why doing the second has significant issues.
To be clear, I think reporting the stream number correctly is sufficient for now.
(In reply to Peter Barnes from comment #4)
> I'm not sure I understand the tenor of your question:
> > Is just being able to know what automatic assignments occurred
> > a good enough outcome here?
> Do you think that is sufficient? or insufficient?
> It's certainly watered down from what I originally requested:
> - record (and report) actual stream number
> - support explicit assignment of automatic stream numbers (streams < 0)
> Doing the first item is straightforward. My subsequent comments illustrate
> why doing the second has significant issues.
> To be clear, I think reporting the stream number correctly is sufficient for
OK, I was just wondering if the removal of the second goal (the watering down of your original goals) was going to be problematic for your experiments (and therefore still needs a solution despite the difficulty you explained).