Merge branch 'master' into vtk-m-cmake_refactor

This commit is contained in:
Robert Maynard 2018-01-16 14:57:52 -05:00
commit 0660c67fef
259 changed files with 18968 additions and 4616 deletions

2
.gitattributes vendored

@ -14,4 +14,4 @@ data/* filter=lfs diff=lfs merge=lfs -text
*.rst whitespace=tab-in-indent conflict-marker-size=79 *.rst whitespace=tab-in-indent conflict-marker-size=79
*.txt whitespace=tab-in-indent *.txt whitespace=tab-in-indent
diy/** -format.clang-format -whitespace vtkm/thirdparty/diy/vtkmdiy/** -format.clang-format -whitespace

@ -39,9 +39,7 @@ set(FILES_TO_CHECK
set(EXCEPTIONS set(EXCEPTIONS
LICENSE.txt LICENSE.txt
README.txt README.txt
diy/include/diy vtkm/thirdparty/diy/vtkmdiy
diy/LEGAL.txt
diy/LICENSE.txt
) )
if (NOT VTKm_SOURCE_DIR) if (NOT VTKm_SOURCE_DIR)

@ -39,11 +39,21 @@ set(FILES_TO_CHECK
set(EXCEPTIONS set(EXCEPTIONS
) )
set(DIRECTORY_EXCEPTIONS
${VTKm_SOURCE_DIR}/vtkm/thirdparty/diy/vtkmdiy
)
if (NOT VTKm_SOURCE_DIR) if (NOT VTKm_SOURCE_DIR)
message(SEND_ERROR "VTKm_SOURCE_DIR not defined.") message(SEND_ERROR "VTKm_SOURCE_DIR not defined.")
endif (NOT VTKm_SOURCE_DIR) endif (NOT VTKm_SOURCE_DIR)
function(check_directory directory parent_CMakeLists_contents) function(check_directory directory parent_CMakeLists_contents)
foreach(exception IN LISTS DIRECTORY_EXCEPTIONS)
if(directory MATCHES "^${exception}$")
return()
endif()
endforeach(exception)
message("Checking directory ${directory}...") message("Checking directory ${directory}...")
get_filename_component(directory_name "${directory}" NAME) get_filename_component(directory_name "${directory}" NAME)

@ -206,8 +206,8 @@ if(VTKm_ENABLE_MPI)
if (NOT MPI_C_FOUND) if (NOT MPI_C_FOUND)
find_package(MPI ${VTKm_FIND_PACKAGE_QUIETLY}) find_package(MPI ${VTKm_FIND_PACKAGE_QUIETLY})
endif() endif()
add_subdirectory(diy)
endif() endif()
add_subdirectory(vtkm) add_subdirectory(vtkm)
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------

@ -20,4 +20,7 @@
list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
".*warning: ignoring loop annotation.*" ".*warning: ignoring loop annotation.*"
) ".*diy.include.diy.*WShadow.*" # exclude `diy` shadow warnings.
".*diy.include.diy.*note: shadowed.*" # exclude `diy` shadow warnings.
".*diy.include.diy.storage.hpp.*Wunused-result.*" # this is a TODO in DIY.
)

@ -80,8 +80,8 @@ struct MeasureCopySpeed
VTKM_CONT std::string Description() const VTKM_CONT std::string Description() const
{ {
vtkm::UInt64 actualSize = vtkm::UInt64 actualSize = sizeof(ValueType);
static_cast<vtkm::UInt64>(this->Source.GetNumberOfValues() * sizeof(ValueType)); actualSize *= static_cast<vtkm::UInt64>(this->Source.GetNumberOfValues());
std::ostringstream out; std::ostringstream out;
out << "Copying " << HumanSize(this->NumBytes) << " (actual=" << HumanSize(actualSize) out << "Copying " << HumanSize(this->NumBytes) << " (actual=" << HumanSize(actualSize)
<< ") of " << vtkm::testing::TypeName<ValueType>::Name() << "\n"; << ") of " << vtkm::testing::TypeName<ValueType>::Name() << "\n";

@ -36,6 +36,7 @@
#include <vtkm/worklet/StableSortIndices.h> #include <vtkm/worklet/StableSortIndices.h>
#include <algorithm> #include <algorithm>
#include <cctype>
#include <cmath> #include <cmath>
#include <random> #include <random>
#include <string> #include <string>
@ -108,7 +109,7 @@ struct BenchDevAlgoConfig
/// @note FixBytes and FixSizes are not mutually exclusive. If both are /// @note FixBytes and FixSizes are not mutually exclusive. If both are
/// specified, both will run. /// specified, both will run.
bool TestArraySizeValues{ false }; bool TestArraySizeValues{ false };
vtkm::Id ArraySizeValues{ 1 << 21 }; vtkm::UInt64 ArraySizeValues{ 1 << 21 };
/// If true, operations like "Unique" will test with a wider range of unique /// If true, operations like "Unique" will test with a wider range of unique
/// values (5%, 10%, 15%, 20%, 25%, 30%, 35%, 40%, 45%, 50%, 75%, 100% /// values (5%, 10%, 15%, 20%, 25%, 30%, 35%, 40%, 45%, 50%, 75%, 100%
@ -126,7 +127,7 @@ struct BenchDevAlgoConfig
{ {
return this->DoByteSizes return this->DoByteSizes
? static_cast<vtkm::Id>(this->ArraySizeBytes / static_cast<vtkm::UInt64>(sizeof(T))) ? static_cast<vtkm::Id>(this->ArraySizeBytes / static_cast<vtkm::UInt64>(sizeof(T)))
: this->ArraySizeValues; : static_cast<vtkm::Id>(this->ArraySizeValues);
} }
}; };
@ -291,8 +292,8 @@ private:
{ {
vtkm::Id arraySize = Config.ComputeSize<Value>(); vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description; std::stringstream description;
description << "Copy " << arraySize << " values (" << HumanSize(arraySize * sizeof(Value)) description << "Copy " << arraySize << " values ("
<< ")"; << HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ")";
return description.str(); return description.str();
} }
}; };
@ -337,8 +338,8 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>(); vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description; std::stringstream description;
description << "CopyIf on " << arraySize << " values (" description << "CopyIf on " << arraySize << " values ("
<< HumanSize(arraySize * sizeof(Value)) << ") with " << PERCENT_VALID << HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ") with "
<< "% valid values"; << PERCENT_VALID << "% valid values";
return description.str(); return description.str();
} }
}; };
@ -393,8 +394,8 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>(); vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description; std::stringstream description;
description << "LowerBounds on " << arraySize << " input values (" description << "LowerBounds on " << arraySize << " input values ("
<< "(" << HumanSize(arraySize * sizeof(Value)) << ") (" << PERCENT_VALUES << "(" << HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ") ("
<< "% configuration)"; << PERCENT_VALUES << "% configuration)";
return description.str(); return description.str();
} }
}; };
@ -451,7 +452,7 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>(); vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description; std::stringstream description;
description << "Reduce on " << arraySize << " values (" description << "Reduce on " << arraySize << " values ("
<< HumanSize(arraySize * sizeof(Value)) << ")"; << HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ")";
return description.str(); return description.str();
} }
}; };
@ -496,8 +497,8 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>(); vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description; std::stringstream description;
description << "ReduceByKey on " << arraySize << " values (" description << "ReduceByKey on " << arraySize << " values ("
<< HumanSize(arraySize * sizeof(Value)) << ") with " << N_KEYS << " (" << HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ") with "
<< PERCENT_KEYS << "%) distinct vtkm::Id keys"; << N_KEYS << " (" << PERCENT_KEYS << "%) distinct vtkm::Id keys";
return description.str(); return description.str();
} }
}; };
@ -543,7 +544,7 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>(); vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description; std::stringstream description;
description << "ScanInclusive on " << arraySize << " values (" description << "ScanInclusive on " << arraySize << " values ("
<< HumanSize(arraySize * sizeof(Value)) << ")"; << HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ")";
return description.str(); return description.str();
} }
}; };
@ -579,7 +580,7 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>(); vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description; std::stringstream description;
description << "ScanExclusive on " << arraySize << " values (" description << "ScanExclusive on " << arraySize << " values ("
<< HumanSize(arraySize * sizeof(Value)) << ")"; << HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ")";
return description.str(); return description.str();
} }
}; };
@ -621,7 +622,7 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>(); vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description; std::stringstream description;
description << "Sort on " << arraySize << " random values (" description << "Sort on " << arraySize << " random values ("
<< HumanSize(arraySize * sizeof(Value)) << ")"; << HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ")";
return description.str(); return description.str();
} }
}; };
@ -674,8 +675,8 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>(); vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description; std::stringstream description;
description << "SortByKey on " << arraySize << " random values (" description << "SortByKey on " << arraySize << " random values ("
<< HumanSize(arraySize * sizeof(Value)) << ") with " << N_KEYS << " (" << HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ") with "
<< PERCENT_KEYS << "%) different vtkm::Id keys"; << N_KEYS << " (" << PERCENT_KEYS << "%) different vtkm::Id keys";
return description.str(); return description.str();
} }
}; };
@ -731,7 +732,7 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>(); vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description; std::stringstream description;
description << "StableSortIndices::Sort on " << arraySize << " random values (" description << "StableSortIndices::Sort on " << arraySize << " random values ("
<< HumanSize(arraySize * sizeof(Value)) << ")"; << HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ")";
return description.str(); return description.str();
} }
}; };
@ -775,8 +776,8 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>(); vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description; std::stringstream description;
description << "StableSortIndices::Unique on " << arraySize << " values (" description << "StableSortIndices::Unique on " << arraySize << " values ("
<< HumanSize(arraySize * sizeof(Value)) << ") with " << this->N_VALID << " (" << HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ") with "
<< PERCENT_VALID << "%) valid values"; << this->N_VALID << " (" << PERCENT_VALID << "%) valid values";
return description.str(); return description.str();
} }
}; };
@ -831,8 +832,8 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>(); vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description; std::stringstream description;
description << "Unique on " << arraySize << " values (" description << "Unique on " << arraySize << " values ("
<< HumanSize(arraySize * sizeof(Value)) << ") with " << N_VALID << " (" << HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ") with "
<< PERCENT_VALID << "%) valid values"; << N_VALID << " (" << PERCENT_VALID << "%) valid values";
return description.str(); return description.str();
} }
}; };
@ -887,8 +888,8 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>(); vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description; std::stringstream description;
description << "UpperBounds on " << arraySize << " input and " << N_VALS << " (" description << "UpperBounds on " << arraySize << " input and " << N_VALS << " ("
<< PERCENT_VALS << PERCENT_VALS << "%) values (input array size: "
<< "%) values (input array size: " << HumanSize(arraySize * sizeof(Value)) << ")"; << HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ")";
return description.str(); return description.str();
} }
}; };
@ -1196,7 +1197,9 @@ int main(int argc, char* argv[])
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
{ {
std::string arg = argv[i]; std::string arg = argv[i];
std::transform(arg.begin(), arg.end(), arg.begin(), ::tolower); std::transform(arg.begin(), arg.end(), arg.begin(), [](char c) {
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
});
if (arg == "copy") if (arg == "copy")
{ {
config.BenchmarkFlags |= vtkm::benchmarking::COPY; config.BenchmarkFlags |= vtkm::benchmarking::COPY;
@ -1253,7 +1256,9 @@ int main(int argc, char* argv[])
{ {
++i; ++i;
arg = argv[i]; arg = argv[i];
std::transform(arg.begin(), arg.end(), arg.begin(), ::tolower); std::transform(arg.begin(), arg.end(), arg.begin(), [](char c) {
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
});
if (arg == "base") if (arg == "base")
{ {
config.ExtendedTypeList = false; config.ExtendedTypeList = false;
@ -1272,7 +1277,9 @@ int main(int argc, char* argv[])
{ {
++i; ++i;
arg = argv[i]; arg = argv[i];
std::transform(arg.begin(), arg.end(), arg.begin(), ::tolower); std::transform(arg.begin(), arg.end(), arg.begin(), [](char c) {
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
});
if (arg == "off") if (arg == "off")
{ {
config.TestArraySizeBytes = false; config.TestArraySizeBytes = false;
@ -1288,7 +1295,9 @@ int main(int argc, char* argv[])
{ {
++i; ++i;
arg = argv[i]; arg = argv[i];
std::transform(arg.begin(), arg.end(), arg.begin(), ::tolower); std::transform(arg.begin(), arg.end(), arg.begin(), [](char c) {
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
});
if (arg == "off") if (arg == "off")
{ {
config.TestArraySizeValues = false; config.TestArraySizeValues = false;

@ -35,6 +35,7 @@
#include "Benchmarker.h" #include "Benchmarker.h"
#include <vtkm/cont/testing/Testing.h> #include <vtkm/cont/testing/Testing.h>
#include <cctype>
#include <random> #include <random>
#include <string> #include <string>
@ -922,7 +923,9 @@ int main(int argc, char* argv[])
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
{ {
std::string arg = argv[i]; std::string arg = argv[i];
std::transform(arg.begin(), arg.end(), arg.begin(), ::tolower); std::transform(arg.begin(), arg.end(), arg.begin(), [](char c) {
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
});
if (arg == "blackscholes") if (arg == "blackscholes")
{ {
benchmarks |= vtkm::benchmarking::BLACK_SCHOLES; benchmarks |= vtkm::benchmarking::BLACK_SCHOLES;

@ -107,7 +107,6 @@ VTKM_MAKE_BENCHMARK(RayTracing, BenchRayTracing);
int main(int, char* []) int main(int, char* [])
{ {
using TestTypes = vtkm::ListTagBase<vtkm::Float32>;
VTKM_RUN_BENCHMARK(RayTracing, vtkm::ListTagBase<vtkm::Float32>()); VTKM_RUN_BENCHMARK(RayTracing, vtkm::ListTagBase<vtkm::Float32>());
return 0; return 0;
} }

@ -32,6 +32,7 @@
#include "Benchmarker.h" #include "Benchmarker.h"
#include <vtkm/cont/testing/Testing.h> #include <vtkm/cont/testing/Testing.h>
#include <cctype>
#include <random> #include <random>
#include <string> #include <string>
@ -470,7 +471,9 @@ int main(int argc, char* argv[])
for (int i = 1; i < argc; ++i) for (int i = 1; i < argc; ++i)
{ {
std::string arg = argv[i]; std::string arg = argv[i];
std::transform(arg.begin(), arg.end(), arg.begin(), ::tolower); std::transform(arg.begin(), arg.end(), arg.begin(), [](char c) {
return static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
});
if (arg == "celltopoint") if (arg == "celltopoint")
{ {
benchmarks |= vtkm::benchmarking::CELL_TO_POINT; benchmarks |= vtkm::benchmarking::CELL_TO_POINT;

@ -1,935 +0,0 @@
/*
Formatting library for C++
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "format.h"
#include <string.h>
#include <cctype>
#include <cerrno>
#include <climits>
#include <cmath>
#include <cstdarg>
#include <cstddef> // for std::ptrdiff_t
#if defined(_WIN32) && defined(__MINGW32__)
# include <cstring>
#endif
#if FMT_USE_WINDOWS_H
# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
# include <windows.h>
# else
# define NOMINMAX
# include <windows.h>
# undef NOMINMAX
# endif
#endif
using fmt::internal::Arg;
#if FMT_EXCEPTIONS
# define FMT_TRY try
# define FMT_CATCH(x) catch (x)
#else
# define FMT_TRY if (true)
# define FMT_CATCH(x) if (false)
#endif
#ifdef _MSC_VER
# pragma warning(push)
# pragma warning(disable: 4127) // conditional expression is constant
# pragma warning(disable: 4702) // unreachable code
// Disable deprecation warning for strerror. The latter is not called but
// MSVC fails to detect it.
# pragma warning(disable: 4996)
#endif
// Dummy implementations of strerror_r and strerror_s called if corresponding
// system functions are not available.
static inline fmt::internal::Null<> strerror_r(int, char *, ...) {
return fmt::internal::Null<>();
}
static inline fmt::internal::Null<> strerror_s(char *, std::size_t, ...) {
return fmt::internal::Null<>();
}
namespace fmt {
namespace {
#ifndef _MSC_VER
# define FMT_SNPRINTF snprintf
#else // _MSC_VER
inline int fmt_snprintf(char *buffer, size_t size, const char *format, ...) {
va_list args;
va_start(args, format);
int result = vsnprintf_s(buffer, size, _TRUNCATE, format, args);
va_end(args);
return result;
}
# define FMT_SNPRINTF fmt_snprintf
#endif // _MSC_VER
#if defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
# define FMT_SWPRINTF snwprintf
#else
# define FMT_SWPRINTF swprintf
#endif // defined(_WIN32) && defined(__MINGW32__) && !defined(__NO_ISOCEXT)
// Checks if a value fits in int - used to avoid warnings about comparing
// signed and unsigned integers.
template <bool IsSigned>
struct IntChecker {
template <typename T>
static bool fits_in_int(T value) {
unsigned max = INT_MAX;
return value <= max;
}
static bool fits_in_int(bool) { return true; }
};
template <>
struct IntChecker<true> {
template <typename T>
static bool fits_in_int(T value) {
return value >= INT_MIN && value <= INT_MAX;
}
static bool fits_in_int(int) { return true; }
};
const char RESET_COLOR[] = "\x1b[0m";
typedef void (*FormatFunc)(Writer &, int, StringRef);
// Portable thread-safe version of strerror.
// Sets buffer to point to a string describing the error code.
// This can be either a pointer to a string stored in buffer,
// or a pointer to some static immutable string.
// Returns one of the following values:
// 0 - success
// ERANGE - buffer is not large enough to store the error message
// other - failure
// Buffer should be at least of size 1.
int safe_strerror(
int error_code, char *&buffer, std::size_t buffer_size) FMT_NOEXCEPT {
FMT_ASSERT(buffer != 0 && buffer_size != 0, "invalid buffer");
class StrError {
private:
int error_code_;
char *&buffer_;
std::size_t buffer_size_;
// A noop assignment operator to avoid bogus warnings.
void operator=(const StrError &) {}
// Handle the result of XSI-compliant version of strerror_r.
int handle(int result) {
// glibc versions before 2.13 return result in errno.
return result == -1 ? errno : result;
}
// Handle the result of GNU-specific version of strerror_r.
int handle(char *message) {
// If the buffer is full then the message is probably truncated.
if (message == buffer_ && strlen(buffer_) == buffer_size_ - 1)
return ERANGE;
buffer_ = message;
return 0;
}
// Handle the case when strerror_r is not available.
int handle(internal::Null<>) {
return fallback(strerror_s(buffer_, buffer_size_, error_code_));
}
// Fallback to strerror_s when strerror_r is not available.
int fallback(int result) {
// If the buffer is full then the message is probably truncated.
return result == 0 && strlen(buffer_) == buffer_size_ - 1 ?
ERANGE : result;
}
// Fallback to strerror if strerror_r and strerror_s are not available.
int fallback(internal::Null<>) {
errno = 0;
buffer_ = strerror(error_code_);
return errno;
}
public:
StrError(int err_code, char *&buf, std::size_t buf_size)
: error_code_(err_code), buffer_(buf), buffer_size_(buf_size) {}
int run() {
strerror_r(0, 0, ""); // Suppress a warning about unused strerror_r.
return handle(strerror_r(error_code_, buffer_, buffer_size_));
}
};
return StrError(error_code, buffer, buffer_size).run();
}
void format_error_code(Writer &out, int error_code,
StringRef message) FMT_NOEXCEPT {
// Report error code making sure that the output fits into
// INLINE_BUFFER_SIZE to avoid dynamic memory allocation and potential
// bad_alloc.
out.clear();
static const char SEP[] = ": ";
static const char ERROR_STR[] = "error ";
// Subtract 2 to account for terminating null characters in SEP and ERROR_STR.
std::size_t error_code_size = sizeof(SEP) + sizeof(ERROR_STR) - 2;
typedef internal::IntTraits<int>::MainType MainType;
MainType abs_value = static_cast<MainType>(error_code);
if (internal::is_negative(error_code)) {
abs_value = 0 - abs_value;
++error_code_size;
}
error_code_size += internal::count_digits(abs_value);
if (message.size() <= internal::INLINE_BUFFER_SIZE - error_code_size)
out << message << SEP;
out << ERROR_STR << error_code;
assert(out.size() <= internal::INLINE_BUFFER_SIZE);
}
void report_error(FormatFunc func, int error_code,
StringRef message) FMT_NOEXCEPT {
MemoryWriter full_message;
func(full_message, error_code, message);
// Use Writer::data instead of Writer::c_str to avoid potential memory
// allocation.
std::fwrite(full_message.data(), full_message.size(), 1, stderr);
std::fputc('\n', stderr);
}
// IsZeroInt::visit(arg) returns true iff arg is a zero integer.
class IsZeroInt : public ArgVisitor<IsZeroInt, bool> {
public:
template <typename T>
bool visit_any_int(T value) { return value == 0; }
};
// Checks if an argument is a valid printf width specifier and sets
// left alignment if it is negative.
class WidthHandler : public ArgVisitor<WidthHandler, unsigned> {
private:
FormatSpec &spec_;
FMT_DISALLOW_COPY_AND_ASSIGN(WidthHandler);
public:
explicit WidthHandler(FormatSpec &spec) : spec_(spec) {}
void report_unhandled_arg() {
FMT_THROW(FormatError("width is not integer"));
}
template <typename T>
unsigned visit_any_int(T value) {
typedef typename internal::IntTraits<T>::MainType UnsignedType;
UnsignedType width = static_cast<UnsignedType>(value);
if (internal::is_negative(value)) {
spec_.align_ = ALIGN_LEFT;
width = 0 - width;
}
if (width > INT_MAX)
FMT_THROW(FormatError("number is too big"));
return static_cast<unsigned>(width);
}
};
class PrecisionHandler : public ArgVisitor<PrecisionHandler, int> {
public:
void report_unhandled_arg() {
FMT_THROW(FormatError("precision is not integer"));
}
template <typename T>
int visit_any_int(T value) {
if (!IntChecker<std::numeric_limits<T>::is_signed>::fits_in_int(value))
FMT_THROW(FormatError("number is too big"));
return static_cast<int>(value);
}
};
template <typename T, typename U>
struct is_same {
enum { value = 0 };
};
template <typename T>
struct is_same<T, T> {
enum { value = 1 };
};
// An argument visitor that converts an integer argument to T for printf,
// if T is an integral type. If T is void, the argument is converted to
// corresponding signed or unsigned type depending on the type specifier:
// 'd' and 'i' - signed, other - unsigned)
template <typename T = void>
class ArgConverter : public ArgVisitor<ArgConverter<T>, void> {
private:
internal::Arg &arg_;
wchar_t type_;
FMT_DISALLOW_COPY_AND_ASSIGN(ArgConverter);
public:
ArgConverter(internal::Arg &arg, wchar_t type)
: arg_(arg), type_(type) {}
void visit_bool(bool value) {
if (type_ != 's')
visit_any_int(value);
}
template <typename U>
void visit_any_int(U value) {
bool is_signed = type_ == 'd' || type_ == 'i';
using internal::Arg;
typedef typename internal::Conditional<
is_same<T, void>::value, U, T>::type TargetType;
if (sizeof(TargetType) <= sizeof(int)) {
// Extra casts are used to silence warnings.
if (is_signed) {
arg_.type = Arg::INT;
arg_.int_value = static_cast<int>(static_cast<TargetType>(value));
} else {
arg_.type = Arg::UINT;
typedef typename internal::MakeUnsigned<TargetType>::Type Unsigned;
arg_.uint_value = static_cast<unsigned>(static_cast<Unsigned>(value));
}
} else {
if (is_signed) {
arg_.type = Arg::LONG_LONG;
// glibc's printf doesn't sign extend arguments of smaller types:
// std::printf("%lld", -42); // prints "4294967254"
// but we don't have to do the same because it's a UB.
arg_.long_long_value = static_cast<LongLong>(value);
} else {
arg_.type = Arg::ULONG_LONG;
arg_.ulong_long_value =
static_cast<typename internal::MakeUnsigned<U>::Type>(value);
}
}
}
};
// Converts an integer argument to char for printf.
class CharConverter : public ArgVisitor<CharConverter, void> {
private:
internal::Arg &arg_;
FMT_DISALLOW_COPY_AND_ASSIGN(CharConverter);
public:
explicit CharConverter(internal::Arg &arg) : arg_(arg) {}
template <typename T>
void visit_any_int(T value) {
arg_.type = internal::Arg::CHAR;
arg_.int_value = static_cast<char>(value);
}
};
} // namespace
namespace internal {
template <typename Char>
class PrintfArgFormatter :
public ArgFormatterBase<PrintfArgFormatter<Char>, Char> {
void write_null_pointer() {
this->spec().type_ = 0;
this->write("(nil)");
}
typedef ArgFormatterBase<PrintfArgFormatter<Char>, Char> Base;
public:
PrintfArgFormatter(BasicWriter<Char> &w, FormatSpec &s)
: ArgFormatterBase<PrintfArgFormatter<Char>, Char>(w, s) {}
void visit_bool(bool value) {
FormatSpec &fmt_spec = this->spec();
if (fmt_spec.type_ != 's')
return this->visit_any_int(value);
fmt_spec.type_ = 0;
this->write(value);
}
void visit_char(int value) {
const FormatSpec &fmt_spec = this->spec();
BasicWriter<Char> &w = this->writer();
if (fmt_spec.type_ && fmt_spec.type_ != 'c')
w.write_int(value, fmt_spec);
typedef typename BasicWriter<Char>::CharPtr CharPtr;
CharPtr out = CharPtr();
if (fmt_spec.width_ > 1) {
Char fill = ' ';
out = w.grow_buffer(fmt_spec.width_);
if (fmt_spec.align_ != ALIGN_LEFT) {
std::fill_n(out, fmt_spec.width_ - 1, fill);
out += fmt_spec.width_ - 1;
} else {
std::fill_n(out + 1, fmt_spec.width_ - 1, fill);
}
} else {
out = w.grow_buffer(1);
}
*out = static_cast<Char>(value);
}
void visit_cstring(const char *value) {
if (value)
Base::visit_cstring(value);
else if (this->spec().type_ == 'p')
write_null_pointer();
else
this->write("(null)");
}
void visit_pointer(const void *value) {
if (value)
return Base::visit_pointer(value);
this->spec().type_ = 0;
write_null_pointer();
}
void visit_custom(Arg::CustomValue c) {
BasicFormatter<Char> formatter(ArgList(), this->writer());
const Char format_str[] = {'}', 0};
const Char *format = format_str;
c.format(&formatter, c.value, &format);
}
};
} // namespace internal
} // namespace fmt
FMT_FUNC void fmt::SystemError::init(
int err_code, CStringRef format_str, ArgList args) {
error_code_ = err_code;
MemoryWriter w;
internal::format_system_error(w, err_code, format(format_str, args));
std::runtime_error &base = *this;
base = std::runtime_error(w.str());
}
template <typename T>
int fmt::internal::CharTraits<char>::format_float(
char *buffer, std::size_t size, const char *format,
unsigned width, int precision, T value) {
if (width == 0) {
return precision < 0 ?
FMT_SNPRINTF(buffer, size, format, value) :
FMT_SNPRINTF(buffer, size, format, precision, value);
}
return precision < 0 ?
FMT_SNPRINTF(buffer, size, format, width, value) :
FMT_SNPRINTF(buffer, size, format, width, precision, value);
}
template <typename T>
int fmt::internal::CharTraits<wchar_t>::format_float(
wchar_t *buffer, std::size_t size, const wchar_t *format,
unsigned width, int precision, T value) {
if (width == 0) {
return precision < 0 ?
FMT_SWPRINTF(buffer, size, format, value) :
FMT_SWPRINTF(buffer, size, format, precision, value);
}
return precision < 0 ?
FMT_SWPRINTF(buffer, size, format, width, value) :
FMT_SWPRINTF(buffer, size, format, width, precision, value);
}
template <typename T>
const char fmt::internal::BasicData<T>::DIGITS[] =
"0001020304050607080910111213141516171819"
"2021222324252627282930313233343536373839"
"4041424344454647484950515253545556575859"
"6061626364656667686970717273747576777879"
"8081828384858687888990919293949596979899";
#define FMT_POWERS_OF_10(factor) \
factor * 10, \
factor * 100, \
factor * 1000, \
factor * 10000, \
factor * 100000, \
factor * 1000000, \
factor * 10000000, \
factor * 100000000, \
factor * 1000000000
template <typename T>
const uint32_t fmt::internal::BasicData<T>::POWERS_OF_10_32[] = {
0, FMT_POWERS_OF_10(1)
};
template <typename T>
const uint64_t fmt::internal::BasicData<T>::POWERS_OF_10_64[] = {
0,
FMT_POWERS_OF_10(1),
FMT_POWERS_OF_10(fmt::ULongLong(1000000000)),
// Multiply several constants instead of using a single long long constant
// to avoid warnings about C++98 not supporting long long.
fmt::ULongLong(1000000000) * fmt::ULongLong(1000000000) * 10
};
FMT_FUNC void fmt::internal::report_unknown_type(char code, const char *type) {
(void)type;
if (std::isprint(static_cast<unsigned char>(code))) {
FMT_THROW(fmt::FormatError(
fmt::format("unknown format code '{}' for {}", code, type)));
}
FMT_THROW(fmt::FormatError(
fmt::format("unknown format code '\\x{:02x}' for {}",
static_cast<unsigned>(code), type)));
}
#if FMT_USE_WINDOWS_H
FMT_FUNC fmt::internal::UTF8ToUTF16::UTF8ToUTF16(fmt::StringRef s) {
static const char ERROR_MSG[] = "cannot convert string from UTF-8 to UTF-16";
if (s.size() > INT_MAX)
FMT_THROW(WindowsError(ERROR_INVALID_PARAMETER, ERROR_MSG));
int s_size = static_cast<int>(s.size());
int length = MultiByteToWideChar(
CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, 0, 0);
if (length == 0)
FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
buffer_.resize(length + 1);
length = MultiByteToWideChar(
CP_UTF8, MB_ERR_INVALID_CHARS, s.data(), s_size, &buffer_[0], length);
if (length == 0)
FMT_THROW(WindowsError(GetLastError(), ERROR_MSG));
buffer_[length] = 0;
}
FMT_FUNC fmt::internal::UTF16ToUTF8::UTF16ToUTF8(fmt::WStringRef s) {
if (int error_code = convert(s)) {
FMT_THROW(WindowsError(error_code,
"cannot convert string from UTF-16 to UTF-8"));
}
}
FMT_FUNC int fmt::internal::UTF16ToUTF8::convert(fmt::WStringRef s) {
if (s.size() > INT_MAX)
return ERROR_INVALID_PARAMETER;
int s_size = static_cast<int>(s.size());
int length = WideCharToMultiByte(CP_UTF8, 0, s.data(), s_size, 0, 0, 0, 0);
if (length == 0)
return GetLastError();
buffer_.resize(length + 1);
length = WideCharToMultiByte(
CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, 0, 0);
if (length == 0)
return GetLastError();
buffer_[length] = 0;
return 0;
}
FMT_FUNC void fmt::WindowsError::init(
int err_code, CStringRef format_str, ArgList args) {
error_code_ = err_code;
MemoryWriter w;
internal::format_windows_error(w, err_code, format(format_str, args));
std::runtime_error &base = *this;
base = std::runtime_error(w.str());
}
FMT_FUNC void fmt::internal::format_windows_error(
fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT {
FMT_TRY {
MemoryBuffer<wchar_t, INLINE_BUFFER_SIZE> buffer;
buffer.resize(INLINE_BUFFER_SIZE);
for (;;) {
wchar_t *system_message = &buffer[0];
int result = FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
0, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
system_message, static_cast<uint32_t>(buffer.size()), 0);
if (result != 0) {
UTF16ToUTF8 utf8_message;
if (utf8_message.convert(system_message) == ERROR_SUCCESS) {
out << message << ": " << utf8_message;
return;
}
break;
}
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER)
break; // Can't get error message, report error code instead.
buffer.resize(buffer.size() * 2);
}
} FMT_CATCH(...) {}
fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
}
#endif // FMT_USE_WINDOWS_H
FMT_FUNC void fmt::internal::format_system_error(
fmt::Writer &out, int error_code,
fmt::StringRef message) FMT_NOEXCEPT {
FMT_TRY {
MemoryBuffer<char, INLINE_BUFFER_SIZE> buffer;
buffer.resize(INLINE_BUFFER_SIZE);
for (;;) {
char *system_message = &buffer[0];
int result = safe_strerror(error_code, system_message, buffer.size());
if (result == 0) {
out << message << ": " << system_message;
return;
}
if (result != ERANGE)
break; // Can't get error message, report error code instead.
buffer.resize(buffer.size() * 2);
}
} FMT_CATCH(...) {}
fmt::format_error_code(out, error_code, message); // 'fmt::' is for bcc32.
}
template <typename Char>
void fmt::internal::ArgMap<Char>::init(const ArgList &args) {
if (!map_.empty())
return;
typedef internal::NamedArg<Char> NamedArg;
const NamedArg *named_arg = 0;
bool use_values =
args.type(ArgList::MAX_PACKED_ARGS - 1) == internal::Arg::NONE;
if (use_values) {
for (unsigned i = 0;/*nothing*/; ++i) {
internal::Arg::Type arg_type = args.type(i);
switch (arg_type) {
case internal::Arg::NONE:
return;
case internal::Arg::NAMED_ARG:
named_arg = static_cast<const NamedArg*>(args.values_[i].pointer);
map_.push_back(Pair(named_arg->name, *named_arg));
break;
default:
/*nothing*/;
}
}
return;
}
for (unsigned i = 0; i != ArgList::MAX_PACKED_ARGS; ++i) {
internal::Arg::Type arg_type = args.type(i);
if (arg_type == internal::Arg::NAMED_ARG) {
named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
map_.push_back(Pair(named_arg->name, *named_arg));
}
}
for (unsigned i = ArgList::MAX_PACKED_ARGS;/*nothing*/; ++i) {
switch (args.args_[i].type) {
case internal::Arg::NONE:
return;
case internal::Arg::NAMED_ARG:
named_arg = static_cast<const NamedArg*>(args.args_[i].pointer);
map_.push_back(Pair(named_arg->name, *named_arg));
break;
default:
/*nothing*/;
}
}
}
template <typename Char>
void fmt::internal::FixedBuffer<Char>::grow(std::size_t) {
FMT_THROW(std::runtime_error("buffer overflow"));
}
FMT_FUNC Arg fmt::internal::FormatterBase::do_get_arg(
unsigned arg_index, const char *&error) {
Arg arg = args_[arg_index];
switch (arg.type) {
case Arg::NONE:
error = "argument index out of range";
break;
case Arg::NAMED_ARG:
arg = *static_cast<const internal::Arg*>(arg.pointer);
break;
default:
/*nothing*/;
}
return arg;
}
template <typename Char>
void fmt::internal::PrintfFormatter<Char>::parse_flags(
FormatSpec &spec, const Char *&s) {
for (;;) {
switch (*s++) {
case '-':
spec.align_ = ALIGN_LEFT;
break;
case '+':
spec.flags_ |= SIGN_FLAG | PLUS_FLAG;
break;
case '0':
spec.fill_ = '0';
break;
case ' ':
spec.flags_ |= SIGN_FLAG;
break;
case '#':
spec.flags_ |= HASH_FLAG;
break;
default:
--s;
return;
}
}
}
template <typename Char>
Arg fmt::internal::PrintfFormatter<Char>::get_arg(
const Char *s, unsigned arg_index) {
(void)s;
const char *error = 0;
Arg arg = arg_index == UINT_MAX ?
next_arg(error) : FormatterBase::get_arg(arg_index - 1, error);
if (error)
FMT_THROW(FormatError(!*s ? "invalid format string" : error));
return arg;
}
template <typename Char>
unsigned fmt::internal::PrintfFormatter<Char>::parse_header(
const Char *&s, FormatSpec &spec) {
unsigned arg_index = UINT_MAX;
Char c = *s;
if (c >= '0' && c <= '9') {
// Parse an argument index (if followed by '$') or a width possibly
// preceded with '0' flag(s).
unsigned value = parse_nonnegative_int(s);
if (*s == '$') { // value is an argument index
++s;
arg_index = value;
} else {
if (c == '0')
spec.fill_ = '0';
if (value != 0) {
// Nonzero value means that we parsed width and don't need to
// parse it or flags again, so return now.
spec.width_ = value;
return arg_index;
}
}
}
parse_flags(spec, s);
// Parse width.
if (*s >= '0' && *s <= '9') {
spec.width_ = parse_nonnegative_int(s);
} else if (*s == '*') {
++s;
spec.width_ = WidthHandler(spec).visit(get_arg(s));
}
return arg_index;
}
template <typename Char>
void fmt::internal::PrintfFormatter<Char>::format(
BasicWriter<Char> &writer, BasicCStringRef<Char> format_str) {
const Char *start = format_str.c_str();
const Char *s = start;
while (*s) {
Char c = *s++;
if (c != '%') continue;
if (*s == c) {
write(writer, start, s);
start = ++s;
continue;
}
write(writer, start, s - 1);
FormatSpec spec;
spec.align_ = ALIGN_RIGHT;
// Parse argument index, flags and width.
unsigned arg_index = parse_header(s, spec);
// Parse precision.
if (*s == '.') {
++s;
if ('0' <= *s && *s <= '9') {
spec.precision_ = static_cast<int>(parse_nonnegative_int(s));
} else if (*s == '*') {
++s;
spec.precision_ = PrecisionHandler().visit(get_arg(s));
}
}
Arg arg = get_arg(s, arg_index);
if (spec.flag(HASH_FLAG) && IsZeroInt().visit(arg))
spec.flags_ &= ~to_unsigned<int>(HASH_FLAG);
if (spec.fill_ == '0') {
if (arg.type <= Arg::LAST_NUMERIC_TYPE)
spec.align_ = ALIGN_NUMERIC;
else
spec.fill_ = ' '; // Ignore '0' flag for non-numeric types.
}
// Parse length and convert the argument to the required type.
switch (*s++) {
case 'h':
if (*s == 'h')
ArgConverter<signed char>(arg, *++s).visit(arg);
else
ArgConverter<short>(arg, *s).visit(arg);
break;
case 'l':
if (*s == 'l')
ArgConverter<fmt::LongLong>(arg, *++s).visit(arg);
else
ArgConverter<long>(arg, *s).visit(arg);
break;
case 'j':
ArgConverter<intmax_t>(arg, *s).visit(arg);
break;
case 'z':
ArgConverter<std::size_t>(arg, *s).visit(arg);
break;
case 't':
ArgConverter<std::ptrdiff_t>(arg, *s).visit(arg);
break;
case 'L':
// printf produces garbage when 'L' is omitted for long double, no
// need to do the same.
break;
default:
--s;
ArgConverter<void>(arg, *s).visit(arg);
}
// Parse type.
if (!*s)
FMT_THROW(FormatError("invalid format string"));
spec.type_ = static_cast<char>(*s++);
if (arg.type <= Arg::LAST_INTEGER_TYPE) {
// Normalize type.
switch (spec.type_) {
case 'i': case 'u':
spec.type_ = 'd';
break;
case 'c':
// TODO: handle wchar_t
CharConverter(arg).visit(arg);
break;
}
}
start = s;
// Format argument.
internal::PrintfArgFormatter<Char>(writer, spec).visit(arg);
}
write(writer, start, s);
}
FMT_FUNC void fmt::report_system_error(
int error_code, fmt::StringRef message) FMT_NOEXCEPT {
// 'fmt::' is for bcc32.
fmt::report_error(internal::format_system_error, error_code, message);
}
#if FMT_USE_WINDOWS_H
FMT_FUNC void fmt::report_windows_error(
int error_code, fmt::StringRef message) FMT_NOEXCEPT {
// 'fmt::' is for bcc32.
fmt::report_error(internal::format_windows_error, error_code, message);
}
#endif
FMT_FUNC void fmt::print(std::FILE *f, CStringRef format_str, ArgList args) {
MemoryWriter w;
w.write(format_str, args);
std::fwrite(w.data(), 1, w.size(), f);
}
FMT_FUNC void fmt::print(CStringRef format_str, ArgList args) {
print(stdout, format_str, args);
}
FMT_FUNC void fmt::print_colored(Color c, CStringRef format, ArgList args) {
char escape[] = "\x1b[30m";
escape[3] = static_cast<char>('0' + c);
std::fputs(escape, stdout);
print(format, args);
std::fputs(RESET_COLOR, stdout);
}
FMT_FUNC int fmt::fprintf(std::FILE *f, CStringRef format, ArgList args) {
MemoryWriter w;
printf(w, format, args);
std::size_t size = w.size();
return std::fwrite(w.data(), 1, size, f) < size ? -1 : static_cast<int>(size);
}
#ifndef FMT_HEADER_ONLY
template struct fmt::internal::BasicData<void>;
// Explicit instantiations for char.
template void fmt::internal::FixedBuffer<char>::grow(std::size_t);
template void fmt::internal::ArgMap<char>::init(const fmt::ArgList &args);
template void fmt::internal::PrintfFormatter<char>::format(
BasicWriter<char> &writer, CStringRef format);
template int fmt::internal::CharTraits<char>::format_float(
char *buffer, std::size_t size, const char *format,
unsigned width, int precision, double value);
template int fmt::internal::CharTraits<char>::format_float(
char *buffer, std::size_t size, const char *format,
unsigned width, int precision, long double value);
// Explicit instantiations for wchar_t.
template void fmt::internal::FixedBuffer<wchar_t>::grow(std::size_t);
template void fmt::internal::ArgMap<wchar_t>::init(const fmt::ArgList &args);
template void fmt::internal::PrintfFormatter<wchar_t>::format(
BasicWriter<wchar_t> &writer, WCStringRef format);
template int fmt::internal::CharTraits<wchar_t>::format_float(
wchar_t *buffer, std::size_t size, const wchar_t *format,
unsigned width, int precision, double value);
template int fmt::internal::CharTraits<wchar_t>::format_float(
wchar_t *buffer, std::size_t size, const wchar_t *format,
unsigned width, int precision, long double value);
#endif // FMT_HEADER_ONLY
#ifdef _MSC_VER
# pragma warning(pop)
#endif

