Merge branch 'master' into increase-worklet-arguments

This commit is contained in:
Matthew Letter 2018-01-04 12:07:38 -07:00
commit c3737c728e
175 changed files with 2811 additions and 2042 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
*.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
LICENSE.txt
README.txt
diy/include/diy
diy/LEGAL.txt
diy/LICENSE.txt
vtkm/thirdparty/diy/vtkmdiy
)
if (NOT VTKm_SOURCE_DIR)

@ -39,11 +39,21 @@ set(FILES_TO_CHECK
set(EXCEPTIONS
)
set(DIRECTORY_EXCEPTIONS
${VTKm_SOURCE_DIR}/vtkm/thirdparty/diy/vtkmdiy
)
if (NOT VTKm_SOURCE_DIR)
message(SEND_ERROR "VTKm_SOURCE_DIR not defined.")
endif (NOT VTKm_SOURCE_DIR)
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}...")
get_filename_component(directory_name "${directory}" NAME)

@ -221,11 +221,6 @@ find_package(Pyexpander)
#-----------------------------------------------------------------------------
# Add subdirectories
if(VTKm_ENABLE_MPI)
# This `if` is temporary and will be removed once `diy` supports building
# without MPI.
add_subdirectory(diy)
endif()
add_subdirectory(vtkm)
#-----------------------------------------------------------------------------

@ -20,4 +20,7 @@
list(APPEND CTEST_CUSTOM_WARNING_EXCEPTION
".*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.
)

@ -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_

@ -35,6 +35,11 @@ target_link_libraries(CosmoHaloFinder_SERIAL PRIVATE ${VTKm_LIBRARIES})
target_compile_options(CosmoHaloFinder_SERIAL PRIVATE ${VTKm_COMPILE_OPTIONS})
if(VTKm_CUDA_FOUND)
set(old_nvcc_flags ${CUDA_NVCC_FLAGS})
set(old_cxx_flags ${CMAKE_CXX_FLAGS})
vtkm_setup_nvcc_flags( old_nvcc_flags old_cxx_flags)
vtkm_disable_troublesome_thrust_warnings()
# Cuda compiles do not respect target_include_directories
cuda_include_directories(${VTKm_INCLUDE_DIRS})
@ -47,6 +52,9 @@ if(VTKm_CUDA_FOUND)
target_include_directories(CosmoHaloFinder_CUDA PRIVATE ${VTKm_INCLUDE_DIRS})
target_link_libraries(CosmoHaloFinder_CUDA PRIVATE ${VTKm_LIBRARIES})
target_compile_options(CosmoHaloFinder_CUDA PRIVATE ${VTKm_COMPILE_OPTIONS})
set(CUDA_NVCC_FLAGS ${old_nvcc_flags})
set(CMAKE_CXX_FLAGS ${old_cxx_flags})
endif()
if(VTKm_TBB_FOUND)

@ -28,6 +28,12 @@ find_package(VTKm QUIET REQUIRED
if(VTKm_OSMesa_FOUND AND VTKm_Rendering_FOUND)
if(VTKm_CUDA_FOUND)
set(old_nvcc_flags ${CUDA_NVCC_FLAGS})
set(old_cxx_flags ${CMAKE_CXX_FLAGS})
vtkm_setup_nvcc_flags( old_nvcc_flags old_cxx_flags)
vtkm_disable_troublesome_thrust_warnings()
# Cuda compiles do not respect target_include_directories
cuda_include_directories(${VTKm_INCLUDE_DIRS})
cuda_add_executable(Demo Demo.cu)

@ -29,7 +29,16 @@ find_package(VTKm REQUIRED
)
if(VTKm_CUDA_FOUND)
set(old_nvcc_flags ${CUDA_NVCC_FLAGS})
set(old_cxx_flags ${CMAKE_CXX_FLAGS})
vtkm_setup_nvcc_flags( old_nvcc_flags old_cxx_flags)
vtkm_disable_troublesome_thrust_warnings()
cuda_add_executable(GameOfLife GameOfLife.cu LoadShaders.h)
set(CUDA_NVCC_FLAGS ${old_nvcc_flags})
set(CMAKE_CXX_FLAGS ${old_cxx_flags})
else()
add_executable(GameOfLife GameOfLife.cxx LoadShaders.h)
endif()

@ -45,6 +45,9 @@ struct Bounds
VTKM_EXEC_CONT
Bounds() {}
VTKM_EXEC_CONT
Bounds(const Bounds&) = default;
VTKM_EXEC_CONT
Bounds(const vtkm::Range& xRange, const vtkm::Range& yRange, const vtkm::Range& zRange)
: X(xRange)
@ -89,13 +92,7 @@ struct Bounds
}
VTKM_EXEC_CONT
const vtkm::Bounds& operator=(const vtkm::Bounds& src)
{
this->X = src.X;
this->Y = src.Y;
this->Z = src.Z;
return *this;
}
vtkm::Bounds& operator=(const vtkm::Bounds& src) = default;
/// \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
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(internal)

@ -2347,7 +2347,12 @@ static inline VTKM_EXEC_CONT vtkm::Float32 RemainderQuotient(vtkm::Float32 numer
QType& quotient)
{
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;
return result;
}
@ -2357,7 +2362,12 @@ static inline VTKM_EXEC_CONT vtkm::Float64 RemainderQuotient(vtkm::Float64 numer
QType& quotient)
{
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;
return result;
}

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

@ -516,22 +516,6 @@ public:
VTKM_EXEC_CONT
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_GCC) || defined(VTKM_CLANG))
#pragma GCC diagnostic push
@ -1241,46 +1225,85 @@ VTKM_EXEC_CONT static inline vtkm::VecCConst<T> make_VecC(const T* array, vtkm::
return vtkm::VecCConst<T>(array, size);
}
// A pre-declaration of vtkm::Pair so that classes templated on them can refer
// 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)
namespace detail
{
T result = T(a[0] * b[0]);
for (vtkm::IdComponent i = 1; i < Size; ++i)
template <typename T>
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;
}
template <typename T>
static inline VTKM_EXEC_CONT T dot(const vtkm::Vec<T, 2>& a, const vtkm::Vec<T, 2>& b)
template <typename T, vtkm::IdComponent Size>
static inline VTKM_EXEC_CONT typename DotType<T>::type vec_dot(const vtkm::Vec<T, Size>& a,
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>
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>
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, typename VecType>
static inline VTKM_EXEC_CONT T dot(const vtkm::detail::VecBaseCommon<T, VecType>& a,
const vtkm::detail::VecBaseCommon<T, VecType>& b)
template <typename T>
static inline VTKM_EXEC_CONT typename detail::DotType<T>::type dot(const vtkm::Vec<T, 3>& a,
const vtkm::Vec<T, 3>& 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>
VTKM_EXEC_CONT T ReduceSum(const vtkm::Vec<T, Size>& a)
@ -1340,22 +1363,10 @@ VTKM_EXEC_CONT T ReduceProduct(const vtkm::Vec<T, 4>& a)
return a[0] * a[1] * a[2] * a[3];
}
// Integer types of a width less than an integer get implicitly casted to
// an integer when doing a multiplication.
#define VTK_M_INTEGER_PROMOTION_SCALAR_DOT(type) \
static inline VTKM_EXEC_CONT type dot(type a, type b) { return static_cast<type>(a * b); }
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)
// A pre-declaration of vtkm::Pair so that classes templated on them can refer
// to it. The actual implementation is in vtkm/Pair.h.
template <typename U, typename V>
struct Pair;
} // End of namespace vtkm

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

