//============================================================================
//  Copyright (c) Kitware, Inc.
//  All rights reserved.
//  See LICENSE.txt for details.
//  This software is distributed WITHOUT ANY WARRANTY; without even
//  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
//  PURPOSE.  See the above copyright notice for more information.
//
//  Copyright 2014 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
//  Copyright 2014 UT-Battelle, LLC.
//  Copyright 2014 Los Alamos National Security.
//
//  Under the terms of Contract DE-NA0003525 with NTESS,
//  the U.S. Government retains certain rights in this software.
//
//  Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
//  Laboratory (LANL), the U.S. Government retains certain rights in
//  this software.
//============================================================================
// **** DO NOT EDIT THIS FILE!!! ****
// This file is automatically generated by WorkletInvokeFunctorDetail.h.in

// Technically speaking, we can implement this functionality with some clever
// use of FunctionInterface rather than using pyexpander to make variadic
// code. However, this code is probably more friendly to compilers. I expect
// it to compiler faster and optimize better.

#ifndef vtk_m_exec_internal_WorkletInvokeFunctorDetail_h
#define vtk_m_exec_internal_WorkletInvokeFunctorDetail_h

#if !defined(vtk_m_exec_internal_TaskSingular_h) && !defined(vtk_m_exec_internal_TaskTiling_h) &&  \
  !defined(VTKM_TEST_HEADER_BUILD)
#error WorkletInvokeFunctorDetail.h must be included from TaskSingular.h or TaskTiling.h
#endif

#include <vtkm/internal/FunctionInterface.h>
#include <vtkm/internal/Invocation.h>

#include <vtkm/exec/arg/Fetch.h>

#if VTKM_MAX_FUNCTION_PARAMETERS != 10
#error Mismatch of maximum parameters between FunctionInterfaceDatailPre.h.in and WorkletInvokeFunctorDetail.h.in
#endif


namespace vtkm
{
namespace exec
{
namespace internal
{
namespace detail
{

/// A helper class that takes an \c Invocation object and an index to a
/// parameter in the ExecutionSignature and finds the \c Fetch type valid for
/// that parameter.
template <typename ThreadIndicesType,
          typename Invocation,
          vtkm::IdComponent ExecutionParameterIndex>
struct InvocationToFetch
{
  using ExecutionSignatureTag =
    typename Invocation::ExecutionInterface::template ParameterType<ExecutionParameterIndex>::type;

  // Expected fields from ExecutionSignatureTag. If these do not exist in
  // ExecutionSignatureTag, then something that is not really an execution
  // signature tag was used in an ExecutionSignature.
  static const vtkm::IdComponent ControlParameterIndex = ExecutionSignatureTag::INDEX;
  using AspectTag = typename ExecutionSignatureTag::AspectTag;

  // Find the fetch tag from the control signature tag pointed to by
  // ParameterIndex.
  using ControlInterface = typename Invocation::ControlInterface;
  using ControlSignatureTag = typename ControlInterface::template ParameterType<ControlParameterIndex>::type;
  using FetchTag = typename ControlSignatureTag::FetchTag;

  using ExecObjectType =
    typename Invocation::ParameterInterface::template ParameterType<ControlParameterIndex>::type;

  using type = vtkm::exec::arg::Fetch<FetchTag, AspectTag, ThreadIndicesType, ExecObjectType>;
};

// clang-format off

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename R,
          typename P1>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<R(P1)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  using Invocation =  vtkm::internal::Invocation<ParameterInterface,
                                                 ControlInterface,
                                                 vtkm::internal::FunctionInterface<R(P1)>,
                                                 InputDomainIndex,
                                                 OutputToInputMapType,
                                                 VisitArrayType>;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo0 = InvocationToFetch<ThreadIndicesType, Invocation, 0>;
  using ReturnFetchType = typename FetchInfo0::type;
  ReturnFetchType returnFetch;
  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  auto r = typename ReturnFetchType::ValueType(worklet(p1));

  returnFetch.Store(
    threadIndices,
    invocation.Parameters.template GetParameter<FetchInfo0::ControlParameterIndex>(),
    r);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename P1>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<void(P1)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  typedef vtkm::internal::Invocation<ParameterInterface,
                                     ControlInterface,
                                     vtkm::internal::FunctionInterface<void(P1)>,
                                     InputDomainIndex,
                                     OutputToInputMapType,
                                     VisitArrayType>
    Invocation;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  worklet(p1);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename R,
          typename P1,
          typename P2>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<R(P1, P2)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  using Invocation =  vtkm::internal::Invocation<ParameterInterface,
                                                 ControlInterface,
                                                 vtkm::internal::FunctionInterface<R(P1, P2)>,
                                                 InputDomainIndex,
                                                 OutputToInputMapType,
                                                 VisitArrayType>;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo0 = InvocationToFetch<ThreadIndicesType, Invocation, 0>;
  using ReturnFetchType = typename FetchInfo0::type;
  ReturnFetchType returnFetch;
  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  auto r = typename ReturnFetchType::ValueType(worklet(p1, p2));

