code: def test_pmi_unmasked_computation(self, device: str):
      ova_pmi = AssociationWithoutGroundTruth(2, 2, "pmi", "ova")
      pairwise_pmi = AssociationWithoutGroundTruth(
          2, 2, "pmi", "pairwise"
      )
      Y = torch.ones(3, 3, device=device).long()
      X = torch.eye(3, device=device).long()
  
      # P(X = 0, Y = 0) = 0
      # P(X = 0, Y = 1) = 2/3
      # P(X = 1, Y = 0) = 0
      # P(X = 1, Y = 1) = 1/3
      # P(X = 0) = 2/3
      # P(X = 1) = 1/3
      # P(Y = 0) = 0
      # P(Y = 1) = 1
      # G(Y = 0 | X = 0, X = rest, PMI) = NaN
      # G(Y = 1 | X = 0, X = rest, PMI) = ln(1) - ln(1) = 0.0
      # G(Y = 0 | X = 1, X = rest, PMI) = NaN
      # G(Y = 1 | X = 1, X = rest, PMI) = ln(1) - ln(1) = 0.0
      expected_ova_pmi_gaps = {
          0: [np.nan, 0.0],
          1: [np.nan, 0.0],
      }
  
      ova_pmi(Y, X)
      test_ova_pmi_gaps = {
          k: [(e if not math.isnan(e) else np.nan) for e in v.tolist()]  # type: ignore
          for k, v in ova_pmi.get_metric().items()
      }
      assert expected_ova_pmi_gaps == test_ova_pmi_gaps
  
      ova_pmi(Y, X)
      test_ova_pmi_gaps = {
          k: [(e if not math.isnan(e) else np.nan) for e in v.tolist()]  # type: ignore
          for k, v in ova_pmi.get_metric(reset=True).items()
      }
      assert expected_ova_pmi_gaps == test_ova_pmi_gaps
  
      test_ova_pmi_gaps = {
          k: [(e if not math.isnan(e) else np.nan) for e in v.tolist()]  # type: ignore
          for k, v in ova_pmi.get_metric(reset=True).items()
      }
      assert test_ova_pmi_gaps == {
          0: [np.nan, np.nan],
          1: [np.nan, np.nan],
      }
  
      expected_pairwise_pmi_gaps = {
          0: {0: [np.nan, 0.0], 1: [np.nan, 0.0]},
          1: {0: [np.nan, 0.0], 1: [np.nan, 0.0]},
      }
  
      pairwise_pmi(Y, X)
      test_pairwise_pmi_gaps = {
          k1: {
              k2: [(e if not math.isnan(e) else np.nan) for e in v2.tolist()]  # type: ignore
              for k2, v2 in v1.items()
          }
          for k1, v1 in pairwise_pmi.get_metric().items()
      }
      assert expected_pairwise_pmi_gaps == test_pairwise_pmi_gaps
  
      pairwise_pmi(Y, X)
      test_pairwise_pmi_gaps = {
          k1: {
              k2: [
                  (e if not math.isnan(e) else np.nan)
                  for e in v2.tolist()
              ]
              for k2, v2 in v1.items()
          }
          for k1, v1 in pairwise_pmi.get_metric(reset=True).items()
      }
      assert expected_pairwise_pmi_gaps == test_pairwise_pmi_gaps
  
      test_pairwise_pmi_gaps = {
          k1: {
              k2: [
                  (e if not math.isnan(e) else np.nan)
                  for e in v2.tolist()
              ]
              for k2, v2 in v1.items()
          }
          for k1, v1 in pairwise_pmi.get_metric(reset=True).items()
      }
      assert test_pairwise_pmi_gaps == {
          0: {0: [np.nan, np.nan], 1: [np.nan, np.nan]},
          1: {0: [np.nan, np.nan], 1: [np.nan, np.nan]},
      }
  
imports: import pytest
  import torch
  import json
  import math
  import numpy
  from allennlp.common.checks import ConfigurationError
  from allennlp.common.testing import AllenNlpTestCase, multi_device, global_distributed_metric, run_distributed_test
  from allennlp.fairness.bias_metrics import WordEmbeddingAssociationTest, EmbeddingCoherenceTest, NaturalLanguageInference, AssociationWithoutGroundTruth
label_desc: Use image node_id 3 for calling the AssociationWithoutGroundTruthTest obj's underlying member method code with example usage: obj.test_pmi_unmasked_computation(device) without return types