@ -1,61 +0,0 @@
/*
Formatting library for C++ - std::ostream support
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "ostream.h"
namespace fmt {
namespace {
// Write the content of w to os.
void write(std::ostream &os, Writer &w) {
const char *data = w.data();
typedef internal::MakeUnsigned<std::streamsize>::Type UnsignedStreamSize;
UnsignedStreamSize size = w.size();
UnsignedStreamSize max_size =
internal::to_unsigned((std::numeric_limits<std::streamsize>::max)());
do {
UnsignedStreamSize n = size <= max_size ? size : max_size;
os.write(data, static_cast<std::streamsize>(n));
data += n;
size -= n;
} while (size != 0);
}
}
FMT_FUNC void print(std::ostream &os, CStringRef format_str, ArgList args) {
MemoryWriter w;
w.write(format_str, args);
write(os, w);
}
FMT_FUNC int fprintf(std::ostream &os, CStringRef format, ArgList args) {
MemoryWriter w;
printf(w, format, args);
write(os, w);
return static_cast<int>(w.size());
}
} // namespace fmt

@ -1,133 +0,0 @@
/*
Formatting library for C++ - std::ostream support
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef FMT_OSTREAM_H_
#define FMT_OSTREAM_H_
#include "format.h"
#include <ostream>
namespace fmt {
namespace internal {
template <class Char>
class FormatBuf : public std::basic_streambuf<Char> {
private:
typedef typename std::basic_streambuf<Char>::int_type int_type;
typedef typename std::basic_streambuf<Char>::traits_type traits_type;
Buffer<Char> &buffer_;
Char *start_;
public:
FormatBuf(Buffer<Char> &buffer) : buffer_(buffer), start_(&buffer[0]) {
this->setp(start_, start_ + buffer_.capacity());
}
int_type overflow(int_type ch = traits_type::eof()) {
if (!traits_type::eq_int_type(ch, traits_type::eof())) {
size_t buf_size = size();
buffer_.resize(buf_size);
buffer_.reserve(buf_size * 2);
start_ = &buffer_[0];
start_[buf_size] = traits_type::to_char_type(ch);
this->setp(start_+ buf_size + 1, start_ + buf_size * 2);
}
return ch;
}
size_t size() const {
return to_unsigned(this->pptr() - start_);
}
};
Yes &convert(std::ostream &);
struct DummyStream : std::ostream {
DummyStream(); // Suppress a bogus warning in MSVC.
// Hide all operator<< overloads from std::ostream.
void operator<<(Null<>);
};
No &operator<<(std::ostream &, int);
template<typename T>
struct ConvertToIntImpl<T, true> {
// Convert to int only if T doesn't have an overloaded operator<<.
enum {
value = sizeof(convert(get<DummyStream>() << get<T>())) == sizeof(No)
};
};
} // namespace internal
// Formats a value.
template <typename Char, typename ArgFormatter_, typename T>
void format(BasicFormatter<Char, ArgFormatter_> &f,
const Char *&format_str, const T &value) {
internal::MemoryBuffer<Char, internal::INLINE_BUFFER_SIZE> buffer;
internal::FormatBuf<Char> format_buf(buffer);
std::basic_ostream<Char> output(&format_buf);
output << value;
BasicStringRef<Char> str(&buffer[0], format_buf.size());
typedef internal::MakeArg< BasicFormatter<Char> > MakeArg;
format_str = f.format(format_str, MakeArg(str));
}
/**
\rst
Prints formatted data to the stream *os*.
**Example**::
print(cerr, "Don't {}!", "panic");
\endrst
*/
FMT_API void print(std::ostream &os, CStringRef format_str, ArgList args);
FMT_VARIADIC(void, print, std::ostream &, CStringRef)
/**
\rst
Prints formatted data to the stream *os*.
**Example**::
fprintf(cerr, "Don't %s!", "panic");
\endrst
*/
FMT_API int fprintf(std::ostream &os, CStringRef format_str, ArgList args);
FMT_VARIADIC(int, fprintf, std::ostream &, CStringRef)
} // namespace fmt
#ifdef FMT_HEADER_ONLY
# include "ostream.cc"
#endif
#endif // FMT_OSTREAM_H_

@ -104,14 +104,11 @@ int main(int argc, char* argv[])
output.AddCellSet(outputCellSet); output.AddCellSet(outputCellSet);
auto inCoords = input.GetCoordinateSystem(0).GetData();
timer.Reset(); timer.Reset();
vtkm::cont::DynamicArrayHandle coords; auto outCoords = clip.ProcessCellField(inCoords, DeviceAdapter());
{
FieldMapper<DeviceAdapter> coordMapper(coords, clip, false);
input.GetCoordinateSystem(0).GetData().CastAndCall(coordMapper);
}
vtkm::Float64 processCoordinatesTime = timer.GetElapsedTime(); vtkm::Float64 processCoordinatesTime = timer.GetElapsedTime();
output.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coords)); output.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", outCoords));
timer.Reset(); timer.Reset();
for (vtkm::Id i = 0; i < input.GetNumberOfFields(); ++i) for (vtkm::Id i = 0; i < input.GetNumberOfFields(); ++i)

@ -29,7 +29,6 @@ vtkm_find_gl(OPTIONAL GL GLUT GLEW)
if(TARGET OpenGL::GL AND if(TARGET OpenGL::GL AND
TARGET GLUT::GLUT AND TARGET GLUT::GLUT AND
TARGET GLEW::GLEW) TARGET GLEW::GLEW)
if(TARGET vtkm::cuda) if(TARGET vtkm::cuda)
add_executable(GameOfLife GameOfLife.cu LoadShaders.h) add_executable(GameOfLife GameOfLife.cu LoadShaders.h)
else() else()

@ -23,6 +23,7 @@
#endif #endif
#include <vtkm/Math.h> #include <vtkm/Math.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandle.h> #include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DataSet.h> #include <vtkm/cont/DataSet.h>
#include <vtkm/worklet/DispatcherMapField.h> #include <vtkm/worklet/DispatcherMapField.h>
@ -68,30 +69,6 @@ Quaternion qrot;
int lastx, lasty; int lastx, lasty;
int mouse_state = 1; int mouse_state = 1;
//
// Functor to retrieve vertex locations from the CoordinateSystem
// Actually need a static cast to ArrayHandle from DynamicArrayHandleCoordinateSystem
// but haven't been able to figure out what that is
//
struct GetVertexArray
{
template <typename ArrayHandleType>
VTKM_CONT void operator()(ArrayHandleType array) const
{
this->GetVertexPortal(array.GetPortalConstControl());
}
private:
template <typename PortalType>
VTKM_CONT void GetVertexPortal(const PortalType& portal) const
{
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
{
vertexArray.GetPortalControl().Set(index, portal.Get(index));
}
}
};
// //
// Initialize the OpenGL state // Initialize the OpenGL state
// //
@ -145,16 +122,10 @@ void displayCall()
// Get the cell set, coordinate system and coordinate data // Get the cell set, coordinate system and coordinate data
vtkm::cont::CellSetExplicit<> cellSet; vtkm::cont::CellSetExplicit<> cellSet;
outDataSet.GetCellSet(0).CopyTo(cellSet); outDataSet.GetCellSet(0).CopyTo(cellSet);
const vtkm::cont::DynamicArrayHandleCoordinateSystem& coordArray = auto coordArray = outDataSet.GetCoordinateSystem().GetData();
outDataSet.GetCoordinateSystem().GetData();
vtkm::Id numberOfCells = cellSet.GetNumberOfCells(); vtkm::Id numberOfCells = cellSet.GetNumberOfCells();
vtkm::Id numberOfPoints = coordArray.GetNumberOfValues(); vtkm::cont::ArrayCopy(coordArray, vertexArray);
// Need the actual vertex points from a static cast of the dynamic array but can't get it right
// So use cast and call on a functor that stores that dynamic array into static array we created
vertexArray.Allocate(numberOfPoints);
vtkm::cont::CastAndCall(coordArray, GetVertexArray());
// Each cell is a polyline // Each cell is a polyline
glColor3f(1.0f, 0.0f, 0.0f); glColor3f(1.0f, 0.0f, 0.0f);

@ -52,9 +52,6 @@ namespace
// Takes input uniform grid and outputs unstructured grid of tets // Takes input uniform grid and outputs unstructured grid of tets
static vtkm::cont::DataSet outDataSet; static vtkm::cont::DataSet outDataSet;
// Point location of vertices from a CastAndCall but needs a static cast eventually
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>> vertexArray;
// OpenGL display variables // OpenGL display variables
Quaternion qrot; Quaternion qrot;
int lastx, lasty; int lastx, lasty;
@ -123,30 +120,6 @@ vtkm::cont::DataSet MakeTetrahedralizeExplicitDataSet()
return builder.Create(); return builder.Create();
} }
//
// Functor to retrieve vertex locations from the CoordinateSystem
// Actually need a static cast to ArrayHandle from DynamicArrayHandleCoordinateSystem
// but haven't been able to figure out what that is
//
struct GetVertexArray
{
template <typename ArrayHandleType>
VTKM_CONT void operator()(ArrayHandleType array) const
{
this->GetVertexPortal(array.GetPortalConstControl());
}
private:
template <typename PortalType>
VTKM_CONT void GetVertexPortal(const PortalType& portal) const
{
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
{
vertexArray.GetPortalControl().Set(index, portal.Get(index));
}
}
};
// //
// Initialize the OpenGL state // Initialize the OpenGL state
// //
@ -201,10 +174,7 @@ void displayCall()
outDataSet.GetCellSet(0).CopyTo(cellSet); outDataSet.GetCellSet(0).CopyTo(cellSet);
vtkm::Id numberOfCells = cellSet.GetNumberOfCells(); vtkm::Id numberOfCells = cellSet.GetNumberOfCells();
// Need the actual vertex points from a static cast of the dynamic array but can't get it right auto vertexArray = outDataSet.GetCoordinateSystem().GetData();
// So use cast and call on a functor that stores that dynamic array into static array we created
vertexArray.Allocate(cellSet.GetNumberOfPoints());
vtkm::cont::CastAndCall(outDataSet.GetCoordinateSystem(), GetVertexArray());
// Draw the five tetrahedra belonging to each hexadron // Draw the five tetrahedra belonging to each hexadron
vtkm::Float32 color[5][3] = { { 1.0f, 0.0f, 0.0f }, vtkm::Float32 color[5][3] = { { 1.0f, 0.0f, 0.0f },
@ -223,10 +193,10 @@ void displayCall()
cellSet.GetIndices(tetra, tetIndices); cellSet.GetIndices(tetra, tetIndices);
// Get the vertex points for this tetrahedron // Get the vertex points for this tetrahedron
vtkm::Vec<vtkm::Float64, 3> pt0 = vertexArray.GetPortalConstControl().Get(tetIndices[0]); auto pt0 = vertexArray.GetPortalConstControl().Get(tetIndices[0]);
vtkm::Vec<vtkm::Float64, 3> pt1 = vertexArray.GetPortalConstControl().Get(tetIndices[1]); auto pt1 = vertexArray.GetPortalConstControl().Get(tetIndices[1]);
vtkm::Vec<vtkm::Float64, 3> pt2 = vertexArray.GetPortalConstControl().Get(tetIndices[2]); auto pt2 = vertexArray.GetPortalConstControl().Get(tetIndices[2]);
vtkm::Vec<vtkm::Float64, 3> pt3 = vertexArray.GetPortalConstControl().Get(tetIndices[3]); auto pt3 = vertexArray.GetPortalConstControl().Get(tetIndices[3]);
// Draw the tetrahedron filled with alternating colors // Draw the tetrahedron filled with alternating colors
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@ -323,7 +293,6 @@ int main(int argc, char* argv[])
glutMainLoop(); glutMainLoop();
outDataSet.Clear(); outDataSet.Clear();
vertexArray.ReleaseResources();
return 0; return 0;
} }

@ -52,9 +52,6 @@ static vtkm::Id cellsToDisplay = 64;
// Takes input uniform grid and outputs unstructured grid of tets // Takes input uniform grid and outputs unstructured grid of tets
static vtkm::cont::DataSet tetDataSet; static vtkm::cont::DataSet tetDataSet;
// Point location of vertices from a CastAndCall but needs a static cast eventually
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>> vertexArray;
// OpenGL display variables // OpenGL display variables
static Quaternion qrot; static Quaternion qrot;
static int lastx, lasty; static int lastx, lasty;
@ -87,30 +84,6 @@ vtkm::cont::DataSet MakeTetrahedralizeTestDataSet(vtkm::Id3 dim)
return dataSet; return dataSet;
} }
//
// Functor to retrieve vertex locations from the CoordinateSystem
// Actually need a static cast to ArrayHandle from DynamicArrayHandleCoordinateSystem
// but haven't been able to figure out what that is
//
struct GetVertexArray
{
template <typename ArrayHandleType>
VTKM_CONT void operator()(ArrayHandleType array) const
{
this->GetVertexPortal(array.GetPortalConstControl());
}
private:
template <typename PortalType>
VTKM_CONT void GetVertexPortal(const PortalType& portal) const
{
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
{
vertexArray.GetPortalControl().Set(index, portal.Get(index));
}
}
};
// //
// Initialize the OpenGL state // Initialize the OpenGL state
// //
@ -165,10 +138,7 @@ void displayCall()
vtkm::cont::CellSetSingleType<> cellSet; vtkm::cont::CellSetSingleType<> cellSet;
tetDataSet.GetCellSet(0).CopyTo(cellSet); tetDataSet.GetCellSet(0).CopyTo(cellSet);
// Need the actual vertex points from a static cast of the dynamic array but can't get it right auto vertexArray = tetDataSet.GetCoordinateSystem().GetData();
// So use cast and call on a functor that stores that dynamic array into static array we created
vertexArray.Allocate(cellSet.GetNumberOfPoints());
vtkm::cont::CastAndCall(tetDataSet.GetCoordinateSystem(), GetVertexArray());
// Draw the five tetrahedra belonging to each hexadron // Draw the five tetrahedra belonging to each hexadron
vtkm::Id tetra = 0; vtkm::Id tetra = 0;
@ -190,10 +160,10 @@ void displayCall()
cellSet.GetIndices(tetra, tetIndices); cellSet.GetIndices(tetra, tetIndices);
// Get the vertex points for this tetrahedron // Get the vertex points for this tetrahedron
vtkm::Vec<vtkm::Float64, 3> pt0 = vertexArray.GetPortalConstControl().Get(tetIndices[0]); auto pt0 = vertexArray.GetPortalConstControl().Get(tetIndices[0]);
vtkm::Vec<vtkm::Float64, 3> pt1 = vertexArray.GetPortalConstControl().Get(tetIndices[1]); auto pt1 = vertexArray.GetPortalConstControl().Get(tetIndices[1]);
vtkm::Vec<vtkm::Float64, 3> pt2 = vertexArray.GetPortalConstControl().Get(tetIndices[2]); auto pt2 = vertexArray.GetPortalConstControl().Get(tetIndices[2]);
vtkm::Vec<vtkm::Float64, 3> pt3 = vertexArray.GetPortalConstControl().Get(tetIndices[3]); auto pt3 = vertexArray.GetPortalConstControl().Get(tetIndices[3]);
// Draw the tetrahedron filled with alternating colors // Draw the tetrahedron filled with alternating colors
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
@ -305,7 +275,6 @@ int main(int argc, char* argv[])
glutMainLoop(); glutMainLoop();
tetDataSet.Clear(); tetDataSet.Clear();
vertexArray.ReleaseResources();
return 0; return 0;
} }