  returnFetch.Store(
    threadIndices,
    invocation.Parameters.template GetParameter<FetchInfo0::ControlParameterIndex>(),
    r);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename P1,
          typename P2>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<void(P1, P2)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  typedef vtkm::internal::Invocation<ParameterInterface,
                                     ControlInterface,
                                     vtkm::internal::FunctionInterface<void(P1, P2)>,
                                     InputDomainIndex,
                                     OutputToInputMapType,
                                     VisitArrayType>
    Invocation;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  worklet(p1, p2);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename R,
          typename P1,
          typename P2,
          typename P3>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<R(P1, P2, P3)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  using Invocation =  vtkm::internal::Invocation<ParameterInterface,
                                                 ControlInterface,
                                                 vtkm::internal::FunctionInterface<R(P1, P2, P3)>,
                                                 InputDomainIndex,
                                                 OutputToInputMapType,
                                                 VisitArrayType>;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  using FetchInfo0 = InvocationToFetch<ThreadIndicesType, Invocation, 0>;
  using ReturnFetchType = typename FetchInfo0::type;
  ReturnFetchType returnFetch;
  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  auto r = typename ReturnFetchType::ValueType(worklet(p1, p2, p3));

  returnFetch.Store(
    threadIndices,
    invocation.Parameters.template GetParameter<FetchInfo0::ControlParameterIndex>(),
    r);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename P1,
          typename P2,
          typename P3>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<void(P1, P2, P3)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  typedef vtkm::internal::Invocation<ParameterInterface,
                                     ControlInterface,
                                     vtkm::internal::FunctionInterface<void(P1, P2, P3)>,
                                     InputDomainIndex,
                                     OutputToInputMapType,
                                     VisitArrayType>
    Invocation;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  worklet(p1, p2, p3);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename R,
          typename P1,
          typename P2,
          typename P3,
          typename P4>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<R(P1, P2, P3, P4)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  using Invocation =  vtkm::internal::Invocation<ParameterInterface,
                                                 ControlInterface,
                                                 vtkm::internal::FunctionInterface<R(P1, P2, P3, P4)>,
                                                 InputDomainIndex,
                                                 OutputToInputMapType,
                                                 VisitArrayType>;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  using FetchInfo4 = InvocationToFetch<ThreadIndicesType, Invocation, 4>;
  using FetchType4 = typename FetchInfo4::type;
  FetchType4 fetch4;
  typename FetchType4::ValueType p4 =
    fetch4.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>());

  using FetchInfo0 = InvocationToFetch<ThreadIndicesType, Invocation, 0>;
  using ReturnFetchType = typename FetchInfo0::type;
  ReturnFetchType returnFetch;
  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  auto r = typename ReturnFetchType::ValueType(worklet(p1, p2, p3, p4));

