in botorch/sampling/samplers.py [0:0]
def _construct_base_samples(self, posterior: Posterior, shape: torch.Size) -> None:
r"""Generate quasi-random Normal base samples (if necessary).
This function will generate a new set of base samples and set the
`base_samples` buffer if one of the following is true:
- `resample=True`
- the MCSampler has no `base_samples` attribute.
- `shape` is different than `self.base_samples.shape` (if
`collapse_batch_dims=True`, then batch dimensions of will be
automatically broadcasted as necessary). This shape is expected to
be `sample_shape + base_sample_shape`, where `base_sample_shape` has been
adjusted to account for `collapse_batch_dims` (i.e., the output
of the function `_get_base_sample_shape`).
Args:
posterior: The Posterior for which to generate base samples.
shape: The shape of the base samples to construct.
"""
if (
self.resample
or _check_shape_changed(self.base_samples, self.batch_range, shape)
or (not self.collapse_batch_dims and shape != self.base_samples.shape)
):
batch_start, batch_end = self.batch_range
sample_shape, base_sample_shape = split_shapes(shape)
output_dim = (
base_sample_shape[:batch_start] + base_sample_shape[batch_end:]
).numel()
if output_dim > SobolEngine.MAXDIM:
raise UnsupportedError(
"SobolQMCSampler only supports dimensions "
f"`q * o <= {SobolEngine.MAXDIM}`. Requested: {output_dim}"
)
base_samples = draw_sobol_normal_samples(
d=output_dim,
n=(sample_shape + base_sample_shape[batch_start:batch_end]).numel(),
device=posterior.device,
dtype=posterior.dtype,
seed=self.seed,
)
self.seed += 1
base_samples = base_samples.view(shape)
self.register_buffer("base_samples", base_samples)
elif self.collapse_batch_dims and shape != posterior.base_sample_shape:
self.base_samples = self.base_samples.view(shape)
if self.base_samples.device != posterior.device:
self.to(device=posterior.device) # pragma: nocover
if self.base_samples.dtype != posterior.dtype:
self.to(dtype=posterior.dtype)