Merge branch 'new-list-features' into distpach

This commit is contained in:
Kenneth Moreland 2014-10-22 15:21:48 -06:00
commit f4fb9f0ace
16 changed files with 573 additions and 1169 deletions

@ -54,20 +54,16 @@ if(${pyexpander_result})
return()
endif()
file(WRITE ${GENERATED_FILE} "${pyexpander_output}")
file(WRITE ${GENERATED_FILE}.save "${pyexpander_output}")
execute_process(
COMMAND ${CMAKE_COMMAND} -E compare_files ${SOURCE_FILE} ${GENERATED_FILE}
COMMAND ${CMAKE_COMMAND} -E compare_files ${SOURCE_FILE} ${GENERATED_FILE}.save
RESULT_VARIABLE diff_result
)
if(${diff_result})
# If diff returned non-zero, it failed and the two files are different.
get_filename_component(filename ${SOURCE_FILE} NAME)
# Move the generated file so that the build does not confuse it with the
# files in the source directory.
file(REMOVE ${GENERATED_FILE}.save)
file(RENAME ${GENERATED_FILE} ${GENERATED_FILE}.save)
message(SEND_ERROR
"The source file ${filename} does not match the generated file. If you have modified this file directly, then you have messed up. Modify the ${filename}.in file instead and then copy the pyexpander result to ${filename}. If you modified ${filename}.in, then you might just need to copy the pyresult back to the source directory. If you have not modifed either, then you have likely checked out an inappropriate change. Check the git logs to see what changes were made.
If the changes have resulted from modifying ${filename}.in, then you can finish by moving ${GENERATED_FILE}.save over ${SOURCE_FILE}")
@ -75,7 +71,7 @@ else()
# Now that we have done the comparison, remove the generated file so there is
# no confusion between the generated files and the source files checked into
# the repository.
file(REMOVE ${GENERATED_FILE})
file(REMOVE ${GENERATED_FILE}.save)
# Pyexpander successfully checked, so touch a file to tell make when the
# check was last successfully performed.
execute_process(

@ -24,8 +24,32 @@
#include <vtkm/internal/ExportMacros.h>
#include <boost/static_assert.hpp>
#include <boost/type_traits/is_base_of.hpp>
namespace vtkm {
namespace internal {
template<typename ListTag>
struct ListTagCheck
{
static const bool Valid =
boost::is_base_of<vtkm::detail::ListRoot,ListTag>::value;
};
} // namespace internal
/// Checks that the argument is a proper list tag. This is a handy concept
/// check for functions and classes to make sure that a template argument is
/// actually a device adapter tag. (You can get weird errors elsewhere in the
/// code when a mistake is made.)
///
#define VTKM_IS_LIST_TAG(tag) \
BOOST_STATIC_ASSERT_MSG( \
::vtkm::internal::ListTagCheck<tag>::Valid, \
"Provided type is not a valid VTK-m list tag.")
namespace detail {
template<typename ListTag1, typename ListTag2>
@ -35,14 +59,14 @@ struct ListJoin { };
/// A special tag for an empty list.
///
struct ListTagEmpty {
struct ListTagEmpty : detail::ListRoot {
typedef detail::ListBase<void()> List;
};
/// A tag that is a construction of two other tags joined together. This struct
/// can be subclassed and still behave like a list tag.
template<typename ListTag1, typename ListTag2>
struct ListTagJoin {
struct ListTagJoin : detail::ListRoot {
typedef detail::ListJoin<ListTag1, ListTag2> List;
};
@ -81,6 +105,7 @@ template<typename Functor, typename ListTag>
VTKM_CONT_EXPORT
void ListForEach(Functor &f, ListTag)
{
VTKM_IS_LIST_TAG(ListTag);
detail::ListForEachImpl(f, typename ListTag::List());
}
@ -91,9 +116,33 @@ template<typename Functor, typename ListTag>
VTKM_CONT_EXPORT
void ListForEach(const Functor &f, ListTag)
{
VTKM_IS_LIST_TAG(ListTag);
detail::ListForEachImpl(f, typename ListTag::List());
}
/// Checks to see if the given \c Type is in the list pointed to by \c ListTag.
/// There is a static boolean named \c value that is set to true if the type is
/// contained in the list and false otherwise.
///
template<typename ListTag, typename Type>
struct ListContains
{
VTKM_IS_LIST_TAG(ListTag);
static const bool value =
detail::ListContainsImpl<typename ListTag::List,Type>::value;
};
namespace detail {
template<typename Type, typename ListTag1, typename ListTag2>
struct ListContainsImpl<ListJoin<ListTag1,ListTag2>, Type>
{
static const bool value = (vtkm::ListContains<ListTag1,Type>::value ||
vtkm::ListContains<ListTag2,Type>::value);
};
} // namespace detail
} // namespace vtkm
#endif //vtk_m_ListTag_h

@ -180,6 +180,16 @@ struct TypeListTagCommon
vtkm::Vec<vtkm::Float64,3> >
{ };
// Special implementation of ListContains for TypeListTagAll to always be
// true. Although TypeListTagAll is necessarily finite, the point is to
// be all inclusive. Besides, this should speed up the compilation when
// checking a list that should contain everything.
template<typename Type>
struct ListContains<vtkm::TypeListTagAll, Type>
{
static const bool value = true;
};
} // namespace vtkm
#endif //vtk_m_TypeListTag_h

@ -296,7 +296,7 @@ struct AssignScalarToVec<4>
}
};
template<vtkm::IdComponent Size>
template<typename CType, vtkm::IdComponent Size>
struct VecCopy
{
template<typename T1, typename T2>
@ -306,54 +306,54 @@ struct VecCopy
componentIndex < Size;
componentIndex++)
{
dest[componentIndex] = src[componentIndex];
dest[componentIndex] = CType(src[componentIndex]);
}
}
};
template<>
struct VecCopy<1>
template<typename CType>
struct VecCopy<CType, 1>
{
template<typename T1, typename T2>
VTKM_EXEC_CONT_EXPORT void operator()(T1 &dest, const T2 &src)
{
dest[0] = src[0];
dest[0] = CType(src[0]);
}
};
template<>
struct VecCopy<2>
template<typename CType>
struct VecCopy<CType, 2>
{
template<typename T1, typename T2>
VTKM_EXEC_CONT_EXPORT void operator()(T1 &dest, const T2 &src)
{
dest[0] = src[0];
dest[1] = src[1];
dest[0] = CType(src[0]);
dest[1] = CType(src[1]);
}
};
template<>
struct VecCopy<3>
template<typename CType>
struct VecCopy<CType, 3>
{
template<typename T1, typename T2>
VTKM_EXEC_CONT_EXPORT void operator()(T1 &dest, const T2 &src)
{
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
dest[0] = CType(src[0]);
dest[1] = CType(src[1]);
dest[2] = CType(src[2]);
}
};
template<>
struct VecCopy<4>
template<typename CType>
struct VecCopy<CType, 4>
{
template<typename T1, typename T2>
VTKM_EXEC_CONT_EXPORT void operator()(T1 &dest, const T2 &src)
{
dest[0] = src[0];
dest[1] = src[1];
dest[2] = src[2];
dest[3] = src[3];
dest[0] = CType(src[0]);
dest[1] = CType(src[1]);
dest[2] = CType(src[2]);
dest[3] = CType(src[3]);
}
};
@ -730,21 +730,24 @@ protected:
VTKM_EXEC_CONT_EXPORT
explicit VecBase(const ComponentType* values)
{
vtkm::internal::VecCopy<NUM_COMPONENTS>()(this->Components, values);
vtkm::internal::VecCopy<ComponentType,NUM_COMPONENTS>()(
this->Components, values);
}
template<typename OtherValueType, typename OtherDerivedType>
VTKM_EXEC_CONT_EXPORT
VecBase(const VecBase<OtherValueType,Size,OtherDerivedType> &src)
{
vtkm::internal::VecCopy<NUM_COMPONENTS>()(this->Components, src);
vtkm::internal::VecCopy<ComponentType,NUM_COMPONENTS>()(
this->Components, src);
}
public:
VTKM_EXEC_CONT_EXPORT
DerivedClass &operator=(const DerivedClass &src)
{
vtkm::internal::VecCopy<NUM_COMPONENTS>()(this->Components, src);
vtkm::internal::VecCopy<ComponentType,NUM_COMPONENTS>()(
this->Components, src);
return *reinterpret_cast<DerivedClass *>(this);
}