  returnFetch.Store(
    threadIndices,
    invocation.Parameters.template GetParameter<FetchInfo0::ControlParameterIndex>(),
    r);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
  fetch4.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>(),
               p4);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename P1,
          typename P2,
          typename P3,
          typename P4>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<void(P1, P2, P3, P4)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  typedef vtkm::internal::Invocation<ParameterInterface,
                                     ControlInterface,
                                     vtkm::internal::FunctionInterface<void(P1, P2, P3, P4)>,
                                     InputDomainIndex,
                                     OutputToInputMapType,
                                     VisitArrayType>
    Invocation;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  using FetchInfo4 = InvocationToFetch<ThreadIndicesType, Invocation, 4>;
  using FetchType4 = typename FetchInfo4::type;
  FetchType4 fetch4;
  typename FetchType4::ValueType p4 =
    fetch4.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>());

  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  worklet(p1, p2, p3, p4);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
  fetch4.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>(),
               p4);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename R,
          typename P1,
          typename P2,
          typename P3,
          typename P4,
          typename P5>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  using Invocation =  vtkm::internal::Invocation<ParameterInterface,
                                                 ControlInterface,
                                                 vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5)>,
                                                 InputDomainIndex,
                                                 OutputToInputMapType,
                                                 VisitArrayType>;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  using FetchInfo4 = InvocationToFetch<ThreadIndicesType, Invocation, 4>;
  using FetchType4 = typename FetchInfo4::type;
  FetchType4 fetch4;
  typename FetchType4::ValueType p4 =
    fetch4.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>());

  using FetchInfo5 = InvocationToFetch<ThreadIndicesType, Invocation, 5>;
  using FetchType5 = typename FetchInfo5::type;
  FetchType5 fetch5;
  typename FetchType5::ValueType p5 =
    fetch5.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>());

  using FetchInfo0 = InvocationToFetch<ThreadIndicesType, Invocation, 0>;
  using ReturnFetchType = typename FetchInfo0::type;
  ReturnFetchType returnFetch;
  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  auto r = typename ReturnFetchType::ValueType(worklet(p1, p2, p3, p4, p5));

  returnFetch.Store(
    threadIndices,
    invocation.Parameters.template GetParameter<FetchInfo0::ControlParameterIndex>(),
    r);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
  fetch4.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>(),
               p4);
  fetch5.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>(),
               p5);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename P1,
          typename P2,
          typename P3,
          typename P4,
          typename P5>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  typedef vtkm::internal::Invocation<ParameterInterface,
                                     ControlInterface,
                                     vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5)>,
                                     InputDomainIndex,
                                     OutputToInputMapType,
                                     VisitArrayType>
    Invocation;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  using FetchInfo4 = InvocationToFetch<ThreadIndicesType, Invocation, 4>;
  using FetchType4 = typename FetchInfo4::type;
  FetchType4 fetch4;
  typename FetchType4::ValueType p4 =
    fetch4.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>());

  using FetchInfo5 = InvocationToFetch<ThreadIndicesType, Invocation, 5>;
  using FetchType5 = typename FetchInfo5::type;
  FetchType5 fetch5;
  typename FetchType5::ValueType p5 =
    fetch5.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>());

  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  worklet(p1, p2, p3, p4, p5);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
  fetch4.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>(),
               p4);
  fetch5.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>(),
               p5);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename R,
          typename P1,
          typename P2,
          typename P3,
          typename P4,
          typename P5,
          typename P6>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  using Invocation =  vtkm::internal::Invocation<ParameterInterface,
                                                 ControlInterface,
                                                 vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6)>,
                                                 InputDomainIndex,
                                                 OutputToInputMapType,
                                                 VisitArrayType>;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  using FetchInfo4 = InvocationToFetch<ThreadIndicesType, Invocation, 4>;
  using FetchType4 = typename FetchInfo4::type;
  FetchType4 fetch4;
  typename FetchType4::ValueType p4 =
    fetch4.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>());

  using FetchInfo5 = InvocationToFetch<ThreadIndicesType, Invocation, 5>;
  using FetchType5 = typename FetchInfo5::type;
  FetchType5 fetch5;
  typename FetchType5::ValueType p5 =
    fetch5.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>());

  using FetchInfo6 = InvocationToFetch<ThreadIndicesType, Invocation, 6>;
  using FetchType6 = typename FetchInfo6::type;
  FetchType6 fetch6;
  typename FetchType6::ValueType p6 =
    fetch6.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>());

  using FetchInfo0 = InvocationToFetch<ThreadIndicesType, Invocation, 0>;
  using ReturnFetchType = typename FetchInfo0::type;
  ReturnFetchType returnFetch;
  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  auto r = typename ReturnFetchType::ValueType(worklet(p1, p2, p3, p4, p5, p6));

  returnFetch.Store(
    threadIndices,
    invocation.Parameters.template GetParameter<FetchInfo0::ControlParameterIndex>(),
    r);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
  fetch4.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>(),
               p4);
  fetch5.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>(),
               p5);
  fetch6.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>(),
               p6);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename P1,
          typename P2,
          typename P3,
          typename P4,
          typename P5,
          typename P6>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  typedef vtkm::internal::Invocation<ParameterInterface,
                                     ControlInterface,
                                     vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6)>,
                                     InputDomainIndex,
                                     OutputToInputMapType,
                                     VisitArrayType>
    Invocation;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  using FetchInfo4 = InvocationToFetch<ThreadIndicesType, Invocation, 4>;
  using FetchType4 = typename FetchInfo4::type;
  FetchType4 fetch4;
  typename FetchType4::ValueType p4 =
    fetch4.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>());

  using FetchInfo5 = InvocationToFetch<ThreadIndicesType, Invocation, 5>;
  using FetchType5 = typename FetchInfo5::type;
  FetchType5 fetch5;
  typename FetchType5::ValueType p5 =
    fetch5.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>());

  using FetchInfo6 = InvocationToFetch<ThreadIndicesType, Invocation, 6>;
  using FetchType6 = typename FetchInfo6::type;
  FetchType6 fetch6;
  typename FetchType6::ValueType p6 =
    fetch6.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>());

  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  worklet(p1, p2, p3, p4, p5, p6);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
  fetch4.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>(),
               p4);
  fetch5.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>(),
               p5);
  fetch6.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>(),
               p6);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename R,
          typename P1,
          typename P2,
          typename P3,
          typename P4,
          typename P5,
          typename P6,
          typename P7>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  using Invocation =  vtkm::internal::Invocation<ParameterInterface,
                                                 ControlInterface,
                                                 vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7)>,
                                                 InputDomainIndex,
                                                 OutputToInputMapType,
                                                 VisitArrayType>;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  using FetchInfo4 = InvocationToFetch<ThreadIndicesType, Invocation, 4>;
  using FetchType4 = typename FetchInfo4::type;
  FetchType4 fetch4;
  typename FetchType4::ValueType p4 =
    fetch4.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>());

  using FetchInfo5 = InvocationToFetch<ThreadIndicesType, Invocation, 5>;
  using FetchType5 = typename FetchInfo5::type;
  FetchType5 fetch5;
  typename FetchType5::ValueType p5 =
    fetch5.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>());

  using FetchInfo6 = InvocationToFetch<ThreadIndicesType, Invocation, 6>;
  using FetchType6 = typename FetchInfo6::type;
  FetchType6 fetch6;
  typename FetchType6::ValueType p6 =
    fetch6.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>());

  using FetchInfo7 = InvocationToFetch<ThreadIndicesType, Invocation, 7>;
  using FetchType7 = typename FetchInfo7::type;
  FetchType7 fetch7;
  typename FetchType7::ValueType p7 =
    fetch7.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>());

  using FetchInfo0 = InvocationToFetch<ThreadIndicesType, Invocation, 0>;
  using ReturnFetchType = typename FetchInfo0::type;
  ReturnFetchType returnFetch;
  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  auto r = typename ReturnFetchType::ValueType(worklet(p1, p2, p3, p4, p5, p6, p7));

  returnFetch.Store(
    threadIndices,
    invocation.Parameters.template GetParameter<FetchInfo0::ControlParameterIndex>(),
    r);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
  fetch4.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>(),
               p4);
  fetch5.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>(),
               p5);
  fetch6.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>(),
               p6);
  fetch7.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>(),
               p7);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename P1,
          typename P2,
          typename P3,
          typename P4,
          typename P5,
          typename P6,
          typename P7>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  typedef vtkm::internal::Invocation<ParameterInterface,
                                     ControlInterface,
                                     vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7)>,
                                     InputDomainIndex,
                                     OutputToInputMapType,
                                     VisitArrayType>
    Invocation;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  using FetchInfo4 = InvocationToFetch<ThreadIndicesType, Invocation, 4>;
  using FetchType4 = typename FetchInfo4::type;
  FetchType4 fetch4;
  typename FetchType4::ValueType p4 =
    fetch4.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>());

  using FetchInfo5 = InvocationToFetch<ThreadIndicesType, Invocation, 5>;
  using FetchType5 = typename FetchInfo5::type;
  FetchType5 fetch5;
  typename FetchType5::ValueType p5 =
    fetch5.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>());

  using FetchInfo6 = InvocationToFetch<ThreadIndicesType, Invocation, 6>;
  using FetchType6 = typename FetchInfo6::type;
  FetchType6 fetch6;
  typename FetchType6::ValueType p6 =
    fetch6.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>());

  using FetchInfo7 = InvocationToFetch<ThreadIndicesType, Invocation, 7>;
  using FetchType7 = typename FetchInfo7::type;
  FetchType7 fetch7;
  typename FetchType7::ValueType p7 =
    fetch7.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>());

  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  worklet(p1, p2, p3, p4, p5, p6, p7);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
  fetch4.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>(),
               p4);
  fetch5.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>(),
               p5);
  fetch6.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>(),
               p6);
  fetch7.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>(),
               p7);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename R,
          typename P1,
          typename P2,
          typename P3,
          typename P4,
          typename P5,
          typename P6,
          typename P7,
          typename P8>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  using Invocation =  vtkm::internal::Invocation<ParameterInterface,
                                                 ControlInterface,
                                                 vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8)>,
                                                 InputDomainIndex,
                                                 OutputToInputMapType,
                                                 VisitArrayType>;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  using FetchInfo4 = InvocationToFetch<ThreadIndicesType, Invocation, 4>;
  using FetchType4 = typename FetchInfo4::type;
  FetchType4 fetch4;
  typename FetchType4::ValueType p4 =
    fetch4.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>());

  using FetchInfo5 = InvocationToFetch<ThreadIndicesType, Invocation, 5>;
  using FetchType5 = typename FetchInfo5::type;
  FetchType5 fetch5;
  typename FetchType5::ValueType p5 =
    fetch5.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>());

  using FetchInfo6 = InvocationToFetch<ThreadIndicesType, Invocation, 6>;
  using FetchType6 = typename FetchInfo6::type;
  FetchType6 fetch6;
  typename FetchType6::ValueType p6 =
    fetch6.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>());

  using FetchInfo7 = InvocationToFetch<ThreadIndicesType, Invocation, 7>;
  using FetchType7 = typename FetchInfo7::type;
  FetchType7 fetch7;
  typename FetchType7::ValueType p7 =
    fetch7.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>());

  using FetchInfo8 = InvocationToFetch<ThreadIndicesType, Invocation, 8>;
  using FetchType8 = typename FetchInfo8::type;
  FetchType8 fetch8;
  typename FetchType8::ValueType p8 =
    fetch8.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo8::ControlParameterIndex>());

  using FetchInfo0 = InvocationToFetch<ThreadIndicesType, Invocation, 0>;
  using ReturnFetchType = typename FetchInfo0::type;
  ReturnFetchType returnFetch;
  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  auto r = typename ReturnFetchType::ValueType(worklet(p1, p2, p3, p4, p5, p6, p7, p8));

  returnFetch.Store(
    threadIndices,
    invocation.Parameters.template GetParameter<FetchInfo0::ControlParameterIndex>(),
    r);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
  fetch4.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>(),
               p4);
  fetch5.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>(),
               p5);
  fetch6.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>(),
               p6);
  fetch7.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>(),
               p7);
  fetch8.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo8::ControlParameterIndex>(),
               p8);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename P1,
          typename P2,
          typename P3,
          typename P4,
          typename P5,
          typename P6,
          typename P7,
          typename P8>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  typedef vtkm::internal::Invocation<ParameterInterface,
                                     ControlInterface,
                                     vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8)>,
                                     InputDomainIndex,
                                     OutputToInputMapType,
                                     VisitArrayType>
    Invocation;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  using FetchInfo4 = InvocationToFetch<ThreadIndicesType, Invocation, 4>;
  using FetchType4 = typename FetchInfo4::type;
  FetchType4 fetch4;
  typename FetchType4::ValueType p4 =
    fetch4.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>());

  using FetchInfo5 = InvocationToFetch<ThreadIndicesType, Invocation, 5>;
  using FetchType5 = typename FetchInfo5::type;
  FetchType5 fetch5;
  typename FetchType5::ValueType p5 =
    fetch5.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>());

  using FetchInfo6 = InvocationToFetch<ThreadIndicesType, Invocation, 6>;
  using FetchType6 = typename FetchInfo6::type;
  FetchType6 fetch6;
  typename FetchType6::ValueType p6 =
    fetch6.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>());

  using FetchInfo7 = InvocationToFetch<ThreadIndicesType, Invocation, 7>;
  using FetchType7 = typename FetchInfo7::type;
  FetchType7 fetch7;
  typename FetchType7::ValueType p7 =
    fetch7.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>());

  using FetchInfo8 = InvocationToFetch<ThreadIndicesType, Invocation, 8>;
  using FetchType8 = typename FetchInfo8::type;
  FetchType8 fetch8;
  typename FetchType8::ValueType p8 =
    fetch8.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo8::ControlParameterIndex>());

  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  worklet(p1, p2, p3, p4, p5, p6, p7, p8);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
  fetch4.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>(),
               p4);
  fetch5.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>(),
               p5);
  fetch6.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>(),
               p6);
  fetch7.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>(),
               p7);
  fetch8.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo8::ControlParameterIndex>(),
               p8);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename R,
          typename P1,
          typename P2,
          typename P3,
          typename P4,
          typename P5,
          typename P6,
          typename P7,
          typename P8,
          typename P9>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  using Invocation =  vtkm::internal::Invocation<ParameterInterface,
                                                 ControlInterface,
                                                 vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9)>,
                                                 InputDomainIndex,
                                                 OutputToInputMapType,
                                                 VisitArrayType>;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  using FetchInfo4 = InvocationToFetch<ThreadIndicesType, Invocation, 4>;
  using FetchType4 = typename FetchInfo4::type;
  FetchType4 fetch4;
  typename FetchType4::ValueType p4 =
    fetch4.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>());

  using FetchInfo5 = InvocationToFetch<ThreadIndicesType, Invocation, 5>;
  using FetchType5 = typename FetchInfo5::type;
  FetchType5 fetch5;
  typename FetchType5::ValueType p5 =
    fetch5.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>());

  using FetchInfo6 = InvocationToFetch<ThreadIndicesType, Invocation, 6>;
  using FetchType6 = typename FetchInfo6::type;
  FetchType6 fetch6;
  typename FetchType6::ValueType p6 =
    fetch6.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>());

  using FetchInfo7 = InvocationToFetch<ThreadIndicesType, Invocation, 7>;
  using FetchType7 = typename FetchInfo7::type;
  FetchType7 fetch7;
  typename FetchType7::ValueType p7 =
    fetch7.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>());

  using FetchInfo8 = InvocationToFetch<ThreadIndicesType, Invocation, 8>;
  using FetchType8 = typename FetchInfo8::type;
  FetchType8 fetch8;
  typename FetchType8::ValueType p8 =
    fetch8.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo8::ControlParameterIndex>());

  using FetchInfo9 = InvocationToFetch<ThreadIndicesType, Invocation, 9>;
  using FetchType9 = typename FetchInfo9::type;
  FetchType9 fetch9;
  typename FetchType9::ValueType p9 =
    fetch9.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo9::ControlParameterIndex>());

  using FetchInfo0 = InvocationToFetch<ThreadIndicesType, Invocation, 0>;
  using ReturnFetchType = typename FetchInfo0::type;
  ReturnFetchType returnFetch;
  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  auto r = typename ReturnFetchType::ValueType(worklet(p1, p2, p3, p4, p5, p6, p7, p8, p9));

  returnFetch.Store(
    threadIndices,
    invocation.Parameters.template GetParameter<FetchInfo0::ControlParameterIndex>(),
    r);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
  fetch4.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>(),
               p4);
  fetch5.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>(),
               p5);
  fetch6.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>(),
               p6);
  fetch7.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>(),
               p7);
  fetch8.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo8::ControlParameterIndex>(),
               p8);
  fetch9.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo9::ControlParameterIndex>(),
               p9);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename P1,
          typename P2,
          typename P3,
          typename P4,
          typename P5,
          typename P6,
          typename P7,
          typename P8,
          typename P9>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  typedef vtkm::internal::Invocation<ParameterInterface,
                                     ControlInterface,
                                     vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9)>,
                                     InputDomainIndex,
                                     OutputToInputMapType,
                                     VisitArrayType>
    Invocation;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  using FetchInfo4 = InvocationToFetch<ThreadIndicesType, Invocation, 4>;
  using FetchType4 = typename FetchInfo4::type;
  FetchType4 fetch4;
  typename FetchType4::ValueType p4 =
    fetch4.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>());

  using FetchInfo5 = InvocationToFetch<ThreadIndicesType, Invocation, 5>;
  using FetchType5 = typename FetchInfo5::type;
  FetchType5 fetch5;
  typename FetchType5::ValueType p5 =
    fetch5.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>());

  using FetchInfo6 = InvocationToFetch<ThreadIndicesType, Invocation, 6>;
  using FetchType6 = typename FetchInfo6::type;
  FetchType6 fetch6;
  typename FetchType6::ValueType p6 =
    fetch6.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>());

  using FetchInfo7 = InvocationToFetch<ThreadIndicesType, Invocation, 7>;
  using FetchType7 = typename FetchInfo7::type;
  FetchType7 fetch7;
  typename FetchType7::ValueType p7 =
    fetch7.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>());

  using FetchInfo8 = InvocationToFetch<ThreadIndicesType, Invocation, 8>;
  using FetchType8 = typename FetchInfo8::type;
  FetchType8 fetch8;
  typename FetchType8::ValueType p8 =
    fetch8.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo8::ControlParameterIndex>());

  using FetchInfo9 = InvocationToFetch<ThreadIndicesType, Invocation, 9>;
  using FetchType9 = typename FetchInfo9::type;
  FetchType9 fetch9;
  typename FetchType9::ValueType p9 =
    fetch9.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo9::ControlParameterIndex>());

  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  worklet(p1, p2, p3, p4, p5, p6, p7, p8, p9);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
  fetch4.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>(),
               p4);
  fetch5.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>(),
               p5);
  fetch6.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>(),
               p6);
  fetch7.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>(),
               p7);
  fetch8.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo8::ControlParameterIndex>(),
               p8);
  fetch9.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo9::ControlParameterIndex>(),
               p9);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename R,
          typename P1,
          typename P2,
          typename P3,
          typename P4,
          typename P5,
          typename P6,
          typename P7,
          typename P8,
          typename P9,
          typename P10>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  using Invocation =  vtkm::internal::Invocation<ParameterInterface,
                                                 ControlInterface,
                                                 vtkm::internal::FunctionInterface<R(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)>,
                                                 InputDomainIndex,
                                                 OutputToInputMapType,
                                                 VisitArrayType>;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  using FetchInfo4 = InvocationToFetch<ThreadIndicesType, Invocation, 4>;
  using FetchType4 = typename FetchInfo4::type;
  FetchType4 fetch4;
  typename FetchType4::ValueType p4 =
    fetch4.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>());

  using FetchInfo5 = InvocationToFetch<ThreadIndicesType, Invocation, 5>;
  using FetchType5 = typename FetchInfo5::type;
  FetchType5 fetch5;
  typename FetchType5::ValueType p5 =
    fetch5.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>());

  using FetchInfo6 = InvocationToFetch<ThreadIndicesType, Invocation, 6>;
  using FetchType6 = typename FetchInfo6::type;
  FetchType6 fetch6;
  typename FetchType6::ValueType p6 =
    fetch6.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>());

  using FetchInfo7 = InvocationToFetch<ThreadIndicesType, Invocation, 7>;
  using FetchType7 = typename FetchInfo7::type;
  FetchType7 fetch7;
  typename FetchType7::ValueType p7 =
    fetch7.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>());

  using FetchInfo8 = InvocationToFetch<ThreadIndicesType, Invocation, 8>;
  using FetchType8 = typename FetchInfo8::type;
  FetchType8 fetch8;
  typename FetchType8::ValueType p8 =
    fetch8.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo8::ControlParameterIndex>());

  using FetchInfo9 = InvocationToFetch<ThreadIndicesType, Invocation, 9>;
  using FetchType9 = typename FetchInfo9::type;
  FetchType9 fetch9;
  typename FetchType9::ValueType p9 =
    fetch9.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo9::ControlParameterIndex>());

  using FetchInfo10 = InvocationToFetch<ThreadIndicesType, Invocation, 10>;
  using FetchType10 = typename FetchInfo10::type;
  FetchType10 fetch10;
  typename FetchType10::ValueType p10 =
    fetch10.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo10::ControlParameterIndex>());

  using FetchInfo0 = InvocationToFetch<ThreadIndicesType, Invocation, 0>;
  using ReturnFetchType = typename FetchInfo0::type;
  ReturnFetchType returnFetch;
  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  auto r = typename ReturnFetchType::ValueType(worklet(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10));

  returnFetch.Store(
    threadIndices,
    invocation.Parameters.template GetParameter<FetchInfo0::ControlParameterIndex>(),
    r);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
  fetch4.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>(),
               p4);
  fetch5.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>(),
               p5);
  fetch6.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>(),
               p6);
  fetch7.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>(),
               p7);
  fetch8.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo8::ControlParameterIndex>(),
               p8);
  fetch9.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo9::ControlParameterIndex>(),
               p9);
  fetch10.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo10::ControlParameterIndex>(),
               p10);
}