@ -50,9 +50,6 @@ namespace
static vtkm::cont::DataSet outDataSet; static vtkm::cont::DataSet outDataSet;
static vtkm::Id numberOfInPoints; static vtkm::Id numberOfInPoints;
// Point location of vertices from a CastAndCall but needs a static cast eventually
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>> vertexArray;
} // anonymous namespace } // anonymous namespace
// //
@ -125,30 +122,6 @@ vtkm::cont::DataSet MakeTriangulateExplicitDataSet()
return builder.Create(); return builder.Create();
} }
//
// Functor to retrieve vertex locations from the CoordinateSystem
// Actually need a static cast to ArrayHandle from DynamicArrayHandleCoordinateSystem
// but haven't been able to figure out what that is
//
struct GetVertexArray
{
template <typename ArrayHandleType>
VTKM_CONT void operator()(ArrayHandleType array) const
{
this->GetVertexPortal(array.GetPortalConstControl());
}
private:
template <typename PortalType>
VTKM_CONT void GetVertexPortal(const PortalType& portal) const
{
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
{
vertexArray.GetPortalControl().Set(index, portal.Get(index));
}
}
};
// //
// Initialize the OpenGL state // Initialize the OpenGL state
// //
@ -173,10 +146,7 @@ void displayCall()
outDataSet.GetCellSet(0).CopyTo(cellSet); outDataSet.GetCellSet(0).CopyTo(cellSet);
vtkm::Id numberOfCells = cellSet.GetNumberOfCells(); vtkm::Id numberOfCells = cellSet.GetNumberOfCells();
// Need the actual vertex points from a static cast of the dynamic array but can't get it right auto vertexArray = outDataSet.GetCoordinateSystem().GetData();
// So use cast and call on a functor that stores that dynamic array into static array we created
vertexArray.Allocate(numberOfInPoints);
vtkm::cont::CastAndCall(outDataSet.GetCoordinateSystem(), GetVertexArray());
// Draw the two triangles belonging to each quad // Draw the two triangles belonging to each quad
vtkm::Float32 color[4][3] = { vtkm::Float32 color[4][3] = {
@ -239,7 +209,6 @@ int main(int argc, char* argv[])
glutMainLoop(); glutMainLoop();
outDataSet.Clear(); outDataSet.Clear();
vertexArray.ReleaseResources();
return 0; return 0;
} }

@ -50,9 +50,6 @@ static vtkm::Id cellsToDisplay = 16;
// Takes input uniform grid and outputs unstructured grid of triangles // Takes input uniform grid and outputs unstructured grid of triangles
static vtkm::cont::DataSet triDataSet; static vtkm::cont::DataSet triDataSet;
// Point location of vertices from a CastAndCall but needs a static cast eventually
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>> vertexArray;
// //
// Construct an input data set with uniform grid of indicated dimensions, origin and spacing // Construct an input data set with uniform grid of indicated dimensions, origin and spacing
// //
@ -78,30 +75,6 @@ vtkm::cont::DataSet MakeTriangulateTestDataSet(vtkm::Id2 dim)
return dataSet; return dataSet;
} }
//
// Functor to retrieve vertex locations from the CoordinateSystem
// Actually need a static cast to ArrayHandle from DynamicArrayHandleCoordinateSystem
// but haven't been able to figure out what that is
//
struct GetVertexArray
{
template <typename ArrayHandleType>
VTKM_CONT void operator()(ArrayHandleType array) const
{
this->GetVertexPortal(array.GetPortalConstControl());
}
private:
template <typename PortalType>
VTKM_CONT void GetVertexPortal(const PortalType& portal) const
{
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
{
vertexArray.GetPortalControl().Set(index, portal.Get(index));
}
}
};
// //
// Initialize the OpenGL state // Initialize the OpenGL state
// //
@ -125,10 +98,7 @@ void displayCall()
vtkm::cont::CellSetSingleType<> cellSet; vtkm::cont::CellSetSingleType<> cellSet;
triDataSet.GetCellSet(0).CopyTo(cellSet); triDataSet.GetCellSet(0).CopyTo(cellSet);
// Need the actual vertex points from a static cast of the dynamic array but can't get it right auto vertexArray = triDataSet.GetCoordinateSystem().GetData();
// So use cast and call on a functor that stores that dynamic array into static array we created
vertexArray.Allocate(cellSet.GetNumberOfPoints());
vtkm::cont::CastAndCall(triDataSet.GetCoordinateSystem(), GetVertexArray());
// Draw the two triangles belonging to each quad // Draw the two triangles belonging to each quad
vtkm::Id triangle = 0; vtkm::Id triangle = 0;
@ -207,7 +177,6 @@ int main(int argc, char* argv[])
glutMainLoop(); glutMainLoop();
triDataSet.Clear(); triDataSet.Clear();
vertexArray.ReleaseResources();
return 0; return 0;
} }

@ -45,6 +45,9 @@ struct Bounds
VTKM_EXEC_CONT VTKM_EXEC_CONT
Bounds() {} Bounds() {}
VTKM_EXEC_CONT
Bounds(const Bounds&) = default;
VTKM_EXEC_CONT VTKM_EXEC_CONT
Bounds(const vtkm::Range& xRange, const vtkm::Range& yRange, const vtkm::Range& zRange) Bounds(const vtkm::Range& xRange, const vtkm::Range& yRange, const vtkm::Range& zRange)
: X(xRange) : X(xRange)
@ -89,13 +92,7 @@ struct Bounds
} }
VTKM_EXEC_CONT VTKM_EXEC_CONT
const vtkm::Bounds& operator=(const vtkm::Bounds& src) vtkm::Bounds& operator=(const vtkm::Bounds& src) = default;
{
this->X = src.X;
this->Y = src.Y;
this->Z = src.Z;
return *this;
}
/// \b Determine if the bounds are valid (i.e. has at least one valid point). /// \b Determine if the bounds are valid (i.e. has at least one valid point).
/// ///

@ -67,6 +67,11 @@ vtkm_declare_headers(${headers})
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
#first add all the components vtkm that are shared between control and exec #first add all the components vtkm that are shared between control and exec
if(VTKm_ENABLE_MPI)
# This `if` is temporary and will be removed once `diy` supports building
# without MPI.
add_subdirectory(thirdparty/diy)
endif()
add_subdirectory(testing) add_subdirectory(testing)
add_subdirectory(internal) add_subdirectory(internal)

File diff suppressed because it is too large Load Diff

@ -108,28 +108,30 @@ static inline VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<
}} }}
'''.format(vtkmname) '''.format(vtkmname)
def unary_math_function_no_vec(vtkmname, sysname, returntype = None): def unary_math_function_no_vec(vtkmname, sysname):
return unary_function(vtkmname, general_type = '''template <typename T>
'T', static inline VTKM_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type {0}(const T& x)
'typename detail::FloatingPointReturnType<T>::Type' if returntype == None else returntype, {{
'VTKM_CUDA_MATH_FUNCTION_64(' + sysname + ')(static_cast<vtkm::Float64>(x))', using RT = typename detail::FloatingPointReturnType<T>::Type;
'std::' + sysname + '(static_cast<vtkm::Float64>(x))', return vtkm::{0}(static_cast<RT>(x));
'template <typename T>', }}
'static inline') + \ '''.format(vtkmname)
unary_function(vtkmname, specialization_types = unary_function(vtkmname,
'vtkm::Float32', 'vtkm::Float32',
'detail::FloatingPointReturnType<vtkm::Float32>::Type' if returntype == None else returntype, 'vtkm::Float32',
'VTKM_CUDA_MATH_FUNCTION_32(' + sysname + ')(x)', 'VTKM_CUDA_MATH_FUNCTION_32(' + sysname + ')(x)',
'std::' + sysname + '(x)', 'std::' + sysname + '(x)',
'template <>', '',
'inline') + \ 'inline')
unary_function(vtkmname, specialization_types += unary_function(vtkmname,
'vtkm::Float64', 'vtkm::Float64',
'detail::FloatingPointReturnType<vtkm::Float64>::Type' if returntype == None else returntype, 'vtkm::Float64',
'VTKM_CUDA_MATH_FUNCTION_64(' + sysname + ')(x)', 'VTKM_CUDA_MATH_FUNCTION_64(' + sysname + ')(x)',
'std::' + sysname + '(x)', 'std::' + sysname + '(x)',
'template <>', '',
'inline') 'inline')
return specialization_types + general_type
def unary_math_function(vtkmname, sysname): def unary_math_function(vtkmname, sysname):
return unary_math_function_no_vec(vtkmname, sysname) + \ return unary_math_function_no_vec(vtkmname, sysname) + \
@ -195,6 +197,7 @@ $extend(unary_template_function_no_vec)\
$extend(binary_math_function)\ $extend(binary_math_function)\
$extend(binary_template_function)\ $extend(binary_template_function)\
\ \
// clang-format off
namespace vtkm namespace vtkm
{ {
@ -235,25 +238,15 @@ static inline VTKM_EXEC_CONT vtkm::Float64 Pi_4()
namespace detail namespace detail
{ {
template <typename T> template <typename T>
struct FloatingPointReturnCondition
: std::enable_if<
std::is_same<typename vtkm::VecTraits<T>::ComponentType, vtkm::Float32>::value ||
std::is_same<typename vtkm::VecTraits<T>::ComponentType, const vtkm::Float32>::value>
{
};
template <typename T, typename = void>
struct FloatingPointReturnType struct FloatingPointReturnType
{ {
using Type = vtkm::Float64; using ctype = typename vtkm::VecTraits<T>::ComponentType;
}; using representable_as_float_type = std::integral_constant<bool,
((sizeof(ctype) < sizeof(float)) || std::is_same<ctype, vtkm::Float32>::value)>;
template <typename T> using Type = typename std::conditional<representable_as_float_type::value,
struct FloatingPointReturnType<T, typename FloatingPointReturnCondition<T>::type> vtkm::Float32,
{ vtkm::Float64>::type;
using Type = vtkm::Float32;
}; };
} // namespace detail } // namespace detail
@ -928,7 +921,12 @@ static inline VTKM_EXEC_CONT vtkm::Float32 RemainderQuotient(vtkm::Float32 numer
QType& quotient) QType& quotient)
{ {
int iQuotient; int iQuotient;
vtkm::Float32 result = std::remquo(numerator, denominator, &iQuotient); #ifdef VTKM_CUDA
const vtkm::Float64 result =
VTKM_CUDA_MATH_FUNCTION_32(remquo)(numerator, denominator, &iQuotient);
#else
const vtkm::Float32 result = std::remquo(numerator, denominator, &iQuotient);
#endif
quotient = iQuotient; quotient = iQuotient;
return result; return result;
} }
@ -938,7 +936,12 @@ static inline VTKM_EXEC_CONT vtkm::Float64 RemainderQuotient(vtkm::Float64 numer
QType& quotient) QType& quotient)
{ {
int iQuotient; int iQuotient;
vtkm::Float64 result = std::remquo(numerator, denominator, &iQuotient); #ifdef VTKM_CUDA
const vtkm::Float64 result =
VTKM_CUDA_MATH_FUNCTION_64(remquo)(numerator, denominator, &iQuotient);
#else
const vtkm::Float64 result = std::remquo(numerator, denominator, &iQuotient);
#endif
quotient = iQuotient; quotient = iQuotient;
return result; return result;
} }
@ -1061,5 +1064,6 @@ static inline VTKM_EXEC_CONT vtkm::Vec<T, N> CopySign(const vtkm::Vec<T, N>& x,
} }
} // namespace vtkm } // namespace vtkm
// clang-format on
#endif //vtk_m_Math_h #endif //vtk_m_Math_h

@ -49,6 +49,9 @@ struct Range
{ {
} }
VTKM_EXEC_CONT
Range(const Range&) = default;
template <typename T1, typename T2> template <typename T1, typename T2>
VTKM_EXEC_CONT Range(const T1& min, const T2& max) VTKM_EXEC_CONT Range(const T1& min, const T2& max)
: Min(static_cast<vtkm::Float64>(min)) : Min(static_cast<vtkm::Float64>(min))
@ -57,12 +60,7 @@ struct Range
} }
VTKM_EXEC_CONT VTKM_EXEC_CONT
const vtkm::Range& operator=(const vtkm::Range& src) vtkm::Range& operator=(const vtkm::Range& src) = default;
{
this->Min = src.Min;
this->Max = src.Max;
return *this;
}
/// \b Determine if the range is valid (i.e. has at least one valid point). /// \b Determine if the range is valid (i.e. has at least one valid point).
/// ///

@ -27,4 +27,20 @@
static_assert((condition), "Failed static assert: " #condition) static_assert((condition), "Failed static assert: " #condition)
#define VTKM_STATIC_ASSERT_MSG(condition, message) static_assert((condition), message) #define VTKM_STATIC_ASSERT_MSG(condition, message) static_assert((condition), message)
namespace vtkm
{
template <bool noError>
struct ReadTheSourceCodeHereForHelpOnThisError;
template <>
struct ReadTheSourceCodeHereForHelpOnThisError<true> : std::true_type
{
};
} // namespace vtkm
#define VTKM_READ_THE_SOURCE_CODE_FOR_HELP(noError) \
VTKM_STATIC_ASSERT(vtkm::ReadTheSourceCodeHereForHelpOnThisError<noError>::value)
#endif //vtk_m_StaticAssert_h #endif //vtk_m_StaticAssert_h

@ -515,22 +515,6 @@ public:
VTKM_EXEC_CONT VTKM_EXEC_CONT
bool operator!=(const DerivedClass& other) const { return !(this->operator==(other)); } bool operator!=(const DerivedClass& other) const { return !(this->operator==(other)); }
VTKM_EXEC_CONT
ComponentType Dot(const VecBaseCommon<ComponentType, DerivedClass>& other) const
{
// Why the static_cast here and below? Because * on small integers (char,
// short) promotes the result to a 32-bit int. After helpfully promoting
// the width of the result, some compilers then warn you about casting it
// back to the type you were expecting in the first place. The static_cast
// suppresses this warning.
ComponentType result = static_cast<ComponentType>(this->Component(0) * other.Component(0));
for (vtkm::IdComponent i = 1; i < this->NumComponents(); ++i)
{
result = static_cast<ComponentType>(result + this->Component(i) * other.Component(i));
}
return result;
}
#if (!(defined(VTKM_CUDA) && (__CUDACC_VER_MAJOR__ < 8))) #if (!(defined(VTKM_CUDA) && (__CUDACC_VER_MAJOR__ < 8)))
#if (defined(VTKM_GCC) || defined(VTKM_CLANG)) #if (defined(VTKM_GCC) || defined(VTKM_CLANG))
#pragma GCC diagnostic push #pragma GCC diagnostic push
@ -1239,46 +1223,85 @@ VTKM_EXEC_CONT static inline vtkm::VecCConst<T> make_VecC(const T* array, vtkm::
return vtkm::VecCConst<T>(array, size); return vtkm::VecCConst<T>(array, size);
} }
// A pre-declaration of vtkm::Pair so that classes templated on them can refer namespace detail
// to it. The actual implementation is in vtkm/Pair.h.
template <typename U, typename V>
struct Pair;
template <typename T, vtkm::IdComponent Size>
static inline VTKM_EXEC_CONT T dot(const vtkm::Vec<T, Size>& a, const vtkm::Vec<T, Size>& b)
{ {
T result = T(a[0] * b[0]); template <typename T>
for (vtkm::IdComponent i = 1; i < Size; ++i) struct DotType
{
//results when < 32bit can be float if somehow we are using float16/float8, otherwise is
// int32 or uint32 depending on if it signed or not.
using float_type = vtkm::Float32;
using integer_type =
typename std::conditional<std::is_signed<T>::value, vtkm::Int32, vtkm::UInt32>::type;
using promote_type =
typename std::conditional<std::is_integral<T>::value, integer_type, float_type>::type;
using type =
typename std::conditional<(sizeof(T) < sizeof(vtkm::Float32)), promote_type, T>::type;
};
template <typename T>
static inline VTKM_EXEC_CONT typename DotType<typename T::ComponentType>::type vec_dot(const T& a,
const T& b)
{
using U = typename DotType<typename T::ComponentType>::type;
U result = a[0] * b[0];
for (vtkm::IdComponent i = 1; i < a.GetNumberOfComponents(); ++i)
{ {
result = T(result + a[i] * b[i]); result = result + a[i] * b[i];
} }
return result; return result;
} }
template <typename T, vtkm::IdComponent Size>
template <typename T> static inline VTKM_EXEC_CONT typename DotType<T>::type vec_dot(const vtkm::Vec<T, Size>& a,
static inline VTKM_EXEC_CONT T dot(const vtkm::Vec<T, 2>& a, const vtkm::Vec<T, 2>& b) const vtkm::Vec<T, Size>& b)
{ {
return T((a[0] * b[0]) + (a[1] * b[1])); using U = typename DotType<T>::type;
U result = a[0] * b[0];
for (vtkm::IdComponent i = 1; i < Size; ++i)
{
result = result + a[i] * b[i];
}
return result;
}
} }
template <typename T> template <typename T>
static inline VTKM_EXEC_CONT T dot(const vtkm::Vec<T, 3>& a, const vtkm::Vec<T, 3>& b) static inline VTKM_EXEC_CONT auto dot(const T& a, const T& b) -> decltype(detail::vec_dot(a, b))
{ {
return T((a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2])); return detail::vec_dot(a, b);
} }
template <typename T> template <typename T>
static inline VTKM_EXEC_CONT T dot(const vtkm::Vec<T, 4>& a, const vtkm::Vec<T, 4>& b) static inline VTKM_EXEC_CONT typename detail::DotType<T>::type dot(const vtkm::Vec<T, 2>& a,
const vtkm::Vec<T, 2>& b)
{ {
return T((a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]) + (a[3] * b[3])); return (a[0] * b[0]) + (a[1] * b[1]);
} }
template <typename T>
template <typename T, typename VecType> static inline VTKM_EXEC_CONT typename detail::DotType<T>::type dot(const vtkm::Vec<T, 3>& a,
static inline VTKM_EXEC_CONT T dot(const vtkm::detail::VecBaseCommon<T, VecType>& a, const vtkm::Vec<T, 3>& b)
const vtkm::detail::VecBaseCommon<T, VecType>& b)
{ {
return a.Dot(b); return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]);
} }
template <typename T>
static inline VTKM_EXEC_CONT typename detail::DotType<T>::type dot(const vtkm::Vec<T, 4>& a,
const vtkm::Vec<T, 4>& b)
{
return (a[0] * b[0]) + (a[1] * b[1]) + (a[2] * b[2]) + (a[3] * b[3]);
}
// Integer types of a width less than an integer get implicitly casted to
// an integer when doing a multiplication.
#define VTK_M_SCALAR_DOT(stype) \
static inline VTKM_EXEC_CONT detail::DotType<stype>::type dot(stype a, stype b) { return a * b; }
VTK_M_SCALAR_DOT(vtkm::Int8)
VTK_M_SCALAR_DOT(vtkm::UInt8)
VTK_M_SCALAR_DOT(vtkm::Int16)
VTK_M_SCALAR_DOT(vtkm::UInt16)
VTK_M_SCALAR_DOT(vtkm::Int32)
VTK_M_SCALAR_DOT(vtkm::UInt32)
VTK_M_SCALAR_DOT(vtkm::Int64)
VTK_M_SCALAR_DOT(vtkm::UInt64)
VTK_M_SCALAR_DOT(vtkm::Float32)
VTK_M_SCALAR_DOT(vtkm::Float64)
template <typename T, vtkm::IdComponent Size> template <typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT T ReduceSum(const vtkm::Vec<T, Size>& a) VTKM_EXEC_CONT T ReduceSum(const vtkm::Vec<T, Size>& a)
@ -1338,22 +1361,10 @@ VTKM_EXEC_CONT T ReduceProduct(const vtkm::Vec<T, 4>& a)
return a[0] * a[1] * a[2] * a[3]; return a[0] * a[1] * a[2] * a[3];
} }
// Integer types of a width less than an integer get implicitly casted to // A pre-declaration of vtkm::Pair so that classes templated on them can refer
// an integer when doing a multiplication. // to it. The actual implementation is in vtkm/Pair.h.
#define VTK_M_INTEGER_PROMOTION_SCALAR_DOT(type) \ template <typename U, typename V>
static inline VTKM_EXEC_CONT type dot(type a, type b) { return static_cast<type>(a * b); } struct Pair;
VTK_M_INTEGER_PROMOTION_SCALAR_DOT(vtkm::Int8)
VTK_M_INTEGER_PROMOTION_SCALAR_DOT(vtkm::UInt8)
VTK_M_INTEGER_PROMOTION_SCALAR_DOT(vtkm::Int16)
VTK_M_INTEGER_PROMOTION_SCALAR_DOT(vtkm::UInt16)
#define VTK_M_SCALAR_DOT(type) \
static inline VTKM_EXEC_CONT type dot(type a, type b) { return a * b; }
VTK_M_SCALAR_DOT(vtkm::Int32)
VTK_M_SCALAR_DOT(vtkm::UInt32)
VTK_M_SCALAR_DOT(vtkm::Int64)
VTK_M_SCALAR_DOT(vtkm::UInt64)
VTK_M_SCALAR_DOT(vtkm::Float32)
VTK_M_SCALAR_DOT(vtkm::Float64)
} // End of namespace vtkm } // End of namespace vtkm

@ -71,9 +71,10 @@ VTKM_EXEC_CONT vtkm::Vec<ValueType, N> Lerp(const vtkm::Vec<ValueType, N>& value
/// when possible. /// when possible.
/// ///
template <typename T> template <typename T>
VTKM_EXEC_CONT typename vtkm::VecTraits<T>::ComponentType MagnitudeSquared(const T& x) VTKM_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type MagnitudeSquared(const T& x)
{ {
return vtkm::dot(x, x); using U = typename detail::FloatingPointReturnType<T>::Type;
return static_cast<U>(vtkm::dot(x, x));
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

@ -19,8 +19,8 @@
// this software. // this software.
// //
//============================================================================= //=============================================================================
#ifndef vtk_m_ArrayHandleConcatenate_h #ifndef vtk_m_cont_ArrayHandleConcatenate_h
#define vtk_m_ArrayHandleConcatenate_h #define vtk_m_cont_ArrayHandleConcatenate_h
#include <vtkm/cont/ArrayHandle.h> #include <vtkm/cont/ArrayHandle.h>
@ -323,4 +323,4 @@ VTKM_CONT ArrayHandleConcatenate<ArrayHandleType1, ArrayHandleType2> make_ArrayH
} }
} // namespace vtkm::cont } // namespace vtkm::cont
#endif //vtk_m_ArrayHandleConcatenate_h #endif //vtk_m_cont_ArrayHandleConcatenate_h

@ -19,8 +19,8 @@
// this software. // this software.
// //
//============================================================================= //=============================================================================
#ifndef vtk_m_ArrayHandlePermutation_h #ifndef vtk_m_cont_ArrayHandlePermutation_h
#define vtk_m_ArrayHandlePermutation_h #define vtk_m_cont_ArrayHandlePermutation_h
#include <vtkm/cont/ArrayHandle.h> #include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ErrorBadType.h> #include <vtkm/cont/ErrorBadType.h>
@ -372,4 +372,4 @@ make_ArrayHandlePermutation(IndexArrayHandleType indexArray, ValueArrayHandleTyp
} }
} // namespace vtkm::cont } // namespace vtkm::cont
#endif //vtk_m_ArrayHandlePermutation_h #endif //vtk_m_cont_ArrayHandlePermutation_h

