class_docstr: Codegen class, which provides an entry point to generate
  Cutlass "Epilogue Visitor Tree" (EVT) functor declarations.
  
  See https://github.com/NVIDIA/cutlass/tree/main/examples/49_hopper_gemm_with_collective_builder
  for more about EVTs and how they are declared and used to generate.
  
  Notes:
      * Used by CUTLASSGemmTemplate.
      * This class should not be instantiated by users, it is intended to be used
          by calling CutlassEVTEpilogueTypeFormatter.ir_to_evt_string(...)
          which instantiates this class as an ops handler for virtualized.V.ops.[op-name]
      * Extend this with more _op_<whatever> nodes to add support for new pointwise operations.
class_docstr_tok: ["Codegen","class",",","which","provides","an","entry","point","to","generate","Cutlass","``","Epilogue","Visitor","Tree","''","(","EVT",")","functor","declarations",".","See","https",":","\/\/github.com\/NVIDIA\/cutlass\/tree\/main\/examples\/49_hopper_gemm_with_collective_builder","for","more","about","EVTs","and","how","they","are","declared","and","used","to","generate",".","Notes",":","*","Used","by","CUTLASSGemmTemplate",".","*","This","class","should","not","be","instantiated","by","users",",","it","is","intended","to","be","used","by","calling","CutlassEVTEpilogueTypeFormatter.ir_to_evt_string","(","...",")","which","instantiates","this","class","as","an","ops","handler","for","virtualized.V.ops",".","[","op-name","]","*","Extend","this","with","more","_op_","<","whatever",">","nodes","to","add","support","for","new","pointwise","operations","."]
docstr: Formats IR nodes into a string representation compatible with Cutlass EVT format.
  
  Args:
      template_output_node_name (str): The name of the template output node.
      evt_type_name (str): The name of the EVT type.
      epilogue_nodes (List[IRNode]): A list of IR nodes representing the epilogue nodes. As of now, these must be
          ComputedBuffer nodes wrapping Pointwise nodes.
  
  Returns:
      A string representation of the IR nodes formatted according to the Cutlass EVT format.
docstr_tok: ["Formats","IR","nodes","into","a","string","representation","compatible","with","Cutlass","EVT","format",".","Args",":","template_output_node_name","(","str",")",":","The","name","of","the","template","output","node",".","evt_type_name","(","str",")",":","The","name","of","the","EVT","type",".","epilogue_nodes","(","List","[","IRNode","]",")",":","A","list","of","IR","nodes","representing","the","epilogue","nodes",".","As","of","now",",","these","must","be","ComputedBuffer","nodes","wrapping","Pointwise","nodes",".","Returns",":","A","string","representation","of","the","IR","nodes","formatted","according","to","the","Cutlass","EVT","format","."]
code: def ir_to_evt_string(
      template_output_node_name: str,
      evt_type_name: str,
      epilogue_nodes: List[IRNode],
  ):
      """
      Formats IR nodes into a string representation compatible with Cutlass EVT format.
  
      Args:
          template_output_node_name (str): The name of the template output node.
          evt_type_name (str): The name of the EVT type.
          epilogue_nodes (List[IRNode]): A list of IR nodes representing the epilogue nodes. As of now, these must be
              ComputedBuffer nodes wrapping Pointwise nodes.
  
      Returns:
          A string representation of the IR nodes formatted according to the Cutlass EVT format.
      """
      formatter = CutlassEVTEpilogueTypeFormatter(
          template_output_node_name, evt_type_name
      )
  
      with virtualized.V.set_ops_handler(formatter), patch.object(
          FlexibleLayout, "allow_indexing", True
      ):
          for node in epilogue_nodes:
              if isinstance(node, ComputedBuffer):
                  pnode = node.data
              else:
                  raise RuntimeError(
                      "Epilogue nodes must be Pointwise nodes, wrapped in a named ComputedBuffer"
                  )
              assert isinstance(pnode, Pointwise)
              index = pnode._index(pnode.ranges)
              result = pnode.inner_fn(index)
              # each epilogue node results in a single "using" statement and may refer to the previous steps by name
              formatter.aliases[node.name] = result
          res = formatter.getvalue(result)
          if _MAGIC_SYMPY_ERROR_STRING in res:
              raise CUTLASSEVTOpNotImplementedError(
                  "sympy / indexing expressions not yet supported in EVT fusion"
              )
          else:
              return res
  
imports: from typing import Dict, List
  from unittest.mock import patch
  import sympy
  import torch._inductor.virtualized
  from torch._inductor.ir import ComputedBuffer, FlexibleLayout, IRNode, Pointwise
  from torch._inductor.utils import IndentedBuffer, sympy_str
label_desc: Use image node_id 2 for calling the CutlassEVTEpilogueTypeFormatter obj's underlying member method code with example usage: obj.ir_to_evt_string(template_output_node_name, evt_type_name, epilogue_nodes) and returns: res