docstr: Test basic logic of seq2slate on policy sampling
docstr_tok: ["Test","basic","logic","of","seq2slate","on","policy","sampling"]
code: def test_seq2slate_transformer_onpolicy_basic_logic(
      self, output_arch, temperature
  ):
      """
      Test basic logic of seq2slate on policy sampling
      """
      device = torch.device("cpu")
      candidate_num = 4
      candidate_dim = 2
      batch_size = 4096
      hidden_size = 32
      seq2slate_net = create_seq2slate_net(
          MODEL_TRANSFORMER,
          candidate_num,
          candidate_dim,
          hidden_size,
          output_arch,
          temperature,
          device,
      )
      batch = create_batch(
          batch_size,
          candidate_num,
          candidate_dim,
          device,
          ON_POLICY,
          diverse_input=False,
      )
  
      action_to_propensity_map = {}
      action_count = defaultdict(int)
      total_count = 0
      for i in range(50):
          model_propensity, model_action = rank_on_policy(
              seq2slate_net, batch, candidate_num, greedy=False
          )
          for propensity, action in zip(model_propensity, model_action):
              action_str = ",".join(map(str, action.numpy().tolist()))
  
              # Same action always leads to same propensity
              if action_to_propensity_map.get(action_str) is None:
                  action_to_propensity_map[action_str] = float(
                      propensity
                  )
              else:
                  np.testing.assert_allclose(
                      action_to_propensity_map[action_str],
                      float(propensity),
                      atol=0.001,
                      rtol=0.0,
                  )
  
              action_count[action_str] += 1
              total_count += 1
  
          logger.info(f"Finish {i} round, {total_count} data counts")
  
      # Check action distribution
      for action_str, count in action_count.items():
          empirical_propensity = count / total_count
          computed_propensity = action_to_propensity_map[action_str]
          logger.info(
              f"action={action_str}, empirical propensity={empirical_propensity}, "
              f"computed propensity={computed_propensity}"
          )
          np.testing.assert_allclose(
              computed_propensity,
              empirical_propensity,
              atol=0.01,
              rtol=0.0,
          )
  
imports: import itertools
  import logging
  import random
  import unittest
  from collections import defaultdict
  from itertools import permutations
  import numpy
  import pytest
  import reagent.core.types
  import torch
  import torch.nn.functional
  from parameterized import parameterized
  from reagent.model_utils.seq2slate_utils import DECODER_START_SYMBOL, mask_logits_by_idx, per_symbol_to_per_seq_log_probs, per_symbol_to_per_seq_probs, pytorch_decoder_mask, Seq2SlateMode, Seq2SlateOutputArch, subsequent_mask
  from reagent.test.ranking.seq2slate_utils import create_batch, create_seq2slate_net, MODEL_TRANSFORMER, ON_POLICY, rank_on_policy, run_seq2slate_tsp
label_desc: Use image node_id 8 for calling the TestSeq2SlateOnPolicy obj's underlying member method code with example usage: obj.test_seq2slate_transformer_onpolicy_basic_logic(output_arch, temperature) without return types