@ -108,7 +108,7 @@ struct BenchDevAlgoConfig
/// @note FixBytes and FixSizes are not mutually exclusive. If both are
/// specified, both will run.
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
/// values (5%, 10%, 15%, 20%, 25%, 30%, 35%, 40%, 45%, 50%, 75%, 100%
@ -126,7 +126,7 @@ struct BenchDevAlgoConfig
{
return this->DoByteSizes
? static_cast<vtkm::Id>(this->ArraySizeBytes / static_cast<vtkm::UInt64>(sizeof(T)))
: this->ArraySizeValues;
: static_cast<vtkm::Id>(this->ArraySizeValues);
}
};
@ -291,8 +291,8 @@ private:
{
vtkm::Id arraySize = Config.ComputeSize<Value>();
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();
}
};
@ -337,8 +337,8 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description;
description << "CopyIf on " << arraySize << " values ("
<< HumanSize(arraySize * sizeof(Value)) << ") with " << PERCENT_VALID
<< "% valid values";
<< HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ") with "
<< PERCENT_VALID << "% valid values";
return description.str();
}
};
@ -393,8 +393,8 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description;
description << "LowerBounds on " << arraySize << " input values ("
<< "(" << HumanSize(arraySize * sizeof(Value)) << ") (" << PERCENT_VALUES
<< "% configuration)";
<< "(" << HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ") ("
<< PERCENT_VALUES << "% configuration)";
return description.str();
}
};
@ -451,7 +451,7 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description;
description << "Reduce on " << arraySize << " values ("
<< HumanSize(arraySize * sizeof(Value)) << ")";
<< HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ")";
return description.str();
}
};
@ -496,8 +496,8 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description;
description << "ReduceByKey on " << arraySize << " values ("
<< HumanSize(arraySize * sizeof(Value)) << ") with " << N_KEYS << " ("
<< PERCENT_KEYS << "%) distinct vtkm::Id keys";
<< HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ") with "
<< N_KEYS << " (" << PERCENT_KEYS << "%) distinct vtkm::Id keys";
return description.str();
}
};
@ -543,7 +543,7 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description;
description << "ScanInclusive on " << arraySize << " values ("
<< HumanSize(arraySize * sizeof(Value)) << ")";
<< HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ")";
return description.str();
}
};
@ -579,7 +579,7 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description;
description << "ScanExclusive on " << arraySize << " values ("
<< HumanSize(arraySize * sizeof(Value)) << ")";
<< HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ")";
return description.str();
}
};
@ -621,7 +621,7 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description;
description << "Sort on " << arraySize << " random values ("
<< HumanSize(arraySize * sizeof(Value)) << ")";
<< HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ")";
return description.str();
}
};
@ -674,8 +674,8 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description;
description << "SortByKey on " << arraySize << " random values ("
<< HumanSize(arraySize * sizeof(Value)) << ") with " << N_KEYS << " ("
<< PERCENT_KEYS << "%) different vtkm::Id keys";
<< HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ") with "
<< N_KEYS << " (" << PERCENT_KEYS << "%) different vtkm::Id keys";
return description.str();
}
};
@ -731,7 +731,7 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description;
description << "StableSortIndices::Sort on " << arraySize << " random values ("
<< HumanSize(arraySize * sizeof(Value)) << ")";
<< HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ")";
return description.str();
}
};
@ -775,8 +775,8 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description;
description << "StableSortIndices::Unique on " << arraySize << " values ("
<< HumanSize(arraySize * sizeof(Value)) << ") with " << this->N_VALID << " ("
<< PERCENT_VALID << "%) valid values";
<< HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ") with "
<< this->N_VALID << " (" << PERCENT_VALID << "%) valid values";
return description.str();
}
};
@ -831,8 +831,8 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description;
description << "Unique on " << arraySize << " values ("
<< HumanSize(arraySize * sizeof(Value)) << ") with " << N_VALID << " ("
<< PERCENT_VALID << "%) valid values";
<< HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ") with "
<< N_VALID << " (" << PERCENT_VALID << "%) valid values";
return description.str();
}
};
@ -887,8 +887,8 @@ private:
vtkm::Id arraySize = Config.ComputeSize<Value>();
std::stringstream description;
description << "UpperBounds on " << arraySize << " input and " << N_VALS << " ("
<< PERCENT_VALS
<< "%) values (input array size: " << HumanSize(arraySize * sizeof(Value)) << ")";
<< PERCENT_VALS << "%) values (input array size: "
<< HumanSize(static_cast<vtkm::UInt64>(arraySize) * sizeof(Value)) << ")";
return description.str();
}
};

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

@ -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

