//============================================================================ // 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 Sandia Corporation. // Copyright 2014 UT-Battelle, LLC. // Copyright 2014 Los Alamos National Security. // // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // 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. //============================================================================ $# This file uses the pyexpander macro processing utility to build the $# FunctionInterface facilities that use a variable number of arguments. $# Information, documentation, and downloads for pyexpander can be found at: $# $# http://pyexpander.sourceforge.net/ $# $# To build the source code, execute the following (after installing $# pyexpander, of course): $# $# expander.py WorkletInvokeFunctorDetail.h.in > WorkletInvokeFunctorDetail.h $# $# Ignore the following comment. It is meant for the generated file. // **** 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_WorkletInvokeFunctor_h) && !defined(VTKM_TEST_HEADER_BUILD) #error WorkletInvokeFunctorDetail.h must be included from WorkletInvokeFunctor.h #endif #include #include #include $# This needs to match the max_parameters in FunctionInterfaceDetailPre.h.in $py(max_parameters=10)\ #if VTKM_MAX_FUNCTION_PARAMETERS != $(max_parameters) #error Mismatch of maximum parameters between FunctionInterfaceDatailPre.h.in and WorkletInvokeFunctorDetail.h.in #endif $# Python commands used in template expansion. $py( def comma_if(flag): if flag: return ',' else: return ''; def ptype(num, name=''): if num == 0: return '%sR' % name else: return '%sP%d' % (name, num) def pname(num, name=''): if num == 0: return '%sr' % name else: return '%sp%d' % (name, num) def template_params(num_params, start=0, name=''): if num_params < start: return '' result = 'typename %s' % ptype(start, name) for param in xrange(start+1, num_params+1): result += ',\n typename %s' % ptype(param, name) return result def signature(num_params, return_type=ptype(0), name=''): result = '%s(' % return_type if num_params > 0: result += ptype(1, name) for param in xrange(2, num_params+1): result += ',%s' % ptype(param, name) result += ')' return result def arg_list(num_params, name='', start=1): if num_params < start: return '' result = pname(start, name) for param in xrange(start+1, num_params+1): result += ',%s' % pname(param, name) return result )\ $# $extend(comma_if, ptype, pname, template_params, signature, arg_list)\ 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 struct InvocationToFetch { typedef typename Invocation::ExecutionInterface:: template ParameterType::type ExecutionSignatureTag; // 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; typedef typename ExecutionSignatureTag::AspectTag AspectTag; // Find the fetch tag from the control signature tag pointed to by // ParameterIndex. typedef typename Invocation::ControlInterface ControlInterface; typedef typename ControlInterface:: template ParameterType::type ControlSignatureTag; typedef typename ControlSignatureTag::FetchTag FetchTag; typedef typename Invocation::ParameterInterface:: template ParameterType::type ExecObjectType; typedef vtkm::exec::arg::Fetch< FetchTag,AspectTag,ThreadIndicesType,ExecObjectType> type; }; $for(num_params in range(1, max_parameters+1))\ template VTKM_EXEC_EXPORT void DoWorkletInvokeFunctor( const WorkletType &worklet, const vtkm::internal::Invocation< ParameterInterface, ControlInterface, vtkm::internal::FunctionInterface<$signature(num_params)>, InputDomainIndex, OutputToInputMapType, VisitArrayType> &invocation, const ThreadIndicesType &threadIndices) { typedef vtkm::internal::Invocation< ParameterInterface, ControlInterface, vtkm::internal::FunctionInterface<$signature(num_params)>, InputDomainIndex, OutputToInputMapType, VisitArrayType> Invocation; $for(param_index in range(1, num_params+1))\ typedef InvocationToFetch FetchInfo$(param_index); typedef typename FetchInfo$(param_index)::type FetchType$(param_index); FetchType$(param_index) fetch$(param_index); typename FetchType$(param_index)::ValueType $pname(param_index) = fetch$(param_index).Load( threadIndices, invocation.Parameters.template GetParameter()); $endfor\ typedef InvocationToFetch FetchInfo0; typedef typename FetchInfo0::type ReturnFetchType; typedef typename ReturnFetchType::ValueType ReturnValueType; 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. ReturnValueType $pname(0) = ReturnValueType(worklet($arg_list(num_params))); returnFetch.Store( threadIndices, invocation.Parameters.template GetParameter(), $pname(0)); $for(param_index in range(1, num_params+1))\ fetch$(param_index).Store( threadIndices, invocation.Parameters.template GetParameter(), $pname(param_index)); $endfor\ } template VTKM_EXEC_EXPORT void DoWorkletInvokeFunctor( const WorkletType &worklet, const vtkm::internal::Invocation< ParameterInterface, ControlInterface, vtkm::internal::FunctionInterface<$signature(num_params, return_type='void')>, InputDomainIndex, OutputToInputMapType, VisitArrayType> &invocation, const ThreadIndicesType &threadIndices) { typedef vtkm::internal::Invocation< ParameterInterface, ControlInterface, vtkm::internal::FunctionInterface<$signature(num_params, return_type='void')>, InputDomainIndex, OutputToInputMapType, VisitArrayType> Invocation; $for(param_index in range(1, num_params+1))\ typedef InvocationToFetch FetchInfo$(param_index); typedef typename FetchInfo$(param_index)::type FetchType$(param_index); FetchType$(param_index) fetch$(param_index); typename FetchType$(param_index)::ValueType $pname(param_index) = fetch$(param_index).Load( threadIndices, invocation.Parameters.template GetParameter()); $endfor\ // 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($arg_list(num_params)); $for(param_index in range(1, num_params+1))\ fetch$(param_index).Store( threadIndices, invocation.Parameters.template GetParameter(), $pname(param_index)); $endfor\ } $endfor\ } } } } // namespace vtkm::exec::internal::detail #endif //vtk_m_exec_internal_WorkletInvokeFunctorDetail_h