@ -0,0 +1,579 @@
//============================================================================
// 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.
//============================================================================
#ifndef vtk_m_cont_ArrayHandleVirtualCoordinates_h
#define vtk_m_cont_ArrayHandleVirtualCoordinates_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/VirtualObjectHandle.h>
#include <vtkm/cont/internal/DeviceAdapterListHelpers.h>
#include <vtkm/cont/internal/DynamicTransform.h>
#include <vtkm/VecTraits.h>
#include <vtkm/VirtualObjectBase.h>
#include <memory>
#include <type_traits>
namespace vtkm
{
namespace cont
{
namespace internal
{
//=============================================================================
class VTKM_ALWAYS_EXPORT CoordinatesPortalBase : public VirtualObjectBase
{
public:
VTKM_EXEC_CONT virtual vtkm::Vec<vtkm::FloatDefault, 3> Get(vtkm::Id i) const = 0;
VTKM_EXEC_CONT virtual void Set(vtkm::Id i,
const vtkm::Vec<vtkm::FloatDefault, 3>& val) const = 0;
};
template <typename PortalType, typename ValueType>
class VTKM_ALWAYS_EXPORT CoordinatesPortalImpl : public CoordinatesPortalBase
{
public:
VTKM_CONT CoordinatesPortalImpl() = default;
VTKM_CONT explicit CoordinatesPortalImpl(const PortalType& portal)
: Portal(portal)
{
}
VTKM_CONT void SetPortal(const PortalType& portal) { this->Portal = portal; }
VTKM_EXEC_CONT vtkm::Vec<vtkm::FloatDefault, 3> Get(vtkm::Id i) const override
{
auto val = this->Portal.Get(i);
return { static_cast<vtkm::FloatDefault>(val[0]),
static_cast<vtkm::FloatDefault>(val[1]),
static_cast<vtkm::FloatDefault>(val[2]) };
}
VTKM_EXEC_CONT void Set(vtkm::Id i, const vtkm::Vec<vtkm::FloatDefault, 3>& val) const override
{
using VecType = typename PortalType::ValueType;
using ComponentType = typename vtkm::VecTraits<VecType>::ComponentType;
this->Portal.Set(i,
{ static_cast<ComponentType>(val[0]),
static_cast<ComponentType>(val[1]),
static_cast<ComponentType>(val[2]) });
}
private:
PortalType Portal;
};
template <typename PortalType>
class VTKM_ALWAYS_EXPORT CoordinatesPortalImpl<PortalType, void*> : public CoordinatesPortalBase
{
public:
VTKM_CONT CoordinatesPortalImpl() = default;
VTKM_CONT explicit CoordinatesPortalImpl(const PortalType&) {}
VTKM_CONT void SetPortal(const PortalType&) {}
VTKM_EXEC_CONT vtkm::Vec<vtkm::FloatDefault, 3> Get(vtkm::Id) const override { return {}; }
VTKM_EXEC_CONT void Set(vtkm::Id, const vtkm::Vec<vtkm::FloatDefault, 3>&) const override {}
};
template <typename PortalType>
class VTKM_ALWAYS_EXPORT CoordinatesPortal
: public CoordinatesPortalImpl<PortalType, typename PortalType::ValueType>
{
public:
VTKM_CONT CoordinatesPortal() = default;
VTKM_CONT explicit CoordinatesPortal(const PortalType& portal)
: CoordinatesPortalImpl<PortalType, typename PortalType::ValueType>(portal)
{
}
};
template <typename PortalType>
class VTKM_ALWAYS_EXPORT CoordinatesPortalConst : public CoordinatesPortalBase
{
public:
VTKM_CONT CoordinatesPortalConst() = default;
VTKM_CONT explicit CoordinatesPortalConst(const PortalType& portal)
: Portal(portal)
{
}
VTKM_CONT void SetPortal(const PortalType& portal) { this->Portal = portal; }
VTKM_EXEC_CONT vtkm::Vec<vtkm::FloatDefault, 3> Get(vtkm::Id i) const override
{
auto val = this->Portal.Get(i);
return { static_cast<vtkm::FloatDefault>(val[0]),
static_cast<vtkm::FloatDefault>(val[1]),
static_cast<vtkm::FloatDefault>(val[2]) };
}
VTKM_EXEC_CONT void Set(vtkm::Id, const vtkm::Vec<vtkm::FloatDefault, 3>&) const override {}
private:
PortalType Portal;
};
class VTKM_ALWAYS_EXPORT ArrayPortalVirtualCoordinates
{
public:
using ValueType = vtkm::Vec<vtkm::FloatDefault, 3>;
VTKM_EXEC_CONT ArrayPortalVirtualCoordinates()
: NumberOfValues(0)
, VirtualPortal(nullptr)
{
}
VTKM_EXEC_CONT ArrayPortalVirtualCoordinates(vtkm::Id numberOfValues,
const CoordinatesPortalBase* virtualPortal)
: NumberOfValues(numberOfValues)
, VirtualPortal(virtualPortal)
{
}
VTKM_EXEC_CONT vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }
VTKM_EXEC_CONT ValueType Get(vtkm::Id i) const { return this->VirtualPortal->Get(i); }
VTKM_EXEC_CONT void Set(vtkm::Id i, const ValueType& val) const
{
this->VirtualPortal->Set(i, val);
}
private:
vtkm::Id NumberOfValues;
const CoordinatesPortalBase* VirtualPortal;
};
//=============================================================================
class VTKM_ALWAYS_EXPORT CoordinatesArrayHandleBase
{
public:
using Portal = ArrayPortalVirtualCoordinates;
using PortalConst = ArrayPortalVirtualCoordinates;
virtual ~CoordinatesArrayHandleBase() = default;
VTKM_CONT virtual vtkm::Id GetNumberOfValues() const = 0;
VTKM_CONT virtual Portal GetPortalControl() = 0;
VTKM_CONT virtual PortalConst GetPortalConstControl() = 0;
VTKM_CONT virtual void Allocate(vtkm::Id numberOfValues) = 0;
VTKM_CONT virtual void Shrink(vtkm::Id numberOfValues) = 0;
VTKM_CONT virtual void ReleaseResources() = 0;
VTKM_CONT virtual PortalConst PrepareForInput(vtkm::cont::DeviceAdapterId deviceId) = 0;
VTKM_CONT virtual Portal PrepareForOutput(vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId deviceId) = 0;
VTKM_CONT virtual Portal PrepareForInPlace(vtkm::cont::DeviceAdapterId deviceId) = 0;
};
template <typename ArrayHandleType>
class VTKM_ALWAYS_EXPORT CoordinatesArrayHandleArrayWrapper : public CoordinatesArrayHandleBase
{
public:
VTKM_CONT explicit CoordinatesArrayHandleArrayWrapper(const ArrayHandleType& array)
: Array(array)
{
}
VTKM_CONT const ArrayHandleType& GetArray() const { return this->Array; }
protected:
ArrayHandleType Array;
};
template <typename ArrayHandleType, typename DeviceList>
class VTKM_ALWAYS_EXPORT CoordinatesArrayHandle
: public CoordinatesArrayHandleArrayWrapper<ArrayHandleType>
{
public:
static_assert(std::is_same<DeviceList, vtkm::cont::DeviceAdapterListTagCommon>::value, "error");
using Portal = CoordinatesArrayHandleBase::Portal;
using PortalConst = CoordinatesArrayHandleBase::PortalConst;
VTKM_CONT explicit CoordinatesArrayHandle(const ArrayHandleType& array)
: CoordinatesArrayHandleArrayWrapper<ArrayHandleType>(array)
{
}
VTKM_CONT vtkm::Id GetNumberOfValues() const override { return this->Array.GetNumberOfValues(); }
VTKM_CONT Portal GetPortalControl() override
{
this->ControlPortal.SetPortal(this->Array.GetPortalControl());
return Portal(this->GetNumberOfValues(), &this->ControlPortal);
}
VTKM_CONT PortalConst GetPortalConstControl() override
{
this->ControlConstPortal.SetPortal(this->Array.GetPortalConstControl());
return PortalConst(this->GetNumberOfValues(), &this->ControlConstPortal);
}
VTKM_CONT void Allocate(vtkm::Id numberOfValues) override
{
this->Array.Allocate(numberOfValues);
}
VTKM_CONT void Shrink(vtkm::Id numberOfValues) override { this->Array.Shrink(numberOfValues); }
VTKM_CONT void ReleaseResources() override { this->Array.ReleaseResources(); }
VTKM_CONT PortalConst PrepareForInput(vtkm::cont::DeviceAdapterId deviceId) override
{
PortalConst portal;
vtkm::cont::internal::FindDeviceAdapterTagAndCall(
deviceId, DeviceList(), PrepareForInputFunctor(), this, portal);
return portal;
}
VTKM_CONT Portal PrepareForOutput(vtkm::Id numberOfValues,
vtkm::cont::DeviceAdapterId deviceId) override
{
Portal portal;
vtkm::cont::internal::FindDeviceAdapterTagAndCall(
deviceId, DeviceList(), PrepareForOutputFunctor(), this, numberOfValues, portal);
return portal;
}
VTKM_CONT Portal PrepareForInPlace(vtkm::cont::DeviceAdapterId deviceId) override
{
Portal portal;
vtkm::cont::internal::FindDeviceAdapterTagAndCall(
deviceId, DeviceList(), PrepareForInPlaceFunctor(), this, portal);
return portal;
}
private:
struct PrepareForInputFunctor
{
template <typename DeviceAdapter>
VTKM_CONT void operator()(DeviceAdapter,
CoordinatesArrayHandle* instance,
PortalConst& ret) const
{
auto portal = instance->Array.PrepareForInput(DeviceAdapter());
instance->DevicePortalHandle.Reset(new CoordinatesPortalConst<decltype(portal)>(portal),
true,
vtkm::ListTagBase<DeviceAdapter>());
ret = PortalConst(portal.GetNumberOfValues(),
instance->DevicePortalHandle.PrepareForExecution(DeviceAdapter()));
}
};
struct PrepareForOutputFunctor
{
template <typename DeviceAdapter>
VTKM_CONT void operator()(DeviceAdapter,
CoordinatesArrayHandle* instance,
vtkm::Id numberOfValues,
Portal& ret) const
{
auto portal = instance->Array.PrepareForOutput(numberOfValues, DeviceAdapter());
instance->DevicePortalHandle.Reset(
new CoordinatesPortal<decltype(portal)>(portal), true, vtkm::ListTagBase<DeviceAdapter>());
ret =
Portal(numberOfValues, instance->DevicePortalHandle.PrepareForExecution(DeviceAdapter()));
}
};
struct PrepareForInPlaceFunctor
{
template <typename DeviceAdapter>
VTKM_CONT void operator()(DeviceAdapter, CoordinatesArrayHandle* instance, Portal& ret) const
{
auto portal = instance->Array.PrepareForInPlace(DeviceAdapter());
instance->DevicePortalHandle.Reset(
new CoordinatesPortal<decltype(portal)>(portal), true, vtkm::ListTagBase<DeviceAdapter>());
ret = Portal(instance->Array.GetNumberOfValues(),
instance->DevicePortalHandle.PrepareForExecution(DeviceAdapter()));
}
};
CoordinatesPortal<typename ArrayHandleType::PortalControl> ControlPortal;
CoordinatesPortalConst<typename ArrayHandleType::PortalConstControl> ControlConstPortal;
vtkm::cont::VirtualObjectHandle<CoordinatesPortalBase> DevicePortalHandle;
};
//=============================================================================
struct VTKM_ALWAYS_EXPORT StorageTagVirtualCoordinates
{
};
template <>
class Storage<vtkm::Vec<vtkm::FloatDefault, 3>, StorageTagVirtualCoordinates>
{
public:
using ValueType = vtkm::Vec<vtkm::FloatDefault, 3>;
using PortalType = CoordinatesArrayHandleBase::Portal;
using PortalConstType = CoordinatesArrayHandleBase::PortalConst;
VTKM_CONT Storage() = default;
template <typename ArrayHandleType, typename DeviceList>
VTKM_CONT explicit Storage(const ArrayHandleType& array, DeviceList)
: Array(new CoordinatesArrayHandle<ArrayHandleType, DeviceList>(array))
{
}
VTKM_CONT PortalType GetPortal() { return this->Array->GetPortalControl(); }
VTKM_CONT PortalConstType GetPortalConst() const { return this->Array->GetPortalConstControl(); }
VTKM_CONT vtkm::Id GetNumberOfValues() const { return this->Array->GetNumberOfValues(); }
VTKM_CONT void Allocate(vtkm::Id numberOfValues) { this->Array->Allocate(numberOfValues); }
VTKM_CONT void Shrink(vtkm::Id numberOfValues) { this->Array->Shrink(numberOfValues); }
VTKM_CONT void ReleaseResources() { this->Array->ReleaseResources(); }
VTKM_CONT CoordinatesArrayHandleBase* GetVirtualArray() const { return this->Array.get(); }
private:
std::shared_ptr<CoordinatesArrayHandleBase> Array;
};
//=============================================================================
template <typename DeviceAdapter>
class ArrayTransfer<vtkm::Vec<vtkm::FloatDefault, 3>, StorageTagVirtualCoordinates, DeviceAdapter>
{
public:
using ValueType = vtkm::Vec<vtkm::FloatDefault, 3>;
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTagVirtualCoordinates>;
using PortalControl = typename StorageType::PortalType;
using PortalConstControl = typename StorageType::PortalConstType;
using PortalExecution = CoordinatesArrayHandleBase::Portal;
using PortalConstExecution = CoordinatesArrayHandleBase::PortalConst;
VTKM_CONT
ArrayTransfer(StorageType* storage)
: Array(storage->GetVirtualArray())
{
}
VTKM_CONT
vtkm::Id GetNumberOfValues() const { return this->Array->GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool)
{
return this->Array->PrepareForInput(vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetId());
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool)
{
return this->Array->PrepareForInPlace(vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetId());
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
{
return this->Array->PrepareForOutput(numberOfValues,
vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetId());
}
VTKM_CONT
void RetrieveOutputData(StorageType*) const
{
// Implementation of this method should be unnecessary.
}
VTKM_CONT
void Shrink(vtkm::Id numberOfValues) { this->Array->Shrink(numberOfValues); }
VTKM_CONT
void ReleaseResources() { this->Array->ReleaseResources(); }
private:
CoordinatesArrayHandleBase* Array;
};
} // internal
//=============================================================================
class VTKM_ALWAYS_EXPORT ArrayHandleVirtualCoordinates
: public ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>, internal::StorageTagVirtualCoordinates>
{
public:
VTKM_ARRAY_HANDLE_SUBCLASS_NT(
ArrayHandleVirtualCoordinates,
(ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>, internal::StorageTagVirtualCoordinates>));
template <typename StorageTag, typename DeviceList = VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG>
explicit ArrayHandleVirtualCoordinates(
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>, StorageTag>& array,
DeviceList devices = DeviceList())
: Superclass(typename Superclass::StorageType(array, devices))
{
}
template <typename StorageTag, typename DeviceList = VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG>
explicit ArrayHandleVirtualCoordinates(
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>, StorageTag>& array,
DeviceList devices = DeviceList())
: Superclass(typename Superclass::StorageType(array, devices))
{
}
template <typename ArrayHandleType>
bool IsSameType() const
{
return this->GetArrayHandleWrapper<ArrayHandleType>() != nullptr;
}
template <typename ArrayHandleType>
bool IsSameType(const ArrayHandleType&) const
{
return this->GetArrayHandleWrapper<ArrayHandleType>() != nullptr;
}
template <typename ArrayHandleType>
const ArrayHandleType Cast() const
{
auto wrapper = this->GetArrayHandleWrapper<ArrayHandleType>();
if (!wrapper)
{
throw vtkm::cont::ErrorBadType("dynamic cast failed");
}
return ArrayHandleType(wrapper->GetArray());
}
private:
template <typename ArrayHandleType>
struct WrapperType
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
using ValueType = typename ArrayHandleType::ValueType;
using StorageTag = typename ArrayHandleType::StorageTag;
using BaseArrayHandleType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
using Type = internal::CoordinatesArrayHandleArrayWrapper<BaseArrayHandleType>;
};
template <typename ArrayHandleType>
VTKM_CONT const typename WrapperType<ArrayHandleType>::Type* GetArrayHandleWrapper() const
{
auto va = this->GetStorage().GetVirtualArray();
return dynamic_cast<const typename WrapperType<ArrayHandleType>::Type*>(va);
}
};
template <typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::ArrayHandleVirtualCoordinates& coords,
Functor&& f,
Args&&... args)
{
if (coords.IsSameType<vtkm::cont::ArrayHandleUniformPointCoordinates>())
{
f(coords.Cast<vtkm::cont::ArrayHandleUniformPointCoordinates>(), std::forward<Args>(args)...);
}
else
{
f(coords, std::forward<Args>(args)...);
}
}
template <typename Functor, typename... Args>
void CastAndCall(const typename vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& coords,
Functor&& f,
Args&&... args)
{
CastAndCall(static_cast<const vtkm::cont::ArrayHandleVirtualCoordinates&>(coords),
std::forward<Functor>(f),
std::forward<Args>(args)...);
}
}
} // vtkm::cont
#ifdef VTKM_CUDA
// Cuda seems to have a bug where it expects the template class VirtualObjectTransfer
// to be instantiated in a consitent order among all the translation units of an
// executable. Failing to do so results in random crashes and incorrect results.
// We workaroud this issue by explicitly instantiating VirtualObjectTransfer for
// all the portal types here.
#include <vtkm/cont/cuda/internal/VirtualObjectTransferCuda.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
namespace vtkm
{
namespace cont
{
namespace internal
{
template <typename ArrayHandleType>
struct CudaPortalTypes
{
using PortalConst = typename ArrayHandleType::template ExecutionTypes<
vtkm::cont::DeviceAdapterTagCuda>::PortalConst;
using Portal =
typename ArrayHandleType::template ExecutionTypes<vtkm::cont::DeviceAdapterTagCuda>::Portal;
};
using CudaPortalsBasicF32 = CudaPortalTypes<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>>>;
using CudaPortalsBasicF64 = CudaPortalTypes<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>>>;
using CudaPortalsUniformPointCoordinates =
CudaPortalTypes<vtkm::cont::ArrayHandleUniformPointCoordinates>;
using CudaPortalsRectilinearCoords = CudaPortalTypes<
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>>;
}
}
} // vtkm::cont::internal
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::cont::internal::CoordinatesPortalConst<
vtkm::cont::internal::CudaPortalsBasicF32::PortalConst>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
vtkm::cont::internal::CoordinatesPortal<vtkm::cont::internal::CudaPortalsBasicF32::Portal>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::cont::internal::CoordinatesPortalConst<
vtkm::cont::internal::CudaPortalsBasicF64::PortalConst>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
vtkm::cont::internal::CoordinatesPortal<vtkm::cont::internal::CudaPortalsBasicF64::Portal>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
vtkm::cont::internal::CoordinatesPortalConst<
vtkm::cont::internal::CudaPortalsUniformPointCoordinates::PortalConst>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
vtkm::cont::internal::CoordinatesPortal<
vtkm::cont::internal::CudaPortalsUniformPointCoordinates::Portal>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(
vtkm::cont::internal::CoordinatesPortalConst<
vtkm::cont::internal::CudaPortalsRectilinearCoords::PortalConst>);
VTKM_EXPLICITLY_INSTANTIATE_TRANSFER(vtkm::cont::internal::CoordinatesPortal<
vtkm::cont::internal::CudaPortalsRectilinearCoords::Portal>);
#endif // VTKM_CUDA
#endif // vtk_m_cont_ArrayHandleVirtualCoordinates_h

@ -71,6 +71,10 @@ VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::UInt8, 4, vtkm::cont::StorageTagBasic);
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::Float32, 4, vtkm::cont::StorageTagBasic); VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::Float32, 4, vtkm::cont::StorageTagBasic);
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::Float64, 4, vtkm::cont::StorageTagBasic); VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::Float64, 4, vtkm::cont::StorageTagBasic);
VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC(vtkm::FloatDefault,
3,
vtkm::cont::ArrayHandleVirtualCoordinates::StorageTag);
#undef VTKM_ARRAY_RANGE_COMPUTE_IMPL_T #undef VTKM_ARRAY_RANGE_COMPUTE_IMPL_T
#undef VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC #undef VTKM_ARRAY_RANGE_COMPUTE_IMPL_VEC

@ -26,6 +26,7 @@
#include <vtkm/cont/ArrayHandleCartesianProduct.h> #include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/ArrayHandleCompositeVector.h> #include <vtkm/cont/ArrayHandleCompositeVector.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h> #include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/ArrayHandleVirtualCoordinates.h>
#include <vtkm/cont/RuntimeDeviceTracker.h> #include <vtkm/cont/RuntimeDeviceTracker.h>
namespace vtkm namespace vtkm
@ -97,6 +98,10 @@ VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::FloatDefault,
3, 3,
vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag); vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag);
VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC(vtkm::FloatDefault,
3,
vtkm::cont::ArrayHandleVirtualCoordinates::StorageTag);
#undef VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T #undef VTKM_ARRAY_RANGE_COMPUTE_EXPORT_T
#undef VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC #undef VTKM_ARRAY_RANGE_COMPUTE_EXPORT_VEC

@ -0,0 +1,80 @@
//============================================================================
// 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 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 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.
//============================================================================
#include <vtkm/cont/AssignerMultiBlock.h>
#if defined(VTKM_ENABLE_MPI)
// clang-format off
#include <vtkm/cont/EnvironmentTracker.h>
#include VTKM_DIY(diy/mpi.hpp)
// clang-format on
#include <algorithm> // std::lower_bound
#include <numeric> // std::iota
namespace vtkm
{
namespace cont
{
VTKM_CONT
AssignerMultiBlock::AssignerMultiBlock(const vtkm::cont::MultiBlock& mb)
: diy::Assigner(vtkm::cont::EnvironmentTracker::GetCommunicator().size(), 1)
, IScanBlockCounts()
{
auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
const auto nblocks = mb.GetNumberOfBlocks();
vtkm::Id iscan;
diy::mpi::scan(comm, nblocks, iscan, std::plus<vtkm::Id>());
diy::mpi::all_gather(comm, iscan, this->IScanBlockCounts);
this->set_nblocks(static_cast<int>(this->IScanBlockCounts.back()));
}
VTKM_CONT
void AssignerMultiBlock::local_gids(int rank, std::vector<int>& gids) const
{
if (rank == 0)
{
assert(this->IScanBlockCounts.size() > 0);
gids.resize(this->IScanBlockCounts[rank]);
std::iota(gids.begin(), gids.end(), 0);
}
else if (rank > 0 && rank < static_cast<int>(this->IScanBlockCounts.size()))
{
gids.resize(this->IScanBlockCounts[rank] - this->IScanBlockCounts[rank - 1]);
std::iota(gids.begin(), gids.end(), this->IScanBlockCounts[rank - 1]);
}
}
VTKM_CONT
int AssignerMultiBlock::rank(int gid) const
{
return static_cast<int>(
std::lower_bound(this->IScanBlockCounts.begin(), this->IScanBlockCounts.end(), gid + 1) -
this->IScanBlockCounts.begin());
}
} // vtkm::cont
} // vtkm
#endif // defined(VTKM_ENABLE_MPI)

@ -0,0 +1,74 @@
//============================================================================
// 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 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 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.
//============================================================================
#ifndef vtk_m_cont_AssignerMultiBlock_h
#define vtk_m_cont_AssignerMultiBlock_h
#include <vtkm/internal/Configure.h>
#if defined(VTKM_ENABLE_MPI)
#include <vtkm/cont/MultiBlock.h>
// clang-format off
#include <vtkm/thirdparty/diy/Configure.h>
#include VTKM_DIY(diy/assigner.hpp)
// clang-format on
namespace vtkm
{
namespace cont
{
/// \brief Assigner for `MultiBlock` blocks.
///
/// `AssignerMultiBlock` is a `diy::Assigner` implementation that uses
/// `MultiBlock`'s block distribution to build global-id/rank associations
/// needed for several `diy` operations.
/// It uses a contiguous assignment strategy to map blocks to global ids i.e.
/// blocks on rank 0 come first, then rank 1, etc. Any rank may have 0 blocks.
///
/// AssignerMultiBlock uses collectives in the constructor hence it is
/// essential it gets created on all ranks irrespective of whether the rank has
/// any blocks.
///
class VTKM_CONT_EXPORT AssignerMultiBlock : public diy::Assigner
{
public:
/// Initialize the assigner using a multiblock dataset.
/// This may initialize collective operations to populate the assigner with
/// information about blocks on all ranks.
VTKM_CONT
AssignerMultiBlock(const vtkm::cont::MultiBlock& mb);
///@{
/// diy::Assigner API implementation.
VTKM_CONT
void local_gids(int rank, std::vector<int>& gids) const override;
VTKM_CONT
int rank(int gid) const override;
//@}
private:
std::vector<vtkm::Id> IScanBlockCounts;
};
}
}
#endif // defined(VTKM_ENABLE_MPI)
#endif

