code: def make_reordered_loop(
      init_loop_orders, olv_index, dtypes, inner_task, sub, openmp=None
  ):
      """A bit like make_loop, but when only the inner-most loop executes code.
  
      All the loops will be reordered so that the loops over the output tensor
      are executed with memory access as contiguous as possible.
      For instance, if the output tensor is c_contiguous, the inner-most loop
      will be on its rows; if it's f_contiguous, it will be on its columns.
  
      The output tensor's index among the loop variables is indicated by olv_index.
  
      """
  
      # Number of variables
      nvars = len(init_loop_orders)
      # Number of loops (dimensionality of the variables)
      nnested = len(init_loop_orders[0])
  
      # This is the var from which we'll get the loop order
      ovar = sub[f"lv{int(olv_index)}"]
  
      # The loops are ordered by (decreasing) absolute values of ovar's strides.
      # The first element of each pair is the absolute value of the stride
      # The second element correspond to the index in the initial loop order
      order_loops = f"""
      std::vector< std::pair<int, int> > {ovar}_loops({int(nnested)});
      std::vector< std::pair<int, int> >::iterator {ovar}_loops_it = {ovar}_loops.begin();
      """
  
      # Fill the loop vector with the appropriate <stride, index> pairs
      for i, index in enumerate(init_loop_orders[olv_index]):
          if index != "x":
              order_loops += f"""
              {ovar}_loops_it->first = abs(PyArray_STRIDES({ovar})[{int(index)}]);
              """
          else:
              # Stride is 0 when dimension is broadcastable
              order_loops += f"""
              {ovar}_loops_it->first = 0;
              """
  
          order_loops += f"""
          {ovar}_loops_it->second = {int(i)};
          ++{ovar}_loops_it;
          """
  
      # We sort in decreasing order so that the outermost loop (loop 0)
      # has the largest stride, and the innermost loop (nnested - 1) has
      # the smallest stride.
      order_loops += f"""
      // rbegin and rend are reversed iterators, so this sorts in decreasing order
      std::sort({ovar}_loops.rbegin(), {ovar}_loops.rend());
      """
  
      # Get the (sorted) total number of iterations of each loop
      declare_totals = f"int init_totals[{nnested}];\n"
      declare_totals += compute_output_dims_lengths(
          "init_totals", init_loop_orders, sub
      )
  
      # Sort totals to match the new order that was computed by sorting
      # the loop vector. One integer variable per loop is declared.
      declare_totals += f"""
      {ovar}_loops_it = {ovar}_loops.begin();
      """
  
      for i in range(nnested):
          declare_totals += f"""
          int TOTAL_{int(i)} = init_totals[{ovar}_loops_it->second];
          ++{ovar}_loops_it;
          """
  
      # Get sorted strides
      # Get strides in the initial order
      def get_loop_strides(loop_order, i):
          """
          Returns a list containing a C expression representing the
          stride for each dimension of the ith variable, in the
          specified loop_order.
  
          """
          var = sub[f"lv{int(i)}"]
          r = []
          for index in loop_order:
              # Note: the stride variable is not declared for broadcasted variables
              if index != "x":
                  r.append(f"{var}_stride{index}")
              else:
                  r.append("0")
          return r
  
      # We declare the initial strides as a 2D array, nvars x nnested
      strides = ", \n".join(
          ", ".join(get_loop_strides(lo, i))
          for i, lo in enumerate(init_loop_orders)
          if len(lo) > 0
      )
  
      declare_strides = f"""
      int init_strides[{int(nvars)}][{int(nnested)}] = {{
          {strides}
      }};"""
  
      # Declare (sorted) stride and for each variable
      # we iterate from innermost loop to outermost loop
      declare_strides += f"""
      std::vector< std::pair<int, int> >::reverse_iterator {ovar}_loops_rit;
      """
  
      for i in range(nvars):
          var = sub[f"lv{int(i)}"]
          declare_strides += f"""
          {ovar}_loops_rit = {ovar}_loops.rbegin();"""
          for j in reversed(range(nnested)):
              declare_strides += f"""
              int {var}_stride_l{int(j)} = init_strides[{int(i)}][{ovar}_loops_rit->second];
              ++{ovar}_loops_rit;
              """
  
      declare_iter = ""
      for i, dtype in enumerate(dtypes):
          var = sub[f"lv{int(i)}"]
          declare_iter += (
              f"{var}_iter = ({dtype}*)(PyArray_DATA({var}));\n"
          )
  
      pointer_update = ""
      for j, dtype in enumerate(dtypes):
          var = sub[f"lv{int(j)}"]
          pointer_update += f"{dtype} &{var}_i = * ( {var}_iter"
          for i in reversed(range(nnested)):
              iterv = f"ITER_{int(i)}"
              pointer_update += f"+{var}_stride_l{int(i)}*{iterv}"
          pointer_update += ");\n"
  
      loop = inner_task
      for i in reversed(range(nnested)):
          iterv = f"ITER_{int(i)}"
          total = f"TOTAL_{int(i)}"
          update = ""
          forloop = ""
          # The pointers are defined only in the most inner loop
          if i == nnested - 1:
              update = pointer_update
          if i == 0:
              if openmp:
                  openmp_elemwise_minsize = (
                      config.openmp_elemwise_minsize
                  )
                  forloop += f"""#pragma omp parallel for if( {total} >={openmp_elemwise_minsize})\n"""
          forloop += f"for(int {iterv} = 0; {iterv}<{total}; {iterv}++)"
  
          loop = f"""
          {forloop}
          {{ // begin loop {int(i)}
              {update}
              {loop}
          }} // end loop {int(i)}
          """
  
      return "\n".join(
          [
              "{",
              order_loops,
              declare_totals,
              declare_strides,
              declare_iter,
              loop,
              "}\n",
          ]
      )
  
file_path: pytensor/pytensor/tensor/elemwise_cgen.py
imports: from pytensor.configdefaults import config
label_desc: Use image node_id 6 for calling a global function with example usage: make_reordered_loop(init_loop_orders, olv_index, dtypes, inner_task, sub, openmp) and returns: str, r