template <typename WorkletType,
          typename ParameterInterface,
          typename ControlInterface,
          vtkm::IdComponent InputDomainIndex,
          typename OutputToInputMapType,
          typename VisitArrayType,
          typename ThreadIndicesType,
          typename P1,
          typename P2,
          typename P3,
          typename P4,
          typename P5,
          typename P6,
          typename P7,
          typename P8,
          typename P9,
          typename P10>
VTKM_EXEC void DoWorkletInvokeFunctor(
  const WorkletType& worklet,
  const vtkm::internal::Invocation<ParameterInterface,
                                   ControlInterface,
                                   vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)>,
                                   InputDomainIndex,
                                   OutputToInputMapType,
                                   VisitArrayType>& invocation,
  const ThreadIndicesType& threadIndices)
{
  typedef vtkm::internal::Invocation<ParameterInterface,
                                     ControlInterface,
                                     vtkm::internal::FunctionInterface<void(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)>,
                                     InputDomainIndex,
                                     OutputToInputMapType,
                                     VisitArrayType>
    Invocation;

  using FetchInfo1 = InvocationToFetch<ThreadIndicesType, Invocation, 1>;
  using FetchType1 = typename FetchInfo1::type;
  FetchType1 fetch1;
  typename FetchType1::ValueType p1 =
    fetch1.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>());

  using FetchInfo2 = InvocationToFetch<ThreadIndicesType, Invocation, 2>;
  using FetchType2 = typename FetchInfo2::type;
  FetchType2 fetch2;
  typename FetchType2::ValueType p2 =
    fetch2.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>());

  using FetchInfo3 = InvocationToFetch<ThreadIndicesType, Invocation, 3>;
  using FetchType3 = typename FetchInfo3::type;
  FetchType3 fetch3;
  typename FetchType3::ValueType p3 =
    fetch3.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>());

  using FetchInfo4 = InvocationToFetch<ThreadIndicesType, Invocation, 4>;
  using FetchType4 = typename FetchInfo4::type;
  FetchType4 fetch4;
  typename FetchType4::ValueType p4 =
    fetch4.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>());

  using FetchInfo5 = InvocationToFetch<ThreadIndicesType, Invocation, 5>;
  using FetchType5 = typename FetchInfo5::type;
  FetchType5 fetch5;
  typename FetchType5::ValueType p5 =
    fetch5.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>());

  using FetchInfo6 = InvocationToFetch<ThreadIndicesType, Invocation, 6>;
  using FetchType6 = typename FetchInfo6::type;
  FetchType6 fetch6;
  typename FetchType6::ValueType p6 =
    fetch6.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>());

  using FetchInfo7 = InvocationToFetch<ThreadIndicesType, Invocation, 7>;
  using FetchType7 = typename FetchInfo7::type;
  FetchType7 fetch7;
  typename FetchType7::ValueType p7 =
    fetch7.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>());

  using FetchInfo8 = InvocationToFetch<ThreadIndicesType, Invocation, 8>;
  using FetchType8 = typename FetchInfo8::type;
  FetchType8 fetch8;
  typename FetchType8::ValueType p8 =
    fetch8.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo8::ControlParameterIndex>());

  using FetchInfo9 = InvocationToFetch<ThreadIndicesType, Invocation, 9>;
  using FetchType9 = typename FetchInfo9::type;
  FetchType9 fetch9;
  typename FetchType9::ValueType p9 =
    fetch9.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo9::ControlParameterIndex>());

  using FetchInfo10 = InvocationToFetch<ThreadIndicesType, Invocation, 10>;
  using FetchType10 = typename FetchInfo10::type;
  FetchType10 fetch10;
  typename FetchType10::ValueType p10 =
    fetch10.Load(threadIndices,
                invocation.Parameters.template GetParameter<FetchInfo10::ControlParameterIndex>());

  // If you got a compile error on the following line, it probably means that
  // the operator() of a worklet does not match the definition expected. One
  // common problem is that the operator() method must be declared const. Check
  // to make sure the "const" keyword is after parameters. Another common
  // problem is that the type of one or more parameters is incompatible with
  // the actual type that VTK-m creates in the execution environment. Make sure
  // that the types of the worklet operator() parameters match those in the
  // ExecutionSignature. The compiler error might help you narrow down which
  // parameter is wrong and the types that did not match.
  worklet(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10);

  fetch1.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo1::ControlParameterIndex>(),
               p1);
  fetch2.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo2::ControlParameterIndex>(),
               p2);
  fetch3.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo3::ControlParameterIndex>(),
               p3);
  fetch4.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo4::ControlParameterIndex>(),
               p4);
  fetch5.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo5::ControlParameterIndex>(),
               p5);
  fetch6.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo6::ControlParameterIndex>(),
               p6);
  fetch7.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo7::ControlParameterIndex>(),
               p7);
  fetch8.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo8::ControlParameterIndex>(),
               p8);
  fetch9.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo9::ControlParameterIndex>(),
               p9);
  fetch10.Store(threadIndices,
               invocation.Parameters.template GetParameter<FetchInfo10::ControlParameterIndex>(),
               p10);
}

// clang-format on
}
}
}
} // namespace vtkm::exec::internal::detail

#endif //vtk_m_exec_internal_WorkletInvokeFunctorDetail_h
