class_docstr: Base class for continuous entropy models.
  
  The basic functionality of this class is to pre-compute integer probability
  tables based on the provided `tfp.distributions.Distribution` object, which
  can then be used reliably across different platforms by the range coder and
  decoder.
class_docstr_tok: ["Base","class","for","continuous","entropy","models",".","The","basic","functionality","of","this","class","is","to","pre-compute","integer","probability","tables","based","on","the","provided","`","tfp.distributions.Distribution","`","object",",","which","can","then","be","used","reliably","across","different","platforms","by","the","range","coder","and","decoder","."]
docstr: Computes integer-valued probability tables used by the range coder.
  
  These tables must not be re-generated independently on the sending and
  receiving side, since small numerical discrepancies between both sides can
  occur in this process. If the tables differ slightly, this in turn would
  very likely cause catastrophic error propagation during range decoding. For
  a more in-depth discussion of this, see:
  
  > "Integer Networks for Data Compression with Latent-Variable Models"<br />
  > J. Ballé, N. Johnston, D. Minnen<br />
  > https://openreview.net/forum?id=S1zz2i0cY7
  
  Args:
    prior: The `tfp.distributions.Distribution` object (see initializer).
    precision: Integer. Precision for range coder.
    offset: None or float tensor between -.5 and +.5. Sub-integer quantization
      offsets to use for sampling prior probabilities. Defaults to 0.
  
  Returns:
    CDF table, CDF offsets, CDF lengths.
docstr_tok: ["Computes","integer-valued","probability","tables","used","by","the","range","coder",".","These","tables","must","not","be","re-generated","independently","on","the","sending","and","receiving","side",",","since","small","numerical","discrepancies","between","both","sides","can","occur","in","this","process",".","If","the","tables","differ","slightly",",","this","in","turn","would","very","likely","cause","catastrophic","error","propagation","during","range","decoding",".","For","a","more","in-depth","discussion","of","this",",","see",":",">","``","Integer","Networks","for","Data","Compression","with","Latent-Variable","Models","''","<","br","\/",">",">","J.","Ball\u00e9",",","N.","Johnston",",","D.","Minnen","<","br","\/",">",">","https",":","\/\/openreview.net\/forum","?","id=S1zz2i0cY7","Args",":","prior",":","The","`","tfp.distributions.Distribution","`","object","(","see","initializer",")",".","precision",":","Integer",".","Precision","for","range","coder",".","offset",":","None","or","float","tensor","between","-.5","and","+.5",".","Sub-integer","quantization","offsets","to","use","for","sampling","prior","probabilities",".","Defaults","to","0",".","Returns",":","CDF","table",",","CDF","offsets",",","CDF","lengths","."]
code: def _build_tables(self, prior, precision, offset=None):
      """Computes integer-valued probability tables used by the range coder.
  
      These tables must not be re-generated independently on the sending and
      receiving side, since small numerical discrepancies between both sides can
      occur in this process. If the tables differ slightly, this in turn would
      very likely cause catastrophic error propagation during range decoding. For
      a more in-depth discussion of this, see:
  
      > "Integer Networks for Data Compression with Latent-Variable Models"<br />
      > J. Ballé, N. Johnston, D. Minnen<br />
      > https://openreview.net/forum?id=S1zz2i0cY7
  
      Args:
        prior: The `tfp.distributions.Distribution` object (see initializer).
        precision: Integer. Precision for range coder.
        offset: None or float tensor between -.5 and +.5. Sub-integer quantization
          offsets to use for sampling prior probabilities. Defaults to 0.
  
      Returns:
        CDF table, CDF offsets, CDF lengths.
      """
      precision = int(precision)
      offset = tf.cast(0 if offset is None else offset, prior.dtype)
      # Subclasses should have already caught this, but better be safe.
      assert not prior.event_shape.rank
  
      lower_tail = helpers.lower_tail(prior, self.tail_mass)
      upper_tail = helpers.upper_tail(prior, self.tail_mass)
      # Integers such that:
      # minima + offset < lower_tail
      # maxima + offset > upper_tail
      minima = tf.cast(tf.math.floor(lower_tail - offset), tf.int32)
      maxima = tf.cast(tf.math.ceil(upper_tail - offset), tf.int32)
  
      # PMF starting positions and lengths.
      pmf_start = tf.cast(minima, prior.dtype) + offset
      pmf_length = maxima - minima + 1
  
      # Sample the densities in the computed ranges, possibly computing more
      # samples than necessary at the upper end.
      max_length = tf.math.reduce_max(pmf_length)
      if tf.executing_eagerly() and max_length > 2048:
          logging.warning(
              "Very wide PMF with %d elements may lead to out of memory issues. "
              "Consider priors with smaller variance, or increasing `tail_mass` "
              "parameter.",
              int(max_length),
          )
      samples = tf.range(
          tf.cast(max_length, prior.dtype), dtype=prior.dtype
      )
      samples = tf.reshape(samples, [-1] + pmf_length.shape.rank * [1])
      samples += pmf_start
      pmf = prior.prob(samples)
      pmf_shape = tf.shape(pmf)[1:]
      num_pmfs = tf.reduce_prod(pmf_shape)
  
      # Collapse batch dimensions of distribution.
      pmf = tf.reshape(pmf, [max_length, num_pmfs])
      pmf = tf.transpose(pmf)
  
      pmf_length = tf.broadcast_to(pmf_length, pmf_shape)
      pmf_length = tf.reshape(pmf_length, [num_pmfs])
      cdf_offset = tf.broadcast_to(minima, pmf_shape)
      cdf_offset = tf.reshape(cdf_offset, [num_pmfs])
      precision_tensor = tf.constant([-precision], dtype=tf.int32)
  
      # Prevent tensors from bouncing back and forth between host and GPU.
      with tf.device("/cpu:0"):
  
          def loop_body(i, cdf):
              p = pmf[i, : pmf_length[i]]
              overflow = tf.math.maximum(
                  1.0 - tf.reduce_sum(p, keepdims=True), 0.0
              )
              p = tf.cast(tf.concat([p, overflow], 0), tf.float32)
              c = gen_ops.pmf_to_quantized_cdf(p, precision=precision)
              return i + 1, tf.concat([cdf, precision_tensor, c], 0)
  
          i_0 = tf.constant(0, tf.int32)
          cdf_0 = tf.constant([], tf.int32)
          _, cdf = tf.while_loop(
              lambda i, _: i < num_pmfs,
              loop_body,
              (i_0, cdf_0),
              shape_invariants=(i_0.shape, tf.TensorShape([None])),
              name="pmf_to_cdf",
          )
  
      return cdf, cdf_offset
  
imports: import abc
  from absl import logging
  import tensorflow
  from tensorflow_compression.python.distributions import helpers
  from tensorflow_compression.python.distributions import uniform_noise
  from tensorflow_compression.python.ops import gen_ops
label_desc: Use image node_id 16 for calling the ContinuousEntropyModelBase obj's underlying member method code with example usage: obj._build_tables(prior, precision, offset) and returns: cdf,  cdf_offset, unknown,  tf