code: def _print_math(self, expr):
      name = self.known_functions[expr.__class__.__name__]
      if not isinstance(name, str):
          for cb, fname in name:
              if cb(*expr.args):
                  name = fname
                  break
          else:
              raise ValueError("No matching printer")
  
      # Setting precision of math functions required some rethinking
      # Doing e.g., hls::pow<x.width, x.iwidth>(x, y) passes C sim, but fails synthesis, need to use hls::pow<16,6>(x,y)
      type_name = self.layer.types["result_t"].name
      type_precision = self.layer.types["result_t"].precision
      template = f"<{type_precision.width}, {type_precision.integer}>"
      cast = f"({type_name})"
      args = ", ".join(map(lambda arg: self._print(arg), expr.args))
  
      if self.use_built_in_luts and name + "_lut" in built_in_luts:
          ns = "nnet::"
          name = name + "_lut"
          template = f"<{type_name}>"
      else:
          ns = self._ns
  
      return f"{ns}{name}{template}({cast}({args}))"
  
imports: import re
  from sympy.core import S
  from sympy.core.numbers import Integer
  from sympy.printing.cxx import CXX11CodePrinter
  from hls4ml.backends.template import FunctionCallTemplate, LayerConfigTemplate
  from hls4ml.model.layers import SymbolicExpression
label_desc: Use image node_id 8 for calling the HLSCodePrinter obj's underlying member method code with example usage: obj._print_math(expr) and returns: ns, name, template, str, cast, str, args, str