class_docstr: CUTLASS GEMM template, which is used to generate CUTLASS GEMM kernels
  including those which allow flexible fusions with epilogues.
class_docstr_tok: ["CUTLASS","GEMM","template",",","which","is","used","to","generate","CUTLASS","GEMM","kernels","including","those","which","allow","flexible","fusions","with","epilogues","."]
code: def render(  # type: ignore[override]
      self,
      kernel: CUDATemplateKernel,
      op: "cutlass_gemm_op.GemmOperation" = None,  # type: ignore[name-defined]  # noqa: F821
      template_buffer_node: Optional[CUDATemplateBuffer] = None,
      epilogue_nodes: Optional[List[IRNode]] = None,
      **kwargs,
  ) -> str:
      if epilogue_nodes is not None and len(epilogue_nodes) > 0:
          assert (
              self.can_fuse_epilogue
              and CUTLASSGemmTemplate.supports_evt(op)
          ), "op does not support EVT epilogue fusion"
          assert (
              template_buffer_node is not None
          ), "Template node is required for epilogue fusion"
          assert isinstance(
              template_buffer_node, CUDATemplateBuffer
          ), f"Template node has to be a CUDATemplateBuffer, is type {type(template_buffer_node)}"
          assert (
              template_buffer_node.name is not None
          ), "Output node has to be a Buffer with a name"
          # This is the name of the output of the Matmul, before epilogues are applied.
          # it is not necessarily materialized in global memory if we have an epilogue
  
      template_output_node_name = (
          template_buffer_node.name
          if template_buffer_node is not None
          else None
      )
  
      assert cutlass_utils.try_import_cutlass()
      import cutlass_library.gemm_operation as cutlass_gemm_op
      import cutlass_library.library as cutlass_lib
  
      assert isinstance(
          op, cutlass_gemm_op.GemmOperation
      ), "op argument is required and has to be an instance of GemmOperation"
      if template_buffer_node is not None:
          self.output_node = template_buffer_node
      if epilogue_nodes is not None and len(epilogue_nodes) > 0:
          self.output_node = cast(Buffer, epilogue_nodes[-1])
  
      assert len(self.input_nodes) >= 2 and self.output_node is not None
      X, W = self.input_nodes[0], self.input_nodes[1]
      Y = self.output_node
      Bias = None if len(self.input_nodes) == 2 else self.input_nodes[2]
  
      epilogue_template: Optional[str] = None
      should_swap_xw: bool = False
      epilogue_args = f"{{ElementComputeEpilogue({self.alpha}), ElementComputeEpilogue({self.beta})}}"
      if op.gemm_kind == cutlass_lib.GemmKind.Universal3x:
          if Bias is not None and self.has_tma_epilogue(op):
              if self.should_swap_XW(Bias, self.beta):
                  # TMA epilogue requires bias vector in column major to get best perf.
                  op = self.swap_XW(op)
                  should_swap_xw = True
          if epilogue_nodes is not None and len(epilogue_nodes) > 0:
              epilogue_args = CutlassEVTEpilogueArgumentFormatter.ir_to_evt_argument_string(
                  cast(str, template_output_node_name), epilogue_nodes
              )
          epilogue_template = GEMM_ARGS_CUTLASS_3X_EPILOGUE
          argument_template = GEMM_ARGS_CUTLASS_3X
      else:
          # TODO: Support split_k.
          argument_template = GEMM_ARGS_CUTLASS_2X
  
      instance_definition, instance_type = self.define_gemm_instance(
          op, cast(str, template_output_node_name), epilogue_nodes
      )
      options = dict(
          alpha=self.alpha,
          beta=self.beta,
          X=X,
          W=W,
          Y=Y,
          Bias=Bias,
          epilogue_template=epilogue_template,
          argument_template=argument_template,
          should_swap_xw=should_swap_xw,
          template=self,
          kernel=kernel,
          instance_definition=instance_definition,
          instance_type=instance_type,
          input_reorder=self.input_reorder,
          epilogue_args=epilogue_args,
      )
      res = self._template_from_string(GEMM_TEMPLATE).render(**options)
      return res
  
imports: import copy
  import logging
  import re
  from typing import cast, Dict, List, Optional, Tuple
  from ...config import cuda
  from ...ir import Buffer, CUDATemplateBuffer, FixedLayout, IRNode, Layout
  from ..common import IndentedBuffer
  from .None import cutlass_utils
  from .cuda_kernel import CUDATemplateKernel
  from .cuda_template import CUTLASSTemplate
  from .cutlass_epilogue_gen import CutlassEVTEpilogueArgumentFormatter, CutlassEVTEpilogueTypeFormatter
label_desc: Use image node_id 18 for calling the CUTLASSGemmTemplate obj's underlying member method code with example usage: obj.render(kernel, op, template_buffer_node, epilogue_nodes) and returns: res