code: def param2img_parallel(
      param, decision, meta_brushes, cur_canvas, stroke_num=8
  ):
      """
      Input stroke parameters and decisions for each patch, meta brushes, current canvas, frame directory,
      and whether there is a border (if intermediate painting results are required).
      Output the painting results of adding the corresponding strokes on the current canvas.
      Args:
          param: a tensor with shape batch size x patch along height dimension x patch along width dimension
           x n_stroke_per_patch x n_param_per_stroke
          decision: a 01 tensor with shape batch size x patch along height dimension x patch along width dimension
           x n_stroke_per_patch
          meta_brushes: a tensor with shape 2 x 3 x meta_brush_height x meta_brush_width.
          The first slice on the batch dimension denotes vertical brush and the second one denotes horizontal brush.
          cur_canvas: a tensor with shape batch size x 3 x H x W,
           where H and W denote height and width of padded results of original images.
  
      Returns:
          cur_canvas: a tensor with shape batch size x 3 x H x W, denoting painting results.
      """
      # param: b, h, w, stroke_per_patch, param_per_stroke
      # decision: b, h, w, stroke_per_patch
      b, h, w, s, p = param.shape
      h, w = int(h), int(w)
      param = param.reshape([-1, 8])
      decision = decision.reshape([-1, 8])
  
      H, W = cur_canvas.shape[-2:]
      is_odd_y = h % 2 == 1
      is_odd_x = w % 2 == 1
      render_size_y = 2 * H // h
      render_size_x = 2 * W // w
  
      even_idx_y = paddle.arange(0, h, 2)
      even_idx_x = paddle.arange(0, w, 2)
      if h > 1:
          odd_idx_y = paddle.arange(1, h, 2)
      if w > 1:
          odd_idx_x = paddle.arange(1, w, 2)
  
      cur_canvas = F.pad(
          cur_canvas,
          [
              render_size_x // 4,
              render_size_x // 4,
              render_size_y // 4,
              render_size_y // 4,
          ],
      )
  
      valid_foregrounds = render_utils.param2stroke(
          param, render_size_y, render_size_x, meta_brushes
      )
  
      # * ----- load dilation/erosion ---- *#
      dilation = render_utils.Dilation2d(m=1)
      erosion = render_utils.Erosion2d(m=1)
  
      # * ----- generate alphas ----- *#
      valid_alphas = (valid_foregrounds > 0).astype("float32")
      valid_foregrounds = valid_foregrounds.reshape(
          [-1, stroke_num, 1, render_size_y, render_size_x]
      )
      valid_alphas = valid_alphas.reshape(
          [-1, stroke_num, 1, render_size_y, render_size_x]
      )
  
      temp = [
          dilation(valid_foregrounds[:, i, :, :, :])
          for i in range(stroke_num)
      ]
      valid_foregrounds = paddle.stack(temp, axis=1)
      valid_foregrounds = valid_foregrounds.reshape(
          [-1, 1, render_size_y, render_size_x]
      )
  
      temp = [
          erosion(valid_alphas[:, i, :, :, :])
          for i in range(stroke_num)
      ]
      valid_alphas = paddle.stack(temp, axis=1)
      valid_alphas = valid_alphas.reshape(
          [-1, 1, render_size_y, render_size_x]
      )
  
      foregrounds = valid_foregrounds.reshape(
          [-1, h, w, stroke_num, 1, render_size_y, render_size_x]
      )
      alphas = valid_alphas.reshape(
          [-1, h, w, stroke_num, 1, render_size_y, render_size_x]
      )
      decision = decision.reshape([-1, h, w, stroke_num, 1, 1, 1])
      param = param.reshape([-1, h, w, stroke_num, 8])
  
      def partial_render(this_canvas, patch_coord_y, patch_coord_x):
          canvas_patch = F.unfold(
              this_canvas,
              [render_size_y, render_size_x],
              strides=[render_size_y // 2, render_size_x // 2],
          )
          # canvas_patch: b, 3 * py * px, h * w
          canvas_patch = canvas_patch.reshape(
              [b, 3, render_size_y, render_size_x, h, w]
          )
          canvas_patch = canvas_patch.transpose([0, 4, 5, 1, 2, 3])
          selected_canvas_patch = paddle.gather(
              canvas_patch, patch_coord_y, 1
          )
          selected_canvas_patch = paddle.gather(
              selected_canvas_patch, patch_coord_x, 2
          )
          selected_canvas_patch = selected_canvas_patch.reshape(
              [0, 0, 0, 1, 3, render_size_y, render_size_x]
          )
          selected_foregrounds = paddle.gather(
              foregrounds, patch_coord_y, 1
          )
          selected_foregrounds = paddle.gather(
              selected_foregrounds, patch_coord_x, 2
          )
          selected_alphas = paddle.gather(alphas, patch_coord_y, 1)
          selected_alphas = paddle.gather(
              selected_alphas, patch_coord_x, 2
          )
          selected_decisions = paddle.gather(decision, patch_coord_y, 1)
          selected_decisions = paddle.gather(
              selected_decisions, patch_coord_x, 2
          )
          selected_color = paddle.gather(param, patch_coord_y, 1)
          selected_color = paddle.gather(
              selected_color, patch_coord_x, 2
          )
          selected_color = paddle.gather(
              selected_color, paddle.to_tensor([5, 6, 7]), 4
          )
          selected_color = selected_color.reshape(
              [0, 0, 0, stroke_num, 3, 1, 1]
          )
  
          for i in range(stroke_num):
              i = paddle.to_tensor(i)
  
              cur_foreground = paddle.gather(selected_foregrounds, i, 3)
              cur_alpha = paddle.gather(selected_alphas, i, 3)
              cur_decision = paddle.gather(selected_decisions, i, 3)
              cur_color = paddle.gather(selected_color, i, 3)
              cur_foreground = cur_foreground * cur_color
              selected_canvas_patch = (
                  cur_foreground * cur_alpha * cur_decision
                  + selected_canvas_patch
                  * (1 - cur_alpha * cur_decision)
              )
  
          selected_canvas_patch = selected_canvas_patch.reshape(
              [0, 0, 0, 3, render_size_y, render_size_x]
          )
          this_canvas = selected_canvas_patch.transpose(
              [0, 3, 1, 4, 2, 5]
          )
  
          # this_canvas: b, 3, h_half, py, w_half, px
          h_half = this_canvas.shape[2]
          w_half = this_canvas.shape[4]
          this_canvas = this_canvas.reshape(
              [b, 3, h_half * render_size_y, w_half * render_size_x]
          )
          # this_canvas: b, 3, h_half * py, w_half * px
          return this_canvas
  
      # even - even area
      # 1 | 0
      # 0 | 0
      canvas = partial_render(cur_canvas, even_idx_y, even_idx_x)
      if not is_odd_y:
          canvas = paddle.concat(
              [
                  canvas,
                  cur_canvas[
                      :, :, -render_size_y // 2 :, : canvas.shape[3]
                  ],
              ],
              axis=2,
          )
      if not is_odd_x:
          canvas = paddle.concat(
              [
                  canvas,
                  cur_canvas[
                      :, :, : canvas.shape[2], -render_size_x // 2 :
                  ],
              ],
              axis=3,
          )
      cur_canvas = canvas
  
      # odd - odd area
      # 0 | 0
      # 0 | 1
      if h > 1 and w > 1:
          canvas = partial_render(cur_canvas, odd_idx_y, odd_idx_x)
          canvas = paddle.concat(
              [
                  cur_canvas[
                      :, :, : render_size_y // 2, -canvas.shape[3] :
                  ],
                  canvas,
              ],
              axis=2,
          )
          canvas = paddle.concat(
              [
                  cur_canvas[
                      :, :, -canvas.shape[2] :, : render_size_x // 2
                  ],
                  canvas,
              ],
              axis=3,
          )
          if is_odd_y:
              canvas = paddle.concat(
                  [
                      canvas,
                      cur_canvas[
                          :, :, -render_size_y // 2 :, : canvas.shape[3]
                      ],
                  ],
                  axis=2,
              )
          if is_odd_x:
              canvas = paddle.concat(
                  [
                      canvas,
                      cur_canvas[
                          :, :, : canvas.shape[2], -render_size_x // 2 :
                      ],
                  ],
                  axis=3,
              )
          cur_canvas = canvas
  
      # odd - even area
      # 0 | 0
      # 1 | 0
      if h > 1:
          canvas = partial_render(cur_canvas, odd_idx_y, even_idx_x)
          canvas = paddle.concat(
              [
                  cur_canvas[
                      :, :, : render_size_y // 2, : canvas.shape[3]
                  ],
                  canvas,
              ],
              axis=2,
          )
          if is_odd_y:
              canvas = paddle.concat(
                  [
                      canvas,
                      cur_canvas[
                          :, :, -render_size_y // 2 :, : canvas.shape[3]
                      ],
                  ],
                  axis=2,
              )
          if not is_odd_x:
              canvas = paddle.concat(
                  [
                      canvas,
                      cur_canvas[
                          :, :, : canvas.shape[2], -render_size_x // 2 :
                      ],
                  ],
                  axis=3,
              )
          cur_canvas = canvas
  
      # odd - even area
      # 0 | 1
      # 0 | 0
      if w > 1:
          canvas = partial_render(cur_canvas, even_idx_y, odd_idx_x)
          canvas = paddle.concat(
              [
                  cur_canvas[
                      :, :, : canvas.shape[2], : render_size_x // 2
                  ],
                  canvas,
              ],
              axis=3,
          )
          if not is_odd_y:
              canvas = paddle.concat(
                  [
                      canvas,
                      cur_canvas[
                          :,
                          :,
                          -render_size_y // 2 :,
                          -canvas.shape[3] :,
                      ],
                  ],
                  axis=2,
              )
          if is_odd_x:
              canvas = paddle.concat(
                  [
                      canvas,
                      cur_canvas[
                          :, :, : canvas.shape[2], -render_size_x // 2 :
                      ],
                  ],
                  axis=3,
              )
          cur_canvas = canvas
  
      cur_canvas = cur_canvas[
          :,
          :,
          render_size_y // 4 : -render_size_y // 4,
          render_size_x // 4 : -render_size_x // 4,
      ]
  
      return cur_canvas
  
file_path: PaddleHub/modules/image/Image_gan/style_transfer/paint_transformer/render_parallel.py
imports: import render_utils
  import paddle
  import paddle.nn
  import paddle.nn.functional
  import numpy
  import math
label_desc: Use image node_id 3 for calling a global function with example usage: param2img_parallel(param, decision, meta_brushes, cur_canvas, stroke_num) and returns: cur_canvas, this_canvas