@ -45,6 +45,7 @@ set(headers
ArrayHandleConcatenate.h
ArrayRangeCompute.h
ArrayRangeCompute.hxx
AssignerMultiBlock.h
CellLocatorTwoLevelUniformGrid.h
CellSet.h
CellSetExplicit.h
@ -58,6 +59,7 @@ set(headers
DataSetBuilderRectilinear.h
DataSetBuilderUniform.h
DataSetFieldAdd.h
DecomposerMultiBlock.h
DeviceAdapter.h
DeviceAdapterAlgorithm.h
DeviceAdapterListTag.h
@ -94,10 +96,12 @@ set(header_impls
set(sources
ArrayHandle.cxx
AssignerMultiBlock.cxx
CellSet.cxx
CellSetExplicit.cxx
CellSetStructured.cxx
CoordinateSystem.cxx
DataSet.cxx
DynamicArrayHandle.cxx
EnvironmentTracker.cxx
Field.cxx

@ -107,6 +107,7 @@ private:
DimVec3 Min;
DimVec3 Max;
VTKM_EXEC
bool Empty() const
{
return (this->Max[0] < this->Min[0]) || (this->Max[1] < this->Min[1]) ||

164
vtkm/cont/DataSet.cxx Normal file

@ -0,0 +1,164 @@
//============================================================================
// 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/DataSet.h>
namespace vtkm
{
namespace cont
{
DataSet::DataSet()
{
}
void DataSet::Clear()
{
this->CoordSystems.clear();
this->Fields.clear();
this->CellSets.clear();
}
const vtkm::cont::Field& DataSet::GetField(vtkm::Id index) const
{
VTKM_ASSERT((index >= 0) && (index < this->GetNumberOfFields()));
return this->Fields[static_cast<std::size_t>(index)];
}
vtkm::Id DataSet::GetFieldIndex(const std::string& name,
vtkm::cont::Field::AssociationEnum assoc) const
{
bool found;
vtkm::Id index = this->FindFieldIndex(name, assoc, found);
if (found)
{
return index;
}
else
{
throw vtkm::cont::ErrorBadValue("No field with requested name: " + name);
}
}
const vtkm::cont::CoordinateSystem& DataSet::GetCoordinateSystem(vtkm::Id index) const
{
VTKM_ASSERT((index >= 0) && (index < this->GetNumberOfCoordinateSystems()));
return this->CoordSystems[static_cast<std::size_t>(index)];
}
vtkm::Id DataSet::GetCoordinateSystemIndex(const std::string& name) const
{
bool found;
vtkm::Id index = this->FindCoordinateSystemIndex(name, found);
if (found)
{
return index;
}
else
{
throw vtkm::cont::ErrorBadValue("No coordinate system with requested name");
}
}
vtkm::Id DataSet::GetCellSetIndex(const std::string& name) const
{
bool found;
vtkm::Id index = this->FindCellSetIndex(name, found);
if (found)
{
return index;
}
else
{
throw vtkm::cont::ErrorBadValue("No cell set with requested name");
}
}
void DataSet::PrintSummary(std::ostream& out) const
{
out << "DataSet:\n";
out << " CoordSystems[" << this->CoordSystems.size() << "]\n";
for (std::size_t index = 0; index < this->CoordSystems.size(); index++)
{
this->CoordSystems[index].PrintSummary(out);
}
out << " CellSets[" << this->GetNumberOfCellSets() << "]\n";
for (vtkm::Id index = 0; index < this->GetNumberOfCellSets(); index++)
{
this->GetCellSet(index).PrintSummary(out);
}
out << " Fields[" << this->GetNumberOfFields() << "]\n";
for (vtkm::Id index = 0; index < this->GetNumberOfFields(); index++)
{
this->GetField(index).PrintSummary(out);
}
}
vtkm::Id DataSet::FindFieldIndex(const std::string& name,
vtkm::cont::Field::AssociationEnum association,
bool& found) const
{
for (std::size_t index = 0; index < this->Fields.size(); ++index)
{
if ((association == vtkm::cont::Field::ASSOC_ANY ||
association == this->Fields[index].GetAssociation()) &&
this->Fields[index].GetName() == name)
{
found = true;
return static_cast<vtkm::Id>(index);
}
}
found = false;
return -1;
}
vtkm::Id DataSet::FindCoordinateSystemIndex(const std::string& name, bool& found) const
{
for (std::size_t index = 0; index < this->CoordSystems.size(); ++index)
{
if (this->CoordSystems[index].GetName() == name)
{
found = true;
return static_cast<vtkm::Id>(index);
}
}
found = false;
return -1;
}
vtkm::Id DataSet::FindCellSetIndex(const std::string& name, bool& found) const
{
for (std::size_t index = 0; index < static_cast<size_t>(this->GetNumberOfCellSets()); ++index)
{
if (this->CellSets[index].GetName() == name)
{
found = true;
return static_cast<vtkm::Id>(index);
}
}
found = false;
return -1;
}
} // namespace cont
} // namespace vtkm

@ -20,6 +20,8 @@
#ifndef vtk_m_cont_DataSet_h
#define vtk_m_cont_DataSet_h
#include <vtkm/cont/vtkm_cont_export.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/CoordinateSystem.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
@ -33,29 +35,17 @@ namespace vtkm
namespace cont
{
class DataSet
class VTKM_CONT_EXPORT DataSet
{
public:
VTKM_CONT
DataSet() {}
VTKM_CONT DataSet();
VTKM_CONT void Clear();
VTKM_CONT void AddField(const Field& field) { this->Fields.push_back(field); }
VTKM_CONT
void Clear()
{
this->CoordSystems.clear();
this->Fields.clear();
this->CellSets.clear();
}
VTKM_CONT
void AddField(Field field) { this->Fields.push_back(field); }
VTKM_CONT
const vtkm::cont::Field& GetField(vtkm::Id index) const
{
VTKM_ASSERT((index >= 0) && (index < this->GetNumberOfFields()));
return this->Fields[static_cast<std::size_t>(index)];
}
const vtkm::cont::Field& GetField(vtkm::Id index) const;
VTKM_CONT
bool HasField(const std::string& name,
@ -69,19 +59,7 @@ public:
VTKM_CONT
vtkm::Id GetFieldIndex(
const std::string& name,
vtkm::cont::Field::AssociationEnum assoc = vtkm::cont::Field::ASSOC_ANY) const
{
bool found;
vtkm::Id index = this->FindFieldIndex(name, assoc, found);
if (found)
{
return index;
}
else
{
throw vtkm::cont::ErrorBadValue("No field with requested name: " + name);
}
}
vtkm::cont::Field::AssociationEnum assoc = vtkm::cont::Field::ASSOC_ANY) const;
VTKM_CONT
const vtkm::cont::Field& GetField(
@ -104,14 +82,13 @@ public:
}
VTKM_CONT
void AddCoordinateSystem(vtkm::cont::CoordinateSystem cs) { this->CoordSystems.push_back(cs); }
void AddCoordinateSystem(const vtkm::cont::CoordinateSystem& cs)
{
this->CoordSystems.push_back(cs);
}
VTKM_CONT
const vtkm::cont::CoordinateSystem& GetCoordinateSystem(vtkm::Id index = 0) const
{
VTKM_ASSERT((index >= 0) && (index < this->GetNumberOfCoordinateSystems()));
return this->CoordSystems[static_cast<std::size_t>(index)];
}
const vtkm::cont::CoordinateSystem& GetCoordinateSystem(vtkm::Id index = 0) const;
VTKM_CONT
bool HasCoordinateSystem(const std::string& name) const
@ -122,19 +99,7 @@ public:
}
VTKM_CONT
vtkm::Id GetCoordinateSystemIndex(const std::string& name) const
{
bool found;
vtkm::Id index = this->FindCoordinateSystemIndex(name, found);
if (found)
{
return index;
}
else
{
throw vtkm::cont::ErrorBadValue("No coordinate system with requested name");
}
}
vtkm::Id GetCoordinateSystemIndex(const std::string& name) const;
VTKM_CONT
const vtkm::cont::CoordinateSystem& GetCoordinateSystem(const std::string& name) const
@ -143,7 +108,7 @@ public:
}
VTKM_CONT
void AddCellSet(vtkm::cont::DynamicCellSet cellSet) { this->CellSets.push_back(cellSet); }
void AddCellSet(const vtkm::cont::DynamicCellSet& cellSet) { this->CellSets.push_back(cellSet); }
template <typename CellSetType>
VTKM_CONT void AddCellSet(const CellSetType& cellSet)
@ -168,19 +133,7 @@ public:
}
VTKM_CONT
vtkm::Id GetCellSetIndex(const std::string& name) const
{
bool found;
vtkm::Id index = this->FindCellSetIndex(name, found);
if (found)
{
return index;
}
else
{
throw vtkm::cont::ErrorBadValue("No cell set with requested name");
}
}
vtkm::Id GetCellSetIndex(const std::string& name) const;
VTKM_CONT
vtkm::cont::DynamicCellSet GetCellSet(const std::string& name) const
@ -207,27 +160,7 @@ public:
}
VTKM_CONT
void PrintSummary(std::ostream& out) const
{
out << "DataSet:\n";
out << " CoordSystems[" << this->CoordSystems.size() << "]\n";
for (std::size_t index = 0; index < this->CoordSystems.size(); index++)
{
this->CoordSystems[index].PrintSummary(out);
}
out << " CellSets[" << this->GetNumberOfCellSets() << "]\n";
for (vtkm::Id index = 0; index < this->GetNumberOfCellSets(); index++)
{
this->GetCellSet(index).PrintSummary(out);
}
out << " Fields[" << this->GetNumberOfFields() << "]\n";
for (vtkm::Id index = 0; index < this->GetNumberOfFields(); index++)
{
this->GetField(index).PrintSummary(out);
}
}
void PrintSummary(std::ostream& out) const;
private:
std::vector<vtkm::cont::CoordinateSystem> CoordSystems;
@ -237,51 +170,13 @@ private:
VTKM_CONT
vtkm::Id FindFieldIndex(const std::string& name,
vtkm::cont::Field::AssociationEnum association,
bool& found) const
{
for (std::size_t index = 0; index < this->Fields.size(); ++index)
{
if ((association == vtkm::cont::Field::ASSOC_ANY ||
association == this->Fields[index].GetAssociation()) &&
this->Fields[index].GetName() == name)
{
found = true;
return static_cast<vtkm::Id>(index);
}
}
found = false;
return -1;
}
bool& found) const;
VTKM_CONT
vtkm::Id FindCoordinateSystemIndex(const std::string& name, bool& found) const
{
for (std::size_t index = 0; index < this->CoordSystems.size(); ++index)
{
if (this->CoordSystems[index].GetName() == name)
{
found = true;
return static_cast<vtkm::Id>(index);
}
}
found = false;
return -1;
}
vtkm::Id FindCoordinateSystemIndex(const std::string& name, bool& found) const;
VTKM_CONT
vtkm::Id FindCellSetIndex(const std::string& name, bool& found) const
{
for (std::size_t index = 0; index < static_cast<size_t>(this->GetNumberOfCellSets()); ++index)
{
if (this->CellSets[index].GetName() == name)
{
found = true;
return static_cast<vtkm::Id>(index);
}
}
found = false;
return -1;
}
vtkm::Id FindCellSetIndex(const std::string& name, bool& found) const;
};
} // namespace cont

@ -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

