Commit a94abd7a authored by Robert Maynard's avatar Robert Maynard

Add in the minimum part of the control env to have a testable array handle.

parent 24f561f0
......@@ -35,5 +35,4 @@ add_subdirectory(internal)
#-----------------------------------------------------------------------------
#add the control and exec folders
# add_subdirectory(cont)
add_subdirectory(cont)
//============================================================================
// 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.
//============================================================================
#ifndef vtkm_cont__ArrayContainerControl_h
#define vtkm_cont__ArrayContainerControl_h
#define VTKM_ARRAY_CONTAINER_CONTROL_ERROR -1
#define VTKM_ARRAY_CONTAINER_CONTROL_UNDEFINED 0
#define VTKM_ARRAY_CONTAINER_CONTROL_BASIC 1
#ifndef VTKM_ARRAY_CONTAINER_CONTROL
#define VTKM_ARRAY_CONTAINER_CONTROL VTKM_ARRAY_CONTAINER_CONTROL_BASIC
#endif
namespace vtkm {
namespace cont {
#ifdef VTKM_DOXYGEN_ONLY
/// \brief A tag specifying client memory allocation.
///
/// An ArrayContainerControl tag specifies how an ArrayHandle allocates and
/// frees memory. The tag ArrayContainerControlTag___ does not actually exist.
/// Rather, this documentation is provided to describe how array containers are
/// specified. Loading the vtkm/cont/ArrayContainerControl.h header will set a
/// default array container. You can specify the default array container by
/// first setting the VTKM_ARRAY_CONTAINER_CONTROL macro. Currently it can only
/// be set to VTKM_ARRAY_CONTAINER_CONTROL_BASIC.
///
/// User code external to VTKm is free to make its own ArrayContainerControlTag.
/// This is a good way to get VTKm to read data directly in and out of arrays
/// from other libraries. However, care should be taken when creating an
/// ArrayContainerControl. One particular problem that is likely is a container
/// that "constructs" all the items in the array. If done incorrectly, then
/// memory of the array can be incorrectly bound to the wrong process. If you
/// do provide your own ArrayContainerControlTag, please be diligent in
/// comparing its performance to the ArrayContainerControlTagBasic.
///
/// To implement your own ArrayContainerControlTag, you first must create a tag
/// class (an empty struct) defining your tag (i.e. struct
/// ArrayContainerControlTagMyAlloc { };). Then provide a partial template
/// specialization of vtkm::cont::internal::ArrayContainerControl for your new
/// tag.
///
struct ArrayContainerControlTag___ { };
#endif // VTKM_DOXYGEN_ONLY
namespace internal {
/// This templated class must be partially specialized for each
/// ArrayContainerControlTag created, which will define the implementation for
/// that tag.
///
template<typename T, class ArrayContainerControlTag>
class ArrayContainerControl
#ifdef VTKM_DOXYGEN_ONLY
{
public:
/// The type of each item in the array.
///
typedef T ValueType;
/// \brief The type of portal objects for the array.
///
/// The actual portal object can take any form. This is a simple example of a
/// portal to a C array.
///
typedef ::vtkm::cont::internal::ArrayPortalFromIterators<ValueType*> PortalType;
/// \brief The type of portal objects (const version) for the array.
///
/// The actual portal object can take any form. This is a simple example of a
/// portal to a C array.
///
typedef ::vtkm::cont::internal::ArrayPortalFromIterators<const ValueType*> PortalConstType;
/// Returns a portal to the array.
///
VTKM_CONT_EXPORT
PortalType GetPortal();
/// Returns a portal to the array with immutable values.
///
VTKM_CONT_EXPORT
PortalConstType GetPortalConst() const;
/// Retuns the number of entries allocated in the array.
VTKM_CONT_EXPORT
vtkm::Id GetNumberOfValues() const;
/// \brief Allocates an array large enough to hold the given number of values.
///
/// The allocation may be done on an already existing array, but can wipe out
/// any data already in the array. This method can throw
/// ErrorControlOutOfMemory if the array cannot be allocated.
///
VTKM_CONT_EXPORT
void Allocate(vtkm::Id numberOfValues);
/// \brief Reduces the size of the array without changing its values.
///
/// This method allows you to resize the array without reallocating it. The
/// number of entries in the array is changed to \c numberOfValues. The data
/// in the array (from indices 0 to \c numberOfValues - 1) are the same, but
/// \c numberOfValues must be equal or less than the preexisting size
/// (returned from GetNumberOfValues). That is, this method can only be used
/// to shorten the array, not lengthen.
VTKM_CONT_EXPORT
void Shrink(vtkm::Id numberOfValues);
/// \brief Frees any resources (i.e. memory) stored in this array.
///
/// After calling this method GetNumberOfValues will return 0 and
/// GetIteratorBegin and GetIteratorEnd will return the same iterator. The
/// resources should also be released when the ArrayContainerControl class is
/// destroyed.
VTKM_CONT_EXPORT
void ReleaseResources();
};
#else // VTKM_DOXYGEN_ONLY
;
#endif // VTKM_DOXYGEN_ONLY
} // namespace internal
}
} // namespace vtkm::cont
// This is put at the bottom of the header so that the ArrayContainerControl
// template is declared before any implementations are called.
#if VTKM_ARRAY_CONTAINER_CONTROL == VTKM_ARRAY_CONTAINER_CONTROL_BASIC
#include <vtkm/cont/ArrayContainerControlBasic.h>
#define VTKM_DEFAULT_ARRAY_CONTAINER_CONTROL_TAG \
::vtkm::cont::ArrayContainerControlTagBasic
#elif VTKM_ARRAY_CONTAINER_CONTROL == VTKM_ARRAY_CONTAINER_CONTROL_ERROR
#include <vtkm/cont/internal/ArrayContainerControlError.h>
#define VTKM_DEFAULT_ARRAY_CONTAINER_CONTROL_TAG \
::vtkm::cont::internal::ArrayContainerControlTagError
#elif (VTKM_ARRAY_CONTAINER_CONTROL == VTKM_ARRAY_CONTAINER_CONTROL_UNDEFINED) || !defined(VTKM_ARRAY_CONTAINER_CONTROL)
#ifndef VTKM_DEFAULT_ARRAY_CONTAINER_CONTROL_TAG
#warning If array container for control is undefined, VTKM_DEFAULT_ARRAY_CONTAINER_CONTROL_TAG must be defined.
#endif
#endif
#endif //vtkm_cont__ArrayContainerControl_h
//============================================================================
// 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.
//============================================================================
#ifndef vtkm_cont__ArrayContainerControlBasic_h
#define vtkm_cont__ArrayContainerControlBasic_h
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayContainerControl.h>
#include <vtkm/cont/Assert.h>
#include <vtkm/cont/ErrorControlBadValue.h>
#include <vtkm/cont/ErrorControlOutOfMemory.h>
#include <vtkm/cont/internal/ArrayPortalFromIterators.h>
namespace vtkm {
namespace cont {
/// A tag for the basic implementation of an ArrayContainerControl object.
struct ArrayContainerControlTagBasic { };
namespace internal {
/// A basic implementation of an ArrayContainerControl object.
///
/// \todo This container does \em not construct the values within the array.
/// Thus, it is important to not use this class with any type that will fail if
/// not constructed. These are things like basic types (int, float, etc.) and
/// the VTKm Tuple classes. In the future it would be nice to have a compile
/// time check to enforce this.
///
template <typename ValueT>
class ArrayContainerControl<ValueT, vtkm::cont::ArrayContainerControlTagBasic>
{
public:
typedef ValueT ValueType;
typedef vtkm::cont::internal::ArrayPortalFromIterators<ValueType*> PortalType;
typedef vtkm::cont::internal::ArrayPortalFromIterators<const ValueType*> PortalConstType;
private:
/// The original design of this class provided an allocator as a template
/// parameters. That messed things up, though, because other templated
/// classes assume that the \c ArrayContainerControl has one template
/// parameter. There are other ways to allow you to specify the allocator,
/// but it is uncertain whether that would ever be useful. So, instead of
/// jumping through hoops implementing them, just fix the allocator for now.
///
typedef std::allocator<ValueType> AllocatorType;
public:
ArrayContainerControl() : Array(NULL), NumberOfValues(0), AllocatedSize(0) { }
~ArrayContainerControl()
{
this->ReleaseResources();
}
void ReleaseResources()
{
if (this->NumberOfValues > 0)
{
VTKM_ASSERT_CONT(this->Array != NULL);
AllocatorType allocator;
allocator.deallocate(this->Array, this->AllocatedSize);
this->Array = NULL;
this->NumberOfValues = 0;
this->AllocatedSize = 0;
}
else
{
VTKM_ASSERT_CONT(this->Array == NULL);
}
}
void Allocate(vtkm::Id numberOfValues)
{
if (numberOfValues <= this->AllocatedSize)
{
this->NumberOfValues = numberOfValues;
return;
}
this->ReleaseResources();
try
{
if (numberOfValues > 0)
{
AllocatorType allocator;
this->Array = allocator.allocate(numberOfValues);
this->AllocatedSize = numberOfValues;
this->NumberOfValues = numberOfValues;
}
else
{
// ReleaseResources should have already set AllocatedSize to 0.
VTKM_ASSERT_CONT(this->AllocatedSize == 0);
}
}
catch (std::bad_alloc err)
{
// Make sureour state is OK.
this->Array = NULL;
this->NumberOfValues = 0;
this->AllocatedSize = 0;
throw vtkm::cont::ErrorControlOutOfMemory(
"Could not allocate basic control array.");
}
}
vtkm::Id GetNumberOfValues() const
{
return this->NumberOfValues;
}
void Shrink(vtkm::Id numberOfValues)
{
if (numberOfValues > this->GetNumberOfValues())
{
throw vtkm::cont::ErrorControlBadValue(
"Shrink method cannot be used to grow array.");
}
this->NumberOfValues = numberOfValues;
}
PortalType GetPortal()
{
return PortalType(this->Array, this->Array + this->NumberOfValues);
}
PortalConstType GetPortalConst() const
{
return PortalConstType(this->Array, this->Array + this->NumberOfValues);
}
/// \brief Take the reference away from this object.
///
/// This method returns the pointer to the array held by this array. It then
/// clears the internal array pointer to NULL, thereby ensuring that the
/// ArrayContainerControl will never deallocate the array. This is
/// helpful for taking a reference for an array created internally by VTKm and
/// not having to keep a VTKm object around. Obviously the caller becomes
/// responsible for destroying the memory.
///
ValueType *StealArray()
{
ValueType *saveArray = this->Array;
this->Array = NULL;
this->NumberOfValues = 0;
this->AllocatedSize = 0;
return saveArray;
}
private:
// Not implemented.
ArrayContainerControl(const ArrayContainerControl<ValueType, ArrayContainerControlTagBasic> &src);
void operator=(const ArrayContainerControl<ValueType, ArrayContainerControlTagBasic> &src);
ValueType *Array;
vtkm::Id NumberOfValues;
vtkm::Id AllocatedSize;
};
} // namespace internal
}
} // namespace vtkm::cont
#endif //vtkm_cont__ArrayContainerControlBasic_h
//============================================================================
// 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.
//============================================================================
#ifndef vtkm_cont_ArrayContainerControlImplicit
#define vtkm_cont_ArrayContainerControlImplicit
#include <vtkm/Types.h>
#include <vtkm/cont/ArrayContainerControl.h>
#include <vtkm/cont/Assert.h>
#include <vtkm/cont/ErrorControlBadValue.h>
#include <vtkm/cont/internal/ArrayTransfer.h>
namespace vtkm {
namespace cont {
/// \brief An implementation for read-only implicit arrays.
///
/// It is sometimes the case that you want VTKm to operate on an array of
/// implicit values. That is, rather than store the data in an actual array, it
/// is gerenated on the fly by a function. This is handled in VTKm by creating
/// an ArrayHandle in VTKm with an ArrayContainerControlTagImplicit type of
/// ArrayContainerControl. This tag itself is templated to specify an
/// ArrayPortal that generates the desired values. An ArrayHandle created with
/// this tag will raise an error on any operation that tries to modify it.
///
/// \todo The ArrayHandle currently copies the array in cases where the control
/// and environment do not share memory. This is wasteful and should be fixed.
///
template<class ArrayPortalType>
struct ArrayContainerControlTagImplicit {
typedef ArrayPortalType PortalType;
};
namespace internal {
template<class ArrayPortalType>
class ArrayContainerControl<
typename ArrayPortalType::ValueType,
ArrayContainerControlTagImplicit<ArrayPortalType> >
{
public:
typedef typename ArrayPortalType::ValueType ValueType;
typedef ArrayPortalType PortalConstType;
// This is meant to be invalid. Because implicit arrays are read only, you
// should only be able to use the const version.
struct PortalType {
typedef void *ValueType;
typedef void *IteratorType;
};
// All these methods do nothing but raise errors.
PortalType GetPortal() {
throw vtkm::cont::ErrorControlBadValue("Implicit arrays are read-only.");
}
PortalConstType GetPortalConst() const {
// This does not work because the ArrayHandle holds the constant
// ArrayPortal, not the container.
throw vtkm::cont::ErrorControlBadValue(
"Implicit container does not store array portal. "
"Perhaps you did not set the ArrayPortal when "
"constructing the ArrayHandle.");
}
vtkm::Id GetNumberOfValues() const {
// This does not work because the ArrayHandle holds the constant
// ArrayPortal, not the container.
throw vtkm::cont::ErrorControlBadValue(
"Implicit container does not store array portal. "
"Perhaps you did not set the ArrayPortal when "
"constructing the ArrayHandle.");
}
void Allocate(vtkm::Id vtkmNotUsed(numberOfValues)) {
throw vtkm::cont::ErrorControlBadValue("Implicit arrays are read-only.");
}
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues)) {
throw vtkm::cont::ErrorControlBadValue("Implicit arrays are read-only.");
}
void ReleaseResources() {
throw vtkm::cont::ErrorControlBadValue("Implicit arrays are read-only.");
}
};
template<typename T, class ArrayPortalType, class DeviceAdapterTag>
class ArrayTransfer<
T, ArrayContainerControlTagImplicit<ArrayPortalType>, DeviceAdapterTag>
{
private:
typedef ArrayContainerControlTagImplicit<ArrayPortalType>
ArrayContainerControlTag;
typedef vtkm::cont::internal::ArrayContainerControl<T,ArrayContainerControlTag>
ContainerType;
public:
typedef T ValueType;
typedef typename ContainerType::PortalType PortalControl;
typedef typename ContainerType::PortalConstType PortalConstControl;
typedef PortalControl PortalExecution;
typedef PortalConstControl PortalConstExecution;
ArrayTransfer() : PortalValid(false) { }
VTKM_CONT_EXPORT vtkm::Id GetNumberOfValues() const {
VTKM_ASSERT_CONT(this->PortalValid);
return this->Portal.GetNumberOfValues();
}
VTKM_CONT_EXPORT void LoadDataForInput(PortalConstControl portal) {
this->Portal = portal;
this->PortalValid = true;
}
VTKM_CONT_EXPORT void LoadDataForInput(const ContainerType &controlArray) {
this->LoadDataForInput(controlArray.GetPortalConst());
}
VTKM_CONT_EXPORT
void LoadDataForInPlace(ContainerType &vtkmNotUsed(controlArray))
{
throw vtkm::cont::ErrorControlBadValue(
"Implicit arrays cannot be used for output or in place.");
}
VTKM_CONT_EXPORT void AllocateArrayForOutput(
ContainerType &vtkmNotUsed(controlArray),
vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorControlBadValue(
"Implicit arrays cannot be used for output.");
}
VTKM_CONT_EXPORT void RetrieveOutputData(
ContainerType &vtkmNotUsed(controlArray)) const
{
throw vtkm::cont::ErrorControlBadValue(
"Implicit arrays cannot be used for output.");
}
template <class IteratorTypeControl>
VTKM_CONT_EXPORT void CopyInto(IteratorTypeControl dest) const
{
VTKM_ASSERT_CONT(this->PortalValid);
std::copy(this->Portal.GetIteratorBegin(),
this->Portal.GetIteratorEnd(),
dest);
}
VTKM_CONT_EXPORT void Shrink(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorControlBadValue("Implicit arrays cannot be resized.");
}
VTKM_CONT_EXPORT PortalExecution GetPortalExecution()
{
throw vtkm::cont::ErrorControlBadValue(
"Implicit arrays are read-only. (Get the const portal.)");
}
VTKM_CONT_EXPORT PortalConstExecution GetPortalConstExecution() const
{
VTKM_ASSERT_CONT(this->PortalValid);
return this->Portal;
}
VTKM_CONT_EXPORT void ReleaseResources() { }
private:
PortalConstExecution Portal;
bool PortalValid;
};
} // namespace internal
}
} // namespace vtkm::cont
#endif //vtkm_cont_ArrayContainerControlImplicit
This diff is collapsed.
//============================================================================
// 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.
//============================================================================
#ifndef vtkm_cont_ArrayPortal_h
#define vtkm_cont_ArrayPortal_h
#include <vtkm/Types.h>
namespace vtkm {
namespace cont {
#ifdef VTKM_DOXYGEN_ONLY
/// \brief A class that points to and access and array of data.
///
/// The ArrayPortal class itself does not exist; this code is provided for
/// documentation purposes only.
///
/// An ArrayPortal object acts like a pointer to a random-access container
/// (that is, an array) and also lets you set and get values in that array. In
/// many respects an ArrayPortal is similar in concept to that of iterators but
/// with a much simpler interface and no internal concept of position.
/// Otherwise, ArrayPortal objects may be passed and copied around so that
/// multiple entities may be accessing the same array.
///
/// An ArrayPortal differs from an ArrayHandle in that the ArrayPortal is a
/// much lighterweight object and that it does not manage things like
/// allocation and control/execution sharing. An ArrayPortal also differs from
/// an ArrayContainer in that it does not actually contain the data but rather
/// points to it. In this way the ArrayPortal can be copied and passed and
/// still point to the same data.
///
/// Most VTKm users generally do not need to do much or anything with
/// ArrayPortal objects. It is mostly an internal mechanism. However, an
/// ArrayPortal can be used to pass constant input data to an ArrayHandle.
///
/// Although this documentation is given for the control environment, there are
/// instances of an identical concept in the execution environment, although
/// some features are missing there.
///
template<typename T>
class ArrayPortal
{
public:
/// The type of each value in the array.
///
typedef T ValueType;
/// The total number of values in the array. They are index from 0 to
/// GetNumberOfValues()-1.
///
VTKM_CONT_EXPORT
vtkm::Id GetNumberOfValues() const;
/// Gets a value from the array.
///
VTKM_CONT_EXPORT
ValueType Get(vtkm::Id index) const;
/// Sets a value in the array. This function may not exist for an ArrayPortal
/// pointing to a const array.
///
VTKM_CONT_EXPORT
void Set(vtkm::Id index, const ValueType &value) const;
/// An iterator type that can be used as an alternate way to access the data.
/// If the container being pointed to has a natural iterator that can be
/// used, then use that. Otherwise, use IteratorForArrayPortal. Iterators are
/// not necessary for array portals in the execution environment.
///
typedef ValueType *IteratorType;
/// Returns an iterator to the beginning of the array. Iterators are not
/// necessary for array portals in the execution environment.
///
VTKM_CONT_EXPORT
IteratorType GetIteratorBegin() const;
/// Returns an iterator to the end of the array. Iterators are not necessary
/// for array portals in the execution environment.
///
VTKM_CONT_EXPORT
IteratorType GetIteratorEnd() const;
};
#endif // VTKM_DOXYGEN_ONLY
}
} // namespace vtkm::cont
#endif //vtkm_cont_ArrayPortal_h
//============================================================================
// 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.
//============================================================================
#ifndef vtkm_cont_Assert_h
#define vtkm_cont_Assert_h
#include <vtkm/cont/ErrorControlAssert.h>
// Stringify macros for VTKM_ASSERT_CONT
#define __VTKM_ASSERT_CONT_STRINGIFY_2ND(s) #s
#define __VTKM_ASSERT_CONT_STRINGIFY(s) __VTKM_ASSERT_CONT_STRINGIFY_2ND(s)
/// \def VTKM_ASSERT_CONT(condition)
///
/// Asserts that \a condition resolves to true. If \a condition is false,
/// then an error is raised. This macro is meant to work in the VTKm control
/// environment and throws an ErrorControlAssert object on failure.
#ifndef NDEBUG
#define VTKM_ASSERT_CONT(condition) \
if (!(condition)) \
::vtkm::cont::Assert(condition, __FILE__, __LINE__, #condition)
#else
#define VTKM_ASSERT_CONT(condition)
#endif
namespace vtkm {
namespace cont {
VTKM_CONT_EXPORT void Assert(bool condition,
const std::string &file,
vtkm::Id line,
const std::string &message)
{
if (condition)
{
// Do nothing.
}
else
{
throw vtkm::cont::ErrorControlAssert(file, line, message);
}
}
}
} // namespace vtkm::cont
#endif //vtkm_cont_Assert_h
##============================================================================
## Copyright (c) Kitware, Inc.
## All rights reserved.