@ -39,12 +39,15 @@ set(headers
ArrayHandleSwizzle.h ArrayHandleSwizzle.h
ArrayHandleTransform.h ArrayHandleTransform.h
ArrayHandleUniformPointCoordinates.h ArrayHandleUniformPointCoordinates.h
ArrayHandleVirtualCoordinates.h
ArrayHandleZip.h ArrayHandleZip.h
ArrayPortal.h ArrayPortal.h
ArrayPortalToIterators.h ArrayPortalToIterators.h
ArrayHandleConcatenate.h ArrayHandleConcatenate.h
ArrayRangeCompute.h ArrayRangeCompute.h
ArrayRangeCompute.hxx ArrayRangeCompute.hxx
AssignerMultiBlock.h
CellLocator.h
CellLocatorTwoLevelUniformGrid.h CellLocatorTwoLevelUniformGrid.h
CellSet.h CellSet.h
CellSetExplicit.h CellSetExplicit.h
@ -58,6 +61,7 @@ set(headers
DataSetBuilderRectilinear.h DataSetBuilderRectilinear.h
DataSetBuilderUniform.h DataSetBuilderUniform.h
DataSetFieldAdd.h DataSetFieldAdd.h
DecomposerMultiBlock.h
DeviceAdapter.h DeviceAdapter.h
DeviceAdapterAlgorithm.h DeviceAdapterAlgorithm.h
DeviceAdapterListTag.h DeviceAdapterListTag.h
@ -66,6 +70,7 @@ set(headers
EnvironmentTracker.h EnvironmentTracker.h
Error.h Error.h
ErrorBadAllocation.h ErrorBadAllocation.h
ErrorBadDevice.h
ErrorBadType.h ErrorBadType.h
ErrorBadValue.h ErrorBadValue.h
ErrorExecution.h ErrorExecution.h
@ -94,16 +99,14 @@ set(template_sources
set(sources set(sources
ArrayHandle.cxx ArrayHandle.cxx
AssignerMultiBlock.cxx
CellSet.cxx CellSet.cxx
CellSetExplicit.cxx CellSetExplicit.cxx
CellSetStructured.cxx CellSetStructured.cxx
CoordinateSystem.cxx
DataSet.cxx
DynamicArrayHandle.cxx DynamicArrayHandle.cxx
EnvironmentTracker.cxx EnvironmentTracker.cxx
Field.cxx Field.cxx
internal/SimplePolymorphicContainer.cxx internal/SimplePolymorphicContainer.cxx
MultiBlock.cxx
internal/ArrayManagerExecutionShareWithControl.cxx internal/ArrayManagerExecutionShareWithControl.cxx
StorageBasic.cxx StorageBasic.cxx
) )
@ -113,6 +116,9 @@ set(sources
set(device_sources set(device_sources
ArrayRangeCompute.cxx ArrayRangeCompute.cxx
CellSetExplicit.cxx CellSetExplicit.cxx
CoordinateSystem.cxx
DataSet.cxx
MultiBlock.cxx
RuntimeDeviceTracker.cxx RuntimeDeviceTracker.cxx
TryExecute.cxx TryExecute.cxx
) )

158
vtkm/cont/CellLocator.h Normal file

@ -0,0 +1,158 @@
//============================================================================
// 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 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 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.
//============================================================================
#ifndef vtk_m_cont_CellLocator_h
#define vtk_m_cont_CellLocator_h
#include <vtkm/cont/CellLocatorTwoLevelUniformGrid.h>
#include <vtkm/exec/ParametricCoordinates.h>
namespace vtkm
{
namespace cont
{
class CellLocator
{
private:
using StructuredCellSetList = vtkm::ListTagBase<vtkm::cont::CellSetStructured<1>,
vtkm::cont::CellSetStructured<2>,
vtkm::cont::CellSetStructured<3>>;
VTKM_CONT static bool IsUniformGrid(const vtkm::cont::DynamicCellSet& cellset,
const vtkm::cont::CoordinateSystem& coordinates)
{
return coordinates.GetData().IsSameType<vtkm::cont::ArrayHandleUniformPointCoordinates>() &&
(cellset.IsType<vtkm::cont::CellSetStructured<1>>() ||
cellset.IsType<vtkm::cont::CellSetStructured<2>>() ||
cellset.IsType<vtkm::cont::CellSetStructured<3>>());
}
public:
void SetCellSet(const vtkm::cont::DynamicCellSet& cellset) { this->CellSet = cellset; }
const vtkm::cont::DynamicCellSet& GetCellSet() const { return this->CellSet; }
void SetCoordinates(const vtkm::cont::CoordinateSystem& coords) { this->Coordinates = coords; }
const vtkm::cont::CoordinateSystem& GetCoordinates() const { return this->Coordinates; }
/// Builds the cell locator lookup structure
///
template <typename DeviceAdapter, typename CellSetList = VTKM_DEFAULT_CELL_SET_LIST_TAG>
void Build(DeviceAdapter device, CellSetList cellSetTypes = CellSetList())
{
if (IsUniformGrid(this->CellSet, this->Coordinates))
{
// nothing to build for uniform grid
}
else
{
this->Locator.SetCellSet(this->CellSet);
this->Locator.SetCoordinates(this->Coordinates);
this->Locator.Build(device, cellSetTypes);
}
}
class FindCellWorklet : public vtkm::worklet::WorkletMapField
{
private:
template <vtkm::IdComponent DIM>
using ConnectivityType = vtkm::exec::ConnectivityStructured<vtkm::TopologyElementTagPoint,
vtkm::TopologyElementTagCell,
DIM>;
public:
typedef void ControlSignature(FieldIn<Vec3> points,
WholeCellSetIn<> cellSet,
WholeArrayIn<Vec3> coordinates,
FieldOut<IdType> cellIds,
FieldOut<Vec3> parametricCoordinates);
typedef void ExecutionSignature(_1, _2, _3, _4, _5);
template <typename CoordsPortalType, vtkm::IdComponent DIM>
VTKM_EXEC void operator()(const vtkm::Vec<vtkm::FloatDefault, 3>& point,
const ConnectivityType<DIM>& cellset,
const CoordsPortalType& coordinates,
vtkm::Id& cellId,
vtkm::Vec<vtkm::FloatDefault, 3>& pc) const
{
auto coords = coordinates.GetPortal();
static_assert(
std::is_same<decltype(coords), vtkm::internal::ArrayPortalUniformPointCoordinates>::value,
"expecting ArrayHandleUniformPointCoordinates for coordinates");
auto cellId3 = static_cast<vtkm::Id3>((point - coords.GetOrigin()) / coords.GetSpacing());
auto cellDim = coords.GetDimensions() - vtkm::Id3(1);
if (cellId3[0] < 0 || cellId3[0] >= cellDim[0] || cellId3[1] < 0 ||
cellId3[1] >= cellDim[1] || cellId3[2] < 0 || cellId3[2] >= cellDim[2])
{
cellId = -1;
}
else
{
cellId = cellId3[0] + cellDim[0] * (cellId3[1] + cellDim[1] * cellId3[2]);
auto cellPoints =
vtkm::VecAxisAlignedPointCoordinates<DIM>(coords.Get(cellId3), coords.GetSpacing());
bool success;
pc = vtkm::exec::WorldCoordinatesToParametricCoordinates(
cellPoints, point, cellset.GetCellShape(cellId), success, *this);
VTKM_ASSERT(success);
}
}
};
/// Finds the containing cells for the given array of points. Returns the cell ids
/// in the `cellIds` arrays. If a cell could not be found due to the point being
/// outside all the cells or due to numerical errors, the cell id is set to -1.
/// Parametric coordinates of the point inside the cell is returned in the
/// `parametricCoords` array.
///
template <typename PointComponentType,
typename PointStorageType,
typename DeviceAdapter,
typename CellSetList = VTKM_DEFAULT_CELL_SET_LIST_TAG>
void FindCells(
const vtkm::cont::ArrayHandle<vtkm::Vec<PointComponentType, 3>, PointStorageType>& points,
vtkm::cont::ArrayHandle<vtkm::Id>& cellIds,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::FloatDefault, 3>>& parametricCoords,
DeviceAdapter device,
CellSetList cellSetTypes = CellSetList()) const
{
if (IsUniformGrid(this->CellSet, this->Coordinates))
{
auto coordinates =
this->Coordinates.GetData().Cast<vtkm::cont::ArrayHandleUniformPointCoordinates>();
auto cellset = this->CellSet.ResetCellSetList(StructuredCellSetList());
vtkm::worklet::DispatcherMapField<FindCellWorklet, DeviceAdapter>().Invoke(
points, cellset, coordinates, cellIds, parametricCoords);
}
else
{
this->Locator.FindCells(points, cellIds, parametricCoords, device, cellSetTypes);
}
}
private:
vtkm::cont::DynamicCellSet CellSet;
vtkm::cont::CoordinateSystem Coordinates;
vtkm::cont::CellLocatorTwoLevelUniformGrid Locator;
};
}
} // vtkm::cont
#endif // vtk_m_cont_CellLocator_h

@ -107,6 +107,7 @@ private:
DimVec3 Min; DimVec3 Min;
DimVec3 Max; DimVec3 Max;
VTKM_EXEC
bool Empty() const bool Empty() const
{ {
return (this->Max[0] < this->Min[0]) || (this->Max[1] < this->Min[1]) || return (this->Max[0] < this->Min[0]) || (this->Max[1] < this->Min[1]) ||
@ -495,24 +496,17 @@ public:
/// Builds the cell locator lookup structure /// Builds the cell locator lookup structure
/// ///
template <typename DeviceAdapter, template <typename DeviceAdapter, typename CellSetList = VTKM_DEFAULT_CELL_SET_LIST_TAG>
typename CellSetList = VTKM_DEFAULT_CELL_SET_LIST_TAG, void Build(DeviceAdapter, CellSetList cellSetTypes = CellSetList())
typename CoordsTypeList = VTKM_DEFAULT_COORDINATE_SYSTEM_TYPE_LIST_TAG,
typename CoordsStorageList = VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG>
void Build(DeviceAdapter,
CellSetList cellSetTypes = CellSetList(),
CoordsTypeList coordsValueTypes = CoordsTypeList(),
CoordsStorageList coordsStorageType = CoordsStorageList())
{ {
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>; using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
auto cellset = this->CellSet.ResetCellSetList(cellSetTypes); auto cellset = this->CellSet.ResetCellSetList(cellSetTypes);
auto points = const auto& coords = this->Coordinates;
this->Coordinates.GetData().ResetTypeAndStorageLists(coordsValueTypes, coordsStorageType);
TwoLevelUniformGrid ls; TwoLevelUniformGrid ls;
// 1: Compute the top level grid // 1: Compute the top level grid
auto bounds = this->Coordinates.GetBounds(coordsValueTypes, coordsStorageType); auto bounds = this->Coordinates.GetBounds();
FloatVec3 bmin(static_cast<vtkm::FloatDefault>(bounds.X.Min), FloatVec3 bmin(static_cast<vtkm::FloatDefault>(bounds.X.Min),
static_cast<vtkm::FloatDefault>(bounds.Y.Min), static_cast<vtkm::FloatDefault>(bounds.Y.Min),
static_cast<vtkm::FloatDefault>(bounds.Z.Min)); static_cast<vtkm::FloatDefault>(bounds.Z.Min));
@ -532,7 +526,7 @@ public:
vtkm::cont::ArrayHandle<vtkm::Id> binCounts; vtkm::cont::ArrayHandle<vtkm::Id> binCounts;
CountBinsL1 countL1(ls.TopLevel); CountBinsL1 countL1(ls.TopLevel);
vtkm::worklet::DispatcherMapTopology<CountBinsL1, DeviceAdapter>(countL1).Invoke( vtkm::worklet::DispatcherMapTopology<CountBinsL1, DeviceAdapter>(countL1).Invoke(
cellset, points, binCounts); cellset, coords, binCounts);
// 3: Total number of unique (cell, bin) pairs (for pre-allocating arrays) // 3: Total number of unique (cell, bin) pairs (for pre-allocating arrays)
vtkm::Id numPairsL1 = Algorithm::ScanExclusive(binCounts, binCounts); vtkm::Id numPairsL1 = Algorithm::ScanExclusive(binCounts, binCounts);
@ -542,7 +536,7 @@ public:
binIds.Allocate(numPairsL1); binIds.Allocate(numPairsL1);
FindBinsL1 findL1(ls.TopLevel); FindBinsL1 findL1(ls.TopLevel);
vtkm::worklet::DispatcherMapTopology<FindBinsL1, DeviceAdapter>(findL1).Invoke( vtkm::worklet::DispatcherMapTopology<FindBinsL1, DeviceAdapter>(findL1).Invoke(
cellset, points, binCounts, binIds); cellset, coords, binCounts, binIds);
binCounts.ReleaseResources(); binCounts.ReleaseResources();
// 5: From above, find the number of cells that intersect each top level bin // 5: From above, find the number of cells that intersect each top level bin
@ -576,7 +570,7 @@ public:
// 8: For each cell, find the number of l2 bins they intersect // 8: For each cell, find the number of l2 bins they intersect
CountBinsL2 countL2(ls.TopLevel); CountBinsL2 countL2(ls.TopLevel);
vtkm::worklet::DispatcherMapTopology<CountBinsL2, DeviceAdapter>(countL2).Invoke( vtkm::worklet::DispatcherMapTopology<CountBinsL2, DeviceAdapter>(countL2).Invoke(
cellset, points, ls.LeafDimensions, binCounts); cellset, coords, ls.LeafDimensions, binCounts);
// 9: Total number of unique (cell, bin) pairs (for pre-allocating arrays) // 9: Total number of unique (cell, bin) pairs (for pre-allocating arrays)
vtkm::Id numPairsL2 = Algorithm::ScanExclusive(binCounts, binCounts); vtkm::Id numPairsL2 = Algorithm::ScanExclusive(binCounts, binCounts);
@ -586,7 +580,7 @@ public:
ls.CellIds.Allocate(numPairsL2); ls.CellIds.Allocate(numPairsL2);
FindBinsL2 findL2(ls.TopLevel); FindBinsL2 findL2(ls.TopLevel);
vtkm::worklet::DispatcherMapTopology<FindBinsL2, DeviceAdapter>(findL2).Invoke( vtkm::worklet::DispatcherMapTopology<FindBinsL2, DeviceAdapter>(findL2).Invoke(
cellset, points, ls.LeafDimensions, ls.LeafStartIndex, binCounts, binIds, ls.CellIds); cellset, coords, ls.LeafDimensions, ls.LeafStartIndex, binCounts, binIds, ls.CellIds);
binCounts.ReleaseResources(); binCounts.ReleaseResources();
// 11: From above, find the cells that each l2 bin intersects // 11: From above, find the cells that each l2 bin intersects
@ -709,22 +703,18 @@ public:
template <typename PointComponentType, template <typename PointComponentType,
typename PointStorageType, typename PointStorageType,
typename DeviceAdapter, typename DeviceAdapter,
typename CellSetList = VTKM_DEFAULT_CELL_SET_LIST_TAG, typename CellSetList = VTKM_DEFAULT_CELL_SET_LIST_TAG>
typename CoordsTypeList = VTKM_DEFAULT_COORDINATE_SYSTEM_TYPE_LIST_TAG,
typename CoordsStorageList = VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG>
void FindCells( void FindCells(
const vtkm::cont::ArrayHandle<vtkm::Vec<PointComponentType, 3>, PointStorageType>& points, const vtkm::cont::ArrayHandle<vtkm::Vec<PointComponentType, 3>, PointStorageType>& points,
vtkm::cont::ArrayHandle<vtkm::Id>& cellIds, vtkm::cont::ArrayHandle<vtkm::Id>& cellIds,
vtkm::cont::ArrayHandle<FloatVec3>& parametricCoords, vtkm::cont::ArrayHandle<FloatVec3>& parametricCoords,
DeviceAdapter device, DeviceAdapter device,
CellSetList cellSetTypes = CellSetList(), CellSetList cellSetTypes = CellSetList()) const
CoordsTypeList coordsValueTypes = CoordsTypeList(),
CoordsStorageList coordsStorageType = CoordsStorageList()) const
{ {
vtkm::worklet::DispatcherMapField<FindCellWorklet, DeviceAdapter>().Invoke( vtkm::worklet::DispatcherMapField<FindCellWorklet, DeviceAdapter>().Invoke(
points, points,
this->CellSet.ResetCellSetList(cellSetTypes), this->CellSet.ResetCellSetList(cellSetTypes),
this->Coordinates.GetData().ResetTypeAndStorageLists(coordsValueTypes, coordsStorageType), this->Coordinates,
this->PrepareForDevice(device), this->PrepareForDevice(device),
cellIds, cellIds,
parametricCoords); parametricCoords);

@ -25,6 +25,10 @@ namespace vtkm
namespace cont namespace cont
{ {
using CoordinatesTypeList = vtkm::ListTagBase<vtkm::cont::ArrayHandleVirtualCoordinates::ValueType>;
using CoordinatesStorageList =
vtkm::ListTagBase<vtkm::cont::ArrayHandleVirtualCoordinates::StorageTag>;
VTKM_CONT VTKM_CONT
void CoordinateSystem::PrintSummary(std::ostream& out) const void CoordinateSystem::PrintSummary(std::ostream& out) const
{ {
@ -35,23 +39,21 @@ void CoordinateSystem::PrintSummary(std::ostream& out) const
VTKM_CONT VTKM_CONT
void CoordinateSystem::GetRange(vtkm::Range* range) const void CoordinateSystem::GetRange(vtkm::Range* range) const
{ {
this->Superclass::GetRange(range, this->Superclass::GetRange(range, CoordinatesTypeList(), CoordinatesStorageList());
VTKM_DEFAULT_COORDINATE_SYSTEM_TYPE_LIST_TAG(),
VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG());
} }
VTKM_CONT VTKM_CONT
const vtkm::cont::ArrayHandle<vtkm::Range>& CoordinateSystem::GetRange() const const vtkm::cont::ArrayHandle<vtkm::Range>& CoordinateSystem::GetRange() const
{ {
return this->Superclass::GetRange(VTKM_DEFAULT_COORDINATE_SYSTEM_TYPE_LIST_TAG(), return this->Superclass::GetRange(CoordinatesTypeList(), CoordinatesStorageList());
VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG());
} }
VTKM_CONT VTKM_CONT
vtkm::Bounds CoordinateSystem::GetBounds() const vtkm::Bounds CoordinateSystem::GetBounds() const
{ {
return this->GetBounds(VTKM_DEFAULT_COORDINATE_SYSTEM_TYPE_LIST_TAG(), vtkm::Range ranges[3];
VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG()); this->GetRange(ranges);
return vtkm::Bounds(ranges[0], ranges[1], ranges[2]);
} }
} }
} // namespace vtkm::cont } // namespace vtkm::cont

@ -22,20 +22,11 @@
#include <vtkm/Bounds.h> #include <vtkm/Bounds.h>
#include <vtkm/cont/ArrayHandleCartesianProduct.h> #include <vtkm/cont/ArrayHandleCast.h>
#include <vtkm/cont/ArrayHandleCompositeVector.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h> #include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/ArrayHandleVirtualCoordinates.h>
#include <vtkm/cont/Field.h> #include <vtkm/cont/Field.h>
#ifndef VTKM_DEFAULT_COORDINATE_SYSTEM_TYPE_LIST_TAG
#define VTKM_DEFAULT_COORDINATE_SYSTEM_TYPE_LIST_TAG ::vtkm::TypeListTagFieldVec3
#endif
#ifndef VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG
#define VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG \
::vtkm::cont::StorageListTagCoordinateSystemDefault
#endif
namespace vtkm namespace vtkm
{ {
namespace cont namespace cont
@ -44,49 +35,49 @@ namespace cont
namespace detail namespace detail
{ {
using ArrayHandleCompositeVectorFloat32_3Default = struct MakeArrayHandleVirtualCoordinatesFunctor
vtkm::cont::ArrayHandleCompositeVectorType<vtkm::cont::ArrayHandle<vtkm::Float32>, {
vtkm::cont::ArrayHandle<vtkm::Float32>, VTKM_CONT explicit MakeArrayHandleVirtualCoordinatesFunctor(
vtkm::cont::ArrayHandle<vtkm::Float32>>::type; vtkm::cont::ArrayHandleVirtualCoordinates& out)
: Out(&out)
{
}
using ArrayHandleCompositeVectorFloat64_3Default = template <typename StorageTag>
vtkm::cont::ArrayHandleCompositeVectorType<vtkm::cont::ArrayHandle<vtkm::Float64>, VTKM_CONT void operator()(
vtkm::cont::ArrayHandle<vtkm::Float64>, const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>, StorageTag>& array) const
vtkm::cont::ArrayHandle<vtkm::Float64>>::type; {
*this->Out = vtkm::cont::ArrayHandleVirtualCoordinates(array);
}
template <typename StorageTag>
VTKM_CONT void operator()(
const vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>, StorageTag>& array) const
{
*this->Out = vtkm::cont::ArrayHandleVirtualCoordinates(array);
}
template <typename T, typename StorageTag>
VTKM_CONT void operator()(const vtkm::cont::ArrayHandle<T, StorageTag>&) const
{
throw vtkm::cont::ErrorBadType("CoordinateSystem's value type should be a 3 component Vec "
"of either vtkm::Float32 or vtkm::Float64");
}
vtkm::cont::ArrayHandleVirtualCoordinates* Out;
};
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::cont::ArrayHandleVirtualCoordinates MakeArrayHandleVirtualCoordinates(
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& array)
{
vtkm::cont::ArrayHandleVirtualCoordinates out;
array.CastAndCall(MakeArrayHandleVirtualCoordinatesFunctor(out));
return out;
}
} // namespace detail } // namespace detail
/// \brief Default storage list for CoordinateSystem arrays.
///
/// \c VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG is set to this value
/// by default (unless it is defined before including VTK-m headers.
///
struct StorageListTagCoordinateSystemDefault
: vtkm::ListTagBase<vtkm::cont::StorageTagBasic,
vtkm::cont::ArrayHandleUniformPointCoordinates::StorageTag,
detail::ArrayHandleCompositeVectorFloat32_3Default::StorageTag,
detail::ArrayHandleCompositeVectorFloat64_3Default::StorageTag,
vtkm::cont::ArrayHandleCartesianProduct<
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>::StorageTag>
{
};
}
}
namespace vtkm
{
template struct ListCrossProduct<::vtkm::TypeListTagFieldVec3,
::vtkm::cont::StorageListTagCoordinateSystemDefault>;
namespace cont
{
using DynamicArrayHandleCoordinateSystem =
vtkm::cont::DynamicArrayHandleBase<VTKM_DEFAULT_COORDINATE_SYSTEM_TYPE_LIST_TAG,
VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG>;
class VTKM_CONT_EXPORT CoordinateSystem : public vtkm::cont::Field class VTKM_CONT_EXPORT CoordinateSystem : public vtkm::cont::Field
{ {
using Superclass = vtkm::cont::Field; using Superclass = vtkm::cont::Field;
@ -98,15 +89,22 @@ public:
{ {
} }
VTKM_CONT VTKM_CONT CoordinateSystem(std::string name,
CoordinateSystem(std::string name, const vtkm::cont::DynamicArrayHandle& data) const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& data)
: Superclass(name, ASSOC_POINTS, data) : Superclass(name, ASSOC_POINTS, data)
{ {
} }
template <typename TypeList, typename StorageList>
VTKM_CONT CoordinateSystem(std::string name,
const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& data)
: Superclass(name, ASSOC_POINTS, detail::MakeArrayHandleVirtualCoordinates(data))
{
}
template <typename T, typename Storage> template <typename T, typename Storage>
VTKM_CONT CoordinateSystem(std::string name, const ArrayHandle<T, Storage>& data) VTKM_CONT CoordinateSystem(std::string name, const ArrayHandle<T, Storage>& data)
: Superclass(name, ASSOC_POINTS, data) : Superclass(name, ASSOC_POINTS, vtkm::cont::ArrayHandleVirtualCoordinates(data))
{ {
} }
@ -120,7 +118,7 @@ public:
vtkm::Vec<vtkm::FloatDefault, 3> spacing = vtkm::Vec<vtkm::FloatDefault, 3>(1.0f, 1.0f, 1.0f)) vtkm::Vec<vtkm::FloatDefault, 3> spacing = vtkm::Vec<vtkm::FloatDefault, 3>(1.0f, 1.0f, 1.0f))
: Superclass(name, : Superclass(name,
ASSOC_POINTS, ASSOC_POINTS,
vtkm::cont::DynamicArrayHandle( vtkm::cont::ArrayHandleVirtualCoordinates(
vtkm::cont::ArrayHandleUniformPointCoordinates(dimensions, origin, spacing))) vtkm::cont::ArrayHandleUniformPointCoordinates(dimensions, origin, spacing)))
{ {
} }
@ -129,93 +127,45 @@ public:
CoordinateSystem& operator=(const vtkm::cont::CoordinateSystem& src) = default; CoordinateSystem& operator=(const vtkm::cont::CoordinateSystem& src) = default;
VTKM_CONT VTKM_CONT
vtkm::cont::DynamicArrayHandleCoordinateSystem GetData() const vtkm::cont::ArrayHandleVirtualCoordinates GetData() const
{ {
return vtkm::cont::DynamicArrayHandleCoordinateSystem(this->Superclass::GetData()); return this->Superclass::GetData().Cast<vtkm::cont::ArrayHandleVirtualCoordinates>();
}
VTKM_CONT void SetData(const vtkm::cont::ArrayHandleVirtualCoordinates::Superclass& newdata)
{
this->Superclass::SetData(newdata);
}
template <typename T, typename StorageTag>
VTKM_CONT void SetData(const vtkm::cont::ArrayHandle<T, StorageTag>& newdata)
{
this->Superclass::SetData(vtkm::cont::ArrayHandleVirtualCoordinates(newdata));
} }
VTKM_CONT VTKM_CONT
vtkm::cont::DynamicArrayHandleCoordinateSystem GetData() template <typename TypeList, typename StorageList>
void SetData(const vtkm::cont::DynamicArrayHandleBase<TypeList, StorageList>& newdata)
{ {
return vtkm::cont::DynamicArrayHandleCoordinateSystem(this->Superclass::GetData()); this->Superclass::SetData(detail::MakeArrayHandleVirtualCoordinates(newdata));
} }
VTKM_CONT VTKM_CONT
void GetRange(vtkm::Range* range) const; void GetRange(vtkm::Range* range) const;
template <typename TypeList>
VTKM_CONT void GetRange(vtkm::Range* range, TypeList) const
{
VTKM_IS_LIST_TAG(TypeList);
this->Superclass::GetRange(
range, TypeList(), VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG());
}
template <typename TypeList, typename StorageList>
VTKM_CONT void GetRange(vtkm::Range* range, TypeList, StorageList) const
{
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
this->Superclass::GetRange(range, TypeList(), StorageList());
}
VTKM_CONT VTKM_CONT
const vtkm::cont::ArrayHandle<vtkm::Range>& GetRange() const; const vtkm::cont::ArrayHandle<vtkm::Range>& GetRange() const;
template <typename TypeList>
VTKM_CONT const vtkm::cont::ArrayHandle<vtkm::Range>& GetRange(TypeList) const
{
VTKM_IS_LIST_TAG(TypeList);
return this->Superclass::GetRange(TypeList(),
VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG());
}
template <typename TypeList, typename StorageList>
VTKM_CONT const vtkm::cont::ArrayHandle<vtkm::Range>& GetRange(TypeList, StorageList) const
{
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
return this->Superclass::GetRange(TypeList(), StorageList());
}
VTKM_CONT VTKM_CONT
vtkm::Bounds GetBounds() const; vtkm::Bounds GetBounds() const;
template <typename TypeList>
VTKM_CONT vtkm::Bounds GetBounds(TypeList) const
{
VTKM_IS_LIST_TAG(TypeList);
return this->GetBounds(TypeList(), VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG());
}
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::Bounds GetBounds(TypeList, StorageList) const
{
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
vtkm::cont::ArrayHandle<vtkm::Range> ranges = this->GetRange(TypeList(), StorageList());
VTKM_ASSERT(ranges.GetNumberOfValues() == 3);
vtkm::cont::ArrayHandle<vtkm::Range>::PortalConstControl rangePortal =
ranges.GetPortalConstControl();
return vtkm::Bounds(rangePortal.Get(0), rangePortal.Get(1), rangePortal.Get(2));
}
virtual void PrintSummary(std::ostream& out) const; virtual void PrintSummary(std::ostream& out) const;
}; };
template <typename Functor, typename... Args> template <typename Functor, typename... Args>
void CastAndCall(const vtkm::cont::CoordinateSystem& coords, Functor&& f, Args&&... args) void CastAndCall(const vtkm::cont::CoordinateSystem& coords, Functor&& f, Args&&... args)
{ {
coords.GetData().CastAndCall(std::forward<Functor>(f), std::forward<Args>(args)...); CastAndCall(coords.GetData(), std::forward<Functor>(f), std::forward<Args>(args)...);
} }
template <typename T> template <typename T>

@ -17,7 +17,6 @@
// Laboratory (LANL), the U.S. Government retains certain rights in // Laboratory (LANL), the U.S. Government retains certain rights in
// this software. // this software.
//============================================================================ //============================================================================
#ifndef vtk_m_cont_DataSetFieldAdd_h #ifndef vtk_m_cont_DataSetFieldAdd_h
#define vtk_m_cont_DataSetFieldAdd_h #define vtk_m_cont_DataSetFieldAdd_h

@ -0,0 +1,57 @@
//============================================================================
// 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 2015 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 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.
//============================================================================
#ifndef vtk_m_cont_DecomposerMultiBlock_h
#define vtk_m_cont_DecomposerMultiBlock_h
#include <vtkm/internal/Configure.h>
#if defined(VTKM_ENABLE_MPI)
#include <vtkm/cont/AssignerMultiBlock.h>
namespace vtkm
{
namespace cont
{
/// \brief DIY Decomposer that uses `MultiBlock` existing decomposition.
///
/// To create partners for various reduce operations, DIY requires a decomposer.
/// This class provides an implementation that can use the multiblock's
/// decomposition.
///
class VTKM_CONT_EXPORT DecomposerMultiBlock
{
public:
VTKM_CONT DecomposerMultiBlock(const diy::Assigner& assigner)
: divisions{ assigner.nblocks() }
{
}
using DivisionVector = std::vector<int>;
/// this public member is needed to satisfy decomposer concept for
/// partners in DIY.
DivisionVector divisions;
};
}
}
#endif // defined(VTKM_ENABLE_MPI)
#endif

@ -17,8 +17,8 @@
// Laboratory (LANL), the U.S. Government retains certain rights in // Laboratory (LANL), the U.S. Government retains certain rights in
// this software. // this software.
//============================================================================ //============================================================================
#ifndef vtk_m_cont_internal_DeviceAdapterAlgorithm_h #ifndef vtk_m_cont_DeviceAdapterAlgorithm_h
#define vtk_m_cont_internal_DeviceAdapterAlgorithm_h #define vtk_m_cont_DeviceAdapterAlgorithm_h
#include <vtkm/Types.h> #include <vtkm/Types.h>

@ -40,47 +40,6 @@ struct DeviceAdapterListTagCommon : vtkm::ListTagBase<vtkm::cont::DeviceAdapterT
vtkm::cont::DeviceAdapterTagSerial> vtkm::cont::DeviceAdapterTagSerial>
{ {
}; };
namespace detail
{
template <typename FunctorType>
class ExecuteIfValidDeviceTag
{
private:
template <typename DeviceAdapter>
using EnableIfValid = std::enable_if<vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::Valid>;
template <typename DeviceAdapter>
using EnableIfInvalid = std::enable_if<!vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::Valid>;
public:
explicit ExecuteIfValidDeviceTag(const FunctorType& functor)
: Functor(functor)
{
}
template <typename DeviceAdapter>
typename EnableIfValid<DeviceAdapter>::type operator()(DeviceAdapter) const
{
this->Functor(DeviceAdapter());
}
template <typename DeviceAdapter>
typename EnableIfInvalid<DeviceAdapter>::type operator()(DeviceAdapter) const
{
}
private:
FunctorType Functor;
};
} // detail
template <typename DeviceList, typename Functor>
VTKM_CONT void ForEachValidDevice(DeviceList devices, const Functor& functor)
{
vtkm::ListForEach(detail::ExecuteIfValidDeviceTag<Functor>(functor), devices);
}
} }
} // namespace vtkm::cont } // namespace vtkm::cont

@ -20,7 +20,12 @@
#include <vtkm/cont/EnvironmentTracker.h> #include <vtkm/cont/EnvironmentTracker.h>
#if defined(VTKM_ENABLE_MPI) #if defined(VTKM_ENABLE_MPI)
#include <diy/mpi.hpp>
// clang-format off
#include <vtkm/thirdparty/diy/Configure.h>
#include VTKM_DIY(diy/mpi.hpp)
// clang-format on
#else #else
namespace diy namespace diy
{ {

@ -25,6 +25,11 @@
#include <vtkm/internal/Configure.h> #include <vtkm/internal/Configure.h>
#include <vtkm/internal/ExportMacros.h> #include <vtkm/internal/ExportMacros.h>
#if defined(VTKM_ENABLE_MPI)
// needed for diy mangling.
#include <vtkm/thirdparty/diy/Configure.h>
#endif
namespace diy namespace diy
{ {
namespace mpi namespace mpi

@ -0,0 +1,48 @@
//============================================================================
// 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.
//============================================================================
#ifndef vtk_m_cont_ErrorBadDevice_h
#define vtk_m_cont_ErrorBadDevice_h
#include <vtkm/cont/Error.h>
namespace vtkm
{
namespace cont
{
VTKM_SILENCE_WEAK_VTABLE_WARNING_START
/// This class is thrown when VTK-m performs an operation that is not supported
/// on the current device.
///
class VTKM_ALWAYS_EXPORT ErrorBadDevice : public Error
{
public:
ErrorBadDevice(const std::string& message)
: Error(message)
{
}
};
VTKM_SILENCE_WEAK_VTABLE_WARNING_END
}
} // namespace vtkm::cont
#endif // vtk_m_cont_ErrorBadDevice_h

@ -249,8 +249,8 @@ public:
vtkm::cont::DynamicArrayHandle& GetData(); vtkm::cont::DynamicArrayHandle& GetData();
template <typename T> template <typename T, typename StorageTag>
VTKM_CONT void SetData(const vtkm::cont::ArrayHandle<T>& newdata) VTKM_CONT void SetData(const vtkm::cont::ArrayHandle<T, StorageTag>& newdata)
{ {
this->Data = newdata; this->Data = newdata;
this->ModifiedFlag = true; this->ModifiedFlag = true;

@ -21,7 +21,9 @@
#include <vtkm/StaticAssert.h> #include <vtkm/StaticAssert.h>
#include <vtkm/cont/ArrayCopy.h> #include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandle.h> #include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/AssignerMultiBlock.h>
#include <vtkm/cont/DataSet.h> #include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DecomposerMultiBlock.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h> #include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/DynamicArrayHandle.h> #include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/EnvironmentTracker.h> #include <vtkm/cont/EnvironmentTracker.h>
@ -30,7 +32,14 @@
#include <vtkm/cont/MultiBlock.h> #include <vtkm/cont/MultiBlock.h>
#if defined(VTKM_ENABLE_MPI) #if defined(VTKM_ENABLE_MPI)
#include <diy/master.hpp> // clang-format off
#include <vtkm/thirdparty/diy/Configure.h>
#include VTKM_DIY(diy/decomposition.hpp)
#include VTKM_DIY(diy/master.hpp)
#include VTKM_DIY(diy/partners/all-reduce.hpp)
#include VTKM_DIY(diy/partners/swap.hpp)
#include VTKM_DIY(diy/reduce.hpp)
// clang-format on
namespace vtkm namespace vtkm
{ {
@ -48,111 +57,21 @@ VTKM_CONT std::vector<typename PortalType::ValueType> CopyArrayPortalToVector(
std::copy(iterators.GetBegin(), iterators.GetEnd(), result.begin()); std::copy(iterators.GetBegin(), iterators.GetEnd(), result.begin());
return result; return result;
} }
template <typename T>
const vtkm::cont::DataSet& GetBlock(const vtkm::cont::MultiBlock& mb, const T&);
template <>
const vtkm::cont::DataSet& GetBlock(const vtkm::cont::MultiBlock& mb,
const diy::Master::ProxyWithLink& cp)
{
const int lid = cp.master()->lid(cp.gid());
return mb.GetBlock(lid);
} }
} }
} }
namespace std
{
namespace detail
{
template <typename T, size_t ElementSize = sizeof(T)>
struct MPIPlus
{
MPIPlus()
{
this->OpPtr = std::shared_ptr<MPI_Op>(new MPI_Op(MPI_NO_OP), [](MPI_Op* ptr) {
MPI_Op_free(ptr);
delete ptr;
});
MPI_Op_create(
[](void* a, void* b, int* len, MPI_Datatype*) {
T* ba = reinterpret_cast<T*>(a);
T* bb = reinterpret_cast<T*>(b);
for (int cc = 0; cc < (*len) / ElementSize; ++cc)
{
bb[cc] = ba[cc] + bb[cc];
}
},
1,
this->OpPtr.get());
}
~MPIPlus() {}
operator MPI_Op() const { return *this->OpPtr.get(); }
private:
std::shared_ptr<MPI_Op> OpPtr;
};
} // std::detail
template <>
struct plus<vtkm::Bounds>
{
MPI_Op get_mpi_op() const { return this->Op; }
vtkm::Bounds operator()(const vtkm::Bounds& lhs, const vtkm::Bounds& rhs) const
{
return lhs + rhs;
}
private:
std::detail::MPIPlus<vtkm::Bounds> Op;
};
template <>
struct plus<vtkm::Range>
{
MPI_Op get_mpi_op() const { return this->Op; }
vtkm::Range operator()(const vtkm::Range& lhs, const vtkm::Range& rhs) const { return lhs + rhs; }
private:
std::detail::MPIPlus<vtkm::Range> Op;
};
} }
namespace diy
{
namespace mpi
{
namespace detail
{
template <>
struct mpi_datatype<vtkm::Bounds>
{
static MPI_Datatype datatype() { return get_mpi_datatype<vtkm::Float64>(); }
static const void* address(const vtkm::Bounds& x) { return &x; }
static void* address(vtkm::Bounds& x) { return &x; }
static int count(const vtkm::Bounds&) { return 6; }
};
template <>
struct mpi_op<std::plus<vtkm::Bounds>>
{
static MPI_Op get(const std::plus<vtkm::Bounds>& op) { return op.get_mpi_op(); }
};
template <>
struct mpi_datatype<vtkm::Range>
{
static MPI_Datatype datatype() { return get_mpi_datatype<vtkm::Float64>(); }
static const void* address(const vtkm::Range& x) { return &x; }
static void* address(vtkm::Range& x) { return &x; }
static int count(const vtkm::Range&) { return 2; }
};
template <>
struct mpi_op<std::plus<vtkm::Range>>
{
static MPI_Op get(const std::plus<vtkm::Range>& op) { return op.get_mpi_op(); }
};
} // diy::mpi::detail
} // diy::mpi
} // diy
#endif #endif
namespace vtkm namespace vtkm
@ -286,51 +205,60 @@ void MultiBlock::ReplaceBlock(vtkm::Id index, vtkm::cont::DataSet& ds)
} }
} }
VTKM_CONT VTKM_CONT vtkm::Bounds MultiBlock::GetBounds(vtkm::Id coordinate_system_index) const
vtkm::Bounds MultiBlock::GetBounds(vtkm::Id coordinate_system_index) const
{ {
return this->GetBounds(coordinate_system_index,
VTKM_DEFAULT_COORDINATE_SYSTEM_TYPE_LIST_TAG(),
VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG());
}
template <typename TypeList>
VTKM_CONT vtkm::Bounds MultiBlock::GetBounds(vtkm::Id coordinate_system_index, TypeList) const
{
VTKM_IS_LIST_TAG(TypeList);
return this->GetBounds(
coordinate_system_index, TypeList(), VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG());
}
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::Bounds MultiBlock::GetBounds(vtkm::Id coordinate_system_index,
TypeList,
StorageList) const
{
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
#if defined(VTKM_ENABLE_MPI) #if defined(VTKM_ENABLE_MPI)
auto world = vtkm::cont::EnvironmentTracker::GetCommunicator(); auto world = vtkm::cont::EnvironmentTracker::GetCommunicator();
//const auto global_num_blocks = this->GetGlobalNumberOfBlocks(); diy::Master master(world,
1,
-1,
[]() -> void* { return new vtkm::Bounds(); },
[](void* ptr) { delete static_cast<vtkm::Bounds*>(ptr); });
const auto num_blocks = this->GetNumberOfBlocks(); vtkm::cont::AssignerMultiBlock assigner(*this);
diy::Master master(world, 1, -1); // populate master with blocks from `this`.
for (vtkm::Id cc = 0; cc < num_blocks; ++cc) diy::decompose(world.rank(), assigner, master);
{
int gid = cc * world.size() + world.rank();
master.add(gid, const_cast<vtkm::cont::DataSet*>(&this->Blocks[cc]), new diy::Link());
}
master.foreach ([&](const vtkm::cont::DataSet* block, const diy::Master::ProxyWithLink& cp) { auto self = (*this);
auto coords = block->GetCoordinateSystem(coordinate_system_index); master.foreach ([&](vtkm::Bounds* data, const diy::Master::ProxyWithLink& cp) {
const vtkm::Bounds bounds = coords.GetBounds(TypeList(), StorageList()); const vtkm::cont::DataSet& block = vtkm::cont::detail::GetBlock(self, cp);
cp.all_reduce(bounds, std::plus<vtkm::Bounds>()); try
{
vtkm::cont::CoordinateSystem coords = block.GetCoordinateSystem(coordinate_system_index);
*data = coords.GetBounds();
}
catch (const vtkm::cont::Error&)
{
}
}); });
master.process_collectives(); vtkm::cont::DecomposerMultiBlock decomposer(assigner);
auto bounds = master.proxy(0).get<vtkm::Bounds>(); diy::RegularSwapPartners partners(decomposer, /*k=*/2);
return bounds;
auto callback =
[](vtkm::Bounds* data, const diy::ReduceProxy& srp, const diy::RegularSwapPartners&) {
// 1. dequeue.
std::vector<int> incoming;
srp.incoming(incoming);
vtkm::Bounds message;
for (const int gid : incoming)
{
srp.dequeue(gid, message);
data->Include(message);
}
// 2. enqueue
for (int cc = 0; cc < srp.out_link().size(); ++cc)
{
srp.enqueue(srp.out_link().target(cc), *data);
}
};
diy::reduce(master, assigner, partners, callback);
if (master.size())
{
return (*master.block<vtkm::Bounds>(0));
}
return vtkm::Bounds();
#else #else
const vtkm::Id index = coordinate_system_index; const vtkm::Id index = coordinate_system_index;
@ -339,44 +267,16 @@ VTKM_CONT vtkm::Bounds MultiBlock::GetBounds(vtkm::Id coordinate_system_index,
vtkm::Bounds bounds; vtkm::Bounds bounds;
for (size_t i = 0; i < num_blocks; ++i) for (size_t i = 0; i < num_blocks; ++i)
{ {
vtkm::Bounds block_bounds = this->GetBlockBounds(i, index, TypeList(), StorageList()); vtkm::Bounds block_bounds = this->GetBlockBounds(i, index);
bounds.Include(block_bounds); bounds.Include(block_bounds);
} }
return bounds; return bounds;
#endif #endif
} }
VTKM_CONT
vtkm::Bounds MultiBlock::GetBlockBounds(const std::size_t& block_index,
vtkm::Id coordinate_system_index) const
{
return this->GetBlockBounds(block_index,
coordinate_system_index,
VTKM_DEFAULT_COORDINATE_SYSTEM_TYPE_LIST_TAG(),
VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG());
}
template <typename TypeList>
VTKM_CONT vtkm::Bounds MultiBlock::GetBlockBounds(const std::size_t& block_index, VTKM_CONT vtkm::Bounds MultiBlock::GetBlockBounds(const std::size_t& block_index,
vtkm::Id coordinate_system_index, vtkm::Id coordinate_system_index) const
TypeList) const
{ {
VTKM_IS_LIST_TAG(TypeList);
return this->GetBlockBounds(block_index,
coordinate_system_index,
TypeList(),
VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG());
}
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::Bounds MultiBlock::GetBlockBounds(const std::size_t& block_index,
vtkm::Id coordinate_system_index,
TypeList,
StorageList) const
{
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
const vtkm::Id index = coordinate_system_index; const vtkm::Id index = coordinate_system_index;
vtkm::cont::CoordinateSystem coords; vtkm::cont::CoordinateSystem coords;
try try
@ -391,117 +291,77 @@ VTKM_CONT vtkm::Bounds MultiBlock::GetBlockBounds(const std::size_t& block_index
<< "block " << block_index << ". vtkm error message: " << error.GetMessage(); << "block " << block_index << ". vtkm error message: " << error.GetMessage();
throw ErrorExecution(msg.str()); throw ErrorExecution(msg.str());
} }
return coords.GetBounds(TypeList(), StorageList()); return coords.GetBounds();
} }
VTKM_CONT VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> MultiBlock::GetGlobalRange(const int& index) const
vtkm::cont::ArrayHandle<vtkm::Range> MultiBlock::GetGlobalRange(const int& index) const
{ {
return this->GetGlobalRange(index, VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG());
}
template <typename TypeList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> MultiBlock::GetGlobalRange(const int& index,
TypeList) const
{
VTKM_IS_LIST_TAG(TypeList);
return this->GetGlobalRange(index, TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG());
}
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> MultiBlock::GetGlobalRange(const int& index,
TypeList,
StorageList) const
{
VTKM_IS_LIST_TAG(TypeList);
VTKM_IS_LIST_TAG(StorageList);
assert(this->Blocks.size() > 0); assert(this->Blocks.size() > 0);
vtkm::cont::Field field = this->Blocks.at(0).GetField(index); vtkm::cont::Field field = this->Blocks.at(0).GetField(index);
std::string field_name = field.GetName(); std::string field_name = field.GetName();
return this->GetGlobalRange(field_name, TypeList(), StorageList()); return this->GetGlobalRange(field_name);
} }
VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Range> MultiBlock::GetGlobalRange(const std::string& field_name) const
{
return this->GetGlobalRange(
field_name, VTKM_DEFAULT_TYPE_LIST_TAG(), VTKM_DEFAULT_STORAGE_LIST_TAG());
}
template <typename TypeList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> MultiBlock::GetGlobalRange( VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> MultiBlock::GetGlobalRange(
const std::string& field_name, const std::string& field_name) const
TypeList) const
{
VTKM_IS_LIST_TAG(TypeList);
return this->GetGlobalRange(field_name, TypeList(), VTKM_DEFAULT_STORAGE_LIST_TAG());
}
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range>
MultiBlock::GetGlobalRange(const std::string& field_name, TypeList, StorageList) const
{ {
#if defined(VTKM_ENABLE_MPI) #if defined(VTKM_ENABLE_MPI)
auto world = vtkm::cont::EnvironmentTracker::GetCommunicator(); using BlockMetaData = std::vector<vtkm::Range>;
const auto num_blocks = this->GetNumberOfBlocks();
diy::Master master(world); auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
for (vtkm::Id cc = 0; cc < num_blocks; ++cc) diy::Master master(comm,
{ 1,
int gid = cc * world.size() + world.rank(); -1,
master.add(gid, const_cast<vtkm::cont::DataSet*>(&this->Blocks[cc]), new diy::Link()); []() -> void* { return new BlockMetaData(); },
} [](void* ptr) { delete static_cast<BlockMetaData*>(ptr); });
// collect info about number of components in the field. vtkm::cont::AssignerMultiBlock assigner(*this);
master.foreach ([&](const vtkm::cont::DataSet* dataset, const diy::Master::ProxyWithLink& cp) {
if (dataset->HasField(field_name)) diy::decompose(comm.rank(), assigner, master);
auto self = (*this);
master.foreach ([&](BlockMetaData* data, const diy::Master::ProxyWithLink& cp) {
const vtkm::cont::DataSet& block = vtkm::cont::detail::GetBlock(self, cp);
if (block.HasField(field_name))
{ {
auto field = dataset->GetField(field_name); auto field = block.GetField(field_name);
const vtkm::cont::ArrayHandle<vtkm::Range> range = field.GetRange(TypeList(), StorageList()); const vtkm::cont::ArrayHandle<vtkm::Range> range = field.GetRange();
vtkm::Id components = range.GetPortalConstControl().GetNumberOfValues(); *data = vtkm::cont::detail::CopyArrayPortalToVector(range.GetPortalConstControl());
cp.all_reduce(components, diy::mpi::maximum<vtkm::Id>());
} }
}); });
master.process_collectives();
const vtkm::Id components = master.size() ? master.proxy(0).read<vtkm::Id>() : 0; vtkm::cont::DecomposerMultiBlock decomposer(assigner);
diy::RegularSwapPartners partners(decomposer, /*k=*/2);
auto callback =
[](BlockMetaData* data, const diy::ReduceProxy& srp, const diy::RegularSwapPartners&) {
std::vector<int> incoming;
srp.incoming(incoming);
// clear all collectives. // 1. dequeue
master.foreach ([&](const vtkm::cont::DataSet*, const diy::Master::ProxyWithLink& cp) { BlockMetaData message;
cp.collectives()->clear(); for (const int gid : incoming)
});
master.foreach ([&](const vtkm::cont::DataSet* dataset, const diy::Master::ProxyWithLink& cp) {
if (dataset->HasField(field_name))
{
auto field = dataset->GetField(field_name);
const vtkm::cont::ArrayHandle<vtkm::Range> range = field.GetRange(TypeList(), StorageList());
const auto v_range =
vtkm::cont::detail::CopyArrayPortalToVector(range.GetPortalConstControl());
for (const vtkm::Range& r : v_range)
{ {
cp.all_reduce(r, std::plus<vtkm::Range>()); srp.dequeue(gid, message);
data->resize(std::max(data->size(), message.size()));
for (size_t cc = 0; cc < data->size(); ++cc)
{
(*data)[cc].Include(message[cc]);
}
} }
// if current block has less that the max number of components, just add invalid ranges for the rest. // 2. enqueue
for (vtkm::Id cc = static_cast<vtkm::Id>(v_range.size()); cc < components; ++cc) for (int cc = 0; cc < srp.out_link().size(); ++cc)
{ {
cp.all_reduce(vtkm::Range(), std::plus<vtkm::Range>()); srp.enqueue(srp.out_link().target(cc), *data);
} }
} };
});
master.process_collectives();
std::vector<vtkm::Range> ranges(components);
// FIXME: is master.size() == 0 i.e. there are no blocks on the current rank,
// this method won't return valid range.
if (master.size() > 0)
{
for (vtkm::Id cc = 0; cc < components; ++cc)
{
ranges[cc] = master.proxy(0).get<vtkm::Range>();
}
}
diy::reduce(master, assigner, partners, callback);
BlockMetaData ranges;
if (master.size())
{
ranges = *(master.block<BlockMetaData>(0));
}
vtkm::cont::ArrayHandle<vtkm::Range> tmprange = vtkm::cont::make_ArrayHandle(ranges); vtkm::cont::ArrayHandle<vtkm::Range> tmprange = vtkm::cont::make_ArrayHandle(ranges);
vtkm::cont::ArrayHandle<vtkm::Range> range; vtkm::cont::ArrayHandle<vtkm::Range> range;
vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandle(ranges), range); vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandle(ranges), range);
@ -522,7 +382,7 @@ MultiBlock::GetGlobalRange(const std::string& field_name, TypeList, StorageList)
} }
const vtkm::cont::Field& field = this->Blocks[i].GetField(field_name); const vtkm::cont::Field& field = this->Blocks[i].GetField(field_name);
vtkm::cont::ArrayHandle<vtkm::Range> sub_range = field.GetRange(TypeList(), StorageList()); vtkm::cont::ArrayHandle<vtkm::Range> sub_range = field.GetRange();
vtkm::cont::ArrayHandle<vtkm::Range>::PortalConstControl sub_range_control = vtkm::cont::ArrayHandle<vtkm::Range>::PortalConstControl sub_range_control =
sub_range.GetPortalConstControl(); sub_range.GetPortalConstControl();
@ -546,7 +406,6 @@ MultiBlock::GetGlobalRange(const std::string& field_name, TypeList, StorageList)
throw ErrorExecution(msg.str()); throw ErrorExecution(msg.str());
} }
for (vtkm::Id c = 0; c < components; ++c) for (vtkm::Id c = 0; c < components; ++c)
{ {
vtkm::Range s_range = sub_range_control.Get(c); vtkm::Range s_range = sub_range_control.Get(c);

@ -92,27 +92,11 @@ public:
VTKM_CONT VTKM_CONT
vtkm::Bounds GetBounds(vtkm::Id coordinate_system_index = 0) const; vtkm::Bounds GetBounds(vtkm::Id coordinate_system_index = 0) const;
template <typename TypeList>
VTKM_CONT vtkm::Bounds GetBounds(vtkm::Id coordinate_system_index, TypeList) const;
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::Bounds GetBounds(vtkm::Id coordinate_system_index, TypeList, StorageList) const;
/// get the bounds of a coordinate system within a given DataSet /// get the bounds of a coordinate system within a given DataSet
VTKM_CONT VTKM_CONT
vtkm::Bounds GetBlockBounds(const std::size_t& block_index, vtkm::Bounds GetBlockBounds(const std::size_t& block_index,
vtkm::Id coordinate_system_index = 0) const; vtkm::Id coordinate_system_index = 0) const;
template <typename TypeList>
VTKM_CONT vtkm::Bounds GetBlockBounds(const std::size_t& block_index,
vtkm::Id coordinate_system_index,
TypeList) const;
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::Bounds GetBlockBounds(const std::size_t& block_index,
vtkm::Id coordinate_system_index,
TypeList,
StorageList) const;
//@{ //@{
/// Get the unified range of the same field within all contained DataSet. /// Get the unified range of the same field within all contained DataSet.
/// These methods are not thread-safe and may involve global communication /// These methods are not thread-safe and may involve global communication
@ -120,25 +104,8 @@ public:
VTKM_CONT VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Range> GetGlobalRange(const std::string& field_name) const; vtkm::cont::ArrayHandle<vtkm::Range> GetGlobalRange(const std::string& field_name) const;
template <typename TypeList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> GetGlobalRange(const std::string& field_name,
TypeList) const;
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> GetGlobalRange(const std::string& field_name,
TypeList,
StorageList) const;
VTKM_CONT VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Range> GetGlobalRange(const int& index) const; vtkm::cont::ArrayHandle<vtkm::Range> GetGlobalRange(const int& index) const;
template <typename TypeList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> GetGlobalRange(const int& index, TypeList) const;
template <typename TypeList, typename StorageList>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range> GetGlobalRange(const int& index,
TypeList,
StorageList) const;
//@} //@}
VTKM_CONT VTKM_CONT

@ -17,7 +17,6 @@
// Laboratory (LANL), the U.S. Government retains certain rights in // Laboratory (LANL), the U.S. Government retains certain rights in
// this software. // this software.
//============================================================================ //============================================================================
#ifndef vtk_m_cont_PointLocatorUniformGrid_h #ifndef vtk_m_cont_PointLocatorUniformGrid_h
#define vtk_m_cont_PointLocatorUniformGrid_h #define vtk_m_cont_PointLocatorUniformGrid_h

@ -22,6 +22,7 @@
#include <vtkm/cont/DeviceAdapterAlgorithm.h> #include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/ErrorBadAllocation.h> #include <vtkm/cont/ErrorBadAllocation.h>
#include <vtkm/cont/ErrorBadDevice.h>
#include <vtkm/cont/RuntimeDeviceInformation.h> #include <vtkm/cont/RuntimeDeviceInformation.h>
namespace vtkm namespace vtkm
@ -85,6 +86,23 @@ public:
this->SetDeviceState(deviceId, name, false); this->SetDeviceState(deviceId, name, false);
} }
//@{
/// Report a ErrorBadDevice failure and flag the device as unusable.
template <typename DeviceAdapterTag>
VTKM_CONT void ReportBadDeviceFailure(DeviceAdapterTag, const vtkm::cont::ErrorBadDevice&)
{
using Traits = vtkm::cont::DeviceAdapterTraits<DeviceAdapterTag>;
this->SetDeviceState(Traits::GetId(), Traits::GetName(), false);
}
VTKM_CONT void ReportBadDeviceFailure(vtkm::Int8 deviceId,
const std::string& name,
const vtkm::cont::ErrorBadDevice&)
{
this->SetDeviceState(deviceId, name, false);
}
//@}
/// Reset the tracker for the given device. This will discard any updates /// Reset the tracker for the given device. This will discard any updates
/// caused by reported failures /// caused by reported failures
/// ///

@ -46,6 +46,11 @@ void HandleTryExecuteException(vtkm::Int8 deviceId,
//than we fallback to another device //than we fallback to another device
tracker.ReportAllocationFailure(deviceId, name, e); tracker.ReportAllocationFailure(deviceId, name, e);
} }
catch (vtkm::cont::ErrorBadDevice& e)
{
std::cerr << "caught ErrorBadDevice: " << e.GetMessage() << std::endl;
tracker.ReportBadDeviceFailure(deviceId, name, e);
}
catch (vtkm::cont::ErrorBadType& e) catch (vtkm::cont::ErrorBadType& e)
{ {
//should bad type errors should stop the execution, instead of //should bad type errors should stop the execution, instead of

@ -23,6 +23,7 @@
#include <vtkm/cont/DeviceAdapterListTag.h> #include <vtkm/cont/DeviceAdapterListTag.h>
#include <vtkm/cont/ErrorBadType.h> #include <vtkm/cont/ErrorBadType.h>
#include <vtkm/cont/ErrorBadValue.h> #include <vtkm/cont/ErrorBadValue.h>
#include <vtkm/cont/internal/DeviceAdapterListHelpers.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h> #include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <vtkm/cont/internal/VirtualObjectTransfer.h> #include <vtkm/cont/internal/VirtualObjectTransfer.h>
@ -101,9 +102,10 @@ public:
this->Internals->VirtualObject = derived; this->Internals->VirtualObject = derived;
this->Internals->Owner = acquireOwnership; this->Internals->Owner = acquireOwnership;
vtkm::cont::ForEachValidDevice( vtkm::cont::internal::ForEachValidDevice(devices,
devices, CreateTransferInterface<VirtualDerivedType>(),
CreateTransferInterface<VirtualDerivedType>(this->Internals->Transfers.data(), derived)); this->Internals->Transfers.data(),
derived);
} }
} }
@ -202,18 +204,12 @@ private:
}; };
template <typename VirtualDerivedType> template <typename VirtualDerivedType>
class CreateTransferInterface struct CreateTransferInterface
{ {
public:
CreateTransferInterface(std::unique_ptr<TransferInterface>* transfers,
const VirtualDerivedType* virtualObject)
: Transfers(transfers)
, VirtualObject(virtualObject)
{
}
template <typename DeviceAdapter> template <typename DeviceAdapter>
void operator()(DeviceAdapter) const VTKM_CONT void operator()(DeviceAdapter,
std::unique_ptr<TransferInterface>* transfers,
const VirtualDerivedType* virtualObject) const
{ {
using DeviceInfo = vtkm::cont::DeviceAdapterTraits<DeviceAdapter>; using DeviceInfo = vtkm::cont::DeviceAdapterTraits<DeviceAdapter>;
@ -225,12 +221,8 @@ private:
throw vtkm::cont::ErrorBadType(msg); throw vtkm::cont::ErrorBadType(msg);
} }
using TransferImpl = TransferInterfaceImpl<VirtualDerivedType, DeviceAdapter>; using TransferImpl = TransferInterfaceImpl<VirtualDerivedType, DeviceAdapter>;
this->Transfers[DeviceInfo::GetId()].reset(new TransferImpl(this->VirtualObject)); transfers[DeviceInfo::GetId()].reset(new TransferImpl(virtualObject));
} }
private:
std::unique_ptr<TransferInterface>* Transfers;
const VirtualDerivedType* VirtualObject;
}; };
struct InternalStruct struct InternalStruct