@ -20,7 +20,12 @@
#include <vtkm/cont/EnvironmentTracker.h>
#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
namespace diy
{

@ -25,6 +25,11 @@
#include <vtkm/internal/Configure.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 mpi

@ -21,7 +21,9 @@
#include <vtkm/StaticAssert.h>
#include <vtkm/cont/ArrayCopy.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/AssignerMultiBlock.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DecomposerMultiBlock.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/DynamicArrayHandle.h>
#include <vtkm/cont/EnvironmentTracker.h>
@ -30,7 +32,14 @@
#include <vtkm/cont/MultiBlock.h>
#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
{
@ -48,111 +57,21 @@ VTKM_CONT std::vector<typename PortalType::ValueType> CopyArrayPortalToVector(
std::copy(iterators.GetBegin(), iterators.GetEnd(), result.begin());
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
namespace vtkm
@ -311,26 +230,56 @@ VTKM_CONT vtkm::Bounds MultiBlock::GetBounds(vtkm::Id coordinate_system_index,
#if defined(VTKM_ENABLE_MPI)
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);
for (vtkm::Id cc = 0; cc < num_blocks; ++cc)
{
int gid = cc * world.size() + world.rank();
master.add(gid, const_cast<vtkm::cont::DataSet*>(&this->Blocks[cc]), new diy::Link());
}
// populate master with blocks from `this`.
diy::decompose(world.rank(), assigner, master);
master.foreach ([&](const vtkm::cont::DataSet* block, const diy::Master::ProxyWithLink& cp) {
auto coords = block->GetCoordinateSystem(coordinate_system_index);
const vtkm::Bounds bounds = coords.GetBounds(TypeList(), StorageList());
cp.all_reduce(bounds, std::plus<vtkm::Bounds>());
auto self = (*this);
master.foreach ([&](vtkm::Bounds* data, const diy::Master::ProxyWithLink& cp) {
const vtkm::cont::DataSet& block = vtkm::cont::detail::GetBlock(self, cp);
try
{
vtkm::cont::CoordinateSystem coords = block.GetCoordinateSystem(coordinate_system_index);
*data = coords.GetBounds(TypeList(), StorageList());
}
catch (const vtkm::cont::Error&)
{
}
});
master.process_collectives();
auto bounds = master.proxy(0).get<vtkm::Bounds>();
return bounds;
vtkm::cont::DecomposerMultiBlock decomposer(assigner);
diy::RegularSwapPartners partners(decomposer, /*k=*/2);
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
const vtkm::Id index = coordinate_system_index;
@ -443,65 +392,62 @@ VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Range>
MultiBlock::GetGlobalRange(const std::string& field_name, TypeList, StorageList) const
{
#if defined(VTKM_ENABLE_MPI)
auto world = vtkm::cont::EnvironmentTracker::GetCommunicator();
const auto num_blocks = this->GetNumberOfBlocks();
using BlockMetaData = std::vector<vtkm::Range>;
diy::Master master(world);
for (vtkm::Id cc = 0; cc < num_blocks; ++cc)
{
int gid = cc * world.size() + world.rank();
master.add(gid, const_cast<vtkm::cont::DataSet*>(&this->Blocks[cc]), new diy::Link());
}
auto comm = vtkm::cont::EnvironmentTracker::GetCommunicator();
diy::Master master(comm,
1,
-1,
[]() -> void* { return new BlockMetaData(); },
[](void* ptr) { delete static_cast<BlockMetaData*>(ptr); });
// collect info about number of components in the field.
master.foreach ([&](const vtkm::cont::DataSet* dataset, const diy::Master::ProxyWithLink& cp) {
if (dataset->HasField(field_name))
vtkm::cont::AssignerMultiBlock assigner(*this);
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());
vtkm::Id components = range.GetPortalConstControl().GetNumberOfValues();
cp.all_reduce(components, diy::mpi::maximum<vtkm::Id>());
*data = vtkm::cont::detail::CopyArrayPortalToVector(range.GetPortalConstControl());
}
});
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.
master.foreach ([&](const vtkm::cont::DataSet*, const diy::Master::ProxyWithLink& cp) {
cp.collectives()->clear();
});
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)
// 1. dequeue
BlockMetaData message;
for (const int gid : incoming)
{
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.
for (vtkm::Id cc = static_cast<vtkm::Id>(v_range.size()); cc < components; ++cc)
// 2. enqueue
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)
};
diy::reduce(master, assigner, partners, callback);
BlockMetaData ranges;
if (master.size())
{
for (vtkm::Id cc = 0; cc < components; ++cc)
{
ranges[cc] = master.proxy(0).get<vtkm::Range>();
}
ranges = *(master.block<BlockMetaData>(0));
}
vtkm::cont::ArrayHandle<vtkm::Range> tmprange = vtkm::cont::make_ArrayHandle(ranges);
vtkm::cont::ArrayHandle<vtkm::Range> range;
vtkm::cont::ArrayCopy(vtkm::cont::make_ArrayHandle(ranges), range);

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

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

@ -37,11 +37,10 @@ namespace
const vtkm::Id ARRAY_SIZE = 10;
template <typename ValueType>
struct MySquare
{
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);
}
@ -59,7 +58,7 @@ struct CheckTransformFunctor : vtkm::exec::FunctorBase
using T = typename TransformedPortalType::ValueType;
typename OriginalPortalType::ValueType original = this->OriginalPortal.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.");
}
@ -107,7 +106,7 @@ VTKM_CONT void CheckControlPortals(const OriginalArrayHandleType& originalArray,
using T = typename TransformedPortalType::ValueType;
typename OriginalPortalType::ValueType original = originalPortal.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
{
using OutputValueType = typename vtkm::VecTraits<InputValueType>::ComponentType;
using FunctorType = MySquare<OutputValueType>;
using TransformHandle =
vtkm::cont::ArrayHandleTransform<vtkm::cont::ArrayHandle<InputValueType>, FunctorType>;
vtkm::cont::ArrayHandleTransform<vtkm::cont::ArrayHandle<InputValueType>, MySquare>;
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 Algorithm = vtkm::cont::DeviceAdapterAlgorithm<Device>;
void operator()() const
{
FunctorType functor;
MySquare functor;
std::cout << "Test a transform handle with a counting handle as the values" << std::endl;
vtkm::cont::ArrayHandleCounting<InputValueType> counting = vtkm::cont::make_ArrayHandleCounting(

@ -36,7 +36,12 @@
#include <vtkm/exec/ConnectivityStructured.h>
#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
void DataSet_Compare(vtkm::cont::DataSet& LeftDateSet, vtkm::cont::DataSet& RightDateSet);

@ -29,14 +29,16 @@ namespace vtkm
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
/// content to be a parameter in an execution environment
/// function. This can be used to allow worklets to have a shared search
/// structure
/// structure.
///
template <typename T,
typename StorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename DeviceAdapterTag = VTKM_DEFAULT_DEVICE_ADAPTER_TAG>
template <typename T, typename StorageTag, typename DeviceAdapterTag>
class ExecutionWholeArray : public vtkm::exec::ExecutionObjectBase
{
public:
@ -86,9 +88,7 @@ private:
/// function. This can be used to allow worklets to have a shared search
/// structure
///
template <typename T,
typename StorageTag = VTKM_DEFAULT_STORAGE_TAG,
typename DeviceAdapterTag = VTKM_DEFAULT_DEVICE_ADAPTER_TAG>
template <typename T, typename StorageTag, typename DeviceAdapterTag>
class ExecutionWholeArrayConst : public vtkm::exec::ExecutionObjectBase
{
public:

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

@ -21,8 +21,9 @@
#-----------------------------------------------------------------------------
# Build the configure file.
# 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_64BIT_IDS ${VTKm_USE_64BIT_IDS})

@ -76,12 +76,16 @@ struct ParameterContainer;
template <typename R>
struct ParameterContainer<R()>
{
VTKM_SUPPRESS_EXEC_WARNINGS
~ParameterContainer() = default;
};
template <typename R,
typename P1>
struct ParameterContainer<R(P1)>
{
VTKM_SUPPRESS_EXEC_WARNINGS
~ParameterContainer() = default;
P1 Parameter1;
};
@ -90,6 +94,8 @@ template <typename R,
typename P2>
struct ParameterContainer<R(P1, P2)>
{
VTKM_SUPPRESS_EXEC_WARNINGS
~ParameterContainer() = default;
P1 Parameter1;
P2 Parameter2;
};
@ -100,6 +106,8 @@ template <typename R,
typename P3>
struct ParameterContainer<R(P1, P2, P3)>
{
VTKM_SUPPRESS_EXEC_WARNINGS
~ParameterContainer() = default;
P1 Parameter1;
P2 Parameter2;
P3 Parameter3;
@ -112,6 +120,8 @@ template <typename R,
typename P4>
struct ParameterContainer<R(P1, P2, P3, P4)>
{
VTKM_SUPPRESS_EXEC_WARNINGS
~ParameterContainer() = default;
P1 Parameter1;
P2 Parameter2;
P3 Parameter3;
@ -126,6 +136,8 @@ template <typename R,
typename P5>
struct ParameterContainer<R(P1, P2, P3, P4, P5)>
{
VTKM_SUPPRESS_EXEC_WARNINGS
~ParameterContainer() = default;
P1 Parameter1;
P2 Parameter2;
P3 Parameter3;
@ -142,6 +154,8 @@ template <typename R,
typename P6>
struct ParameterContainer<R(P1, P2, P3, P4, P5, P6)>
{
VTKM_SUPPRESS_EXEC_WARNINGS
~ParameterContainer() = default;
P1 Parameter1;
P2 Parameter2;
P3 Parameter3;
@ -160,6 +174,8 @@ template <typename R,
typename P7>
struct ParameterContainer<R(P1, P2, P3, P4, P5, P6, P7)>
{
VTKM_SUPPRESS_EXEC_WARNINGS
~ParameterContainer() = default;
P1 Parameter1;
P2 Parameter2;
P3 Parameter3;
@ -180,6 +196,8 @@ template <typename R,
typename P8>
struct ParameterContainer<R(P1, P2, P3, P4, P5, P6, P7, P8)>
{
VTKM_SUPPRESS_EXEC_WARNINGS
~ParameterContainer() = default;
P1 Parameter1;
P2 Parameter2;
P3 Parameter3;
@ -202,6 +220,8 @@ template <typename R,
typename P9>
struct ParameterContainer<R(P1, P2, P3, P4, P5, P6, P7, P8, P9)>
{
VTKM_SUPPRESS_EXEC_WARNINGS
~ParameterContainer() = default;
P1 Parameter1;
P2 Parameter2;
P3 Parameter3;
@ -226,6 +246,8 @@ template <typename R,
typename P10>
struct ParameterContainer<R(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10)>
{
VTKM_SUPPRESS_EXEC_WARNINGS
~ParameterContainer() = default;
P1 Parameter1;
P2 Parameter2;
P3 Parameter3;

@ -123,6 +123,8 @@ $for(num_params in range(0, max_parameters+1))\
template <$template_params(num_params)>
struct ParameterContainer<$signature(num_params)>
{
VTKM_SUPPRESS_EXEC_WARNINGS
~ParameterContainer() = default;
$for(param_index in range(1, num_params+1))\
$ptype(param_index) Parameter$(param_index);
$endfor\

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

@ -24,7 +24,6 @@
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/CellSetPermutation.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/exec/ExecutionWholeArray.h>
#include <vtkm/rendering/raytracing/MeshConnectivityBuilder.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/DispatcherMapTopology.h>
@ -276,17 +275,21 @@ public:
public:
VTKM_CONT
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);
VTKM_EXEC
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]);
}
VTKM_EXEC
void operator()(vtkm::exec::ExecutionWholeArrayConst<vtkm::Vec<vtkm::Id, 4>>& indices,
vtkm::exec::ExecutionWholeArray<vtkm::UInt8>& outputFlags,
const vtkm::Id& index) const
template <typename IndicesPortalType, typename OutputFlagsPortalType>
VTKM_EXEC void operator()(const IndicesPortalType& indices,
OutputFlagsPortalType& outputFlags,
const vtkm::Id& index) const
{
if (index == 0)
return;
@ -612,9 +615,7 @@ public:
flags.Allocate(outputTriangles);
vtkm::worklet::DispatcherMapField<MemSet<vtkm::UInt8>>(MemSet<vtkm::UInt8>(1)).Invoke(flags);
//Unique triangles will have a flag = 1
vtkm::worklet::DispatcherMapField<UniqueTriangles>().Invoke(
vtkm::exec::ExecutionWholeArrayConst<vtkm::Vec<vtkm::Id, 4>>(outputIndices),
vtkm::exec::ExecutionWholeArray<vtkm::UInt8>(flags));
vtkm::worklet::DispatcherMapField<UniqueTriangles>().Invoke(outputIndices, flags);
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Id, 4>> 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));
}
VTKM_EXEC_CONT
vtkm::UInt32 PackColor(vtkm::Float32 r, vtkm::Float32 g, vtkm::Float32 b, vtkm::Float32 a);
VTKM_EXEC_CONT
@ -92,6 +93,7 @@ vtkm::UInt32 PackColor(vtkm::Float32 r, vtkm::Float32 g, vtkm::Float32 b, vtkm::
return packed;
}
VTKM_EXEC_CONT
void UnpackColor(vtkm::UInt32 color,
vtkm::Float32& r,
vtkm::Float32& g,
@ -157,7 +159,7 @@ class EdgePlotter : public vtkm::worklet::WorkletMapField
public:
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);
using InputDomain = _1;
@ -393,14 +395,16 @@ public:
VTKM_CONT
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);
VTKM_EXEC
void operator()(const vtkm::Int64& packedValue,
vtkm::exec::ExecutionWholeArray<vtkm::Float32>& depthBuffer,
vtkm::exec::ExecutionWholeArray<vtkm::Vec<vtkm::Float32, 4>>& colorBuffer,
const vtkm::Id& index) const
template <typename DepthBufferPortalType, typename ColorBufferPortalType>
VTKM_EXEC void operator()(const vtkm::Int64& packedValue,
DepthBufferPortalType& depthBuffer,
ColorBufferPortalType& colorBuffer,
const vtkm::Id& index) const
{
PackedValue packed;
packed.Raw = packedValue;
@ -551,9 +555,7 @@ private:
BufferConverter converter;
vtkm::worklet::DispatcherMapField<BufferConverter, DeviceTag>(converter).Invoke(
FrameBuffer,
vtkm::exec::ExecutionWholeArray<vtkm::Float32>(Canvas->GetDepthBuffer()),
vtkm::exec::ExecutionWholeArray<vtkm::Vec<vtkm::Float32, 4>>(Canvas->GetColorBuffer()));
FrameBuffer, Canvas->GetDepthBuffer(), Canvas->GetColorBuffer());
}
VTKM_CONT

@ -316,22 +316,22 @@ public:
{
this->FlatBVH = flatBVH.PrepareForOutput((LeafCount - 1) * 4, Device());
}
typedef void ControlSignature(ExecObject,
ExecObject,
ExecObject,
ExecObject,
ExecObject,
ExecObject);
typedef void ControlSignature(WholeArrayIn<Scalar>,
WholeArrayIn<Scalar>,
WholeArrayIn<Scalar>,
WholeArrayIn<Scalar>,
WholeArrayIn<Scalar>,
WholeArrayIn<Scalar>);
typedef void ExecutionSignature(WorkIndex, _1, _2, _3, _4, _5, _6);
template <typename StrorageType>
VTKM_EXEC_CONT void operator()(
const vtkm::Id workIndex,
const vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32, StrorageType>& xmin,
const vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32, StrorageType>& ymin,
const vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32, StrorageType>& zmin,
const vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32, StrorageType>& xmax,
const vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32, StrorageType>& ymax,
const vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32, StrorageType>& zmax) const
template <typename InputPortalType>
VTKM_EXEC_CONT void operator()(const vtkm::Id workIndex,
const InputPortalType& xmin,
const InputPortalType& ymin,
const InputPortalType& zmin,
const InputPortalType& xmax,
const InputPortalType& ymax,
const InputPortalType& zmax) const
{
//move up into the inner nodes
vtkm::Id currentNode = LeafCount - 1 + workIndex;
@ -780,12 +780,7 @@ VTKM_CONT void LinearBVHBuilder::RunOnDevice(LinearBVH& linearBVH, Device device
vtkm::worklet::DispatcherMapField<PropagateAABBs<Device>, Device>(
PropagateAABBs<Device>(
bvh.parent, bvh.leftChild, bvh.rightChild, primitiveCount, linearBVH.FlatBVH, atomicCounters))
.Invoke(vtkm::exec::ExecutionWholeArrayConst<vtkm::Float32>(*bvh.xmins),
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));
.Invoke(*bvh.xmins, *bvh.ymins, *bvh.zmins, *bvh.xmaxs, *bvh.ymaxs, *bvh.zmaxs);
time = timer.GetElapsedTime();
logger->AddLogData("propagate_aabbs", time);

@ -95,7 +95,7 @@ public:
VTKM_CONT
MortonNeighbor() {}
typedef void ControlSignature(WholeArrayIn<>,
ExecObject,
WholeArrayInOut<Id3Type>,
WholeArrayIn<>,
WholeArrayIn<>,
WholeArrayIn<>,
@ -146,18 +146,18 @@ public:
template <typename MortonPortalType,
typename FaceIdPairsPortalType,
typename ConnPortalType,
typename ShapePortalType,
typename OffsetPortalType,
typename ExternalFaceFlagType>
VTKM_EXEC inline void operator()(
const MortonPortalType& mortonCodes,
vtkm::exec::ExecutionWholeArray<vtkm::Vec<vtkm::Id, 3>>& faceIdPairs,
const vtkm::Id& index,
const ConnPortalType& connectivity,
const ShapePortalType& shapes,
const OffsetPortalType& offsets,
ExternalFaceFlagType& flags) const
VTKM_EXEC inline void operator()(const MortonPortalType& mortonCodes,
FaceIdPairsPortalType& faceIdPairs,
const vtkm::Id& index,
const ConnPortalType& connectivity,
const ShapePortalType& shapes,
const OffsetPortalType& offsets,
ExternalFaceFlagType& flags) const
{
if (index == 0)
{
@ -330,14 +330,16 @@ public:
class WriteFaceConn : public vtkm::worklet::WorkletMapField
{
public:
typedef void ControlSignature(FieldIn<>, WholeArrayIn<>, WholeArrayOut<IdType>);
typedef void ExecutionSignature(_1, _2, _3);
VTKM_CONT
WriteFaceConn() {}
typedef void ControlSignature(FieldIn<>, WholeArrayIn<>, ExecObject);
typedef void ExecutionSignature(_1, _2, _3);
template <typename FaceOffsetsPortalType>
template <typename FaceOffsetsPortalType, typename FaceConnectivityPortalType>
VTKM_EXEC inline void operator()(const vtkm::Vec<vtkm::Id, 3>& faceIdPair,
const FaceOffsetsPortalType& faceOffsets,
vtkm::exec::ExecutionWholeArray<vtkm::Id>& faceConn) const
FaceConnectivityPortalType& faceConn) const
{
vtkm::Id cellId = faceIdPair[0];
BOUNDS_CHECK(faceOffsets, cellId);
@ -570,8 +572,7 @@ public:
// scatter the coonectivity into the original order
vtkm::worklet::DispatcherMapField<WriteFaceConn>(WriteFaceConn())
.Invoke(
cellFaceId, this->FaceOffsets, vtkm::exec::ExecutionWholeArray<vtkm::Id>(faceConnectivity));
.Invoke(cellFaceId, this->FaceOffsets, faceConnectivity);
FaceConnectivity = faceConnectivity;
@ -628,8 +629,7 @@ public:
// scatter the coonectivity into the original order
vtkm::worklet::DispatcherMapField<WriteFaceConn>(WriteFaceConn())
.Invoke(
cellFaceId, this->FaceOffsets, vtkm::exec::ExecutionWholeArray<vtkm::Id>(faceConnectivity));
.Invoke(cellFaceId, this->FaceOffsets, faceConnectivity);
FaceConnectivity = faceConnectivity;
OutsideTriangles = externalTriangles;
@ -754,12 +754,7 @@ protected:
.Invoke(faceConnectivity);
vtkm::worklet::DispatcherMapField<MortonNeighbor, DeviceAdapter>(MortonNeighbor())
.Invoke(faceMortonCodes,
vtkm::exec::ExecutionWholeArray<vtkm::Vec<vtkm::Id, 3>>(cellFaceId),
conn,
shapes,
shapeOffsets,
faceConnectivity);
.Invoke(faceMortonCodes, cellFaceId, conn, shapes, shapeOffsets, faceConnectivity);
vtkm::Float64 time = timer.GetElapsedTime();
Logger::GetInstance()->AddLogData("gen_face_conn", time);

@ -22,7 +22,6 @@
#include <cstring>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCompositeVector.h>
#include <vtkm/exec/ExecutionWholeArray.h>
#include <vtkm/rendering/raytracing/BoundingVolumeHierarchy.h>
#include <vtkm/rendering/raytracing/Ray.h>
#include <vtkm/rendering/raytracing/RayOperations.h>

@ -189,7 +189,7 @@ void GeneralVecCTypeTest(const vtkm::Vec<ComponentType, Size>&)
div = aSrc / b;
VTKM_TEST_ASSERT(test_equal(div, correct_div), "Tuples not divided correctly.");
ComponentType d = vtkm::dot(a, b);
ComponentType d = static_cast<ComponentType>(vtkm::dot(a, b));
ComponentType correct_d = 0;
for (vtkm::IdComponent i = 0; i < Size; ++i)
{
@ -286,7 +286,7 @@ void GeneralVecCConstTypeTest(const vtkm::Vec<ComponentType, Size>&)
div = aSrc / b;
VTKM_TEST_ASSERT(test_equal(div, correct_div), "Tuples not divided correctly.");
ComponentType d = vtkm::dot(a, b);
ComponentType d = static_cast<ComponentType>(vtkm::dot(a, b));
ComponentType correct_d = 0;
for (vtkm::IdComponent i = 0; i < Size; ++i)
{
@ -403,7 +403,7 @@ void GeneralVecTypeTest(const vtkm::Vec<ComponentType, Size>&)
div = a / ComponentType(2);
VTKM_TEST_ASSERT(test_equal(div, b), "Tuple does not divide by Scalar correctly.");
ComponentType d = vtkm::dot(a, b);
ComponentType d = static_cast<ComponentType>(vtkm::dot(a, b));
ComponentType correct_d = 0;
for (vtkm::IdComponent i = 0; i < T::NUM_COMPONENTS; ++i)
{
@ -477,7 +477,7 @@ void TypeTest(const vtkm::Vec<Scalar, 2>&)
VTKM_TEST_ASSERT(test_equal(div, vtkm::make_Vec(1, 2)),
"Vector does not divide by Scalar correctly.");
Scalar d = vtkm::dot(a, b);
Scalar d = static_cast<Scalar>(vtkm::dot(a, b));
VTKM_TEST_ASSERT(test_equal(d, Scalar(10)), "dot(Vector2) wrong");
VTKM_TEST_ASSERT(!(a < b), "operator< wrong");
@ -539,7 +539,7 @@ void TypeTest(const vtkm::Vec<Scalar, 3>&)
div = a / Scalar(2);
VTKM_TEST_ASSERT(test_equal(div, b), "Vector does not divide by Scalar correctly.");
Scalar d = vtkm::dot(a, b);
Scalar d = static_cast<Scalar>(vtkm::dot(a, b));
VTKM_TEST_ASSERT(test_equal(d, Scalar(28)), "dot(Vector3) wrong");
VTKM_TEST_ASSERT(!(a < b), "operator< wrong");
@ -601,7 +601,7 @@ void TypeTest(const vtkm::Vec<Scalar, 4>&)
div = a / Scalar(2);
VTKM_TEST_ASSERT(test_equal(div, b), "Vector does not divide by Scalar correctly.");
Scalar d = vtkm::dot(a, b);
Scalar d = static_cast<Scalar>(vtkm::dot(a, b));
VTKM_TEST_ASSERT(test_equal(d, Scalar(60)), "dot(Vector4) wrong");
VTKM_TEST_ASSERT(!(a < b), "operator< wrong");
@ -672,6 +672,17 @@ void TypeTest(Scalar)
{
VTKM_TEST_FAIL("dot(Scalar) wrong");
}
//verify we don't roll over
Scalar c = 128;
Scalar d = 32;
auto r = vtkm::dot(c, d);
VTKM_TEST_ASSERT((sizeof(r) >= sizeof(int)),
"dot(Scalar) didn't promote smaller than 32bit types");
if (r != 4096)
{
VTKM_TEST_FAIL("dot(Scalar) wrong");
}
}
struct TypeTestFunctor

@ -135,14 +135,14 @@ static void TestVecTypeImpl(const typename std::remove_const<T>::type& inVector,
VTKM_TEST_ASSERT(test_equal(vectorCopy, inVector), "CopyInto does not work.");
{
ComponentType result = 0;
auto expected = vtkm::dot(vectorCopy, vectorCopy);
decltype(expected) result = 0;
for (vtkm::IdComponent i = 0; i < NUM_COMPONENTS; i++)
{
ComponentType component = Traits::GetComponent(inVector, i);
result = ComponentType(result + (component * component));
result = result + (component * component);
}
VTKM_TEST_ASSERT(test_equal(result, vtkm::dot(vectorCopy, vectorCopy)),
"Got bad result for dot product");
VTKM_TEST_ASSERT(test_equal(result, expected), "Got bad result for dot product");
}
// This will fail to compile if the tags are wrong.

105
vtkm/thirdparty/UPDATING.md vendored Normal file

@ -0,0 +1,105 @@
# Updating Third Party Projects
When updating a third party project, any changes to the imported project
itself (e.g., the `diy/vtkmdiy` directory for diy), should go through the
`update.sh` framework. This framework ensures that all patches to the third
party projects are tracked externally and available for (preferably) upstream
or other projects also embedding the library.
# Updating a Project
Once converted, a project should be updated by applying patches to the
repository specified in its `update.sh` script. Once the changes are merged,
pulling the changes involves running the `update.sh` script. This will update
the local copy of the project to the version specified in `update.sh` (usually
a `for/foo` branch, like `for/vtk-m` for example, but may be `master` or any
other Git reference) and merge it into the main tree.
This requires a Git 2.5 or higher due the `worktree` tool being used to
simplify the availability of the commits to the main checkout.
Here's an example of updating the `diy` project from tag v2.0 to v2.1,
starting with updating the third-party repo
```sh
$ cd diy
$ git checkout for/vtk-m
$ git fetch origin
$ git rebase --onto v2.1 v2.0
$ git push
```
Now import into VTK-m
```sh
$ cd vtkm/ThirdParty/diy
$ git checkout -b update_diy
$ ./update.sh
```
Now you can review the change and make a merge request from the branch as normal.
# Porting a Project
When converting a project, if there are any local patches, a project should be
created [on GitLab](https://gitlab.kitware.com/third-party) to track it. If
the upstream project does not use Git, it should be imported into Git (there
may be existing conversions available on Github already). The project's
description should indicate where the source repository lives.
Once a mirror of the project is created, a branch named `for/foo` should be
created where patches for the `foo` project will be applied (i.e., `for/vtk-m`
for VTK-m's patches to the project). Usually, changes to the build system, the
source code for mangling, the addition of `.gitattributes` files, and other
changes belong here. Functional changes should be submitted upstream (but may
still be tracked so that they may be used).
The basic steps to import a project `diy` based on the tag
`v2.0` looks like this:
```sh
$ git clone https://github.com/diatomic/diy.git
$ cd diy/
$ git remote add kitware git@gitlab.kitware.com:third-party/diy.git
$ git push -u kitware
$ git push -u kitware --tags
$ git checkout v2.0
$ git checkout -b for/vtk-m
$ git push --set-upstream kitware for/vtk-m
```
Making the initial import involves filling out the project's `update.sh`
script in its directory. The [update-common.sh](update-common.sh) script
describes what is necessary, but in a nutshell, it is basically metadata such
as the name of the project and where it goes in the importing project.
The most important bit is the `extract_source` function which should subset
the repository. If all that needs to be done is to extract the files given in
the `paths` variable (described in the `update-common.sh` script), the
`git_archive` function may be used if the `git archive` tool generates a
suitable subset.
Make sure `update.sh` is executable before commit. On Unix, run:
```sh
$ chmod u+x update.sh && git add -u update.sh
```
On Windows, run:
```sh
$ git update-index --chmod=+x update.sh
```
# Process
The basic process involves a second branch where the third party project's
changes are tracked. This branch has a commit for each time it has been
updated and is stripped to only contain the relevant parts (no unit tests,
documentation, etc.). This branch is then merged into the main branch as a
subdirectory using the `subtree` merge strategy.
Initial conversions will require a manual push by the maintainers since the
conversion involves a root commit which is not allowed under normal
circumstances. Please send an email to the mailing list asking for assistance
if necessary.

@ -19,17 +19,22 @@
## this software.
##
##=============================================================================
#==============================================================================
# See License.txt
#==============================================================================
add_library(diy INTERFACE)
vtkm_get_kit_name(kit_name kit_dir)
# diy needs C++11
target_compile_features(diy INTERFACE cxx_auto_type)
# placeholder to support external DIY
set(VTKM_USE_EXTERNAL_DIY OFF)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/Configure.h.in
${VTKm_BINARY_INCLUDE_DIR}/${kit_dir}/Configure.h)
target_include_directories(diy INTERFACE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>
$<INSTALL_INTERFACE:${VTKm_INSTALL_INCLUDE_DIR}>)
# presently, this dependency is required. Make it optional in the future.
@ -55,11 +60,8 @@ endif()
install(TARGETS diy
EXPORT ${VTKm_EXPORT_NAME})
# Install headers
install(DIRECTORY include/diy
DESTINATION ${VTKm_INSTALL_INCLUDE_DIR})
# Install other files.
install(FILES LEGAL.txt LICENSE.txt
DESTINATION ${VTKm_INSTALL_INCLUDE_DIR}/diy
)
## Install headers
install(DIRECTORY vtkmdiy
DESTINATION ${VTKm_INSTALL_INCLUDE_DIR}/${kit_dir}/)
install(FILES ${VTKm_BINARY_INCLUDE_DIR}/${kit_dir}/Configure.h
DESTINATION ${VTKm_INSTALL_INCLUDE_DIR}/${kit_dir}/)

35
vtkm/thirdparty/diy/Configure.h.in vendored Normal file

@ -0,0 +1,35 @@
//=============================================================================
//
// 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 vtkm_diy_h
#define vtkm_diy_h
/* Use the diy library configured for VTM-m. */
#cmakedefine01 VTKM_USE_EXTERNAL_DIY
#if VTKM_USE_EXTERNAL_DIY
# define VTKM_DIY(header) <header>
#else
# define VTKM_DIY(header) <vtkmdiy/include/header>
# define diy vtkmdiy // mangle namespace diy
#endif
#endif

26
vtkm/thirdparty/diy/update.sh vendored Executable file

@ -0,0 +1,26 @@
#!/usr/bin/env bash
set -e
set -x
shopt -s dotglob
readonly name="diy"
readonly ownership="Diy Upstream <kwrobot@kitware.com>"
readonly subtree="vtkm/thirdparty/$name/vtkm$name"
readonly repo="https://gitlab.kitware.com/third-party/diy2.git"
readonly tag="for/vtk-m"
readonly paths="
include
LEGAL.txt
LICENSE.txt
README.md
"
extract_source () {
git_archive
pushd "$extractdir/$name-reduced"
mv include/diy include/vtkmdiy
popd
}
. "${BASH_SOURCE%/*}/../update-common.sh"

85
vtkm/thirdparty/diy/vtkmdiy/README.md vendored Normal file

@ -0,0 +1,85 @@
## DIY is a block-parallel library
DIY is a block-parallel library for implementing scalable algorithms that can execute both
in-core and out-of-core. The same program can be executed with one or more threads per MPI
process, seamlessly combining distributed-memory message passing with shared-memory thread
parallelism. The abstraction enabling these capabilities is block parallelism; blocks
and their message queues are mapped onto processing elements (MPI processes or threads) and are
migrated between memory and storage by the DIY runtime. Complex communication patterns,
including neighbor exchange, merge reduction, swap reduction, and all-to-all exchange, are
possible in- and out-of-core in DIY.
## Licensing
DIY is released as open source software under a BSD-style [license](./LICENSE.txt).
## Dependencies
DIY requires an MPI installation. We recommend [MPICH](http://www.mpich.org/).
## Download, build, install
- You can clone this repository, or
- You can download the [latest tarball](https://github.com/diatomic/diy2/archive/master.tar.gz).
DIY is a header-only library. It does not need to be built; you can simply
include it in your project. The examples can be built using `cmake` from the
top-level directory.
## Documentation
[Doxygen pages](https://diatomic.github.io/diy)
## Example
A simple DIY program, shown below, consists of the following components:
- `struct`s called blocks,
- a diy object called the `master`,
- a set of callback functions performed on each block by `master.foreach()`,
- optionally, one or more message exchanges between the blocks by `master.exchange()`, and
- there may be other collectives and global reductions not shown below.
The callback functions (`enqueue_local()` and `average()` in the example below) receive the block
pointer and a communication proxy for the message exchange between blocks. It is usual for the
callback functions to enqueue or dequeue messages from the proxy, so that information can be
received and sent during rounds of message exchange.
```cpp
// --- main program --- //
struct Block { float local, average; }; // define your block structure
Master master(world); // world = MPI_Comm
... // populate master with blocks
master.foreach(&enqueue_local); // call enqueue_local() for each block
master.exchange(); // exchange enqueued data between blocks
master.foreach(&average); // call average() for each block
// --- callback functions --- //
// enqueue block data prior to exchanging it
void enqueue_local(Block* b, // current block
const Proxy& cp) // communication proxy provides access to the neighbor blocks
{
for (size_t i = 0; i < cp.link()->size(); i++) // for all neighbor blocks
cp.enqueue(cp.link()->target(i), b->local); // enqueue the data to be sent to this neighbor
// block in the next exchange
}
// use the received data after exchanging it, in this case compute its average
void average(Block* b, // current block
const Proxy& cp) // communication proxy provides access to the neighbor blocks
{
float x, average = 0;
for (size_t i = 0; i < cp.link()->size(); i++) // for all neighbor blocks
{
cp.dequeue(cp.link()->target(i).gid, x); // dequeue the data received from this
// neighbor block in the last exchange
average += x;
}
b->average = average / cp.link()->size();
}
```

@ -0,0 +1,535 @@
/*
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(FMT_HEADER_ONLY) && !defined(WIN32_LEAN_AND_MEAN)
# define WIN32_LEAN_AND_MEAN
# endif
# if defined(NOMINMAX) || defined(FMT_WIN_MINMAX)
# include <windows.h>
# else
# define NOMINMAX
# include <windows.h>
# undef NOMINMAX
# endif
#endif
#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 {
FMT_FUNC internal::RuntimeError::~RuntimeError() FMT_DTOR_NOEXCEPT {}
FMT_FUNC FormatError::~FormatError() FMT_DTOR_NOEXCEPT {}
FMT_FUNC SystemError::~SystemError() FMT_DTOR_NOEXCEPT {}
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)
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() {
// Suppress a warning about unused strerror_r.
strerror_r(0, FMT_NULL, "");
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);
}
} // namespace
FMT_FUNC void SystemError::init(
int err_code, CStringRef format_str, ArgList args) {
error_code_ = err_code;
MemoryWriter w;
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 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 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 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 internal::BasicData<T>::POWERS_OF_10_32[] = {
0, FMT_POWERS_OF_10(1)
};
template <typename T>
const uint64_t internal::BasicData<T>::POWERS_OF_10_64[] = {
0,
FMT_POWERS_OF_10(1),
FMT_POWERS_OF_10(ULongLong(1000000000)),
// Multiply several constants instead of using a single long long constant
// to avoid warnings about C++98 not supporting long long.
ULongLong(1000000000) * ULongLong(1000000000) * 10
};
FMT_FUNC void internal::report_unknown_type(char code, const char *type) {
(void)type;
if (std::isprint(static_cast<unsigned char>(code))) {
FMT_THROW(FormatError(
format("unknown format code '{}' for {}", code, type)));
}
FMT_THROW(FormatError(
format("unknown format code '\\x{:02x}' for {}",
static_cast<unsigned>(code), type)));
}
#if FMT_USE_WINDOWS_H
FMT_FUNC internal::UTF8ToUTF16::UTF8ToUTF16(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, FMT_NULL, 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 internal::UTF16ToUTF8::UTF16ToUTF8(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 internal::UTF16ToUTF8::convert(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, FMT_NULL, 0, FMT_NULL, FMT_NULL);
if (length == 0)
return GetLastError();
buffer_.resize(length + 1);
length = WideCharToMultiByte(
CP_UTF8, 0, s.data(), s_size, &buffer_[0], length, FMT_NULL, FMT_NULL);
if (length == 0)
return GetLastError();
buffer_[length] = 0;
return 0;
}
FMT_FUNC void 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 internal::format_windows_error(
Writer &out, int error_code, 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,
FMT_NULL, error_code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
system_message, static_cast<uint32_t>(buffer.size()), FMT_NULL);
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 format_system_error(
Writer &out, int error_code, StringRef message) FMT_NOEXCEPT {
FMT_TRY {
internal::MemoryBuffer<char, internal::INLINE_BUFFER_SIZE> buffer;
buffer.resize(internal::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 internal::ArgMap<Char>::init(const ArgList &args) {
if (!map_.empty())
return;
typedef internal::NamedArg<Char> NamedArg;
const NamedArg *named_arg = FMT_NULL;
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 internal::FixedBuffer<Char>::grow(std::size_t) {
FMT_THROW(std::runtime_error("buffer overflow"));
}
FMT_FUNC internal::Arg internal::FormatterBase::do_get_arg(
unsigned arg_index, const char *&error) {
internal::Arg arg = args_[arg_index];
switch (arg.type) {
case internal::Arg::NONE:
error = "argument index out of range";
break;
case internal::Arg::NAMED_ARG:
arg = *static_cast<const internal::Arg*>(arg.pointer);
break;
default:
/*nothing*/;
}
return arg;
}
FMT_FUNC void report_system_error(
int error_code, fmt::StringRef message) FMT_NOEXCEPT {
// 'fmt::' is for bcc32.
report_error(format_system_error, error_code, message);
}
#if FMT_USE_WINDOWS_H
FMT_FUNC void report_windows_error(
int error_code, fmt::StringRef message) FMT_NOEXCEPT {
// 'fmt::' is for bcc32.
report_error(internal::format_windows_error, error_code, message);
}
#endif
FMT_FUNC void 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 print(CStringRef format_str, ArgList args) {
print(stdout, format_str, args);
}
FMT_FUNC void 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);
}
#ifndef FMT_HEADER_ONLY
template struct internal::BasicData<void>;
// Explicit instantiations for char.
template void internal::FixedBuffer<char>::grow(std::size_t);
template void internal::ArgMap<char>::init(const ArgList &args);
template FMT_API int internal::CharTraits<char>::format_float(
char *buffer, std::size_t size, const char *format,
unsigned width, int precision, double value);
template FMT_API int 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 internal::FixedBuffer<wchar_t>::grow(std::size_t);
template void internal::ArgMap<wchar_t>::init(const ArgList &args);
template FMT_API int internal::CharTraits<wchar_t>::format_float(
wchar_t *buffer, std::size_t size, const wchar_t *format,
unsigned width, int precision, double value);
template FMT_API int 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
} // namespace fmt
#ifdef _MSC_VER
# pragma warning(pop)
#endif

@ -0,0 +1,35 @@
/*
Formatting library for C++ - std::ostream support
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
For the license information refer to format.h.
*/
#include "ostream.h"
namespace fmt {
namespace internal {
FMT_FUNC 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);
internal::write(os, w);
}
} // namespace fmt

@ -0,0 +1,105 @@
/*
Formatting library for C++ - std::ostream support
Copyright (c) 2012 - 2016, Victor Zverovich
All rights reserved.
For the license information refer to format.h.
*/
#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_;
public:
FormatBuf(Buffer<Char> &buffer) : buffer_(buffer) {}
protected:
// The put-area is actually always empty. This makes the implementation
// simpler and has the advantage that the streambuf and the buffer are always
// in sync and sputc never writes into uninitialized memory. The obvious
// disadvantage is that each call to sputc always results in a (virtual) call
// to overflow. There is no disadvantage here for sputn since this always
// results in a call to xsputn.
int_type overflow(int_type ch = traits_type::eof()) FMT_OVERRIDE {
if (!traits_type::eq_int_type(ch, traits_type::eof()))
buffer_.push_back(static_cast<Char>(ch));
return ch;
}
std::streamsize xsputn(const Char *s, std::streamsize count) FMT_OVERRIDE {
buffer_.append(s, s + count);
return count;
}
};
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)
};
};
// Write the content of w to os.
FMT_API void write(std::ostream &os, Writer &w);
} // namespace internal
// Formats a value.
template <typename Char, typename ArgFormatter_, typename T>
void format_arg(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], buffer.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)
} // namespace fmt
#ifdef FMT_HEADER_ONLY
# include "ostream.cc"
#endif
#endif // FMT_OSTREAM_H_

@ -1062,8 +1062,6 @@ void
diy::Master::
flush()
{
auto scoped = prof.scoped("comm");
#ifdef DEBUG
time_type start = get_time();
unsigned wait = 1;

@ -152,13 +152,13 @@ namespace mpi
}
}
static void reduce(const communicator& comm, const T& in, T& out, int root, const Op& op)
static void reduce(const communicator& comm, const T& in, T& out, int root, const Op&)
{
MPI_Reduce(Datatype::address(const_cast<T&>(in)),
Datatype::address(out),
Datatype::count(in),
Datatype::datatype(),
detail::mpi_op<Op>::get(op),
detail::mpi_op<Op>::get(),
root, comm);
}
@ -168,38 +168,38 @@ namespace mpi
Datatype::address(const_cast<T&>(in)),
Datatype::count(in),
Datatype::datatype(),
detail::mpi_op<Op>::get(op),
detail::mpi_op<Op>::get(),
root, comm);
}
static void all_reduce(const communicator& comm, const T& in, T& out, const Op& op)
static void all_reduce(const communicator& comm, const T& in, T& out, const Op&)
{
MPI_Allreduce(Datatype::address(const_cast<T&>(in)),
Datatype::address(out),
Datatype::count(in),
Datatype::datatype(),
detail::mpi_op<Op>::get(op),
detail::mpi_op<Op>::get(),
comm);
}
static void all_reduce(const communicator& comm, const std::vector<T>& in, std::vector<T>& out, const Op& op)
static void all_reduce(const communicator& comm, const std::vector<T>& in, std::vector<T>& out, const Op&)
{
out.resize(in.size());
MPI_Allreduce(Datatype::address(const_cast<T&>(in[0])),
Datatype::address(out[0]),
in.size(),
Datatype::datatype(),
detail::mpi_op<Op>::get(op),
detail::mpi_op<Op>::get(),
comm);
}
static void scan(const communicator& comm, const T& in, T& out, const Op& op)
static void scan(const communicator& comm, const T& in, T& out, const Op&)
{
MPI_Scan(Datatype::address(const_cast<T&>(in)),
Datatype::address(out),
Datatype::count(in),
Datatype::datatype(),
detail::mpi_op<Op>::get(op),
detail::mpi_op<Op>::get(),
comm);
}

@ -9,7 +9,7 @@ namespace mpi
{
public:
communicator(MPI_Comm comm = MPI_COMM_WORLD):
comm_(comm), rank_(0), size_(1) { if (comm != MPI_COMM_NULL) { MPI_Comm_rank(comm_, &rank_); MPI_Comm_size(comm_, &size_); } }
comm_(comm), rank_(0), size_(1) { if (comm != MPI_COMM_NULL) { MPI_Comm_rank(comm_, &rank_); MPI_Comm_size(comm_, &size_); } }
int rank() const { return rank_; }
int size() const { return size_; }

@ -14,13 +14,13 @@ namespace mpi
namespace detail
{
template<class T> struct mpi_op { static MPI_Op get(const T&); };
template<class U> struct mpi_op< maximum<U> > { static MPI_Op get(const maximum<U>&) { return MPI_MAX; } };
template<class U> struct mpi_op< minimum<U> > { static MPI_Op get(const minimum<U>&) { return MPI_MIN; } };
template<class U> struct mpi_op< std::plus<U> > { static MPI_Op get(const std::plus<U>&) { return MPI_SUM; } };
template<class U> struct mpi_op< std::multiplies<U> > { static MPI_Op get(const std::multiplies<U>&) { return MPI_PROD; } };
template<class U> struct mpi_op< std::logical_and<U> > { static MPI_Op get(const std::logical_and<U>&) { return MPI_LAND; } };
template<class U> struct mpi_op< std::logical_or<U> > { static MPI_Op get(const std::logical_or<U>&) { return MPI_LOR; } };
template<class T> struct mpi_op { static MPI_Op get(); };
template<class U> struct mpi_op< maximum<U> > { static MPI_Op get() { return MPI_MAX; } };
template<class U> struct mpi_op< minimum<U> > { static MPI_Op get() { return MPI_MIN; } };
template<class U> struct mpi_op< std::plus<U> > { static MPI_Op get() { return MPI_SUM; } };
template<class U> struct mpi_op< std::multiplies<U> > { static MPI_Op get() { return MPI_PROD; } };
template<class U> struct mpi_op< std::logical_and<U> > { static MPI_Op get() { return MPI_LAND; } };
template<class U> struct mpi_op< std::logical_or<U> > { static MPI_Op get() { return MPI_LOR; } };
}
}
}

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