@ -130,6 +130,7 @@ public:
VTKM_CONT_EXPORT
internal::DynamicArrayHandleCast<NewTypeList,VTKM_DEFAULT_STORAGE_LIST_TAG>
ResetTypeList(NewTypeList = NewTypeList()) const {
VTKM_IS_LIST_TAG(NewTypeList);
return internal::DynamicArrayHandleCast<
NewTypeList,VTKM_DEFAULT_STORAGE_LIST_TAG>(*this);
}
@ -145,6 +146,7 @@ public:
VTKM_CONT_EXPORT
internal::DynamicArrayHandleCast<VTKM_DEFAULT_TYPE_LIST_TAG,NewStorageList>
ResetStorageList(NewStorageList = NewStorageList()) const {
VTKM_IS_LIST_TAG(NewStorageList);
return internal::DynamicArrayHandleCast<
VTKM_DEFAULT_TYPE_LIST_TAG,NewStorageList>(*this);
}
@ -258,6 +260,8 @@ void DynamicArrayHandle::CastAndCall(const Functor &f,
TypeList,
StorageList) const
{
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
typedef detail::DynamicArrayHandleTryType<Functor, StorageList> TryTypeType;
TryTypeType tryType = TryTypeType(*this, f);
vtkm::ListForEach(tryType, TypeList());
@ -273,6 +277,9 @@ namespace internal {
template<typename TypeList, typename StorageList>
class DynamicArrayHandleCast : public vtkm::cont::DynamicArrayHandle
{
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
public:
VTKM_CONT_EXPORT
DynamicArrayHandleCast() : DynamicArrayHandle() { }
@ -291,6 +298,7 @@ public:
VTKM_CONT_EXPORT
DynamicArrayHandleCast<NewTypeList,StorageList>
ResetTypeList(NewTypeList = NewTypeList()) const {
VTKM_IS_LIST_TAG(NewTypeList);
return DynamicArrayHandleCast<NewTypeList,StorageList>(*this);
}
@ -298,6 +306,7 @@ public:
VTKM_CONT_EXPORT
internal::DynamicArrayHandleCast<TypeList,NewStorageList>
ResetStorageList(NewStorageList = NewStorageList()) const {
VTKM_IS_LIST_TAG(NewStorageList);
return internal::DynamicArrayHandleCast<TypeList,NewStorageList>(*this);
}

@ -165,6 +165,7 @@ public:
VTKM_DEFAULT_STORAGE_LIST_TAG>
ResetPointCoordinatesList(
NewPointCoordinatesList = NewPointCoordinatesList()) const {
VTKM_IS_LIST_TAG(NewPointCoordinatesList);
return internal::DynamicPointCoordinatesCast<
NewPointCoordinatesList,
VTKM_DEFAULT_TYPE_LIST_TAG,
@ -185,6 +186,7 @@ public:
NewTypeList,
VTKM_DEFAULT_STORAGE_LIST_TAG>
ResetTypeList(NewTypeList = NewTypeList()) const {
VTKM_IS_LIST_TAG(NewTypeList);
return internal::DynamicPointCoordinatesCast<
VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG,
NewTypeList,
@ -205,6 +207,7 @@ public:
VTKM_DEFAULT_TYPE_LIST_TAG,
NewStorageList>
ResetStorageList(NewStorageList = NewStorageList()) const {
VTKM_IS_LIST_TAG(NewStorageList);
return internal::DynamicPointCoordinatesCast<
VTKM_DEFAULT_POINT_COORDINATES_LIST_TAG,
VTKM_DEFAULT_TYPE_LIST_TAG,
@ -300,6 +303,9 @@ void DynamicPointCoordinates::CastAndCall(const Functor &f,
TypeList,
StorageList) const
{
VTKM_IS_LIST_TAG(PointCoordinatesList);
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
typedef detail::DynamicPointCoordinatesTryStorage<
Functor, TypeList, StorageList> TryTypeType;
TryTypeType tryType = TryTypeType(*this, f);
@ -318,6 +324,10 @@ template<typename PointCoordinatesList,
typename StorageList>
class DynamicPointCoordinatesCast : public vtkm::cont::DynamicPointCoordinates
{
VTKM_IS_LIST_TAG(PointCoordinatesList);
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
public:
VTKM_CONT_EXPORT
DynamicPointCoordinatesCast() : DynamicPointCoordinates() { }
@ -340,6 +350,7 @@ public:
DynamicPointCoordinatesCast<NewPointCoordinatesList,TypeList,StorageList>
ResetPointCoordinatesList(
NewPointCoordinatesList = NewPointCoordinatesList()) const {
VTKM_IS_LIST_TAG(NewPointCoordinatesList);
return DynamicPointCoordinatesCast<
NewPointCoordinatesList,TypeList,StorageList>(*this);
}
@ -348,6 +359,7 @@ public:
VTKM_CONT_EXPORT
DynamicPointCoordinatesCast<PointCoordinatesList,NewTypeList,StorageList>
ResetTypeList(NewTypeList = NewTypeList()) const {
VTKM_IS_LIST_TAG(NewTypeList);
return DynamicPointCoordinatesCast<
PointCoordinatesList,NewTypeList,StorageList>(*this);
}
@ -356,6 +368,7 @@ public:
VTKM_CONT_EXPORT
DynamicPointCoordinatesCast<PointCoordinatesList,TypeList,NewStorageList>
ResetStorageList(NewStorageList = NewStorageList()) const {
VTKM_IS_LIST_TAG(NewStorageList);
return DynamicPointCoordinatesCast<
PointCoordinatesList,TypeList,NewStorageList>(*this);
}

@ -80,10 +80,11 @@ struct DeviceAdapterTagCheck
/// concept check for functions and classes to make sure that a template
/// argument is actually a device adapter tag. (You can get weird errors
/// elsewhere in the code when a mistake is made.)
///
#define VTKM_IS_DEVICE_ADAPTER_TAG(tag) \
BOOST_STATIC_ASSERT_MSG( \
::vtkm::cont::internal::DeviceAdapterTagCheck<tag>::Valid, \
"Provided type is not a valid VTKm device adapter tag.")
"Provided type is not a valid VTK-m device adapter tag.")
//-----------------------------------------------------------------------------
#if VTKM_DEVICE_ADAPTER == VTKM_DEVICE_ADAPTER_SERIAL

@ -74,7 +74,7 @@ struct TemplatedTests
{
ValueType array[ARRAY_SIZE];
static const ComponentType ORIGINAL_VALUE = 239;
static const ComponentType ORIGINAL_VALUE = 109;
FillIterator(array, array+ARRAY_SIZE, ORIGINAL_VALUE);
::vtkm::cont::internal::ArrayPortalFromIterators<ValueType *>

@ -72,7 +72,7 @@ struct TemplatedTests
return CheckIterator(iterators.GetBegin(), iterators.GetEnd(), value);
}
ComponentType ORIGINAL_VALUE() { return 239; }
ComponentType ORIGINAL_VALUE() { return 39; }
template<class ArrayPortalType>
void TestIteratorRead(ArrayPortalType portal)

@ -437,7 +437,7 @@ private:
Sleep(1000);
#endif
vtkm::FloatDefault elapsedTime = timer.GetElapsedTime();
vtkm::Float64 elapsedTime = timer.GetElapsedTime();
std::cout << "Elapsed time: " << elapsedTime << std::endl;

@ -43,7 +43,9 @@ const vtkm::Id ARRAY_SIZE = DIMENSION[0]*DIMENSION[1]*DIMENSION[2];
vtkm::Vec<vtkm::FloatDefault,3> ExpectedCoordinates(vtkm::Id index)
{
vtkm::Id3 index3d = vtkm::ExtentPointFlatIndexToTopologyIndex(index, EXTENT);
return vtkm::Vec<vtkm::FloatDefault,3>(index3d[0], index3d[1], index3d[2]);
return vtkm::make_Vec(vtkm::FloatDefault(index3d[0]),
vtkm::FloatDefault(index3d[1]),
vtkm::FloatDefault(index3d[2]));
}
int g_CheckArrayInvocations;

@ -57,7 +57,9 @@ struct StorageListTag : vtkm::cont::StorageListTagBasic { };
vtkm::Vec<vtkm::FloatDefault,3> ExpectedCoordinates(vtkm::Id index)
{
vtkm::Id3 index3d = vtkm::ExtentPointFlatIndexToTopologyIndex(index, EXTENT);
return vtkm::Vec<vtkm::FloatDefault,3>(index3d[0], index3d[1], index3d[2]);
return vtkm::make_Vec(vtkm::FloatDefault(index3d[0]),
vtkm::FloatDefault(index3d[1]),
vtkm::FloatDefault(index3d[2]));
}
struct CheckArray

File diff suppressed because it is too large Load Diff

@ -41,7 +41,7 @@ $# Ignore the following comment. It is meant for the generated file.
#include <vtkm/Types.h>
$py(max_base_list=25)\
$py(max_base_list=15)\
#define VTKM_MAX_BASE_LIST $(max_base_list)
$# Python commands used in template expansion.
@ -68,11 +68,11 @@ def param_list(num_params, name='T', start=1):
result += ',%s%d' % (name, param)
return result
def signature(num_params, name='T', return_type='void'):
def signature(num_params, name='T', return_type='void', start=1):
result = '%s(' % return_type
if num_params > 0:
result += '%s1' % name
for param in xrange(2, num_params+1):
if num_params >= start:
result += '%s%d' % (name, start)
for param in xrange(start+1, num_params+1):
result += ',%s%d' % (name, param)
result += ')'
return result
@ -86,6 +86,11 @@ namespace detail {
//-----------------------------------------------------------------------------
/// Base class that all ListTag classes inherit from. Helps identify lists
/// in macros like VTKM_IS_LIST_TAG.
///
struct ListRoot { };
template<typename signature>
struct ListBase { };
@ -120,6 +125,47 @@ $endfor\
$endfor\
//-----------------------------------------------------------------------------
template<typename List, typename Type>
struct ListContainsImpl;
template<typename Type>
struct ListContainsImpl<ListBase<void()>, Type>
{
static const bool value = false;
};
template<typename Type>
struct ListContainsImpl<ListBase<void(Type)>, Type>
{
static const bool value = true;
};
template<typename Type, typename T1>
struct ListContainsImpl<ListBase<void(T1)>, Type>
{
static const bool value = false;
};
$for(num_params in xrange(2, max_base_list+1))\
template<typename Type,
$template_params(num_params, start=2)>
struct ListContainsImpl<ListBase<void(Type,$param_list(num_params, start=2))>, Type>
{
static const bool value = true;
};
template<typename Type,
$template_params(num_params)>
struct ListContainsImpl<ListBase<$signature(num_params)>, Type>
{
static const bool value =
ListContainsImpl<ListBase<$signature(num_params, start=2)>, Type>::value;
};
$endfor\
} // namespace detail
//-----------------------------------------------------------------------------
@ -127,14 +173,14 @@ $endfor\
/// A basic tag for a list of typenames. This struct can be subclassed
/// and still behave like a list tag.
template<$template_params(max_base_list, default=' = vtkm::detail::ListParamNull')>
struct ListTagBase
struct ListTagBase : detail::ListRoot
{
typedef detail::ListBase<void($param_list(max_base_list))> List;
};
$for(num_params in xrange(0, (max_base_list+1)-1))\
template<$template_params(num_params)>
struct ListTagBase<$param_list(num_params)>
struct ListTagBase<$param_list(num_params)> : detail::ListRoot
{
typedef detail::ListBase<void($param_list(num_params))> List;
};

@ -243,7 +243,7 @@ struct DynamicTransformFinish
struct ForEachFunctor
{
template<typename T>
void operator()(T &x) const { x = 2*x; }
void operator()(T &x) const { x = T(2)*x; }
void operator()(std::string &x) const { x.append("*2"); }
};
@ -453,14 +453,14 @@ void TestForEach()
VTKM_TEST_ASSERT(funcInterface.GetParameter<1>() == 2*Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<2>() == 2*Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<3>() == Arg3+"*2", "Arg 3 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<4>() == 2*Arg4, "Arg 4 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<4>() == 2.0f*Arg4, "Arg 4 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<5>() == 2*Arg5, "Arg 5 incorrect.");
funcInterface.ForEachExec(ForEachFunctor());
VTKM_TEST_ASSERT(funcInterface.GetParameter<1>() == 4*Arg1, "Arg 1 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<2>() == 4*Arg2, "Arg 2 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<3>() == Arg3+"*2*2", "Arg 3 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<4>() == 4*Arg4, "Arg 4 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<4>() == 4.0f*Arg4, "Arg 4 incorrect.");
VTKM_TEST_ASSERT(funcInterface.GetParameter<5>() == 4*Arg5, "Arg 5 incorrect.");
}

@ -24,6 +24,7 @@
#include <vtkm/testing/Testing.h>
#include <algorithm>
#include <vector>
namespace {
@ -94,9 +95,21 @@ void CheckSame(const vtkm::Vec<int,N> &expected,
}
}
template<int N, typename ListTag>
void CheckContains(TestClass<N>, ListTag, const std::vector<int> contents)
{
bool listContains = vtkm::ListContains<ListTag, TestClass<N> >::value;
bool shouldContain =
std::find(contents.begin(), contents.end(), N) != contents.end();
VTKM_TEST_ASSERT(listContains == shouldContain,
"ListContains check failed.");
}
template<vtkm::IdComponent N, typename ListTag>
void TryList(const vtkm::Vec<int,N> &expected, ListTag)
{
VTKM_IS_LIST_TAG(ListTag);
std::cout << " Try mutable for each" << std::endl;
MutableFunctor functor;
vtkm::ListForEach(functor, ListTag());
@ -105,10 +118,30 @@ void TryList(const vtkm::Vec<int,N> &expected, ListTag)
std::cout << " Try constant for each" << std::endl;
vtkm::ListForEach(ConstantFunctor(), ListTag());
CheckSame(expected, g_FoundType);
std::cout << " Try checking contents" << std::endl;
CheckContains(TestClass<11>(), ListTag(), functor.FoundTypes);
CheckContains(TestClass<21>(), ListTag(), functor.FoundTypes);
CheckContains(TestClass<22>(), ListTag(), functor.FoundTypes);
CheckContains(TestClass<31>(), ListTag(), functor.FoundTypes);
CheckContains(TestClass<32>(), ListTag(), functor.FoundTypes);
CheckContains(TestClass<33>(), ListTag(), functor.FoundTypes);
CheckContains(TestClass<41>(), ListTag(), functor.FoundTypes);
CheckContains(TestClass<42>(), ListTag(), functor.FoundTypes);
CheckContains(TestClass<43>(), ListTag(), functor.FoundTypes);
CheckContains(TestClass<44>(), ListTag(), functor.FoundTypes);
}
void TestLists()
{
std::cout << "Valid List Tag Checks" << std::endl;
VTKM_TEST_ASSERT(vtkm::internal::ListTagCheck<TestListTag1>::Valid,
"Failed list tag check");
VTKM_TEST_ASSERT(vtkm::internal::ListTagCheck<TestListTagJoin>::Valid,
"Failed list tag check");
VTKM_TEST_ASSERT(!vtkm::internal::ListTagCheck<TestClass<1> >::Valid,
"Failed list tag check");
std::cout << "ListTagEmpty" << std::endl;
TryList(vtkm::Vec<int,0>(), vtkm::ListTagEmpty());