@ -20,6 +20,7 @@
set(unit_tests set(unit_tests
UnitTestCudaArrayHandleFancy.cu UnitTestCudaArrayHandleFancy.cu
UnitTestCudaArrayHandleVirtualCoordinates.cu
UnitTestCudaCellLocatorTwoLevelUniformGrid.cu UnitTestCudaCellLocatorTwoLevelUniformGrid.cu
UnitTestCudaComputeRange.cu UnitTestCudaComputeRange.cu
UnitTestCudaDataSetExplicit.cu UnitTestCudaDataSetExplicit.cu

@ -0,0 +1,27 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/testing/TestingArrayHandleVirtualCoordinates.h>
int UnitTestCudaArrayHandleVirtualCoordinates(int, char* [])
{
return vtkm::cont::testing::TestingArrayHandleVirtualCoordinates<
vtkm::cont::DeviceAdapterTagCuda>::Run();
}

@ -32,6 +32,7 @@ set(headers
DeviceAdapterAlgorithmGeneral.h DeviceAdapterAlgorithmGeneral.h
DeviceAdapterDefaultSelection.h DeviceAdapterDefaultSelection.h
DeviceAdapterError.h DeviceAdapterError.h
DeviceAdapterListHelpers.h
DeviceAdapterTag.h DeviceAdapterTag.h
DynamicTransform.h DynamicTransform.h
FunctorsGeneral.h FunctorsGeneral.h

@ -0,0 +1,138 @@
//============================================================================
// 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 2016 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2016 UT-Battelle, LLC.
// Copyright 2016 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.
//============================================================================
#ifndef vtk_m_cont_internal_DeviceAdapterListHelpers_h
#define vtk_m_cont_internal_DeviceAdapterListHelpers_h
#include <vtkm/ListTag.h>
#include <vtkm/cont/ErrorBadDevice.h>
#include <vtkm/cont/RuntimeDeviceTracker.h>
namespace vtkm
{
namespace cont
{
namespace internal
{
//============================================================================
template <typename FunctorType>
class ExecuteIfValidDeviceTag
{
private:
template <typename DeviceAdapter>
using EnableIfValid = std::enable_if<vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::Valid>;
template <typename DeviceAdapter>
using EnableIfInvalid = std::enable_if<!vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::Valid>;
public:
explicit ExecuteIfValidDeviceTag(const FunctorType& functor)
: Functor(functor)
{
}
template <typename DeviceAdapter, typename... Args>
typename EnableIfValid<DeviceAdapter>::type operator()(
DeviceAdapter device,
const vtkm::cont::RuntimeDeviceTracker& tracker,
Args&&... args) const
{
if (tracker.CanRunOn(device))
{
this->Functor(device, std::forward<Args>(args)...);
}
}
// do not generate code for invalid devices
template <typename DeviceAdapter, typename... Args>
typename EnableIfInvalid<DeviceAdapter>::type operator()(DeviceAdapter,
const vtkm::cont::RuntimeDeviceTracker&,
Args&&...) const
{
}
private:
FunctorType Functor;
};
/// Execute the given functor on each valid device in \c DeviceList.
///
template <typename DeviceList, typename Functor, typename... Args>
VTKM_CONT void ForEachValidDevice(DeviceList devices, const Functor& functor, Args&&... args)
{
auto tracker = vtkm::cont::GetGlobalRuntimeDeviceTracker();
ExecuteIfValidDeviceTag<Functor> wrapped(functor);
vtkm::ListForEach(wrapped, devices, tracker, std::forward<Args>(args)...);
}
//============================================================================
template <typename FunctorType>
class ExecuteIfSameDeviceId
{
public:
ExecuteIfSameDeviceId(FunctorType functor)
: Functor(functor)
{
}
template <typename DeviceAdapter, typename... Args>
void operator()(DeviceAdapter device,
vtkm::cont::DeviceAdapterId deviceId,
bool& status,
Args&&... args) const
{
if (vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetId() == deviceId)
{
VTKM_ASSERT(status == false);
this->Functor(device, std::forward<Args>(args)...);
status = true;
}
}
private:
FunctorType Functor;
};
/// Finds the \c DeviceAdapterTag in \c DeviceList with id equal to deviceId
/// and executes the functor with the tag. Throws \c ErrorBadDevice if a valid
/// \c DeviceAdapterTag is not found.
///
template <typename DeviceList, typename Functor, typename... Args>
VTKM_CONT void FindDeviceAdapterTagAndCall(vtkm::cont::DeviceAdapterId deviceId,
DeviceList devices,
const Functor& functor,
Args&&... args)
{
bool status = false;
ExecuteIfSameDeviceId<Functor> wrapped(functor);
ForEachValidDevice(devices, wrapped, deviceId, status, std::forward<Args>(args)...);
if (!status)
{
std::string msg =
"Device with id " + std::to_string(deviceId) + " is either not in the list or is invalid";
throw vtkm::cont::ErrorBadDevice(msg);
}
}
}
}
} // vtkm::cont::internal
#endif // vtk_m_cont_internal_DeviceAdapterListHelpers_h

@ -68,6 +68,7 @@ private:
} }
} }
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename InIter, typename OutIter> template <typename InIter, typename OutIter>
VTKM_EXEC static void DoCopy(InIter src, InIter srcEnd, OutIter dst, std::true_type) VTKM_EXEC static void DoCopy(InIter src, InIter srcEnd, OutIter dst, std::true_type)
{ {

@ -21,6 +21,7 @@
set(unit_tests set(unit_tests
UnitTestSerialArrayHandle.cxx UnitTestSerialArrayHandle.cxx
UnitTestSerialArrayHandleFancy.cxx UnitTestSerialArrayHandleFancy.cxx
UnitTestSerialArrayHandleVirtualCoordinates.cxx
UnitTestSerialCellLocatorTwoLevelUniformGrid.cxx UnitTestSerialCellLocatorTwoLevelUniformGrid.cxx
UnitTestSerialComputeRange.cxx UnitTestSerialComputeRange.cxx
UnitTestSerialDataSetExplicit.cxx UnitTestSerialDataSetExplicit.cxx

@ -0,0 +1,27 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/cont/testing/TestingArrayHandleVirtualCoordinates.h>
int UnitTestSerialArrayHandleVirtualCoordinates(int, char* [])
{
return vtkm::cont::testing::TestingArrayHandleVirtualCoordinates<
vtkm::cont::DeviceAdapterTagSerial>::Run();
}

@ -98,7 +98,6 @@ struct CopyBody
vtkm::Id InputOffset; vtkm::Id InputOffset;
vtkm::Id OutputOffset; vtkm::Id OutputOffset;
VTKM_EXEC_CONT
CopyBody(const InputPortalType& inPortal, CopyBody(const InputPortalType& inPortal,
const OutputPortalType& outPortal, const OutputPortalType& outPortal,
vtkm::Id inOffset, vtkm::Id inOffset,
@ -127,12 +126,14 @@ struct CopyBody
} }
} }
VTKM_SUPPRESS_EXEC_WARNINGS
template <typename InIter, typename OutIter> template <typename InIter, typename OutIter>
VTKM_EXEC void DoCopy(InIter src, InIter srcEnd, OutIter dst, std::true_type) const VTKM_EXEC void DoCopy(InIter src, InIter srcEnd, OutIter dst, std::true_type) const
{ {
std::copy(src, srcEnd, dst); std::copy(src, srcEnd, dst);
} }
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC VTKM_EXEC
void operator()(const ::tbb::blocked_range<vtkm::Id>& range) const void operator()(const ::tbb::blocked_range<vtkm::Id>& range) const
{ {

@ -21,6 +21,7 @@
set(unit_tests set(unit_tests
UnitTestTBBArrayHandle.cxx UnitTestTBBArrayHandle.cxx
UnitTestTBBArrayHandleFancy.cxx UnitTestTBBArrayHandleFancy.cxx
UnitTestTBBArrayHandleVirtualCoordinates.cxx
UnitTestTBBCellLocatorTwoLevelUniformGrid.cxx UnitTestTBBCellLocatorTwoLevelUniformGrid.cxx
UnitTestTBBComputeRange.cxx UnitTestTBBComputeRange.cxx
UnitTestTBBDataSetExplicit.cxx UnitTestTBBDataSetExplicit.cxx

@ -0,0 +1,27 @@
//============================================================================
// 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.
//============================================================================
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
#include <vtkm/cont/testing/TestingArrayHandleVirtualCoordinates.h>
int UnitTestTBBArrayHandleVirtualCoordinates(int, char* [])
{
return vtkm::cont::testing::TestingArrayHandleVirtualCoordinates<
vtkm::cont::DeviceAdapterTagTBB>::Run();
}

@ -23,6 +23,7 @@ set(headers
MakeTestDataSet.h MakeTestDataSet.h
Testing.h Testing.h
TestingArrayHandles.h TestingArrayHandles.h
TestingArrayHandleVirtualCoordinates.h
TestingCellLocatorTwoLevelUniformGrid.h TestingCellLocatorTwoLevelUniformGrid.h
TestingComputeRange.h TestingComputeRange.h
TestingDeviceAdapter.h TestingDeviceAdapter.h
@ -53,6 +54,7 @@ set(unit_tests
UnitTestArrayHandleUniformPointCoordinates.cxx UnitTestArrayHandleUniformPointCoordinates.cxx
UnitTestArrayHandleConcatenate.cxx UnitTestArrayHandleConcatenate.cxx
UnitTestArrayPortalToIterators.cxx UnitTestArrayPortalToIterators.cxx
UnitTestCellLocator.cxx
UnitTestCellSetExplicit.cxx UnitTestCellSetExplicit.cxx
UnitTestCellSetPermutation.cxx UnitTestCellSetPermutation.cxx
UnitTestContTesting.cxx UnitTestContTesting.cxx

@ -0,0 +1,117 @@
//============================================================================
// 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.
//============================================================================
#ifndef vtk_m_cont_testing_TestingArrayHandleVirtualCoordinates_h
#define vtk_m_cont_testing_TestingArrayHandleVirtualCoordinates_h
#include <vtkm/cont/ArrayHandleCartesianProduct.h>
#include <vtkm/cont/ArrayHandleUniformPointCoordinates.h>
#include <vtkm/cont/ArrayHandleVirtualCoordinates.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
namespace vtkm
{
namespace cont
{
namespace testing
{
namespace
{
struct CopyWorklet : public vtkm::worklet::WorkletMapField
{
typedef void ControlSignature(FieldIn<FieldCommon> in, FieldOut<FieldCommon> out);
typedef _2 ExecutionSignature(_1);
template <typename T>
VTKM_EXEC T operator()(const T& in) const
{
return in;
}
};
} // anonymous namespace
template <typename DeviceAdapter>
class TestingArrayHandleVirtualCoordinates
{
private:
using ArrayHandleRectilinearCoords =
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>;
template <typename T, typename InStorageTag, typename OutStorageTag>
static void TestVirtualAccess(const vtkm::cont::ArrayHandle<T, InStorageTag>& in,
vtkm::cont::ArrayHandle<T, OutStorageTag>& out)
{
vtkm::worklet::DispatcherMapField<CopyWorklet, DeviceAdapter>().Invoke(
vtkm::cont::ArrayHandleVirtualCoordinates(in),
vtkm::cont::ArrayHandleVirtualCoordinates(out));
VTKM_TEST_ASSERT(test_equal_portals(in.GetPortalConstControl(), out.GetPortalConstControl()),
"Input and output portals don't match");
}
static void TestAll()
{
using PointType = vtkm::Vec<vtkm::FloatDefault, 3>;
static const vtkm::Id length = 64;
vtkm::cont::ArrayHandle<PointType> out;
std::cout << "Testing basic ArrayHandle as input\n";
vtkm::cont::ArrayHandle<PointType> a1;
a1.Allocate(length);
for (vtkm::Id i = 0; i < length; ++i)
{
a1.GetPortalControl().Set(i, TestValue(i, PointType()));
}
TestVirtualAccess(a1, out);
std::cout << "Testing ArrayHandleUniformPointCoordinates as input\n";
TestVirtualAccess(vtkm::cont::ArrayHandleUniformPointCoordinates(vtkm::Id3(4, 4, 4)), out);
std::cout << "Testing ArrayHandleCartesianProduct as input\n";
vtkm::cont::ArrayHandle<vtkm::FloatDefault> c1, c2, c3;
c1.Allocate(length);
c2.Allocate(length);
c3.Allocate(length);
for (vtkm::Id i = 0; i < length; ++i)
{
auto p = a1.GetPortalConstControl().Get(i);
c1.GetPortalControl().Set(i, p[0]);
c2.GetPortalControl().Set(i, p[1]);
c3.GetPortalControl().Set(i, p[2]);
}
TestVirtualAccess(vtkm::cont::make_ArrayHandleCartesianProduct(c1, c2, c3), out);
}
public:
static int Run() { return vtkm::cont::testing::Testing::Run(TestAll); }
};
}
}
} // vtkm::cont::testing
#endif // vtk_m_cont_testing_TestingArrayHandleVirtualCoordinates_h

@ -91,10 +91,7 @@ vtkm::cont::DataSet MakeTestDataSet(const vtkm::Vec<vtkm::Id, DIMENSIONS>& dims,
// copy points // copy points
vtkm::cont::ArrayHandle<PointType> points; vtkm::cont::ArrayHandle<PointType> points;
Algorithm::Copy(uniformDs.GetCoordinateSystem() Algorithm::Copy(uniformDs.GetCoordinateSystem().GetData(), points);
.GetData()
.template Cast<vtkm::cont::ArrayHandleUniformPointCoordinates>(),
points);
vtkm::Id numberOfCells = uniformDs.GetCellSet().GetNumberOfCells(); vtkm::Id numberOfCells = uniformDs.GetCellSet().GetNumberOfCells();
vtkm::Id numberOfIndices = numberOfCells * PointsPerCell; vtkm::Id numberOfIndices = numberOfCells * PointsPerCell;

@ -37,11 +37,10 @@ namespace
const vtkm::Id ARRAY_SIZE = 10; const vtkm::Id ARRAY_SIZE = 10;
template <typename ValueType>
struct MySquare struct MySquare
{ {
template <typename U> template <typename U>
VTKM_EXEC ValueType operator()(U u) const VTKM_EXEC auto operator()(U u) const -> decltype(vtkm::dot(u, u))
{ {
return vtkm::dot(u, u); return vtkm::dot(u, u);
} }
@ -59,7 +58,7 @@ struct CheckTransformFunctor : vtkm::exec::FunctorBase
using T = typename TransformedPortalType::ValueType; using T = typename TransformedPortalType::ValueType;
typename OriginalPortalType::ValueType original = this->OriginalPortal.Get(index); typename OriginalPortalType::ValueType original = this->OriginalPortal.Get(index);
T transformed = this->TransformedPortal.Get(index); T transformed = this->TransformedPortal.Get(index);
if (!test_equal(transformed, MySquare<T>()(original))) if (!test_equal(transformed, MySquare{}(original)))
{ {
this->RaiseError("Encountered bad transformed value."); this->RaiseError("Encountered bad transformed value.");
} }
@ -107,7 +106,7 @@ VTKM_CONT void CheckControlPortals(const OriginalArrayHandleType& originalArray,
using T = typename TransformedPortalType::ValueType; using T = typename TransformedPortalType::ValueType;
typename OriginalPortalType::ValueType original = originalPortal.Get(index); typename OriginalPortalType::ValueType original = originalPortal.Get(index);
T transformed = transformedPortal.Get(index); T transformed = transformedPortal.Get(index);
VTKM_TEST_ASSERT(test_equal(transformed, MySquare<T>()(original)), "Bad transform value."); VTKM_TEST_ASSERT(test_equal(transformed, MySquare{}(original)), "Bad transform value.");
} }
} }
@ -115,20 +114,19 @@ template <typename InputValueType>
struct TransformTests struct TransformTests
{ {
using OutputValueType = typename vtkm::VecTraits<InputValueType>::ComponentType; using OutputValueType = typename vtkm::VecTraits<InputValueType>::ComponentType;
using FunctorType = MySquare<OutputValueType>;
using TransformHandle = using TransformHandle =
vtkm::cont::ArrayHandleTransform<vtkm::cont::ArrayHandle<InputValueType>, FunctorType>; vtkm::cont::ArrayHandleTransform<vtkm::cont::ArrayHandle<InputValueType>, MySquare>;
using CountingTransformHandle = using CountingTransformHandle =
vtkm::cont::ArrayHandleTransform<vtkm::cont::ArrayHandleCounting<InputValueType>, FunctorType>; vtkm::cont::ArrayHandleTransform<vtkm::cont::ArrayHandleCounting<InputValueType>, MySquare>;
using Device = VTKM_DEFAULT_DEVICE_ADAPTER_TAG; using Device = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<Device>; using Algorithm = vtkm::cont::DeviceAdapterAlgorithm<Device>;
void operator()() const void operator()() const
{ {
FunctorType functor; MySquare functor;
std::cout << "Test a transform handle with a counting handle as the values" << std::endl; std::cout << "Test a transform handle with a counting handle as the values" << std::endl;
vtkm::cont::ArrayHandleCounting<InputValueType> counting = vtkm::cont::make_ArrayHandleCounting( vtkm::cont::ArrayHandleCounting<InputValueType> counting = vtkm::cont::make_ArrayHandleCounting(

@ -0,0 +1,66 @@
//============================================================================
// 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 2017 National Technology & Engineering Solutions of Sandia, LLC (NTESS).
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 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.
//============================================================================
#include <vtkm/cont/CellLocator.h>
#include <vtkm/cont/DataSetBuilderUniform.h>
#include <vtkm/cont/testing/Testing.h>
namespace
{
void TestCellLocator()
{
using PointType = vtkm::Vec<vtkm::FloatDefault, 3>;
VTKM_DEFAULT_DEVICE_ADAPTER_TAG device;
const vtkm::Id SIZE = 4;
auto ds =
vtkm::cont::DataSetBuilderUniform::Create(vtkm::Id3(SIZE), PointType(0.0f), PointType(1.0f));
vtkm::cont::CellLocator locator;
locator.SetCellSet(ds.GetCellSet());
locator.SetCoordinates(ds.GetCoordinateSystem());
locator.Build(device);
PointType points[] = {
{ 0.25, 0.25, 0.25 }, { 1.25, 1.25, 1.25 }, { 2.25, 2.25, 2.25 }, { 3.25, 3.25, 3.25 }
};
vtkm::cont::ArrayHandle<vtkm::Id> cellIds;
vtkm::cont::ArrayHandle<PointType> parametricCoords;
locator.FindCells(vtkm::cont::make_ArrayHandle(points, 4), cellIds, parametricCoords, device);
const vtkm::Id NCELLS_PER_AXIS = SIZE - 1;
const vtkm::Id DIA_STRIDE = (NCELLS_PER_AXIS * NCELLS_PER_AXIS) + NCELLS_PER_AXIS + 1;
for (int i = 0; i < 3; ++i)
{
VTKM_TEST_ASSERT(cellIds.GetPortalConstControl().Get(i) == (i * DIA_STRIDE),
"Incorrect cell-id value");
VTKM_TEST_ASSERT(parametricCoords.GetPortalConstControl().Get(i) == PointType(0.25f),
"Incorrect parametric coordinate value");
}
VTKM_TEST_ASSERT(cellIds.GetPortalConstControl().Get(3) == -1, "Incorrect cell-id value");
}
} // anonymous namespace
int UnitTestCellLocator(int, char* [])
{
return vtkm::cont::testing::Testing::Run(TestCellLocator);
}

@ -36,7 +36,12 @@
#include <vtkm/exec/ConnectivityStructured.h> #include <vtkm/exec/ConnectivityStructured.h>
#if defined(VTKM_ENABLE_MPI) #if defined(VTKM_ENABLE_MPI)
#include <diy/master.hpp>
// clang-format off
#include <vtkm/thirdparty/diy/Configure.h>
#include VTKM_DIY(diy/master.hpp)
// clang-format on
#endif #endif
void DataSet_Compare(vtkm::cont::DataSet& LeftDateSet, vtkm::cont::DataSet& RightDateSet); void DataSet_Compare(vtkm::cont::DataSet& LeftDateSet, vtkm::cont::DataSet& RightDateSet);

@ -29,14 +29,16 @@ namespace vtkm
namespace exec namespace exec
{ {
/// The following classes have been deprecated and are meant to be used
/// internally only. Please use the \c WholeArrayIn, \c WholeArrayOut, and
/// \c WholeArrayInOut \c ControlSignature tags instead.
/// \c ExecutionWholeArray is an execution object that allows an array handle /// \c ExecutionWholeArray is an execution object that allows an array handle
/// content to be a parameter in an execution environment /// content to be a parameter in an execution environment
/// function. This can be used to allow worklets to have a shared search /// function. This can be used to allow worklets to have a shared search
/// structure /// structure.
/// ///
template <typename T, template <typename T, typename StorageTag, typename DeviceAdapterTag>
typename StorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename DeviceAdapterTag = VTKM_DEFAULT_DEVICE_ADAPTER_TAG>
class ExecutionWholeArray : public vtkm::exec::ExecutionObjectBase class ExecutionWholeArray : public vtkm::exec::ExecutionObjectBase
{ {
public: public:
@ -86,9 +88,7 @@ private:
/// function. This can be used to allow worklets to have a shared search /// function. This can be used to allow worklets to have a shared search
/// structure /// structure
/// ///
template <typename T, template <typename T, typename StorageTag, typename DeviceAdapterTag>
typename StorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename DeviceAdapterTag = VTKM_DEFAULT_DEVICE_ADAPTER_TAG>
class ExecutionWholeArrayConst : public vtkm::exec::ExecutionObjectBase class ExecutionWholeArrayConst : public vtkm::exec::ExecutionObjectBase
{ {
public: public:

@ -37,12 +37,6 @@ namespace
struct TestExecObject struct TestExecObject
{ {
VTKM_EXEC_CONT
TestExecObject()
: Portal()
{
}
VTKM_EXEC_CONT VTKM_EXEC_CONT
TestExecObject(vtkm::exec::cuda::internal::ArrayPortalFromThrust<vtkm::Id> portal) TestExecObject(vtkm::exec::cuda::internal::ArrayPortalFromThrust<vtkm::Id> portal)
: Portal(portal) : Portal(portal)
@ -62,6 +56,7 @@ struct MyOutputToInputMapPortal
struct MyVisitArrayPortal struct MyVisitArrayPortal
{ {
using ValueType = vtkm::IdComponent; using ValueType = vtkm::IdComponent;
VTKM_EXEC_CONT
vtkm::IdComponent Get(vtkm::Id) const { return 1; } vtkm::IdComponent Get(vtkm::Id) const { return 1; }
}; };

File diff suppressed because it is too large Load Diff

@ -51,7 +51,7 @@ $# Ignore the following comment. It is meant for the generated file.
#include <vtkm/exec/arg/Fetch.h> #include <vtkm/exec/arg/Fetch.h>
$# This needs to match the max_parameters in FunctionInterfaceDetailPre.h.in $# This needs to match the max_parameters in FunctionInterfaceDetailPre.h.in
$py(max_parameters=10)\ $py(max_parameters=20)\
#if VTKM_MAX_FUNCTION_PARAMETERS != $(max_parameters) #if VTKM_MAX_FUNCTION_PARAMETERS != $(max_parameters)
#error Mismatch of maximum parameters between FunctionInterfaceDatailPre.h.in and WorkletInvokeFunctorDetail.h.in #error Mismatch of maximum parameters between FunctionInterfaceDatailPre.h.in and WorkletInvokeFunctorDetail.h.in
#endif #endif

@ -28,38 +28,6 @@ namespace vtkm
namespace filter namespace filter
{ {
namespace detail
{
template <typename Device>
struct CleanCompactPointArrayFunctor
{
vtkm::cont::DataSet& OutDataSet;
std::string Name;
const vtkm::filter::CleanGrid* Self;
CleanCompactPointArrayFunctor(vtkm::cont::DataSet& outDataSet,
const std::string& name,
const vtkm::filter::CleanGrid* self)
: OutDataSet(outDataSet)
, Name(name)
, Self(self)
{
}
template <typename ArrayHandleType>
void operator()(const ArrayHandleType& coordSystemArray) const
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType);
vtkm::cont::ArrayHandle<typename ArrayHandleType::ValueType> outArray =
this->Self->MapPointField(coordSystemArray, Device());
this->OutDataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem(this->Name, outArray));
}
};
} // namespace detail
inline VTKM_CONT CleanGrid::CleanGrid() inline VTKM_CONT CleanGrid::CleanGrid()
: CompactPointFields(true) : CompactPointFields(true)
{ {
@ -128,9 +96,8 @@ inline VTKM_CONT vtkm::filter::Result CleanGrid::DoExecute(const vtkm::cont::Dat
if (this->GetCompactPointFields()) if (this->GetCompactPointFields())
{ {
vtkm::filter::ApplyPolicy(coordSystem, policy, vtkm::filter::FilterTraits<CleanGrid>()) auto outArray = this->MapPointField(coordSystem.GetData(), Device());
.CastAndCall( outData.AddCoordinateSystem(vtkm::cont::CoordinateSystem(coordSystem.GetName(), outArray));
detail::CleanCompactPointArrayFunctor<Device>(outData, coordSystem.GetName(), this));
} }
else else
{ {

@ -95,9 +95,7 @@ inline VTKM_CONT vtkm::filter::Result ClipWithField::DoExecute(
output.AddCellSet(outputCellSet); output.AddCellSet(outputCellSet);
// Compute the new boundary points and add them to the output: // Compute the new boundary points and add them to the output:
vtkm::cont::DynamicArrayHandle outputCoordsArray; auto outputCoordsArray = this->Worklet.ProcessPointField(inputCoords.GetData(), device);
PointMapHelper<DeviceAdapter> pointMapper(this->Worklet, outputCoordsArray);
vtkm::filter::ApplyPolicy(inputCoords, policy).CastAndCall(pointMapper);
vtkm::cont::CoordinateSystem outputCoords(inputCoords.GetName(), outputCoordsArray); vtkm::cont::CoordinateSystem outputCoords(inputCoords.GetName(), outputCoordsArray);
output.AddCoordinateSystem(outputCoords); output.AddCoordinateSystem(outputCoords);
vtkm::filter::Result result(output); vtkm::filter::Result result(output);

@ -72,9 +72,7 @@ inline vtkm::filter::Result ClipWithImplicitFunction::DoExecute(
vtkm::filter::ApplyPolicy(cells, policy), this->Function, inputCoords, device); vtkm::filter::ApplyPolicy(cells, policy), this->Function, inputCoords, device);
// compute output coordinates // compute output coordinates
vtkm::cont::DynamicArrayHandle outputCoordsArray; auto outputCoordsArray = this->Worklet.ProcessPointField(inputCoords.GetData(), device);
PointMapHelper<DeviceAdapter> pointMapper(this->Worklet, outputCoordsArray);
vtkm::filter::ApplyPolicy(inputCoords, policy).CastAndCall(pointMapper);
vtkm::cont::CoordinateSystem outputCoords(inputCoords.GetName(), outputCoordsArray); vtkm::cont::CoordinateSystem outputCoords(inputCoords.GetName(), outputCoordsArray);
//create the output data //create the output data

@ -69,7 +69,7 @@ inline vtkm::filter::Result ExtractPoints::DoExecute(
vtkm::worklet::ExtractPoints worklet; vtkm::worklet::ExtractPoints worklet;
outCellSet = worklet.Run(vtkm::filter::ApplyPolicy(cells, policy), outCellSet = worklet.Run(vtkm::filter::ApplyPolicy(cells, policy),
vtkm::filter::ApplyPolicy(coords, policy), coords.GetData(),
this->Function, this->Function,
this->ExtractInside, this->ExtractInside,
device); device);

@ -52,10 +52,8 @@ inline VTKM_CONT vtkm::filter::Result ExtractStructured::DoExecute(
this->IncludeBoundary, this->IncludeBoundary,
device); device);
auto coords = auto coords = this->Worklet.MapCoordinates(coordinates, device);
this->Worklet.MapCoordinates(vtkm::filter::ApplyPolicy(coordinates, policy), device); vtkm::cont::CoordinateSystem outputCoordinates(coordinates.GetName(), coords);
vtkm::cont::CoordinateSystem outputCoordinates(coordinates.GetName(),
vtkm::cont::DynamicArrayHandle(coords));
vtkm::cont::DataSet output; vtkm::cont::DataSet output;
output.AddCellSet(vtkm::cont::DynamicCellSet(cellset)); output.AddCellSet(vtkm::cont::DynamicCellSet(cellset));

@ -183,10 +183,8 @@ FilterField<Derived>::PrepareForExecution(const vtkm::cont::DataSet& input,
typedef internal::ResolveFieldTypeAndExecute<Derived, DerivedPolicy, Result> FunctorType; typedef internal::ResolveFieldTypeAndExecute<Derived, DerivedPolicy, Result> FunctorType;
FunctorType functor(static_cast<Derived*>(this), input, metaData, policy, result); FunctorType functor(static_cast<Derived*>(this), input, metaData, policy, result);
vtkm::cont::CastAndCall(field, functor, this->Tracker);
typedef vtkm::filter::FilterTraits<Derived> Traits;
vtkm::cont::CastAndCall(
vtkm::filter::ApplyPolicy(field, policy, Traits()), functor, this->Tracker);
return result; return result;
} }
} }

@ -115,20 +115,14 @@ inline vtkm::filter::Result Gradient::DoExecute(
if (this->ComputePointGradient) if (this->ComputePointGradient)
{ {
vtkm::worklet::PointGradient gradient; vtkm::worklet::PointGradient gradient;
outArray = gradient.Run(vtkm::filter::ApplyPolicy(cells, policy), outArray = gradient.Run(
vtkm::filter::ApplyPolicy(coords, policy), vtkm::filter::ApplyPolicy(cells, policy), coords, inField, gradientfields, adapter);
inField,
gradientfields,
adapter);
} }
else else
{ {
vtkm::worklet::CellGradient gradient; vtkm::worklet::CellGradient gradient;
outArray = gradient.Run(vtkm::filter::ApplyPolicy(cells, policy), outArray = gradient.Run(
vtkm::filter::ApplyPolicy(coords, policy), vtkm::filter::ApplyPolicy(cells, policy), coords, inField, gradientfields, adapter);
inField,
gradientfields,
adapter);
} }
if (!this->RowOrdering) if (!this->RowOrdering)
{ {

@ -167,7 +167,7 @@ inline VTKM_CONT vtkm::filter::Result MarchingCubes::DoExecute(
outputCells = this->Worklet.Run(&ivalues[0], outputCells = this->Worklet.Run(&ivalues[0],
static_cast<vtkm::Id>(ivalues.size()), static_cast<vtkm::Id>(ivalues.size()),
vtkm::filter::ApplyPolicy(cells, policy), vtkm::filter::ApplyPolicy(cells, policy),
vtkm::filter::ApplyPolicy(coords, policy), coords.GetData(),
field, field,
vertices, vertices,
normals, normals,
@ -178,7 +178,7 @@ inline VTKM_CONT vtkm::filter::Result MarchingCubes::DoExecute(
outputCells = this->Worklet.Run(&ivalues[0], outputCells = this->Worklet.Run(&ivalues[0],
static_cast<vtkm::Id>(ivalues.size()), static_cast<vtkm::Id>(ivalues.size()),
vtkm::filter::ApplyPolicy(cells, policy), vtkm::filter::ApplyPolicy(cells, policy),
vtkm::filter::ApplyPolicy(coords, policy), coords.GetData(),
field, field,
vertices, vertices,
device); device);

@ -47,9 +47,6 @@ struct PolicyBase
typedef vtkm::cont::CellSetListTagUnstructured UnstructuredCellSetList; typedef vtkm::cont::CellSetListTagUnstructured UnstructuredCellSetList;
typedef VTKM_DEFAULT_CELL_SET_LIST_TAG AllCellSetList; typedef VTKM_DEFAULT_CELL_SET_LIST_TAG AllCellSetList;
typedef VTKM_DEFAULT_COORDINATE_SYSTEM_TYPE_LIST_TAG CoordinateTypeList;
typedef VTKM_DEFAULT_COORDINATE_SYSTEM_STORAGE_LIST_TAG CoordinateStorageList;
// List of backends to try in sequence (if one fails, the next is attempted). // List of backends to try in sequence (if one fails, the next is attempted).
typedef VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG DeviceAdapterList; typedef VTKM_DEFAULT_DEVICE_ADAPTER_LIST_TAG DeviceAdapterList;
}; };
@ -81,33 +78,6 @@ ApplyPolicy(const vtkm::cont::Field& field,
return field.GetData().ResetTypeAndStorageLists(TypeList(), StorageList()); return field.GetData().ResetTypeAndStorageLists(TypeList(), StorageList());
} }
//-----------------------------------------------------------------------------
template <typename DerivedPolicy>
VTKM_CONT vtkm::cont::DynamicArrayHandleBase<typename DerivedPolicy::CoordinateTypeList,
typename DerivedPolicy::CoordinateStorageList>
ApplyPolicy(const vtkm::cont::CoordinateSystem& coordinates,
const vtkm::filter::PolicyBase<DerivedPolicy>&)
{
typedef typename DerivedPolicy::CoordinateTypeList TypeList;
typedef typename DerivedPolicy::CoordinateStorageList StorageList;
return coordinates.GetData().ResetTypeAndStorageLists(TypeList(), StorageList());
}
//-----------------------------------------------------------------------------
template <typename DerivedPolicy, typename FilterType>
VTKM_CONT vtkm::cont::DynamicArrayHandleBase<typename DerivedPolicy::CoordinateTypeList,
typename DerivedPolicy::CoordinateStorageList>
ApplyPolicy(const vtkm::cont::CoordinateSystem& coordinates,
const vtkm::filter::PolicyBase<DerivedPolicy>&,
const vtkm::filter::FilterTraits<FilterType>&)
{
//todo: we need to intersect the policy field type list and the
//filter traits to the get smallest set of valid types
typedef typename DerivedPolicy::CoordinateTypeList TypeList;
typedef typename DerivedPolicy::CoordinateStorageList StorageList;
return coordinates.GetData().ResetTypeAndStorageLists(TypeList(), StorageList());
}
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
template <typename DerivedPolicy> template <typename DerivedPolicy>
VTKM_CONT vtkm::cont::DynamicCellSetBase<typename DerivedPolicy::AllCellSetList> ApplyPolicy( VTKM_CONT vtkm::cont::DynamicCellSetBase<typename DerivedPolicy::AllCellSetList> ApplyPolicy(

@ -40,12 +40,11 @@ inline VTKM_CONT vtkm::filter::Result VertexClustering::DoExecute(
// todo this code needs to obey the policy for what storage types // todo this code needs to obey the policy for what storage types
// the output should use // the output should use
//need to compute bounds first //need to compute bounds first
vtkm::Bounds bounds = input.GetCoordinateSystem().GetBounds( vtkm::Bounds bounds = input.GetCoordinateSystem().GetBounds();
typename DerivedPolicy::CoordinateTypeList(), typename DerivedPolicy::CoordinateStorageList());
vtkm::cont::DataSet outDataSet = vtkm::cont::DataSet outDataSet =
this->Worklet.Run(vtkm::filter::ApplyPolicyUnstructured(input.GetCellSet(), policy), this->Worklet.Run(vtkm::filter::ApplyPolicyUnstructured(input.GetCellSet(), policy),
vtkm::filter::ApplyPolicy(input.GetCoordinateSystem(), policy), input.GetCoordinateSystem(),
bounds, bounds,
this->GetNumberOfDivisions(), this->GetNumberOfDivisions(),
tag); tag);

@ -91,9 +91,7 @@ void TestPointElevationNoPolicy()
const bool valid = result.FieldAs(resultArrayHandle); const bool valid = result.FieldAs(resultArrayHandle);
if (valid) if (valid)
{ {
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>> coordinates; auto coordinates = inputData.GetCoordinateSystem().GetData();
inputData.GetCoordinateSystem().GetData().CopyTo(coordinates);
for (vtkm::Id i = 0; i < resultArrayHandle.GetNumberOfValues(); ++i) for (vtkm::Id i = 0; i < resultArrayHandle.GetNumberOfValues(); ++i)
{ {
VTKM_TEST_ASSERT(test_equal(coordinates.GetPortalConstControl().Get(i)[1] * 2.0, VTKM_TEST_ASSERT(test_equal(coordinates.GetPortalConstControl().Get(i)[1] * 2.0,
@ -131,9 +129,7 @@ void TestPointElevationWithPolicy()
const bool valid = result.FieldAs(resultArrayHandle); const bool valid = result.FieldAs(resultArrayHandle);
if (valid) if (valid)
{ {
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>> coordinates; auto coordinates = inputData.GetCoordinateSystem().GetData();
inputData.GetCoordinateSystem().GetData().CopyTo(coordinates);
for (vtkm::Id i = 0; i < resultArrayHandle.GetNumberOfValues(); ++i) for (vtkm::Id i = 0; i < resultArrayHandle.GetNumberOfValues(); ++i)
{ {
VTKM_TEST_ASSERT(test_equal(coordinates.GetPortalConstControl().Get(i)[1] * 2.0, VTKM_TEST_ASSERT(test_equal(coordinates.GetPortalConstControl().Get(i)[1] * 2.0,

@ -78,9 +78,7 @@ void TestVertexClustering()
} }
{ {
typedef vtkm::Vec<vtkm::Float64, 3> PointType; auto pointArray = output.GetCoordinateSystem(0).GetData();
vtkm::cont::ArrayHandle<PointType> pointArray;
output.GetCoordinateSystem(0).GetData().CopyTo(pointArray);
std::cerr << "output_points = " << pointArray.GetNumberOfValues() << "\n"; std::cerr << "output_points = " << pointArray.GetNumberOfValues() << "\n";
std::cerr << "output_point[] = "; std::cerr << "output_point[] = ";
vtkm::cont::printSummary_ArrayHandle(pointArray, std::cerr, true); vtkm::cont::printSummary_ArrayHandle(pointArray, std::cerr, true);
@ -90,8 +88,7 @@ void TestVertexClustering()
vtkm::cont::printSummary_ArrayHandle(cellvar, std::cerr, true); vtkm::cont::printSummary_ArrayHandle(cellvar, std::cerr, true);
typedef vtkm::Vec<vtkm::Float64, 3> PointType; typedef vtkm::Vec<vtkm::Float64, 3> PointType;
vtkm::cont::ArrayHandle<PointType> pointArray; auto pointArray = output.GetCoordinateSystem(0).GetData();
output.GetCoordinateSystem(0).GetData().CopyTo(pointArray);
VTKM_TEST_ASSERT(pointArray.GetNumberOfValues() == output_points, VTKM_TEST_ASSERT(pointArray.GetNumberOfValues() == output_points,
"Number of output points mismatch"); "Number of output points mismatch");
for (vtkm::Id i = 0; i < pointArray.GetNumberOfValues(); ++i) for (vtkm::Id i = 0; i < pointArray.GetNumberOfValues(); ++i)

@ -21,8 +21,9 @@
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------
# Build the configure file. # Build the configure file.
# need to set numerous VTKm cmake properties to the naming convention # need to set numerous VTKm cmake properties to the naming convention
# that we exepect for our C++ defines. # that we expect for our C++ defines.
set(VTKM_NO_ASSERT ${VTKm_NO_ASSERT})
set(VTKM_USE_DOUBLE_PRECISION ${VTKm_USE_DOUBLE_PRECISION}) set(VTKM_USE_DOUBLE_PRECISION ${VTKm_USE_DOUBLE_PRECISION})
set(VTKM_USE_64BIT_IDS ${VTKm_USE_64BIT_IDS}) set(VTKM_USE_64BIT_IDS ${VTKm_USE_64BIT_IDS})

File diff suppressed because it is too large Load Diff

@ -42,7 +42,7 @@ $# Ignore the following comment. It is meant for the generated file.
#include <vtkm/internal/FunctionInterface.h> #include <vtkm/internal/FunctionInterface.h>
$# This needs to match the max_parameters in FunctionInterfaceDetailPre.h.in $# This needs to match the max_parameters in FunctionInterfaceDetailPre.h.in
$py(max_parameters=10)\ $py(max_parameters=20)\
#if VTKM_MAX_FUNCTION_PARAMETERS != $(max_parameters) #if VTKM_MAX_FUNCTION_PARAMETERS != $(max_parameters)
#error Mismatch of maximum parameters between FunctionInterfaceDatailPre.h.in and FunctionInterfaceDetailPost.h.in #error Mismatch of maximum parameters between FunctionInterfaceDatailPre.h.in and FunctionInterfaceDetailPost.h.in
#endif #endif

File diff suppressed because it is too large Load Diff

@ -46,7 +46,7 @@ $# Ignore the following comment. It is meant for the generated file.
#include <vtkm/internal/brigand.hpp> #include <vtkm/internal/brigand.hpp>
$py(max_parameters=10)\ $py(max_parameters=20)\
#define VTKM_MAX_FUNCTION_PARAMETERS $(max_parameters) #define VTKM_MAX_FUNCTION_PARAMETERS $(max_parameters)
$# Python commands used in template expansion. $# Python commands used in template expansion.
@ -123,6 +123,8 @@ $for(num_params in range(0, max_parameters+1))\
template <$template_params(num_params)> template <$template_params(num_params)>
struct ParameterContainer<$signature(num_params)> struct ParameterContainer<$signature(num_params)>
{ {
VTKM_SUPPRESS_EXEC_WARNINGS
~ParameterContainer() = default;
$for(param_index in range(1, num_params+1))\ $for(param_index in range(1, num_params+1))\
$ptype(param_index) Parameter$(param_index); $ptype(param_index) Parameter$(param_index);
$endfor\ $endfor\

@ -161,17 +161,13 @@ private:
{ {
///\todo: support other coordinate systems ///\todo: support other coordinate systems
int cindex = 0; int cindex = 0;
auto cdata = dataSet.GetCoordinateSystem(cindex).GetData();
vtkm::cont::CoordinateSystem coords = dataSet.GetCoordinateSystem(cindex);
vtkm::cont::DynamicArrayHandleCoordinateSystem cdata = coords.GetData();
vtkm::Id npoints = cdata.GetNumberOfValues(); vtkm::Id npoints = cdata.GetNumberOfValues();
out << "POINTS " << npoints << " "
<< vtkm::io::internal::DataTypeName<vtkm::FloatDefault>::Name() << " " << std::endl;
std::string typeName; detail::OutputPointsFunctor{ out }(cdata);
vtkm::cont::CastAndCall(cdata, detail::GetDataTypeName(typeName));
out << "POINTS " << npoints << " " << typeName << " " << std::endl;
vtkm::cont::CastAndCall(cdata, detail::OutputPointsFunctor(out));
} }
template <class CellSetType> template <class CellSetType>

@ -87,25 +87,19 @@ set(sources
BitmapFontFactory.cxx BitmapFontFactory.cxx
BoundingBoxAnnotation.cxx BoundingBoxAnnotation.cxx
Camera.cxx Camera.cxx
Canvas.cxx
CanvasRayTracer.cxx
Color.cxx Color.cxx
ColorBarAnnotation.cxx ColorBarAnnotation.cxx
ColorLegendAnnotation.cxx ColorLegendAnnotation.cxx
ColorTable.cxx ColorTable.cxx
ConnectivityProxy.cxx
DecodePNG.cxx DecodePNG.cxx
LineRenderer.cxx LineRenderer.cxx
Mapper.cxx MapperConnectivity.cxx
MapperRayTracer.cxx MapperRayTracer.cxx
MapperVolume.cxx MapperVolume.cxx
MapperConnectivity.cxx
MapperWireframer.cxx
Scene.cxx Scene.cxx
TextAnnotation.cxx TextAnnotation.cxx
TextAnnotationBillboard.cxx TextAnnotationBillboard.cxx
TextAnnotationScreen.cxx TextAnnotationScreen.cxx
TextRenderer.cxx
View.cxx View.cxx
View1D.cxx View1D.cxx
View2D.cxx View2D.cxx
@ -113,13 +107,10 @@ set(sources
WorldAnnotator.cxx WorldAnnotator.cxx
internal/RunTriangulator.cxx internal/RunTriangulator.cxx
raytracing/BoundingVolumeHierarchy.cxx raytracing/ConnectivityBase.cxx
raytracing/Camera.cxx raytracing/ConnectivityTracerBase.cxx
raytracing/ChannelBuffer.cxx raytracing/ConnectivityTracerFactory.cxx
raytracing/Logger.cxx raytracing/Logger.cxx
raytracing/RayTracer.cxx
raytracing/RayOperations.cxx
raytracing/VolumeRendererStructured.cxx
) )
# Note that EGL and OSMesa Canvas depend on the GL version being built. Only # Note that EGL and OSMesa Canvas depend on the GL version being built. Only
@ -157,18 +148,20 @@ set(osmesa_sources
# This list of sources has code that uses devices and so might need to be # This list of sources has code that uses devices and so might need to be
# compiled with a device-specific compiler (like CUDA). # compiled with a device-specific compiler (like CUDA).
set(device_sources set(device_sources
Mapper.cxx
MapperWireframer.cxx
Canvas.cxx Canvas.cxx
CanvasRayTracer.cxx CanvasRayTracer.cxx
ConnectivityProxy.cxx ConnectivityProxy.cxx
Mapper.cxx
MapperWireframer.cxx
TextRenderer.cxx TextRenderer.cxx
raytracing/BoundingVolumeHierarchy.cxx raytracing/BoundingVolumeHierarchy.cxx
raytracing/Camera.cxx raytracing/Camera.cxx
raytracing/ChannelBuffer.cxx raytracing/ChannelBuffer.cxx
raytracing/VolumeRendererStructured.cxx raytracing/ConnectivityTracer.cxx
raytracing/RayOperations.cxx raytracing/RayOperations.cxx
raytracing/RayTracer.cxx raytracing/RayTracer.cxx
raytracing/VolumeRendererStructured.cxx
) )
#----------------------------------------------------------------------------- #-----------------------------------------------------------------------------

@ -21,7 +21,6 @@
#include <vtkm/rendering/CanvasRayTracer.h> #include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/cont/TryExecute.h> #include <vtkm/cont/TryExecute.h>
#include <vtkm/exec/ExecutionWholeArray.h>
#include <vtkm/rendering/Canvas.h> #include <vtkm/rendering/Canvas.h>
#include <vtkm/rendering/Color.h> #include <vtkm/rendering/Color.h>
#include <vtkm/rendering/raytracing/Ray.h> #include <vtkm/rendering/raytracing/Ray.h>
@ -51,19 +50,21 @@ public:
FieldIn<>, FieldIn<>,
FieldIn<>, FieldIn<>,
FieldIn<>, FieldIn<>,
ExecObject, WholeArrayOut<vtkm::ListTagBase<vtkm::Float32>>,
ExecObject); WholeArrayOut<vtkm::ListTagBase<vtkm::Vec<vtkm::Float32, 4>>>);
typedef void ExecutionSignature(_1, _2, _3, _4, _5, _6, _7, WorkIndex); typedef void ExecutionSignature(_1, _2, _3, _4, _5, _6, _7, WorkIndex);
template <typename Precision, typename ColorPortalType> template <typename Precision,
VTKM_EXEC void operator()( typename ColorPortalType,
const vtkm::Id& pixelIndex, typename DepthBufferPortalType,
ColorPortalType& colorBufferIn, typename ColorBufferPortalType>
const Precision& inDepth, VTKM_EXEC void operator()(const vtkm::Id& pixelIndex,
const vtkm::Vec<Precision, 3>& origin, ColorPortalType& colorBufferIn,
const vtkm::Vec<Precision, 3>& dir, const Precision& inDepth,
vtkm::exec::ExecutionWholeArray<vtkm::Float32>& depthBuffer, const vtkm::Vec<Precision, 3>& origin,
vtkm::exec::ExecutionWholeArray<vtkm::Vec<vtkm::Float32, 4>>& colorBuffer, const vtkm::Vec<Precision, 3>& dir,
const vtkm::Id& index) const DepthBufferPortalType& depthBuffer,
ColorBufferPortalType& colorBuffer,
const vtkm::Id& index) const
{ {
vtkm::Vec<Precision, 3> intersection = origin + inDepth * dir; vtkm::Vec<Precision, 3> intersection = origin + inDepth * dir;
vtkm::Vec<vtkm::Float32, 4> point; vtkm::Vec<vtkm::Float32, 4> point;
@ -140,14 +141,13 @@ public:
{ {
VTKM_IS_DEVICE_ADAPTER_TAG(Device); VTKM_IS_DEVICE_ADAPTER_TAG(Device);
vtkm::worklet::DispatcherMapField<SurfaceConverter, Device>(SurfaceConverter(ViewProjMat)) vtkm::worklet::DispatcherMapField<SurfaceConverter, Device>(SurfaceConverter(ViewProjMat))
.Invoke( .Invoke(Rays.PixelIdx,
Rays.PixelIdx, Colors,
Colors, Rays.Distance,
Rays.Distance, Rays.Origin,
Rays.Origin, Rays.Dir,
Rays.Dir, Canvas->GetDepthBuffer(),
vtkm::exec::ExecutionWholeArray<vtkm::Float32>(Canvas->GetDepthBuffer()), Canvas->GetColorBuffer());
vtkm::exec::ExecutionWholeArray<vtkm::Vec<vtkm::Float32, 4>>(Canvas->GetColorBuffer()));
return true; return true;
} }
}; };

@ -25,6 +25,8 @@
#include <vtkm/rendering/Mapper.h> #include <vtkm/rendering/Mapper.h>
#include <vtkm/rendering/raytracing/ConnectivityTracerFactory.h> #include <vtkm/rendering/raytracing/ConnectivityTracerFactory.h>
#include <vtkm/rendering/raytracing/Logger.h> #include <vtkm/rendering/raytracing/Logger.h>
#include <vtkm/rendering/raytracing/RayOperations.h>
namespace vtkm namespace vtkm
{ {
@ -66,7 +68,7 @@ protected:
{ {
VTKM_IS_DEVICE_ADAPTER_TAG(Device); VTKM_IS_DEVICE_ADAPTER_TAG(Device);
Internals->SpatialBounds = Internals->Coords.GetBounds(Device()); Internals->SpatialBounds = Internals->Coords.GetBounds();
return true; return true;
} }
}; };

@ -432,7 +432,7 @@ void MapperGL::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
{ {
vtkm::cont::ArrayHandle<vtkm::Float32> sf; vtkm::cont::ArrayHandle<vtkm::Float32> sf;
sf = scalarField.GetData().Cast<vtkm::cont::ArrayHandle<vtkm::Float32>>(); sf = scalarField.GetData().Cast<vtkm::cont::ArrayHandle<vtkm::Float32>>();
vtkm::cont::DynamicArrayHandleCoordinateSystem dcoords = coords.GetData(); auto dcoords = coords.GetData();
vtkm::Id numVerts = coords.GetData().GetNumberOfValues(); vtkm::Id numVerts = coords.GetData().GetNumberOfValues();
//Handle 1D cases. //Handle 1D cases.
@ -459,20 +459,20 @@ void MapperGL::RenderCells(const vtkm::cont::DynamicCellSet& cellset,
vtkm::cont::ArrayHandleUniformPointCoordinates uVerts; vtkm::cont::ArrayHandleUniformPointCoordinates uVerts;
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>> eVerts; vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>> eVerts;
if (dcoords.IsSameType(vtkm::cont::ArrayHandleUniformPointCoordinates())) if (dcoords.IsSameType<vtkm::cont::ArrayHandleUniformPointCoordinates>())
{ {
uVerts = dcoords.Cast<vtkm::cont::ArrayHandleUniformPointCoordinates>(); uVerts = dcoords.Cast<vtkm::cont::ArrayHandleUniformPointCoordinates>();
RenderTriangles(*this, numTri, uVerts, indices, sf, colorTable, scalarRange, camera); RenderTriangles(*this, numTri, uVerts, indices, sf, colorTable, scalarRange, camera);
} }
else if (dcoords.IsSameType(vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>>())) else if (dcoords.IsSameType<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>>>())
{ {
eVerts = dcoords.Cast<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>>>(); eVerts = dcoords.Cast<vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>>>();
RenderTriangles(*this, numTri, eVerts, indices, sf, colorTable, scalarRange, camera); RenderTriangles(*this, numTri, eVerts, indices, sf, colorTable, scalarRange, camera);
} }
else if (dcoords.IsSameType(vtkm::cont::ArrayHandleCartesianProduct< else if (dcoords.IsSameType<vtkm::cont::ArrayHandleCartesianProduct<
vtkm::cont::ArrayHandle<vtkm::FloatDefault>, vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>, vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>>())) vtkm::cont::ArrayHandle<vtkm::FloatDefault>>>())
{ {
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::FloatDefault>, vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<vtkm::FloatDefault>,
vtkm::cont::ArrayHandle<vtkm::FloatDefault>, vtkm::cont::ArrayHandle<vtkm::FloatDefault>,

@ -24,7 +24,6 @@
#include <vtkm/cont/ArrayHandleCounting.h> #include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/CellSetPermutation.h> #include <vtkm/cont/CellSetPermutation.h>
#include <vtkm/cont/DataSet.h> #include <vtkm/cont/DataSet.h>
#include <vtkm/exec/ExecutionWholeArray.h>
#include <vtkm/rendering/raytracing/MeshConnectivityBuilder.h> #include <vtkm/rendering/raytracing/MeshConnectivityBuilder.h>
#include <vtkm/worklet/DispatcherMapField.h> #include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/DispatcherMapTopology.h> #include <vtkm/worklet/DispatcherMapTopology.h>
@ -276,17 +275,21 @@ public:
public: public:
VTKM_CONT VTKM_CONT
UniqueTriangles() {} UniqueTriangles() {}
typedef void ControlSignature(ExecObject, ExecObject);
typedef void ControlSignature(WholeArrayIn<vtkm::ListTagBase<vtkm::Vec<vtkm::Id, 4>>>,
WholeArrayOut<vtkm::ListTagBase<vtkm::UInt8>>);
typedef void ExecutionSignature(_1, _2, WorkIndex); typedef void ExecutionSignature(_1, _2, WorkIndex);
VTKM_EXEC VTKM_EXEC
bool IsTwin(const vtkm::Vec<vtkm::Id, 4>& a, const vtkm::Vec<vtkm::Id, 4>& b) const bool IsTwin(const vtkm::Vec<vtkm::Id, 4>& a, const vtkm::Vec<vtkm::Id, 4>& b) const
{ {
return (a[1] == b[1] && a[2] == b[2] && a[3] == b[3]); return (a[1] == b[1] && a[2] == b[2] && a[3] == b[3]);
} }
VTKM_EXEC
void operator()(vtkm::exec::ExecutionWholeArrayConst<vtkm::Vec<vtkm::Id, 4>>& indices, template <typename IndicesPortalType, typename OutputFlagsPortalType>
vtkm::exec::ExecutionWholeArray<vtkm::UInt8>& outputFlags, VTKM_EXEC void operator()(const IndicesPortalType& indices,
const vtkm::Id& index) const OutputFlagsPortalType& outputFlags,
const vtkm::Id& index) const
{ {
if (index == 0) if (index == 0)
return; return;
@ -612,9 +615,7 @@ public:
flags.Allocate(outputTriangles); flags.Allocate(outputTriangles);
vtkm::worklet::DispatcherMapField<MemSet<vtkm::UInt8>>(MemSet<vtkm::UInt8>(1)).Invoke(flags); vtkm::worklet::DispatcherMapField<MemSet<vtkm::UInt8>>(MemSet<vtkm::UInt8>(1)).Invoke(flags);
//Unique triangles will have a flag = 1 //Unique triangles will have a flag = 1
vtkm::worklet::DispatcherMapField<UniqueTriangles>().Invoke( vtkm::worklet::DispatcherMapField<UniqueTriangles>().Invoke(outputIndices, flags);
vtkm::exec::ExecutionWholeArrayConst<vtkm::Vec<vtkm::Id, 4>>(outputIndices),
vtkm::exec::ExecutionWholeArray<vtkm::UInt8>(flags));
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> subset; vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> subset;
vtkm::cont::DeviceAdapterAlgorithm<Device>::CopyIf(outputIndices, flags, subset); vtkm::cont::DeviceAdapterAlgorithm<Device>::CopyIf(outputIndices, flags, subset);

@ -74,6 +74,7 @@ vtkm::UInt32 ScaleColorComponent(vtkm::Float32 c)
return vtkm::UInt32(t < 0 ? 0 : (t > 255 ? 255 : t)); return vtkm::UInt32(t < 0 ? 0 : (t > 255 ? 255 : t));
} }
VTKM_EXEC_CONT
vtkm::UInt32 PackColor(vtkm::Float32 r, vtkm::Float32 g, vtkm::Float32 b, vtkm::Float32 a); vtkm::UInt32 PackColor(vtkm::Float32 r, vtkm::Float32 g, vtkm::Float32 b, vtkm::Float32 a);
VTKM_EXEC_CONT VTKM_EXEC_CONT
@ -92,6 +93,7 @@ vtkm::UInt32 PackColor(vtkm::Float32 r, vtkm::Float32 g, vtkm::Float32 b, vtkm::
return packed; return packed;
} }
VTKM_EXEC_CONT
void UnpackColor(vtkm::UInt32 color, void UnpackColor(vtkm::UInt32 color,
vtkm::Float32& r, vtkm::Float32& r,
vtkm::Float32& g, vtkm::Float32& g,
@ -157,7 +159,7 @@ class EdgePlotter : public vtkm::worklet::WorkletMapField
public: public:
using AtomicPackedFrameBufferHandle = vtkm::exec::AtomicArray<vtkm::Int64, DeviceTag>; using AtomicPackedFrameBufferHandle = vtkm::exec::AtomicArray<vtkm::Int64, DeviceTag>;
typedef void ControlSignature(FieldIn<>, WholeArrayIn<>, WholeArrayIn<Scalar>); typedef void ControlSignature(FieldIn<Id2Type>, WholeArrayIn<Vec3>, WholeArrayIn<Scalar>);
typedef void ExecutionSignature(_1, _2, _3); typedef void ExecutionSignature(_1, _2, _3);
using InputDomain = _1; using InputDomain = _1;
@ -393,14 +395,16 @@ public:
VTKM_CONT VTKM_CONT
BufferConverter() {} BufferConverter() {}
typedef void ControlSignature(FieldIn<>, ExecObject, ExecObject); typedef void ControlSignature(FieldIn<>,
WholeArrayOut<vtkm::ListTagBase<vtkm::Float32>>,
WholeArrayOut<vtkm::ListTagBase<vtkm::Vec<vtkm::Float32, 4>>>);
typedef void ExecutionSignature(_1, _2, _3, WorkIndex); typedef void ExecutionSignature(_1, _2, _3, WorkIndex);
VTKM_EXEC template <typename DepthBufferPortalType, typename ColorBufferPortalType>
void operator()(const vtkm::Int64& packedValue, VTKM_EXEC void operator()(const vtkm::Int64& packedValue,
vtkm::exec::ExecutionWholeArray<vtkm::Float32>& depthBuffer, DepthBufferPortalType& depthBuffer,
vtkm::exec::ExecutionWholeArray<vtkm::Vec<vtkm::Float32, 4>>& colorBuffer, ColorBufferPortalType& colorBuffer,
const vtkm::Id& index) const const vtkm::Id& index) const
{ {
PackedValue packed; PackedValue packed;
packed.Raw = packedValue; packed.Raw = packedValue;
@ -447,7 +451,7 @@ public:
const vtkm::Range& fieldRange) const vtkm::Range& fieldRange)
{ {
this->Bounds = coords.GetBounds(); this->Bounds = coords.GetBounds();
this->Coordinates = coords.GetData(); this->Coordinates = coords;
this->PointIndices = endPointIndices; this->PointIndices = endPointIndices;
this->ScalarField = field; this->ScalarField = field;
this->ScalarFieldRange = fieldRange; this->ScalarFieldRange = fieldRange;
@ -551,9 +555,7 @@ private:
BufferConverter converter; BufferConverter converter;
vtkm::worklet::DispatcherMapField<BufferConverter, DeviceTag>(converter).Invoke( vtkm::worklet::DispatcherMapField<BufferConverter, DeviceTag>(converter).Invoke(
FrameBuffer, FrameBuffer, Canvas->GetDepthBuffer(), Canvas->GetColorBuffer());
vtkm::exec::ExecutionWholeArray<vtkm::Float32>(Canvas->GetDepthBuffer()),
vtkm::exec::ExecutionWholeArray<vtkm::Vec<vtkm::Float32, 4>>(Canvas->GetColorBuffer()));
} }
VTKM_CONT VTKM_CONT
@ -581,7 +583,7 @@ private:
bool ShowInternalZones; bool ShowInternalZones;
bool IsOverlay; bool IsOverlay;
ColorMapHandle ColorMap; ColorMapHandle ColorMap;
vtkm::cont::DynamicArrayHandleCoordinateSystem Coordinates; vtkm::cont::CoordinateSystem Coordinates;
IndicesHandle PointIndices; IndicesHandle PointIndices;
vtkm::cont::Field ScalarField; vtkm::cont::Field ScalarField;
vtkm::Range ScalarFieldRange; vtkm::Range ScalarFieldRange;

@ -316,22 +316,22 @@ public:
{ {
this->FlatBVH = flatBVH.PrepareForOutput((LeafCount - 1) * 4, Device()); this->FlatBVH = flatBVH.PrepareForOutput((LeafCount - 1) * 4, Device());
} }
typedef void ControlSignature(ExecObject, typedef void ControlSignature(WholeArrayIn<Scalar>,
ExecObject, WholeArrayIn<Scalar>,
ExecObject, WholeArrayIn<Scalar>,
ExecObject, WholeArrayIn<Scalar>,
ExecObject, WholeArrayIn<Scalar>,
ExecObject); WholeArrayIn<Scalar>);
typedef void ExecutionSignature(WorkIndex, _1, _2, _3, _4, _5, _6); typedef void ExecutionSignature(WorkIndex, _1, _2, _3, _4, _5, _6);
template <typename StrorageType>
VTKM_EXEC_CONT void operator()( template <typename InputPortalType>
const vtkm::Id workIndex, VTKM_EXEC_CONT void operator()(const vtkm::Id workIndex,
const vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32, StrorageType>& xmin, const InputPortalType& xmin,
const vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32, StrorageType>& ymin, const InputPortalType& ymin,
const vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32, StrorageType>& zmin, const InputPortalType& zmin,
const vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32, StrorageType>& xmax, const InputPortalType& xmax,
const vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32, StrorageType>& ymax, const InputPortalType& ymax,
const vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32, StrorageType>& zmax) const const InputPortalType& zmax) const
{ {
//move up into the inner nodes //move up into the inner nodes
vtkm::Id currentNode = LeafCount - 1 + workIndex; vtkm::Id currentNode = LeafCount - 1 + workIndex;
@ -689,7 +689,7 @@ VTKM_CONT void LinearBVHBuilder::RunOnDevice(LinearBVH& linearBVH, Device device
logger->AddLogData("device", GetDeviceString(Device())); logger->AddLogData("device", GetDeviceString(Device()));
vtkm::cont::Timer<Device> constructTimer; vtkm::cont::Timer<Device> constructTimer;
vtkm::cont::DynamicArrayHandleCoordinateSystem coordsHandle = linearBVH.GetCoordsHandle(); auto coordsHandle = linearBVH.GetCoordsHandle();
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangleIndices = linearBVH.GetTriangles(); vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangleIndices = linearBVH.GetTriangles();
vtkm::Id numberOfTriangles = linearBVH.GetNumberOfTriangles(); vtkm::Id numberOfTriangles = linearBVH.GetNumberOfTriangles();
@ -780,12 +780,7 @@ VTKM_CONT void LinearBVHBuilder::RunOnDevice(LinearBVH& linearBVH, Device device
vtkm::worklet::DispatcherMapField<PropagateAABBs<Device>, Device>( vtkm::worklet::DispatcherMapField<PropagateAABBs<Device>, Device>(
PropagateAABBs<Device>( PropagateAABBs<Device>(
bvh.parent, bvh.leftChild, bvh.rightChild, primitiveCount, linearBVH.FlatBVH, atomicCounters)) bvh.parent, bvh.leftChild, bvh.rightChild, primitiveCount, linearBVH.FlatBVH, atomicCounters))
.Invoke(vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32>(*bvh.xmins), .Invoke(*bvh.xmins, *bvh.ymins, *bvh.zmins, *bvh.xmaxs, *bvh.ymaxs, *bvh.zmaxs);
vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32>(*bvh.ymins),
vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32>(*bvh.zmins),
vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32>(*bvh.xmaxs),
vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32>(*bvh.ymaxs),
vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32>(*bvh.zmaxs));
time = timer.GetElapsedTime(); time = timer.GetElapsedTime();
logger->AddLogData("propagate_aabbs", time); logger->AddLogData("propagate_aabbs", time);
@ -816,7 +811,7 @@ LinearBVH::LinearBVH()
, CanConstruct(false){}; , CanConstruct(false){};
VTKM_CONT VTKM_CONT
LinearBVH::LinearBVH(vtkm::cont::DynamicArrayHandleCoordinateSystem coordsHandle, LinearBVH::LinearBVH(vtkm::cont::ArrayHandleVirtualCoordinates coordsHandle,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles, vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles,
vtkm::Bounds coordBounds) vtkm::Bounds coordBounds)
: CoordBounds(coordBounds) : CoordBounds(coordBounds)
@ -861,7 +856,7 @@ void LinearBVH::Construct()
} }
VTKM_CONT VTKM_CONT
void LinearBVH::SetData(vtkm::cont::DynamicArrayHandleCoordinateSystem coordsHandle, void LinearBVH::SetData(vtkm::cont::ArrayHandleVirtualCoordinates coordsHandle,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles, vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles,
vtkm::Bounds coordBounds) vtkm::Bounds coordBounds)
{ {
@ -923,7 +918,7 @@ bool LinearBVH::GetIsConstructed() const
return IsConstructed; return IsConstructed;
} }
VTKM_CONT VTKM_CONT
vtkm::cont::DynamicArrayHandleCoordinateSystem LinearBVH::GetCoordsHandle() const vtkm::cont::ArrayHandleVirtualCoordinates LinearBVH::GetCoordsHandle() const
{ {
return CoordsHandle; return CoordsHandle;
} }

@ -46,7 +46,7 @@ public:
vtkm::Bounds CoordBounds; vtkm::Bounds CoordBounds;
protected: protected:
vtkm::cont::DynamicArrayHandleCoordinateSystem CoordsHandle; vtkm::cont::ArrayHandleVirtualCoordinates CoordsHandle;
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Triangles; vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> Triangles;
bool IsConstructed; bool IsConstructed;
bool CanConstruct; bool CanConstruct;
@ -55,7 +55,7 @@ public:
LinearBVH(); LinearBVH();
VTKM_CONT VTKM_CONT
LinearBVH(vtkm::cont::DynamicArrayHandleCoordinateSystem coordsHandle, LinearBVH(vtkm::cont::ArrayHandleVirtualCoordinates coordsHandle,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles, vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles,
vtkm::Bounds coordBounds); vtkm::Bounds coordBounds);
@ -69,7 +69,7 @@ public:
void Construct(); void Construct();
VTKM_CONT VTKM_CONT
void SetData(vtkm::cont::DynamicArrayHandleCoordinateSystem coordsHandle, void SetData(vtkm::cont::ArrayHandleVirtualCoordinates coordsHandle,
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles, vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> triangles,
vtkm::Bounds coordBounds); vtkm::Bounds coordBounds);
@ -80,7 +80,7 @@ public:
bool GetIsConstructed() const; bool GetIsConstructed() const;
VTKM_CONT VTKM_CONT
vtkm::cont::DynamicArrayHandleCoordinateSystem GetCoordsHandle() const; vtkm::cont::ArrayHandleVirtualCoordinates GetCoordsHandle() const;
VTKM_CONT VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> GetTriangles() const; vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> GetTriangles() const;

Some files were not shown because too many files have changed in this diff Show More