Project: 055_Prioritized_Generative_Replay | Function: sample_cond (iclr)

system: You are an expert Python programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow Python best practices and maintain consistent code style.
Return **only** the complete Python function code.

user: Complete this Python function:

**DESCRIPTION:** Prioritized sampling mechanism that selects conditioning signals from transitions with highest relevance scores. Implements the core prioritization strategy of PGR by sampling from the top fraction of curiosity-driven relevance values to guide generative replay towards more learning-informative regions.

**KEY TERMS:** {
  "top_frac_indices": "highest F(s, a, s′, r) indices",
  "irews_buf": "relevance buffer F values",
  "best_indices": "selected high-priority transitions",
  "batch_size": "number of conditions to sample"
}

**CONTEXT CODE:**         data = make_inputs_from_replay_buffer(buffer, self.model_terminals)
        data = torch.from_numpy(data).float()
        self.model.normalizer.reset(data)
        self.ema.ema_model.normalizer.reset(data)
        if device:
            self.model.normalizer.to(device)
            self.ema.ema_model.normalizer.to(device)



class CondDistri(object):
    def __init__(self, cond_net, train_batch_size, buffer, top_frac):
        self.top_frac = top_frac
        self.buffer = buffer

        # Iterate over buffer and generate the conditional generation signal
        self.irews_buf = np.zeros_like(buffer.rews_buf)
        # Use some large batch size
        for i in range(0, buffer.size, train_batch_size):
            idxs = np.arange(i, min(i + train_batch_size, buffer.size))
            obs = self.buffer.obs1_buf[idxs]
            next_obs = self.buffer.obs2_buf[idxs]
            actions = self.buffer.acts_buf[idxs]
            rewards = self.buffer.rews_buf[idxs][:, None]
            done = self.buffer.done_buf[idxs][:, None]
            with torch.no_grad():
                self.irews_buf[idxs] = cond_net.compute_reward(obs, next_obs, actions, rewards, done).squeeze().cpu().numpy()
        
        self.top_frac_indices = np.argsort(self.irews_buf, axis=0)[-int(top_frac * buffer.size):]

    def sample_batch(self, batch_size=32, idxs=None):
        """
        :param batch_size: size of minibatch
        :param idxs: specify indexes if you want specific data points
        :return: mini-batch data as a dictionary
        """
        if idxs is None:
            idxs = np.random.randint(0, self.buffer.size, size=batch_size)
        return dict(obs1=self.buffer.obs1_buf[idxs],
                    obs2=self.buffer.obs2_buf[idxs],
                    acts=self.buffer.acts_buf[idxs],
                    rews=self.buffer.rews_buf[idxs],
                    done=self.buffer.done_buf[idxs],
                    irews=self.irews_buf[idxs],
                    idxs=idxs)

    def sample_uncond(self, batch_size):
        # Sample batch_size randomly from self.irews
        return self.irews_buf[np.random.choice(self.irews_buf.shape[0], batch_size, replace=True), None]
    
    def sample_cond(self, batch_size):
        raise NotImplementedError("Function implementation has been masked for testing")

Complete the function implementation replacing "raise NotImplementedError".