code: def make_unary_op(op):
      """
      Make closures that implement unary operations. See register_unary_op for
      details.
      """
  
      def masked_scalar_unary_op_impl(context, builder, sig, args):
          """
          Implement <op> `MaskedType`
          """
          # MaskedType(...)
          masked_type_1 = sig.args[0]
          # MaskedType(...)
          masked_return_type = sig.return_type
  
          m1 = cgutils.create_struct_proxy(masked_type_1)(
              context, builder, value=args[0]
          )
  
          # we will return an output struct
          result = cgutils.create_struct_proxy(masked_return_type)(
              context, builder
          )
  
          # compute output validity
          result.valid = m1.valid
          with builder.if_then(m1.valid):
              # Let numba handle generating the extra IR needed to perform
              # operations on mixed types, by compiling the final core op between
              # the two primitive values as a separate function and calling it
              result.value = context.compile_internal(
                  builder,
                  lambda x: op(x),
                  nb_signature(
                      masked_return_type.value_type,
                      masked_type_1.value_type,
                  ),
                  (m1.value,),
              )
          return result._getvalue()
  
      return masked_scalar_unary_op_impl
  
imports: import operator
  from llvmlite import ir
  from numba.core import cgutils
  from numba.core.typing import signature
  from numba.cuda.cudaimpl import lower, registry
  from numba.extending import lower_builtin, types
  from cudf.core.udf import api
  from cudf.core.udf._ops import arith_ops, bitwise_ops, comparison_ops, unary_ops
  from cudf.core.udf.masked_typing import MaskedType, NAType, _supported_masked_types
label_desc: Use image node_id 3 for calling a global function with example usage: make_unary_op(op) and returns: masked_scalar_unary_op_impl, result