Merge branch 'master' of gitlab.kitware.com:dpugmire/vtk-m

This commit is contained in:
Dave Pugmire 2017-07-28 10:07:37 -04:00
commit 3759887aed
863 changed files with 109331 additions and 63005 deletions

17
.clang-format Normal file

@ -0,0 +1,17 @@
---
# This configuration requires clang-format 3.8 or higher.
BasedOnStyle: Mozilla
AlignAfterOpenBracket: Align
AlignOperands: false
AlwaysBreakAfterReturnType: None
AlwaysBreakAfterDefinitionReturnType: None
BreakBeforeBraces: Allman
BinPackArguments: false
BinPackParameters: false
ColumnLimit: 100
MaxEmptyLinesToKeep: 4
Standard: Cpp11
# This requires clang-format 4.0 (at least).
#FixNamespaceComments: true
ReflowComments: false
...

13
.gitattributes vendored

@ -1,2 +1,15 @@
# Attributes used for formatting.
[attr]our-c-style whitespace=tab-in-indent format.clang-format
*.cxx our-c-style
*.h our-c-style
*.hxx our-c-style
*.cu our-c-style
data/* filter=lfs diff=lfs merge=lfs -text
/**/data/* filter=lfs diff=lfs merge=lfs -text
*.cmake whitespace=tab-in-indent
*.md whitespace=tab-in-indent conflict-marker-size=79 -whitespace
*.rst whitespace=tab-in-indent conflict-marker-size=79
*.txt whitespace=tab-in-indent

@ -136,6 +136,20 @@ set(TBB_INC_SEARCH_PATH "")
set(TBB_LIB_SEARCH_PATH "")
# If we found parts of TBB in a previous pass, add the directories for those
# components to the list of those we look for.
if(TBB_INCLUDE_DIR)
list(APPEND TBB_INC_SEARCH_PATH ${TBB_INCLUDE_DIR})
endif()
if(TBB_LIBRARY_RELEASE)
get_filename_component(dir ${TBB_LIBRARY_RELEASE} DIRECTORY)
list(APPEND TBB_LIB_SEARCH_PATH ${dir})
elseif(TBB_LIBRARY_DEBUG)
get_filename_component(dir ${TBB_LIBRARY_DEBUG} DIRECTORY)
list(APPEND TBB_LIB_SEARCH_PATH ${dir})
endif()
# If user built from sources
set(TBB_BUILD_PREFIX $ENV{TBB_BUILD_PREFIX})
if (TBB_BUILD_PREFIX AND ENV_TBB_ROOT)

@ -29,9 +29,7 @@ find_package(Doxygen REQUIRED)
set(VTKm_DOXYGEN_HAVE_DOT ${DOXYGEN_DOT_FOUND})
set(VTKm_DOXYGEN_DOT_PATH ${DOXYGEN_DOT_PATH})
set(VTKm_DOXYFILE ${CMAKE_CURRENT_BINARY_DIR}/docs/doxyfile)
set(VTKm_DOXYGEN_EXCLUDE_FILES
${VTKm_SOURCE_DIR}/vtkm/testing/OptionParser.h
)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/CMake/doxyfile.in ${VTKm_DOXYFILE}
@ONLY)

@ -56,10 +56,8 @@ function(vtkm_configure_component_message message_text)
list(FIND VTKm_CONFIGURE_COMPONENT_MESSAGES "${message_text}" in_list)
if(in_list EQUAL -1)
message(STATUS "${message_text}")
set(VTKm_CONFIGURE_COMPONENT_MESSAGES
${VTKm_CONFIGURE_COMPONENT_MESSAGES}
${message_text}
CACHE INTERNAL "" FORCE)
set(VTKm_CONFIGURE_COMPONENT_MESSAGES "${VTKm_CONFIGURE_COMPONENT_MESSAGES} ${message_text}"
CACHE STRING "" FORCE)
endif()
endif()
endfunction(vtkm_configure_component_message)
@ -174,8 +172,13 @@ macro(vtkm_configure_component_OpenGL)
ADD_LIBRARIES ${vtkm_opengl_libraries}
)
set(VTKm_OPENGL_INCLUDE_DIRS ${vtkm_opengl_includes})
set(VTKm_OPENGL_LIBRARIES ${vtkm_opengl_libraries})
#setting VTKm_OPENGL_INCLUDE_DIRS when both mesa and
#opengl are not present causes cmake to fail to configure
#becase of a percieved dependency in the rendering lib
if(VTKm_OSMesa_FOUND OR OPENGL_FOUND)
set(VTKm_OPENGL_INCLUDE_DIRS ${vtkm_opengl_includes})
set(VTKm_OPENGL_LIBRARIES ${vtkm_opengl_libraries})
endif()
endmacro(vtkm_configure_component_OpenGL)
@ -323,26 +326,29 @@ macro(vtkm_configure_component_CUDA)
# 1 - native
# - Uses system introspection to determine compile flags
# 2 - fermi
# - Uses: --generate-code arch=compute_20,code=compute_20
# - Uses: --generate-code=arch=compute_20,code=compute_20
# 3 - kepler
# - Uses: --generate-code arch=compute_30,code=compute_30
# - Uses: --generate-code arch=compute_35,code=compute_35
# - Uses: --generate-code=arch=compute_30,code=compute_30
# - Uses: --generate-code=arch=compute_35,code=compute_35
# 4 - maxwell
# - Uses: --generate-code arch=compute_50,code=compute_50
# - Uses: --generate-code arch=compute_52,code=compute_52
# - Uses: --generate-code=arch=compute_50,code=compute_50
# - Uses: --generate-code=arch=compute_52,code=compute_52
# 5 - pascal
# - Uses: --generate-code arch=compute_60,code=compute_60
# - Uses: --generate-code arch=compute_61,code=compute_61
# - Uses: --generate-code=arch=compute_60,code=compute_60
# - Uses: --generate-code=arch=compute_61,code=compute_61
# 6 - all
# - Uses: --generate-code arch=compute_20,code=compute_20
# - Uses: --generate-code arch=compute_30,code=compute_30
# - Uses: --generate-code arch=compute_35,code=compute_35
# - Uses: --generate-code arch=compute_50,code=compute_50
# - Uses: --generate-code=arch=compute_20,code=compute_20
# - Uses: --generate-code=arch=compute_30,code=compute_30
# - Uses: --generate-code=arch=compute_35,code=compute_35
# - Uses: --generate-code=arch=compute_50,code=compute_50
# - Uses: --generate-code=arch=compute_52,code=compute_52
# - Uses: --generate-code=arch=compute_60,code=compute_60
# - Uses: --generate-code=arch=compute_61,code=compute_61
#
#specify the property
set(VTKm_CUDA_Architecture "native" CACHE STRING "Which GPU Architecture(s) to compile for")
set_property(CACHE VTKm_CUDA_Architecture PROPERTY STRINGS native fermi kepler maxwell all)
set_property(CACHE VTKm_CUDA_Architecture PROPERTY STRINGS native fermi kepler maxwell pascal all)
#detect what the propery is set too
if(VTKm_CUDA_Architecture STREQUAL "native")
@ -355,8 +361,10 @@ macro(vtkm_configure_component_CUDA)
#run execute_process to do auto_detection
if(CMAKE_GENERATOR MATCHES "Visual Studio")
set(args "-ccbin" "${CMAKE_CXX_COMPILER}" "--run" "${VTKm_CMAKE_MODULE_PATH}/VTKmDetectCUDAVersion.cu")
else()
elseif(CUDA_HOST_COMPILER)
set(args "-ccbin" "${CUDA_HOST_COMPILER}" "--run" "${VTKm_CMAKE_MODULE_PATH}/VTKmDetectCUDAVersion.cu")
else()
set(args "--run" "${VTKm_CMAKE_MODULE_PATH}/VTKmDetectCUDAVersion.cu")
endif()
execute_process(
@ -364,6 +372,7 @@ macro(vtkm_configure_component_CUDA)
RESULT_VARIABLE ran_properly
OUTPUT_VARIABLE run_output
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
if(ran_properly EQUAL 0)
#find the position of the "--generate-code" output. With some compilers such as
#msvc we get compile output plus run output. So we need to strip out just the
@ -376,9 +385,7 @@ macro(vtkm_configure_component_CUDA)
"device type(s) for cuda[native]")
else()
set(VTKm_CUDA_Architecture "fermi")
vtkm_configure_component_message(
"Unable to run \"${CUDA_NVCC_EXECUTABLE}\" to autodetect GPU architecture.
Falling back to fermi, please manually specify if you want something else.")
vtkm_configure_component_message("Unable to run ${CUDA_NVCC_EXECUTABLE} to autodetect GPU architecture. Falling back to fermi, please manually specify if you want something else.")
endif()
endif()
endif()
@ -386,24 +393,24 @@ Falling back to fermi, please manually specify if you want something else.")
#since when we are native we can fail, and fall back to "fermi" these have
#to happen after, and separately of the native check
if(VTKm_CUDA_Architecture STREQUAL "fermi")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --generate-code arch=compute_20,code=compute_20")
list(APPEND CUDA_NVCC_FLAGS "--generate-code=arch=compute_20,code=compute_20")
elseif(VTKm_CUDA_Architecture STREQUAL "kepler")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --generate-code arch=compute_30,code=compute_30")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --generate-code arch=compute_35,code=compute_35")
list(APPEND CUDA_NVCC_FLAGS "--generate-code=arch=compute_30,code=compute_30")
list(APPEND CUDA_NVCC_FLAGS "--generate-code=arch=compute_35,code=compute_35")
elseif(VTKm_CUDA_Architecture STREQUAL "maxwell")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --generate-code arch=compute_50,code=compute_50")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --generate-code arch=compute_52,code=compute_52")
list(APPEND CUDA_NVCC_FLAGS "--generate-code=arch=compute_50,code=compute_50")
list(APPEND CUDA_NVCC_FLAGS "--generate-code=arch=compute_52,code=compute_52")
elseif(VTKm_CUDA_Architecture STREQUAL "pascal")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --generate-code arch=compute_60,code=compute_60")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --generate-code arch=compute_61,code=compute_61")
list(APPEND CUDA_NVCC_FLAGS "--generate-code=arch=compute_60,code=compute_60")
list(APPEND CUDA_NVCC_FLAGS "--generate-code=arch=compute_61,code=compute_61")
elseif(VTKm_CUDA_Architecture STREQUAL "all")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --generate-code arch=compute_20,code=compute_20")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --generate-code arch=compute_30,code=compute_30")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --generate-code arch=compute_35,code=compute_35")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --generate-code arch=compute_50,code=compute_50")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --generate-code arch=compute_52,code=compute_52")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --generate-code arch=compute_60,code=compute_60")
set(CUDA_NVCC_FLAGS "${CUDA_NVCC_FLAGS} --generate-code arch=compute_61,code=compute_61")
list(APPEND CUDA_NVCC_FLAGS "--generate-code=arch=compute_20,code=compute_20")
list(APPEND CUDA_NVCC_FLAGS "--generate-code=arch=compute_30,code=compute_30")
list(APPEND CUDA_NVCC_FLAGS "--generate-code=arch=compute_35,code=compute_35")
list(APPEND CUDA_NVCC_FLAGS "--generate-code=arch=compute_50,code=compute_50")
list(APPEND CUDA_NVCC_FLAGS "--generate-code=arch=compute_52,code=compute_52")
list(APPEND CUDA_NVCC_FLAGS "--generate-code=arch=compute_60,code=compute_60")
list(APPEND CUDA_NVCC_FLAGS "--generate-code=arch=compute_61,code=compute_61")
endif()
if(WIN32)

@ -19,31 +19,42 @@
// this software.
//
//=============================================================================
#include <cstdio>
#include <cuda.h>
#include <cuda_runtime.h>
#include <cstdio>
int main()
{
int count = 0;
if (cudaSuccess != cudaGetDeviceCount(&count)) return 1;
if (count == 0) return 1;
if (cudaSuccess != cudaGetDeviceCount(&count))
return 1;
if (count == 0)
return 1;
int prev_arch = 0;
for (int device = 0; device < count; ++device)
{
{
cudaDeviceProp prop;
if (cudaSuccess == cudaGetDeviceProperties(&prop, device))
{
{
int arch = (prop.major * 10) + prop.minor;
int compute_level = arch;
//arch 21 has no equivalent compute level.
if(compute_level == 21) { compute_level = 20; }
if (compute_level == 21)
{
compute_level = 20;
}
//handle multiple cards of the same architecture
if(arch == prev_arch) { continue; }
prev_arch = arch;
printf("--generate-code arch=compute_%d,code=sm_%d ", compute_level, arch);
if (arch == prev_arch)
{
continue;
}
prev_arch = arch;
//we need to print out a semi-colon as this needs to be output
//as a CMake list which is separated by semicolons
printf("--generate-code=arch=compute_%d,code=sm_%d;", compute_level, arch);
}
}
return 0;
}
}

@ -127,6 +127,11 @@ function(vtkm_add_header_build_test name dir_prefix use_cuda)
set_source_files_properties(${hfiles}
PROPERTIES HEADER_FILE_ONLY TRUE
)
if(MSVC)
vtkm_setup_msvc_properties(TestBuild_${name})
endif()
# Send the libraries created for test builds to their own directory so as to
# not polute the directory with useful libraries.
set_target_properties(TestBuild_${name} PROPERTIES

@ -38,7 +38,7 @@ ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = YES
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
@ -46,13 +46,15 @@ STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
SHOW_NAMESPACES = NO
JAVADOC_AUTOBRIEF = YES
MULTILINE_CPP_IS_BRIEF = NO
INHERIT_DOCS = YES
DISTRIBUTE_GROUP_DOC = NO
DISTRIBUTE_GROUP_DOC = YES
TAB_SIZE = 2
@ -136,17 +138,30 @@ WARN_LOGFILE =
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = @VTKm_SOURCE_DIR@/vtkm
INPUT = @VTKm_SOURCE_DIR@/README.md
INPUT += @VTKm_SOURCE_DIR@/CONTRIBUTING.md
INPUT += @VTKm_SOURCE_DIR@/docs/CodingConventions.md
INPUT += @VTKm_SOURCE_DIR@/vtkm
USE_MDFILE_AS_MAINPAGE = README.md
FILE_PATTERNS = *.cxx *.h *.cu
RECURSIVE = YES
EXCLUDE = @VTKm_DOXYGEN_EXCLUDE_FILES@
EXCLUDE = @VTKm_SOURCE_DIR@/vtkm/testing/OptionParser.h
EXCLUDE += @VTKm_SOURCE_DIR@/vtkm/exec/cuda/internal/ExecutionPolicy.h
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_PATTERNS = */testing/*
EXCLUDE_PATTERNS += */examples/*
EXCLUDE_PATTERNS += UnitTest*
EXCLUDE_SYMBOLS = thrust
EXCLUDE_SYMBOLS += detail
EXCLUDE_SYMBOLS += placeholders
EXCLUDE_SYMBOLS += benchmarking
EXAMPLE_PATH =
@ -172,9 +187,9 @@ INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = YES
REFERENCED_BY_RELATION = NO
REFERENCES_RELATION = YES
REFERENCES_RELATION = NO
VERBATIM_HEADERS = YES
@ -182,9 +197,9 @@ VERBATIM_HEADERS = YES
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
ALPHABETICAL_INDEX = YES
COLS_IN_ALPHA_INDEX = 5
COLS_IN_ALPHA_INDEX = 2
IGNORE_PREFIX =
@ -220,7 +235,7 @@ DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = YES
GENERATE_TREEVIEW = NO
TREEVIEW_WIDTH = 250
@ -364,7 +379,7 @@ COLLABORATION_GRAPH = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = YES
TEMPLATE_RELATIONS = NO
INCLUDE_GRAPH = YES
@ -372,7 +387,7 @@ INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
GRAPHICAL_HIERARCHY = NO
DOT_IMAGE_FORMAT = png
@ -380,7 +395,9 @@ DOT_PATH = @VTKm_DOXYGEN_DOT_PATH@
DOTFILE_DIRS =
MAX_DOT_GRAPH_DEPTH = 0
DOT_GRAPH_MAX_NODES = 75
MAX_DOT_GRAPH_DEPTH = 5
GENERATE_LEGEND = YES

@ -99,8 +99,8 @@ option(VTKm_ENABLE_TESTING "Enable VTKm Testing" ON)
option(VTKm_ENABLE_BENCHMARKS "Enable VTKm Benchmarking" OFF)
option(VTKm_ENABLE_OSMESA "Enable creating the OSMesa canvas" OFF)
option(VTKm_BUILD_DOCUMENTATION "Build Doxygen documentation" OFF)
option(VTKm_BUILD_EXAMPLES "Build examples" OFF)
option(VTKm_ENABLE_DOCUMENTATION "Build Doxygen documentation" OFF)
option(VTKm_ENABLE_EXAMPLES "Build examples" OFF)
option(VTKm_USE_DOUBLE_PRECISION
"Use double precision for floating point calculations"
@ -212,7 +212,7 @@ add_subdirectory(vtkm)
#-----------------------------------------------------------------------------
# Build documentation
if (VTKm_BUILD_DOCUMENTATION)
if (VTKm_ENABLE_DOCUMENTATION)
include(CMake/VTKmBuildDocumentation.cmake)
vtkm_build_documentation()
endif()
@ -340,6 +340,6 @@ include(CPack)
#-----------------------------------------------------------------------------
# Build examples
if(VTKm_BUILD_EXAMPLES)
if(VTKm_ENABLE_EXAMPLES)
add_subdirectory(examples)
endif(VTKm_BUILD_EXAMPLES)
endif(VTKm_ENABLE_EXAMPLES)

@ -1,51 +1,445 @@
Contributing to VTK-m
=====================
This page documents at a very high level how to contribute to VTK-m.
Please check our [developer instructions][] for a more detailed guide to
developing and contributing to the project.
This page documents how to develop VTK-m through [Git](http://git-scm.com).
1. Register [GitLab Access] to create an account and select a user name.
Git is an extremely powerful version control tool that supports many
different "workflows" for individual development and collaboration.
Here we document procedures used by the VTK-m development community.
In the interest of simplicity and brevity we do *not* provide an
explanation of why we use this approach.
Setup
-----
Before you begin, perform initial setup:
1. Register [GitLab Access][] to create an account and select a user name.
2. [Fork VTK-m][] into your user's namespace on GitLab.
3. Create a local clone of the main VTK-m repository:
3. Follow the [download instructions](download.md#clone) to create a
local clone of the main VTK repository:
$ git clone https://gitlab.kitware.com/vtk/vtk-m.git vtkm
$ cd vtkm
$ git clone https://gitlab.kitware.com/vtk/vtk-m.git VTK
$ cd vtk-m
The main repository will be configured as your `origin` remote.
4. Associate your GitLab fork of VTK-m VTK-m repository:
4. Run the [developer setup script] to prepare your VTK-m work tree and
create Git command aliases used below:
$ git remote add gitlab git@gitlab.com:username/vtk-m.git
$ ./Utilities/SetupForDevelopment.sh
Your fork will be configured as your `gitlab` remote.
This will prompt for your GitLab user name and configure a remote
called `gitlab` to refer to it.
5. Edit files and create commits (repeat as needed):
5. (Optional but highly recommended.)
[Register](https://open.cdash.org/register.php) with the VTK-m project
on Kitware's CDash instance to better know how your code performs in
regression tests. After registering and signing in, click on
"All Dashboards" link in the upper left corner, scroll down and click
"Subscribe to this project" on the right of VTK-m.
[GitLab Access]: https://gitlab.kitware.com/users/sign_in
[Fork VTK-m]: https://gitlab.kitware.com/vtk/vtk-m/forks/new
Workflow
--------
VTK-m development uses a [branchy workflow][] based on topic branches.
Our collaboration workflow consists of three main steps:
1. Local Development:
* [Update](#update)
* [Create a Topic](#create-a-topic)
2. Code Review (requires [GitLab Access][]):
* [Share a Topic](#share-a-topic)
* [Create a Merge Request](#create-a-merge-request)
* [Review a Merge Request](#review-a-merge-request)
* [Reformat a Topic](#reformat-a-topic)
* [Revise a Topic](#revise-a-topic)
3. Integrate Changes:
* [Merge a Topic](#merge-a-topic) (requires permission in GitLab)
[branchy workflow]: http://public.kitware.com/Wiki/Git/Workflow/Topic
Update
------
1. Update your local `master` branch:
$ git checkout master
$ git pull
2. Optionally push `master` to your fork in GitLab:
$ git push gitlab master
Create a Topic
--------------
All new work must be committed on topic branches.
Name topics like you might name functions: concise but precise.
A reader should have a general idea of the feature or fix to be developed given just the branch name.
1. To start a new topic branch:
$ git fetch origin
2. For new development, start the topic from `origin/master`:
$ git checkout -b my-topic origin/master
3. Edit files and create commits (repeat as needed):
$ edit file1 file2 file3
$ git add file1 file2 file3
$ git commit
6. Push commits in your topic branch to your fork in GitLab:
$ git push gitlab HEAD
7. Visit your fork in GitLab, browse to the "**Merge Requests**" link on the
left, and use the "**New Merge Request**" button in the upper right to
create a Merge Request.
Caveats:
* Data files must be placed in either the root data directory, or a
folder explicitly named 'data'. This is required as VTK-m uses Git-LFS
to efficiently support data files.
VTK-m uses GitLab for code review and Buildbot to test proposed
patches before they are merged.
Guidelines for Commit Messages
------------------------------
Our [Issue Tracker][] is used to document feature requests and technical issues.
Remember to *motivate & summarize*. When writing commit messages, get into
the habit of creating messages that have enough information for any developer
to read and glean relevant information such as:
Our [Wiki][] is out to propose new infrastructure designs and host other
documentation.
1. Is this change important and why?
2. If addressing an issue, which issue(s)?
3. If a new feature, why is it useful and/or necessary?
4. Are there background references or documentation?
[developer instructions]: http://m.vtk.org/index.php/Contributing_to_VTK-m
[GitLab Access]: https://gitlab.kitware.com/users/sign_in
[Fork VTK-m]: https://gitlab.kitware.com/vtk/vtk/fork/new
[Issue Tracker]: https://gitlab.kitware.com/vtk/vtk-m/issues
[Wiki]: http://m.vtk.org/
A short description of what the issue being addressed and how will go a long way
towards making the log more readable and the software more maintainable. VTK-m
requires that your message start with a single subject line, followed by a
blank line, followed by the message body which contains the more detailed
explanatory text for the commit. You can consider a commit message to very
similar to an email with the first line being the subject of an email and the
rest of the text as the body.
Style guidelines for commit messages are as follows:
1. Separate subject from body with a blank line
2. Limit the subject line to 78 characters
3. Capitalize the subject line
4. Use the imperative mood in the subject line e.g. "Refactor foo" or "Fix Issue #12322",
instead of "Refactoring foo", or "Fixing issue #12322".
5. Wrap the body at 80 characters
6. Use the body to explain `what` and `why` and if applicable a brief `how`.
Share a Topic
-------------
When a topic is ready for review and possible inclusion, share it by pushing
to a fork of your repository in GitLab. Be sure you have registered and
signed in for [GitLab Access][] and created your fork by visiting the main
[VTK-m GitLab][] repository page and using the "Fork" button in the upper right.
[VTK-m GitLab]: https://gitlab.kitware.com/vtk/vtk-m
1. Checkout the topic if it is not your current branch:
$ git checkout my-topic
2. Push commits in your topic branch to your fork in GitLab:
$ git gitlab-push
Notes:
* If you are revising a previously pushed topic and have rewritten the
topic history, add `-f` or `--force` to overwrite the destination.
* The `gitlab-push` script also pushes the `master` branch to your
fork in GitLab to keep it in sync with the upstream `master`.
The output will include a link to the topic branch in your fork in GitLab
and a link to a page for creating a Merge Request.
Create a Merge Request
----------------------
Visit your fork in GitLab, browse to the "**Merge Requests**" link on the
left, and use the "**New Merge Request**" button in the upper right to
reach the URL printed at the end of the [previous step](#share-a-topic).
It should be of the form:
https://gitlab.kitware.com/<username>/vtk-m/merge_requests/new
Follow these steps:
1. In the "**Source branch**" box select the `<username>/vtk-m` repository
and the `my-topic` branch.
2. In the "**Target branch**" box select the `vtk/vtk-m` repository and
the `master` branch. It should be the default.
3. Use the "**Compare branches**" button to proceed to the next page
and fill out the merge request creation form.
4. In the "**Title**" field provide a one-line summary of the entire
topic. This will become the title of the Merge Request.
Example Merge Request Title:
Add OpenMP Device Adapter
5. In the "**Description**" field provide a high-level description
of the change the topic makes and any relevant information about
how to try it.
* Use `@username` syntax to draw attention of specific developers.
This syntax may be used anywhere outside literal text and code
blocks. Or, wait until the [next step](#review-a-merge-request)
and add comments to draw attention of developers.
* Optionally use a fenced code block with type `message` to specify
text to be included in the generated merge commit message when the
topic is [merged](#merge-a-topic).
Example Merge Request Description:
This branch adds a new device adapter that uses new OpenMP 4+ features
including Task groups to better handle unbalanced and irregular domains
```message
Add a OpenMP 4+ task-based device adapter.
```
Cc: @user1 @user2
6. The "**Assign to**", "**Milestone**", and "**Labels**" fields
may be left blank.
7. Use the "**Submit merge request**" button to create the merge request
and visit its page.
Guidelines for Merge Requests
-----------------------------
Remember to *motivate & summarize*. When creating a merge request, consider the
reviewers and future perusers of the software. Provide enough information to motivate
the merge request such as:
1. Is this merge request important and why?
2. If addressing an issue, which issue(s)?
3. If a new feature, why is it useful and/or necessary?
4. Are there background references or documentation?
Also provide a summary statement expressing what you did and if there is a choice
in implementation or design pattern, the rationale for choosing a certain path.
Notable software or data features should be mentioned as well.
A well written merge request will motivate your reviewers, and bring them up
to speed faster. Future software developers will be able to understand the
reasons why something was done, and possibly avoid chasing down dead ends,
Although it may take you a little more time to write a good merge request,
youll likely see payback in faster reviews and better understood and
maintainable software.
Review a Merge Request
----------------------
Add comments mentioning specific developers using `@username` syntax to
draw their attention and have the topic reviewed. After typing `@` and
some text, GitLab will offer completions for developers whose real names
or user names match.
Comments use [GitLab Flavored Markdown][] for formatting. See GitLab
documentation on [Special GitLab References][] to add links to things
like merge requests and commits in other repositories.
[GitLab Flavored Markdown]: https://gitlab.kitware.com/help/markdown/markdown
[Special GitLab References]: https://gitlab.kitware.com/help/markdown/markdown#special-gitlab-references
### Reviews ###
Reviewers may add comments providing feedback or to acknowledge their
approval. All comments use the [GitLab Flavored Markdown][], any line of a
comment may be exactly one of the following votes followed by nothing but
whitespace before the end of the line:
* `-1` or :-1: (`:-1:`) means "The change is not ready for integration."
* `+1` or :+1: (`:+1:`) means "The change is ready for integration."
These are used to inform the author that a merge srequest has been approved
for [merging]((#merge-a-topic).
#### Fetching Changes ####s
One may fetch the changes associated with a merge request by using
the `git fetch` command line shown at the top of the Merge Request
page. It is of the form:
$ git fetch https://gitlab.kitware.com/$username/vtk-m.git $branch
This updates the local `FETCH_HEAD` to refer to the branch.
There are a few options for checking out the changes in a work tree:
* One may checkout the branch:
$ git checkout FETCH_HEAD -b $branch
or checkout the commit without creating a local branch:
$ git checkout FETCH_HEAD
* Or, one may cherry-pick the commits to minimize rebuild time:
$ git cherry-pick ..FETCH_HEAD
### Robot Reviews ###
The "Kitware Robot" automatically performs basic checks on the commits
and adds a comment acknowledging or rejecting the topic. This will be
repeated automatically whenever the topic is updated.
A re-check may be explicitly requested by adding a comment with a single
[*trailing* line](#trailing-lines):
Do: check
A topic cannot be [merged](#merge-a-topic) until the automatic review
succeeds.
### Testing ###
VTK-m has a [buildbot](http://buildbot.net) instance watching for merge requests
to test. Each time a merge request is updated the buildbot user (@buildbot)
will automatically trigger a new build on all VTK-m buildbot workers. The
buildbot user (@buildbot) will respond with a comment linking to the CDash
results when it schedules builds.
The buildbot user (@buildbot) will also respond to any comment with the form:
Do: test
The `Do: test` command accepts the following arguments:
* `--oneshot`
only build the *current* hash of the branch; updates will not be built
using this command
* `--stop`
clear the list of commands for the merge request
* `--superbuild`
build the superbuilds related to the project
* `--clear`
clear previous commands before adding this command
* `--regex-include <arg>` or `-i <arg>`
only build on builders matching `<arg>` (a Python regular expression)
* `--regex-exclude <arg>` or `-e <arg>`
excludes builds on builders matching `<arg>` (a Python regular
expression)
Multiple `Do: test` commands may be given in separate comments. Buildbot may
skip tests for older branch updates that have not started before a test for
a new update is requested.
Builder names always follow this pattern:
project-host-os-libtype-buildtype+feature1+feature2
* project: always `vtk-m`
* host: the buildbot host
* os: one of `windows`, `osx`, or `linux`
* libtype: `shared` or `static`
* buildtype: `release` or `debug`
* feature: alphabetical list of features enabled for the build
Reformat a Topic
----------------
The "Kitware Robot" automatically performs basic code formatting on the commits
and adds a comment acknowledging or rejecting a merge request based on the
format. You may request "Kitware Robot" to automatically reformat the
remote copy of your branch by issuing the command:
Do: reformat
This reformatting of the topic rewrites the commits to fix the formatting
errors, and causes the version on the developers machine to differ from
version on the gitlab server. To resolve this issue you must update
the local version to match the reformatted one on the server if you wish
to extend or revise the topic.
1. Checkout the topic if it is not your current branch:
$ git checkout my-topic
2. Get the new version from gitlab
$ git gitlab-sync -f
If you do not wish to have the "Kitware Robot" automatically reformat your
branch you can do so manually by running [clang-format][https://clang.llvm.org/docs/ClangFormat.html]
manually on each commit of your branch. This must be done by [revising each commit](#revise-a-topic)
not as new commits onto the end of the branch.
Revise a Topic
--------------
Revising a topic is a special way to modify the commits within a topic. Normally
during a review of a merge request a developer will resolve issues brought
up during review by adding more commits to the topic. While this is sufficient
for most issues, some issues can only be resolved by rewriting the history
of the topic.
If a reviewer has asked explicitly for certain commits to be rewritten, you will
need to revise the commits and force push it back to GitLab for another review.
To revise a topic for another review as follows:
1. Checkout the topic if it is not your current branch:
$ git checkout my-topic
2. To revise the `3`rd commit back on the topic:
$ git rebase -i HEAD~3
(Substitute the correct number of commits back, as low as `1`.)
Follow Git's interactive instructions.
3. Push commits in your topic branch to your fork in GitLab:
$ git gitlab-push -f
Notes:
* You need to add `-f` or `--force` to overwrite the destination as you
are revising a previously pushed topic and have rewritten the
topic history.
Merge a Topic
-------------
After a topic has been reviewed and approved in a GitLab Merge Request,
authorized developers may add a comment with a single
[*trailing* line](#trailing-lines):
Do: merge
to ask that the change be merged into the upstream repository. By
convention, only merge if you have recieved `+1` . Do not request a merge if
any `-1` review comments have not been resolved.
### Merge Success ###
If the merge succeeds the topic will appear in the upstream repository
`master` branch and the Merge Request will be closed automatically.
### Merge Failure ###
If the merge fails (likely due to a conflict), a comment will be added
describing the failure. In the case of a conflict, fetch the latest
upstream history and rebase on it:
$ git fetch origin
$ git rebase origin/master
Return to the [above step](#share-a-topic) to share the revised topic.

182
README.md

@ -1,30 +1,186 @@
## VTK-m ##
One of the biggest recent changes in high-performance computing is the increasing use of accelerators. Accelerators contain processing cores that independently are inferior to a core in a typical CPU, but these cores are replicated and grouped such that their aggregate execution provides a very high computation rate at a much lower power. Current and future CPU processors also require much more explicit parallelism. Each successive version of the hardware packs more cores into each processor, and technologies like hyperthreading and vector operations require even more parallel processing to leverage each cores full potential.
VTK-m is a toolkit of scientific visualization algorithms for emerging processor
architectures. VTK-m supports the fine-grained concurrency for data analysis and
visualization algorithms required to drive extreme scale computing by providing
abstract models for data and execution that can be applied to a variety of
algorithms across many different processor architectures.
VTK-m is a toolkit of scientific visualization algorithms for emerging processor architectures. VTK-m supports the fine-grained concurrency for data analysis and visualization algorithms required to drive extreme scale computing by providing abstract models for data and execution that can be applied to a variety of algorithms across many different processor architectures.
You can find out more about the design of VTK-m on our [wiki][]
Example
=======
## Getting VTK-m ##
The VTK-m source distribution includes a number of examples. The goal of the
VTK-m examples is to illustrate specific VTK-m concepts in a consistent and
simple format. However, these examples only cover a small part of the
capabilities of VTK-m.
The VTK-m repository is located at [https://gitlab.kitware.com/vtk/vtk-m](https://gitlab.kitware.com/vtk/vtk-m)
Below is a simple example of using VTK-m to load a VTK image file, run the
Marching Cubes algorithm on it, and render the results to an image:
VTK-m required dependencies are:
```cpp
vtkm::io::reader::VTKDataSetReader reader("path/to/vtk_image_file");
inputData = reader.ReadDataSet();
vtkm::Float64 isovalue = 100.0f;
std::string fieldName = "pointvar";
// Create an isosurface filter
vtkm::filter::MarchingCubes filter;
filter.SetIsoValue(0, isovalue);
vtkm::filter::ResultDataSet result = filter.Execute( inputData,
inputData.GetField(fieldName) );
filter.MapFieldOntoOutput(result, inputData.GetField(fieldName));
// compute the bounds and extends of the input data
vtkm::Bounds coordsBounds = inputData.GetCoordinateSystem().GetBounds();
vtkm::Vec<vtkm::Float64,3> totalExtent( coordsBounds.X.Length(),
coordsBounds.Y.Length(),
coordsBounds.Z.Length() );
vtkm::Float64 mag = vtkm::Magnitude(totalExtent);
vtkm::Normalize(totalExtent);
// setup a camera and point it to towards the center of the input data
vtkm::rendering::Camera camera;
camera.ResetToBounds(coordsBounds);
camera.SetLookAt(totalExtent*(mag * .5f));
camera.SetViewUp(vtkm::make_Vec(0.f, 1.f, 0.f));
camera.SetClippingRange(1.f, 100.f);
camera.SetFieldOfView(60.f);
camera.SetPosition(totalExtent*(mag * 2.f));
vtkm::rendering::ColorTable colorTable("thermal");
// Create a mapper, canvas and view that will be used to render the scene
vtkm::rendering::Scene scene;
vtkm::rendering::MapperRayTracer mapper;
vtkm::rendering::CanvasRayTracer canvas(512, 512);
vtkm::rendering::Color bg(0.2f, 0.2f, 0.2f, 1.0f);
// Render an image of the output isosurface
vtkm::cont::DataSet& outputData = result.GetDataSet();
scene.AddActor(vtkm::rendering::Actor(outputData.GetCellSet(),
outputData.GetCoordinateSystem(),
outputData.GetField(fieldName),
colorTable));
vtkm::rendering::View3D view(scene, mapper, canvas, camera, bg);
view.Initialize();
view.Paint();
view.SaveAs("demo_output.pnm");
```
Learning
========
VTK-m offers numerous different ways to learn how to use the provided components.
If you are interested in a high level overview of VTK-m a good place to start
is with the IEEE Vis talk ["VTK-m: Accelerating the Visualization Toolkit for Massively Threaded Architectures"](http://m.vtk.org/images/2/29/VTKmVis2016.pptx) or the older and more technical presentation
["VTK-m Overview for Intel Design Review"](http://m.vtk.org/images/a/a4/VTKmIntelMeet.pptx).
If you are interested in learning how to use the existing VTK-m codebase,
or how to integrate into your own project, we recommend reading "Part 1: Getting Started"
and "Part 2: Using VTK-m" of the [VTK-m Users Guide][].
If you want to contribute to VTK-m we recommend reading the following sections
of the [VTK-m Users Guide][].
+ "Part 2: Using VTK-m"
- Covers the core fundamental components of VTK-m including data model, worklets, and filters.
- "Part 3: Developing with VTK-m"
- Covers how to develop new worklets and filters.
- "Part 4: Advanced Development"
- Covers topics such as new worklet tags, opengl interop and custom device adapters .
Contributing
============
There are many ways to contribute to [VTK-m][], with varying levels of effort.
+ Ask a question on the [VTK-m users email list](http://vtk.org/mailman/listinfo/vtkm)
+ Submit a feature request or bug, or add to an existing discussion on the VTK-m [Issue Tracker][]
+ Submit a Pull Request to improve [VTK-m]
++ See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed instructions on how to create
a Pull Request.
++ Submit an Issue or Pull Request for the [VTK-m User's Guide](http://m.vtk.org/images/c/c8/VTKmUsersGuide.pdf)
Dependencies
============
VTK-m Requires:
+ C++11 Compiler. VTK-m has been confirmed to work with the following
+ GCC 4.8+
+ Clang 3.3+
+ XCode 5.0+
+ MSVC 2013+
+ [CMake 3.3](http://www.cmake.org/download/)
VTK-m optional dependencies are:
+ [Cuda Toolkit 7+](https://developer.nvidia.com/cuda-toolkit)
+ [TBB](https://www.threadingbuildingblocks.org/)
Optional dependencies are:
+ CUDA Device Adapter
+ [Cuda Toolkit 7+](https://developer.nvidia.com/cuda-toolkit)
+ TBB Device Adapter
+ [TBB](https://www.threadingbuildingblocks.org/)
+ Rendering Module
+ The rendering module requires that you have a extension binding library
and one rendering library. A windowing library is not needed expect
for some optional tests.
+ Extension Binding
+ [GLEW](http://glew.sourceforge.net/)
+ Rendering Canvas
+ OpenGL Driver (See your GPU/iGPU vendor)
+ EGL (See your GPU/iGPU vendor)
+ [OSMesa](https://www.mesa3d.org/osmesa.html)
+ Windowing/Contexts
+ EGL (See your GPU/iGPU vendor)
+ [GLFW](http://www.glfw.org/)
+ [GLUT](http://freeglut.sourceforge.net/)
Building
========
VTK-m supports all majors platforms ( Windows, Linux, OSX ), and uses CMake
to generate all the build rules for the project.
```
git clone https://gitlab.kitware.com/vtk/vtk-m.git vtkm
mkdir vtkm-build
cd vtkm-build
cmake-gui ../vtkm
$ git clone https://gitlab.kitware.com/vtk/vtk-m.git
$ mkdir vtkm-build
$ cd vtkm-build
$ cmake-gui ../vtk-m
$ make -j<N>
$ make test
```
A detailed walk-through of installing and building VTK-m can be found on our [Contributing page](http://m.vtk.org/index.php/Contributing_to_VTK-m)
The VTK-m CMake configuration supports several options, including what specific
device adapters ( e.g. CUDA, TBB ) that you wish to enable. Here are some
relevant options
| Variable | Description |
|-----------------------------|-----------------------------|
| BUILD_SHARED_LIBS | Enabled by default. Build all VTK-m libraries as shared libraries. |
| CMAKE_BUILD_TYPE | This statically specifies what build type (configuration) will be built in this build tree. Possible values are empty, Debug, Release, RelWithDebInfo and MinSizeRel. This variable is only meaningful to single-configuration generators (such as make and Ninja). |
| CMAKE_INSTALL_PREFIX | Directory to install VTK-m into. |
| VTKm_ENABLE_EXAMPLES | Disabled by default. Turn on building of simple examples of using VTK-m. |
| VTKm_ENABLE_BENCHMARKS | Disabled by default. Turn on additional timing tests. |
| VTKm_ENABLE_CUDA | Disabled by default. Enable CUDA backend. |
| VTKm_CUDA_Architecture | Defaults to native. Specify what GPU architecture(s) to build CUDA code for, options include native, fermi, kepler, maxwell, and pascal. |
| VTKm_ENABLE_TBB | Disabled by default. Enable Intel Threading Building Blocks backend. |
| VTKm_ENABLE_TESTING | Enabled by default. Turn on header, unit, worklet, and filter tests. |
| VTKm_ENABLE_RENDERING | Enabled by default. Turn on the rendering module. |
| VTKm_USE_64BIT_IDS | Enabled by default. This is the size of integers used to index arrays, points, cells, etc. Use 64 bit precision when on, 32 bit precision when off. |
| VTKm_USE_DOUBLE_PRECISION | Disabled by default. Precision to use in floating point numbers when no other precision can be inferred. Use 64 bit precision when on, 32 bit precision when off. |
License
=======
VTK-m is distributed under the OSI-approved BSD 3-clause License.
See [LICENSE.txt](LICENSE.txt) for details.
[VTK-m]: https://gitlab.kitware.com/vtk/vtk-m/
[Issue Tracker]: https://gitlab.kitware.com/vtk/vtk-m/issues
[wiki]: http://m.vtk.org/
[VTK-m Users Guide]: http://m.vtk.org/images/c/c8/VTKmUsersGuide.pdf

7
Utilities/GitSetup/.gitattributes vendored Normal file

@ -0,0 +1,7 @@
.git* export-ignore
.gitattributes -export-ignore
config* eol=lf whitespace=indent-with-non-tab
git-* eol=lf whitespace=indent-with-non-tab
tips eol=lf whitespace=indent-with-non-tab
setup-* eol=lf whitespace=indent-with-non-tab

202
Utilities/GitSetup/LICENSE Normal file

@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.

@ -0,0 +1,5 @@
Kitware Local Git Setup Scripts
Copyright 2010-2012 Kitware, Inc.
This product includes software developed at Kitware, Inc.
(http://www.kitware.com/).

87
Utilities/GitSetup/README Normal file

@ -0,0 +1,87 @@
Kitware Local Git Setup Scripts
Introduction
------------
This is a collection of local Git development setup scripts meant for
inclusion in project source trees to aid their development workflow.
Project-specific information needed by the scripts may be configured
in a "config" file added next to them in the project.
Import
------
A project may import these scripts into their source tree by
initializing a subtree merge. Bring up a Git prompt and set the
current working directory inside a clone of the target project.
Fetch the "setup" branch from the GitSetup repository:
$ git fetch ../GitSetup setup:setup
Prepare to merge the branch but place the content in a subdirectory.
Any prefix (with trailing '/') may be chosen so long as it is used
consistently within a project through the rest of these instructions:
$ git merge -s ours --no-commit setup
$ git read-tree -u --prefix=Utilities/GitSetup/ setup
Commit the merge with an informative message:
$ git commit
------------------------------------------------------------------------
Merge branch 'setup'
Add Utilities/GitSetup/ directory using subtree merge from
the general GitSetup repository "setup" branch.
------------------------------------------------------------------------
Optionally add to the project ".gitattributes" file the line
/Utilities/GitSetup export-ignore
to exclude the GitSetup directory from inclusion by "git archive"
since it does not make sense in source tarballs.
Configuration
-------------
Read the "Project configuration instructions" comment in each script.
Add a "config" file next to the scripts with desired configuration
(optionally copy and modify "config.sample"). For example, to
configure the "setup-hooks" script:
$ git config -f Utilities/GitSetup/config hooks.url "$url"
where "$url" is the project repository publishing the "hooks" branch.
When finished, add and commit the configuration file:
$ git add Utilities/GitSetup/config
$ git commit
Update
------
A project may update these scripts from the GitSetup repository.
Bring up a Git prompt and set the current working directory inside a
clone of the target project. Fetch the "setup" branch from the
GitSetup repository:
$ git fetch ../GitSetup setup:setup
Merge the "setup" branch into the subtree:
$ git merge -X subtree=Utilities/GitSetup setup
where "Utilities/GitSetup" is the same prefix used during the import
setup, but without a trailing '/'.
License
-------
Distributed under the Apache License 2.0.
See LICENSE and NOTICE for details.

10
Utilities/GitSetup/config Normal file

@ -0,0 +1,10 @@
[hooks]
url = https://gitlab.kitware.com/utils/gitsetup.git
[upstream]
url = https://gitlab.kitware.com/vtk/vtk-m.git
[gitlab]
host = gitlab.kitware.com
group-path = vtk
group-name = VTK
project-path = vtk-m
project-name = VTK-m

@ -0,0 +1,177 @@
#!/usr/bin/env bash
#=============================================================================
# Copyright 2010-2015 Kitware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#=============================================================================
USAGE='[<remote>] [<options>...] [--]
OPTIONS
--dry-run
Show what would be pushed without actually updating the destination
-f,--force
Force-push the topic HEAD to rewrite the destination branch
--no-default
Do not push the default branch (e.g. master)
--no-topic
Do not push the topic HEAD.
'
OPTIONS_SPEC=
SUBDIRECTORY_OK=Yes
. "$(git --exec-path)/git-sh-setup"
egrep-q() {
egrep "$@" >/dev/null 2>/dev/null
}
# Load the project configuration.
gitlab_upstream='' &&
gitlab_configured='' &&
config="${BASH_SOURCE%/*}/config" &&
protocol=$(git config -f "$config" --get gitlab.protocol ||
echo "https") &&
host=$(git config -f "$config" --get gitlab.host) &&
site=$(git config -f "$config" --get gitlab.site ||
echo "$protocol://$host") &&
group_path=$(git config -f "$config" --get gitlab.group-path) &&
project_path=$(git config -f "$config" --get gitlab.project-path) &&
gitlab_upstream="$site/$group_path/$project_path.git" &&
gitlab_pushurl=$(git config --get remote.gitlab.pushurl ||
git config --get remote.gitlab.url) &&
gitlab_configured=1
#-----------------------------------------------------------------------------
remote=''
refspecs=''
force=''
lease=false
lease_flag=''
no_topic=''
no_default=''
dry_run=''
# Parse the command line options.
while test $# != 0; do
case "$1" in
-f|--force) force='+'; lease=true ;;
--no-topic) no_topic=1 ;;
--dry-run) dry_run=--dry-run ;;
--no-default) no_default=1 ;;
--) shift; break ;;
-*) usage ;;
*) test -z "$remote" || usage ; remote="$1" ;;
esac
shift
done
test $# = 0 || usage
# Default remote.
test -n "$remote" || remote="gitlab"
if test -z "$no_topic"; then
# Identify and validate the topic branch name.
head="$(git symbolic-ref HEAD)" && topic="${head#refs/heads/}" || topic=''
if test -z "$topic" -o "$topic" = "master"; then
die 'Please name your topic:
git checkout -b descriptive-name'
fi
if $lease; then
have_ref=false
remoteref="refs/remotes/$remote/$topic"
if git rev-parse --verify -q "$remoteref"; then
have_ref=true
else
die "It seems that a local ref for the branch is
missing; forcing a push is dangerous and may overwrite
previous work. Fetch from the $remote remote first or
push without '-f' or '--force'."
fi
have_lease_flag=false
if git push -h | egrep-q -e '--force-with-lease'; then
have_lease_flag=true
fi
if $have_lease_flag && $have_ref; then
# Set the lease flag.
lease_flag="--force-with-lease=$topic:$remoteref"
# Clear the force string.
force=''
fi
fi
# The topic branch will be pushed by name.
refspecs="${force}HEAD:refs/heads/$topic $refspecs"
fi
# Fetch the current remote master branch head.
# This helps computation of a minimal pack to push.
echo "Fetching $remote master"
fetch_out=$(git fetch "$remote" master 2>&1) || die "$fetch_out"
gitlab_head=$(git rev-parse FETCH_HEAD) || exit
# Fetch the current upstream master branch head.
if origin_fetchurl=$(git config --get remote.origin.url) &&
test "$origin_fetchurl" = "$gitlab_upstream"; then
upstream_remote='origin'
else
upstream_remote="$gitlab_upstream"
fi
echo "Fetching $upstream_remote master"
fetch_out=$(git fetch "$upstream_remote" master 2>&1) || die "$fetch_out"
upstream_head=$(git rev-parse FETCH_HEAD) || exit
# Add a refspec to keep the remote master up to date if possible.
if test -z "$no_default" &&
base=$(git merge-base "$gitlab_head" "$upstream_head") &&
test "$base" = "$gitlab_head"; then
refspecs="$upstream_head:refs/heads/master $refspecs"
fi
# Exit early if we have nothing to push.
if test -z "$refspecs"; then
echo 'Nothing to push!'
exit 0
fi
# Push. Save output and exit code.
echo "Pushing to $remote"
push_config='-c advice.pushUpdateRejected=false'
push_stdout=$(git $push_config push $lease_flag --porcelain $dry_run "$remote" $refspecs); push_exit=$?
echo "$push_stdout"
if test "$push_exit" -ne 0 && test -z "$force"; then
# Advise the user to fetch if needed.
if echo "$push_stdout" | egrep-q 'stale info'; then
echo "
You have pushed to your branch from another machine; you may be overwriting
commits unintentionally. Fetch from the $remote remote and check that you are
not pushing an outdated branch."
fi
# Advise the user to force-push if needed.
if echo "$push_stdout" | egrep-q 'non-fast-forward'; then
echo '
Add "-f" or "--force" to push a rewritten topic.'
fi
fi
# Reproduce the push exit code.
exit $push_exit

@ -0,0 +1,135 @@
#!/usr/bin/env bash
#=============================================================================
# Copyright 2010-2015 Kitware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#=============================================================================
USAGE='[<remote>] [<options>...] [--]
OPTIONS
--dry-run
Show what would be changed without actually updating
--autostash
automatically stash/stash pop before and after
'
OPTIONS_SPEC=
SUBDIRECTORY_OK=Yes
. "$(git --exec-path)/git-sh-setup"
egrep-q() {
egrep "$@" >/dev/null 2>/dev/null
}
# Load the project configuration.
require_work_tree_exists
state_dir="$GIT_DIR"/gitlab-sync
#-----------------------------------------------------------------------------
remote=''
autostash="$(git config --bool gitlab.sync.autostash || echo false)"
dry_run=false
# Parse the command line options.
while test $# != 0; do
case "$1" in
--autostash) autostash=true ;;
--no-autostash) autostash=false ;;
--dry-run) dry_run=true ;;
--) shift; break ;;
-*) usage ;;
*) test -z "$remote" || usage ; remote="$1" ;;
esac
shift
done
test $# = 0 || usage
# Default remote.
test -n "$remote" || remote="gitlab"
# Identify and validate the topic branch name.
head="$(git symbolic-ref HEAD)" && topic="${head#refs/heads/}" || topic=''
if test -z "$topic" -o "$topic" = "master"; then
die 'You cant sync the master branch, please checkout the correct a branch with:
git checkout <branch>'
fi
#-----------------------------------------------------------------------------
apply_autostash () {
if test -f "$state_dir/autostash"
then
stash_sha1=$(cat "$state_dir/autostash")
if git stash apply $stash_sha1 2>&1 >/dev/null
then
gettext 'Applied autostash.'
else
git stash store -m "autostash" -q $stash_sha1 ||
die "$(eval_gettext "Cannot store \$stash_sha1")"
gettext 'Applying autostash resulted in conflicts.
Your changes are safe in the stash.
You can run "git stash pop" or "git stash drop" at any time.
'
fi
fi
}
finish_sync () {
apply_autostash &&
{ git gc --auto || true; } &&
rm -rf "$state_dir"
}
#-----------------------------------------------------------------------------
if test "$autostash" = true && ! (require_clean_work_tree) 2>/dev/null
then
gettext 'trying to stash local changes' &&
stash_sha1=$(git stash create "autostash") ||
die "$(gettext 'Cannot autostash')"
mkdir -p "$state_dir" &&
echo $stash_sha1 >"$state_dir/autostash" &&
stash_abbrev=$(git rev-parse --short $stash_sha1) &&
echo "$(eval_gettext 'Created autostash: $stash_abbrev')" &&
git reset --hard
fi
require_clean_work_tree "sync" "$(gettext "Error syncing \
We are trying to overwrite all local changes on this branch with the version on \
gitlab. Before you do this make sure to stash your changes or commit these \
changes to a different branch.")"
#-----------------------------------------------------------------------------
fetch_stdout=$(git fetch "$remote" $topic); fetch_exit=$?
gettext "$fetch_stdout"
if [ $fetch_exit -eq 0 ]
then
if test "$dry_run" = true
then
reset_stdout=$(git diff --color HEAD..FETCH_HEAD); fetch_exit=$?
gettext "$reset_stdout"
else
reset_stdout=$(git reset --hard FETCH_HEAD); fetch_exit=$?
gettext "$reset_stdout"
fi
fi
finish_sync
# Reproduce the push exit code.
exit $fetch_exit

140
Utilities/GitSetup/setup-gitlab Executable file

@ -0,0 +1,140 @@
#!/usr/bin/env bash
#=============================================================================
# Copyright 2010-2015 Kitware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#=============================================================================
# Run this script to set up the local Git repository to push to
# a personal fork for this project in GitLab.
# Project configuration instructions:
#
# - Run a GitLab server
#
# - Populate adjacent "config" file with:
# gitlab.protocol = Top GitLab protocol, if not 'https'
# gitlab.host = Top GitLab fully qualified host name
# gitlab.site = Top GitLab URL, if not "<protocol>://<host>"
# gitlab.group-name = Name of group containing project in GitLab
# gitlab.group-path = Path of group containing project in GitLab
# gitlab.project-name = Name of project within GitLab group
# gitlab.project-path = Path of project within GitLab group
# gitlab.url = GitLab push URL with "$username" placeholder,
# if not "<site>/$username/<project-path>.git"
# gitlab.pushurl = GitLab push URL with "$username" placeholder,
# if not "git@<host>:$username/<project-path>.git"
# gitlab.remote = GitLab remote name, if not "gitlab"
die() {
echo 1>&2 "$@" ; exit 1
}
# Make sure we are inside the repository.
cd "${BASH_SOURCE%/*}" &&
# Load the project configuration.
protocol=$(git config -f config --get gitlab.protocol ||
echo "https") &&
host=$(git config -f config --get gitlab.host) &&
site=$(git config -f config --get gitlab.site ||
echo "$protocol://$host") &&
group_path=$(git config -f config --get gitlab.group-path) &&
group_name=$(git config -f config --get gitlab.group-name) &&
project_name=$(git config -f config --get gitlab.project-name) &&
project_path=$(git config -f config --get gitlab.project-path) &&
pushurl_=$(git config -f config --get gitlab.pushurl ||
echo "git@$host:\$username/$project_path.git") &&
remote=$(git config -f config --get gitlab.remote ||
echo "gitlab") &&
fetchurl_=$(git config -f config --get gitlab.url ||
echo "$site/\$username/$project_path.git") ||
die 'This project is not configured to use GitLab.'
# Get current gitlab push URL.
pushurl=$(git config --get remote."$remote".pushurl ||
git config --get remote."$remote".url || echo '') &&
# Tell user about current configuration.
if test -n "$pushurl"; then
echo 'Remote "'"$remote"'" is currently configured to push to
'"$pushurl"'
' &&
read -ep 'Reconfigure GitLab? [y/N]: ' ans &&
if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then
setup=1
else
setup=''
fi
else
echo 'Remote "'"$remote"'" is not yet configured.
' &&
read -ep 'Configure GitLab to contribute to '"$project_name"'? [Y/n]: ' ans &&
if [ "$ans" == "n" ] || [ "$ans" == "N" ]; then
exit 0
else
setup=1
fi
fi &&
setup_instructions='Add your SSH public keys at
'"$site"'/profile/keys
Then visit the main repository at:
'"$site/$group_path/$project_path"'
and use the Fork button in the upper right.
'
# Perform setup if necessary.
if test -n "$setup"; then
echo 'Sign-in to GitLab to get/set your username at
'"$site/profile/account"'
'"$setup_instructions" &&
read -ep "GitLab username? [$USER]: " gu &&
if test -z "$gu"; then
gu="$USER"
fi &&
fetchurl="${fetchurl_/\$username/$gu}" &&
if test -z "$pushurl"; then
git remote add "$remote" "$fetchurl"
else
git config remote."$remote".url "$fetchurl"
fi &&
pushurl="${pushurl_/\$username/$gu}" &&
git config remote."$remote".pushurl "$pushurl" &&
echo 'Remote "'"$remote"'" is now configured to push to
'"$pushurl"'
'
fi &&
# Optionally test GitLab access.
if test -n "$pushurl"; then
read -ep 'Test access to GitLab (SSH)? [y/N]: ' ans &&
if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then
echo -n 'Testing GitLab access by SSH...'
if git ls-remote --heads "$pushurl" >/dev/null; then
echo 'passed.'
else
echo 'failed.' &&
die 'Could not access your GitLab fork of this project.
'"$setup_instructions"
fi
fi
fi

64
Utilities/GitSetup/setup-hooks Executable file

@ -0,0 +1,64 @@
#!/usr/bin/env bash
#=============================================================================
# Copyright 2010-2012 Kitware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#=============================================================================
# Run this script to set up local Git hooks for this project.
# Project configuration instructions:
#
# - Publish a "hooks" branch in the project repository such that
# clones will have "refs/remotes/origin/hooks".
#
# - Populate adjacent "config" file with:
# hooks.url = Repository URL publishing "hooks" branch
# hooks.branch = Repository branch instead of "hooks"
egrep-q() {
egrep "$@" >/dev/null 2>/dev/null
}
die() {
echo 1>&2 "$@" ; exit 1
}
# Make sure we are inside the repository.
cd "${BASH_SOURCE%/*}" &&
# Select a hooks branch.
if url=$(git config --get hooks.url); then
# Fetch hooks from locally configured repository.
branch=$(git config hooks.branch || echo hooks)
elif git for-each-ref refs/remotes/origin/hooks 2>/dev/null |
egrep-q 'refs/remotes/origin/hooks$'; then
# Use hooks cloned from origin.
url=.. && branch=remotes/origin/hooks
elif url=$(git config -f config --get hooks.url); then
# Fetch hooks from project-configured repository.
branch=$(git config -f config hooks.branch || echo hooks)
else
die 'This project is not configured to install local hooks.'
fi &&
# Populate ".git/hooks".
echo 'Setting up git hooks...' &&
git_dir=$(git rev-parse --git-dir) &&
mkdir -p "$git_dir/hooks" &&
cd "$git_dir/hooks" &&
if ! test -e .git; then
git init -q || die 'Could not run git init for hooks.'
fi &&
git fetch -q "$url" "$branch" &&
git reset -q --hard FETCH_HEAD || die 'Failed to install hooks'

111
Utilities/GitSetup/setup-ssh Executable file

@ -0,0 +1,111 @@
#!/usr/bin/env bash
#=============================================================================
# Copyright 2010-2012 Kitware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#=============================================================================
# Run this script to set up ssh push access to the repository host.
# Project configuration instructions:
#
# - Populate adjacent "config" file with:
# ssh.host = Repository host name
# ssh.user = Username on host, if not "git"
# ssh.key = Local ssh key name
# ssh.request-url = Web page URL to request ssh access
egrep-q() {
egrep "$@" >/dev/null 2>/dev/null
}
die() {
echo 1>&2 "$@" ; exit 1
}
# Make sure we are inside the repository.
cd "${BASH_SOURCE%/*}" &&
# Load the project configuration.
host=$(git config -f config --get ssh.host) &&
user=$(git config -f config --get ssh.user || echo git) &&
key=$(git config -f config --get ssh.key) &&
request_url=$(git config -f config --get ssh.request-url) ||
die 'This project is not configured for ssh push access.'
# Check for existing configuration.
if test -r ~/.ssh/config &&
egrep-q 'Host[= ]'"${host//\./\\.}" ~/.ssh/config; then
echo 'Host "'"$host"'" is already in ~/.ssh/config' &&
setup= &&
question='Test'
else
echo 'Host "'"$host"'" not found in ~/.ssh/config' &&
setup=1 &&
question='Setup and test'
fi &&
# Ask the user whether to make changes.
echo '' &&
read -ep "${question} push access by ssh to $user@$host? [y/N]: " access &&
if test "$access" != "y" -a "$access" != "Y"; then
exit 0
fi &&
# Setup host configuration if necessary.
if test -n "$setup"; then
if ! test -d ~/.ssh; then
mkdir -p ~/.ssh &&
chmod 700 ~/.ssh
fi &&
if ! test -f ~/.ssh/config; then
touch ~/.ssh/config &&
chmod 600 ~/.ssh/config
fi &&
ssh_config='Host='"$host"'
IdentityFile ~/.ssh/'"$key" &&
echo "Adding to ~/.ssh/config:
$ssh_config
" &&
echo "$ssh_config" >> ~/.ssh/config &&
if ! test -e ~/.ssh/"$key"; then
if test -f ~/.ssh/id_rsa; then
# Take care of the common case.
ln -s id_rsa ~/.ssh/"$key"
echo '
Assuming ~/.ssh/id_rsa is the private key corresponding to the public key for
'"$user@$host"'
If this is incorrect place private key at "~/.ssh/'"$key"'".'
else
echo '
Place the private key corresponding to the public key registered for
'"$user@$host"'
at "~/.ssh/'"$key"'".'
fi
read -e -n 1 -p 'Press any key to continue...'
fi
fi || exit 1
# Test access configuration.
echo 'Testing ssh push access to "'"$user@$host"'"...' &&
if ! ssh "$user@$host" info; then
die 'No ssh push access to "'"$user@$host"'". You may need to request access at
'"$request_url"'
'
fi

104
Utilities/GitSetup/setup-upstream Executable file

@ -0,0 +1,104 @@
#!/usr/bin/env bash
#=============================================================================
# Copyright 2010-2015 Kitware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#=============================================================================
# Run this script to set up the local Git repository to use the
# preferred upstream repository URLs.
# Project configuration instructions:
#
# - Populate adjacent "config" file with:
# upstream.url = Preferred fetch url for upstream remote
# upstream.remote = Preferred name for upstream remote, if not "origin"
die() {
echo 1>&2 "$@" ; exit 1
}
# Make sure we are inside the repository.
cd "${BASH_SOURCE%/*}" &&
# Load the project configuration.
url=$(git config -f config --get upstream.url) &&
remote=$(git config -f config --get upstream.remote ||
echo 'origin') ||
die 'This project is not configured to use a preferred upstream repository.'
# Get current upstream URLs.
fetchurl=$(git config --get remote."$remote".url || echo '') &&
pushurl=$(git config --get remote."$remote".pushurl || echo '') &&
if test "$fetchurl" = "$url"; then
echo 'Remote "'"$remote"'" already uses recommended upstream repository.'
exit 0
fi
upstream_recommend='
We recommended configuring the "'"$remote"'" remote to fetch from upstream at
'"$url"'
'
# Tell user about current configuration.
if test -n "$fetchurl"; then
echo 'Remote "'"$remote"'" is currently configured to fetch from
'"$fetchurl"'
' &&
if test -n "$pushurl"; then
echo 'and push to
'"$pushurl"
fi &&
echo "$upstream_recommend" &&
if test -n "$pushurl"; then
echo 'and to never push to it directly.
'
fi &&
read -ep 'Reconfigure "'"$remote"'" remote as recommended? [y/N]: ' ans &&
if [ "$ans" == "y" ] || [ "$ans" == "Y" ]; then
setup=1
else
setup=''
fi
else
echo 'Remote "'"$remote"'" is not yet configured.' &&
echo "$upstream_recommend" &&
read -ep 'Configure "'"$remote"'" remote as recommended? [Y/n]: ' ans &&
if [ "$ans" == "n" ] || [ "$ans" == "N" ]; then
exit 0
else
setup=1
fi
fi &&
# Perform setup if necessary.
if test -n "$setup"; then
if test -z "$fetchurl"; then
git remote add "$remote" "$url"
else
git config remote."$remote".url "$url" &&
if old=$(git config --get remote."$remote".pushurl); then
git config --unset remote."$remote".pushurl ||
echo 'Warning: failed to unset remote.'"$remote"'.pushurl'
fi
fi &&
echo 'Remote "'"$remote"'" is now configured to fetch from
'"$url"'
'
fi

39
Utilities/GitSetup/setup-user Executable file

@ -0,0 +1,39 @@
#!/usr/bin/env bash
#=============================================================================
# Copyright 2010-2012 Kitware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#=============================================================================
# Run this script to configure Git user info in this repository.
# Project configuration instructions: NONE
for (( ; ; )); do
user_name=$(git config user.name || echo '') &&
user_email=$(git config user.email || echo '') &&
if test -n "$user_name" -a -n "$user_email"; then
echo 'Your commits will record as Author:
'"$user_name <$user_email>"'
' &&
read -ep 'Is the author name and email address above correct? [Y/n] ' correct &&
if test "$correct" != "n" -a "$correct" != "N"; then
break
fi
fi &&
read -ep 'Enter your full name e.g. "John Doe": ' name &&
read -ep 'Enter your email address e.g. "john@gmail.com": ' email &&
git config user.name "$name" &&
git config user.email "$email"
done

55
Utilities/GitSetup/tips Executable file

@ -0,0 +1,55 @@
#!/usr/bin/env bash
#=============================================================================
# Copyright 2010-2012 Kitware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#=============================================================================
# This script makes optional suggestions for working with Git.
# Project configuration instructions: NONE
egrep-q() {
egrep "$@" >/dev/null 2>/dev/null
}
# Suggest color configuration.
if test -z "$(git config --get color.ui)"; then
echo '
One may enable color output from Git commands with
git config --global color.ui auto
'
fi
# Suggest bash completion.
if ! bash -i -c 'echo $PS1' | egrep-q '__git_ps1'; then
echo '
A dynamic, informative Git shell prompt can be obtained by sourcing
the git bash-completion script in your "~/.bashrc". Set the PS1
environmental variable as suggested in the comments at the top of the
bash-completion script. You may need to install the bash-completion
package from your distribution to obtain it.
'
fi
# Suggest merge tool.
if test -z "$(git config --get merge.tool)"; then
echo '
One may configure Git to load a merge tool with
git config merge.tool <toolname>
See "git help mergetool" for more information.
'
fi

@ -0,0 +1,28 @@
#!/usr/bin/env bash
cd "${BASH_SOURCE%/*}/.." &&
Utilities/GitSetup/setup-user && echo &&
Utilities/GitSetup/setup-hooks && echo &&
(Utilities/GitSetup/setup-upstream ||
echo 'Failed to setup origin. Run this again to retry.') && echo &&
(Utilities/GitSetup/setup-gitlab ||
echo 'Failed to setup GitLab. Run this again to retry.') && echo &&
Utilities/GitSetup/tips
echo "Setting up useful Git aliases..." &&
# Rebase master by default
git config rebase.stat true
git config branch.master.rebase true
# General aliases that could be global
git config alias.pullall '!bash -c "git pull && git submodule update --init"' &&
git config alias.prepush 'log --graph --stat origin/master..' &&
# Alias to push the current topic branch to GitLab
git config alias.gitlab-push '!bash Utilities/GitSetup/git-gitlab-push' &&
echo "Set up git gitlab-push" &&
git config alias.gitlab-sync '!bash Utilities/GitSetup/git-gitlab-sync' &&
echo "Set up git gitlab-sync" &&
true

31
Utilities/update-gitsetup.bash Executable file

@ -0,0 +1,31 @@
#!/usr/bin/env bash
set -e
set -x
shopt -s dotglob
readonly name="GitSetup"
readonly ownership="GitSetup Upstream <kwrobot@kitware.com>"
readonly subtree="Utilities/GitSetup"
readonly repo="https://gitlab.kitware.com/utils/gitsetup.git"
readonly tag="setup"
readonly shortlog=false
readonly paths="
.gitattributes
LICENSE
NOTICE
README
git-gitlab-push
setup-gitlab
setup-hooks
setup-ssh
setup-upstream
setup-user
tips
"
extract_source () {
git_archive
}
. "${BASH_SOURCE%/*}/update-third-party.bash"

@ -0,0 +1,169 @@
#=============================================================================
# Copyright 2015-2016 Kitware, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#=============================================================================
########################################################################
# Script for updating third party packages.
#
# This script should be sourced in a project-specific script which sets
# the following variables:
#
# name
# The name of the project.
# ownership
# A git author name/email for the commits.
# subtree
# The location of the thirdparty package within the main source
# tree.
# repo
# The git repository to use as upstream.
# tag
# The tag, branch or commit hash to use for upstream.
# shortlog
# Optional. Set to 'true' to get a shortlog in the commit message.
#
# Additionally, an "extract_source" function must be defined. It will be
# run within the checkout of the project on the requested tag. It should
# should place the desired tree into $extractdir/$name-reduced. This
# directory will be used as the newest commit for the project.
#
# For convenience, the function may use the "git_archive" function which
# does a standard "git archive" extraction using the (optional) "paths"
# variable to only extract a subset of the source tree.
########################################################################
########################################################################
# Utility functions
########################################################################
git_archive () {
git archive --worktree-attributes --prefix="$name-reduced/" HEAD -- $paths | \
tar -C "$extractdir" -x
}
die () {
echo >&2 "$@"
exit 1
}
warn () {
echo >&2 "warning: $@"
}
readonly regex_date='20[0-9][0-9]-[0-9][0-9]-[0-9][0-9]'
readonly basehash_regex="$name $regex_date ([0-9a-f]*)"
readonly basehash="$( git rev-list --author="$ownership" --grep="$basehash_regex" -n 1 HEAD )"
readonly upstream_old_short="$( git cat-file commit "$basehash" | sed -n '/'"$basehash_regex"'/ {s/.*(//;s/)//;p}' | egrep '^[0-9a-f]+$' )"
########################################################################
# Sanity checking
########################################################################
[ -n "$name" ] || \
die "'name' is empty"
[ -n "$ownership" ] || \
die "'ownership' is empty"
[ -n "$subtree" ] || \
die "'subtree' is empty"
[ -n "$repo" ] || \
die "'repo' is empty"
[ -n "$tag" ] || \
die "'tag' is empty"
[ -n "$basehash" ] || \
warn "'basehash' is empty; performing initial import"
readonly do_shortlog="${shortlog-false}"
readonly workdir="$PWD/work"
readonly upstreamdir="$workdir/upstream"
readonly extractdir="$workdir/extract"
[ -d "$workdir" ] && \
die "error: workdir '$workdir' already exists"
trap "rm -rf '$workdir'" EXIT
# Get upstream
git clone "$repo" "$upstreamdir"
if [ -n "$basehash" ]; then
# Use the existing package's history
git worktree add "$extractdir" "$basehash"
# Clear out the working tree
pushd "$extractdir"
git ls-files | xargs rm -v
find . -type d -empty -delete
popd
else
# Create a repo to hold this package's history
mkdir -p "$extractdir"
git -C "$extractdir" init
fi
# Extract the subset of upstream we care about
pushd "$upstreamdir"
git checkout "$tag"
readonly upstream_hash="$( git rev-parse HEAD )"
readonly upstream_hash_short="$( git rev-parse --short=8 "$upstream_hash" )"
readonly upstream_datetime="$( git rev-list "$upstream_hash" --format='%ci' -n 1 | grep -e "^$regex_date" )"
readonly upstream_date="$( echo "$upstream_datetime" | grep -o -e "$regex_date" )"
if $do_shortlog && [ -n "$basehash" ]; then
readonly commit_shortlog="
Upstream Shortlog
-----------------
$( git shortlog --no-merges --abbrev=8 --format='%h %s' "$upstream_old_short".."$upstream_hash" )"
else
readonly commit_shortlog=""
fi
extract_source || \
die "failed to extract source"
popd
[ -d "$extractdir/$name-reduced" ] || \
die "expected directory to extract does not exist"
readonly commit_summary="$name $upstream_date ($upstream_hash_short)"
# Commit the subset
pushd "$extractdir"
mv -v "$name-reduced/"* .
rmdir "$name-reduced/"
git add -A .
git commit -n --author="$ownership" --date="$upstream_datetime" -F - <<-EOF
$commit_summary
Code extracted from:
$repo
at commit $upstream_hash ($tag).$commit_shortlog
EOF
git branch -f "upstream-$name"
popd
# Merge the subset into this repository
if [ -n "$basehash" ]; then
git merge --log -s recursive "-Xsubtree=$subtree/" --no-commit "upstream-$name"
else
unrelated_histories_flag=""
if git merge --help | grep -q -e allow-unrelated-histories; then
unrelated_histories_flag="--allow-unrelated-histories "
fi
readonly unrelated_histories_flag
git fetch "$extractdir" "upstream-$name:upstream-$name"
git merge --log -s ours --no-commit $unrelated_histories_flag "upstream-$name"
git read-tree -u --prefix="$subtree/" "upstream-$name"
fi
git commit --no-edit
git branch -d "upstream-$name"

@ -39,6 +39,7 @@ add_subdirectory(tau_timing)
#endif()
=======
add_subdirectory(tetrahedra)
add_subdirectory(particle_advection)
if(VTKm_ENABLE_RENDERING)
add_subdirectory(rendering)
endif()

@ -29,34 +29,64 @@
#include <algorithm>
#include <fstream>
#include <iostream>
#include <string>
#include <stdexcept>
#include <string>
typedef vtkm::Vec<vtkm::Float32, 3> FloatVec3;
namespace
{
int main(int argc, char *argv[])
template <typename DeviceTag>
struct FieldMapper
{
vtkm::cont::DynamicArrayHandle& Output;
vtkm::worklet::Clip& Worklet;
bool IsCellField;
FieldMapper(vtkm::cont::DynamicArrayHandle& output,
vtkm::worklet::Clip& worklet,
bool isCellField)
: Output(output)
, Worklet(worklet)
, IsCellField(isCellField)
{
}
template <typename ArrayType>
void operator()(const ArrayType& input) const
{
if (this->IsCellField)
{
this->Output = this->Worklet.ProcessCellField(input, DeviceTag());
}
else
{
this->Output = this->Worklet.ProcessPointField(input, DeviceTag());
}
}
};
} // end anon namespace
int main(int argc, char* argv[])
{
if (argc < 4)
{
std::cout << "Usage: " << std::endl
<< "$ " << argv[0]
<< " <input_vtk_file> [fieldName] <isoval> <output_vtk_file>"
<< "$ " << argv[0] << " <input_vtk_file> [fieldName] <isoval> <output_vtk_file>"
<< std::endl;
return 1;
}
typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter;
std::cout << "Device Adapter Name: "
<< vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetName()
std::cout << "Device Adapter Name: " << vtkm::cont::DeviceAdapterTraits<DeviceAdapter>::GetName()
<< std::endl;
vtkm::io::reader::VTKDataSetReader reader(argv[1]);
vtkm::cont::DataSet input = reader.ReadDataSet();
vtkm::cont::Field scalarField = (argc == 5) ?
input.GetField(argv[2]) :
input.GetField(0);
vtkm::cont::Field scalarField = (argc == 5) ? input.GetField(argv[2]) : input.GetField(0);
vtkm::Float32 clipValue = std::stof(argv[argc - 2]);
vtkm::worklet::Clip clip;
@ -73,9 +103,13 @@ int main(int argc, char *argv[])
vtkm::cont::DataSet output;
output.AddCellSet(outputCellSet);
timer.Reset();
vtkm::cont::DynamicArrayHandle coords =
clip.ProcessField(input.GetCoordinateSystem(0), DeviceAdapter());
vtkm::cont::DynamicArrayHandle coords;
{
FieldMapper<DeviceAdapter> coordMapper(coords, clip, false);
input.GetCoordinateSystem(0).GetData().CastAndCall(coordMapper);
}
vtkm::Float64 processCoordinatesTime = timer.GetElapsedTime();
output.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coords));
@ -83,16 +117,27 @@ int main(int argc, char *argv[])
for (vtkm::Id i = 0; i < input.GetNumberOfFields(); ++i)
{
vtkm::cont::Field inField = input.GetField(i);
if (inField.GetAssociation() != vtkm::cont::Field::ASSOC_POINTS)
bool isCellField;
switch (inField.GetAssociation())
{
continue; // clip only supports point fields for now.
case vtkm::cont::Field::ASSOC_POINTS:
isCellField = false;
break;
case vtkm::cont::Field::ASSOC_CELL_SET:
isCellField = true;
break;
default:
continue;
}
vtkm::cont::DynamicArrayHandle data =
clip.ProcessField(inField.GetData().ResetTypeList(vtkm::TypeListTagAll()),
DeviceAdapter());
output.AddField(vtkm::cont::Field(inField.GetName(),
vtkm::cont::Field::ASSOC_POINTS, data));
vtkm::cont::DynamicArrayHandle outField;
FieldMapper<DeviceAdapter> fieldMapper(outField, clip, isCellField);
inField.GetData().CastAndCall(fieldMapper);
output.AddField(vtkm::cont::Field(inField.GetName(), inField.GetAssociation(), outField));
}
vtkm::Float64 processScalarsTime = timer.GetElapsedTime();
vtkm::Float64 totalTime = total.GetElapsedTime();

@ -20,48 +20,48 @@
// Copyright (c) 2016, Los Alamos National Security, LLC
// All rights reserved.
//
// Copyright 2016. Los Alamos National Security, LLC.
// This software was produced under U.S. Government contract DE-AC52-06NA25396
// for Los Alamos National Laboratory (LANL), which is operated by
// Los Alamos National Security, LLC for the U.S. Department of Energy.
// The U.S. Government has rights to use, reproduce, and distribute this
// software. NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY, LLC
// MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE
// USE OF THIS SOFTWARE. If software is modified to produce derivative works,
// such modified software should be clearly marked, so as not to confuse it
// Copyright 2016. Los Alamos National Security, LLC.
// This software was produced under U.S. Government contract DE-AC52-06NA25396
// for Los Alamos National Laboratory (LANL), which is operated by
// Los Alamos National Security, LLC for the U.S. Department of Energy.
// The U.S. Government has rights to use, reproduce, and distribute this
// software. NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY, LLC
// MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE
// USE OF THIS SOFTWARE. If software is modified to produce derivative works,
// such modified software should be clearly marked, so as not to confuse it
// with the version available from LANL.
//
// Additionally, redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following conditions
// Additionally, 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,
// 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.
// 3. Neither the name of Los Alamos National Security, LLC, Los Alamos
// National Laboratory, LANL, the U.S. Government, nor the names of its
// contributors may be used to endorse or promote products derived from
// 3. Neither the name of Los Alamos National Security, LLC, Los Alamos
// National Laboratory, LANL, the U.S. Government, nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY LOS ALAMOS NATIONAL SECURITY, LLC 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 LOS ALAMOS
// NATIONAL SECURITY, LLC 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 IS PROVIDED BY LOS ALAMOS NATIONAL SECURITY, LLC 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 LOS ALAMOS
// NATIONAL SECURITY, LLC 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.
//============================================================================
// This code is based on the algorithm presented in the paper:
// “Parallel Peak Pruning for Scalable SMP Contour Tree Computation.”
// Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens.
// Proceedings of the IEEE Symposium on Large Data Analysis and Visualization
// This code is based on the algorithm presented in the paper:
// “Parallel Peak Pruning for Scalable SMP Contour Tree Computation.”
// Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens.
// Proceedings of the IEEE Symposium on Large Data Analysis and Visualization
// (LDAV), October 2016, Baltimore, Maryland.
#ifndef VTKM_DEVICE_ADAPTER
@ -81,7 +81,8 @@ int main(int argc, char* argv[])
{
std::cout << "ContourTreeMesh2D Example" << std::endl;
if (argc != 2) {
if (argc != 2)
{
std::cout << "Parameter is fileName" << std::endl;
std::cout << "File is expected to be ASCII with xdim ydim integers " << std::endl;
std::cout << "followed by vector data last dimension varying fastest" << std::endl;
@ -90,7 +91,8 @@ int main(int argc, char* argv[])
// open input file
std::ifstream inFile(argv[1]);
if (inFile.bad()) return 0;
if (inFile.bad())
return 0;
// read size of mesh
vtkm::Id2 vdims;
@ -120,8 +122,8 @@ int main(int argc, char* argv[])
vtkm::filter::ContourTreeMesh2D filter;
result = filter.Execute(inDataSet, std::string("values"));
vtkm::cont::Field resultField = result.GetField();
vtkm::cont::ArrayHandle<vtkm::Pair<vtkm::Id, vtkm::Id> > saddlePeak;
vtkm::cont::Field resultField = result.GetField();
vtkm::cont::ArrayHandle<vtkm::Pair<vtkm::Id, vtkm::Id>> saddlePeak;
resultField.GetData().CopyTo(saddlePeak);
return 0;

@ -20,48 +20,48 @@
// Copyright (c) 2016, Los Alamos National Security, LLC
// All rights reserved.
//
// Copyright 2016. Los Alamos National Security, LLC.
// This software was produced under U.S. Government contract DE-AC52-06NA25396
// for Los Alamos National Laboratory (LANL), which is operated by
// Los Alamos National Security, LLC for the U.S. Department of Energy.
// The U.S. Government has rights to use, reproduce, and distribute this
// software. NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY, LLC
// MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE
// USE OF THIS SOFTWARE. If software is modified to produce derivative works,
// such modified software should be clearly marked, so as not to confuse it
// Copyright 2016. Los Alamos National Security, LLC.
// This software was produced under U.S. Government contract DE-AC52-06NA25396
// for Los Alamos National Laboratory (LANL), which is operated by
// Los Alamos National Security, LLC for the U.S. Department of Energy.
// The U.S. Government has rights to use, reproduce, and distribute this
// software. NEITHER THE GOVERNMENT NOR LOS ALAMOS NATIONAL SECURITY, LLC
// MAKES ANY WARRANTY, EXPRESS OR IMPLIED, OR ASSUMES ANY LIABILITY FOR THE
// USE OF THIS SOFTWARE. If software is modified to produce derivative works,
// such modified software should be clearly marked, so as not to confuse it
// with the version available from LANL.
//
// Additionally, redistribution and use in source and binary forms, with or
// without modification, are permitted provided that the following conditions
// Additionally, 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,
// 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.
// 3. Neither the name of Los Alamos National Security, LLC, Los Alamos
// National Laboratory, LANL, the U.S. Government, nor the names of its
// contributors may be used to endorse or promote products derived from
// 3. Neither the name of Los Alamos National Security, LLC, Los Alamos
// National Laboratory, LANL, the U.S. Government, nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY LOS ALAMOS NATIONAL SECURITY, LLC 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 LOS ALAMOS
// NATIONAL SECURITY, LLC 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 IS PROVIDED BY LOS ALAMOS NATIONAL SECURITY, LLC 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 LOS ALAMOS
// NATIONAL SECURITY, LLC 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.
//============================================================================
// This code is based on the algorithm presented in the paper:
// “Parallel Peak Pruning for Scalable SMP Contour Tree Computation.”
// Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens.
// Proceedings of the IEEE Symposium on Large Data Analysis and Visualization
// This code is based on the algorithm presented in the paper:
// “Parallel Peak Pruning for Scalable SMP Contour Tree Computation.”
// Hamish Carr, Gunther Weber, Christopher Sewell, and James Ahrens.
// Proceedings of the IEEE Symposium on Large Data Analysis and Visualization
// (LDAV), October 2016, Baltimore, Maryland.
#ifndef VTKM_DEVICE_ADAPTER
@ -81,7 +81,8 @@ int main(int argc, char* argv[])
{
std::cout << "ContourTreeMesh3D Example" << std::endl;
if (argc != 2) {
if (argc != 2)
{
std::cout << "Parameter is fileName" << std::endl;
std::cout << "File is expected to be ASCII with xdim ydim zdim integers " << std::endl;
std::cout << "followed by vector data last dimension varying fastest" << std::endl;
@ -90,15 +91,15 @@ int main(int argc, char* argv[])
// open input file
std::ifstream inFile(argv[1]);
if (inFile.bad()) return 0;
if (inFile.bad())
return 0;
// read size of mesh
vtkm::Id3 vdims;
inFile >> vdims[0];
inFile >> vdims[1];
inFile >> vdims[2];
std::size_t nVertices =
static_cast<std::size_t>(vdims[0] * vdims[1] * vdims[2]);
std::size_t nVertices = static_cast<std::size_t>(vdims[0] * vdims[1] * vdims[2]);
// read data
std::vector<vtkm::Float32> values(nVertices);
@ -122,8 +123,8 @@ int main(int argc, char* argv[])
vtkm::filter::ContourTreeMesh3D filter;
result = filter.Execute(inDataSet, std::string("values"));
vtkm::cont::Field resultField = result.GetField();
vtkm::cont::ArrayHandle<vtkm::Pair<vtkm::Id, vtkm::Id> > saddlePeak;
vtkm::cont::Field resultField = result.GetField();
vtkm::cont::ArrayHandle<vtkm::Pair<vtkm::Id, vtkm::Id>> saddlePeak;
resultField.GetData().CopyTo(saddlePeak);
return 0;

@ -18,33 +18,31 @@
// this software.
//============================================================================
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/testing/MakeTestDataSet.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/rendering/Actor.h>
#include <vtkm/rendering/CanvasRayTracer.h>
#include <vtkm/rendering/MapperRayTracer.h>
#include <vtkm/rendering/Scene.h>
#include <vtkm/rendering/View3D.h>
#include <vtkm/cont/DeviceAdapter.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/io/reader/VTKDataSetReader.h>
#include <vtkm/filter/MarchingCubes.h>
#include <vtkm/cont/DataSetFieldAdd.h>
#include <vtkm/filter/MarchingCubes.h>
#include <iostream>
void makeScene(const vtkm::cont::DataSet &inputData,
const vtkm::rendering::ColorTable &colorTable,
const std::string &fieldName,
vtkm::rendering::Scene &scene)
void makeScene(const vtkm::cont::DataSet& inputData,
const vtkm::rendering::ColorTable& colorTable,
const std::string& fieldName,
vtkm::rendering::Scene& scene)
{
scene.AddActor(vtkm::rendering::Actor(inputData.GetCellSet(),
inputData.GetCoordinateSystem(),
inputData.GetField(fieldName),
colorTable));
scene.AddActor(vtkm::rendering::Actor(inputData.GetCellSet(),
inputData.GetCoordinateSystem(),
inputData.GetField(fieldName),
colorTable));
}
// This example reads an input vtk file specified on the command-line (or generates a default
@ -78,7 +76,7 @@ int main(int argc, char* argv[])
fieldName = "SCALARS:pointvar";
}
typedef vtkm::rendering::MapperRayTracer Mapper;
typedef vtkm::rendering::MapperRayTracer Mapper;
typedef vtkm::rendering::CanvasRayTracer Canvas;
// Set up a camera for rendering the input data
@ -91,7 +89,7 @@ int main(int argc, char* argv[])
camera.ResetToBounds(coordsBounds);
vtkm::Vec<vtkm::Float32,3> totalExtent;
vtkm::Vec<vtkm::Float32, 3> totalExtent;
totalExtent[0] = vtkm::Float32(coordsBounds.X.Max - coordsBounds.X.Min);
totalExtent[1] = vtkm::Float32(coordsBounds.Y.Max - coordsBounds.Y.Min);
totalExtent[2] = vtkm::Float32(coordsBounds.Z.Max - coordsBounds.Z.Min);
@ -107,15 +105,11 @@ int main(int argc, char* argv[])
// Create a scene for rendering the input data
vtkm::rendering::Scene scene;
vtkm::rendering::Color bg(0.2f, 0.2f, 0.2f, 1.0f);
Canvas canvas(512,512);
Canvas canvas(512, 512);
makeScene(inputData, colorTable, fieldName, scene);
// Create a view and use it to render the input data using OS Mesa
vtkm::rendering::View3D view(scene,
mapper,
canvas,
camera,
bg);
vtkm::rendering::View3D view(scene, mapper, canvas, camera, bg);
view.Initialize();
view.Paint();
view.SaveAs("demo_input.pnm");
@ -125,8 +119,7 @@ int main(int argc, char* argv[])
filter.SetGenerateNormals(false);
filter.SetMergeDuplicatePoints(false);
filter.SetIsoValue(0, isovalue);
vtkm::filter::ResultDataSet result = filter.Execute( inputData,
inputData.GetField(fieldName) );
vtkm::filter::ResultDataSet result = filter.Execute(inputData, inputData.GetField(fieldName));
filter.MapFieldOntoOutput(result, inputData.GetField(fieldName));
vtkm::cont::DataSet& outputData = result.GetDataSet();
// Render a separate image with the output isosurface
@ -134,12 +127,7 @@ int main(int argc, char* argv[])
vtkm::rendering::Scene scene2;
makeScene(outputData, colorTable, fieldName, scene2);
vtkm::rendering::View3D view2(scene2,
mapper,
canvas,
camera,
bg);
vtkm::rendering::View3D view2(scene2, mapper, canvas, camera, bg);
view2.Initialize();
view2.Paint();
view2.SaveAs("demo_output.pnm");

@ -31,18 +31,21 @@
struct ExampleFieldWorklet : public vtkm::worklet::WorkletMapField
{
typedef void ControlSignature( FieldIn<>, FieldIn<>, FieldIn<>,
FieldOut<>, FieldOut<>, FieldOut<> );
typedef void ExecutionSignature( _1, _2, _3, _4, _5, _6 );
typedef void ControlSignature(FieldIn<>,
FieldIn<>,
FieldIn<>,
FieldOut<>,
FieldOut<>,
FieldOut<>);
typedef void ExecutionSignature(_1, _2, _3, _4, _5, _6);
template<typename T, typename U, typename V>
VTKM_EXEC
void operator()( const vtkm::Vec< T, 3 > & vec,
const U & scalar1,
const V& scalar2,
vtkm::Vec<T, 3>& out_vec,
U& out_scalar1,
V& out_scalar2 ) const
template <typename T, typename U, typename V>
VTKM_EXEC void operator()(const vtkm::Vec<T, 3>& vec,
const U& scalar1,
const V& scalar2,
vtkm::Vec<T, 3>& out_vec,
U& out_scalar1,
V& out_scalar2) const
{
out_vec = vec * scalar1;
out_scalar1 = static_cast<U>(scalar1 + scalar2);
@ -50,46 +53,35 @@ struct ExampleFieldWorklet : public vtkm::worklet::WorkletMapField
std::cout << "hello world" << std::endl;
}
template<typename T, typename U, typename V, typename W, typename X, typename Y>
VTKM_EXEC
void operator()( const T &,
const U &,
const V&,
W&,
X&,
Y& ) const
template <typename T, typename U, typename V, typename W, typename X, typename Y>
VTKM_EXEC void operator()(const T&, const U&, const V&, W&, X&, Y&) const
{
//no-op
//no-op
}
};
int main(int argc, char** argv)
{
(void)argc;
(void)argv;
std::vector< vtkm::Vec<vtkm::Float32, 3> > inputVec(10);
std::vector< vtkm::Int32 > inputScalar1(10);
std::vector< vtkm::Float64 > inputScalar2(10);
std::vector<vtkm::Vec<vtkm::Float32, 3>> inputVec(10);
std::vector<vtkm::Int32> inputScalar1(10);
std::vector<vtkm::Float64> inputScalar2(10);
vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32, 3> > handleV =
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>> handleV =
vtkm::cont::make_ArrayHandle(inputVec);
vtkm::cont::ArrayHandle< vtkm::Int32 > handleS1 =
vtkm::cont::make_ArrayHandle(inputScalar1);
vtkm::cont::ArrayHandle<vtkm::Int32> handleS1 = vtkm::cont::make_ArrayHandle(inputScalar1);
vtkm::cont::ArrayHandle< vtkm::Float64 > handleS2 =
vtkm::cont::make_ArrayHandle(inputScalar2);
vtkm::cont::ArrayHandle<vtkm::Float64> handleS2 = vtkm::cont::make_ArrayHandle(inputScalar2);
vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32, 3> > handleOV;
vtkm::cont::ArrayHandle< vtkm::Int32 > handleOS1;
vtkm::cont::ArrayHandle< vtkm::Float64 > handleOS2;
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>> handleOV;
vtkm::cont::ArrayHandle<vtkm::Int32> handleOS1;
vtkm::cont::ArrayHandle<vtkm::Float64> handleOS2;
vtkm::cont::DynamicArrayHandle out1(handleOV), out2(handleOS1), out3(handleOS2);
vtkm::worklet::DispatcherMapField<ExampleFieldWorklet> dispatcher;
dispatcher.Invoke(handleV, handleS1, handleS2, out1, out2, out3);
}

@ -35,25 +35,25 @@
//Suppress warnings about glut being deprecated on OSX
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
//OpenGL Graphics includes
//glew needs to go before glut
//that is why this is after the TransferToOpenGL include
#if defined (__APPLE__)
# include <GLUT/glut.h>
#if defined(__APPLE__)
#include <GLUT/glut.h>
#else
# include <GL/glut.h>
#include <GL/glut.h>
#endif
#include "LoadShaders.h"
template< typename DeviceAdapter, typename T >
template <typename DeviceAdapter, typename T>
struct HelloVTKMInterop
{
vtkm::Vec< vtkm::Int32, 2 > Dims;
vtkm::Vec<vtkm::Int32, 2> Dims;
GLuint ProgramId;
GLuint VAOId;
@ -63,71 +63,69 @@ struct HelloVTKMInterop
vtkm::cont::Timer<DeviceAdapter> Timer;
std::vector< vtkm::Vec< T, 3 > > InputData;
vtkm::cont::ArrayHandle< vtkm::Vec< T, 3 > > InHandle;
vtkm::cont::ArrayHandle< vtkm::Vec< T, 3 > > OutCoords;
vtkm::cont::ArrayHandle< vtkm::Vec< vtkm::UInt8, 4 > > OutColors;
std::vector<vtkm::Vec<T, 3>> InputData;
vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>> InHandle;
vtkm::cont::ArrayHandle<vtkm::Vec<T, 3>> OutCoords;
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::UInt8, 4>> OutColors;
HelloVTKMInterop(vtkm::Int32 width, vtkm::Int32 height):
Dims(256,256),
ProgramId(),
VAOId(),
VBOState(),
ColorState(),
Timer(),
InputData(),
InHandle(),
OutCoords(),
OutColors()
HelloVTKMInterop(vtkm::Int32 width, vtkm::Int32 height)
: Dims(256, 256)
, ProgramId()
, VAOId()
, VBOState()
, ColorState()
, Timer()
, InputData()
, InHandle()
, OutCoords()
, OutColors()
{
int dim = 256;
this->InputData.reserve( static_cast<std::size_t>(dim*dim) );
for (int i = 0; i < dim; ++i )
this->InputData.reserve(static_cast<std::size_t>(dim * dim));
for (int i = 0; i < dim; ++i)
{
for (int j = 0; j < dim; ++j )
for (int j = 0; j < dim; ++j)
{
this->InputData.push_back(vtkm::Vec<T,3>(2.f*static_cast<T>(i/dim)-1.f,
0.f,
2.f*static_cast<T>(j/dim)-1.f));
this->InputData.push_back(vtkm::Vec<T, 3>(
2.f * static_cast<T>(i / dim) - 1.f, 0.f, 2.f * static_cast<T>(j / dim) - 1.f));
}
}
this->Dims = vtkm::Vec< vtkm::Int32, 2 >( dim, dim );
this->Dims = vtkm::Vec<vtkm::Int32, 2>(dim, dim);
this->InHandle = vtkm::cont::make_ArrayHandle(this->InputData);
glGenVertexArrays( 1, &this->VAOId );
glBindVertexArray( this->VAOId );
glGenVertexArrays(1, &this->VAOId);
glBindVertexArray(this->VAOId);
this->ProgramId = LoadShaders();
glUseProgram( this->ProgramId );
glUseProgram(this->ProgramId);
glClearColor( .08f, .08f, .08f, 0.f );
glViewport(0, 0, width, height );
glClearColor(.08f, .08f, .08f, 0.f);
glViewport(0, 0, width, height);
}
void render()
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
vtkm::Int32 arraySize = this->Dims[0]*this->Dims[1];
vtkm::Int32 arraySize = this->Dims[0] * this->Dims[1];
//precomputed based on 1027x768 render window size
vtkm::Float32 mvp[16] = {-1.79259f, 0.f, 0.f, 0.f,
0.f, 1.26755f, -0.721392f, -0.707107f,
0.f, 1.26755f, 0.721392f, 0.707107f,
0.f, 0.f, 1.24076f, 1.41421f};
vtkm::Float32 mvp[16] = { -1.79259f, 0.f, 0.f, 0.f, 0.f, 1.26755f,
-0.721392f, -0.707107f, 0.f, 1.26755f, 0.721392f, 0.707107f,
0.f, 0.f, 1.24076f, 1.41421f };
GLint unifLoc = glGetUniformLocation( this->ProgramId, "MVP");
glUniformMatrix4fv( unifLoc, 1, GL_FALSE, mvp );
GLint unifLoc = glGetUniformLocation(this->ProgramId, "MVP");
glUniformMatrix4fv(unifLoc, 1, GL_FALSE, mvp);
glEnableVertexAttribArray(0);
glBindBuffer(GL_ARRAY_BUFFER, *this->VBOState.GetHandle());
glVertexAttribPointer( 0, 3, GL_FLOAT, GL_FALSE, 0, 0 );
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, 0);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, *this->ColorState.GetHandle());
glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0 );
glColorPointer(4, GL_UNSIGNED_BYTE, 0, 0);
glDrawArrays( GL_POINTS, 0, arraySize );
glDrawArrays(GL_POINTS, 0, arraySize);
glDisableClientState(GL_COLOR_ARRAY);
glDisableVertexAttribArray(0);
@ -136,51 +134,54 @@ struct HelloVTKMInterop
struct GenerateSurfaceWorklet : public vtkm::worklet::WorkletMapField
{
vtkm::Float32 t;
GenerateSurfaceWorklet(vtkm::Float32 st) : t(st) {}
GenerateSurfaceWorklet(vtkm::Float32 st)
: t(st)
{
}
typedef void ControlSignature( FieldIn<>, FieldOut<>, FieldOut<> );
typedef void ExecutionSignature( _1, _2, _3 );
typedef void ControlSignature(FieldIn<>, FieldOut<>, FieldOut<>);
typedef void ExecutionSignature(_1, _2, _3);
VTKM_EXEC
void operator()( const vtkm::Vec< T, 3 > & input,
vtkm::Vec<T, 3> & output,
vtkm::Vec<vtkm::UInt8, 4>& color ) const
void operator()(const vtkm::Vec<T, 3>& input,
vtkm::Vec<T, 3>& output,
vtkm::Vec<vtkm::UInt8, 4>& color) const
{
output[0] = input[0];
output[1] = 0.25f * vtkm::Sin( input[0] * 10.f + t ) * vtkm::Cos( input[2] * 10.f + t );
output[1] = 0.25f * vtkm::Sin(input[0] * 10.f + t) * vtkm::Cos(input[2] * 10.f + t);
output[2] = input[2];
color[0] = 0;
color[1] = static_cast<vtkm::UInt8>(160 + 96*vtkm::Sin(input[0]*10.f+t));
color[2] = static_cast<vtkm::UInt8>(160 + 96*vtkm::Cos(input[2]*5.f+t));
color[1] = static_cast<vtkm::UInt8>(160 + 96 * vtkm::Sin(input[0] * 10.f + t));
color[2] = static_cast<vtkm::UInt8>(160 + 96 * vtkm::Cos(input[2] * 5.f + t));
color[3] = 255;
}
};
void renderFrame( )
void renderFrame()
{
typedef vtkm::worklet::DispatcherMapField<GenerateSurfaceWorklet> DispatcherType;
typedef vtkm::worklet::DispatcherMapField<GenerateSurfaceWorklet> DispatcherType;
vtkm::Float32 t = static_cast<vtkm::Float32>(this->Timer.GetElapsedTime());
vtkm::Float32 t = static_cast<vtkm::Float32>(this->Timer.GetElapsedTime());
GenerateSurfaceWorklet worklet( t );
DispatcherType(worklet).Invoke( this->InHandle, this->OutCoords, this->OutColors );
GenerateSurfaceWorklet worklet(t);
DispatcherType(worklet).Invoke(this->InHandle, this->OutCoords, this->OutColors);
vtkm::interop::TransferToOpenGL( this->OutCoords, this->VBOState, DeviceAdapter() );
vtkm::interop::TransferToOpenGL( this->OutColors, this->ColorState, DeviceAdapter() );
vtkm::interop::TransferToOpenGL(this->OutCoords, this->VBOState, DeviceAdapter());
vtkm::interop::TransferToOpenGL(this->OutColors, this->ColorState, DeviceAdapter());
this->render();
if(t > 10)
{
//after 10seconds quit the demo
exit(0);
}
this->render();
if (t > 10)
{
//after 10seconds quit the demo
exit(0);
}
}
};
//global static so that glut callback can access it
typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter;
HelloVTKMInterop< DeviceAdapter, vtkm::Float32 >* helloWorld = nullptr;
HelloVTKMInterop<DeviceAdapter, vtkm::Float32>* helloWorld = nullptr;
// Render the output using simple OpenGL
void run()
@ -197,26 +198,26 @@ void idle()
int main(int argc, char** argv)
{
typedef vtkm::cont::DeviceAdapterTraits<DeviceAdapter> DeviceAdapterTraits;
std::cout << "Running Hello World example on device adapter: "
<< DeviceAdapterTraits::GetName() << std::endl;
std::cout << "Running Hello World example on device adapter: " << DeviceAdapterTraits::GetName()
<< std::endl;
glewExperimental = GL_TRUE;
glutInit(&argc, argv);
const vtkm::UInt32 width = 1024;
const vtkm::UInt32 width = 1024;
const vtkm::UInt32 height = 768;
glutInitWindowSize ( width, height );
glutInitDisplayMode ( GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(width, height);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutCreateWindow("VTK-m Hello World OpenGL Interop");
GLenum err = glewInit();
GLenum err = glewInit();
if (GLEW_OK != err)
{
std::cout << "glewInit failed\n";
std::cout << "glewInit failed\n";
}
HelloVTKMInterop< DeviceAdapter, vtkm::Float32 > hw(width,height);
HelloVTKMInterop<DeviceAdapter, vtkm::Float32> hw(width, height);
helloWorld = &hw;
glutDisplayFunc(run);
@ -225,5 +226,5 @@ int main(int argc, char** argv)
}
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#endif

@ -21,113 +21,109 @@
#ifndef LOAD_SHADERS
#define LOAD_SHADERS
#if defined (__APPLE__)
# include <GLUT/glut.h>
#if defined(__APPLE__)
#include <GLUT/glut.h>
#else
# include <GL/glut.h>
#include <GL/glut.h>
#endif
namespace shaders
{
static std::string const& make_fragment_shader_code()
{
static std::string const data =
"#version 120\n"
"void main(void)"
"{"
" gl_FragColor = gl_Color;"
"}";
static std::string const data = "#version 120\n"
"void main(void)"
"{"
" gl_FragColor = gl_Color;"
"}";
return data;
}
static std::string const& make_vertex_shader_code()
{
static std::string const data =
"#version 120\n"
"attribute vec3 posAttr;"
"uniform mat4 MVP;"
"void main()"
"{"
" vec4 pos = vec4( posAttr, 1.0 );"
" gl_FrontColor = gl_Color;"
" gl_Position = MVP * pos;"
"}";
static std::string const data = "#version 120\n"
"attribute vec3 posAttr;"
"uniform mat4 MVP;"
"void main()"
"{"
" vec4 pos = vec4( posAttr, 1.0 );"
" gl_FrontColor = gl_Color;"
" gl_Position = MVP * pos;"
"}";
return data;
}
}
inline GLuint LoadShaders()
{
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Create the shaders
GLuint VertexShaderID = glCreateShader(GL_VERTEX_SHADER);
GLuint FragmentShaderID = glCreateShader(GL_FRAGMENT_SHADER);
// Get the Vertex Shader code
std::string VertexShaderCode = shaders::make_vertex_shader_code();
// Get the Vertex Shader code
std::string VertexShaderCode = shaders::make_vertex_shader_code();
// Get the Fragment Shader code
std::string FragmentShaderCode = shaders::make_fragment_shader_code();
// Get the Fragment Shader code
std::string FragmentShaderCode = shaders::make_fragment_shader_code();
GLint Result = GL_FALSE;
int InfoLogLength;
GLint Result = GL_FALSE;
int InfoLogLength;
// Compile Vertex Shader
std::cout << "Compiling vertex shader" << std::endl;
char const * VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer, NULL);
glCompileShader(VertexShaderID);
// Compile Vertex Shader
std::cout << "Compiling vertex shader" << std::endl;
char const* VertexSourcePointer = VertexShaderCode.c_str();
glShaderSource(VertexShaderID, 1, &VertexSourcePointer, nullptr);
glCompileShader(VertexShaderID);
// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> VertexShaderErrorMessage( static_cast<std::size_t>(InfoLogLength) );
if(VertexShaderErrorMessage.size() > 0)
{
glGetShaderInfoLog(VertexShaderID, InfoLogLength, NULL, &VertexShaderErrorMessage[0]);
std::cout << &VertexShaderErrorMessage[0] << std::endl;
}
// Check Vertex Shader
glGetShaderiv(VertexShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(VertexShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> VertexShaderErrorMessage(static_cast<std::size_t>(InfoLogLength));
if (VertexShaderErrorMessage.size() > 0)
{
glGetShaderInfoLog(VertexShaderID, InfoLogLength, nullptr, &VertexShaderErrorMessage[0]);
std::cout << &VertexShaderErrorMessage[0] << std::endl;
}
// Compile Fragment Shader
std::cout << "Compiling fragment shader" << std::endl;
char const * FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, NULL);
glCompileShader(FragmentShaderID);
// Compile Fragment Shader
std::cout << "Compiling fragment shader" << std::endl;
char const* FragmentSourcePointer = FragmentShaderCode.c_str();
glShaderSource(FragmentShaderID, 1, &FragmentSourcePointer, nullptr);
glCompileShader(FragmentShaderID);
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> FragmentShaderErrorMessage( static_cast<std::size_t>(InfoLogLength) );
if(FragmentShaderErrorMessage.size() > 0)
{
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, NULL, &FragmentShaderErrorMessage[0]);
std::cout << &FragmentShaderErrorMessage[0] << std::endl;
}
// Check Fragment Shader
glGetShaderiv(FragmentShaderID, GL_COMPILE_STATUS, &Result);
glGetShaderiv(FragmentShaderID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> FragmentShaderErrorMessage(static_cast<std::size_t>(InfoLogLength));
if (FragmentShaderErrorMessage.size() > 0)
{
glGetShaderInfoLog(FragmentShaderID, InfoLogLength, nullptr, &FragmentShaderErrorMessage[0]);
std::cout << &FragmentShaderErrorMessage[0] << std::endl;
}
// Link the program
std::cout << "Linking program" << std::endl;
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Link the program
std::cout << "Linking program" << std::endl;
GLuint ProgramID = glCreateProgram();
glAttachShader(ProgramID, VertexShaderID);
glAttachShader(ProgramID, FragmentShaderID);
glLinkProgram(ProgramID);
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> ProgramErrorMessage( static_cast<std::size_t>(InfoLogLength) );
if(ProgramErrorMessage.size() > 0)
{
glGetProgramInfoLog(ProgramID, InfoLogLength, NULL, &ProgramErrorMessage[0]);
std::cout << &ProgramErrorMessage[0] << std::endl;
}
// Check the program
glGetProgramiv(ProgramID, GL_LINK_STATUS, &Result);
glGetProgramiv(ProgramID, GL_INFO_LOG_LENGTH, &InfoLogLength);
std::vector<char> ProgramErrorMessage(static_cast<std::size_t>(InfoLogLength));
if (ProgramErrorMessage.size() > 0)
{
glGetProgramInfoLog(ProgramID, InfoLogLength, nullptr, &ProgramErrorMessage[0]);
std::cout << &ProgramErrorMessage[0] << std::endl;
}
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
glDeleteShader(VertexShaderID);
glDeleteShader(FragmentShaderID);
return ProgramID;
return ProgramID;
}
#endif

@ -34,14 +34,14 @@
//Suppress warnings about glut being deprecated on OSX
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#if defined (__APPLE__)
# include <GLUT/glut.h>
#if defined(__APPLE__)
#include <GLUT/glut.h>
#else
# include <GL/glut.h>
#include <GL/glut.h>
#endif
#include "quaternion.h"
@ -49,13 +49,14 @@
#include <vector>
static vtkm::Id3 dims(256, 256, 256);
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32,3> > verticesArray, normalsArray;
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>> verticesArray, normalsArray;
static vtkm::cont::ArrayHandle<vtkm::Float32> scalarsArray;
static Quaternion qrot;
static int lastx, lasty;
static int mouse_state = 1;
namespace {
namespace
{
// Define the tangle field for the input data
class TangleField : public vtkm::worklet::WorkletMapField
@ -70,29 +71,40 @@ public:
const vtkm::Id cellsPerLayer;
VTKM_CONT
TangleField(const vtkm::Id3 dims, const vtkm::Float32 mins[3], const vtkm::Float32 maxs[3]) : xdim(dims[0]), ydim(dims[1]), zdim(dims[2]),
xmin(mins[0]), ymin(mins[1]), zmin(mins[2]), xmax(maxs[0]), ymax(maxs[1]), zmax(maxs[2]), cellsPerLayer((xdim) * (ydim)) { };
TangleField(const vtkm::Id3 dims, const vtkm::Float32 mins[3], const vtkm::Float32 maxs[3])
: xdim(dims[0])
, ydim(dims[1])
, zdim(dims[2])
, xmin(mins[0])
, ymin(mins[1])
, zmin(mins[2])
, xmax(maxs[0])
, ymax(maxs[1])
, zmax(maxs[2])
, cellsPerLayer((xdim) * (ydim)){};
VTKM_EXEC
void operator()(const vtkm::Id &vertexId, vtkm::Float32 &v) const
void operator()(const vtkm::Id& vertexId, vtkm::Float32& v) const
{
const vtkm::Id x = vertexId % (xdim);
const vtkm::Id y = (vertexId / (xdim)) % (ydim);
const vtkm::Id z = vertexId / cellsPerLayer;
const vtkm::Float32 fx = static_cast<vtkm::Float32>(x) / static_cast<vtkm::Float32>(xdim-1);
const vtkm::Float32 fy = static_cast<vtkm::Float32>(y) / static_cast<vtkm::Float32>(xdim-1);
const vtkm::Float32 fz = static_cast<vtkm::Float32>(z) / static_cast<vtkm::Float32>(xdim-1);
const vtkm::Float32 fx = static_cast<vtkm::Float32>(x) / static_cast<vtkm::Float32>(xdim - 1);
const vtkm::Float32 fy = static_cast<vtkm::Float32>(y) / static_cast<vtkm::Float32>(xdim - 1);
const vtkm::Float32 fz = static_cast<vtkm::Float32>(z) / static_cast<vtkm::Float32>(xdim - 1);
const vtkm::Float32 xx = 3.0f*(xmin+(xmax-xmin)*(fx));
const vtkm::Float32 yy = 3.0f*(ymin+(ymax-ymin)*(fy));
const vtkm::Float32 zz = 3.0f*(zmin+(zmax-zmin)*(fz));
const vtkm::Float32 xx = 3.0f * (xmin + (xmax - xmin) * (fx));
const vtkm::Float32 yy = 3.0f * (ymin + (ymax - ymin) * (fy));
const vtkm::Float32 zz = 3.0f * (zmin + (zmax - zmin) * (fz));
v = (xx*xx*xx*xx - 5.0f*xx*xx + yy*yy*yy*yy - 5.0f*yy*yy + zz*zz*zz*zz - 5.0f*zz*zz + 11.8f) * 0.2f + 0.5f;
v = (xx * xx * xx * xx - 5.0f * xx * xx + yy * yy * yy * yy - 5.0f * yy * yy +
zz * zz * zz * zz - 5.0f * zz * zz + 11.8f) *
0.2f +
0.5f;
}
};
// Construct an input data set using the tangle field worklet
vtkm::cont::DataSet MakeIsosurfaceTestDataSet(vtkm::Id3 dims)
{
@ -100,24 +112,23 @@ vtkm::cont::DataSet MakeIsosurfaceTestDataSet(vtkm::Id3 dims)
const vtkm::Id3 vdims(dims[0] + 1, dims[1] + 1, dims[2] + 1);
vtkm::Float32 mins[3] = {-1.0f, -1.0f, -1.0f};
vtkm::Float32 maxs[3] = {1.0f, 1.0f, 1.0f};
vtkm::Float32 mins[3] = { -1.0f, -1.0f, -1.0f };
vtkm::Float32 maxs[3] = { 1.0f, 1.0f, 1.0f };
vtkm::cont::ArrayHandle<vtkm::Float32> fieldArray;
vtkm::cont::ArrayHandleCounting<vtkm::Id> vertexCountImplicitArray(0, 1, vdims[0]*vdims[1]*vdims[2]);
vtkm::worklet::DispatcherMapField<TangleField> tangleFieldDispatcher(TangleField(vdims, mins, maxs));
vtkm::cont::ArrayHandleCounting<vtkm::Id> vertexCountImplicitArray(
0, 1, vdims[0] * vdims[1] * vdims[2]);
vtkm::worklet::DispatcherMapField<TangleField> tangleFieldDispatcher(
TangleField(vdims, mins, maxs));
tangleFieldDispatcher.Invoke(vertexCountImplicitArray, fieldArray);
vtkm::Vec<vtkm::FloatDefault,3> origin(0.0f, 0.0f, 0.0f);
vtkm::Vec<vtkm::FloatDefault,3> spacing(
1.0f/static_cast<vtkm::FloatDefault>(dims[0]),
1.0f/static_cast<vtkm::FloatDefault>(dims[2]),
1.0f/static_cast<vtkm::FloatDefault>(dims[1]));
vtkm::Vec<vtkm::FloatDefault, 3> origin(0.0f, 0.0f, 0.0f);
vtkm::Vec<vtkm::FloatDefault, 3> spacing(1.0f / static_cast<vtkm::FloatDefault>(dims[0]),
1.0f / static_cast<vtkm::FloatDefault>(dims[2]),
1.0f / static_cast<vtkm::FloatDefault>(dims[1]));
vtkm::cont::ArrayHandleUniformPointCoordinates
coordinates(vdims, origin, spacing);
dataSet.AddCoordinateSystem(
vtkm::cont::CoordinateSystem("coordinates", coordinates));
vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(vdims, origin, spacing);
dataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates));
dataSet.AddField(vtkm::cont::Field("nodevar", vtkm::cont::Field::ASSOC_POINTS, fieldArray));
@ -128,10 +139,8 @@ vtkm::cont::DataSet MakeIsosurfaceTestDataSet(vtkm::Id3 dims)
return dataSet;
}
}
// Initialize the OpenGL state
void initializeGL()
{
@ -157,7 +166,6 @@ void initializeGL()
glEnable(GL_COLOR_MATERIAL);
}
// Render the output using simple OpenGL
void displayCall()
{
@ -166,7 +174,7 @@ void displayCall()
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 45.0f, 1.0f, 1.0f, 20.0f);
gluPerspective(45.0f, 1.0f, 1.0f, 20.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
@ -181,7 +189,7 @@ void displayCall()
glColor3f(0.1f, 0.1f, 0.6f);
glBegin(GL_TRIANGLES);
for (vtkm::IdComponent i=0; i<verticesArray.GetNumberOfValues(); i++)
for (vtkm::IdComponent i = 0; i < verticesArray.GetNumberOfValues(); i++)
{
vtkm::Vec<vtkm::Float32, 3> curNormal = normalsArray.GetPortalConstControl().Get(i);
vtkm::Vec<vtkm::Float32, 3> curVertex = verticesArray.GetPortalConstControl().Get(i);
@ -194,7 +202,6 @@ void displayCall()
glutSwapBuffers();
}
// Allow rotations of the view
void mouseMove(int x, int y)
{
@ -205,11 +212,11 @@ void mouseMove(int x, int y)
{
vtkm::Float32 pideg = static_cast<vtkm::Float32>(vtkm::Pi_2());
Quaternion newRotX;
newRotX.setEulerAngles(-0.2f*dx*pideg/180.0f, 0.0f, 0.0f);
newRotX.setEulerAngles(-0.2f * dx * pideg / 180.0f, 0.0f, 0.0f);
qrot.mul(newRotX);
Quaternion newRotY;
newRotY.setEulerAngles(0.0f, 0.0f, -0.2f*dy*pideg/180.0f);
newRotY.setEulerAngles(0.0f, 0.0f, -0.2f * dy * pideg / 180.0f);
qrot.mul(newRotY);
}
lastx = x;
@ -218,15 +225,18 @@ void mouseMove(int x, int y)
glutPostRedisplay();
}
// Respond to mouse button
void mouseCall(int button, int state, int x, int y)
{
if (button == 0) mouse_state = state;
if ((button == 0) && (state == 0)) { lastx = x; lasty = y; }
if (button == 0)
mouse_state = state;
if ((button == 0) && (state == 0))
{
lastx = x;
lasty = y;
}
}
// Compute and render an isosurface for a uniform grid example
int main(int argc, char* argv[])
{
@ -236,21 +246,20 @@ int main(int argc, char* argv[])
filter.SetGenerateNormals(true);
filter.SetMergeDuplicatePoints(false);
filter.SetIsoValue(0, 0.5);
vtkm::filter::ResultDataSet result =
filter.Execute( dataSet, dataSet.GetField("nodevar") );
vtkm::filter::ResultDataSet result = filter.Execute(dataSet, dataSet.GetField("nodevar"));
filter.MapFieldOntoOutput(result, dataSet.GetField("nodevar"));
//need to extract vertices, normals, and scalars
vtkm::cont::DataSet& outputData = result.GetDataSet();
typedef vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32,3> > VertType;
typedef vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>> VertType;
vtkm::cont::CoordinateSystem coords = outputData.GetCoordinateSystem();
verticesArray = coords.GetData().Cast<VertType>();
normalsArray = outputData.GetField("normals").GetData().Cast<VertType>();
scalarsArray = outputData.GetField("nodevar").GetData().Cast< vtkm::cont::ArrayHandle<vtkm::Float32> >();
scalarsArray =
outputData.GetField("nodevar").GetData().Cast<vtkm::cont::ArrayHandle<vtkm::Float32>>();
std::cout << "Number of output vertices: " << verticesArray.GetNumberOfValues() << std::endl;
@ -282,5 +291,5 @@ int main(int argc, char* argv[])
}
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#endif

@ -36,55 +36,84 @@
class Quaternion
{
public:
Quaternion() { x = y = z = 0.0; w = 1.0; }
Quaternion(double ax, double ay, double az, double aw) : x(ax), y(ay), z(az), w(aw) {};
void set(double ax, double ay, double az, double aw) { x = ax; y = ay; z = az; w = aw; }
void normalize()
{
float norm = static_cast<float>(sqrt(x*x + y*y + z*z + w*w));
if (norm > 0.00001) { x /= norm; y /= norm; z /= norm; w /= norm; }
}
void mul(Quaternion q)
{
double tx, ty, tz, tw;
tx = w*q.x + x*q.w + y*q.z - z*q.y;
ty = w*q.y + y*q.w + z*q.x - x*q.z;
tz = w*q.z + z*q.w + x*q.y - y*q.x;
tw = w*q.w - x*q.x - y*q.y - z*q.z;
Quaternion()
{
x = y = z = 0.0;
w = 1.0;
}
Quaternion(double ax, double ay, double az, double aw)
: x(ax)
, y(ay)
, z(az)
, w(aw){};
void set(double ax, double ay, double az, double aw)
{
x = ax;
y = ay;
z = az;
w = aw;
}
void normalize()
{
float norm = static_cast<float>(sqrt(x * x + y * y + z * z + w * w));
if (norm > 0.00001)
{
x /= norm;
y /= norm;
z /= norm;
w /= norm;
}
}
void mul(Quaternion q)
{
double tx, ty, tz, tw;
tx = w * q.x + x * q.w + y * q.z - z * q.y;
ty = w * q.y + y * q.w + z * q.x - x * q.z;
tz = w * q.z + z * q.w + x * q.y - y * q.x;
tw = w * q.w - x * q.x - y * q.y - z * q.z;
x = tx; y = ty; z = tz; w = tw;
}
void setEulerAngles(float pitch, float yaw, float roll)
{
w = cos(pitch/2.0)*cos(yaw/2.0)*cos(roll/2.0) - sin(pitch/2.0)*sin(yaw/2.0)*sin(roll/2.0);
x = sin(pitch/2.0)*sin(yaw/2.0)*cos(roll/2.0) + cos(pitch/2.0)*cos(yaw/2.0)*sin(roll/2.0);
y = sin(pitch/2.0)*cos(yaw/2.0)*cos(roll/2.0) + cos(pitch/2.0)*sin(yaw/2.0)*sin(roll/2.0);
z = cos(pitch/2.0)*sin(yaw/2.0)*cos(roll/2.0) - sin(pitch/2.0)*cos(yaw/2.0)*sin(roll/2.0);
x = tx;
y = ty;
z = tz;
w = tw;
}
void setEulerAngles(float pitch, float yaw, float roll)
{
w = cos(pitch / 2.0) * cos(yaw / 2.0) * cos(roll / 2.0) -
sin(pitch / 2.0) * sin(yaw / 2.0) * sin(roll / 2.0);
x = sin(pitch / 2.0) * sin(yaw / 2.0) * cos(roll / 2.0) +
cos(pitch / 2.0) * cos(yaw / 2.0) * sin(roll / 2.0);
y = sin(pitch / 2.0) * cos(yaw / 2.0) * cos(roll / 2.0) +
cos(pitch / 2.0) * sin(yaw / 2.0) * sin(roll / 2.0);
z = cos(pitch / 2.0) * sin(yaw / 2.0) * cos(roll / 2.0) -
sin(pitch / 2.0) * cos(yaw / 2.0) * sin(roll / 2.0);
normalize();
}
normalize();
}
void getRotMat(float* m) const
{
for (int i=0; i<16; i++) {m[i] = 0.0;}
void getRotMat(float* m) const
{
for (int i = 0; i < 16; i++)
{
m[i] = 0.0;
}
m[0] = static_cast<float>(1.0 - 2.0*y*y - 2.0*z*z);
m[1] = static_cast<float>(2.0*x*y - 2.0*z*w);
m[2] = static_cast<float>(2.0*x*z + 2.0*y*w);
m[0] = static_cast<float>(1.0 - 2.0 * y * y - 2.0 * z * z);
m[1] = static_cast<float>(2.0 * x * y - 2.0 * z * w);
m[2] = static_cast<float>(2.0 * x * z + 2.0 * y * w);
m[4] = static_cast<float>(2.0*x*y + 2.0*z*w);
m[5] = static_cast<float>(1.0 - 2.0*x*x - 2.0*z*z);
m[6] = static_cast<float>(2.0*y*z - 2.0*x*w);
m[4] = static_cast<float>(2.0 * x * y + 2.0 * z * w);
m[5] = static_cast<float>(1.0 - 2.0 * x * x - 2.0 * z * z);
m[6] = static_cast<float>(2.0 * y * z - 2.0 * x * w);
m[8] = static_cast<float>(2.0*x*z - 2.0*y*w);
m[9] = static_cast<float>(2.0*y*z + 2.0*x*w);
m[10] = static_cast<float>(1.0 - 2.0*x*x - 2.0*y*y);
m[8] = static_cast<float>(2.0 * x * z - 2.0 * y * w);
m[9] = static_cast<float>(2.0 * y * z + 2.0 * x * w);
m[10] = static_cast<float>(1.0 - 2.0 * x * x - 2.0 * y * y);
m[15] = 1.0;
}
}
double x,y,z,w;
double x, y, z, w;
};
#endif /* QUATERNION_H_ */

@ -26,30 +26,32 @@
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/cont/TryExecute.h>
#include <vtkm/cont/cuda/DeviceAdapterCuda.h>
#include <vtkm/cont/serial/DeviceAdapterSerial.h>
#include <vtkm/cont/tbb/DeviceAdapterTBB.h>
typedef vtkm::Vec< vtkm::Float32, 3 > FloatVec3;
typedef vtkm::Vec< vtkm::UInt8, 4 > Uint8Vec4;
typedef vtkm::Vec<vtkm::Float32, 3> FloatVec3;
typedef vtkm::Vec<vtkm::UInt8, 4> Uint8Vec4;
struct GenerateSurfaceWorklet : public vtkm::worklet::WorkletMapField
{
vtkm::Float32 t;
GenerateSurfaceWorklet(vtkm::Float32 st) : t(st) {}
GenerateSurfaceWorklet(vtkm::Float32 st)
: t(st)
{
}
typedef void ControlSignature( FieldIn<>, FieldOut<>, FieldOut<> );
typedef void ExecutionSignature( _1, _2, _3 );
typedef void ControlSignature(FieldIn<>, FieldOut<>, FieldOut<>);
typedef void ExecutionSignature(_1, _2, _3);
template<typename T>
VTKM_EXEC
void operator()( const vtkm::Vec< T, 3 > & input,
vtkm::Vec<T, 3> & output,
vtkm::Vec<vtkm::UInt8, 4>& color ) const
template <typename T>
VTKM_EXEC void operator()(const vtkm::Vec<T, 3>& input,
vtkm::Vec<T, 3>& output,
vtkm::Vec<vtkm::UInt8, 4>& color) const
{
output[0] = input[0];
output[1] = 0.25f * vtkm::Sin( input[0] * 10.f + t ) * vtkm::Cos( input[2] * 10.f + t );
output[1] = 0.25f * vtkm::Sin(input[0] * 10.f + t) * vtkm::Cos(input[2] * 10.f + t);
output[2] = input[2];
color[0] = 0;
@ -61,65 +63,58 @@ struct GenerateSurfaceWorklet : public vtkm::worklet::WorkletMapField
struct RunGenerateSurfaceWorklet
{
template<typename DeviceAdapterTag>
bool operator()(DeviceAdapterTag ) const
template <typename DeviceAdapterTag>
bool operator()(DeviceAdapterTag) const
{
//At this point we know we have runtime support
typedef vtkm::cont::DeviceAdapterTraits<DeviceAdapterTag> DeviceTraits;
typedef vtkm::worklet::DispatcherMapField<GenerateSurfaceWorklet,
DeviceAdapterTag> DispatcherType;
typedef vtkm::worklet::DispatcherMapField<GenerateSurfaceWorklet, DeviceAdapterTag>
DispatcherType;
std::cout << "Running a worklet on device adapter: "
<< DeviceTraits::GetName() << std::endl;
std::cout << "Running a worklet on device adapter: " << DeviceTraits::GetName() << std::endl;
GenerateSurfaceWorklet worklet( 0.05f );
DispatcherType(worklet).Invoke( this->In,
this->Out,
this->Color);
GenerateSurfaceWorklet worklet(0.05f);
DispatcherType(worklet).Invoke(this->In, this->Out, this->Color);
return true;
return true;
}
vtkm::cont::ArrayHandle< FloatVec3 > In;
vtkm::cont::ArrayHandle< FloatVec3 > Out;
vtkm::cont::ArrayHandle< Uint8Vec4 > Color;
vtkm::cont::ArrayHandle<FloatVec3> In;
vtkm::cont::ArrayHandle<FloatVec3> Out;
vtkm::cont::ArrayHandle<Uint8Vec4> Color;
};
template<typename T>
std::vector< vtkm::Vec<T, 3> > make_testData(int size)
template <typename T>
std::vector<vtkm::Vec<T, 3>> make_testData(int size)
{
std::vector< vtkm::Vec< T, 3 > > data;
data.reserve( static_cast<std::size_t>(size*size) );
for (int i = 0; i < size; ++i )
std::vector<vtkm::Vec<T, 3>> data;
data.reserve(static_cast<std::size_t>(size * size));
for (int i = 0; i < size; ++i)
{
for (int j = 0; j < size; ++j)
{
for (int j = 0; j < size; ++j )
{
data.push_back( vtkm::Vec<T,3>(2.f*static_cast<T>(i/size)-1.f,
0.f,
2.f*static_cast<T>(j/size)-1.f));
}
data.push_back(vtkm::Vec<T, 3>(
2.f * static_cast<T>(i / size) - 1.f, 0.f, 2.f * static_cast<T>(j / size) - 1.f));
}
}
return data;
}
//This is the list of devices to compile in support for. The order of the
//devices determines the runtime preference.
struct DevicesToTry
: vtkm::ListTagBase<
vtkm::cont::DeviceAdapterTagCuda,
vtkm::cont::DeviceAdapterTagTBB,
vtkm::cont::DeviceAdapterTagSerial> { };
struct DevicesToTry : vtkm::ListTagBase<vtkm::cont::DeviceAdapterTagCuda,
vtkm::cont::DeviceAdapterTagTBB,
vtkm::cont::DeviceAdapterTagSerial>
{
};
int main(int, char**)
{
std::vector< FloatVec3 > data = make_testData<vtkm::Float32>(1024);
std::vector<FloatVec3> data = make_testData<vtkm::Float32>(1024);
//make array handles for the data
// TryExecutes takes a functor and a list of devices. It then tries to run
// the functor for each device (in the order given in the list) until the
// execution succeeds. This allows you to compile in support for multiple
@ -136,7 +131,4 @@ int main(int, char**)
RunGenerateSurfaceWorklet task;
task.In = vtkm::cont::make_ArrayHandle(data);
vtkm::cont::TryExecute(task, DevicesToTry());
}

@ -0,0 +1,47 @@
##=============================================================================
##
## 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 Sandia Corporation.
## Copyright 2015 UT-Battelle, LLC.
## Copyright 2015 Los Alamos National Security.
##
## Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
## the U.S. Government retains certain rights in this software.
## Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
## Laboratory (LANL), the U.S. Government retains certain rights in
## this software.
##
##=============================================================================
#Find the VTK-m package
find_package(VTKm REQUIRED QUIET
OPTIONAL_COMPONENTS Serial CUDA TBB
)
add_executable(Particle_Advection_SERIAL ParticleAdvection.cxx)
target_include_directories(Particle_Advection_SERIAL PRIVATE ${VTKm_INCLUDE_DIRS})
target_link_libraries(Particle_Advection_SERIAL ${VTKm_LIBRARIES})
target_compile_options(Particle_Advection_SERIAL PRIVATE ${VTKm_COMPILE_OPTIONS})
if(VTKm_TBB_FOUND)
add_executable(Particle_Advection_TBB ParticleAdvectionTBB.cxx)
target_include_directories(Particle_Advection_TBB PRIVATE ${VTKm_INCLUDE_DIRS})
target_link_libraries(Particle_Advection_TBB ${VTKm_LIBRARIES})
target_compile_options(Particle_Advection_TBB PRIVATE ${VTKm_COMPILE_OPTIONS})
endif()
if(VTKm_CUDA_FOUND)
# Cuda compiles do not respect target_include_directories
cuda_include_directories(${VTKm_INCLUDE_DIRS})
cuda_add_executable(Particle_Advection_CUDA ParticleAdvection.cu)
target_include_directories(Particle_Advection_SERIAL PRIVATE ${VTKm_INCLUDE_DIRS})
target_link_libraries(Particle_Advection_CUDA PRIVATE ${VTKm_LIBRARIES})
target_compile_options(Particle_Advection_CUDA PRIVATE ${VTKm_COMPILE_OPTIONS})
endif()

@ -0,0 +1,23 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_CUDA
#include "ParticleAdvection.cxx"

@ -0,0 +1,328 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef VTKM_DEVICE_ADAPTER
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
#endif
#include <vtkm/cont/DataSet.h>
#include <vtkm/worklet/ParticleAdvection.h>
#include <vtkm/worklet/particleadvection/GridEvaluators.h>
#include <vtkm/worklet/particleadvection/Integrators.h>
#include <vtkm/worklet/particleadvection/ParticleAdvectionWorklets.h>
#include <vtkm/worklet/particleadvection/Particles.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/io/reader/BOVDataSetReader.h>
#include <chrono>
#include <vector>
const vtkm::Id SPARSE = 0;
const vtkm::Id DENSE = 1;
const vtkm::Id MEDIUM = 2;
template <typename T>
static vtkm::Range subRange(vtkm::Range& range, T a, T b)
{
vtkm::Float32 arg1, arg2, len;
arg1 = static_cast<vtkm::Float32>(a);
arg2 = static_cast<vtkm::Float32>(b);
len = static_cast<vtkm::Float32>(range.Length());
return vtkm::Range(range.Min + arg1 * len, range.Min + arg2 * len);
}
template <typename T>
void ignore(T&&)
{
}
void RunTest(const std::string& fname,
vtkm::Id numSeeds,
vtkm::Id numSteps,
vtkm::Float32 stepSize,
vtkm::Id numThreads,
vtkm::Id advectType,
vtkm::Id stepsPerRound,
vtkm::Id particlesPerRound,
vtkm::Id seeding)
{
typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter;
typedef vtkm::Float32 FieldType;
typedef vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>> FieldHandle;
typedef
typename FieldHandle::template ExecutionTypes<DeviceAdapter>::PortalConst FieldPortalConstType;
vtkm::io::reader::BOVDataSetReader rdr(fname);
vtkm::cont::DataSet ds = rdr.ReadDataSet();
typedef vtkm::worklet::particleadvection::UniformGridEvaluate<FieldPortalConstType, FieldType>
RGEvalType;
typedef vtkm::worklet::particleadvection::RK4Integrator<RGEvalType, FieldType> RK4RGType;
RGEvalType eval(ds);
RK4RGType rk4(eval, stepSize);
std::vector<vtkm::Vec<FieldType, 3>> seeds;
srand(314);
vtkm::Bounds bounds = ds.GetCoordinateSystem().GetBounds();
if (seeding == SPARSE)
bounds = ds.GetCoordinateSystem().GetBounds();
else if (seeding == DENSE)
{
if (fname.find("astro") != std::string::npos)
{
bounds.X = subRange(bounds.X, .1, .15);
bounds.Y = subRange(bounds.Y, .1, .15);
bounds.Z = subRange(bounds.Z, .1, .15);
}
else if (fname.find("fusion") != std::string::npos)
{
bounds.X = subRange(bounds.X, .8, .85);
bounds.Y = subRange(bounds.Y, .55, .60);
bounds.Z = subRange(bounds.Z, .55, .60);
}
else if (fname.find("fishtank") != std::string::npos)
{
bounds.X = subRange(bounds.X, .1, .15);
bounds.Y = subRange(bounds.Y, .1, .15);
bounds.Z = subRange(bounds.Z, .55, .60);
}
}
else if (seeding == MEDIUM)
{
if (fname.find("astro") != std::string::npos)
{
bounds.X = subRange(bounds.X, .4, .6);
bounds.Y = subRange(bounds.Y, .4, .6);
bounds.Z = subRange(bounds.Z, .4, .6);
}
else if (fname.find("fusion") != std::string::npos)
{
bounds.X = subRange(bounds.X, .01, .99);
bounds.Y = subRange(bounds.Y, .01, .99);
bounds.Z = subRange(bounds.Z, .45, .55);
}
else if (fname.find("fishtank") != std::string::npos)
{
bounds.X = subRange(bounds.X, .4, .6);
bounds.Y = subRange(bounds.Y, .4, .6);
bounds.Z = subRange(bounds.Z, .4, .6);
}
}
for (int i = 0; i < numSeeds; i++)
{
vtkm::Vec<FieldType, 3> p;
vtkm::Float32 rx = (vtkm::Float32)rand() / (vtkm::Float32)RAND_MAX;
vtkm::Float32 ry = (vtkm::Float32)rand() / (vtkm::Float32)RAND_MAX;
vtkm::Float32 rz = (vtkm::Float32)rand() / (vtkm::Float32)RAND_MAX;
p[0] = static_cast<FieldType>(bounds.X.Min + rx * bounds.X.Length());
p[1] = static_cast<FieldType>(bounds.Y.Min + ry * bounds.Y.Length());
p[2] = static_cast<FieldType>(bounds.Z.Min + rz * bounds.Z.Length());
seeds.push_back(p);
}
#ifdef __BUILDING_TBB_VERSION__
int nT = tbb::task_scheduler_init::default_num_threads();
if (numThreads != -1)
nT = (int)numThreads;
//make sure the task_scheduler_init object is in scope when running sth w/ TBB
tbb::task_scheduler_init init(nT);
#else
ignore(numThreads);
#endif
//time only the actual run
auto t0 = std::chrono::high_resolution_clock::now();
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>> seedArray;
seedArray = vtkm::cont::make_ArrayHandle(seeds);
vtkm::cont::ArrayHandle<vtkm::Vec<FieldType, 3>> fieldArray;
ds.GetField(0).GetData().CopyTo(fieldArray);
if (advectType == 0)
{
vtkm::worklet::ParticleAdvection particleAdvection;
particleAdvection.Run(rk4, seedArray, fieldArray, numSteps, DeviceAdapter());
}
else
{
vtkm::worklet::Streamline streamline;
streamline.Run(
rk4, seedArray, fieldArray, numSteps, stepsPerRound, particlesPerRound, DeviceAdapter());
}
auto t1 = std::chrono::high_resolution_clock::now() - t0;
auto runtime = std::chrono::duration_cast<std::chrono::milliseconds>(t1).count();
std::cerr << "Runtime = " << runtime << " ms " << std::endl;
}
bool ParseArgs(int argc,
char** argv,
vtkm::Id& numSeeds,
vtkm::Id& numSteps,
vtkm::Float32& stepSize,
vtkm::Id& advectType,
vtkm::Id& stepsPerRound,
vtkm::Id& particlesPerRound,
vtkm::Id& numThreads,
std::string& dataFile,
std::string& pgmType,
bool& dumpOutput,
vtkm::Id& seeding)
{
numSeeds = 100;
numSteps = 100;
stepSize = 0.1f;
advectType = 0;
stepsPerRound = -1;
particlesPerRound = -1;
numThreads = -1;
dataFile = "";
pgmType = "UNKNOWN";
dumpOutput = false;
seeding = SPARSE;
if (argc < 2)
{
std::cerr << "Usage " << argv[0] << std::endl;
std::cerr << " -seeds #seeds" << std::endl;
std::cerr << " -steps maxSteps" << std::endl;
std::cerr << " -h stepSize" << std::endl;
std::cerr << " -particle : particle push" << std::endl;
std::cerr << " -streamline steps_per_round (-1 = 0 rounds): particle history" << std::endl;
std::cerr << " -t #numThreads" << std::endl;
std::cerr << " -file dataFile" << std::endl;
std::cerr << " -dump : dump output points" << std::endl;
return false;
}
std::string pgm = argv[0];
if (pgm.find("SERIAL") != std::string::npos)
pgmType = "SER";
else if (pgm.find("TBB") != std::string::npos)
pgmType = "TBB";
else if (pgm.find("CUDA") != std::string::npos)
pgmType = "CUD";
for (int i = 1; i < argc; i++)
{
std::string arg = argv[i];
if (arg == "-seeds")
numSeeds = static_cast<vtkm::Id>(atoi(argv[++i]));
else if (arg == "-steps")
numSteps = static_cast<vtkm::Id>(atoi(argv[++i]));
else if (arg == "-h")
stepSize = static_cast<vtkm::Float32>(atof(argv[++i]));
else if (arg == "-particle")
advectType = 0;
else if (arg == "-streamline")
{
advectType = 1;
}
else if (arg == "-streamlineS")
{
advectType = 1;
stepsPerRound = static_cast<vtkm::Id>(atoi(argv[++i]));
}
else if (arg == "-streamlineP")
{
advectType = 1;
particlesPerRound = static_cast<vtkm::Id>(atoi(argv[++i]));
}
else if (arg == "-streamlineSP")
{
advectType = 1;
stepsPerRound = static_cast<vtkm::Id>(atoi(argv[++i]));
particlesPerRound = static_cast<vtkm::Id>(atoi(argv[++i]));
}
else if (arg == "-file")
dataFile = argv[++i];
else if (arg == "-t")
numThreads = static_cast<vtkm::Id>(atoi(argv[++i]));
else if (arg == "-dump")
dumpOutput = true;
else if (arg == "-sparse")
seeding = SPARSE;
else if (arg == "-dense")
seeding = DENSE;
else if (arg == "-medium")
seeding = MEDIUM;
else
std::cerr << "Unexpected argument: " << arg << std::endl;
}
if (dataFile.size() == 0)
{
std::cerr << "Error: no data file specified" << std::endl;
return false;
}
//Congratulations user, we have a valid run:
std::cerr << pgmType << ": " << numSeeds << " " << numSteps << " " << stepSize << " ";
if (advectType == 0)
std::cerr << "PP ";
else
std::cerr << "SL ";
std::cerr << numThreads << " ";
std::cerr << dataFile << std::endl;
return true;
}
int main(int argc, char** argv)
{
vtkm::Id numSeeds = 100, numSteps = 100, advectType = 0, numThreads = -1, stepsPerRound = -1,
particlesPerRound = -1;
vtkm::Float32 stepSize = 0.1f;
std::string dataFile, pgmType;
vtkm::Id seeding = SPARSE;
bool dumpOutput = false;
if (!ParseArgs(argc,
argv,
numSeeds,
numSteps,
stepSize,
advectType,
stepsPerRound,
particlesPerRound,
numThreads,
dataFile,
pgmType,
dumpOutput,
seeding))
{
return -1;
}
RunTest(dataFile,
numSeeds,
numSteps,
stepSize,
numThreads,
advectType,
stepsPerRound,
particlesPerRound,
seeding);
return 0;
}

@ -0,0 +1,26 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_TBB
#define __BUILDING_TBB_VERSION__
#include <tbb/task_scheduler_init.h>
#include "ParticleAdvection.cxx"

@ -30,130 +30,127 @@
//Suppress warnings about glut being deprecated on OSX
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#include <vtkm/rendering/internal/OpenGLHeaders.h> //Required for compile....
#if defined (__APPLE__)
# include <GLUT/glut.h>
#if defined(__APPLE__)
#include <GLUT/glut.h>
#else
# include <GL/glut.h>
#include <GL/glut.h>
#endif
#include <vtkm/rendering/CanvasGL.h>
#include <vtkm/rendering/ColorTable.h>
#include <vtkm/rendering/MapperGL.h>
#include <vtkm/rendering/View3D.h>
#include <vtkm/rendering/ColorTable.h>
vtkm::rendering::View3D *view = nullptr;
vtkm::rendering::View3D* view = nullptr;
const vtkm::Int32 W = 512, H = 512;
int buttonStates[3] = {GLUT_UP, GLUT_UP, GLUT_UP};
int buttonStates[3] = { GLUT_UP, GLUT_UP, GLUT_UP };
bool shiftKey = false;
int lastx=-1, lasty=-1;
int lastx = -1, lasty = -1;
void
reshape(int, int)
void reshape(int, int)
{
//Don't allow resizing window.
glutReshapeWindow(W,H);
//Don't allow resizing window.
glutReshapeWindow(W, H);
}
// Render the output using simple OpenGL
void displayCall()
{
view->Paint();
glutSwapBuffers();
view->Paint();
glutSwapBuffers();
}
// Allow rotations of the camera
void mouseMove(int x, int y)
{
const vtkm::Id width = view->GetCanvas().GetWidth();
const vtkm::Id height = view->GetCanvas().GetHeight();
//Map to XY
y = static_cast<int>(height-y);
if (lastx != -1 && lasty != -1)
const vtkm::Id width = view->GetCanvas().GetWidth();
const vtkm::Id height = view->GetCanvas().GetHeight();
//Map to XY
y = static_cast<int>(height - y);
if (lastx != -1 && lasty != -1)
{
vtkm::Float32 x1 = vtkm::Float32(lastx * 2) / vtkm::Float32(width) - 1.0f;
vtkm::Float32 y1 = vtkm::Float32(lasty * 2) / vtkm::Float32(height) - 1.0f;
vtkm::Float32 x2 = vtkm::Float32(x * 2) / vtkm::Float32(width) - 1.0f;
vtkm::Float32 y2 = vtkm::Float32(y * 2) / vtkm::Float32(height) - 1.0f;
if (buttonStates[0] == GLUT_DOWN)
{
vtkm::Float32 x1 = vtkm::Float32(lastx*2)/vtkm::Float32(width) - 1.0f;
vtkm::Float32 y1 = vtkm::Float32(lasty*2)/vtkm::Float32(height) - 1.0f;
vtkm::Float32 x2 = vtkm::Float32(x*2)/vtkm::Float32(width) - 1.0f;
vtkm::Float32 y2 = vtkm::Float32(y*2)/vtkm::Float32(height) - 1.0f;
if (buttonStates[0] == GLUT_DOWN)
{
if (shiftKey)
view->GetCamera().Pan(x2-x1, y2-y1);
else
view->GetCamera().TrackballRotate(x1,y1, x2,y2);
}
else if (buttonStates[1] == GLUT_DOWN)
view->GetCamera().Zoom(y2-y1);
if (shiftKey)
view->GetCamera().Pan(x2 - x1, y2 - y1);
else
view->GetCamera().TrackballRotate(x1, y1, x2, y2);
}
else if (buttonStates[1] == GLUT_DOWN)
view->GetCamera().Zoom(y2 - y1);
}
lastx = x;
lasty = y;
glutPostRedisplay();
lastx = x;
lasty = y;
glutPostRedisplay();
}
// Respond to mouse button
void mouseCall(int button, int state, int vtkmNotUsed(x), int vtkmNotUsed(y))
{
int modifiers = glutGetModifiers();
shiftKey = modifiers & GLUT_ACTIVE_SHIFT;
buttonStates[button] = state;
int modifiers = glutGetModifiers();
shiftKey = modifiers & GLUT_ACTIVE_SHIFT;
buttonStates[button] = state;
//std::cout<<"Buttons: "<<buttonStates[0]<<" "<<buttonStates[1]<<" "<<buttonStates[2]<<" SHIFT= "<<shiftKey<<std::endl;
//std::cout<<"Buttons: "<<buttonStates[0]<<" "<<buttonStates[1]<<" "<<buttonStates[2]<<" SHIFT= "<<shiftKey<<std::endl;
//mouse down, reset.
if (buttonStates[button] == GLUT_DOWN)
{
lastx = -1;
lasty = -1;
}
//mouse down, reset.
if (buttonStates[button] == GLUT_DOWN)
{
lastx = -1;
lasty = -1;
}
}
// Compute and render an isosurface for a uniform grid example
int
main(int argc, char* argv[])
int main(int argc, char* argv[])
{
vtkm::cont::testing::MakeTestDataSet maker;
vtkm::cont::DataSet ds = maker.Make3DUniformDataSet0();
vtkm::cont::testing::MakeTestDataSet maker;
vtkm::cont::DataSet ds = maker.Make3DUniformDataSet0();
lastx = lasty = -1;
lastx = lasty = -1;
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(W,H);
glutCreateWindow("VTK-m Rendering");
glutDisplayFunc(displayCall);
glutMotionFunc(mouseMove);
glutMouseFunc(mouseCall);
glutReshapeFunc(reshape);
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowSize(W, H);
glutCreateWindow("VTK-m Rendering");
glutDisplayFunc(displayCall);
glutMotionFunc(mouseMove);
glutMouseFunc(mouseCall);
glutReshapeFunc(reshape);
vtkm::rendering::Color bg(0.2f, 0.2f, 0.2f, 1.0f);
vtkm::rendering::CanvasGL canvas;
vtkm::rendering::MapperGL mapper;
vtkm::rendering::Color bg(0.2f, 0.2f, 0.2f, 1.0f);
vtkm::rendering::CanvasGL canvas;
vtkm::rendering::MapperGL mapper;
vtkm::rendering::Scene scene;
scene.AddActor(vtkm::rendering::Actor(ds.GetCellSet(),
ds.GetCoordinateSystem(),
ds.GetField("pointvar"),
vtkm::rendering::ColorTable("thermal")));
vtkm::rendering::Scene scene;
scene.AddActor(vtkm::rendering::Actor(ds.GetCellSet(),
ds.GetCoordinateSystem(),
ds.GetField("pointvar"),
vtkm::rendering::ColorTable("thermal")));
//Create vtkm rendering stuff.
view = new vtkm::rendering::View3D(scene, mapper, canvas, bg);
view->Initialize();
glutMainLoop();
//Create vtkm rendering stuff.
view = new vtkm::rendering::View3D(scene, mapper, canvas, bg);
view->Initialize();
glutMainLoop();
return 0;
return 0;
}
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#endif

86
examples/streamline/StreamLineUniformGrid.cxx Executable file → Normal file

@ -22,28 +22,28 @@
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
#endif
#include <vtkm/worklet/StreamLineUniformGrid.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/Math.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/StreamLineUniformGrid.h>
#include <vtkm/cont/testing/Testing.h>
#include <fstream>
#include <vector>
#include <math.h>
#include <vector>
//Suppress warnings about glut being deprecated on OSX
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#if defined (__APPLE__)
# include <GLUT/glut.h>
#if defined(__APPLE__)
#include <GLUT/glut.h>
#else
# include <GL/glut.h>
#include <GL/glut.h>
#endif
#include "../isosurface/quaternion.h"
@ -51,7 +51,7 @@
typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter;
// Output data set shared with opengl
static vtkm::worklet::StreamLineFilterUniformGrid<vtkm::Float32, DeviceAdapter> *streamLineFilter;
static vtkm::worklet::StreamLineFilterUniformGrid<vtkm::Float32, DeviceAdapter>* streamLineFilter;
static vtkm::cont::DataSet outDataSet;
// Input parameters
@ -61,7 +61,7 @@ const vtkm::Float32 tStep = 0.5f;
const vtkm::Id direction = vtkm::worklet::internal::BOTH;
// Point location of vertices from a CastAndCall but needs a static cast eventually
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3> > vertexArray;
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>> vertexArray;
// OpenGL display variables
Quaternion qrot;
@ -76,16 +76,14 @@ int mouse_state = 1;
struct GetVertexArray
{
template <typename ArrayHandleType>
VTKM_CONT
void operator()(ArrayHandleType array) const
VTKM_CONT void operator()(ArrayHandleType array) const
{
this->GetVertexPortal(array.GetPortalConstControl());
}
private:
template <typename PortalType>
VTKM_CONT
void GetVertexPortal(const PortalType &portal) const
VTKM_CONT void GetVertexPortal(const PortalType& portal) const
{
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
{
@ -131,7 +129,7 @@ void displayCall()
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 60.0f, 1.0f, 1.0f, 100.0f);
gluPerspective(60.0f, 1.0f, 1.0f, 100.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
@ -147,8 +145,8 @@ void displayCall()
// Get the cell set, coordinate system and coordinate data
vtkm::cont::CellSetExplicit<> cellSet;
outDataSet.GetCellSet(0).CopyTo(cellSet);
const vtkm::cont::DynamicArrayHandleCoordinateSystem &coordArray =
outDataSet.GetCoordinateSystem().GetData();
const vtkm::cont::DynamicArrayHandleCoordinateSystem& coordArray =
outDataSet.GetCoordinateSystem().GetData();
vtkm::Id numberOfCells = cellSet.GetNumberOfCells();
vtkm::Id numberOfPoints = coordArray.GetNumberOfValues();
@ -169,7 +167,7 @@ void displayCall()
glBegin(GL_LINE_STRIP);
for (vtkm::IdComponent i = 0; i < numIndices; i++)
{
vtkm::Vec<vtkm::Float32,3> pt = vertexArray.GetPortalConstControl().Get(polylineIndices[i]);
vtkm::Vec<vtkm::Float32, 3> pt = vertexArray.GetPortalConstControl().Get(polylineIndices[i]);
glVertex3f(pt[0], pt[1], pt[2]);
}
glEnd();
@ -201,19 +199,23 @@ void mouseMove(int x, int y)
glutPostRedisplay();
}
// Respond to mouse button
void mouseCall(int button, int state, int x, int y)
{
if (button == 0) mouse_state = state;
if ((button == 0) && (state == 0)) { lastx = x; lasty = y; }
if (button == 0)
mouse_state = state;
if ((button == 0) && (state == 0))
{
lastx = x;
lasty = y;
}
}
namespace {
namespace
{
template <typename T>
VTKM_EXEC_CONT
vtkm::Vec<T,3> Normalize(vtkm::Vec<T,3> v)
VTKM_EXEC_CONT vtkm::Vec<T, 3> Normalize(vtkm::Vec<T, 3> v)
{
T magnitude = static_cast<T>(sqrt(vtkm::dot(v, v)));
T zero = static_cast<T>(0.0);
@ -223,49 +225,50 @@ vtkm::Vec<T,3> Normalize(vtkm::Vec<T,3> v)
else
return one / magnitude * v;
}
}
// Run streamlines on a uniform grid of vector data
int main(int argc, char* argv[])
{
std::cout << "StreamLineUniformGrid Example" << std::endl;
std::cout << "Parameters are fileName [numSeeds maxSteps timeStep direction]" << std::endl << std::endl;
std::cout << "Parameters are fileName [numSeeds maxSteps timeStep direction]" << std::endl
<< std::endl;
std::cout << "Direction is FORWARD=0 BACKWARD=1 BOTH=2" << std::endl << std::endl;
std::cout << "File is expected to be binary with xdim ydim zdim as 32 bit integers " << std::endl;
std::cout << "followed by vector data per dimension point as 32 bit float" << std::endl;
// Read in the vector data for testing
FILE * pFile = fopen(argv[1], "rb");
if (pFile == nullptr) perror ("Error opening file");
FILE* pFile = fopen(argv[1], "rb");
if (pFile == nullptr)
perror("Error opening file");
size_t ret_code = 0;
// Size of the dataset
int dims[3];
ret_code = fread(dims, sizeof(int), 3, pFile);
if(ret_code != 3)
{
if (ret_code != 3)
{
perror("Error reading size of data");
fclose(pFile);
return 0;
}
}
const vtkm::Id3 vdims(dims[0], dims[1], dims[2]);
// Read vector data at each point of the uniform grid and store
vtkm::Id nElements = vdims[0] * vdims[1] * vdims[2] * 3;
float* data = new float[static_cast<std::size_t>(nElements)];
ret_code = fread(data, sizeof(float), static_cast<std::size_t>(nElements), pFile);
if( ret_code != static_cast<size_t>(nElements) )
{
if (ret_code != static_cast<size_t>(nElements))
{
perror("Error reading vector data");
fclose(pFile);
return 0;
}
}
//We are done with the file now, so release the file descriptor
fclose(pFile);
std::vector<vtkm::Vec<vtkm::Float32, 3> > field;
std::vector<vtkm::Vec<vtkm::Float32, 3>> field;
for (vtkm::Id i = 0; i < nElements; i++)
{
vtkm::Float32 x = data[i];
@ -274,14 +277,14 @@ int main(int argc, char* argv[])
vtkm::Vec<vtkm::Float32, 3> vecData(x, y, z);
field.push_back(Normalize(vecData));
}
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3> > fieldArray;
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>> fieldArray;
fieldArray = vtkm::cont::make_ArrayHandle(field);
// Construct the input dataset (uniform) to hold the input and set vector data
vtkm::cont::DataSet inDataSet;
vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(vdims);
inDataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates));
inDataSet.AddField(vtkm::cont::Field("vec", vtkm::cont::Field::ASSOC_POINTS, fieldArray));
inDataSet.AddField(vtkm::cont::Field("vecData", vtkm::cont::Field::ASSOC_POINTS, fieldArray));
vtkm::cont::CellSetStructured<3> inCellSet("cells");
inCellSet.SetPointDimensions(vtkm::make_Vec(vdims[0], vdims[1], vdims[2]));
@ -289,12 +292,7 @@ int main(int argc, char* argv[])
// Create and run the filter
streamLineFilter = new vtkm::worklet::StreamLineFilterUniformGrid<vtkm::Float32, DeviceAdapter>();
outDataSet = streamLineFilter->Run(inDataSet,
//vtkm::worklet::internal::FORWARD,
direction,
nSeeds,
nSteps,
tStep);
outDataSet = streamLineFilter->Run(inDataSet, direction, nSeeds, nSteps, tStep);
// Render the output dataset of polylines
lastx = lasty = 0;
@ -319,5 +317,5 @@ int main(int argc, char* argv[])
}
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#endif

@ -22,38 +22,38 @@
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
#endif
#include <vtkm/worklet/TetrahedralizeExplicitGrid.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/Math.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DataSetBuilderExplicit.h>
#include <vtkm/filter/Tetrahedralize.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/cont/testing/Testing.h>
//Suppress warnings about glut being deprecated on OSX
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#if defined (__APPLE__)
# include <GLUT/glut.h>
#if defined(__APPLE__)
#include <GLUT/glut.h>
#else
# include <GL/glut.h>
#include <GL/glut.h>
#endif
#include "../isosurface/quaternion.h"
typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter;
namespace {
namespace
{
// Takes input uniform grid and outputs unstructured grid of tets
static vtkm::cont::DataSet outDataSet;
vtkm::Id numberOfInPoints;
// Point location of vertices from a CastAndCall but needs a static cast eventually
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3> > vertexArray;
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>> vertexArray;
// OpenGL display variables
Quaternion qrot;
@ -70,24 +70,24 @@ vtkm::cont::DataSet MakeTetrahedralizeExplicitDataSet()
vtkm::cont::DataSetBuilderExplicitIterative builder;
builder.Begin();
builder.AddPoint( 0, 0, 0);
builder.AddPoint( 1, 0, 0);
builder.AddPoint( 2, 0, 0);
builder.AddPoint( 3, 0, 0);
builder.AddPoint( 0, 1, 0);
builder.AddPoint( 1, 1, 0);
builder.AddPoint( 2, 1, 0);
builder.AddPoint( 2.5, 1.0, 0.0);
builder.AddPoint( 0, 2, 0);
builder.AddPoint( 1, 2, 0);
builder.AddPoint( 0.5, 0.5, 1.0);
builder.AddPoint( 1, 0, 1);
builder.AddPoint( 2, 0, 1);
builder.AddPoint( 3, 0, 1);
builder.AddPoint( 1, 1, 1);
builder.AddPoint( 2, 1, 1);
builder.AddPoint( 2.5, 1.0, 1.0);
builder.AddPoint( 0.5, 1.5, 1.0);
builder.AddPoint(0, 0, 0);
builder.AddPoint(1, 0, 0);
builder.AddPoint(2, 0, 0);
builder.AddPoint(3, 0, 0);
builder.AddPoint(0, 1, 0);
builder.AddPoint(1, 1, 0);
builder.AddPoint(2, 1, 0);
builder.AddPoint(2.5, 1.0, 0.0);
builder.AddPoint(0, 2, 0);
builder.AddPoint(1, 2, 0);
builder.AddPoint(0.5, 0.5, 1.0);
builder.AddPoint(1, 0, 1);
builder.AddPoint(2, 0, 1);
builder.AddPoint(3, 0, 1);
builder.AddPoint(1, 1, 1);
builder.AddPoint(2, 1, 1);
builder.AddPoint(2.5, 1.0, 1.0);
builder.AddPoint(0.5, 1.5, 1.0);
builder.AddCell(vtkm::CELL_SHAPE_TETRA);
builder.AddCellPoint(0);
@ -131,16 +131,14 @@ vtkm::cont::DataSet MakeTetrahedralizeExplicitDataSet()
struct GetVertexArray
{
template <typename ArrayHandleType>
VTKM_CONT
void operator()(ArrayHandleType array) const
VTKM_CONT void operator()(ArrayHandleType array) const
{
this->GetVertexPortal(array.GetPortalConstControl());
}
private:
template <typename PortalType>
VTKM_CONT
void GetVertexPortal(const PortalType &portal) const
VTKM_CONT void GetVertexPortal(const PortalType& portal) const
{
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
{
@ -176,7 +174,6 @@ void initializeGL()
glEnable(GL_COLOR_MATERIAL);
}
//
// Render the output using simple OpenGL
//
@ -187,7 +184,7 @@ void displayCall()
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 45.0f, 1.0f, 1.0f, 40.0f);
gluPerspective(45.0f, 1.0f, 1.0f, 40.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
@ -206,19 +203,18 @@ void displayCall()
// Need the actual vertex points from a static cast of the dynamic array but can't get it right
// So use cast and call on a functor that stores that dynamic array into static array we created
vertexArray.Allocate(numberOfInPoints);
vertexArray.Allocate(cellSet.GetNumberOfPoints());
vtkm::cont::CastAndCall(outDataSet.GetCoordinateSystem(), GetVertexArray());
// Draw the five tetrahedra belonging to each hexadron
vtkm::Float32 color[5][3] = {
{1.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 1.0f},
{1.0f, 0.0f, 1.0f},
{1.0f, 1.0f, 0.0f}
};
vtkm::Float32 color[5][3] = { { 1.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f },
{ 1.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f, 0.0f } };
for (vtkm::Id tetra = 0; tetra < numberOfCells; tetra++) {
for (vtkm::Id tetra = 0; tetra < numberOfCells; tetra++)
{
vtkm::Id indx = tetra % 5;
glColor3f(color[indx][0], color[indx][1], color[indx][2]);
@ -227,13 +223,13 @@ void displayCall()
cellSet.GetIndices(tetra, tetIndices);
// Get the vertex points for this tetrahedron
vtkm::Vec<vtkm::Float64,3> pt0 = vertexArray.GetPortalConstControl().Get(tetIndices[0]);
vtkm::Vec<vtkm::Float64,3> pt1 = vertexArray.GetPortalConstControl().Get(tetIndices[1]);
vtkm::Vec<vtkm::Float64,3> pt2 = vertexArray.GetPortalConstControl().Get(tetIndices[2]);
vtkm::Vec<vtkm::Float64,3> pt3 = vertexArray.GetPortalConstControl().Get(tetIndices[3]);
vtkm::Vec<vtkm::Float64, 3> pt0 = vertexArray.GetPortalConstControl().Get(tetIndices[0]);
vtkm::Vec<vtkm::Float64, 3> pt1 = vertexArray.GetPortalConstControl().Get(tetIndices[1]);
vtkm::Vec<vtkm::Float64, 3> pt2 = vertexArray.GetPortalConstControl().Get(tetIndices[2]);
vtkm::Vec<vtkm::Float64, 3> pt3 = vertexArray.GetPortalConstControl().Get(tetIndices[3]);
// Draw the tetrahedron filled with alternating colors
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBegin(GL_TRIANGLE_STRIP);
glVertex3d(pt0[0], pt0[1], pt0[2]);
glVertex3d(pt1[0], pt1[1], pt1[2]);
@ -245,7 +241,7 @@ void displayCall()
// Draw the tetrahedron wireframe
glColor3f(1.0f, 1.0f, 1.0f);
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_TRIANGLE_STRIP);
glVertex3d(pt0[0], pt0[1], pt0[2]);
glVertex3d(pt1[0], pt1[1], pt1[2]);
@ -259,7 +255,6 @@ void displayCall()
glutSwapBuffers();
}
// Allow rotations of the view
void mouseMove(int x, int y)
{
@ -283,15 +278,18 @@ void mouseMove(int x, int y)
glutPostRedisplay();
}
// Respond to mouse button
void mouseCall(int button, int state, int x, int y)
{
if (button == 0) mouse_state = state;
if ((button == 0) && (state == 0)) { lastx = x; lasty = y; }
if (button == 0)
mouse_state = state;
if ((button == 0) && (state == 0))
{
lastx = x;
lasty = y;
}
}
// Tetrahedralize and render uniform grid example
int main(int argc, char* argv[])
{
@ -302,17 +300,11 @@ int main(int argc, char* argv[])
vtkm::cont::CellSetExplicit<> inCellSet;
inDataSet.GetCellSet(0).CopyTo(inCellSet);
numberOfInPoints = inCellSet.GetNumberOfPoints();
// Create the output dataset explicit cell set with same coordinate system
vtkm::cont::CellSetSingleType<> cellSet("cells");
outDataSet.AddCellSet(cellSet);
outDataSet.AddCoordinateSystem(inDataSet.GetCoordinateSystem(0));
// Convert cells to tetrahedra
vtkm::worklet::TetrahedralizeFilterExplicitGrid<DeviceAdapter>
tetrahedralizeFilter(inDataSet, outDataSet);
tetrahedralizeFilter.Run();
vtkm::filter::Tetrahedralize tetrahedralize;
vtkm::filter::ResultDataSet result = tetrahedralize.Execute(inDataSet);
outDataSet = result.GetDataSet();
// Render the output dataset of tets
lastx = lasty = 0;
@ -336,5 +328,5 @@ int main(int argc, char* argv[])
}
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#endif

@ -22,23 +22,23 @@
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
#endif
#include <vtkm/worklet/TetrahedralizeUniformGrid.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/Math.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/filter/Tetrahedralize.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/cont/testing/Testing.h>
//Suppress warnings about glut being deprecated on OSX
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#if defined (__APPLE__)
# include <GLUT/glut.h>
#if defined(__APPLE__)
#include <GLUT/glut.h>
#else
# include <GL/glut.h>
#include <GL/glut.h>
#endif
#include "../isosurface/quaternion.h"
@ -46,16 +46,14 @@
typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter;
// Default size of the example
static vtkm::Id3 dims(4,4,4);
static vtkm::Id3 dims(4, 4, 4);
static vtkm::Id cellsToDisplay = 64;
static vtkm::Id numberOfInPoints;
// Takes input uniform grid and outputs unstructured grid of tets
static vtkm::worklet::TetrahedralizeFilterUniformGrid<DeviceAdapter> *tetrahedralizeFilter;
static vtkm::cont::DataSet tetDataSet;
// Point location of vertices from a CastAndCall but needs a static cast eventually
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3> > vertexArray;
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>> vertexArray;
// OpenGL display variables
static Quaternion qrot;
@ -72,15 +70,14 @@ vtkm::cont::DataSet MakeTetrahedralizeTestDataSet(vtkm::Id3 dim)
// Place uniform grid on a set physical space so OpenGL drawing is easier
const vtkm::Id3 vdims(dim[0] + 1, dim[1] + 1, dim[2] + 1);
const vtkm::Vec<vtkm::Float32, 3> origin = vtkm::make_Vec(0.0f, 0.0f, 0.0f);
const vtkm::Vec<vtkm::Float32, 3> spacing = vtkm::make_Vec(
1.0f/static_cast<vtkm::Float32>(dim[0]),
1.0f/static_cast<vtkm::Float32>(dim[1]),
1.0f/static_cast<vtkm::Float32>(dim[2]));
const vtkm::Vec<vtkm::Float32, 3> spacing =
vtkm::make_Vec(1.0f / static_cast<vtkm::Float32>(dim[0]),
1.0f / static_cast<vtkm::Float32>(dim[1]),
1.0f / static_cast<vtkm::Float32>(dim[2]));
// Generate coordinate system
vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(vdims, origin, spacing);
dataSet.AddCoordinateSystem(
vtkm::cont::CoordinateSystem("coordinates", coordinates));
dataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates));
// Generate cell set
vtkm::cont::CellSetStructured<3> cellSet("cells");
@ -98,16 +95,14 @@ vtkm::cont::DataSet MakeTetrahedralizeTestDataSet(vtkm::Id3 dim)
struct GetVertexArray
{
template <typename ArrayHandleType>
VTKM_CONT
void operator()(ArrayHandleType array) const
VTKM_CONT void operator()(ArrayHandleType array) const
{
this->GetVertexPortal(array.GetPortalConstControl());
}
private:
template <typename PortalType>
VTKM_CONT
void GetVertexPortal(const PortalType &portal) const
VTKM_CONT void GetVertexPortal(const PortalType& portal) const
{
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
{
@ -143,7 +138,6 @@ void initializeGL()
glEnable(GL_COLOR_MATERIAL);
}
//
// Render the output using simple OpenGL
//
@ -154,7 +148,7 @@ void displayCall()
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective( 45.0f, 1.0f, 1.0f, 20.0f);
gluPerspective(45.0f, 1.0f, 1.0f, 20.0f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
@ -173,19 +167,16 @@ void displayCall()
// Need the actual vertex points from a static cast of the dynamic array but can't get it right
// So use cast and call on a functor that stores that dynamic array into static array we created
vertexArray.Allocate(numberOfInPoints);
vertexArray.Allocate(cellSet.GetNumberOfPoints());
vtkm::cont::CastAndCall(tetDataSet.GetCoordinateSystem(), GetVertexArray());
// Draw the five tetrahedra belonging to each hexadron
vtkm::Id tetra = 0;
vtkm::Float32 color[5][3] =
{
{1.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 1.0f},
{1.0f, 0.0f, 1.0f},
{1.0f, 1.0f, 0.0f}
};
vtkm::Float32 color[5][3] = { { 1.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f },
{ 1.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f, 0.0f } };
for (vtkm::Id hex = 0; hex < cellsToDisplay; hex++)
{
@ -199,13 +190,13 @@ void displayCall()
cellSet.GetIndices(tetra, tetIndices);
// Get the vertex points for this tetrahedron
vtkm::Vec<vtkm::Float64,3> pt0 = vertexArray.GetPortalConstControl().Get(tetIndices[0]);
vtkm::Vec<vtkm::Float64,3> pt1 = vertexArray.GetPortalConstControl().Get(tetIndices[1]);
vtkm::Vec<vtkm::Float64,3> pt2 = vertexArray.GetPortalConstControl().Get(tetIndices[2]);
vtkm::Vec<vtkm::Float64,3> pt3 = vertexArray.GetPortalConstControl().Get(tetIndices[3]);
vtkm::Vec<vtkm::Float64, 3> pt0 = vertexArray.GetPortalConstControl().Get(tetIndices[0]);
vtkm::Vec<vtkm::Float64, 3> pt1 = vertexArray.GetPortalConstControl().Get(tetIndices[1]);
vtkm::Vec<vtkm::Float64, 3> pt2 = vertexArray.GetPortalConstControl().Get(tetIndices[2]);
vtkm::Vec<vtkm::Float64, 3> pt3 = vertexArray.GetPortalConstControl().Get(tetIndices[3]);
// Draw the tetrahedron filled with alternating colors
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBegin(GL_TRIANGLE_STRIP);
glVertex3d(pt0[0], pt0[1], pt0[2]);
glVertex3d(pt1[0], pt1[1], pt1[2]);
@ -217,7 +208,7 @@ void displayCall()
// Draw the tetrahedron wireframe
glColor3f(1.0f, 1.0f, 1.0f);
glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glBegin(GL_TRIANGLE_STRIP);
glVertex3d(pt0[0], pt0[1], pt0[2]);
glVertex3d(pt1[0], pt1[1], pt1[2]);
@ -235,7 +226,6 @@ void displayCall()
glutSwapBuffers();
}
// Allow rotations of the view
void mouseMove(int x, int y)
{
@ -259,15 +249,18 @@ void mouseMove(int x, int y)
glutPostRedisplay();
}
// Respond to mouse button
void mouseCall(int button, int state, int x, int y)
{
if (button == 0) mouse_state = state;
if ((button == 0) && (state == 0)) { lastx = x; lasty = y; }
if (button == 0)
mouse_state = state;
if ((button == 0) && (state == 0))
{
lastx = x;
lasty = y;
}
}
// Tetrahedralize and render uniform grid example
int main(int argc, char* argv[])
{
@ -282,25 +275,18 @@ int main(int argc, char* argv[])
dims[2] = atoi(argv[3]);
cellsToDisplay = dims[0] * dims[1] * dims[2];
}
if (argc == 5) {
if (argc == 5)
{
cellsToDisplay = atoi(argv[4]);
}
// Create the input uniform cell set
vtkm::cont::DataSet inDataSet = MakeTetrahedralizeTestDataSet(dims);
// Set number of cells and vertices in input dataset
numberOfInPoints = (dims[0] + 1) * (dims[1] + 1) * (dims[2] + 1);
vtkm::filter::Tetrahedralize tetrahedralize;
vtkm::filter::ResultDataSet result = tetrahedralize.Execute(inDataSet);
// Create the output dataset explicit cell set with same coordinate system
vtkm::cont::CellSetSingleType<> cellSet("cells");
tetDataSet.AddCellSet(cellSet);
tetDataSet.AddCoordinateSystem(inDataSet.GetCoordinateSystem(0));
// Convert uniform hexahedra to tetrahedra
tetrahedralizeFilter = new vtkm::worklet::TetrahedralizeFilterUniformGrid<DeviceAdapter>
(inDataSet, tetDataSet);
tetrahedralizeFilter->Run();
tetDataSet = result.GetDataSet();
// Render the output dataset of tets
lastx = lasty = 0;
@ -318,12 +304,11 @@ int main(int argc, char* argv[])
glutMouseFunc(mouseCall);
glutMainLoop();
delete tetrahedralizeFilter;
tetDataSet.Clear();
vertexArray.ReleaseResources();
return 0;
}
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#endif

@ -22,36 +22,36 @@
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
#endif
#include <vtkm/worklet/TetrahedralizeExplicitGrid.h>
#include <vtkm/cont/CellSetExplicit.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/DataSetBuilderExplicit.h>
#include <vtkm/filter/Triangulate.h>
#include <vtkm/cont/testing/Testing.h>
//Suppress warnings about glut being deprecated on OSX
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#if defined (__APPLE__)
# include <GLUT/glut.h>
#if defined(__APPLE__)
#include <GLUT/glut.h>
#else
# include <GL/glut.h>
#include <GL/glut.h>
#endif
typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter;
namespace {
namespace
{
// Takes input uniform grid and outputs unstructured grid of triangles
static vtkm::worklet::TetrahedralizeFilterExplicitGrid<DeviceAdapter> *tetrahedralizeFilter;
static vtkm::cont::DataSet outDataSet;
static vtkm::Id numberOfInPoints;
// Point location of vertices from a CastAndCall but needs a static cast eventually
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3> > vertexArray;
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>> vertexArray;
} // anonymous namespace
@ -133,16 +133,14 @@ vtkm::cont::DataSet MakeTriangulateExplicitDataSet()
struct GetVertexArray
{
template <typename ArrayHandleType>
VTKM_CONT
void operator()(ArrayHandleType array) const
VTKM_CONT void operator()(ArrayHandleType array) const
{
this->GetVertexPortal(array.GetPortalConstControl());
}
private:
template <typename PortalType>
VTKM_CONT
void GetVertexPortal(const PortalType &portal) const
VTKM_CONT void GetVertexPortal(const PortalType& portal) const
{
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
{
@ -162,7 +160,6 @@ void initializeGL()
glOrtho(-0.5f, 3.5f, -0.5f, 4.5f, -1.0f, 1.0f);
}
//
// Render the output using simple OpenGL
//
@ -183,13 +180,11 @@ void displayCall()
// Draw the two triangles belonging to each quad
vtkm::Float32 color[4][3] = {
{1.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 1.0f},
{1.0f, 1.0f, 0.0f}
{ 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }
};
for (vtkm::Id triangle = 0; triangle < numberOfCells; triangle++) {
for (vtkm::Id triangle = 0; triangle < numberOfCells; triangle++)
{
vtkm::Id indx = triangle % 4;
glColor3f(color[indx][0], color[indx][1], color[indx][2]);
@ -198,16 +193,16 @@ void displayCall()
cellSet.GetIndices(triangle, triIndices);
// Get the vertex points for this triangle
vtkm::Vec<vtkm::Float64,3> pt0 = vertexArray.GetPortalConstControl().Get(triIndices[0]);
vtkm::Vec<vtkm::Float64,3> pt1 = vertexArray.GetPortalConstControl().Get(triIndices[1]);
vtkm::Vec<vtkm::Float64,3> pt2 = vertexArray.GetPortalConstControl().Get(triIndices[2]);
vtkm::Vec<vtkm::Float64, 3> pt0 = vertexArray.GetPortalConstControl().Get(triIndices[0]);
vtkm::Vec<vtkm::Float64, 3> pt1 = vertexArray.GetPortalConstControl().Get(triIndices[1]);
vtkm::Vec<vtkm::Float64, 3> pt2 = vertexArray.GetPortalConstControl().Get(triIndices[2]);
// Draw the triangle filled with alternating colors
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBegin(GL_TRIANGLES);
glVertex3d(pt0[0], pt0[1], pt0[2]);
glVertex3d(pt1[0], pt1[1], pt1[2]);
glVertex3d(pt2[0], pt2[1], pt2[2]);
glVertex3d(pt0[0], pt0[1], pt0[2]);
glVertex3d(pt1[0], pt1[1], pt1[2]);
glVertex3d(pt2[0], pt2[1], pt2[2]);
glEnd();
}
glFlush();
@ -225,15 +220,10 @@ int main(int argc, char* argv[])
numberOfInPoints = inCellSet.GetNumberOfPoints();
// Create the output dataset explicit cell set with same coordinate system
vtkm::cont::CellSetSingleType<> cellSet("cells");;
outDataSet.AddCellSet(cellSet);
outDataSet.AddCoordinateSystem(inDataSet.GetCoordinateSystem(0));
// Convert 2D explicit cells to triangles
tetrahedralizeFilter = new vtkm::worklet::TetrahedralizeFilterExplicitGrid<DeviceAdapter>
(inDataSet, outDataSet);
tetrahedralizeFilter->Run();
vtkm::filter::Triangulate triangulate;
vtkm::filter::ResultDataSet result = triangulate.Execute(inDataSet);
outDataSet = result.GetDataSet();
// Render the output dataset of tets
glutInit(&argc, argv);
@ -248,12 +238,11 @@ int main(int argc, char* argv[])
glutDisplayFunc(displayCall);
glutMainLoop();
delete tetrahedralizeFilter;
outDataSet.Clear();
vertexArray.ReleaseResources();
return 0;
}
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#endif

@ -22,38 +22,36 @@
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_SERIAL
#endif
#include <vtkm/worklet/TetrahedralizeUniformGrid.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/Math.h>
#include <vtkm/cont/DataSet.h>
#include <vtkm/filter/Triangulate.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/cont/testing/Testing.h>
//Suppress warnings about glut being deprecated on OSX
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
#if defined (__APPLE__)
# include <GLUT/glut.h>
#if defined(__APPLE__)
#include <GLUT/glut.h>
#else
# include <GL/glut.h>
#include <GL/glut.h>
#endif
typedef VTKM_DEFAULT_DEVICE_ADAPTER_TAG DeviceAdapter;
// Default size of the example
static vtkm::Id2 dims(4,4);
static vtkm::Id2 dims(4, 4);
static vtkm::Id cellsToDisplay = 16;
static vtkm::Id numberOfInPoints;
// Takes input uniform grid and outputs unstructured grid of triangles
static vtkm::worklet::TetrahedralizeFilterUniformGrid<DeviceAdapter> *tetrahedralizeFilter;
static vtkm::cont::DataSet tetDataSet;
static vtkm::cont::DataSet triDataSet;
// Point location of vertices from a CastAndCall but needs a static cast eventually
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3> > vertexArray;
static vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float64, 3>> vertexArray;
//
// Construct an input data set with uniform grid of indicated dimensions, origin and spacing
@ -66,14 +64,11 @@ vtkm::cont::DataSet MakeTriangulateTestDataSet(vtkm::Id2 dim)
const vtkm::Id3 vdims(dim[0] + 1, dim[1] + 1, 1);
const vtkm::Vec<vtkm::Float32, 3> origin = vtkm::make_Vec(0.0f, 0.0f, 0.0f);
const vtkm::Vec<vtkm::Float32, 3> spacing = vtkm::make_Vec(
1.0f/static_cast<vtkm::Float32>(dim[0]),
1.0f/static_cast<vtkm::Float32>(dim[1]),
1.0f/static_cast<vtkm::Float32>(dim[2]));
1.0f / static_cast<vtkm::Float32>(dim[0]), 1.0f / static_cast<vtkm::Float32>(dim[1]), 0.0f);
// Generate coordinate system
vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(vdims, origin, spacing);
dataSet.AddCoordinateSystem(
vtkm::cont::CoordinateSystem("coordinates", coordinates));
dataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates));
// Generate cell set
vtkm::cont::CellSetStructured<2> cellSet("cells");
@ -91,16 +86,14 @@ vtkm::cont::DataSet MakeTriangulateTestDataSet(vtkm::Id2 dim)
struct GetVertexArray
{
template <typename ArrayHandleType>
VTKM_CONT
void operator()(ArrayHandleType array) const
VTKM_CONT void operator()(ArrayHandleType array) const
{
this->GetVertexPortal(array.GetPortalConstControl());
}
private:
template <typename PortalType>
VTKM_CONT
void GetVertexPortal(const PortalType &portal) const
VTKM_CONT void GetVertexPortal(const PortalType& portal) const
{
for (vtkm::Id index = 0; index < portal.GetNumberOfValues(); index++)
{
@ -120,7 +113,6 @@ void initializeGL()
glOrtho(-0.5f, 1.5f, -0.5f, 1.5f, -1.0f, 1.0f);
}
//
// Render the output using simple OpenGL
//
@ -131,21 +123,17 @@ void displayCall()
// Get the cellset, coordinate system and coordinate data
vtkm::cont::CellSetSingleType<> cellSet;
tetDataSet.GetCellSet(0).CopyTo(cellSet);
triDataSet.GetCellSet(0).CopyTo(cellSet);
// Need the actual vertex points from a static cast of the dynamic array but can't get it right
// So use cast and call on a functor that stores that dynamic array into static array we created
vertexArray.Allocate(numberOfInPoints);
vtkm::cont::CastAndCall(tetDataSet.GetCoordinateSystem(), GetVertexArray());
vertexArray.Allocate(cellSet.GetNumberOfPoints());
vtkm::cont::CastAndCall(triDataSet.GetCoordinateSystem(), GetVertexArray());
// Draw the two triangles belonging to each quad
vtkm::Id triangle = 0;
vtkm::Float32 color[4][3] =
{
{1.0f, 0.0f, 0.0f},
{0.0f, 1.0f, 0.0f},
{0.0f, 0.0f, 1.0f},
{1.0f, 1.0f, 0.0f}
vtkm::Float32 color[4][3] = {
{ 1.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, { 0.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 0.0f }
};
for (vtkm::Id quad = 0; quad < cellsToDisplay; quad++)
@ -160,16 +148,16 @@ void displayCall()
cellSet.GetIndices(triangle, triIndices);
// Get the vertex points for this triangle
vtkm::Vec<vtkm::Float64,3> pt0 = vertexArray.GetPortalConstControl().Get(triIndices[0]);
vtkm::Vec<vtkm::Float64,3> pt1 = vertexArray.GetPortalConstControl().Get(triIndices[1]);
vtkm::Vec<vtkm::Float64,3> pt2 = vertexArray.GetPortalConstControl().Get(triIndices[2]);
vtkm::Vec<vtkm::Float64, 3> pt0 = vertexArray.GetPortalConstControl().Get(triIndices[0]);
vtkm::Vec<vtkm::Float64, 3> pt1 = vertexArray.GetPortalConstControl().Get(triIndices[1]);
vtkm::Vec<vtkm::Float64, 3> pt2 = vertexArray.GetPortalConstControl().Get(triIndices[2]);
// Draw the triangle filled with alternating colors
glPolygonMode( GL_FRONT_AND_BACK, GL_FILL );
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBegin(GL_TRIANGLES);
glVertex3d(pt0[0], pt0[1], pt0[2]);
glVertex3d(pt1[0], pt1[1], pt1[2]);
glVertex3d(pt2[0], pt2[1], pt2[2]);
glVertex3d(pt0[0], pt0[1], pt0[2]);
glVertex3d(pt1[0], pt1[1], pt1[2]);
glVertex3d(pt2[0], pt2[1], pt2[2]);
glEnd();
triangle++;
@ -178,7 +166,7 @@ void displayCall()
glFlush();
}
// Tetrahedralize and render uniform grid example
// Triangulate and render uniform grid example
int main(int argc, char* argv[])
{
std::cout << "TrianguleUniformGrid Example" << std::endl;
@ -195,20 +183,15 @@ int main(int argc, char* argv[])
{
cellsToDisplay = atoi(argv[3]);
}
numberOfInPoints = (dims[0] + 1) * (dims[1] + 1);
// Create the input uniform cell set
vtkm::cont::DataSet inDataSet = MakeTriangulateTestDataSet(dims);
// Create the output dataset explicit cell set with same coordinate system
vtkm::cont::CellSetSingleType<> cellSet("cells");
tetDataSet.AddCellSet(cellSet);
tetDataSet.AddCoordinateSystem(inDataSet.GetCoordinateSystem(0));
// Convert uniform quad to triangle
vtkm::filter::Triangulate triangulate;
vtkm::filter::ResultDataSet result = triangulate.Execute(inDataSet);
// Convert uniform hexahedra to tetrahedra
tetrahedralizeFilter = new vtkm::worklet::TetrahedralizeFilterUniformGrid<DeviceAdapter>
(inDataSet, tetDataSet);
tetrahedralizeFilter->Run();
triDataSet = result.GetDataSet();
// Render the output dataset of tets
glutInit(&argc, argv);
@ -223,12 +206,11 @@ int main(int argc, char* argv[])
glutDisplayFunc(displayCall);
glutMainLoop();
delete tetrahedralizeFilter;
tetDataSet.Clear();
triDataSet.Clear();
vertexArray.ReleaseResources();
return 0;
}
#if (defined(VTKM_GCC) || defined(VTKM_CLANG))
# pragma GCC diagnostic pop
#pragma GCC diagnostic pop
#endif

@ -21,9 +21,9 @@
#define VTKM_DEVICE_ADAPTER VTKM_DEVICE_ADAPTER_CUDA
#include <vtkm/cont/ArrayHandleStreaming.h>
#include <vtkm/worklet/DispatcherStreamingMapField.h>
#include <vtkm/filter/MarchingCubes.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/DispatcherStreamingMapField.h>
#include <vtkm/Math.h>
#include <vtkm/cont/ArrayHandleCounting.h>
@ -31,8 +31,8 @@
#include <vtkm/cont/DataSet.h>
#include <vtkm/cont/Timer.h>
namespace {
namespace
{
// Define the tangle field for the input data
class TangleField : public vtkm::worklet::WorkletMapField
@ -47,29 +47,40 @@ public:
const vtkm::Id cellsPerLayer;
VTKM_CONT
TangleField(const vtkm::Id3 dims, const vtkm::Float32 mins[3], const vtkm::Float32 maxs[3]) : xdim(dims[0]), ydim(dims[1]), zdim(dims[2]),
xmin(mins[0]), ymin(mins[1]), zmin(mins[2]), xmax(maxs[0]), ymax(maxs[1]), zmax(maxs[2]), cellsPerLayer((xdim) * (ydim)) { };
TangleField(const vtkm::Id3 dims, const vtkm::Float32 mins[3], const vtkm::Float32 maxs[3])
: xdim(dims[0])
, ydim(dims[1])
, zdim(dims[2])
, xmin(mins[0])
, ymin(mins[1])
, zmin(mins[2])
, xmax(maxs[0])
, ymax(maxs[1])
, zmax(maxs[2])
, cellsPerLayer((xdim) * (ydim)){};
VTKM_EXEC
void operator()(const vtkm::Id &vertexId, vtkm::Float32 &v) const
void operator()(const vtkm::Id& vertexId, vtkm::Float32& v) const
{
const vtkm::Id x = vertexId % (xdim);
const vtkm::Id y = (vertexId / (xdim)) % (ydim);
const vtkm::Id z = vertexId / cellsPerLayer;
const vtkm::Float32 fx = static_cast<vtkm::Float32>(x) / static_cast<vtkm::Float32>(xdim-1);
const vtkm::Float32 fy = static_cast<vtkm::Float32>(y) / static_cast<vtkm::Float32>(xdim-1);
const vtkm::Float32 fz = static_cast<vtkm::Float32>(z) / static_cast<vtkm::Float32>(xdim-1);
const vtkm::Float32 fx = static_cast<vtkm::Float32>(x) / static_cast<vtkm::Float32>(xdim - 1);
const vtkm::Float32 fy = static_cast<vtkm::Float32>(y) / static_cast<vtkm::Float32>(xdim - 1);
const vtkm::Float32 fz = static_cast<vtkm::Float32>(z) / static_cast<vtkm::Float32>(xdim - 1);
const vtkm::Float32 xx = 3.0f*(xmin+(xmax-xmin)*(fx));
const vtkm::Float32 yy = 3.0f*(ymin+(ymax-ymin)*(fy));
const vtkm::Float32 zz = 3.0f*(zmin+(zmax-zmin)*(fz));
const vtkm::Float32 xx = 3.0f * (xmin + (xmax - xmin) * (fx));
const vtkm::Float32 yy = 3.0f * (ymin + (ymax - ymin) * (fy));
const vtkm::Float32 zz = 3.0f * (zmin + (zmax - zmin) * (fz));
v = (xx*xx*xx*xx - 5.0f*xx*xx + yy*yy*yy*yy - 5.0f*yy*yy + zz*zz*zz*zz - 5.0f*zz*zz + 11.8f) * 0.2f + 0.5f;
v = (xx * xx * xx * xx - 5.0f * xx * xx + yy * yy * yy * yy - 5.0f * yy * yy +
zz * zz * zz * zz - 5.0f * zz * zz + 11.8f) *
0.2f +
0.5f;
}
};
// Construct an input data set using the tangle field worklet
vtkm::cont::DataSet MakeIsosurfaceTestDataSet(vtkm::Id3 dims)
{
@ -77,24 +88,23 @@ vtkm::cont::DataSet MakeIsosurfaceTestDataSet(vtkm::Id3 dims)
const vtkm::Id3 vdims(dims[0] + 1, dims[1] + 1, dims[2] + 1);
vtkm::Float32 mins[3] = {-1.0f, -1.0f, -1.0f};
vtkm::Float32 maxs[3] = {1.0f, 1.0f, 1.0f};
vtkm::Float32 mins[3] = { -1.0f, -1.0f, -1.0f };
vtkm::Float32 maxs[3] = { 1.0f, 1.0f, 1.0f };
vtkm::cont::ArrayHandle<vtkm::Float32> fieldArray;
vtkm::cont::ArrayHandleCounting<vtkm::Id> vertexCountImplicitArray(0, 1, vdims[0]*vdims[1]*vdims[2]);
vtkm::worklet::DispatcherMapField<TangleField> tangleFieldDispatcher(TangleField(vdims, mins, maxs));
vtkm::cont::ArrayHandleCounting<vtkm::Id> vertexCountImplicitArray(0, 1, vdims[0] * vdims[1] *
vdims[2]);
vtkm::worklet::DispatcherMapField<TangleField> tangleFieldDispatcher(
TangleField(vdims, mins, maxs));
tangleFieldDispatcher.Invoke(vertexCountImplicitArray, fieldArray);
vtkm::Vec<vtkm::FloatDefault,3> origin(0.0f, 0.0f, 0.0f);
vtkm::Vec<vtkm::FloatDefault,3> spacing(
1.0f/static_cast<vtkm::FloatDefault>(dims[0]),
1.0f/static_cast<vtkm::FloatDefault>(dims[2]),
1.0f/static_cast<vtkm::FloatDefault>(dims[1]));
vtkm::Vec<vtkm::FloatDefault, 3> origin(0.0f, 0.0f, 0.0f);
vtkm::Vec<vtkm::FloatDefault, 3> spacing(1.0f / static_cast<vtkm::FloatDefault>(dims[0]),
1.0f / static_cast<vtkm::FloatDefault>(dims[2]),
1.0f / static_cast<vtkm::FloatDefault>(dims[1]));
vtkm::cont::ArrayHandleUniformPointCoordinates
coordinates(vdims, origin, spacing);
dataSet.AddCoordinateSystem(
vtkm::cont::CoordinateSystem("coordinates", coordinates));
vtkm::cont::ArrayHandleUniformPointCoordinates coordinates(vdims, origin, spacing);
dataSet.AddCoordinateSystem(vtkm::cont::CoordinateSystem("coordinates", coordinates));
dataSet.AddField(vtkm::cont::Field("nodevar", vtkm::cont::Field::ASSOC_POINTS, fieldArray));
@ -105,10 +115,8 @@ vtkm::cont::DataSet MakeIsosurfaceTestDataSet(vtkm::Id3 dims)
return dataSet;
}
}
namespace vtkm
{
namespace worklet
@ -120,26 +128,26 @@ public:
typedef _2 ExecutionSignature(_1, WorkIndex);
VTKM_EXEC
vtkm::Float32 operator()(vtkm::Int64 x, vtkm::Id& index) const {
return (vtkm::Sin(1.0*x));
}
vtkm::Float32 operator()(vtkm::Int64 x, vtkm::Id& index) const { return (vtkm::Sin(1.0 * x)); }
};
}
}
// Run a simple worklet, and compute an isosurface
int main(int argc, char* argv[])
{
vtkm::Int64 N = 1024*1024*1024;
if (argc > 1) N = N*atoi(argv[1]);
else N = N*4;
vtkm::Int64 N = 1024 * 1024 * 1024;
if (argc > 1)
N = N * atoi(argv[1]);
else
N = N * 4;
std::cout << "Testing streaming worklet with size " << N << std::endl;
vtkm::cont::ArrayHandle<vtkm::Int64> input;
vtkm::cont::ArrayHandle<vtkm::Float32> output;
std::vector<vtkm::Int64> data(N);
for (vtkm::Int64 i=0; i<N; i++) data[i] = i;
std::vector<vtkm::Int64> data(N);
for (vtkm::Int64 i = 0; i < N; i++)
data[i] = i;
input = vtkm::cont::make_ArrayHandle(data);
typedef vtkm::cont::DeviceAdapterAlgorithm<VTKM_DEFAULT_DEVICE_ADAPTER_TAG> DeviceAlgorithms;
@ -148,30 +156,29 @@ int main(int argc, char* argv[])
#ifdef VTKM_USE_UNIFIED_MEMORY
std::cout << "Testing with unified memory" << std::endl;
vtkm::worklet::DispatcherMapField<vtkm::worklet::SineWorklet>
dispatcher(sineWorklet);
vtkm::worklet::DispatcherMapField<vtkm::worklet::SineWorklet> dispatcher(sineWorklet);
vtkm::cont::Timer<> timer;
dispatcher.Invoke(input, output);
std::cout << output.GetPortalConstControl().Get(output.GetNumberOfValues()-1) << std::endl;
std::cout << output.GetPortalConstControl().Get(output.GetNumberOfValues() - 1) << std::endl;
vtkm::Float64 elapsedTime = timer.GetElapsedTime();
std::cout << "Time: " << elapsedTime << std::endl;
#else
vtkm::worklet::DispatcherStreamingMapField<vtkm::worklet::SineWorklet>
dispatcher(sineWorklet);
vtkm::Id NBlocks = N/(1024*1024*1024);
vtkm::worklet::DispatcherStreamingMapField<vtkm::worklet::SineWorklet> dispatcher(sineWorklet);
vtkm::Id NBlocks = N / (1024 * 1024 * 1024);
NBlocks *= 2;
dispatcher.SetNumberOfBlocks(NBlocks);
std::cout << "Testing with streaming (without unified memory) with " << NBlocks << " blocks" << std::endl;
std::cout << "Testing with streaming (without unified memory) with " << NBlocks << " blocks"
<< std::endl;
vtkm::cont::Timer<> timer;
dispatcher.Invoke(input, output);
std::cout << output.GetPortalConstControl().Get(output.GetNumberOfValues()-1) << std::endl;
std::cout << output.GetPortalConstControl().Get(output.GetNumberOfValues() - 1) << std::endl;
vtkm::Float64 elapsedTime = timer.GetElapsedTime();
std::cout << "Time: " << elapsedTime << std::endl;
@ -179,32 +186,33 @@ int main(int argc, char* argv[])
#endif
int dim = 128;
if (argc > 2) dim = atoi(argv[2]);
if (argc > 2)
dim = atoi(argv[2]);
std::cout << "Testing Marching Cubes with size " << dim << "x" << dim << "x" << dim << std::endl;
vtkm::Id3 dims(dim, dim, dim);
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32,3> > verticesArray, normalsArray;
vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>> verticesArray, normalsArray;
vtkm::cont::ArrayHandle<vtkm::Float32> scalarsArray;
vtkm::cont::DataSet dataSet = MakeIsosurfaceTestDataSet(dims);
vtkm::filter::MarchingCubes filter;
filter.SetGenerateNormals(true);
filter.SetMergeDuplicatePoints( false );
filter.SetIsoValue( 0.5 );
vtkm::filter::ResultDataSet result =
filter.Execute( dataSet, dataSet.GetField("nodevar") );
filter.SetMergeDuplicatePoints(false);
filter.SetIsoValue(0.5);
vtkm::filter::ResultDataSet result = filter.Execute(dataSet, dataSet.GetField("nodevar"));
filter.MapFieldOntoOutput(result, dataSet.GetField("nodevar"));
//need to extract vertices, normals, and scalars
vtkm::cont::DataSet& outputData = result.GetDataSet();
typedef vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32,3> > VertType;
typedef vtkm::cont::ArrayHandle<vtkm::Vec<vtkm::Float32, 3>> VertType;
vtkm::cont::CoordinateSystem coords = outputData.GetCoordinateSystem();
verticesArray = coords.GetData().Cast<VertType>();
normalsArray = outputData.GetField("normals").GetData().Cast<VertType>();
scalarsArray = outputData.GetField("nodevar").GetData().Cast< vtkm::cont::ArrayHandle<vtkm::Float32> >();
scalarsArray =
outputData.GetField("nodevar").GetData().Cast<vtkm::cont::ArrayHandle<vtkm::Float32>>();
std::cout << "Number of output vertices: " << verticesArray.GetNumberOfValues() << std::endl;
@ -220,4 +228,3 @@ int main(int argc, char* argv[])
return 0;
}

2
vtkm/.gitattributes vendored Normal file

@ -0,0 +1,2 @@
# Generated.
TypeListTag.h -format.clang-format

@ -37,11 +37,9 @@
/// for the possibility that the condition is never evaluated.
///
#if !defined(NDEBUG)
#define VTKM_ASSERT(condition) \
assert(condition)
#define VTKM_ASSERT(condition) assert(condition)
#else
#define VTKM_ASSERT(condition)
#endif
#endif //vtk_m_Assert_h

@ -20,37 +20,38 @@
#ifndef vtk_m_BaseComponent_h
#define vtk_m_BaseComponent_h
#include <vtkm/Matrix.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/VecTraits.h>
namespace vtkm {
namespace vtkm
{
namespace detail {
namespace detail
{
template<typename VecType, typename DimensionalityTag>
template <typename VecType, typename DimensionalityTag>
struct BaseComponentImpl;
template<typename VecType>
template <typename VecType>
struct BaseComponentImpl<VecType, vtkm::TypeTraitsVectorTag>
{
private:
using ComponentType = typename vtkm::VecTraits<VecType>::ComponentType;
public:
using Type =
typename BaseComponentImpl<
ComponentType,
typename vtkm::TypeTraits<ComponentType>::DimensionalityTag
>::Type;
typename BaseComponentImpl<ComponentType,
typename vtkm::TypeTraits<ComponentType>::DimensionalityTag>::Type;
};
template<typename VecType>
template <typename VecType>
struct BaseComponentImpl<VecType, vtkm::TypeTraitsMatrixTag>
: BaseComponentImpl<VecType, vtkm::TypeTraitsVectorTag>
{ };
{
};
template<typename ScalarType>
template <typename ScalarType>
struct BaseComponentImpl<ScalarType, vtkm::TypeTraitsScalarTag>
{
using Type = ScalarType;
@ -60,13 +61,12 @@ struct BaseComponentImpl<ScalarType, vtkm::TypeTraitsScalarTag>
// Finds the base component type of a Vec. If you have a Vec of Vecs, it will
// descend all Vecs until you get to the scalar type.
template<typename VecType>
template <typename VecType>
struct BaseComponent
{
using Type =
typename detail::BaseComponentImpl<
VecType,
typename vtkm::TypeTraits<VecType>::DimensionalityTag>::Type;
typename detail::BaseComponentImpl<VecType,
typename vtkm::TypeTraits<VecType>::DimensionalityTag>::Type;
};
} // namespace vtkm

@ -20,10 +20,11 @@
#ifndef vtk_m_BinaryOperators_h
#define vtk_m_BinaryOperators_h
#include <vtkm/internal/ExportMacros.h>
#include <vtkm/Math.h>
#include <vtkm/internal/ExportMacros.h>
namespace vtkm {
namespace vtkm
{
// Disable conversion warnings for Sum and Product on GCC only.
// GCC creates false positive warnings for signed/unsigned char* operations.
@ -41,7 +42,7 @@ namespace vtkm {
/// Note: Requires Type \p T implement the + operator.
struct Sum
{
template<typename T>
template <typename T>
VTKM_EXEC_CONT T operator()(const T& x, const T& y) const
{
return x + y;
@ -53,7 +54,7 @@ struct Sum
/// Note: Requires Type \p T implement the * operator.
struct Product
{
template<typename T>
template <typename T>
VTKM_EXEC_CONT T operator()(const T& x, const T& y) const
{
return x * y;
@ -64,17 +65,16 @@ struct Product
#pragma GCC diagnostic pop
#endif // gcc || clang
/// Binary Predicate that takes two arguments argument \c x, and \c y and
/// returns the \c x if x > y otherwise returns \c y.
/// Note: Requires Type \p T implement the < operator.
//needs to be full length to not clash with vtkm::math function Max.
struct Maximum
{
template<typename T>
template <typename T>
VTKM_EXEC_CONT T operator()(const T& x, const T& y) const
{
return x < y ? y: x;
return x < y ? y : x;
}
};
@ -84,14 +84,13 @@ struct Maximum
//needs to be full length to not clash with vtkm::math function Min.
struct Minimum
{
template<typename T>
template <typename T>
VTKM_EXEC_CONT T operator()(const T& x, const T& y) const
{
return x < y ? x: y;
return x < y ? x : y;
}
};
/// Binary Predicate that takes two arguments argument \c x, and \c y and
/// returns a vtkm::Vec<T,2> that represents the minimum and maximum values
/// Note: Requires Type \p T implement the vtkm::Min and vtkm::Max functions.
@ -99,27 +98,25 @@ template <typename T>
struct MinAndMax
{
VTKM_EXEC_CONT
vtkm::Vec<T,2> operator()(const T& a, const T& b) const
vtkm::Vec<T, 2> operator()(const T& a, const T& b) const
{
return vtkm::make_Vec(vtkm::Min(a, b), vtkm::Max(a, b));
}
VTKM_EXEC_CONT
vtkm::Vec<T,2> operator()(
const vtkm::Vec<T,2>& a, const vtkm::Vec<T,2>& b) const
vtkm::Vec<T, 2> operator()(const vtkm::Vec<T, 2>& a, const vtkm::Vec<T, 2>& b) const
{
return vtkm::make_Vec(
vtkm::Min(a[0], b[0]), vtkm::Max(a[1], b[1]));
return vtkm::make_Vec(vtkm::Min(a[0], b[0]), vtkm::Max(a[1], b[1]));
}
VTKM_EXEC_CONT
vtkm::Vec<T,2> operator()(const T& a, const vtkm::Vec<T,2>& b) const
vtkm::Vec<T, 2> operator()(const T& a, const vtkm::Vec<T, 2>& b) const
{
return vtkm::make_Vec(vtkm::Min(a, b[0]), vtkm::Max(a, b[1]));
}
VTKM_EXEC_CONT
vtkm::Vec<T,2> operator()(const vtkm::Vec<T,2>& a, const T& b) const
vtkm::Vec<T, 2> operator()(const vtkm::Vec<T, 2>& a, const T& b) const
{
return vtkm::make_Vec(vtkm::Min(a[0], b), vtkm::Max(a[1], b));
}
@ -130,7 +127,7 @@ struct MinAndMax
/// Note: Requires Type \p T implement the & operator.
struct BitwiseAnd
{
template<typename T>
template <typename T>
VTKM_EXEC_CONT T operator()(const T& x, const T& y) const
{
return x & y;
@ -142,7 +139,7 @@ struct BitwiseAnd
/// Note: Requires Type \p T implement the | operator.
struct BitwiseOr
{
template<typename T>
template <typename T>
VTKM_EXEC_CONT T operator()(const T& x, const T& y) const
{
return x | y;
@ -154,14 +151,13 @@ struct BitwiseOr
/// Note: Requires Type \p T implement the ^ operator.
struct BitwiseXor
{
template<typename T>
template <typename T>
VTKM_EXEC_CONT T operator()(const T& x, const T& y) const
{
return x ^ y;
}
};
} // namespace vtkm
#endif //vtk_m_BinaryOperators_h

@ -22,14 +22,15 @@
#include <vtkm/internal/ExportMacros.h>
namespace vtkm {
namespace vtkm
{
/// Binary Predicate that takes two arguments argument \c x, and \c y and
/// returns True if and only if \c x is equal to \c y.
/// Note: Requires Type \p T implement the == operator.
struct Equal
{
template<typename T>
template <typename T>
VTKM_EXEC_CONT bool operator()(const T& x, const T& y) const
{
return x == y;
@ -41,7 +42,7 @@ struct Equal
/// Note: Requires Type \p T implement the != operator.
struct NotEqual
{
template<typename T>
template <typename T>
VTKM_EXEC_CONT bool operator()(const T& x, const T& y) const
{
return x != y;
@ -53,7 +54,7 @@ struct NotEqual
/// Note: Requires Type \p T implement the < operator.
struct SortLess
{
template<typename T>
template <typename T>
VTKM_EXEC_CONT bool operator()(const T& x, const T& y) const
{
return x < y;
@ -66,7 +67,7 @@ struct SortLess
/// comparison
struct SortGreater
{
template<typename T>
template <typename T>
VTKM_EXEC_CONT bool operator()(const T& x, const T& y) const
{
return y < x;
@ -79,7 +80,7 @@ struct SortGreater
/// && operator.
struct LogicalAnd
{
template<typename T>
template <typename T>
VTKM_EXEC_CONT bool operator()(const T& x, const T& y) const
{
return x && y;
@ -92,7 +93,7 @@ struct LogicalAnd
/// || operator.
struct LogicalOr
{
template<typename T>
template <typename T>
VTKM_EXEC_CONT bool operator()(const T& x, const T& y) const
{
return x || y;

@ -23,7 +23,8 @@
#include <vtkm/Range.h>
namespace vtkm {
namespace vtkm
{
/// \brief Represent an axis-aligned 3D bounds in space.
///
@ -42,53 +43,53 @@ struct Bounds
vtkm::Range Z;
VTKM_EXEC_CONT
Bounds() { }
Bounds() {}
VTKM_EXEC_CONT
Bounds(const vtkm::Range &xRange,
const vtkm::Range &yRange,
const vtkm::Range &zRange)
: X(xRange), Y(yRange), Z(zRange) { }
Bounds(const vtkm::Range& xRange, const vtkm::Range& yRange, const vtkm::Range& zRange)
: X(xRange)
, Y(yRange)
, Z(zRange)
{
}
template<typename T1,
typename T2,
typename T3,
typename T4,
typename T5,
typename T6>
VTKM_EXEC_CONT
Bounds(const T1 &minX, const T2 &maxX,
const T3 &minY, const T4 &maxY,
const T5 &minZ, const T6 &maxZ)
: X(vtkm::Range(minX, maxX)),
Y(vtkm::Range(minY, maxY)),
Z(vtkm::Range(minZ, maxZ))
{ }
template <typename T1, typename T2, typename T3, typename T4, typename T5, typename T6>
VTKM_EXEC_CONT Bounds(const T1& minX,
const T2& maxX,
const T3& minY,
const T4& maxY,
const T5& minZ,
const T6& maxZ)
: X(vtkm::Range(minX, maxX))
, Y(vtkm::Range(minY, maxY))
, Z(vtkm::Range(minZ, maxZ))
{
}
/// Initialize bounds with an array of 6 values in the order xmin, xmax,
/// ymin, ymax, zmin, zmax.
///
template<typename T>
VTKM_EXEC_CONT
explicit Bounds(const T bounds[6])
: X(vtkm::Range(bounds[0], bounds[1])),
Y(vtkm::Range(bounds[2], bounds[3])),
Z(vtkm::Range(bounds[4], bounds[5]))
{ }
template <typename T>
VTKM_EXEC_CONT explicit Bounds(const T bounds[6])
: X(vtkm::Range(bounds[0], bounds[1]))
, Y(vtkm::Range(bounds[2], bounds[3]))
, Z(vtkm::Range(bounds[4], bounds[5]))
{
}
/// Initialize bounds with the minimum corner point and the maximum corner
/// point.
///
template<typename T>
VTKM_EXEC_CONT
Bounds(const vtkm::Vec<T,3> &minPoint, const vtkm::Vec<T,3> &maxPoint)
: X(vtkm::Range(minPoint[0], maxPoint[0])),
Y(vtkm::Range(minPoint[1], maxPoint[1])),
Z(vtkm::Range(minPoint[2], maxPoint[2]))
{ }
template <typename T>
VTKM_EXEC_CONT Bounds(const vtkm::Vec<T, 3>& minPoint, const vtkm::Vec<T, 3>& maxPoint)
: X(vtkm::Range(minPoint[0], maxPoint[0]))
, Y(vtkm::Range(minPoint[1], maxPoint[1]))
, Z(vtkm::Range(minPoint[2], maxPoint[2]))
{
}
VTKM_EXEC_CONT
const vtkm::Bounds &operator=(const vtkm::Bounds &src)
const vtkm::Bounds& operator=(const vtkm::Bounds& src)
{
this->X = src.X;
this->Y = src.Y;
@ -105,20 +106,15 @@ struct Bounds
VTKM_EXEC_CONT
bool IsNonEmpty() const
{
return (this->X.IsNonEmpty() &&
this->Y.IsNonEmpty() &&
this->Z.IsNonEmpty());
return (this->X.IsNonEmpty() && this->Y.IsNonEmpty() && this->Z.IsNonEmpty());
}
/// \b Determines if a point coordinate is within the bounds.
///
template<typename T>
VTKM_EXEC_CONT
bool Contains(const vtkm::Vec<T,3> &point) const
template <typename T>
VTKM_EXEC_CONT bool Contains(const vtkm::Vec<T, 3>& point) const
{
return (this->X.Contains(point[0]) &&
this->Y.Contains(point[1]) &&
this->Z.Contains(point[2]));
return (this->X.Contains(point[0]) && this->Y.Contains(point[1]) && this->Z.Contains(point[2]));
}
/// \b Returns the center of the range.
@ -127,11 +123,9 @@ struct Bounds
/// are empty, the results are undefined.
///
VTKM_EXEC_CONT
vtkm::Vec<vtkm::Float64,3> Center() const
vtkm::Vec<vtkm::Float64, 3> Center() const
{
return vtkm::Vec<vtkm::Float64,3>(this->X.Center(),
this->Y.Center(),
this->Z.Center());
return vtkm::Vec<vtkm::Float64, 3>(this->X.Center(), this->Y.Center(), this->Z.Center());
}
/// \b Expand bounds to include a point.
@ -140,9 +134,8 @@ struct Bounds
/// given point coordinates. If the bounds already include this point, then
/// nothing is done.
///
template<typename T>
VTKM_EXEC_CONT
void Include(const vtkm::Vec<T,3> &point)
template <typename T>
VTKM_EXEC_CONT void Include(const vtkm::Vec<T, 3>& point)
{
this->X.Include(point[0]);
this->Y.Include(point[1]);
@ -155,7 +148,7 @@ struct Bounds
/// that of another bounds. Esentially it is the union of the two bounds.
///
VTKM_EXEC_CONT
void Include(const vtkm::Bounds &bounds)
void Include(const vtkm::Bounds& bounds)
{
this->X.Include(bounds.X);
this->Y.Include(bounds.Y);
@ -167,7 +160,7 @@ struct Bounds
/// This is a nondestructive form of \c Include.
///
VTKM_EXEC_CONT
vtkm::Bounds Union(const vtkm::Bounds &otherBounds) const
vtkm::Bounds Union(const vtkm::Bounds& otherBounds) const
{
vtkm::Bounds unionBounds(*this);
unionBounds.Include(otherBounds);
@ -177,25 +170,18 @@ struct Bounds
/// \b Operator for union
///
VTKM_EXEC_CONT
vtkm::Bounds operator+(const vtkm::Bounds &otherBounds) const
vtkm::Bounds operator+(const vtkm::Bounds& otherBounds) const { return this->Union(otherBounds); }
VTKM_EXEC_CONT
bool operator==(const vtkm::Bounds& bounds) const
{
return this->Union(otherBounds);
return ((this->X == bounds.X) && (this->Y == bounds.Y) && (this->Z == bounds.Z));
}
VTKM_EXEC_CONT
bool operator==(const vtkm::Bounds &bounds) const
bool operator!=(const vtkm::Bounds& bounds) const
{
return ((this->X == bounds.X) &&
(this->Y == bounds.Y) &&
(this->Z == bounds.Z));
}
VTKM_EXEC_CONT
bool operator!=(const vtkm::Bounds &bounds) const
{
return ((this->X != bounds.X) ||
(this->Y != bounds.Y) ||
(this->Z != bounds.Z));
return ((this->X != bounds.X) || (this->Y != bounds.Y) || (this->Z != bounds.Z));
}
};
@ -203,12 +189,9 @@ struct Bounds
/// Helper function for printing bounds during testing
///
static inline VTKM_CONT
std::ostream &operator<<(std::ostream &stream, const vtkm::Bounds &bounds)
static inline VTKM_CONT std::ostream& operator<<(std::ostream& stream, const vtkm::Bounds& bounds)
{
return stream << "{ X:" << bounds.X
<< ", Y:" << bounds.Y
<< ", Z:" << bounds.Z << " }";
return stream << "{ X:" << bounds.X << ", Y:" << bounds.Y << ", Z:" << bounds.Z << " }";
}
#endif //vtk_m_Bounds_h

@ -34,22 +34,23 @@ set(headers
Bounds.h
CellShape.h
CellTraits.h
ImplicitFunctions.h
ListTag.h
Math.h
Matrix.h
NewtonsMethod.h
Pair.h
Range.h
RangeId.h
RangeId3.h
StaticAssert.h
TopologyElementTag.h
Transform3D.h
TypeListTag.h
Types.h
TypeTraits.h
VecAxisAlignedPointCoordinates.h
VecFromPortal.h
VecFromPortalPermute.h
VecRectilinearPointCoordinates.h
VectorAnalysis.h
VecTraits.h
VecVariable.h

@ -23,7 +23,8 @@
#include <vtkm/StaticAssert.h>
#include <vtkm/Types.h>
namespace vtkm {
namespace vtkm
{
/// CellShapeId identifies the type of each cell. Currently these are designed
/// to match up with VTK cell types.
@ -31,21 +32,21 @@ namespace vtkm {
enum CellShapeIdEnum
{
// Linear cells
CELL_SHAPE_EMPTY = 0,
CELL_SHAPE_VERTEX = 1,
CELL_SHAPE_EMPTY = 0,
CELL_SHAPE_VERTEX = 1,
//CELL_SHAPE_POLY_VERTEX = 2,
CELL_SHAPE_LINE = 3,
CELL_SHAPE_LINE = 3,
//CELL_SHAPE_POLY_LINE = 4,
CELL_SHAPE_TRIANGLE = 5,
CELL_SHAPE_TRIANGLE = 5,
//CELL_SHAPE_TRIANGLE_STRIP = 6,
CELL_SHAPE_POLYGON = 7,
CELL_SHAPE_POLYGON = 7,
//CELL_SHAPE_PIXEL = 8,
CELL_SHAPE_QUAD = 9,
CELL_SHAPE_TETRA = 10,
CELL_SHAPE_QUAD = 9,
CELL_SHAPE_TETRA = 10,
//CELL_SHAPE_VOXEL = 11,
CELL_SHAPE_HEXAHEDRON = 12,
CELL_SHAPE_WEDGE = 13,
CELL_SHAPE_PYRAMID = 14,
CELL_SHAPE_HEXAHEDRON = 12,
CELL_SHAPE_WEDGE = 13,
CELL_SHAPE_PYRAMID = 14,
NUMBER_OF_CELL_SHAPES
};
@ -56,13 +57,16 @@ enum CellShapeIdEnum
// There are also many other cell-specific features that code might expect such
// as \c CellTraits and interpolations.
namespace internal {
namespace internal
{
/// A class that can be used to determine if a class is a CellShapeTag or not.
/// The class will be either std::true_type or std::false_type.
///
template<typename T>
struct CellShapeTagCheck : std::false_type { };
template <typename T>
struct CellShapeTagCheck : std::false_type
{
};
} // namespace internal
@ -70,15 +74,15 @@ struct CellShapeTagCheck : std::false_type { };
/// concept check to make sure that a template argument is a proper cell shape
/// tag.
///
#define VTKM_IS_CELL_SHAPE_TAG(tag) \
VTKM_STATIC_ASSERT_MSG( \
::vtkm::internal::CellShapeTagCheck<tag>::value, \
"Provided type is not a valid VTK-m cell shape tag.")
#define VTKM_IS_CELL_SHAPE_TAG(tag) \
VTKM_STATIC_ASSERT_MSG(::vtkm::internal::CellShapeTagCheck<tag>::value, \
"Provided type is not a valid VTK-m cell shape tag.")
/// A traits-like class to get an CellShapeId known at compile time to a tag.
///
template<vtkm::IdComponent Id>
struct CellShapeIdToTag {
template <vtkm::IdComponent Id>
struct CellShapeIdToTag
{
// If you get a compile error for this class about Id not being defined, that
// probably means you are using an ID that does not have a defined cell
// shape.
@ -86,29 +90,32 @@ struct CellShapeIdToTag {
typedef std::false_type valid;
};
// Define a tag for each cell shape as well as the support structs to go
// between tags and ids. The following macro is only valid here.
#define VTKM_DEFINE_CELL_TAG(name, idname) \
struct CellShapeTag ## name { \
static const vtkm::UInt8 Id = vtkm::idname; \
}; \
namespace internal { \
template<> \
struct CellShapeTagCheck<vtkm::CellShapeTag ## name> : std::true_type { }; \
} \
static inline VTKM_EXEC_CONT \
const char *GetCellShapeName(vtkm::CellShapeTag ## name) { \
return #name; \
} \
template<> \
struct CellShapeIdToTag<vtkm::idname> { \
typedef std::true_type valid; \
typedef vtkm::CellShapeTag ## name Tag; \
#define VTKM_DEFINE_CELL_TAG(name, idname) \
struct CellShapeTag##name \
{ \
static const vtkm::UInt8 Id = vtkm::idname; \
}; \
namespace internal \
{ \
template <> \
struct CellShapeTagCheck<vtkm::CellShapeTag##name> : std::true_type \
{ \
}; \
} \
static inline VTKM_EXEC_CONT const char* GetCellShapeName(vtkm::CellShapeTag##name) \
{ \
return #name; \
} \
template <> \
struct CellShapeIdToTag<vtkm::idname> \
{ \
typedef std::true_type valid; \
typedef vtkm::CellShapeTag##name Tag; \
}
VTKM_DEFINE_CELL_TAG(Empty, CELL_SHAPE_EMPTY);
VTKM_DEFINE_CELL_TAG(Vertex, CELL_SHAPE_VERTEX);
//VTKM_DEFINE_CELL_TAG(PolyVertex, CELL_SHAPE_POLY_VERTEX);
@ -127,28 +134,29 @@ VTKM_DEFINE_CELL_TAG(Pyramid, CELL_SHAPE_PYRAMID);
#undef VTKM_DEFINE_CELL_TAG
/// A special cell shape tag that holds a cell shape that is not known at
/// compile time. Unlike other cell set tags, the Id field is set at runtime
/// so its value cannot be used in template parameters. You need to use
/// \c vtkmGenericCellShapeMacro to specialize on the cell type.
///
struct CellShapeTagGeneric {
struct CellShapeTagGeneric
{
VTKM_EXEC_CONT
CellShapeTagGeneric(vtkm::UInt8 shape) : Id(shape) { }
CellShapeTagGeneric(vtkm::UInt8 shape)
: Id(shape)
{
}
vtkm::UInt8 Id;
};
#define vtkmGenericCellShapeMacroCase(cellShapeId, call) \
case vtkm::cellShapeId: \
{ \
typedef \
vtkm::CellShapeIdToTag<vtkm::cellShapeId>::Tag CellShapeTag; \
call; \
} \
break
#define vtkmGenericCellShapeMacroCase(cellShapeId, call) \
case vtkm::cellShapeId: \
{ \
typedef vtkm::CellShapeIdToTag<vtkm::cellShapeId>::Tag CellShapeTag; \
call; \
} \
break
/// \brief A macro used in a \c switch statement to determine cell shape.
///
@ -180,16 +188,16 @@ struct CellShapeTagGeneric {
/// Note that \c vtkmGenericCellShapeMacro does not have a default case. You
/// should consider adding one that gives a
///
#define vtkmGenericCellShapeMacro(call) \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_EMPTY, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_VERTEX, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_LINE, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_TRIANGLE, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_POLYGON, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_QUAD, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_TETRA, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_HEXAHEDRON, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_WEDGE, call); \
#define vtkmGenericCellShapeMacro(call) \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_EMPTY, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_VERTEX, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_LINE, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_TRIANGLE, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_POLYGON, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_QUAD, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_TETRA, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_HEXAHEDRON, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_WEDGE, call); \
vtkmGenericCellShapeMacroCase(CELL_SHAPE_PYRAMID, call)
} // namespace vtkm

@ -22,22 +22,29 @@
#include <vtkm/CellShape.h>
namespace vtkm {
namespace vtkm
{
/// \c vtkm::CellTraits::TopologyDimensionType is typedef to this with the
/// template parameter set to \c TOPOLOGICAL_DIMENSIONS. See \c
/// vtkm::CellTraits for more information.
///
template<vtkm::IdComponent dimension>
struct CellTopologicalDimensionsTag { };
template <vtkm::IdComponent dimension>
struct CellTopologicalDimensionsTag
{
};
/// \brief Tag for cell shapes with a fixed number of points.
///
struct CellTraitsTagSizeFixed { };
struct CellTraitsTagSizeFixed
{
};
/// \brief Tag for cell shapes that can have a variable number of points.
///
struct CellTraitsTagSizeVariable { };
struct CellTraitsTagSizeVariable
{
};
/// \brief Information about a cell based on its tag.
///
@ -45,7 +52,7 @@ struct CellTraitsTagSizeVariable { };
/// about cells (like the number of vertices in the cell or its
/// dimensionality).
///
template<class CellTag>
template <class CellTag>
struct CellTraits
#ifdef VTKM_DOXYGEN_ONLY
{
@ -59,8 +66,7 @@ struct CellTraits
/// a convenient way to overload a function based on topological dimensions
/// (which is usually more efficient than conditionals).
///
typedef vtkm::CellTopologicalDimensionsTag<TOPOLOGICAL_DIMENSIONS>
TopologicalDimensionsTag;
typedef vtkm::CellTopologicalDimensionsTag<TOPOLOGICAL_DIMENSIONS> TopologicalDimensionsTag;
/// \brief A tag specifying whether the number of points is fixed.
///
@ -77,31 +83,31 @@ struct CellTraits
///
static const vtkm::IdComponent NUM_POINTS = 3;
};
#else // VTKM_DOXYGEN_ONLY
;
#else // VTKM_DOXYGEN_ONLY
;
#endif // VTKM_DOXYGEN_ONLY
//-----------------------------------------------------------------------------
// Define traits for every cell type.
#define VTKM_DEFINE_CELL_TRAITS(name, dimensions, numPoints) \
template<> \
struct CellTraits<vtkm::CellShapeTag ## name> { \
const static vtkm::IdComponent TOPOLOGICAL_DIMENSIONS = dimensions; \
typedef vtkm::CellTopologicalDimensionsTag<TOPOLOGICAL_DIMENSIONS> \
TopologicalDimensionsTag; \
typedef vtkm::CellTraitsTagSizeFixed IsSizeFixed; \
static const vtkm::IdComponent NUM_POINTS = numPoints; \
#define VTKM_DEFINE_CELL_TRAITS(name, dimensions, numPoints) \
template <> \
struct CellTraits<vtkm::CellShapeTag##name> \
{ \
const static vtkm::IdComponent TOPOLOGICAL_DIMENSIONS = dimensions; \
typedef vtkm::CellTopologicalDimensionsTag<TOPOLOGICAL_DIMENSIONS> TopologicalDimensionsTag; \
typedef vtkm::CellTraitsTagSizeFixed IsSizeFixed; \
static const vtkm::IdComponent NUM_POINTS = numPoints; \
}
#define VTKM_DEFINE_CELL_TRAITS_VARIABLE(name, dimensions) \
template<> \
struct CellTraits<vtkm::CellShapeTag ## name> { \
const static vtkm::IdComponent TOPOLOGICAL_DIMENSIONS = dimensions; \
typedef vtkm::CellTopologicalDimensionsTag<TOPOLOGICAL_DIMENSIONS> \
TopologicalDimensionsTag; \
typedef vtkm::CellTraitsTagSizeVariable IsSizeFixed; \
#define VTKM_DEFINE_CELL_TRAITS_VARIABLE(name, dimensions) \
template <> \
struct CellTraits<vtkm::CellShapeTag##name> \
{ \
const static vtkm::IdComponent TOPOLOGICAL_DIMENSIONS = dimensions; \
typedef vtkm::CellTopologicalDimensionsTag<TOPOLOGICAL_DIMENSIONS> TopologicalDimensionsTag; \
typedef vtkm::CellTraitsTagSizeVariable IsSizeFixed; \
}
VTKM_DEFINE_CELL_TRAITS(Empty, 0, 0);

@ -1,221 +0,0 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2014 Sandia Corporation.
// Copyright 2014 UT-Battelle, LLC.
// Copyright 2014 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_ImplicitFunctions_h
#define vtk_m_ImplicitFunctions_h
#include <vtkm/Types.h>
#include <iostream>
namespace vtkm {
/// \brief Implicit function for a plane
class Plane
{
public:
VTKM_CONT
Plane()
: Origin(FloatDefault(0)),
Normal(FloatDefault(0), FloatDefault(0), FloatDefault(1))
{ }
VTKM_CONT
explicit Plane(const vtkm::Vec<FloatDefault, 3> &normal)
: Origin(FloatDefault(0)),
Normal(normal)
{ }
VTKM_CONT
Plane(const vtkm::Vec<FloatDefault, 3> &origin,
const vtkm::Vec<FloatDefault, 3> &normal)
: Origin(origin), Normal(normal)
{ }
VTKM_EXEC_CONT
const vtkm::Vec<FloatDefault, 3>& GetOrigin() const
{
return this->Origin;
}
VTKM_EXEC_CONT
const vtkm::Vec<FloatDefault, 3>& GetNormal() const
{
return this->Normal;
}
VTKM_EXEC_CONT
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return ((x - this->Origin[0]) * this->Normal[0]) +
((y - this->Origin[1]) * this->Normal[1]) +
((z - this->Origin[2]) * this->Normal[2]);
}
VTKM_EXEC_CONT
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
return this->Value(x[0], x[1], x[2]);
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault, FloatDefault, FloatDefault) const
{
return this->Normal;
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3>&) const
{
return this->Normal;
}
private:
vtkm::Vec<FloatDefault, 3> Origin;
vtkm::Vec<FloatDefault, 3> Normal;
};
/// \brief Implicit function for a sphere
class Sphere
{
public:
VTKM_CONT
Sphere() : Radius(FloatDefault(0.2)), Center(FloatDefault(0))
{ }
VTKM_CONT
explicit Sphere(FloatDefault radius) : Radius(radius), Center(FloatDefault(0))
{ }
VTKM_CONT
Sphere(vtkm::Vec<FloatDefault, 3> center, FloatDefault radius)
: Radius(radius), Center(center)
{ }
VTKM_EXEC_CONT
FloatDefault GetRadius() const
{
return this->Radius;
}
VTKM_EXEC_CONT
const vtkm::Vec<FloatDefault, 3>& GetCenter() const
{
return this->Center;
}
VTKM_EXEC_CONT
FloatDefault Value(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return ((x - this->Center[0]) * (x - this->Center[0]) +
(y - this->Center[1]) * (y - this->Center[1]) +
(z - this->Center[2]) * (z - this->Center[2])) -
(this->Radius * this->Radius);
}
VTKM_EXEC_CONT
FloatDefault Value(const vtkm::Vec<FloatDefault, 3> &x) const
{
return this->Value(x[0], x[1], x[2]);
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(FloatDefault x, FloatDefault y, FloatDefault z)
const
{
return this->Gradient(vtkm::Vec<FloatDefault, 3>(x, y, z));
}
VTKM_EXEC_CONT
vtkm::Vec<FloatDefault, 3> Gradient(const vtkm::Vec<FloatDefault, 3> &x) const
{
return FloatDefault(2) * (x - this->Center);
}
private:
FloatDefault Radius;
vtkm::Vec<FloatDefault, 3> Center;
};
/// \brief A function object that evaluates the contained implicit function
template <typename ImplicitFunction>
class ImplicitFunctionValue
{
public:
VTKM_CONT
ImplicitFunctionValue()
: Function()
{ }
VTKM_CONT
explicit ImplicitFunctionValue(const ImplicitFunction &func)
: Function(func)
{ }
VTKM_EXEC_CONT
FloatDefault operator()(const vtkm::Vec<FloatDefault, 3> x) const
{
return this->Function.Value(x);
}
VTKM_EXEC_CONT
FloatDefault operator()(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Function.Value(x, y, z);
}
private:
ImplicitFunction Function;
};
/// \brief A function object that computes the gradient of the contained implicit
/// function and the specified point.
template <typename ImplicitFunction>
class ImplicitFunctionGradient
{
public:
VTKM_CONT
ImplicitFunctionGradient()
: Function()
{ }
VTKM_CONT
explicit ImplicitFunctionGradient(const ImplicitFunction &func)
: Function(func)
{ }
VTKM_EXEC_CONT
FloatDefault operator()(const vtkm::Vec<FloatDefault, 3> x) const
{
return this->Function.Gradient(x);
}
VTKM_EXEC_CONT
FloatDefault operator()(FloatDefault x, FloatDefault y, FloatDefault z) const
{
return this->Function.Gradient(x, y, z);
}
private:
ImplicitFunction Function;
};
} // namespace vtkm
#endif // vtk_m_ImplicitFunctions_h

@ -27,15 +27,16 @@
#include <type_traits>
namespace vtkm {
namespace internal {
template<typename ListTag>
struct ListTagCheck : std::is_base_of<vtkm::detail::ListRoot,ListTag>
namespace vtkm
{
static VTKM_CONSTEXPR bool Valid = std::is_base_of<vtkm::detail::ListRoot,
ListTag>::value;
namespace internal
{
template <typename ListTag>
struct ListTagCheck : std::is_base_of<vtkm::detail::ListRoot, ListTag>
{
static VTKM_CONSTEXPR bool Valid = std::is_base_of<vtkm::detail::ListRoot, ListTag>::value;
};
} // namespace internal
@ -45,49 +46,47 @@ struct ListTagCheck : std::is_base_of<vtkm::detail::ListRoot,ListTag>
/// actually a device adapter tag. (You can get weird errors elsewhere in the
/// code when a mistake is made.)
///
#define VTKM_IS_LIST_TAG(tag) \
VTKM_STATIC_ASSERT_MSG( \
(::vtkm::internal::ListTagCheck<tag>::value), \
"Provided type is not a valid VTK-m list tag.")
#define VTKM_IS_LIST_TAG(tag) \
VTKM_STATIC_ASSERT_MSG((::vtkm::internal::ListTagCheck<tag>::value), \
"Provided type is not a valid VTK-m list tag.")
/// A special tag for a list that represents holding all potential values
///
/// Note: Can not be used with ForEach for obvious reasons.
struct ListTagUniversal : detail::ListRoot {
struct ListTagUniversal : detail::ListRoot
{
using list = vtkm::detail::ListBase<vtkm::detail::UniversalTag>;
};
/// A special tag for an empty list.
///
struct ListTagEmpty : detail::ListRoot {
struct ListTagEmpty : detail::ListRoot
{
using list = vtkm::detail::ListBase<>;
};
/// A tag that is a construction of two other tags joined together. This struct
/// can be subclassed and still behave like a list tag.
template<typename ListTag1, typename ListTag2>
struct ListTagJoin : detail::ListRoot {
using list = typename detail::ListJoin<
typename ListTag1::list,
typename ListTag2::list>::type;
template <typename ListTag1, typename ListTag2>
struct ListTagJoin : detail::ListRoot
{
using list = typename detail::ListJoin<typename ListTag1::list, typename ListTag2::list>::type;
};
/// A tag that consits of elements that are found in both tags. This struct
/// can be subclassed and still behave like a list tag.
template<typename ListTag1, typename ListTag2>
struct ListTagIntersect : detail::ListRoot {
using list = typename detail::ListIntersect<
typename ListTag1::list,
typename ListTag2::list>::type;
template <typename ListTag1, typename ListTag2>
struct ListTagIntersect : detail::ListRoot
{
using list =
typename detail::ListIntersect<typename ListTag1::list, typename ListTag2::list>::type;
};
/// For each typename represented by the list tag, call the functor with a
/// default instance of that type.
///
template<typename Functor, typename ListTag>
VTKM_CONT
void ListForEach(Functor &f, ListTag)
template <typename Functor, typename ListTag>
VTKM_CONT void ListForEach(Functor& f, ListTag)
{
VTKM_IS_LIST_TAG(ListTag);
detail::ListForEachImpl(f, typename ListTag::list());
@ -96,9 +95,8 @@ void ListForEach(Functor &f, ListTag)
/// For each typename represented by the list tag, call the functor with a
/// default instance of that type.
///
template<typename Functor, typename ListTag>
VTKM_CONT
void ListForEach(const Functor &f, ListTag)
template <typename Functor, typename ListTag>
VTKM_CONT void ListForEach(const Functor& f, ListTag)
{
VTKM_IS_LIST_TAG(ListTag);
detail::ListForEachImpl(f, typename ListTag::list());
@ -108,12 +106,11 @@ void ListForEach(const Functor &f, ListTag)
/// There is a static boolean named \c value that is set to true if the type is
/// contained in the list and false otherwise.
///
template<typename ListTag, typename Type>
template <typename ListTag, typename Type>
struct ListContains
{
VTKM_IS_LIST_TAG(ListTag);
static VTKM_CONSTEXPR bool value =
detail::ListContainsImpl<Type,typename ListTag::list>::value;
static VTKM_CONSTEXPR bool value = detail::ListContainsImpl<Type, typename ListTag::list>::value;
};
} // namespace vtkm

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -24,11 +24,12 @@
#include <vtkm/Assert.h>
#include <vtkm/Math.h>
#include <vtkm/Types.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/Types.h>
#include <vtkm/VecTraits.h>
namespace vtkm {
namespace vtkm
{
/// \brief Basic Matrix type.
///
@ -40,26 +41,29 @@ namespace vtkm {
/// per-thread data structure to hold information like geometric transforms and
/// tensors.
///
template<typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
class Matrix {
template <typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
class Matrix
{
public:
typedef T ComponentType;
static const vtkm::IdComponent NUM_ROWS = NumRow;
static const vtkm::IdComponent NUM_COLUMNS = NumCol;
VTKM_EXEC_CONT
Matrix() { }
Matrix() {}
VTKM_EXEC_CONT
explicit Matrix(const ComponentType &value)
: Components(vtkm::Vec<ComponentType, NUM_COLUMNS>(value)) { }
explicit Matrix(const ComponentType& value)
: Components(vtkm::Vec<ComponentType, NUM_COLUMNS>(value))
{
}
/// Brackets are used to reference a matrix like a 2D array (i.e.
/// matrix[row][column]).
///
VTKM_EXEC_CONT
const vtkm::Vec<ComponentType, NUM_COLUMNS> &
operator[](vtkm::IdComponent rowIndex) const {
const vtkm::Vec<ComponentType, NUM_COLUMNS>& operator[](vtkm::IdComponent rowIndex) const
{
VTKM_ASSERT(rowIndex >= 0);
VTKM_ASSERT(rowIndex < NUM_ROWS);
return this->Components[rowIndex];
@ -69,8 +73,8 @@ public:
/// matrix[row][column].
///
VTKM_EXEC_CONT
vtkm::Vec<ComponentType, NUM_COLUMNS> &
operator[](vtkm::IdComponent rowIndex) {
vtkm::Vec<ComponentType, NUM_COLUMNS>& operator[](vtkm::IdComponent rowIndex)
{
VTKM_ASSERT(rowIndex >= 0);
VTKM_ASSERT(rowIndex < NUM_ROWS);
return this->Components[rowIndex];
@ -80,8 +84,8 @@ public:
/// notation i.e. matrix(row,column).
///
VTKM_EXEC_CONT
const ComponentType &
operator()(vtkm::IdComponent rowIndex, vtkm::IdComponent colIndex) const {
const ComponentType& operator()(vtkm::IdComponent rowIndex, vtkm::IdComponent colIndex) const
{
VTKM_ASSERT(rowIndex >= 0);
VTKM_ASSERT(rowIndex < NUM_ROWS);
VTKM_ASSERT(colIndex >= 0);
@ -93,8 +97,8 @@ public:
/// notation i.e. matrix(row,column).
///
VTKM_EXEC_CONT
ComponentType &
operator()(vtkm::IdComponent rowIndex, vtkm::IdComponent colIndex) {
ComponentType& operator()(vtkm::IdComponent rowIndex, vtkm::IdComponent colIndex)
{
VTKM_ASSERT(rowIndex >= 0);
VTKM_ASSERT(rowIndex < NUM_ROWS);
VTKM_ASSERT(colIndex >= 0);
@ -109,10 +113,10 @@ private:
/// Returns a tuple containing the given row (indexed from 0) of the given
/// matrix.
///
template<typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT
const vtkm::Vec<T, NumCol> &MatrixGetRow(
const vtkm::Matrix<T,NumRow,NumCol> &matrix, vtkm::IdComponent rowIndex)
template <typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT const vtkm::Vec<T, NumCol>& MatrixGetRow(
const vtkm::Matrix<T, NumRow, NumCol>& matrix,
vtkm::IdComponent rowIndex)
{
return matrix[rowIndex];
}
@ -120,10 +124,9 @@ const vtkm::Vec<T, NumCol> &MatrixGetRow(
/// Returns a tuple containing the given column (indexed from 0) of the given
/// matrix. Might not be as efficient as the \c MatrixGetRow function.
///
template<typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT
vtkm::Vec<T, NumRow> MatrixGetColumn(
const vtkm::Matrix<T,NumRow,NumCol> &matrix, vtkm::IdComponent columnIndex)
template <typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT vtkm::Vec<T, NumRow> MatrixGetColumn(const vtkm::Matrix<T, NumRow, NumCol>& matrix,
vtkm::IdComponent columnIndex)
{
vtkm::Vec<T, NumRow> columnValues;
for (vtkm::IdComponent rowIndex = 0; rowIndex < NumRow; rowIndex++)
@ -135,22 +138,20 @@ vtkm::Vec<T, NumRow> MatrixGetColumn(
/// Convenience function for setting a row of a matrix.
///
template<typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT
void MatrixSetRow(vtkm::Matrix<T,NumRow,NumCol> &matrix,
vtkm::IdComponent rowIndex,
const vtkm::Vec<T,NumCol> &rowValues)
template <typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT void MatrixSetRow(vtkm::Matrix<T, NumRow, NumCol>& matrix,
vtkm::IdComponent rowIndex,
const vtkm::Vec<T, NumCol>& rowValues)
{
matrix[rowIndex] = rowValues;
}
/// Convenience function for setting a column of a matrix.
///
template<typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT
void MatrixSetColumn(vtkm::Matrix<T,NumRow,NumCol> &matrix,
vtkm::IdComponent columnIndex,
const vtkm::Vec<T,NumRow> &columnValues)
template <typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT void MatrixSetColumn(vtkm::Matrix<T, NumRow, NumCol>& matrix,
vtkm::IdComponent columnIndex,
const vtkm::Vec<T, NumRow>& columnValues)
{
for (vtkm::IdComponent rowIndex = 0; rowIndex < NumRow; rowIndex++)
{
@ -160,27 +161,23 @@ void MatrixSetColumn(vtkm::Matrix<T,NumRow,NumCol> &matrix,
/// Standard matrix multiplication.
///
template<typename T,
vtkm::IdComponent NumRow,
vtkm::IdComponent NumCol,
vtkm::IdComponent NumInternal>
VTKM_EXEC_CONT
vtkm::Matrix<T,NumRow,NumCol> MatrixMultiply(
const vtkm::Matrix<T,NumRow,NumInternal> &leftFactor,
const vtkm::Matrix<T,NumInternal,NumCol> &rightFactor)
template <typename T,
vtkm::IdComponent NumRow,
vtkm::IdComponent NumCol,
vtkm::IdComponent NumInternal>
VTKM_EXEC_CONT vtkm::Matrix<T, NumRow, NumCol> MatrixMultiply(
const vtkm::Matrix<T, NumRow, NumInternal>& leftFactor,
const vtkm::Matrix<T, NumInternal, NumCol>& rightFactor)
{
vtkm::Matrix<T,NumRow,NumCol> result;
vtkm::Matrix<T, NumRow, NumCol> result;
for (vtkm::IdComponent rowIndex = 0; rowIndex < NumRow; rowIndex++)
{
for (vtkm::IdComponent colIndex = 0; colIndex < NumCol; colIndex++)
{
T sum = T(leftFactor(rowIndex, 0) * rightFactor(0, colIndex));
for (vtkm::IdComponent internalIndex = 1;
internalIndex < NumInternal;
internalIndex++)
for (vtkm::IdComponent internalIndex = 1; internalIndex < NumInternal; internalIndex++)
{
sum = T(sum + (leftFactor(rowIndex, internalIndex)
* rightFactor(internalIndex, colIndex)));
sum = T(sum + (leftFactor(rowIndex, internalIndex) * rightFactor(internalIndex, colIndex)));
}
result(rowIndex, colIndex) = sum;
}
@ -190,70 +187,62 @@ vtkm::Matrix<T,NumRow,NumCol> MatrixMultiply(
/// Standard matrix-vector multiplication.
///
template<typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT
vtkm::Vec<T,NumRow> MatrixMultiply(
const vtkm::Matrix<T,NumRow,NumCol> &leftFactor,
const vtkm::Vec<T,NumCol> &rightFactor)
template <typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT vtkm::Vec<T, NumRow> MatrixMultiply(
const vtkm::Matrix<T, NumRow, NumCol>& leftFactor,
const vtkm::Vec<T, NumCol>& rightFactor)
{
vtkm::Vec<T,NumRow> product;
vtkm::Vec<T, NumRow> product;
for (vtkm::IdComponent rowIndex = 0; rowIndex < NumRow; rowIndex++)
{
product[rowIndex] =
vtkm::dot(vtkm::MatrixGetRow(leftFactor,rowIndex), rightFactor);
product[rowIndex] = vtkm::dot(vtkm::MatrixGetRow(leftFactor, rowIndex), rightFactor);
}
return product;
}
/// Standard vector-matrix multiplication
///
template<typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT
vtkm::Vec<T,NumCol> MatrixMultiply(
const vtkm::Vec<T,NumRow> &leftFactor,
const vtkm::Matrix<T,NumRow,NumCol> &rightFactor)
template <typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT vtkm::Vec<T, NumCol> MatrixMultiply(
const vtkm::Vec<T, NumRow>& leftFactor,
const vtkm::Matrix<T, NumRow, NumCol>& rightFactor)
{
vtkm::Vec<T,NumCol> product;
vtkm::Vec<T, NumCol> product;
for (vtkm::IdComponent colIndex = 0; colIndex < NumCol; colIndex++)
{
product[colIndex] =
vtkm::dot(leftFactor,
vtkm::MatrixGetColumn(rightFactor, colIndex));
product[colIndex] = vtkm::dot(leftFactor, vtkm::MatrixGetColumn(rightFactor, colIndex));
}
return product;
}
/// Returns the identity matrix.
///
template<typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT
vtkm::Matrix<T,Size,Size> MatrixIdentity()
template <typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT vtkm::Matrix<T, Size, Size> MatrixIdentity()
{
vtkm::Matrix<T,Size,Size> result(T(0));
vtkm::Matrix<T, Size, Size> result(T(0));
for (vtkm::IdComponent index = 0; index < Size; index++)
{
result(index,index) = T(1.0);
result(index, index) = T(1.0);
}
return result;
}
/// Fills the given matrix with the identity matrix.
///
template<typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT
void MatrixIdentity(vtkm::Matrix<T,Size,Size> &matrix)
template <typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT void MatrixIdentity(vtkm::Matrix<T, Size, Size>& matrix)
{
matrix = vtkm::MatrixIdentity<T,Size>();
matrix = vtkm::MatrixIdentity<T, Size>();
}
/// Returns the transpose of the given matrix.
///
template<typename T, vtkm::IdComponent NumRows, vtkm::IdComponent NumCols>
VTKM_EXEC_CONT
vtkm::Matrix<T,NumCols,NumRows> MatrixTranspose(
const vtkm::Matrix<T,NumRows,NumCols> &matrix)
template <typename T, vtkm::IdComponent NumRows, vtkm::IdComponent NumCols>
VTKM_EXEC_CONT vtkm::Matrix<T, NumCols, NumRows> MatrixTranspose(
const vtkm::Matrix<T, NumRows, NumCols>& matrix)
{
vtkm::Matrix<T,NumCols,NumRows> result;
vtkm::Matrix<T, NumCols, NumRows> result;
for (vtkm::IdComponent index = 0; index < NumRows; index++)
{
vtkm::MatrixSetColumn(result, index, vtkm::MatrixGetRow(matrix, index));
@ -270,22 +259,20 @@ vtkm::Matrix<T,NumCols,NumRows> MatrixTranspose(
return result;
}
namespace detail {
namespace detail
{
// Used with MatrixLUPFactor.
template<typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT
void MatrixLUPFactorFindPivot(vtkm::Matrix<T,Size,Size> &A,
vtkm::Vec<vtkm::IdComponent,Size> &permutation,
vtkm::IdComponent topCornerIndex,
T &inversionParity,
bool &valid)
template <typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT void MatrixLUPFactorFindPivot(vtkm::Matrix<T, Size, Size>& A,
vtkm::Vec<vtkm::IdComponent, Size>& permutation,
vtkm::IdComponent topCornerIndex,
T& inversionParity,
bool& valid)
{
vtkm::IdComponent maxRowIndex = topCornerIndex;
T maxValue = vtkm::Abs(A(maxRowIndex, topCornerIndex));
for (vtkm::IdComponent rowIndex = topCornerIndex + 1;
rowIndex < Size;
rowIndex++)
for (vtkm::IdComponent rowIndex = topCornerIndex + 1; rowIndex < Size; rowIndex++)
{
T compareValue = vtkm::Abs(A(rowIndex, topCornerIndex));
if (maxValue < compareValue)
@ -295,15 +282,16 @@ void MatrixLUPFactorFindPivot(vtkm::Matrix<T,Size,Size> &A,
}
}
if (maxValue < vtkm::Epsilon<T>()) { valid = false; }
if (maxValue < vtkm::Epsilon<T>())
{
valid = false;
}
if (maxRowIndex != topCornerIndex)
{
// Swap rows in matrix.
vtkm::Vec<T,Size> maxRow = vtkm::MatrixGetRow(A, maxRowIndex);
vtkm::MatrixSetRow(A,
maxRowIndex,
vtkm::MatrixGetRow(A,topCornerIndex));
vtkm::Vec<T, Size> maxRow = vtkm::MatrixGetRow(A, maxRowIndex);
vtkm::MatrixSetRow(A, maxRowIndex, vtkm::MatrixGetRow(A, topCornerIndex));
vtkm::MatrixSetRow(A, topCornerIndex, maxRow);
// Record change in permutation matrix.
@ -317,30 +305,22 @@ void MatrixLUPFactorFindPivot(vtkm::Matrix<T,Size,Size> &A,
}
// Used with MatrixLUPFactor
template<typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT
void MatrixLUPFactorFindUpperTriangleElements(vtkm::Matrix<T,Size,Size> &A,
vtkm::IdComponent topCornerIndex)
template <typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT void MatrixLUPFactorFindUpperTriangleElements(vtkm::Matrix<T, Size, Size>& A,
vtkm::IdComponent topCornerIndex)
{
// Compute values for upper triangle on row topCornerIndex
for (vtkm::IdComponent colIndex = topCornerIndex+1;
colIndex < Size;
colIndex++)
for (vtkm::IdComponent colIndex = topCornerIndex + 1; colIndex < Size; colIndex++)
{
A(topCornerIndex,colIndex) /= A(topCornerIndex,topCornerIndex);
A(topCornerIndex, colIndex) /= A(topCornerIndex, topCornerIndex);
}
// Update the rest of the matrix for calculations on subsequent rows
for (vtkm::IdComponent rowIndex = topCornerIndex+1;
rowIndex < Size;
rowIndex++)
for (vtkm::IdComponent rowIndex = topCornerIndex + 1; rowIndex < Size; rowIndex++)
{
for (vtkm::IdComponent colIndex = topCornerIndex+1;
colIndex < Size;
colIndex++)
for (vtkm::IdComponent colIndex = topCornerIndex + 1; colIndex < Size; colIndex++)
{
A(rowIndex,colIndex) -=
A(rowIndex,topCornerIndex)*A(topCornerIndex,colIndex);
A(rowIndex, colIndex) -= A(rowIndex, topCornerIndex) * A(topCornerIndex, colIndex);
}
}
}
@ -375,12 +355,11 @@ void MatrixLUPFactorFindUpperTriangleElements(vtkm::Matrix<T,Size,Size> &A,
/// LUP-factorization. If the LUP-factorization succeeds, valid is set to true.
/// Otherwise, valid is set to false and the result is indeterminant.
///
template<typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT
void MatrixLUPFactor(vtkm::Matrix<T,Size,Size> &A,
vtkm::Vec<vtkm::IdComponent,Size> &permutation,
T &inversionParity,
bool &valid)
template <typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT void MatrixLUPFactor(vtkm::Matrix<T, Size, Size>& A,
vtkm::Vec<vtkm::IdComponent, Size>& permutation,
T& inversionParity,
bool& valid)
{
// Initialize permutation.
for (vtkm::IdComponent index = 0; index < Size; index++)
@ -401,12 +380,11 @@ void MatrixLUPFactor(vtkm::Matrix<T,Size,Size> &A,
/// system Ax = b. Instead of A, this method takes in the LU and P
/// matrices calculated by MatrixLUPFactor from A. The x matrix is returned.
///
template<typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT
vtkm::Vec<T,Size>
MatrixLUPSolve(const vtkm::Matrix<T,Size,Size> &LU,
const vtkm::Vec<vtkm::IdComponent,Size> &permutation,
const vtkm::Vec<T,Size> &b)
template <typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT vtkm::Vec<T, Size> MatrixLUPSolve(
const vtkm::Matrix<T, Size, Size>& LU,
const vtkm::Vec<vtkm::IdComponent, Size>& permutation,
const vtkm::Vec<T, Size>& b)
{
// The LUP-factorization gives us PA = LU or equivalently A = inv(P)LU.
// Substituting into Ax = b gives us inv(P)LUx = b or LUx = Pb.
@ -414,28 +392,28 @@ MatrixLUPSolve(const vtkm::Matrix<T,Size,Size> &LU,
// Substituting in the previous two equations yields Ly = Pb.
// Solving Ly = Pb is easy because L is triangular and P is just a
// permutation.
vtkm::Vec<T,Size> y;
vtkm::Vec<T, Size> y;
for (vtkm::IdComponent rowIndex = 0; rowIndex < Size; rowIndex++)
{
{
y[rowIndex] = b[permutation[rowIndex]];
// Recall that L is stored in the lower triangle of LU including diagonal.
for (vtkm::IdComponent colIndex = 0; colIndex < rowIndex; colIndex++)
{
y[rowIndex] -= LU(rowIndex,colIndex)*y[colIndex];
}
y[rowIndex] /= LU(rowIndex,rowIndex);
{
y[rowIndex] -= LU(rowIndex, colIndex) * y[colIndex];
}
y[rowIndex] /= LU(rowIndex, rowIndex);
}
// Now that we have y, we can easily solve Ux = y for x.
vtkm::Vec<T,Size> x;
for (vtkm::IdComponent rowIndex = Size-1; rowIndex >= 0; rowIndex--)
vtkm::Vec<T, Size> x;
for (vtkm::IdComponent rowIndex = Size - 1; rowIndex >= 0; rowIndex--)
{
// Recall that U is stored in the upper triangle of LU with the diagonal
// implicitly all 1's.
x[rowIndex] = y[rowIndex];
for (vtkm::IdComponent colIndex = rowIndex+1; colIndex < Size; colIndex++)
for (vtkm::IdComponent colIndex = rowIndex + 1; colIndex < Size; colIndex++)
{
x[rowIndex] -= LU(rowIndex,colIndex)*x[colIndex];
x[rowIndex] -= LU(rowIndex, colIndex) * x[colIndex];
}
}
@ -447,16 +425,15 @@ MatrixLUPSolve(const vtkm::Matrix<T,Size,Size> &LU,
/// Solve the linear system Ax = b for x. If a single solution is found, valid
/// is set to true, false otherwise.
///
template<typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT
vtkm::Vec<T,Size> SolveLinearSystem(const vtkm::Matrix<T,Size,Size> &A,
const vtkm::Vec<T,Size> &b,
bool &valid)
template <typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT vtkm::Vec<T, Size> SolveLinearSystem(const vtkm::Matrix<T, Size, Size>& A,
const vtkm::Vec<T, Size>& b,
bool& valid)
{
// First, we will make an LUP-factorization to help us.
vtkm::Matrix<T,Size,Size> LU = A;
vtkm::Vec<vtkm::IdComponent,Size> permutation;
T inversionParity; // Unused.
vtkm::Matrix<T, Size, Size> LU = A;
vtkm::Vec<vtkm::IdComponent, Size> permutation;
T inversionParity; // Unused.
detail::MatrixLUPFactor(LU, permutation, inversionParity, valid);
// Next, use the decomposition to solve the system.
@ -466,48 +443,49 @@ vtkm::Vec<T,Size> SolveLinearSystem(const vtkm::Matrix<T,Size,Size> &A,
/// Find and return the inverse of the given matrix. If the matrix is singular,
/// the inverse will not be correct and valid will be set to false.
///
template<typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT
vtkm::Matrix<T,Size,Size> MatrixInverse(const vtkm::Matrix<T,Size,Size> &A,
bool &valid)
template <typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT vtkm::Matrix<T, Size, Size> MatrixInverse(const vtkm::Matrix<T, Size, Size>& A,
bool& valid)
{
// First, we will make an LUP-factorization to help us.
vtkm::Matrix<T,Size,Size> LU = A;
vtkm::Vec<vtkm::IdComponent,Size> permutation;
T inversionParity; // Unused
vtkm::Matrix<T, Size, Size> LU = A;
vtkm::Vec<vtkm::IdComponent, Size> permutation;
T inversionParity; // Unused
detail::MatrixLUPFactor(LU, permutation, inversionParity, valid);
// We will use the decomposition to solve AX = I for X where X is
// clearly the inverse of A. Our solve method only works for vectors,
// so we solve for one column of invA at a time.
vtkm::Matrix<T,Size,Size> invA;
vtkm::Vec<T,Size> ICol(T(0));
vtkm::Matrix<T, Size, Size> invA;
vtkm::Vec<T, Size> ICol(T(0));
for (vtkm::IdComponent colIndex = 0; colIndex < Size; colIndex++)
{
{
ICol[colIndex] = 1;
vtkm::Vec<T,Size> invACol = detail::MatrixLUPSolve(LU, permutation, ICol);
vtkm::Vec<T, Size> invACol = detail::MatrixLUPSolve(LU, permutation, ICol);
ICol[colIndex] = 0;
vtkm::MatrixSetColumn(invA, colIndex, invACol);
}
}
return invA;
}
/// Compute the determinant of a matrix.
///
template<typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT
T MatrixDeterminant(const vtkm::Matrix<T,Size,Size> &A)
template <typename T, vtkm::IdComponent Size>
VTKM_EXEC_CONT T MatrixDeterminant(const vtkm::Matrix<T, Size, Size>& A)
{
// First, we will make an LUP-factorization to help us.
vtkm::Matrix<T,Size,Size> LU = A;
vtkm::Vec<vtkm::IdComponent,Size> permutation;
vtkm::Matrix<T, Size, Size> LU = A;
vtkm::Vec<vtkm::IdComponent, Size> permutation;
T inversionParity;
bool valid;
detail::MatrixLUPFactor(LU, permutation, inversionParity, valid);
// If the matrix is singular, the factorization is invalid, but in that
// case we know that the determinant is 0.
if (!valid) { return 0; }
if (!valid)
{
return 0;
}
// The determinant is equal to the product of the diagonal of the L matrix,
// possibly negated depending on the parity of the inversion. The
@ -515,35 +493,31 @@ T MatrixDeterminant(const vtkm::Matrix<T,Size,Size> &A)
// respectively. This sign determines whether the product should be negated.
T product = inversionParity;
for (vtkm::IdComponent index = 0; index < Size; index++)
{
product *= LU(index,index);
}
{
product *= LU(index, index);
}
return product;
}
// Specializations for common small determinants.
template<typename T>
VTKM_EXEC_CONT
T MatrixDeterminant(const vtkm::Matrix<T,1,1> &A)
template <typename T>
VTKM_EXEC_CONT T MatrixDeterminant(const vtkm::Matrix<T, 1, 1>& A)
{
return A(0,0);
return A(0, 0);
}
template<typename T>
VTKM_EXEC_CONT
T MatrixDeterminant(const vtkm::Matrix<T,2,2> &A)
template <typename T>
VTKM_EXEC_CONT T MatrixDeterminant(const vtkm::Matrix<T, 2, 2>& A)
{
return A(0,0)*A(1,1) - A(1,0)*A(0,1);
return A(0, 0) * A(1, 1) - A(1, 0) * A(0, 1);
}
template<typename T>
VTKM_EXEC_CONT
T MatrixDeterminant(const vtkm::Matrix<T,3,3> &A)
template <typename T>
VTKM_EXEC_CONT T MatrixDeterminant(const vtkm::Matrix<T, 3, 3>& A)
{
return A(0,0) * A(1,1) * A(2,2) + A(1,0) * A(2,1) * A(0,2) +
A(2,0) * A(0,1) * A(1,2) - A(0,0) * A(2,1) * A(1,2) -
A(1,0) * A(0,1) * A(2,2) - A(2,0) * A(1,1) * A(0,2);
return A(0, 0) * A(1, 1) * A(2, 2) + A(1, 0) * A(2, 1) * A(0, 2) + A(2, 0) * A(0, 1) * A(1, 2) -
A(0, 0) * A(2, 1) * A(1, 2) - A(1, 0) * A(0, 1) * A(2, 2) - A(2, 0) * A(1, 1) * A(0, 2);
}
//---------------------------------------------------------------------------
@ -552,49 +526,50 @@ T MatrixDeterminant(const vtkm::Matrix<T,3,3> &A)
/// Tag used to identify 2 dimensional types (matrices). A TypeTraits class
/// will typedef this class to DimensionalityTag.
///
struct TypeTraitsMatrixTag {};
struct TypeTraitsMatrixTag
{
};
template<typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
struct TypeTraits<vtkm::Matrix<T, NumRow, NumCol> > {
template <typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
struct TypeTraits<vtkm::Matrix<T, NumRow, NumCol>>
{
typedef typename TypeTraits<T>::NumericTag NumericTag;
typedef TypeTraitsMatrixTag DimensionalityTag;
};
/// A matrix has vector traits to implement component-wise operations.
///
template<typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
struct VecTraits<vtkm::Matrix<T, NumRow, NumCol> > {
template <typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
struct VecTraits<vtkm::Matrix<T, NumRow, NumCol>>
{
private:
typedef vtkm::Matrix<T, NumRow, NumCol> MatrixType;
public:
typedef T ComponentType;
static const vtkm::IdComponent NUM_COMPONENTS = NumRow*NumCol;
static const vtkm::IdComponent NUM_COMPONENTS = NumRow * NumCol;
typedef vtkm::VecTraitsTagMultipleComponents HasMultipleComponents;
typedef vtkm::VecTraitsTagSizeStatic IsSizeStatic;
VTKM_EXEC_CONT
static vtkm::IdComponent GetNumberOfComponents(const MatrixType &) {
return NUM_COMPONENTS;
}
static vtkm::IdComponent GetNumberOfComponents(const MatrixType&) { return NUM_COMPONENTS; }
VTKM_EXEC_CONT
static const ComponentType &GetComponent(const MatrixType &matrix,
vtkm::IdComponent component) {
static const ComponentType& GetComponent(const MatrixType& matrix, vtkm::IdComponent component)
{
vtkm::IdComponent colIndex = component % NumCol;
vtkm::IdComponent rowIndex = component / NumCol;
return matrix(rowIndex,colIndex);
return matrix(rowIndex, colIndex);
}
VTKM_EXEC_CONT
static ComponentType &GetComponent(MatrixType &matrix,
vtkm::IdComponent component) {
static ComponentType& GetComponent(MatrixType& matrix, vtkm::IdComponent component)
{
vtkm::IdComponent colIndex = component % NumCol;
vtkm::IdComponent rowIndex = component / NumCol;
return matrix(rowIndex,colIndex);
return matrix(rowIndex, colIndex);
}
VTKM_EXEC_CONT
static void SetComponent(MatrixType &matrix,
vtkm::IdComponent component,
T value)
static void SetComponent(MatrixType& matrix, vtkm::IdComponent component, T value)
{
GetComponent(matrix, component) = value;
}
@ -605,24 +580,23 @@ public:
//---------------------------------------------------------------------------
// Basic comparison operators.
template<typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT
bool operator==(const vtkm::Matrix<T,NumRow,NumCol> &a,
const vtkm::Matrix<T,NumRow,NumCol> &b)
template <typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT bool operator==(const vtkm::Matrix<T, NumRow, NumCol>& a,
const vtkm::Matrix<T, NumRow, NumCol>& b)
{
for (vtkm::IdComponent colIndex = 0; colIndex < NumCol; colIndex++)
{
for (vtkm::IdComponent rowIndex = 0; rowIndex < NumRow; rowIndex++)
{
if (a(rowIndex, colIndex) != b(rowIndex, colIndex)) return false;
if (a(rowIndex, colIndex) != b(rowIndex, colIndex))
return false;
}
}
return true;
}
template<typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT
bool operator!=(const vtkm::Matrix<T,NumRow,NumCol> &a,
const vtkm::Matrix<T,NumRow,NumCol> &b)
template <typename T, vtkm::IdComponent NumRow, vtkm::IdComponent NumCol>
VTKM_EXEC_CONT bool operator!=(const vtkm::Matrix<T, NumRow, NumCol>& a,
const vtkm::Matrix<T, NumRow, NumCol>& b)
{
return !(a == b);
}

@ -23,7 +23,8 @@
#include <vtkm/Math.h>
#include <vtkm/Matrix.h>
namespace vtkm {
namespace vtkm
{
/// Uses Newton's method (a.k.a. Newton-Raphson method) to solve a nonlinear
/// system of equations. This function assumes that the number of variables
@ -36,30 +37,26 @@ namespace vtkm {
/// returned.
///
VTKM_SUPPRESS_EXEC_WARNINGS
template<typename ScalarType,
vtkm::IdComponent Size,
typename JacobianFunctor,
typename FunctionFunctor>
VTKM_EXEC_CONT
vtkm::Vec<ScalarType,Size>
NewtonsMethod(JacobianFunctor jacobianEvaluator,
FunctionFunctor functionEvaluator,
vtkm::Vec<ScalarType,Size> desiredFunctionOutput,
vtkm::Vec<ScalarType,Size> initialGuess
= vtkm::Vec<ScalarType,Size>(ScalarType(0)),
ScalarType convergeDifference = ScalarType(1e-3),
vtkm::IdComponent maxIterations = 10)
template <typename ScalarType,
vtkm::IdComponent Size,
typename JacobianFunctor,
typename FunctionFunctor>
VTKM_EXEC_CONT vtkm::Vec<ScalarType, Size> NewtonsMethod(
JacobianFunctor jacobianEvaluator,
FunctionFunctor functionEvaluator,
vtkm::Vec<ScalarType, Size> desiredFunctionOutput,
vtkm::Vec<ScalarType, Size> initialGuess = vtkm::Vec<ScalarType, Size>(ScalarType(0)),
ScalarType convergeDifference = ScalarType(1e-3),
vtkm::IdComponent maxIterations = 10)
{
typedef vtkm::Vec<ScalarType,Size> VectorType;
typedef vtkm::Matrix<ScalarType,Size,Size> MatrixType;
typedef vtkm::Vec<ScalarType, Size> VectorType;
typedef vtkm::Matrix<ScalarType, Size, Size> MatrixType;
VectorType x = initialGuess;
bool converged = false;
for (vtkm::IdComponent iteration = 0;
!converged && (iteration < maxIterations);
iteration++)
{
for (vtkm::IdComponent iteration = 0; !converged && (iteration < maxIterations); iteration++)
{
// For Newton's method, we solve the linear system
//
// Jacobian x deltaX = currentFunctionOutput - desiredFunctionOutput
@ -72,21 +69,18 @@ NewtonsMethod(JacobianFunctor jacobianEvaluator,
MatrixType jacobian = jacobianEvaluator(x);
VectorType currentFunctionOutput = functionEvaluator(x);
bool valid; // Ignored.
bool valid; // Ignored.
VectorType deltaX =
vtkm::SolveLinearSystem(
jacobian,
currentFunctionOutput - desiredFunctionOutput,
valid);
vtkm::SolveLinearSystem(jacobian, currentFunctionOutput - desiredFunctionOutput, valid);
x = x - deltaX;
converged = true;
for (vtkm::IdComponent index = 0; index < Size; index++)
{
{
converged &= (vtkm::Abs(deltaX[index]) < convergeDifference);
}
}
}
// Not checking whether converged.
return x;

@ -27,7 +27,8 @@
#include <iostream>
#include <utility>
namespace vtkm {
namespace vtkm
{
/// A \c vtkm::Pair is essentially the same as an STL pair object except that
/// the methods (constructors and operators) are defined to work in both the
@ -64,37 +65,50 @@ struct Pair
SecondType second;
VTKM_EXEC_CONT
Pair() : first(), second() { }
Pair()
: first()
, second()
{
}
VTKM_EXEC_CONT
Pair(const FirstType &firstSrc, const SecondType &secondSrc)
: first(firstSrc), second(secondSrc) { }
Pair(const FirstType& firstSrc, const SecondType& secondSrc)
: first(firstSrc)
, second(secondSrc)
{
}
template <typename U1, typename U2>
VTKM_EXEC_CONT
Pair(const vtkm::Pair<U1,U2> &src)
: first(src.first), second(src.second) { }
VTKM_EXEC_CONT Pair(const vtkm::Pair<U1, U2>& src)
: first(src.first)
, second(src.second)
{
}
template <typename U1, typename U2>
VTKM_EXEC_CONT
Pair(const std::pair<U1,U2> &src)
: first(src.first), second(src.second) { }
VTKM_EXEC_CONT Pair(const std::pair<U1, U2>& src)
: first(src.first)
, second(src.second)
{
}
VTKM_EXEC_CONT
vtkm::Pair<FirstType,SecondType> &
operator=(const vtkm::Pair<FirstType,SecondType> &src) {
vtkm::Pair<FirstType, SecondType>& operator=(const vtkm::Pair<FirstType, SecondType>& src)
{
this->first = src.first;
this->second = src.second;
return *this;
}
VTKM_EXEC_CONT
bool operator==(const vtkm::Pair<FirstType,SecondType> &other) const {
bool operator==(const vtkm::Pair<FirstType, SecondType>& other) const
{
return ((this->first == other.first) && (this->second == other.second));
}
VTKM_EXEC_CONT
bool operator!=(const vtkm::Pair<FirstType,SecondType> &other) const {
bool operator!=(const vtkm::Pair<FirstType, SecondType>& other) const
{
return !(*this == other);
}
@ -102,54 +116,46 @@ struct Pair
/// first are equal.
///
VTKM_EXEC_CONT
bool operator<(const vtkm::Pair<FirstType,SecondType> &other) const {
return ((this->first < other.first)
|| (!(other.first < this->first) && (this->second < other.second)));
bool operator<(const vtkm::Pair<FirstType, SecondType>& other) const
{
return ((this->first < other.first) ||
(!(other.first < this->first) && (this->second < other.second)));
}
/// Tests ordering on the first object, and then on the second object if the
/// first are equal.
///
VTKM_EXEC_CONT
bool operator>(const vtkm::Pair<FirstType,SecondType> &other) const {
return (other < *this);
}
bool operator>(const vtkm::Pair<FirstType, SecondType>& other) const { return (other < *this); }
/// Tests ordering on the first object, and then on the second object if the
/// first are equal.
///
VTKM_EXEC_CONT
bool operator<=(const vtkm::Pair<FirstType,SecondType> &other) const {
return !(other < *this);
}
bool operator<=(const vtkm::Pair<FirstType, SecondType>& other) const { return !(other < *this); }
/// Tests ordering on the first object, and then on the second object if the
/// first are equal.
///
VTKM_EXEC_CONT
bool operator>=(const vtkm::Pair<FirstType,SecondType> &other) const {
return !(*this < other);
}
bool operator>=(const vtkm::Pair<FirstType, SecondType>& other) const { return !(*this < other); }
};
/// Pairwise Add.
/// This is done by adding the two objects separately.
/// Useful for Reduce operation on a zipped array
template<typename T, typename U>
VTKM_EXEC_CONT
vtkm::Pair<T, U> operator+(const vtkm::Pair<T, U>& a, const vtkm::Pair<T, U> &b)
template <typename T, typename U>
VTKM_EXEC_CONT vtkm::Pair<T, U> operator+(const vtkm::Pair<T, U>& a, const vtkm::Pair<T, U>& b)
{
return vtkm::Pair<T,U>(a.first + b.first, a.second + b.second);
return vtkm::Pair<T, U>(a.first + b.first, a.second + b.second);
}
template <typename T1, typename T2>
VTKM_EXEC_CONT
vtkm::Pair<T1,T2> make_Pair(const T1 &firstSrc, const T2 &secondSrc)
VTKM_EXEC_CONT vtkm::Pair<T1, T2> make_Pair(const T1& firstSrc, const T2& secondSrc)
{
return vtkm::Pair<T1,T2>(firstSrc, secondSrc);
return vtkm::Pair<T1, T2>(firstSrc, secondSrc);
}
} // namespace vtkm
#endif //vtk_m_Pair_h

@ -25,7 +25,8 @@
#include <vtkm/Math.h>
#include <vtkm/Types.h>
namespace vtkm {
namespace vtkm
{
/// \brief Represent a continuous scalar range of values.
///
@ -42,16 +43,21 @@ struct Range
vtkm::Float64 Max;
VTKM_EXEC_CONT
Range() : Min(vtkm::Infinity64()), Max(vtkm::NegativeInfinity64()) { }
Range()
: Min(vtkm::Infinity64())
, Max(vtkm::NegativeInfinity64())
{
}
template<typename T1, typename T2>
VTKM_EXEC_CONT
Range(const T1 &min, const T2 &max)
: Min(static_cast<vtkm::Float64>(min)), Max(static_cast<vtkm::Float64>(max))
{ }
template <typename T1, typename T2>
VTKM_EXEC_CONT Range(const T1& min, const T2& max)
: Min(static_cast<vtkm::Float64>(min))
, Max(static_cast<vtkm::Float64>(max))
{
}
VTKM_EXEC_CONT
const vtkm::Range &operator=(const vtkm::Range &src)
const vtkm::Range& operator=(const vtkm::Range& src)
{
this->Min = src.Min;
this->Max = src.Max;
@ -68,10 +74,7 @@ struct Range
/// are equal then true is returned.
///
VTKM_EXEC_CONT
bool IsNonEmpty() const
{
return (this->Min <= this->Max);
}
bool IsNonEmpty() const { return (this->Min <= this->Max); }
/// \b Determines if a value is within the range.
///
@ -79,9 +82,8 @@ struct Range
/// otherwise. \c Contains treats the min and max as inclusive. That is, if
/// the value is exactly the min or max, true is returned.
///
template<typename T>
VTKM_EXEC_CONT
bool Contains(const T &value) const
template <typename T>
VTKM_EXEC_CONT bool Contains(const T& value) const
{
return ((this->Min <= static_cast<vtkm::Float64>(value)) &&
(this->Max >= static_cast<vtkm::Float64>(value)));
@ -115,7 +117,7 @@ struct Range
{
if (this->IsNonEmpty())
{
return 0.5*(this->Max + this->Min);
return 0.5 * (this->Max + this->Min);
}
else
{
@ -129,9 +131,8 @@ struct Range
/// given value. If the range already includes this value, then nothing is
/// done.
///
template<typename T>
VTKM_EXEC_CONT
void Include(const T &value)
template <typename T>
VTKM_EXEC_CONT void Include(const T& value)
{
this->Min = vtkm::Min(this->Min, static_cast<vtkm::Float64>(value));
this->Max = vtkm::Max(this->Max, static_cast<vtkm::Float64>(value));
@ -143,7 +144,7 @@ struct Range
/// of another range. Esentially it is the union of the two ranges.
///
VTKM_EXEC_CONT
void Include(const vtkm::Range &range)
void Include(const vtkm::Range& range)
{
this->Include(range.Min);
this->Include(range.Max);
@ -154,7 +155,7 @@ struct Range
/// This is a nondestructive form of \c Include.
///
VTKM_EXEC_CONT
vtkm::Range Union(const vtkm::Range &otherRange) const
vtkm::Range Union(const vtkm::Range& otherRange) const
{
vtkm::Range unionRange(*this);
unionRange.Include(otherRange);
@ -164,19 +165,16 @@ struct Range
/// \b Operator for union
///
VTKM_EXEC_CONT
vtkm::Range operator+(const vtkm::Range &otherRange) const
{
return this->Union(otherRange);
}
vtkm::Range operator+(const vtkm::Range& otherRange) const { return this->Union(otherRange); }
VTKM_EXEC_CONT
bool operator==(const vtkm::Range &otherRange) const
bool operator==(const vtkm::Range& otherRange) const
{
return ((this->Min == otherRange.Min) && (this->Max == otherRange.Max));
}
VTKM_EXEC_CONT
bool operator!=(const vtkm::Range &otherRange) const
bool operator!=(const vtkm::Range& otherRange) const
{
return ((this->Min != otherRange.Min) || (this->Max != otherRange.Max));
}
@ -186,8 +184,7 @@ struct Range
/// Helper function for printing ranges during testing
///
static inline VTKM_CONT
std::ostream &operator<<(std::ostream &stream, const vtkm::Range &range)
static inline VTKM_CONT std::ostream& operator<<(std::ostream& stream, const vtkm::Range& range)
{
return stream << "[" << range.Min << ".." << range.Max << "]";
}

153
vtkm/RangeId.h Normal file

@ -0,0 +1,153 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_RangeId_h
#define vtk_m_RangeId_h
#include <vtkm/Math.h>
#include <vtkm/Types.h>
namespace vtkm
{
/// \brief Represent a range of vtkm::Id values.
///
/// \c vtkm::RangeId is a helper class for representing a range of vtkm::Id
/// values. This is specified simply with a \c Min and \c Max value, where
/// \c Max is exclusive.
///
/// \c RangeId also contains several helper functions for computing and
/// maintaining the range.
///
struct RangeId
{
vtkm::Id Min;
vtkm::Id Max;
VTKM_EXEC_CONT
RangeId()
: Min(0)
, Max(0)
{
}
VTKM_EXEC_CONT
RangeId(vtkm::Id min, vtkm::Id max)
: Min(min)
, Max(max)
{
}
/// \b Determine if the range is valid.
///
/// \c IsNonEmpty return true if the range contains some valid values between
/// \c Min and \c Max. If \c Max <= \c Min, then no values satisfy
/// the range and \c IsNonEmpty returns false. Otherwise, return true.
///
VTKM_EXEC_CONT
bool IsNonEmpty() const { return (this->Min < this->Max); }
/// \b Determines if a value is within the range.
///
/// \c Contains returns true if the give value is within the range, false
/// otherwise.
///
VTKM_EXEC_CONT
bool Contains(vtkm::Id value) const { return ((this->Min <= value) && (this->Max > value)); }
/// \b Returns the length of the range.
///
/// \c Length computes the distance between the min and max. If the range
/// is empty, 0 is returned.
///
VTKM_EXEC_CONT
vtkm::Id Length() const { return this->Max - this->Min; }
/// \b Returns the center of the range.
///
/// \c Center computes the middle value of the range.
///
VTKM_EXEC_CONT
vtkm::Id Center() const { return (this->Min + this->Max) / 2; }
/// \b Expand range to include a value.
///
/// This version of \c Include expands the range just enough to include the
/// given value. If the range already includes this value, then nothing is
/// done.
///
VTKM_EXEC_CONT
void Include(vtkm::Id value)
{
this->Min = vtkm::Min(this->Min, value);
this->Max = vtkm::Max(this->Max, value + 1);
}
/// \b Expand range to include other range.
///
/// This version of \c Include expands this range just enough to include that
/// of another range. Esentially it is the union of the two ranges.
///
VTKM_EXEC_CONT
void Include(const vtkm::RangeId& range)
{
this->Min = vtkm::Min(this->Min, range.Min);
this->Max = vtkm::Max(this->Max, range.Max);
}
/// \b Return the union of this and another range.
///
/// This is a nondestructive form of \c Include.
///
VTKM_EXEC_CONT
vtkm::RangeId Union(const vtkm::RangeId& other) const
{
vtkm::RangeId unionRange(*this);
unionRange.Include(other);
return unionRange;
}
/// \b Operator for union
///
VTKM_EXEC_CONT
vtkm::RangeId operator+(const vtkm::RangeId& other) const { return this->Union(other); }
VTKM_EXEC_CONT
bool operator==(const vtkm::RangeId& other) const
{
return ((this->Min == other.Min) && (this->Max == other.Max));
}
VTKM_EXEC_CONT
bool operator!=(const vtkm::RangeId& other) const
{
return ((this->Min != other.Min) || (this->Max != other.Max));
}
};
} // namespace vtkm
/// Helper function for printing ranges during testing
///
static inline VTKM_CONT std::ostream& operator<<(std::ostream& stream, const vtkm::RangeId& range)
{
return stream << "[" << range.Min << ".." << range.Max << ")";
}
#endif // vtk_m_RangeId_h

183
vtkm/RangeId3.h Normal file

@ -0,0 +1,183 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_RangeId3_h
#define vtk_m_RangeId3_h
#include <vtkm/RangeId.h>
namespace vtkm
{
/// \brief Represent 3D integer range.
///
/// \c vtkm::RangeId3 is a helper class for representing a 3D range of integer
/// values. The typical use of this class is to express a box of indices
/// in the x, y, and z directions.
///
/// \c RangeId3 also contains several helper functions for computing and
/// maintaining the range.
///
struct RangeId3
{
vtkm::RangeId X;
vtkm::RangeId Y;
vtkm::RangeId Z;
VTKM_EXEC_CONT
RangeId3() = default;
VTKM_EXEC_CONT
RangeId3(const vtkm::RangeId& xrange, const vtkm::RangeId& yrange, const vtkm::RangeId& zrange)
: X(xrange)
, Y(yrange)
, Z(zrange)
{
}
VTKM_EXEC_CONT
RangeId3(vtkm::Id minX, vtkm::Id maxX, vtkm::Id minY, vtkm::Id maxY, vtkm::Id minZ, vtkm::Id maxZ)
: X(vtkm::RangeId(minX, maxX))
, Y(vtkm::RangeId(minY, maxY))
, Z(vtkm::RangeId(minZ, maxZ))
{
}
/// Initialize range with an array of 6 values in the order xmin, xmax,
/// ymin, ymax, zmin, zmax.
///
VTKM_EXEC_CONT
explicit RangeId3(const vtkm::Id range[6])
: X(vtkm::RangeId(range[0], range[1]))
, Y(vtkm::RangeId(range[2], range[3]))
, Z(vtkm::RangeId(range[4], range[5]))
{
}
/// Initialize range with the minimum and the maximum corners
///
VTKM_EXEC_CONT
RangeId3(const vtkm::Id3& min, const vtkm::Id3& max)
: X(vtkm::RangeId(min[0], max[0]))
, Y(vtkm::RangeId(min[1], max[1]))
, Z(vtkm::RangeId(min[2], max[2]))
{
}
/// \b Determine if the range is non-empty.
///
/// \c IsNonEmpty returns true if the range is non-empty.
///
VTKM_EXEC_CONT
bool IsNonEmpty() const
{
return (this->X.IsNonEmpty() && this->Y.IsNonEmpty() && this->Z.IsNonEmpty());
}
/// \b Determines if an Id3 value is within the range.
///
VTKM_EXEC_CONT
bool Contains(const vtkm::Id3& val) const
{
return (this->X.Contains(val[0]) && this->Y.Contains(val[1]) && this->Z.Contains(val[2]));
}
/// \b Returns the center of the range.
///
/// \c Center computes the middle of the range.
///
VTKM_EXEC_CONT
vtkm::Id3 Center() const
{
return vtkm::Id3(this->X.Center(), this->Y.Center(), this->Z.Center());
}
VTKM_EXEC_CONT
vtkm::Id3 Dimensions() const
{
return vtkm::Id3(this->X.Length(), this->Y.Length(), this->Z.Length());
}
/// \b Expand range to include a value.
///
/// This version of \c Include expands the range just enough to include the
/// given value. If the range already include this value, then
/// nothing is done.
///
template <typename T>
VTKM_EXEC_CONT void Include(const vtkm::Vec<T, 3>& point)
{
this->X.Include(point[0]);
this->Y.Include(point[1]);
this->Z.Include(point[2]);
}
/// \b Expand range to include other range.
///
/// This version of \c Include expands the range just enough to include
/// the other range. Esentially it is the union of the two ranges.
///
VTKM_EXEC_CONT
void Include(const vtkm::RangeId3& range)
{
this->X.Include(range.X);
this->Y.Include(range.Y);
this->Z.Include(range.Z);
}
/// \b Return the union of this and another range.
///
/// This is a nondestructive form of \c Include.
///
VTKM_EXEC_CONT
vtkm::RangeId3 Union(const vtkm::RangeId3& other) const
{
vtkm::RangeId3 unionRangeId3(*this);
unionRangeId3.Include(other);
return unionRangeId3;
}
/// \b Operator for union
///
VTKM_EXEC_CONT
vtkm::RangeId3 operator+(const vtkm::RangeId3& other) const { return this->Union(other); }
VTKM_EXEC_CONT
bool operator==(const vtkm::RangeId3& range) const
{
return ((this->X == range.X) && (this->Y == range.Y) && (this->Z == range.Z));
}
VTKM_EXEC_CONT
bool operator!=(const vtkm::RangeId3& range) const
{
return ((this->X != range.X) || (this->Y != range.Y) || (this->Z != range.Z));
}
};
} // namespace vtkm
/// Helper function for printing range during testing
///
static inline VTKM_CONT std::ostream& operator<<(std::ostream& stream, const vtkm::RangeId3& range)
{
return stream << "{ X:" << range.X << ", Y:" << range.Y << ", Z:" << range.Z << " }";
}
#endif //vtk_m_RangeId3_h

@ -20,13 +20,11 @@
#ifndef vtk_m_StaticAssert_h
#define vtk_m_StaticAssert_h
#include <vtkm/internal/Configure.h>
#include <type_traits>
#include <vtkm/internal/Configure.h>
#define VTKM_STATIC_ASSERT(condition) \
static_assert( (condition), "Failed static assert: " #condition)
#define VTKM_STATIC_ASSERT_MSG(condition, message) \
static_assert( (condition), message)
#define VTKM_STATIC_ASSERT(condition) \
static_assert((condition), "Failed static assert: " #condition)
#define VTKM_STATIC_ASSERT_MSG(condition, message) static_assert((condition), message)
#endif //vtk_m_StaticAssert_h

@ -22,7 +22,8 @@
#include <vtkm/Types.h>
namespace vtkm {
namespace vtkm
{
/// \brief A tag used to identify the cell elements in a topology.
///
@ -30,7 +31,9 @@ namespace vtkm {
/// example, a 3D mesh has points, edges, faces, and cells. Each of these is an
/// example of a topology element and has its own tag.
///
struct TopologyElementTagCell { };
struct TopologyElementTagCell
{
};
/// \brief A tag used to identify the point elements in a topology.
///
@ -38,7 +41,9 @@ struct TopologyElementTagCell { };
/// example, a 3D mesh has points, edges, faces, and cells. Each of these is an
/// example of a topology element and has its own tag.
///
struct TopologyElementTagPoint { };
struct TopologyElementTagPoint
{
};
/// \brief A tag used to identify the edge elements in a topology.
///
@ -46,7 +51,9 @@ struct TopologyElementTagPoint { };
/// example, a 3D mesh has points, edges, faces, and cells. Each of these is an
/// example of a topology element and has its own tag.
///
struct TopologyElementTagEdge { };
struct TopologyElementTagEdge
{
};
/// \brief A tag used to identify the face elements in a topology.
///
@ -54,10 +61,12 @@ struct TopologyElementTagEdge { };
/// example, a 3D mesh has points, edges, faces, and cells. Each of these is an
/// example of a topology element and has its own tag.
///
struct TopologyElementTagFace { };
struct TopologyElementTagFace
{
};
namespace internal {
namespace internal
{
/// Checks to see if the given object is a topology element tag.This check is
/// compatible with C++11 type_traits.
@ -65,35 +74,34 @@ namespace internal {
/// std::false_type. Both of these have a typedef named value with the
/// respective boolean value.
///
template<typename T>
template <typename T>
struct TopologyElementTagCheck : std::false_type
{
};
template<>
template <>
struct TopologyElementTagCheck<vtkm::TopologyElementTagCell> : std::true_type
{
};
template<>
template <>
struct TopologyElementTagCheck<vtkm::TopologyElementTagPoint> : std::true_type
{
};
template<>
template <>
struct TopologyElementTagCheck<vtkm::TopologyElementTagEdge> : std::true_type
{
};
template<>
template <>
struct TopologyElementTagCheck<vtkm::TopologyElementTagFace> : std::true_type
{
};
#define VTKM_IS_TOPOLOGY_ELEMENT_TAG(type) \
static_assert( ::vtkm::internal::TopologyElementTagCheck<type>::value, \
"Invalid Topology Element Tag being used")
#define VTKM_IS_TOPOLOGY_ELEMENT_TAG(type) \
static_assert(::vtkm::internal::TopologyElementTagCheck<type>::value, \
"Invalid Topology Element Tag being used")
} // namespace internal

@ -28,7 +28,8 @@
#include <vtkm/Matrix.h>
#include <vtkm/VectorAnalysis.h>
namespace vtkm {
namespace vtkm
{
/// \brief Transform a 3D point by a transformation matrix.
///
@ -41,16 +42,14 @@ namespace vtkm {
/// (such as translate, scale, and rotate), but not for perspective
/// transformations.
///
template<typename T>
VTKM_EXEC_CONT
vtkm::Vec<T,3> Transform3DPoint(const vtkm::Matrix<T,4,4> &matrix,
const vtkm::Vec<T,3> &point)
template <typename T>
VTKM_EXEC_CONT vtkm::Vec<T, 3> Transform3DPoint(const vtkm::Matrix<T, 4, 4>& matrix,
const vtkm::Vec<T, 3>& point)
{
vtkm::Vec<T,4> homogeneousPoint(point[0], point[1], point[2], T(1));
return vtkm::Vec<T,3>(
vtkm::dot(vtkm::MatrixGetRow(matrix,0), homogeneousPoint),
vtkm::dot(vtkm::MatrixGetRow(matrix,1), homogeneousPoint),
vtkm::dot(vtkm::MatrixGetRow(matrix,2), homogeneousPoint));
vtkm::Vec<T, 4> homogeneousPoint(point[0], point[1], point[2], T(1));
return vtkm::Vec<T, 3>(vtkm::dot(vtkm::MatrixGetRow(matrix, 0), homogeneousPoint),
vtkm::dot(vtkm::MatrixGetRow(matrix, 1), homogeneousPoint),
vtkm::dot(vtkm::MatrixGetRow(matrix, 2), homogeneousPoint));
}
/// \brief Transform a 3D point by a transformation matrix with perspective.
@ -62,17 +61,15 @@ vtkm::Vec<T,3> Transform3DPoint(const vtkm::Matrix<T,4,4> &matrix,
/// transformed homogeneous coordiante. This makes it applicable for perspective
/// transformations, but requires some more computations.
///
template<typename T>
VTKM_EXEC_CONT
vtkm::Vec<T,3> Transform3DPointPerspective(const vtkm::Matrix<T,4,4> &matrix,
const vtkm::Vec<T,3> &point)
template <typename T>
VTKM_EXEC_CONT vtkm::Vec<T, 3> Transform3DPointPerspective(const vtkm::Matrix<T, 4, 4>& matrix,
const vtkm::Vec<T, 3>& point)
{
vtkm::Vec<T,4> homogeneousPoint(point[0], point[1], point[2], T(1));
T inverseW = 1/vtkm::dot(vtkm::MatrixGetRow(matrix,3), homogeneousPoint);
return vtkm::Vec<T,3>(
vtkm::dot(vtkm::MatrixGetRow(matrix,0), homogeneousPoint)*inverseW,
vtkm::dot(vtkm::MatrixGetRow(matrix,1), homogeneousPoint)*inverseW,
vtkm::dot(vtkm::MatrixGetRow(matrix,2), homogeneousPoint)*inverseW);
vtkm::Vec<T, 4> homogeneousPoint(point[0], point[1], point[2], T(1));
T inverseW = 1 / vtkm::dot(vtkm::MatrixGetRow(matrix, 3), homogeneousPoint);
return vtkm::Vec<T, 3>(vtkm::dot(vtkm::MatrixGetRow(matrix, 0), homogeneousPoint) * inverseW,
vtkm::dot(vtkm::MatrixGetRow(matrix, 1), homogeneousPoint) * inverseW,
vtkm::dot(vtkm::MatrixGetRow(matrix, 2), homogeneousPoint) * inverseW);
}
/// \brief Transform a 3D vector by a transformation matrix.
@ -81,17 +78,13 @@ vtkm::Vec<T,3> Transform3DPointPerspective(const vtkm::Matrix<T,4,4> &matrix,
/// transformed by the given matrix in homogeneous coordinates. Unlike points,
/// vectors do not get translated.
///
template<typename T>
VTKM_EXEC_CONT
vtkm::Vec<T,3> Transform3DVector(const vtkm::Matrix<T,4,4> &matrix,
const vtkm::Vec<T,3> &vector)
template <typename T>
VTKM_EXEC_CONT vtkm::Vec<T, 3> Transform3DVector(const vtkm::Matrix<T, 4, 4>& matrix,
const vtkm::Vec<T, 3>& vector)
{
vtkm::Vec<T,4> homogeneousVector(vector[0], vector[1], vector[2], T(0));
vtkm::Vec<T, 4> homogeneousVector(vector[0], vector[1], vector[2], T(0));
homogeneousVector = vtkm::MatrixMultiply(matrix, homogeneousVector);
return vtkm::Vec<T,3>(
homogeneousVector[0],
homogeneousVector[1],
homogeneousVector[2]);
return vtkm::Vec<T, 3>(homogeneousVector[0], homogeneousVector[1], homogeneousVector[2]);
}
/// \brief Returns a scale matrix.
@ -99,16 +92,16 @@ vtkm::Vec<T,3> Transform3DVector(const vtkm::Matrix<T,4,4> &matrix,
/// Given a scale factor for the x, y, and z directions, returns a
/// transformation matrix for those scales.
///
template<typename T>
VTKM_EXEC_CONT
vtkm::Matrix<T,4,4>
Transform3DScale(const T &scaleX, const T &scaleY, const T &scaleZ)
template <typename T>
VTKM_EXEC_CONT vtkm::Matrix<T, 4, 4> Transform3DScale(const T& scaleX,
const T& scaleY,
const T& scaleZ)
{
vtkm::Matrix<T,4,4> scaleMatrix(T(0));
scaleMatrix(0,0) = scaleX;
scaleMatrix(1,1) = scaleY;
scaleMatrix(2,2) = scaleZ;
scaleMatrix(3,3) = T(1);
vtkm::Matrix<T, 4, 4> scaleMatrix(T(0));
scaleMatrix(0, 0) = scaleX;
scaleMatrix(1, 1) = scaleY;
scaleMatrix(2, 2) = scaleZ;
scaleMatrix(3, 3) = T(1);
return scaleMatrix;
}
@ -117,9 +110,8 @@ Transform3DScale(const T &scaleX, const T &scaleY, const T &scaleZ)
/// Given a scale factor for the x, y, and z directions (defined in a Vec),
/// returns a transformation matrix for those scales.
///
template<typename T>
VTKM_EXEC_CONT
vtkm::Matrix<T,4,4> Transform3DScale(const vtkm::Vec<T,3> &scaleVec)
template <typename T>
VTKM_EXEC_CONT vtkm::Matrix<T, 4, 4> Transform3DScale(const vtkm::Vec<T, 3>& scaleVec)
{
return vtkm::Transform3DScale(scaleVec[0], scaleVec[1], scaleVec[2]);
}
@ -129,29 +121,26 @@ vtkm::Matrix<T,4,4> Transform3DScale(const vtkm::Vec<T,3> &scaleVec)
/// Given a uniform scale factor, returns a transformation matrix for those
/// scales.
///
template<typename T>
VTKM_EXEC_CONT
vtkm::Matrix<T,4,4> Transform3DScale(const T &scale)
template <typename T>
VTKM_EXEC_CONT vtkm::Matrix<T, 4, 4> Transform3DScale(const T& scale)
{
return vtkm::Transform3DScale(scale, scale, scale);
}
/// \brief Returns a translation matrix.
///
template<typename T>
VTKM_EXEC_CONT
vtkm::Matrix<T,4,4> Transform3DTranslate(const T &x, const T &y, const T &z)
template <typename T>
VTKM_EXEC_CONT vtkm::Matrix<T, 4, 4> Transform3DTranslate(const T& x, const T& y, const T& z)
{
vtkm::Matrix<T,4,4> translateMatrix;
vtkm::Matrix<T, 4, 4> translateMatrix;
vtkm::MatrixIdentity(translateMatrix);
translateMatrix(0,3) = x;
translateMatrix(1,3) = y;
translateMatrix(2,3) = z;
translateMatrix(0, 3) = x;
translateMatrix(1, 3) = y;
translateMatrix(2, 3) = z;
return translateMatrix;
}
template<typename T>
VTKM_EXEC_CONT
vtkm::Matrix<T,4,4> Transform3DTranslate(const vtkm::Vec<T,3> &v)
template <typename T>
VTKM_EXEC_CONT vtkm::Matrix<T, 4, 4> Transform3DTranslate(const vtkm::Vec<T, 3>& v)
{
return vtkm::Transform3DTranslate(v[0], v[1], v[2]);
}
@ -163,54 +152,51 @@ vtkm::Matrix<T,4,4> Transform3DTranslate(const vtkm::Vec<T,3> &v)
/// follows the right-hand rule, so if the vector points toward the user, the
/// rotation will be counterclockwise.
///
template<typename T>
VTKM_EXEC_CONT
vtkm::Matrix<T,4,4> Transform3DRotate(T angleDegrees,
const vtkm::Vec<T,3> &axisOfRotation)
template <typename T>
VTKM_EXEC_CONT vtkm::Matrix<T, 4, 4> Transform3DRotate(T angleDegrees,
const vtkm::Vec<T, 3>& axisOfRotation)
{
T angleRadians = static_cast<T>(vtkm::Pi()/180)*angleDegrees;
const vtkm::Vec<T,3> normAxis = vtkm::Normal(axisOfRotation);
T angleRadians = static_cast<T>(vtkm::Pi() / 180) * angleDegrees;
const vtkm::Vec<T, 3> normAxis = vtkm::Normal(axisOfRotation);
T sinAngle = vtkm::Sin(angleRadians);
T cosAngle = vtkm::Cos(angleRadians);
vtkm::Matrix<T,4,4> matrix;
vtkm::Matrix<T, 4, 4> matrix;
matrix(0,0) = normAxis[0]*normAxis[0]*(1-cosAngle) + cosAngle;
matrix(0,1) = normAxis[0]*normAxis[1]*(1-cosAngle) - normAxis[2]*sinAngle;
matrix(0,2) = normAxis[0]*normAxis[2]*(1-cosAngle) + normAxis[1]*sinAngle;
matrix(0,3) = T(0);
matrix(0, 0) = normAxis[0] * normAxis[0] * (1 - cosAngle) + cosAngle;
matrix(0, 1) = normAxis[0] * normAxis[1] * (1 - cosAngle) - normAxis[2] * sinAngle;
matrix(0, 2) = normAxis[0] * normAxis[2] * (1 - cosAngle) + normAxis[1] * sinAngle;
matrix(0, 3) = T(0);
matrix(1,0) = normAxis[1]*normAxis[0]*(1-cosAngle) + normAxis[2]*sinAngle;
matrix(1,1) = normAxis[1]*normAxis[1]*(1-cosAngle) + cosAngle;
matrix(1,2) = normAxis[1]*normAxis[2]*(1-cosAngle) - normAxis[0]*sinAngle;
matrix(1,3) = T(0);
matrix(1, 0) = normAxis[1] * normAxis[0] * (1 - cosAngle) + normAxis[2] * sinAngle;
matrix(1, 1) = normAxis[1] * normAxis[1] * (1 - cosAngle) + cosAngle;
matrix(1, 2) = normAxis[1] * normAxis[2] * (1 - cosAngle) - normAxis[0] * sinAngle;
matrix(1, 3) = T(0);
matrix(2,0) = normAxis[2]*normAxis[0]*(1-cosAngle) - normAxis[1]*sinAngle;
matrix(2,1) = normAxis[2]*normAxis[1]*(1-cosAngle) + normAxis[0]*sinAngle;
matrix(2,2) = normAxis[2]*normAxis[2]*(1-cosAngle) + cosAngle;
matrix(2,3) = T(0);
matrix(2, 0) = normAxis[2] * normAxis[0] * (1 - cosAngle) - normAxis[1] * sinAngle;
matrix(2, 1) = normAxis[2] * normAxis[1] * (1 - cosAngle) + normAxis[0] * sinAngle;
matrix(2, 2) = normAxis[2] * normAxis[2] * (1 - cosAngle) + cosAngle;
matrix(2, 3) = T(0);
matrix(3,0) = T(0);
matrix(3,1) = T(0);
matrix(3,2) = T(0);
matrix(3,3) = T(1);
matrix(3, 0) = T(0);
matrix(3, 1) = T(0);
matrix(3, 2) = T(0);
matrix(3, 3) = T(1);
return matrix;
}
template<typename T>
VTKM_EXEC_CONT
vtkm::Matrix<T,4,4> Transform3DRotate(T angleDegrees, T x, T y, T z)
template <typename T>
VTKM_EXEC_CONT vtkm::Matrix<T, 4, 4> Transform3DRotate(T angleDegrees, T x, T y, T z)
{
return vtkm::Transform3DRotate(angleDegrees, vtkm::Vec<T,3>(x,y,z));
return vtkm::Transform3DRotate(angleDegrees, vtkm::Vec<T, 3>(x, y, z));
}
/// \brief Returns a rotation matrix.
///
/// Returns a transformation matrix that rotates around the x axis.
///
template<typename T>
VTKM_EXEC_CONT
vtkm::Matrix<T,4,4> Transform3DRotateX(T angleDegrees)
template <typename T>
VTKM_EXEC_CONT vtkm::Matrix<T, 4, 4> Transform3DRotateX(T angleDegrees)
{
return vtkm::Transform3DRotate(angleDegrees, T(1), T(0), T(0));
}
@ -219,9 +205,8 @@ vtkm::Matrix<T,4,4> Transform3DRotateX(T angleDegrees)
///
/// Returns a transformation matrix that rotates around the y axis.
///
template<typename T>
VTKM_EXEC_CONT
vtkm::Matrix<T,4,4> Transform3DRotateY(T angleDegrees)
template <typename T>
VTKM_EXEC_CONT vtkm::Matrix<T, 4, 4> Transform3DRotateY(T angleDegrees)
{
return vtkm::Transform3DRotate(angleDegrees, T(0), T(1), T(0));
}
@ -230,9 +215,8 @@ vtkm::Matrix<T,4,4> Transform3DRotateY(T angleDegrees)
///
/// Returns a transformation matrix that rotates around the z axis.
///
template<typename T>
VTKM_EXEC_CONT
vtkm::Matrix<T,4,4> Transform3DRotateZ(T angleDegrees)
template <typename T>
VTKM_EXEC_CONT vtkm::Matrix<T, 4, 4> Transform3DRotateZ(T angleDegrees)
{
return vtkm::Transform3DRotate(angleDegrees, T(0), T(0), T(1));
}

@ -27,132 +27,148 @@
#include <vtkm/ListTag.h>
#include <vtkm/Types.h>
namespace vtkm {
namespace vtkm
{
/// A list containing the type vtkm::Id.
///
struct TypeListTagId : vtkm::ListTagBase<vtkm::Id> { };
struct TypeListTagId : vtkm::ListTagBase<vtkm::Id>
{
};
/// A list containing the type vtkm::Id2.
///
struct TypeListTagId2 : vtkm::ListTagBase<vtkm::Id2> { };
struct TypeListTagId2 : vtkm::ListTagBase<vtkm::Id2>
{
};
/// A list containing the type vtkm::Id3.
///
struct TypeListTagId3 : vtkm::ListTagBase<vtkm::Id3> { };
struct TypeListTagId3 : vtkm::ListTagBase<vtkm::Id3>
{
};
/// A list containing the type vtkm::IdComponent
///
struct TypeListTagIdComponent : vtkm::ListTagBase<vtkm::IdComponent> { };
struct TypeListTagIdComponent : vtkm::ListTagBase<vtkm::IdComponent>
{
};
/// A list containing types used to index arrays. Contains vtkm::Id, vtkm::Id2,
/// and vtkm::Id3.
///
struct TypeListTagIndex
: vtkm::ListTagBase<vtkm::Id,vtkm::Id2,vtkm::Id3> { };
struct TypeListTagIndex : vtkm::ListTagBase<vtkm::Id, vtkm::Id2, vtkm::Id3>
{
};
/// A list containing types used for scalar fields. Specifically, contains
/// floating point numbers of different widths (i.e. vtkm::Float32 and
/// vtkm::Float64).
struct TypeListTagFieldScalar : vtkm::ListTagBase<vtkm::Float32,vtkm::Float64> { };
struct TypeListTagFieldScalar : vtkm::ListTagBase<vtkm::Float32, vtkm::Float64>
{
};
/// A list containing types for values for fields with two dimensional
/// vectors.
///
struct TypeListTagFieldVec2
: vtkm::ListTagBase<vtkm::Vec<vtkm::Float32,2>,
vtkm::Vec<vtkm::Float64,2> > { };
: vtkm::ListTagBase<vtkm::Vec<vtkm::Float32, 2>, vtkm::Vec<vtkm::Float64, 2>>
{
};
/// A list containing types for values for fields with three dimensional
/// vectors.
///
struct TypeListTagFieldVec3
: vtkm::ListTagBase<vtkm::Vec<vtkm::Float32,3>,
vtkm::Vec<vtkm::Float64,3> > { };
: vtkm::ListTagBase<vtkm::Vec<vtkm::Float32, 3>, vtkm::Vec<vtkm::Float64, 3>>
{
};
/// A list containing types for values for fields with four dimensional
/// vectors.
///
struct TypeListTagFieldVec4
: vtkm::ListTagBase<vtkm::Vec<vtkm::Float32,4>,
vtkm::Vec<vtkm::Float64,4> > { };
: vtkm::ListTagBase<vtkm::Vec<vtkm::Float32, 4>, vtkm::Vec<vtkm::Float64, 4>>
{
};
/// A list containing common types for values in fields. Specifically contains
/// floating point scalars and vectors of size 2, 3, and 4 with floating point
/// components.
///
struct TypeListTagField
: vtkm::ListTagBase<vtkm::Float32,
vtkm::Float64,
vtkm::Vec<vtkm::Float32,2>,
vtkm::Vec<vtkm::Float64,2>,
vtkm::Vec<vtkm::Float32,3>,
vtkm::Vec<vtkm::Float64,3>,
vtkm::Vec<vtkm::Float32,4>,
vtkm::Vec<vtkm::Float64,4> >
{ };
struct TypeListTagField : vtkm::ListTagBase<vtkm::Float32,
vtkm::Float64,
vtkm::Vec<vtkm::Float32, 2>,
vtkm::Vec<vtkm::Float64, 2>,
vtkm::Vec<vtkm::Float32, 3>,
vtkm::Vec<vtkm::Float64, 3>,
vtkm::Vec<vtkm::Float32, 4>,
vtkm::Vec<vtkm::Float64, 4>>
{
};
/// A list of all scalars defined in vtkm/Types.h. A scalar is a type that
/// holds a single number.
///
struct TypeListTagScalarAll
: vtkm::ListTagBase<vtkm::Int8,
vtkm::UInt8,
vtkm::Int16,
vtkm::UInt16,
vtkm::Int32,
vtkm::UInt32,
vtkm::Int64,
vtkm::UInt64,
vtkm::Float32,
vtkm::Float64>
{ };
struct TypeListTagScalarAll : vtkm::ListTagBase<vtkm::Int8,
vtkm::UInt8,
vtkm::Int16,
vtkm::UInt16,
vtkm::Int32,
vtkm::UInt32,
vtkm::Int64,
vtkm::UInt64,
vtkm::Float32,
vtkm::Float64>
{
};
/// A list of the most commonly use Vec classes. Specifically, these are
/// vectors of size 2, 3, or 4 containing either unsigned bytes, signed
/// integers of 32 or 64 bits, or floating point values of 32 or 64 bits.
///
struct TypeListTagVecCommon
: vtkm::ListTagBase<vtkm::Vec<vtkm::UInt8,2>,
vtkm::Vec<vtkm::Int32,2>,
vtkm::Vec<vtkm::Int64,2>,
vtkm::Vec<vtkm::Float32,2>,
vtkm::Vec<vtkm::Float64,2>,
vtkm::Vec<vtkm::UInt8,3>,
vtkm::Vec<vtkm::Int32,3>,
vtkm::Vec<vtkm::Int64,3>,
vtkm::Vec<vtkm::Float32,3>,
vtkm::Vec<vtkm::Float64,3>,
vtkm::Vec<vtkm::UInt8,4>,
vtkm::Vec<vtkm::Int32,4>,
vtkm::Vec<vtkm::Int64,4>,
vtkm::Vec<vtkm::Float32,4>,
vtkm::Vec<vtkm::Float64,4> >
{ };
struct TypeListTagVecCommon : vtkm::ListTagBase<vtkm::Vec<vtkm::UInt8, 2>,
vtkm::Vec<vtkm::Int32, 2>,
vtkm::Vec<vtkm::Int64, 2>,
vtkm::Vec<vtkm::Float32, 2>,
vtkm::Vec<vtkm::Float64, 2>,
vtkm::Vec<vtkm::UInt8, 3>,
vtkm::Vec<vtkm::Int32, 3>,
vtkm::Vec<vtkm::Int64, 3>,
vtkm::Vec<vtkm::Float32, 3>,
vtkm::Vec<vtkm::Float64, 3>,
vtkm::Vec<vtkm::UInt8, 4>,
vtkm::Vec<vtkm::Int32, 4>,
vtkm::Vec<vtkm::Int64, 4>,
vtkm::Vec<vtkm::Float32, 4>,
vtkm::Vec<vtkm::Float64, 4>>
{
};
namespace internal {
namespace internal
{
/// A list of uncommon Vec classes with length up to 4. This is not much
/// use in general, but is used when joined with \c TypeListTagVecCommon
/// to get a list of all vectors up to size 4.
///
struct TypeListTagVecUncommon
: vtkm::ListTagBase<vtkm::Vec<vtkm::Int8,2>,
vtkm::Vec<vtkm::Int16,2>,
vtkm::Vec<vtkm::UInt16,2>,
vtkm::Vec<vtkm::UInt32,2>,
vtkm::Vec<vtkm::UInt64,2>,
vtkm::Vec<vtkm::Int8,3>,
vtkm::Vec<vtkm::Int16,3>,
vtkm::Vec<vtkm::UInt16,3>,
vtkm::Vec<vtkm::UInt32,3>,
vtkm::Vec<vtkm::UInt64,3>,
vtkm::Vec<vtkm::Int8,4>,
vtkm::Vec<vtkm::Int16,4>,
vtkm::Vec<vtkm::UInt16,4>,
vtkm::Vec<vtkm::UInt32,4>,
vtkm::Vec<vtkm::UInt64,4> >
{ };
struct TypeListTagVecUncommon : vtkm::ListTagBase<vtkm::Vec<vtkm::Int8, 2>,
vtkm::Vec<vtkm::Int16, 2>,
vtkm::Vec<vtkm::UInt16, 2>,
vtkm::Vec<vtkm::UInt32, 2>,
vtkm::Vec<vtkm::UInt64, 2>,
vtkm::Vec<vtkm::Int8, 3>,
vtkm::Vec<vtkm::Int16, 3>,
vtkm::Vec<vtkm::UInt16, 3>,
vtkm::Vec<vtkm::UInt32, 3>,
vtkm::Vec<vtkm::UInt64, 3>,
vtkm::Vec<vtkm::Int8, 4>,
vtkm::Vec<vtkm::Int16, 4>,
vtkm::Vec<vtkm::UInt16, 4>,
vtkm::Vec<vtkm::UInt32, 4>,
vtkm::Vec<vtkm::UInt64, 4>>
{
};
} // namespace internal
@ -160,35 +176,35 @@ struct TypeListTagVecUncommon
/// lengths between 2 and 4.
///
struct TypeListTagVecAll
: vtkm::ListTagJoin<
vtkm::TypeListTagVecCommon, vtkm::internal::TypeListTagVecUncommon>
{ };
: vtkm::ListTagJoin<vtkm::TypeListTagVecCommon, vtkm::internal::TypeListTagVecUncommon>
{
};
/// A list of all basic types listed in vtkm/Types.h. Does not include all
/// possible VTK-m types like arbitrarily typed and sized Vecs (only up to
/// length 4) or math types like matrices.
///
struct TypeListTagAll
: vtkm::ListTagJoin<vtkm::TypeListTagScalarAll, vtkm::TypeListTagVecAll>
{ };
struct TypeListTagAll : vtkm::ListTagJoin<vtkm::TypeListTagScalarAll, vtkm::TypeListTagVecAll>
{
};
/// A list of the most commonly used types across multiple domains. Includes
/// integers, floating points, and 3 dimensional vectors of floating points.
///
struct TypeListTagCommon
: vtkm::ListTagBase<vtkm::Int32,
vtkm::Int64,
vtkm::Float32,
vtkm::Float64,
vtkm::Vec<vtkm::Float32,3>,
vtkm::Vec<vtkm::Float64,3> >
{ };
struct TypeListTagCommon : vtkm::ListTagBase<vtkm::Int32,
vtkm::Int64,
vtkm::Float32,
vtkm::Float64,
vtkm::Vec<vtkm::Float32, 3>,
vtkm::Vec<vtkm::Float64, 3>>
{
};
// Special implementation of ListContains for TypeListTagAll to always be
// true. Although TypeListTagAll is necessarily finite, the point is to
// be all inclusive. Besides, this should speed up the compilation when
// checking a list that should contain everything.
template<typename Type>
template <typename Type>
struct ListContains<vtkm::TypeListTagAll, Type>
{
static const bool value = true;

@ -22,42 +22,52 @@
#include <vtkm/Types.h>
namespace vtkm {
namespace vtkm
{
/// Tag used to identify types that aren't Real, Integer, Scalar or Vector.
///
struct TypeTraitsUnknownTag {};
struct TypeTraitsUnknownTag
{
};
/// Tag used to identify types that store real (floating-point) numbers. A
/// TypeTraits class will typedef this class to NumericTag if it stores real
/// numbers (or vectors of real numbers).
///
struct TypeTraitsRealTag {};
struct TypeTraitsRealTag
{
};
/// Tag used to identify types that store integer numbers. A TypeTraits class
/// will typedef this class to NumericTag if it stores integer numbers (or
/// vectors of integers).
///
struct TypeTraitsIntegerTag {};
struct TypeTraitsIntegerTag
{
};
/// Tag used to identify 0 dimensional types (scalars). Scalars can also be
/// treated like vectors when used with VecTraits. A TypeTraits class will
/// typedef this class to DimensionalityTag.
///
struct TypeTraitsScalarTag {};
struct TypeTraitsScalarTag
{
};
/// Tag used to identify 1 dimensional types (vectors). A TypeTraits class will
/// typedef this class to DimensionalityTag.
///
struct TypeTraitsVectorTag {};
struct TypeTraitsVectorTag
{
};
/// The TypeTraits class provides helpful compile-time information about the
/// basic types used in VTKm (and a few others for convienience). The majority
/// of TypeTraits contents are typedefs to tags that can be used to easily
/// override behavior of called functions.
///
template<typename T>
template <typename T>
class TypeTraits
{
public:
@ -77,27 +87,32 @@ public:
// Const types should have the same traits as their non-const counterparts.
//
template<typename T>
template <typename T>
struct TypeTraits<const T> : TypeTraits<T>
{ };
{
};
#define VTKM_BASIC_REAL_TYPE(T) \
template<> struct TypeTraits<T> { \
typedef TypeTraitsRealTag NumericTag; \
typedef TypeTraitsScalarTag DimensionalityTag; \
VTKM_EXEC_CONT static T ZeroInitialization() { return T(); } \
#define VTKM_BASIC_REAL_TYPE(T) \
template <> \
struct TypeTraits<T> \
{ \
typedef TypeTraitsRealTag NumericTag; \
typedef TypeTraitsScalarTag DimensionalityTag; \
VTKM_EXEC_CONT static T ZeroInitialization() { return T(); } \
};
#define VTKM_BASIC_INTEGER_TYPE(T) \
template<> struct TypeTraits< T > { \
typedef TypeTraitsIntegerTag NumericTag; \
typedef TypeTraitsScalarTag DimensionalityTag; \
VTKM_EXEC_CONT static T ZeroInitialization() \
{ \
typedef T ReturnType; \
return ReturnType(); \
} \
}; \
#define VTKM_BASIC_INTEGER_TYPE(T) \
template <> \
struct TypeTraits<T> \
{ \
typedef TypeTraitsIntegerTag NumericTag; \
typedef TypeTraitsScalarTag DimensionalityTag; \
VTKM_EXEC_CONT static T ZeroInitialization() \
{ \
typedef T ReturnType; \
return ReturnType(); \
} \
};
/// Traits for basic C++ types.
///
@ -117,64 +132,61 @@ VTKM_BASIC_INTEGER_TYPE(unsigned long)
VTKM_BASIC_INTEGER_TYPE(long long)
VTKM_BASIC_INTEGER_TYPE(unsigned long long)
#undef VTKM_BASIC_REAL_TYPE
#undef VTKM_BASIC_INTEGER_TYPE
/// Traits for Vec types.
///
template<typename T, vtkm::IdComponent Size>
struct TypeTraits<vtkm::Vec<T,Size> >
template <typename T, vtkm::IdComponent Size>
struct TypeTraits<vtkm::Vec<T, Size>>
{
typedef typename vtkm::TypeTraits<T>::NumericTag NumericTag;
typedef TypeTraitsVectorTag DimensionalityTag;
VTKM_EXEC_CONT
static vtkm::Vec<T,Size> ZeroInitialization()
static vtkm::Vec<T, Size> ZeroInitialization()
{
return vtkm::Vec<T,Size>(vtkm::TypeTraits<T>::ZeroInitialization());
return vtkm::Vec<T, Size>(vtkm::TypeTraits<T>::ZeroInitialization());
}
};
/// Traits for VecCConst types.
///
template<typename T>
struct TypeTraits<vtkm::VecCConst<T> >
template <typename T>
struct TypeTraits<vtkm::VecCConst<T>>
{
using NumericTag = typename vtkm::TypeTraits<T>::NumericTag;
using DimensionalityTag = TypeTraitsVectorTag;
VTKM_EXEC_CONT
static vtkm::VecCConst<T> ZeroInitialization()
{ return vtkm::VecCConst<T>(); }
static vtkm::VecCConst<T> ZeroInitialization() { return vtkm::VecCConst<T>(); }
};
/// Traits for VecC types.
///
template<typename T>
struct TypeTraits<vtkm::VecC<T> >
template <typename T>
struct TypeTraits<vtkm::VecC<T>>
{
using NumericTag = typename vtkm::TypeTraits<T>::NumericTag;
using DimensionalityTag = TypeTraitsVectorTag;
VTKM_EXEC_CONT
static vtkm::VecC<T> ZeroInitialization()
{ return vtkm::VecC<T>(); }
static vtkm::VecC<T> ZeroInitialization() { return vtkm::VecC<T>(); }
};
/// \brief Traits for Pair types.
///
template<typename T, typename U>
struct TypeTraits<vtkm::Pair<T,U> >
template <typename T, typename U>
struct TypeTraits<vtkm::Pair<T, U>>
{
typedef TypeTraitsUnknownTag NumericTag;
typedef TypeTraitsScalarTag DimensionalityTag;
VTKM_EXEC_CONT
static vtkm::Pair<T,U> ZeroInitialization()
static vtkm::Pair<T, U> ZeroInitialization()
{
return vtkm::Pair<T,U>(TypeTraits<T>::ZeroInitialization(),
TypeTraits<U>::ZeroInitialization());
return vtkm::Pair<T, U>(TypeTraits<T>::ZeroInitialization(),
TypeTraits<U>::ZeroInitialization());
}
};

File diff suppressed because it is too large Load Diff

@ -23,16 +23,17 @@
#include <vtkm/TypeTraits.h>
#include <vtkm/internal/ExportMacros.h>
namespace vtkm {
namespace vtkm
{
/// Predicate that takes a single argument \c x, and returns
/// True if it is the identity of the Type \p T.
struct IsZeroInitialized
{
template<typename T>
VTKM_EXEC_CONT bool operator()(const T &x) const
template <typename T>
VTKM_EXEC_CONT bool operator()(const T& x) const
{
return (x == vtkm::TypeTraits<T>::ZeroInitialization() );
return (x == vtkm::TypeTraits<T>::ZeroInitialization());
}
};
@ -40,10 +41,10 @@ struct IsZeroInitialized
/// True if it isn't the identity of the Type \p T.
struct NotZeroInitialized
{
template<typename T>
VTKM_EXEC_CONT bool operator()(const T &x) const
template <typename T>
VTKM_EXEC_CONT bool operator()(const T& x) const
{
return (x != vtkm::TypeTraits<T>::ZeroInitialization() );
return (x != vtkm::TypeTraits<T>::ZeroInitialization());
}
};
@ -53,7 +54,7 @@ struct NotZeroInitialized
/// ! operator.
struct LogicalNot
{
template<typename T>
template <typename T>
VTKM_EXEC_CONT bool operator()(const T& x) const
{
return !x;

@ -0,0 +1,176 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_VecAxisAlignedPointCoordinates_h
#define vtk_m_VecAxisAlignedPointCoordinates_h
#include <vtkm/Math.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/Types.h>
#include <vtkm/VecTraits.h>
namespace vtkm
{
namespace detail
{
/// Specifies the size of VecAxisAlignedPointCoordinates for the given
/// dimension.
///
template <vtkm::IdComponent NumDimensions>
struct VecAxisAlignedPointCoordinatesNumComponents;
template <>
struct VecAxisAlignedPointCoordinatesNumComponents<1>
{
static const vtkm::IdComponent NUM_COMPONENTS = 2;
};
template <>
struct VecAxisAlignedPointCoordinatesNumComponents<2>
{
static const vtkm::IdComponent NUM_COMPONENTS = 4;
};
template <>
struct VecAxisAlignedPointCoordinatesNumComponents<3>
{
static const vtkm::IdComponent NUM_COMPONENTS = 8;
};
VTKM_EXEC_CONSTANT
const vtkm::FloatDefault VecAxisAlignedPointCoordinatesOffsetTable[8][3] = {
{ 0.0f, 0.0f, 0.0f }, { 1.0f, 0.0f, 0.0f }, { 1.0f, 1.0f, 0.0f }, { 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f }, { 1.0f, 0.0f, 1.0f }, { 1.0f, 1.0f, 1.0f }, { 0.0f, 1.0f, 1.0f }
};
} // namespace detail
/// \brief An implicit vector for point coordinates in axis aligned cells. For
/// internal use only.
///
/// The \C VecAxisAlignedPointCoordinates class is a Vec-like class that holds
/// the point coordinates for a axis aligned cell. The class is templated on the
/// dimensions of the cell, which can be 1 (for a line).
///
/// This is an internal class used to represent coordinates for uniform datasets
/// in an execution environment when executing a WorkletMapPointToCell. Users
/// should not directly construct this class under any circumstances. Use the
/// related ArrayPortalUniformPointCoordinates and
/// ArrayHandleUniformPointCoordinates classes instead.
///
template <vtkm::IdComponent NumDimensions>
class VecAxisAlignedPointCoordinates
{
public:
typedef vtkm::Vec<vtkm::FloatDefault, 3> ComponentType;
static const vtkm::IdComponent NUM_COMPONENTS =
detail::VecAxisAlignedPointCoordinatesNumComponents<NumDimensions>::NUM_COMPONENTS;
VTKM_EXEC_CONT
VecAxisAlignedPointCoordinates(ComponentType origin = ComponentType(0, 0, 0),
ComponentType spacing = ComponentType(1, 1, 1))
: Origin(origin)
, Spacing(spacing)
{
}
VTKM_EXEC_CONT
vtkm::IdComponent GetNumberOfComponents() const { return NUM_COMPONENTS; }
template <vtkm::IdComponent DestSize>
VTKM_EXEC_CONT void CopyInto(vtkm::Vec<ComponentType, DestSize>& dest) const
{
vtkm::IdComponent numComponents = vtkm::Min(DestSize, this->GetNumberOfComponents());
for (vtkm::IdComponent index = 0; index < numComponents; index++)
{
dest[index] = (*this)[index];
}
}
VTKM_EXEC_CONT
ComponentType operator[](vtkm::IdComponent index) const
{
const vtkm::FloatDefault* offset = detail::VecAxisAlignedPointCoordinatesOffsetTable[index];
return ComponentType(this->Origin[0] + offset[0] * this->Spacing[0],
this->Origin[1] + offset[1] * this->Spacing[1],
this->Origin[2] + offset[2] * this->Spacing[2]);
}
VTKM_EXEC_CONT
const ComponentType& GetOrigin() const { return this->Origin; }
VTKM_EXEC_CONT
const ComponentType& GetSpacing() const { return this->Spacing; }
private:
// Position of lower left point.
ComponentType Origin;
// Spacing in the x, y, and z directions.
ComponentType Spacing;
};
template <vtkm::IdComponent NumDimensions>
struct TypeTraits<vtkm::VecAxisAlignedPointCoordinates<NumDimensions>>
{
typedef vtkm::TypeTraitsRealTag NumericTag;
typedef TypeTraitsVectorTag DimensionalityTag;
VTKM_EXEC_CONT
static vtkm::VecAxisAlignedPointCoordinates<NumDimensions> ZeroInitialization()
{
return vtkm::VecAxisAlignedPointCoordinates<NumDimensions>(
vtkm::Vec<vtkm::FloatDefault, 3>(0, 0, 0), vtkm::Vec<vtkm::FloatDefault, 3>(0, 0, 0));
}
};
template <vtkm::IdComponent NumDimensions>
struct VecTraits<vtkm::VecAxisAlignedPointCoordinates<NumDimensions>>
{
typedef vtkm::VecAxisAlignedPointCoordinates<NumDimensions> VecType;
typedef vtkm::Vec<vtkm::FloatDefault, 3> ComponentType;
typedef vtkm::VecTraitsTagMultipleComponents HasMultipleComponents;
typedef vtkm::VecTraitsTagSizeStatic IsSizeStatic;
static const vtkm::IdComponent NUM_COMPONENTS = VecType::NUM_COMPONENTS;
VTKM_EXEC_CONT
static vtkm::IdComponent GetNumberOfComponents(const VecType&) { return NUM_COMPONENTS; }
VTKM_EXEC_CONT
static ComponentType GetComponent(const VecType& vector, vtkm::IdComponent componentIndex)
{
return vector[componentIndex];
}
template <vtkm::IdComponent destSize>
VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec<ComponentType, destSize>& dest)
{
src.CopyInto(dest);
}
};
} // namespace vtkm
#endif //vtk_m_VecAxisAlignedPointCoordinates_h

@ -21,45 +21,48 @@
#define vtk_m_VecFromPortal_h
#include <vtkm/Math.h>
#include <vtkm/Types.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/Types.h>
#include <vtkm/VecTraits.h>
#include <vtkm/internal/ArrayPortalValueReference.h>
namespace vtkm {
namespace vtkm
{
/// \brief A short variable-length array from a window in an ArrayPortal.
///
/// The \c VecFromPortal class is a Vec-like class that holds an array portal
/// and exposes a small window of that portal as if it were a \c Vec.
///
template<typename PortalType>
template <typename PortalType>
class VecFromPortal
{
public:
using ComponentType =
typename std::remove_const<typename PortalType::ValueType>::type;
using ComponentType = typename std::remove_const<typename PortalType::ValueType>::type;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
VecFromPortal() : NumComponents(0), Offset(0) { }
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
VecFromPortal(const PortalType &portal,
vtkm::IdComponent numComponents = 0,
vtkm::Id offset = 0)
: Portal(portal), NumComponents(numComponents), Offset(offset) { }
VTKM_EXEC_CONT
vtkm::IdComponent GetNumberOfComponents() const {
return this->NumComponents;
VecFromPortal()
: NumComponents(0)
, Offset(0)
{
}
template<typename T, vtkm::IdComponent DestSize>
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
void CopyInto(vtkm::Vec<T,DestSize> &dest) const
VecFromPortal(const PortalType& portal, vtkm::IdComponent numComponents = 0, vtkm::Id offset = 0)
: Portal(portal)
, NumComponents(numComponents)
, Offset(offset)
{
}
VTKM_EXEC_CONT
vtkm::IdComponent GetNumberOfComponents() const { return this->NumComponents; }
template <typename T, vtkm::IdComponent DestSize>
VTKM_EXEC_CONT void CopyInto(vtkm::Vec<T, DestSize>& dest) const
{
vtkm::IdComponent numComponents = vtkm::Min(DestSize, this->NumComponents);
for (vtkm::IdComponent index = 0; index < numComponents; index++)
@ -70,11 +73,10 @@ public:
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
vtkm::internal::ArrayPortalValueReference<PortalType>
operator[](vtkm::IdComponent index) const
vtkm::internal::ArrayPortalValueReference<PortalType> operator[](vtkm::IdComponent index) const
{
return vtkm::internal::ArrayPortalValueReference<PortalType>(
this->Portal, index + this->Offset);
return vtkm::internal::ArrayPortalValueReference<PortalType>(this->Portal,
index + this->Offset);
}
private:
@ -83,8 +85,8 @@ private:
vtkm::Id Offset;
};
template<typename PortalType>
struct TypeTraits<vtkm::VecFromPortal<PortalType> >
template <typename PortalType>
struct TypeTraits<vtkm::VecFromPortal<PortalType>>
{
private:
typedef typename PortalType::ValueType ComponentType;
@ -101,8 +103,8 @@ public:
}
};
template<typename PortalType>
struct VecTraits<vtkm::VecFromPortal<PortalType> >
template <typename PortalType>
struct VecTraits<vtkm::VecFromPortal<PortalType>>
{
typedef vtkm::VecFromPortal<PortalType> VecType;
@ -112,23 +114,21 @@ struct VecTraits<vtkm::VecFromPortal<PortalType> >
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
static vtkm::IdComponent GetNumberOfComponents(const VecType &vector) {
static vtkm::IdComponent GetNumberOfComponents(const VecType& vector)
{
return vector.GetNumberOfComponents();
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
static ComponentType GetComponent(const VecType &vector,
vtkm::IdComponent componentIndex)
static ComponentType GetComponent(const VecType& vector, vtkm::IdComponent componentIndex)
{
return vector[componentIndex];
}
VTKM_SUPPRESS_EXEC_WARNINGS
template<vtkm::IdComponent destSize>
VTKM_EXEC_CONT
static void CopyInto(const VecType &src,
vtkm::Vec<ComponentType,destSize> &dest)
template <vtkm::IdComponent destSize>
VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec<ComponentType, destSize>& dest)
{
src.CopyInto(dest);
}

@ -21,11 +21,12 @@
#define vtk_m_VecFromPortalPermute_h
#include <vtkm/Math.h>
#include <vtkm/Types.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/Types.h>
#include <vtkm/VecTraits.h>
namespace vtkm {
namespace vtkm
{
/// \brief A short vector from an ArrayPortal and a vector of indices.
///
@ -33,93 +34,56 @@ namespace vtkm {
/// portal and a second Vec-like containing indices into the array. Each value
/// of this vector is the value from the array with the respective index.
///
template<typename IndexVecType, typename PortalType>
template <typename IndexVecType, typename PortalType>
class VecFromPortalPermute
{
public:
using ComponentType =
typename std::remove_const<typename PortalType::ValueType>::type;
using ComponentType = typename std::remove_const<typename PortalType::ValueType>::type;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
VecFromPortalPermute() { }
VecFromPortalPermute() {}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
VecFromPortalPermute(const IndexVecType *indices, const PortalType &portal)
: Indices(indices), Portal(portal) { }
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
vtkm::IdComponent GetNumberOfComponents() const {
return this->Indices->GetNumberOfComponents();
VecFromPortalPermute(const IndexVecType* indices, const PortalType& portal)
: Indices(indices)
, Portal(portal)
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
template<vtkm::IdComponent DestSize>
VTKM_EXEC_CONT
//DRP
/*inline*/ void CopyInto(vtkm::Vec<ComponentType,DestSize> &dest) const
vtkm::IdComponent GetNumberOfComponents() const { return this->Indices->GetNumberOfComponents(); }
VTKM_SUPPRESS_EXEC_WARNINGS
template <vtkm::IdComponent DestSize>
VTKM_EXEC_CONT void CopyInto(vtkm::Vec<ComponentType, DestSize>& dest) const
{
vtkm::IdComponent numComponents =
vtkm::Min(DestSize, this->GetNumberOfComponents());
vtkm::IdComponent numComponents = vtkm::Min(DestSize, this->GetNumberOfComponents());
for (vtkm::IdComponent index = 0; index < numComponents; index++)
{
dest[index] = (*this)[index];
}
}
//DRP
VTKM_SUPPRESS_EXEC_WARNINGS
template<vtkm::IdComponent DestSize>
VTKM_EXEC_CONT
inline void CopyRangeInto(vtkm::Vec<ComponentType,DestSize> &dest) const
{
this->Portal.CopyRangeInto((*this->Indices), dest);
}
//DRP
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
inline void Copy8(vtkm::Vec<ComponentType,8> &dest) const
{
this->Portal.Get8((*this->Indices), dest);
//dest[0] = this->Portal.Get_1((*this->Indices)); //(*this->Indices));
/*
dest[0] = this->Portal.Get((*this->Indices)[0]);
dest[1] = this->Portal.Get((*this->Indices)[1]);
dest[2] = this->Portal.Get((*this->Indices)[2]);
dest[3] = this->Portal.Get((*this->Indices)[3]);
dest[4] = this->Portal.Get((*this->Indices)[4]);
dest[5] = this->Portal.Get((*this->Indices)[5]);
dest[6] = this->Portal.Get((*this->Indices)[6]);
dest[7] = this->Portal.Get((*this->Indices)[7]);
*/
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
//DRP
/* inline*/ ComponentType operator[](vtkm::IdComponent index) const
ComponentType operator[](vtkm::IdComponent index) const
{
return this->Portal.Get((*this->Indices)[index]);
}
private:
const IndexVecType *Indices;
const IndexVecType* Indices;
PortalType Portal;
};
template<typename IndexVecType, typename PortalType>
struct TypeTraits<
vtkm::VecFromPortalPermute<IndexVecType,PortalType> >
template <typename IndexVecType, typename PortalType>
struct TypeTraits<vtkm::VecFromPortalPermute<IndexVecType, PortalType>>
{
private:
typedef vtkm::VecFromPortalPermute<IndexVecType,PortalType>
VecType;
typedef vtkm::VecFromPortalPermute<IndexVecType, PortalType> VecType;
typedef typename PortalType::ValueType ComponentType;
public:
@ -128,18 +92,13 @@ public:
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
static VecType ZeroInitialization()
{
return VecType();
}
static VecType ZeroInitialization() { return VecType(); }
};
template<typename IndexVecType, typename PortalType>
struct VecTraits<
vtkm::VecFromPortalPermute<IndexVecType,PortalType> >
template <typename IndexVecType, typename PortalType>
struct VecTraits<vtkm::VecFromPortalPermute<IndexVecType, PortalType>>
{
typedef vtkm::VecFromPortalPermute<IndexVecType,PortalType>
VecType;
typedef vtkm::VecFromPortalPermute<IndexVecType, PortalType> VecType;
typedef typename VecType::ComponentType ComponentType;
typedef vtkm::VecTraitsTagMultipleComponents HasMultipleComponents;
@ -147,23 +106,21 @@ struct VecTraits<
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
static vtkm::IdComponent GetNumberOfComponents(const VecType &vector) {
static vtkm::IdComponent GetNumberOfComponents(const VecType& vector)
{
return vector.GetNumberOfComponents();
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
static ComponentType GetComponent(const VecType &vector,
vtkm::IdComponent componentIndex)
static ComponentType GetComponent(const VecType& vector, vtkm::IdComponent componentIndex)
{
return vector[componentIndex];
}
VTKM_SUPPRESS_EXEC_WARNINGS
template<vtkm::IdComponent destSize>
VTKM_EXEC_CONT
static void CopyInto(const VecType &src,
vtkm::Vec<ComponentType,destSize> &dest)
template <vtkm::IdComponent destSize>
VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec<ComponentType, destSize>& dest)
{
src.CopyInto(dest);
}

@ -1,180 +0,0 @@
//============================================================================
// 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 Sandia Corporation.
// Copyright 2015 UT-Battelle, LLC.
// Copyright 2015 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#ifndef vtk_m_exec_VecRectilinearPointCoordinates_h
#define vtk_m_exec_VecRectilinearPointCoordinates_h
#include <vtkm/Math.h>
#include <vtkm/Types.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/VecTraits.h>
namespace vtkm {
namespace detail {
/// Specifies the size of VecRectilinearPointCoordinates for the given
/// dimension.
///
template<vtkm::IdComponent NumDimensions>
struct VecRectilinearPointCoordinatesNumComponents;
template<>
struct VecRectilinearPointCoordinatesNumComponents<1>
{
static const vtkm::IdComponent NUM_COMPONENTS = 2;
};
template<>
struct VecRectilinearPointCoordinatesNumComponents<2>
{
static const vtkm::IdComponent NUM_COMPONENTS = 4;
};
template<>
struct VecRectilinearPointCoordinatesNumComponents<3>
{
static const vtkm::IdComponent NUM_COMPONENTS = 8;
};
VTKM_EXEC_CONSTANT
const vtkm::FloatDefault VecRectilinearPointCoordinatesOffsetTable[8][3] = {
{ 0.0f, 0.0f, 0.0f },
{ 1.0f, 0.0f, 0.0f },
{ 1.0f, 1.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f },
{ 1.0f, 0.0f, 1.0f },
{ 1.0f, 1.0f, 1.0f },
{ 0.0f, 1.0f, 1.0f }
};
} // namespace detail
/// \brief An implicit vector for point coordinates in rectilinear cells.
///
/// The \C VecRectilinearPointCoordinates class is a Vec-like class that holds
/// the point coordinates for a rectilinear cell. The class is templated on the
/// dimensions of the cell, which can be 1 (for a line), 2 (for a pixel), or 3
/// (for a voxel).
///
template<vtkm::IdComponent NumDimensions>
class VecRectilinearPointCoordinates
{
public:
typedef vtkm::Vec<vtkm::FloatDefault,3> ComponentType;
static const vtkm::IdComponent NUM_COMPONENTS =
detail::VecRectilinearPointCoordinatesNumComponents<NumDimensions>::NUM_COMPONENTS;
VTKM_EXEC_CONT
VecRectilinearPointCoordinates(ComponentType origin = ComponentType(0,0,0),
ComponentType spacing = ComponentType(1,1,1))
: Origin(origin), Spacing(spacing) { }
VTKM_EXEC_CONT
vtkm::IdComponent GetNumberOfComponents() const { return NUM_COMPONENTS; }
template<vtkm::IdComponent DestSize>
VTKM_EXEC_CONT
void CopyInto(vtkm::Vec<ComponentType,DestSize> &dest) const
{
vtkm::IdComponent numComponents =
vtkm::Min(DestSize, this->GetNumberOfComponents());
for (vtkm::IdComponent index = 0; index < numComponents; index++)
{
dest[index] = (*this)[index];
}
}
VTKM_EXEC_CONT
ComponentType operator[](vtkm::IdComponent index) const
{
const vtkm::FloatDefault *offset =
detail::VecRectilinearPointCoordinatesOffsetTable[index];
return ComponentType(this->Origin[0] + offset[0]*this->Spacing[0],
this->Origin[1] + offset[1]*this->Spacing[1],
this->Origin[2] + offset[2]*this->Spacing[2]);
}
VTKM_EXEC_CONT
const ComponentType &GetOrigin() const { return this->Origin; }
VTKM_EXEC_CONT
const ComponentType &GetSpacing() const { return this->Spacing; }
private:
// Position of lower left point.
ComponentType Origin;
// Spacing in the x, y, and z directions.
ComponentType Spacing;
};
template<vtkm::IdComponent NumDimensions>
struct TypeTraits<vtkm::VecRectilinearPointCoordinates<NumDimensions> >
{
typedef vtkm::TypeTraitsRealTag NumericTag;
typedef TypeTraitsVectorTag DimensionalityTag;
VTKM_EXEC_CONT
static vtkm::VecRectilinearPointCoordinates<NumDimensions>
ZeroInitialization()
{
return vtkm::VecRectilinearPointCoordinates<NumDimensions>(
vtkm::Vec<vtkm::FloatDefault,3>(0,0,0),
vtkm::Vec<vtkm::FloatDefault,3>(0,0,0));
}
};
template<vtkm::IdComponent NumDimensions>
struct VecTraits<vtkm::VecRectilinearPointCoordinates<NumDimensions> >
{
typedef vtkm::VecRectilinearPointCoordinates<NumDimensions> VecType;
typedef vtkm::Vec<vtkm::FloatDefault,3> ComponentType;
typedef vtkm::VecTraitsTagMultipleComponents HasMultipleComponents;
typedef vtkm::VecTraitsTagSizeStatic IsSizeStatic;
static const vtkm::IdComponent NUM_COMPONENTS = VecType::NUM_COMPONENTS;
VTKM_EXEC_CONT
static vtkm::IdComponent GetNumberOfComponents(const VecType &) {
return NUM_COMPONENTS;
}
VTKM_EXEC_CONT
static ComponentType GetComponent(const VecType &vector,
vtkm::IdComponent componentIndex)
{
return vector[componentIndex];
}
template<vtkm::IdComponent destSize>
VTKM_EXEC_CONT
static void CopyInto(const VecType &src,
vtkm::Vec<ComponentType,destSize> &dest)
{
src.CopyInto(dest);
}
};
} // namespace vtkm
#endif //vtk_m_exec_VecRectilinearPointCoordinates_h

@ -22,36 +22,46 @@
#include <vtkm/Types.h>
namespace vtkm {
namespace vtkm
{
/// A tag for vectors that are "true" vectors (i.e. have more than one
/// component).
///
struct VecTraitsTagMultipleComponents { };
struct VecTraitsTagMultipleComponents
{
};
/// A tag for vectors that are really just scalars (i.e. have only one
/// component)
///
struct VecTraitsTagSingleComponent { };
struct VecTraitsTagSingleComponent
{
};
/// A tag for vectors where the number of components are known at compile time.
///
struct VecTraitsTagSizeStatic { };
struct VecTraitsTagSizeStatic
{
};
/// A tag for vectors where the number of components are not determined until
/// run time.
///
struct VecTraitsTagSizeVariable { };
struct VecTraitsTagSizeVariable
{
};
namespace internal {
namespace internal
{
template<vtkm::IdComponent numComponents>
template <vtkm::IdComponent numComponents>
struct VecTraitsMultipleComponentChooser
{
typedef VecTraitsTagMultipleComponents Type;
};
template<>
template <>
struct VecTraitsMultipleComponentChooser<1>
{
typedef VecTraitsTagSingleComponent Type;
@ -62,7 +72,7 @@ struct VecTraitsMultipleComponentChooser<1>
/// The VecTraits class gives several static members that define how
/// to use a given type as a vector.
///
template<class VecType>
template <class VecType>
struct VecTraits
#ifdef VTKM_DOXYGEN_ONLY
{
@ -78,15 +88,15 @@ struct VecTraits
/// Number of components in the given vector.
///
static vtkm::IdComponent GetNumberOfComponents(const VecType &vec);
static vtkm::IdComponent GetNumberOfComponents(const VecType& vec);
/// \brief A tag specifying whether this vector has multiple components (i.e. is a "real" vector).
///
/// This tag can be useful for creating specialized functions when a vector
/// is really just a scalar.
///
typedef typename internal::VecTraitsMultipleComponentChooser<
NUM_COMPONENTS>::Type HasMultipleComponents;
typedef typename internal::VecTraitsMultipleComponentChooser<NUM_COMPONENTS>::Type
HasMultipleComponents;
/// \brief A tag specifying whether the size of this vector is known at compile time.
///
@ -98,41 +108,40 @@ struct VecTraits
/// Returns the value in a given component of the vector.
///
VTKM_EXEC_CONT static const ComponentType &GetComponent(
const typename std::remove_const<VecType>::type &vector,
vtkm::IdComponent component);
VTKM_EXEC_CONT static ComponentType &GetComponent(
typename std::remove_const<VecType>::type &vector,
vtkm::IdComponent component);
VTKM_EXEC_CONT static const ComponentType& GetComponent(
const typename std::remove_const<VecType>::type& vector,
vtkm::IdComponent component);
VTKM_EXEC_CONT static ComponentType& GetComponent(
typename std::remove_const<VecType>::type& vector,
vtkm::IdComponent component);
/// Changes the value in a given component of the vector.
///
VTKM_EXEC_CONT static void SetComponent(VecType &vector,
vtkm::IdComponent component,
ComponentType value);
VTKM_EXEC_CONT static void SetComponent(VecType& vector,
vtkm::IdComponent component,
ComponentType value);
/// Copies the components in the given vector into a given Vec object.
///
template<vktm::IdComponent destSize>
VTKM_EXEC_CONT
static void
CopyInto(const VecType &src, vtkm::Vec<ComponentType,destSize> &dest);
template <vktm::IdComponent destSize>
VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec<ComponentType, destSize>& dest);
};
#else // VTKM_DOXYGEN_ONLY
;
#else // VTKM_DOXYGEN_ONLY
;
#endif // VTKM_DOXYGEN_ONLY
// This partial specialization allows you to define a non-const version of
// VecTraits and have it still work for const version.
//
template<typename T>
template <typename T>
struct VecTraits<const T> : VecTraits<T>
{ };
template<typename T, vtkm::IdComponent Size>
struct VecTraits<vtkm::Vec<T,Size> >
{
typedef vtkm::Vec<T,Size> VecType;
};
template <typename T, vtkm::IdComponent Size>
struct VecTraits<vtkm::Vec<T, Size>>
{
typedef vtkm::Vec<T, Size> VecType;
/// Type of the components in the vector.
///
@ -145,16 +154,14 @@ struct VecTraits<vtkm::Vec<T,Size> >
/// Number of components in the given vector.
///
VTKM_EXEC_CONT
static vtkm::IdComponent GetNumberOfComponents(const VecType &) {
return NUM_COMPONENTS;
}
static vtkm::IdComponent GetNumberOfComponents(const VecType&) { return NUM_COMPONENTS; }
/// A tag specifying whether this vector has multiple components (i.e. is a
/// "real" vector). This tag can be useful for creating specialized functions
/// when a vector is really just a scalar.
///
typedef typename internal::VecTraitsMultipleComponentChooser<
NUM_COMPONENTS>::Type HasMultipleComponents;
typedef typename internal::VecTraitsMultipleComponentChooser<NUM_COMPONENTS>::Type
HasMultipleComponents;
/// A tag specifying whether the size of this vector is known at compile
/// time. If set to \c VecTraitsTagSizeStatic, then \c NUM_COMPONENTS is set.
@ -167,37 +174,36 @@ struct VecTraits<vtkm::Vec<T,Size> >
/// Returns the value in a given component of the vector.
///
VTKM_EXEC_CONT
static const ComponentType &GetComponent(const VecType &vector,
vtkm::IdComponent component)
static const ComponentType& GetComponent(const VecType& vector, vtkm::IdComponent component)
{
return vector[component];
}
VTKM_EXEC_CONT
static ComponentType &GetComponent(VecType &vector, vtkm::IdComponent component) {
static ComponentType& GetComponent(VecType& vector, vtkm::IdComponent component)
{
return vector[component];
}
/// Changes the value in a given component of the vector.
///
VTKM_EXEC_CONT static void SetComponent(VecType &vector,
vtkm::IdComponent component,
ComponentType value) {
VTKM_EXEC_CONT static void SetComponent(VecType& vector,
vtkm::IdComponent component,
ComponentType value)
{
vector[component] = value;
}
/// Converts whatever type this vector is into the standard VTKm Tuple.
///
template<vtkm::IdComponent destSize>
VTKM_EXEC_CONT
static void
CopyInto(const VecType &src, vtkm::Vec<ComponentType,destSize> &dest)
template <vtkm::IdComponent destSize>
VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec<ComponentType, destSize>& dest)
{
src.CopyInto(dest);
}
};
template<typename T>
struct VecTraits<vtkm::VecC<T> >
template <typename T>
struct VecTraits<vtkm::VecC<T>>
{
using VecType = vtkm::VecC<T>;
@ -208,7 +214,7 @@ struct VecTraits<vtkm::VecC<T> >
/// Number of components in the given vector.
///
VTKM_EXEC_CONT
static vtkm::IdComponent GetNumberOfComponents(const VecType &vector)
static vtkm::IdComponent GetNumberOfComponents(const VecType& vector)
{
return vector.GetNumberOfComponents();
}
@ -234,38 +240,35 @@ struct VecTraits<vtkm::VecC<T> >
/// Returns the value in a given component of the vector.
///
VTKM_EXEC_CONT
static const ComponentType &GetComponent(const VecType &vector,
vtkm::IdComponent component)
static const ComponentType& GetComponent(const VecType& vector, vtkm::IdComponent component)
{
return vector[component];
}
VTKM_EXEC_CONT
static ComponentType &GetComponent(VecType &vector, vtkm::IdComponent component) {
static ComponentType& GetComponent(VecType& vector, vtkm::IdComponent component)
{
return vector[component];
}
/// Changes the value in a given component of the vector.
///
VTKM_EXEC_CONT
static void SetComponent(VecType &vector,
vtkm::IdComponent component,
ComponentType value) {
static void SetComponent(VecType& vector, vtkm::IdComponent component, ComponentType value)
{
vector[component] = value;
}
/// Converts whatever type this vector is into the standard VTKm Tuple.
///
template<vtkm::IdComponent destSize>
VTKM_EXEC_CONT
static void
CopyInto(const VecType &src, vtkm::Vec<ComponentType,destSize> &dest)
template <vtkm::IdComponent destSize>
VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec<ComponentType, destSize>& dest)
{
src.CopyInto(dest);
}
};
template<typename T>
struct VecTraits<vtkm::VecCConst<T> >
template <typename T>
struct VecTraits<vtkm::VecCConst<T>>
{
using VecType = vtkm::VecCConst<T>;
@ -276,7 +279,7 @@ struct VecTraits<vtkm::VecCConst<T> >
/// Number of components in the given vector.
///
VTKM_EXEC_CONT
static vtkm::IdComponent GetNumberOfComponents(const VecType &vector)
static vtkm::IdComponent GetNumberOfComponents(const VecType& vector)
{
return vector.GetNumberOfComponents();
}
@ -302,8 +305,7 @@ struct VecTraits<vtkm::VecCConst<T> >
/// Returns the value in a given component of the vector.
///
VTKM_EXEC_CONT
static const ComponentType &GetComponent(const VecType &vector,
vtkm::IdComponent component)
static const ComponentType& GetComponent(const VecType& vector, vtkm::IdComponent component)
{
return vector[component];
}
@ -311,59 +313,52 @@ struct VecTraits<vtkm::VecCConst<T> >
/// Changes the value in a given component of the vector.
///
VTKM_EXEC_CONT
static void SetComponent(VecType &vector,
vtkm::IdComponent component,
ComponentType value) {
static void SetComponent(VecType& vector, vtkm::IdComponent component, ComponentType value)
{
vector[component] = value;
}
/// Converts whatever type this vector is into the standard VTKm Tuple.
///
template<vtkm::IdComponent destSize>
VTKM_EXEC_CONT
static void
CopyInto(const VecType &src, vtkm::Vec<ComponentType,destSize> &dest)
template <vtkm::IdComponent destSize>
VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec<ComponentType, destSize>& dest)
{
src.CopyInto(dest);
}
};
namespace internal {
namespace internal
{
/// Used for overriding VecTraits for basic scalar types.
///
template<typename ScalarType>
struct VecTraitsBasic {
template <typename ScalarType>
struct VecTraitsBasic
{
typedef ScalarType ComponentType;
static const vtkm::IdComponent NUM_COMPONENTS = 1;
typedef VecTraitsTagSingleComponent HasMultipleComponents;
typedef vtkm::VecTraitsTagSizeStatic IsSizeStatic;
VTKM_EXEC_CONT
static vtkm::IdComponent GetNumberOfComponents(const ScalarType &) {
return 1;
}
static vtkm::IdComponent GetNumberOfComponents(const ScalarType&) { return 1; }
VTKM_EXEC_CONT
static const ComponentType &GetComponent(
const ScalarType &vector,
vtkm::IdComponent) {
static const ComponentType& GetComponent(const ScalarType& vector, vtkm::IdComponent)
{
return vector;
}
VTKM_EXEC_CONT
static ComponentType &GetComponent(ScalarType &vector, vtkm::IdComponent) {
return vector;
}
static ComponentType& GetComponent(ScalarType& vector, vtkm::IdComponent) { return vector; }
VTKM_EXEC_CONT static void SetComponent(ScalarType &vector,
vtkm::IdComponent,
ComponentType value) {
VTKM_EXEC_CONT static void SetComponent(ScalarType& vector,
vtkm::IdComponent,
ComponentType value)
{
vector = value;
}
template<vtkm::IdComponent destSize>
VTKM_EXEC_CONT
static void CopyInto(const ScalarType &src,
vtkm::Vec<ScalarType,destSize> &dest)
template <vtkm::IdComponent destSize>
VTKM_EXEC_CONT static void CopyInto(const ScalarType& src, vtkm::Vec<ScalarType, destSize>& dest)
{
dest[0] = src;
}
@ -377,19 +372,20 @@ struct VecTraitsBasic {
/// every component, and a pair in general has a different type for each
/// component. Thus we treat a pair as a "scalar" unit.
///
template<typename T, typename U>
struct VecTraits<vtkm::Pair<T,U> >
: public vtkm::internal::VecTraitsBasic<vtkm::Pair<T, U> >
template <typename T, typename U>
struct VecTraits<vtkm::Pair<T, U>> : public vtkm::internal::VecTraitsBasic<vtkm::Pair<T, U>>
{
};
} // anonymous namespace
#define VTKM_BASIC_TYPE_VECTOR(type) \
namespace vtkm { \
template<> \
struct VecTraits<type> \
: public vtkm::internal::VecTraitsBasic<type> { }; \
#define VTKM_BASIC_TYPE_VECTOR(type) \
namespace vtkm \
{ \
template <> \
struct VecTraits<type> : public vtkm::internal::VecTraitsBasic<type> \
{ \
}; \
}
/// Allows you to treat basic types as if they were vectors.
@ -409,7 +405,6 @@ VTKM_BASIC_TYPE_VECTOR(unsigned long)
VTKM_BASIC_TYPE_VECTOR(long long)
VTKM_BASIC_TYPE_VECTOR(unsigned long long)
//#undef VTKM_BASIC_TYPE_VECTOR
#endif //vtk_m_VecTraits_h

@ -22,11 +22,12 @@
#include <vtkm/Assert.h>
#include <vtkm/Math.h>
#include <vtkm/Types.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/Types.h>
#include <vtkm/VecTraits.h>
namespace vtkm {
namespace vtkm
{
/// \brief A short variable-length array with maximum length.
///
@ -35,18 +36,20 @@ namespace vtkm {
/// specified at compile time. Internally, \c VecVariable holds a \c Vec of
/// the maximum length and exposes a subsection of it.
///
template<typename T, vtkm::IdComponent MaxSize>
template <typename T, vtkm::IdComponent MaxSize>
class VecVariable
{
public:
typedef T ComponentType;
VTKM_EXEC_CONT
VecVariable() : NumComponents(0) { }
VecVariable()
: NumComponents(0)
{
}
template<vtkm::IdComponent SrcSize>
VTKM_EXEC_CONT
VecVariable(const vtkm::VecVariable<ComponentType,SrcSize> &src)
template <vtkm::IdComponent SrcSize>
VTKM_EXEC_CONT VecVariable(const vtkm::VecVariable<ComponentType, SrcSize>& src)
: NumComponents(src.GetNumberOfComponents())
{
VTKM_ASSERT(this->NumComponents <= MaxSize);
@ -56,9 +59,8 @@ public:
}
}
template<vtkm::IdComponent SrcSize>
VTKM_EXEC_CONT
VecVariable(const vtkm::Vec<ComponentType,SrcSize> &src)
template <vtkm::IdComponent SrcSize>
VTKM_EXEC_CONT VecVariable(const vtkm::Vec<ComponentType, SrcSize>& src)
: NumComponents(SrcSize)
{
VTKM_ASSERT(this->NumComponents <= MaxSize);
@ -69,13 +71,10 @@ public:
}
VTKM_EXEC_CONT
vtkm::IdComponent GetNumberOfComponents() const {
return this->NumComponents;
}
vtkm::IdComponent GetNumberOfComponents() const { return this->NumComponents; }
template<vtkm::IdComponent DestSize>
VTKM_EXEC_CONT
void CopyInto(vtkm::Vec<ComponentType,DestSize> &dest) const
template <vtkm::IdComponent DestSize>
VTKM_EXEC_CONT void CopyInto(vtkm::Vec<ComponentType, DestSize>& dest) const
{
vtkm::IdComponent numComponents = vtkm::Min(DestSize, this->NumComponents);
for (vtkm::IdComponent index = 0; index < numComponents; index++)
@ -85,16 +84,10 @@ public:
}
VTKM_EXEC_CONT
const ComponentType &operator[](vtkm::IdComponent index) const
{
return this->Data[index];
}
const ComponentType& operator[](vtkm::IdComponent index) const { return this->Data[index]; }
VTKM_EXEC_CONT
ComponentType &operator[](vtkm::IdComponent index)
{
return this->Data[index];
}
ComponentType& operator[](vtkm::IdComponent index) { return this->Data[index]; }
VTKM_EXEC_CONT
void Append(ComponentType value)
@ -105,62 +98,59 @@ public:
}
private:
vtkm::Vec<T,MaxSize> Data;
vtkm::Vec<T, MaxSize> Data;
vtkm::IdComponent NumComponents;
};
template<typename T, vtkm::IdComponent MaxSize>
struct TypeTraits<vtkm::VecVariable<T,MaxSize> >
template <typename T, vtkm::IdComponent MaxSize>
struct TypeTraits<vtkm::VecVariable<T, MaxSize>>
{
typedef typename vtkm::TypeTraits<T>::NumericTag NumericTag;
typedef TypeTraitsVectorTag DimensionalityTag;
VTKM_EXEC_CONT
static vtkm::VecVariable<T,MaxSize> ZeroInitialization()
static vtkm::VecVariable<T, MaxSize> ZeroInitialization()
{
return vtkm::VecVariable<T,MaxSize>();
return vtkm::VecVariable<T, MaxSize>();
}
};
template<typename T, vtkm::IdComponent MaxSize>
struct VecTraits<vtkm::VecVariable<T,MaxSize> >
template <typename T, vtkm::IdComponent MaxSize>
struct VecTraits<vtkm::VecVariable<T, MaxSize>>
{
typedef vtkm::VecVariable<T,MaxSize> VecType;
typedef vtkm::VecVariable<T, MaxSize> VecType;
typedef typename VecType::ComponentType ComponentType;
typedef vtkm::VecTraitsTagMultipleComponents HasMultipleComponents;
typedef vtkm::VecTraitsTagSizeVariable IsSizeStatic;
VTKM_EXEC_CONT
static vtkm::IdComponent GetNumberOfComponents(const VecType &vector) {
static vtkm::IdComponent GetNumberOfComponents(const VecType& vector)
{
return vector.GetNumberOfComponents();
}
VTKM_EXEC_CONT
static const ComponentType &GetComponent(const VecType &vector,
vtkm::IdComponent componentIndex)
static const ComponentType& GetComponent(const VecType& vector, vtkm::IdComponent componentIndex)
{
return vector[componentIndex];
}
VTKM_EXEC_CONT
static ComponentType &GetComponent(VecType &vector,
vtkm::IdComponent componentIndex)
static ComponentType& GetComponent(VecType& vector, vtkm::IdComponent componentIndex)
{
return vector[componentIndex];
}
VTKM_EXEC_CONT
static void SetComponent(VecType &vector,
static void SetComponent(VecType& vector,
vtkm::IdComponent componentIndex,
const ComponentType &value)
const ComponentType& value)
{
vector[componentIndex] = value;
}
template<vtkm::IdComponent destSize>
VTKM_EXEC_CONT
static void CopyInto(const VecType &src,
vtkm::Vec<ComponentType,destSize> &dest)
template <vtkm::IdComponent destSize>
VTKM_EXEC_CONT static void CopyInto(const VecType& src, vtkm::Vec<ComponentType, destSize>& dest)
{
src.CopyInto(dest);
}

@ -25,12 +25,12 @@
// This header file defines math functions that deal with linear albegra funcitons
#include <vtkm/Math.h>
#include <vtkm/Types.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/Types.h>
#include <vtkm/VecTraits.h>
namespace vtkm {
namespace vtkm
{
// ----------------------------------------------------------------------------
/// \brief Returns the linear interpolation of two values based on weight
@ -40,30 +40,27 @@ namespace vtkm {
/// vector of the same length as x and y. If w is outside [0,1] then lerp
/// extrapolates. If w=0 => v0 is returned if w=1 => v1 is returned.
///
template<typename ValueType, typename WeightType>
VTKM_EXEC_CONT
ValueType Lerp(const ValueType &value0,
const ValueType &value1,
const WeightType &weight)
template <typename ValueType, typename WeightType>
VTKM_EXEC_CONT ValueType Lerp(const ValueType& value0,
const ValueType& value1,
const WeightType& weight)
{
return static_cast<ValueType>((WeightType(1)-weight)*value0+weight*value1);
return static_cast<ValueType>((WeightType(1) - weight) * value0 + weight * value1);
}
template<typename ValueType, vtkm::IdComponent N, typename WeightType>
VTKM_EXEC_CONT
vtkm::Vec<ValueType,N> Lerp(const vtkm::Vec<ValueType,N> &value0,
const vtkm::Vec<ValueType,N> &value1,
const WeightType &weight)
template <typename ValueType, vtkm::IdComponent N, typename WeightType>
VTKM_EXEC_CONT vtkm::Vec<ValueType, N> Lerp(const vtkm::Vec<ValueType, N>& value0,
const vtkm::Vec<ValueType, N>& value1,
const WeightType& weight)
{
return (WeightType(1)-weight)*value0+weight*value1;
return (WeightType(1) - weight) * value0 + weight * value1;
}
template<typename ValueType, vtkm::IdComponent N>
VTKM_EXEC_CONT
vtkm::Vec<ValueType,N> Lerp(const vtkm::Vec<ValueType,N> &value0,
const vtkm::Vec<ValueType,N> &value1,
const vtkm::Vec<ValueType,N> &weight)
template <typename ValueType, vtkm::IdComponent N>
VTKM_EXEC_CONT vtkm::Vec<ValueType, N> Lerp(const vtkm::Vec<ValueType, N>& value0,
const vtkm::Vec<ValueType, N>& value1,
const vtkm::Vec<ValueType, N>& weight)
{
static const vtkm::Vec<ValueType,N> One(ValueType(1));
return (One-weight)*value0+weight*value1;
static const vtkm::Vec<ValueType, N> One(ValueType(1));
return (One - weight) * value0 + weight * value1;
}
// ----------------------------------------------------------------------------
@ -73,28 +70,27 @@ vtkm::Vec<ValueType,N> Lerp(const vtkm::Vec<ValueType,N> &value0,
/// square, so you should use this function in place of Magnitude or RMagnitude
/// when possible.
///
template<typename T>
VTKM_EXEC_CONT
typename vtkm::VecTraits<T>::ComponentType
MagnitudeSquared(const T &x)
template <typename T>
VTKM_EXEC_CONT typename vtkm::VecTraits<T>::ComponentType MagnitudeSquared(const T& x)
{
return vtkm::dot(x,x);
return vtkm::dot(x, x);
}
// ----------------------------------------------------------------------------
namespace detail {
template<typename T>
VTKM_EXEC_CONT
typename detail::FloatingPointReturnType<T>::Type
MagnitudeTemplate(T x, vtkm::TypeTraitsScalarTag)
namespace detail
{
template <typename T>
VTKM_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type MagnitudeTemplate(
T x,
vtkm::TypeTraitsScalarTag)
{
return static_cast<typename detail::FloatingPointReturnType<T>::Type>(vtkm::Abs(x));
}
template<typename T>
VTKM_EXEC_CONT
typename detail::FloatingPointReturnType<T>::Type
MagnitudeTemplate(const T &x, vtkm::TypeTraitsVectorTag)
template <typename T>
VTKM_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type MagnitudeTemplate(
const T& x,
vtkm::TypeTraitsVectorTag)
{
return vtkm::Sqrt(vtkm::MagnitudeSquared(x));
}
@ -109,29 +105,27 @@ MagnitudeTemplate(const T &x, vtkm::TypeTraitsVectorTag)
/// to find the reciprocal magnitude, so RMagnitude should be used if you
/// actually plan to divide by the magnitude.
///
template<typename T>
VTKM_EXEC_CONT
typename detail::FloatingPointReturnType<T>::Type
Magnitude(const T &x)
template <typename T>
VTKM_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type Magnitude(const T& x)
{
return detail::MagnitudeTemplate(
x, typename vtkm::TypeTraits<T>::DimensionalityTag());
return detail::MagnitudeTemplate(x, typename vtkm::TypeTraits<T>::DimensionalityTag());
}
// ----------------------------------------------------------------------------
namespace detail {
template<typename T>
VTKM_EXEC_CONT
typename detail::FloatingPointReturnType<T>::Type
RMagnitudeTemplate(T x, vtkm::TypeTraitsScalarTag)
namespace detail
{
return T(1)/vtkm::Abs(x);
template <typename T>
VTKM_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type RMagnitudeTemplate(
T x,
vtkm::TypeTraitsScalarTag)
{
return T(1) / vtkm::Abs(x);
}
template<typename T>
VTKM_EXEC_CONT
typename detail::FloatingPointReturnType<T>::Type
RMagnitudeTemplate(const T &x, vtkm::TypeTraitsVectorTag)
template <typename T>
VTKM_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type RMagnitudeTemplate(
const T& x,
vtkm::TypeTraitsVectorTag)
{
return vtkm::RSqrt(vtkm::MagnitudeSquared(x));
}
@ -142,29 +136,25 @@ RMagnitudeTemplate(const T &x, vtkm::TypeTraitsVectorTag)
/// On some hardware RMagnitude is faster than Magnitude, but neither is
/// as fast as MagnitudeSquared.
///
template<typename T>
VTKM_EXEC_CONT
typename detail::FloatingPointReturnType<T>::Type
RMagnitude(const T &x)
template <typename T>
VTKM_EXEC_CONT typename detail::FloatingPointReturnType<T>::Type RMagnitude(const T& x)
{
return detail::RMagnitudeTemplate(
x, typename vtkm::TypeTraits<T>::DimensionalityTag());
return detail::RMagnitudeTemplate(x, typename vtkm::TypeTraits<T>::DimensionalityTag());
}
// ----------------------------------------------------------------------------
namespace detail {
template<typename T>
VTKM_EXEC_CONT
T NormalTemplate(T x, vtkm::TypeTraitsScalarTag)
namespace detail
{
template <typename T>
VTKM_EXEC_CONT T NormalTemplate(T x, vtkm::TypeTraitsScalarTag)
{
return vtkm::CopySign(T(1), x);
}
template<typename T>
VTKM_EXEC_CONT
T NormalTemplate(const T &x, vtkm::TypeTraitsVectorTag)
template <typename T>
VTKM_EXEC_CONT T NormalTemplate(const T& x, vtkm::TypeTraitsVectorTag)
{
return vtkm::RMagnitude(x)*x;
return vtkm::RMagnitude(x) * x;
}
} // namespace detail
@ -172,12 +162,10 @@ T NormalTemplate(const T &x, vtkm::TypeTraitsVectorTag)
///
/// The resulting vector points in the same direction but has unit length.
///
template<typename T>
VTKM_EXEC_CONT
T Normal(const T &x)
template <typename T>
VTKM_EXEC_CONT T Normal(const T& x)
{
return detail::NormalTemplate(
x, typename vtkm::TypeTraits<T>::DimensionalityTag());
return detail::NormalTemplate(x, typename vtkm::TypeTraits<T>::DimensionalityTag());
}
// ----------------------------------------------------------------------------
@ -185,9 +173,8 @@ T Normal(const T &x)
///
/// The given vector is scaled to be unit length.
///
template<typename T>
VTKM_EXEC_CONT
void Normalize(T &x)
template <typename T>
VTKM_EXEC_CONT void Normalize(T& x)
{
x = vtkm::Normal(x);
}
@ -195,14 +182,13 @@ void Normalize(T &x)
// ----------------------------------------------------------------------------
/// \brief Find the cross product of two vectors.
///
template<typename T>
VTKM_EXEC_CONT
vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type,3>
Cross(const vtkm::Vec<T,3> &x, const vtkm::Vec<T,3> &y)
template <typename T>
VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 3> Cross(
const vtkm::Vec<T, 3>& x,
const vtkm::Vec<T, 3>& y)
{
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type,3>(x[1]*y[2] - x[2]*y[1],
x[2]*y[0] - x[0]*y[2],
x[0]*y[1] - x[1]*y[0]);
return vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 3>(
x[1] * y[2] - x[2] * y[1], x[2] * y[0] - x[0] * y[2], x[0] * y[1] - x[1] * y[0]);
}
//-----------------------------------------------------------------------------
@ -212,17 +198,13 @@ Cross(const vtkm::Vec<T,3> &x, const vtkm::Vec<T,3> &y)
/// a triangle and the plane the triangle is on, returns a vector perpendicular
/// to that triangle/plane.
///
template<typename T>
VTKM_EXEC_CONT
vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type,3>
TriangleNormal(const vtkm::Vec<T,3> &a,
const vtkm::Vec<T,3> &b,
const vtkm::Vec<T,3> &c)
template <typename T>
VTKM_EXEC_CONT vtkm::Vec<typename detail::FloatingPointReturnType<T>::Type, 3>
TriangleNormal(const vtkm::Vec<T, 3>& a, const vtkm::Vec<T, 3>& b, const vtkm::Vec<T, 3>& c)
{
return vtkm::Cross(b-a, c-a);
return vtkm::Cross(b - a, c - a);
}
} // namespace vtkm
#endif //vtk_m_VectorAnalysis_h

@ -0,0 +1,560 @@
//============================================================================
// Copyright (c) Kitware, Inc.
// All rights reserved.
// See LICENSE.txt for details.
// This software is distributed WITHOUT ANY WARRANTY; without even
// the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the above copyright notice for more information.
//
// Copyright 2017 Sandia Corporation.
// Copyright 2017 UT-Battelle, LLC.
// Copyright 2017 Los Alamos National Security.
//
// Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
// the U.S. Government retains certain rights in this software.
//
// Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National
// Laboratory (LANL), the U.S. Government retains certain rights in
// this software.
//============================================================================
#include <vtkm/benchmarking/Benchmarker.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/exec/FunctorBase.h>
#include <sstream>
#include <string>
#include <vector>
// 256 MB of floats:
const vtkm::Id ARRAY_SIZE = 256 * 1024 * 1024 / 4;
namespace vtkm
{
namespace benchmarking
{
template <typename DeviceAdapter>
struct BenchmarkArrayTransfer
{
using Algo = vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapter>;
using StorageTag = vtkm::cont::StorageTagBasic;
using Timer = vtkm::cont::Timer<DeviceAdapter>;
//------------- Functors for benchmarks --------------------------------------
// Reads all values in ArrayHandle.
template <typename PortalType>
struct ReadValues : vtkm::exec::FunctorBase
{
using ValueType = typename PortalType::ValueType;
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
PortalType Portal;
const ValueType MinValue;
VTKM_CONT
ReadValues(const PortalType& portal, const ValueType& minValue)
: Portal(portal)
, MinValue(minValue)
{
}
VTKM_EXEC
void operator()(vtkm::Id i) const
{
if (this->Portal.Get(i) < this->MinValue)
{
// We don't really do anything with this, we just need to do *something*
// to prevent the compiler from optimizing out the array accesses.
this->RaiseError("Unexpected value.");
}
}
// unused int argument is simply to distinguish this method from the
// VTKM_EXEC overload (VTKM_EXEC_CONT won't work here because of the
// RaiseError call).
VTKM_CONT
void operator()(vtkm::Id i, int) const
{
if (this->Portal.Get(i) < this->MinValue)
{
// We don't really do anything with this, we just need to do *something*
// to prevent the compiler from optimizing out the array accesses.
std::cerr << "Unexpected value.\n";
}
}
};
// Writes values to ArrayHandle.
template <typename PortalType>
struct WriteValues : vtkm::exec::FunctorBase
{
using ValueType = typename PortalType::ValueType;
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
PortalType Portal;
VTKM_CONT
WriteValues(const PortalType& portal)
: Portal(portal)
{
}
VTKM_EXEC_CONT
void operator()(vtkm::Id i) const { this->Portal.Set(i, static_cast<ValueType>(i)); }
};
// Reads and writes values to ArrayHandle.
template <typename PortalType>
struct ReadWriteValues : vtkm::exec::FunctorBase
{
using ValueType = typename PortalType::ValueType;
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
PortalType Portal;
VTKM_CONT
ReadWriteValues(const PortalType& portal)
: Portal(portal)
{
}
VTKM_EXEC_CONT
void operator()(vtkm::Id i) const
{
ValueType val = this->Portal.Get(i);
val += static_cast<ValueType>(i);
this->Portal.Set(i, val);
}
};
//------------- Benchmark functors -------------------------------------------
// Copies NumValues from control environment to execution environment and
// accesses them as read-only.
template <typename ValueType>
struct BenchContToExecRead
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
using PortalType = typename ArrayType::template ExecutionTypes<DeviceAdapter>::PortalConst;
using ValueTypeTraits = vtkm::TypeTraits<ValueType>;
vtkm::Id NumValues;
VTKM_CONT
BenchContToExecRead(vtkm::Id numValues)
: NumValues(numValues)
{
}
VTKM_CONT
std::string Description() const
{
std::ostringstream out;
out << "Copying from Control --> Execution (read-only): " << this->NumValues << " values ("
<< (this->NumValues * static_cast<vtkm::Id>(sizeof(ValueType))) << " bytes)";
return out.str();
}
VTKM_CONT
vtkm::Float64 operator()()
{
std::vector<ValueType> vec(this->NumValues, ValueTypeTraits::ZeroInitialization());
ArrayType array = vtkm::cont::make_ArrayHandle(vec);
// Time the copy:
Timer timer;
ReadValues<PortalType> functor(array.PrepareForInput(DeviceAdapter()),
ValueTypeTraits::ZeroInitialization());
Algo::Schedule(functor, this->NumValues);
return timer.GetElapsedTime();
}
};
VTKM_MAKE_BENCHMARK(ContToExecRead, BenchContToExecRead, ARRAY_SIZE);
// Writes values to ArrayHandle in execution environment. There is no actual
// copy between control/execution in this case.
template <typename ValueType>
struct BenchContToExecWrite
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
using PortalType = typename ArrayType::template ExecutionTypes<DeviceAdapter>::Portal;
using ValueTypeTraits = vtkm::TypeTraits<ValueType>;
vtkm::Id NumValues;
VTKM_CONT
BenchContToExecWrite(vtkm::Id numValues)
: NumValues(numValues)
{
}
VTKM_CONT
std::string Description() const
{
std::ostringstream out;
out << "Copying from Control --> Execution (write-only): " << this->NumValues << " values ("
<< (this->NumValues * static_cast<vtkm::Id>(sizeof(ValueType))) << " bytes)";
return out.str();
}
VTKM_CONT
vtkm::Float64 operator()()
{
ArrayType array;
// Time the write:
Timer timer;
WriteValues<PortalType> functor(array.PrepareForOutput(this->NumValues, DeviceAdapter()));
Algo::Schedule(functor, this->NumValues);
return timer.GetElapsedTime();
}
};
VTKM_MAKE_BENCHMARK(ContToExecWrite, BenchContToExecWrite, ARRAY_SIZE);
// Copies NumValues from control environment to execution environment and
// both reads and writes them.
template <typename ValueType>
struct BenchContToExecReadWrite
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
using PortalType = typename ArrayType::template ExecutionTypes<DeviceAdapter>::Portal;
using ValueTypeTraits = vtkm::TypeTraits<ValueType>;
vtkm::Id NumValues;
VTKM_CONT
BenchContToExecReadWrite(vtkm::Id numValues)
: NumValues(numValues)
{
}
VTKM_CONT
std::string Description() const
{
std::ostringstream out;
out << "Copying from Control --> Execution (read-write): " << this->NumValues << " values ("
<< (this->NumValues * static_cast<vtkm::Id>(sizeof(ValueType))) << " bytes)";
return out.str();
}
VTKM_CONT
vtkm::Float64 operator()()
{
std::vector<ValueType> vec(this->NumValues, ValueTypeTraits::ZeroInitialization());
ArrayType array = vtkm::cont::make_ArrayHandle(vec);
// Time the copy:
Timer timer;
ReadWriteValues<PortalType> functor(array.PrepareForInPlace(DeviceAdapter()));
Algo::Schedule(functor, this->NumValues);
return timer.GetElapsedTime();
}
};
VTKM_MAKE_BENCHMARK(ContToExecReadWrite, BenchContToExecReadWrite, ARRAY_SIZE);
// Copies NumValues from control environment to execution environment and
// back, then accesses them as read-only.
template <typename ValueType>
struct BenchRoundTripRead
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
using PortalContType = typename ArrayType::PortalConstControl;
using PortalExecType = typename ArrayType::template ExecutionTypes<DeviceAdapter>::PortalConst;
using ValueTypeTraits = vtkm::TypeTraits<ValueType>;
vtkm::Id NumValues;
VTKM_CONT
BenchRoundTripRead(vtkm::Id numValues)
: NumValues(numValues)
{
}
VTKM_CONT
std::string Description() const
{
std::ostringstream out;
out << "Copying from Control --> Execution --> Control (read-only): " << this->NumValues
<< " values (" << (this->NumValues * static_cast<vtkm::Id>(sizeof(ValueType)))
<< " bytes)";
return out.str();
}
VTKM_CONT
vtkm::Float64 operator()()
{
std::vector<ValueType> vec(this->NumValues, ValueTypeTraits::ZeroInitialization());
ArrayType array = vtkm::cont::make_ArrayHandle(vec);
// Ensure data is in control before we start:
array.ReleaseResourcesExecution();
// Time the copy:
Timer timer;
// Copy to device:
ReadValues<PortalExecType> functor(array.PrepareForInput(DeviceAdapter()),
ValueTypeTraits::ZeroInitialization());
Algo::Schedule(functor, this->NumValues);
// Copy back to host and read:
ReadValues<PortalContType> cFunctor(array.GetPortalConstControl(),
ValueTypeTraits::ZeroInitialization());
for (vtkm::Id i = 0; i < this->NumValues; ++i)
{
cFunctor(i, 0);
}
return timer.GetElapsedTime();
}
};
VTKM_MAKE_BENCHMARK(RoundTripRead, BenchRoundTripRead, ARRAY_SIZE);
// Copies NumValues from control environment to execution environment and
// back, then reads and writes them in-place.
template <typename ValueType>
struct BenchRoundTripReadWrite
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
using PortalContType = typename ArrayType::PortalControl;
using PortalExecType = typename ArrayType::template ExecutionTypes<DeviceAdapter>::Portal;
using ValueTypeTraits = vtkm::TypeTraits<ValueType>;
vtkm::Id NumValues;
VTKM_CONT
BenchRoundTripReadWrite(vtkm::Id numValues)
: NumValues(numValues)
{
}
VTKM_CONT
std::string Description() const
{
std::ostringstream out;
out << "Copying from Control --> Execution --> Control (read-write): " << this->NumValues
<< " values (" << (this->NumValues * static_cast<vtkm::Id>(sizeof(ValueType)))
<< " bytes)";
return out.str();
}
VTKM_CONT
vtkm::Float64 operator()()
{
std::vector<ValueType> vec(this->NumValues, ValueTypeTraits::ZeroInitialization());
ArrayType array = vtkm::cont::make_ArrayHandle(vec);
// Ensure data is in control before we start:
array.ReleaseResourcesExecution();
// Time the copy:
Timer timer;
// Do work on device:
ReadWriteValues<PortalExecType> functor(array.PrepareForInPlace(DeviceAdapter()));
Algo::Schedule(functor, this->NumValues);
ReadWriteValues<PortalContType> cFunctor(array.GetPortalControl());
for (vtkm::Id i = 0; i < this->NumValues; ++i)
{
cFunctor(i);
}
return timer.GetElapsedTime();
}
};
VTKM_MAKE_BENCHMARK(RoundTripReadWrite, BenchRoundTripReadWrite, ARRAY_SIZE);
// Write NumValues to device allocated memory and copies them back to control
// for reading.
template <typename ValueType>
struct BenchExecToContRead
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
using PortalContType = typename ArrayType::PortalConstControl;
using PortalExecType = typename ArrayType::template ExecutionTypes<DeviceAdapter>::Portal;
using ValueTypeTraits = vtkm::TypeTraits<ValueType>;
vtkm::Id NumValues;
VTKM_CONT
BenchExecToContRead(vtkm::Id numValues)
: NumValues(numValues)
{
}
VTKM_CONT
std::string Description() const
{
std::ostringstream out;
out << "Copying from Execution --> Control (read-only on control): " << this->NumValues
<< " values (" << (this->NumValues * static_cast<vtkm::Id>(sizeof(ValueType)))
<< " bytes)";
return out.str();
}
VTKM_CONT
vtkm::Float64 operator()()
{
ArrayType array;
// Time the copy:
Timer timer;
// Allocate/write data on device
WriteValues<PortalExecType> functor(array.PrepareForOutput(this->NumValues, DeviceAdapter()));
Algo::Schedule(functor, this->NumValues);
// Read back on host:
ReadValues<PortalContType> cFunctor(array.GetPortalConstControl(),
ValueTypeTraits::ZeroInitialization());
for (vtkm::Id i = 0; i < this->NumValues; ++i)
{
cFunctor(i, 0);
}
return timer.GetElapsedTime();
}
};
VTKM_MAKE_BENCHMARK(ExecToContRead, BenchExecToContRead, ARRAY_SIZE);
// Write NumValues to device allocated memory and copies them back to control
// and overwrites them.
template <typename ValueType>
struct BenchExecToContWrite
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
using PortalContType = typename ArrayType::PortalControl;
using PortalExecType = typename ArrayType::template ExecutionTypes<DeviceAdapter>::Portal;
using ValueTypeTraits = vtkm::TypeTraits<ValueType>;
vtkm::Id NumValues;
VTKM_CONT
BenchExecToContWrite(vtkm::Id numValues)
: NumValues(numValues)
{
}
VTKM_CONT
std::string Description() const
{
std::ostringstream out;
out << "Copying from Execution --> Control (write-only on control): " << this->NumValues
<< " values (" << (this->NumValues * static_cast<vtkm::Id>(sizeof(ValueType)))
<< " bytes)";
return out.str();
}
VTKM_CONT
vtkm::Float64 operator()()
{
ArrayType array;
// Time the copy:
Timer timer;
// Allocate/write data on device
WriteValues<PortalExecType> functor(array.PrepareForOutput(this->NumValues, DeviceAdapter()));
Algo::Schedule(functor, this->NumValues);
// Read back on host:
WriteValues<PortalContType> cFunctor(array.GetPortalControl());
for (vtkm::Id i = 0; i < this->NumValues; ++i)
{
cFunctor(i);
}
return timer.GetElapsedTime();
}
};
VTKM_MAKE_BENCHMARK(ExecToContWrite, BenchExecToContWrite, ARRAY_SIZE);
// Write NumValues to device allocated memory and copies them back to control
// for reading and writing.
template <typename ValueType>
struct BenchExecToContReadWrite
{
using ArrayType = vtkm::cont::ArrayHandle<ValueType, StorageTag>;
using PortalContType = typename ArrayType::PortalControl;
using PortalExecType = typename ArrayType::template ExecutionTypes<DeviceAdapter>::Portal;
using ValueTypeTraits = vtkm::TypeTraits<ValueType>;
vtkm::Id NumValues;
VTKM_CONT
BenchExecToContReadWrite(vtkm::Id numValues)
: NumValues(numValues)
{
}
VTKM_CONT
std::string Description() const
{
std::ostringstream out;
out << "Copying from Execution --> Control (read-write on control): " << this->NumValues
<< " values (" << (this->NumValues * static_cast<vtkm::Id>(sizeof(ValueType)))
<< " bytes)";
return out.str();
}
VTKM_CONT
vtkm::Float64 operator()()
{
ArrayType array;
// Time the copy:
Timer timer;
// Allocate/write data on device
WriteValues<PortalExecType> functor(array.PrepareForOutput(this->NumValues, DeviceAdapter()));
Algo::Schedule(functor, this->NumValues);
// Read back on host:
ReadWriteValues<PortalContType> cFunctor(array.GetPortalControl());
for (vtkm::Id i = 0; i < this->NumValues; ++i)
{
cFunctor(i);
}
return timer.GetElapsedTime();
}
};
VTKM_MAKE_BENCHMARK(ExecToContReadWrite, BenchExecToContReadWrite, ARRAY_SIZE);
//----------- Benchmark caller -----------------------------------------------
using TestTypes = vtkm::ListTagBase<vtkm::Float32>;
static VTKM_CONT bool Run()
{
VTKM_RUN_BENCHMARK(ContToExecRead, TestTypes());
VTKM_RUN_BENCHMARK(ContToExecWrite, TestTypes());
VTKM_RUN_BENCHMARK(ContToExecReadWrite, TestTypes());
VTKM_RUN_BENCHMARK(RoundTripRead, TestTypes());
VTKM_RUN_BENCHMARK(RoundTripReadWrite, TestTypes());
VTKM_RUN_BENCHMARK(ExecToContRead, TestTypes());
VTKM_RUN_BENCHMARK(ExecToContWrite, TestTypes());
VTKM_RUN_BENCHMARK(ExecToContReadWrite, TestTypes());
return true;
}
};
}
} // end namespace vtkm::benchmarking
int main(int, char* [])
{
using DeviceAdapter = VTKM_DEFAULT_DEVICE_ADAPTER_TAG;
using Benchmarks = vtkm::benchmarking::BenchmarkArrayTransfer<DeviceAdapter>;
bool result = Benchmarks::Run();
return result ? EXIT_SUCCESS : EXIT_FAILURE;
}

@ -19,20 +19,19 @@
//============================================================================
#include <vtkm/TypeTraits.h>
#include <vtkm/benchmarking/Benchmarker.h>
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandleConstant.h>
#include <vtkm/cont/ArrayHandleCounting.h>
#include <vtkm/cont/ArrayHandlePermutation.h>
#include <vtkm/cont/ArrayHandleZip.h>
#include <vtkm/cont/ArrayPortalToIterators.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/ErrorExecution.h>
#include <vtkm/cont/StorageBasic.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/cont/DeviceAdapterAlgorithm.h>
#include <vtkm/cont/internal/DeviceAdapterError.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/benchmarking/Benchmarker.h>
#include <algorithm>
#include <cmath>
@ -42,115 +41,132 @@
#include <vtkm/internal/Windows.h>
namespace vtkm {
namespace benchmarking {
namespace vtkm
{
namespace benchmarking
{
#define ARRAY_SIZE (1 << 21)
const static std::string DIVIDER(40, '-');
enum BenchmarkName {
COPY = 1,
COPY_IF = 1 << 1,
LOWER_BOUNDS = 1 << 2,
REDUCE = 1 << 3,
REDUCE_BY_KEY = 1 << 4,
enum BenchmarkName
{
COPY = 1,
COPY_IF = 1 << 1,
LOWER_BOUNDS = 1 << 2,
REDUCE = 1 << 3,
REDUCE_BY_KEY = 1 << 4,
SCAN_INCLUSIVE = 1 << 5,
SCAN_EXCLUSIVE = 1 << 6,
SORT = 1 << 7,
SORT_BY_KEY = 1 << 8,
UNIQUE = 1 << 9,
UPPER_BOUNDS = 1 << 10,
ALL = COPY | COPY_IF | LOWER_BOUNDS | REDUCE | REDUCE_BY_KEY | SCAN_INCLUSIVE
| SCAN_EXCLUSIVE | SORT | SORT_BY_KEY | UNIQUE | UPPER_BOUNDS
SORT = 1 << 7,
SORT_BY_KEY = 1 << 8,
UNIQUE = 1 << 9,
UPPER_BOUNDS = 1 << 10,
ALL = COPY | COPY_IF | LOWER_BOUNDS | REDUCE | REDUCE_BY_KEY | SCAN_INCLUSIVE | SCAN_EXCLUSIVE |
SORT |
SORT_BY_KEY |
UNIQUE |
UPPER_BOUNDS
};
/// This class runs a series of micro-benchmarks to measure
/// performance of the parallel primitives provided by each
/// device adapter
template<class DeviceAdapterTag>
class BenchmarkDeviceAdapter {
template <class DeviceAdapterTag>
class BenchmarkDeviceAdapter
{
typedef vtkm::cont::StorageTagBasic StorageTag;
typedef vtkm::cont::ArrayHandle<vtkm::Id, StorageTag> IdArrayHandle;
typedef vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag>
Algorithm;
typedef vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag> Algorithm;
typedef vtkm::cont::Timer<DeviceAdapterTag> Timer;
public:
// Various kernels used by the different benchmarks to accelerate
// initialization of data
template<typename Value>
struct FillTestValueKernel : vtkm::exec::FunctorBase {
template <typename Value>
struct FillTestValueKernel : vtkm::exec::FunctorBase
{
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
typedef typename ValueArrayHandle::template ExecutionTypes<DeviceAdapterTag>
::Portal PortalType;
typedef typename ValueArrayHandle::template ExecutionTypes<DeviceAdapterTag>::Portal PortalType;
PortalType Output;
VTKM_CONT
FillTestValueKernel(PortalType out) : Output(out){}
VTKM_EXEC void operator()(vtkm::Id i) const {
Output.Set(i, TestValue(i, Value()));
FillTestValueKernel(PortalType out)
: Output(out)
{
}
VTKM_EXEC void operator()(vtkm::Id i) const { Output.Set(i, TestValue(i, Value())); }
};
template<typename Value>
struct FillScaledTestValueKernel : vtkm::exec::FunctorBase {
template <typename Value>
struct FillScaledTestValueKernel : vtkm::exec::FunctorBase
{
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
typedef typename ValueArrayHandle::template ExecutionTypes<DeviceAdapterTag>
::Portal PortalType;
typedef typename ValueArrayHandle::template ExecutionTypes<DeviceAdapterTag>::Portal PortalType;
PortalType Output;
const vtkm::Id IdScale;
VTKM_CONT
FillScaledTestValueKernel(vtkm::Id id_scale, PortalType out) : Output(out), IdScale(id_scale) {}
VTKM_EXEC void operator()(vtkm::Id i) const {
Output.Set(i, TestValue(i * IdScale, Value()));
FillScaledTestValueKernel(vtkm::Id id_scale, PortalType out)
: Output(out)
, IdScale(id_scale)
{
}
VTKM_EXEC void operator()(vtkm::Id i) const { Output.Set(i, TestValue(i * IdScale, Value())); }
};
template<typename Value>
struct FillModuloTestValueKernel : vtkm::exec::FunctorBase {
template <typename Value>
struct FillModuloTestValueKernel : vtkm::exec::FunctorBase
{
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
typedef typename ValueArrayHandle::template ExecutionTypes<DeviceAdapterTag>
::Portal PortalType;
typedef typename ValueArrayHandle::template ExecutionTypes<DeviceAdapterTag>::Portal PortalType;
PortalType Output;
const vtkm::Id Modulus;
VTKM_CONT
FillModuloTestValueKernel(vtkm::Id modulus, PortalType out) : Output(out), Modulus(modulus) {}
VTKM_EXEC void operator()(vtkm::Id i) const {
Output.Set(i, TestValue(i % Modulus, Value()));
FillModuloTestValueKernel(vtkm::Id modulus, PortalType out)
: Output(out)
, Modulus(modulus)
{
}
VTKM_EXEC void operator()(vtkm::Id i) const { Output.Set(i, TestValue(i % Modulus, Value())); }
};
template<typename Value>
struct FillBinaryTestValueKernel : vtkm::exec::FunctorBase {
template <typename Value>
struct FillBinaryTestValueKernel : vtkm::exec::FunctorBase
{
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
typedef typename ValueArrayHandle::template ExecutionTypes<DeviceAdapterTag>
::Portal PortalType;
typedef typename ValueArrayHandle::template ExecutionTypes<DeviceAdapterTag>::Portal PortalType;
PortalType Output;
const vtkm::Id Modulus;
VTKM_CONT
FillBinaryTestValueKernel(vtkm::Id modulus, PortalType out) : Output(out), Modulus(modulus) {}
FillBinaryTestValueKernel(vtkm::Id modulus, PortalType out)
: Output(out)
, Modulus(modulus)
{
}
VTKM_EXEC void operator()(vtkm::Id i) const {
VTKM_EXEC void operator()(vtkm::Id i) const
{
Output.Set(i, i % Modulus == 0 ? TestValue(vtkm::Id(1), Value()) : Value());
}
};
private:
template<typename Value>
struct BenchCopy {
template <typename Value>
struct BenchCopy
{
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
ValueArrayHandle ValueHandle_src;
@ -158,32 +174,37 @@ private:
std::mt19937 Rng;
VTKM_CONT
BenchCopy(){
BenchCopy()
{
ValueHandle_src.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag());
ValueHandle_dst.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag());
}
VTKM_CONT
vtkm::Float64 operator()(){
for (vtkm::Id i = 0; i < ValueHandle_src.GetNumberOfValues(); ++i){
ValueHandle_src.GetPortalControl().Set(vtkm::Id(i), TestValue(vtkm::Id(Rng()), Value()));
vtkm::Float64 operator()()
{
for (vtkm::Id i = 0; i < ValueHandle_src.GetNumberOfValues(); ++i)
{
ValueHandle_src.GetPortalControl().Set(vtkm::Id(i), TestValue(vtkm::Id(Rng()), Value()));
}
Timer timer;
Algorithm::Copy(ValueHandle_src,ValueHandle_dst);
Algorithm::Copy(ValueHandle_src, ValueHandle_dst);
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const {
std::string Description() const
{
std::stringstream description;
description << "Copy " << ARRAY_SIZE << " values";
return description.str();
}
};
VTKM_MAKE_BENCHMARK(Copy, BenchCopy);
VTKM_MAKE_BENCHMARK(Copy, BenchCopy);
template<typename Value>
struct BenchCopyIf {
template <typename Value>
struct BenchCopyIf
{
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
const vtkm::Id N_VALID;
@ -191,28 +212,32 @@ private:
IdArrayHandle StencilHandle;
VTKM_CONT
BenchCopyIf(vtkm::Id percent_valid) : N_VALID((ARRAY_SIZE * percent_valid) / 100)
BenchCopyIf(vtkm::Id percent_valid)
: N_VALID((ARRAY_SIZE * percent_valid) / 100)
{
vtkm::Id modulo = ARRAY_SIZE / N_VALID;
Algorithm::Schedule(FillTestValueKernel<Value>(
ValueHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())), ARRAY_SIZE);
Algorithm::Schedule(FillBinaryTestValueKernel<vtkm::Id>(modulo,
StencilHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())), ARRAY_SIZE);
Algorithm::Schedule(
FillTestValueKernel<Value>(ValueHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())),
ARRAY_SIZE);
Algorithm::Schedule(FillBinaryTestValueKernel<vtkm::Id>(
modulo, StencilHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())),
ARRAY_SIZE);
}
VTKM_CONT
vtkm::Float64 operator()() {
vtkm::Float64 operator()()
{
Timer timer;
Algorithm::CopyIf(ValueHandle, StencilHandle, OutHandle);
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const {
std::string Description() const
{
std::stringstream description;
description << "CopyIf on " << ARRAY_SIZE << " "
<< " values with " << OutHandle.GetNumberOfValues()
<< " valid values";
<< " values with " << OutHandle.GetNumberOfValues() << " valid values";
return description.str();
}
};
@ -223,8 +248,9 @@ private:
VTKM_MAKE_BENCHMARK(CopyIf25, BenchCopyIf, 25);
VTKM_MAKE_BENCHMARK(CopyIf30, BenchCopyIf, 30);
template<typename Value>
struct BenchLowerBounds {
template <typename Value>
struct BenchLowerBounds
{
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
const vtkm::Id N_VALS;
@ -232,26 +258,30 @@ private:
IdArrayHandle OutHandle;
VTKM_CONT
BenchLowerBounds(vtkm::Id value_percent) : N_VALS((ARRAY_SIZE * value_percent) / 100)
BenchLowerBounds(vtkm::Id value_percent)
: N_VALS((ARRAY_SIZE * value_percent) / 100)
{
Algorithm::Schedule(FillTestValueKernel<Value>(
InputHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())), ARRAY_SIZE);
Algorithm::Schedule(FillScaledTestValueKernel<Value>(2,
ValueHandle.PrepareForOutput(N_VALS, DeviceAdapterTag())), N_VALS);
Algorithm::Schedule(
FillTestValueKernel<Value>(InputHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())),
ARRAY_SIZE);
Algorithm::Schedule(FillScaledTestValueKernel<Value>(
2, ValueHandle.PrepareForOutput(N_VALS, DeviceAdapterTag())),
N_VALS);
}
VTKM_CONT
vtkm::Float64 operator()(){
vtkm::Float64 operator()()
{
Timer timer;
Algorithm::LowerBounds(InputHandle, ValueHandle, OutHandle);
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const {
std::string Description() const
{
std::stringstream description;
description << "LowerBounds on " << ARRAY_SIZE << " input and "
<< N_VALS << " values";
description << "LowerBounds on " << ARRAY_SIZE << " input and " << N_VALS << " values";
return description.str();
}
};
@ -262,27 +292,32 @@ private:
VTKM_MAKE_BENCHMARK(LowerBounds25, BenchLowerBounds, 25);
VTKM_MAKE_BENCHMARK(LowerBounds30, BenchLowerBounds, 30);
template<typename Value>
struct BenchReduce {
template <typename Value>
struct BenchReduce
{
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
ValueArrayHandle InputHandle;
VTKM_CONT
BenchReduce(){
Algorithm::Schedule(FillTestValueKernel<Value>(
InputHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())), ARRAY_SIZE);
BenchReduce()
{
Algorithm::Schedule(
FillTestValueKernel<Value>(InputHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())),
ARRAY_SIZE);
}
VTKM_CONT
vtkm::Float64 operator()(){
vtkm::Float64 operator()()
{
Timer timer;
Algorithm::Reduce(InputHandle, Value());
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const {
std::string Description() const
{
std::stringstream description;
description << "Reduce on " << ARRAY_SIZE << " values";
return description.str();
@ -290,8 +325,9 @@ private:
};
VTKM_MAKE_BENCHMARK(Reduce, BenchReduce);
template<typename Value>
struct BenchReduceByKey {
template <typename Value>
struct BenchReduceByKey
{
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
const vtkm::Id N_KEYS;
@ -299,28 +335,32 @@ private:
IdArrayHandle KeyHandle, KeysOut;
VTKM_CONT
BenchReduceByKey(vtkm::Id key_percent) : N_KEYS((ARRAY_SIZE * key_percent) / 100)
BenchReduceByKey(vtkm::Id key_percent)
: N_KEYS((ARRAY_SIZE * key_percent) / 100)
{
Algorithm::Schedule(FillTestValueKernel<Value>(
ValueHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())), ARRAY_SIZE);
Algorithm::Schedule(FillModuloTestValueKernel<vtkm::Id>(N_KEYS,
KeyHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())), ARRAY_SIZE);
Algorithm::Schedule(
FillTestValueKernel<Value>(ValueHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())),
ARRAY_SIZE);
Algorithm::Schedule(FillModuloTestValueKernel<vtkm::Id>(
N_KEYS, KeyHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())),
ARRAY_SIZE);
Algorithm::SortByKey(KeyHandle, ValueHandle);
}
VTKM_CONT
vtkm::Float64 operator()(){
vtkm::Float64 operator()()
{
Timer timer;
Algorithm::ReduceByKey(KeyHandle, ValueHandle, KeysOut, ValuesOut,
vtkm::Add());
Algorithm::ReduceByKey(KeyHandle, ValueHandle, KeysOut, ValuesOut, vtkm::Add());
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const {
std::string Description() const
{
std::stringstream description;
description << "ReduceByKey on " << ARRAY_SIZE
<< " values with " << N_KEYS << " distinct vtkm::Id keys";
description << "ReduceByKey on " << ARRAY_SIZE << " values with " << N_KEYS
<< " distinct vtkm::Id keys";
return description.str();
}
};
@ -331,26 +371,31 @@ private:
VTKM_MAKE_BENCHMARK(ReduceByKey25, BenchReduceByKey, 25);
VTKM_MAKE_BENCHMARK(ReduceByKey30, BenchReduceByKey, 30);
template<typename Value>
struct BenchScanInclusive {
template <typename Value>
struct BenchScanInclusive
{
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
ValueArrayHandle ValueHandle, OutHandle;
VTKM_CONT
BenchScanInclusive(){
Algorithm::Schedule(FillTestValueKernel<Value>(
ValueHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())), ARRAY_SIZE);
BenchScanInclusive()
{
Algorithm::Schedule(
FillTestValueKernel<Value>(ValueHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())),
ARRAY_SIZE);
}
VTKM_CONT
vtkm::Float64 operator()(){
vtkm::Float64 operator()()
{
Timer timer;
Algorithm::ScanInclusive(ValueHandle, OutHandle);
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const {
std::string Description() const
{
std::stringstream description;
description << "ScanInclusive on " << ARRAY_SIZE << " values";
return description.str();
@ -358,27 +403,32 @@ private:
};
VTKM_MAKE_BENCHMARK(ScanInclusive, BenchScanInclusive);
template<typename Value>
struct BenchScanExclusive {
template <typename Value>
struct BenchScanExclusive
{
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
ValueArrayHandle ValueHandle, OutHandle;
VTKM_CONT
BenchScanExclusive(){
Algorithm::Schedule(FillTestValueKernel<Value>(
ValueHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())), ARRAY_SIZE);
BenchScanExclusive()
{
Algorithm::Schedule(
FillTestValueKernel<Value>(ValueHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())),
ARRAY_SIZE);
}
VTKM_CONT
vtkm::Float64 operator()(){
vtkm::Float64 operator()()
{
Timer timer;
Algorithm::ScanExclusive(ValueHandle, OutHandle);
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const {
std::string Description() const
{
std::stringstream description;
description << "ScanExclusive on " << ARRAY_SIZE << " values";
return description.str();
@ -386,21 +436,22 @@ private:
};
VTKM_MAKE_BENCHMARK(ScanExclusive, BenchScanExclusive);
template<typename Value>
struct BenchSort {
template <typename Value>
struct BenchSort
{
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
ValueArrayHandle ValueHandle;
std::mt19937 Rng;
VTKM_CONT
BenchSort(){
ValueHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag());
}
BenchSort() { ValueHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag()); }
VTKM_CONT
vtkm::Float64 operator()(){
for (vtkm::Id i = 0; i < ValueHandle.GetNumberOfValues(); ++i){
vtkm::Float64 operator()()
{
for (vtkm::Id i = 0; i < ValueHandle.GetNumberOfValues(); ++i)
{
ValueHandle.GetPortalControl().Set(vtkm::Id(i), TestValue(vtkm::Id(Rng()), Value()));
}
Timer timer;
@ -409,7 +460,8 @@ private:
}
VTKM_CONT
std::string Description() const {
std::string Description() const
{
std::stringstream description;
description << "Sort on " << ARRAY_SIZE << " random values";
return description.str();
@ -417,8 +469,9 @@ private:
};
VTKM_MAKE_BENCHMARK(Sort, BenchSort);
template<typename Value>
struct BenchSortByKey {
template <typename Value>
struct BenchSortByKey
{
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
std::mt19937 Rng;
@ -427,27 +480,33 @@ private:
IdArrayHandle KeyHandle;
VTKM_CONT
BenchSortByKey(vtkm::Id percent_key) : N_KEYS((ARRAY_SIZE * percent_key) / 100){
BenchSortByKey(vtkm::Id percent_key)
: N_KEYS((ARRAY_SIZE * percent_key) / 100)
{
ValueHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag());
}
VTKM_CONT
vtkm::Float64 operator()(){
for (vtkm::Id i = 0; i < ValueHandle.GetNumberOfValues(); ++i){
vtkm::Float64 operator()()
{
for (vtkm::Id i = 0; i < ValueHandle.GetNumberOfValues(); ++i)
{
ValueHandle.GetPortalControl().Set(vtkm::Id(i), TestValue(vtkm::Id(Rng()), Value()));
}
Algorithm::Schedule(FillModuloTestValueKernel<vtkm::Id>(N_KEYS,
KeyHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())), ARRAY_SIZE);
Algorithm::Schedule(FillModuloTestValueKernel<vtkm::Id>(
N_KEYS, KeyHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())),
ARRAY_SIZE);
Timer timer;
Algorithm::SortByKey(ValueHandle, KeyHandle);
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const {
std::string Description() const
{
std::stringstream description;
description << "SortByKey on " << ARRAY_SIZE
<< " random values with " << N_KEYS << " different vtkm::Id keys";
description << "SortByKey on " << ARRAY_SIZE << " random values with " << N_KEYS
<< " different vtkm::Id keys";
return description.str();
}
};
@ -458,21 +517,26 @@ private:
VTKM_MAKE_BENCHMARK(SortByKey25, BenchSortByKey, 25);
VTKM_MAKE_BENCHMARK(SortByKey30, BenchSortByKey, 30);
template<typename Value>
struct BenchUnique {
template <typename Value>
struct BenchUnique
{
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
const vtkm::Id N_VALID;
ValueArrayHandle ValueHandle;
VTKM_CONT
BenchUnique(vtkm::Id percent_valid) : N_VALID((ARRAY_SIZE * percent_valid) / 100)
{}
BenchUnique(vtkm::Id percent_valid)
: N_VALID((ARRAY_SIZE * percent_valid) / 100)
{
}
VTKM_CONT
vtkm::Float64 operator()(){
Algorithm::Schedule(FillModuloTestValueKernel<Value>(N_VALID,
ValueHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())), ARRAY_SIZE);
vtkm::Float64 operator()()
{
Algorithm::Schedule(FillModuloTestValueKernel<Value>(
N_VALID, ValueHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())),
ARRAY_SIZE);
Algorithm::Sort(ValueHandle);
Timer timer;
Algorithm::Unique(ValueHandle);
@ -480,10 +544,11 @@ private:
}
VTKM_CONT
std::string Description() const {
std::string Description() const
{
std::stringstream description;
description << "Unique on " << ARRAY_SIZE << " values with "
<< ValueHandle.GetNumberOfValues() << " valid values";
<< ValueHandle.GetNumberOfValues() << " valid values";
return description.str();
}
};
@ -494,8 +559,9 @@ private:
VTKM_MAKE_BENCHMARK(Unique25, BenchUnique, 25);
VTKM_MAKE_BENCHMARK(Unique30, BenchUnique, 30);
template<typename Value>
struct BenchUpperBounds {
template <typename Value>
struct BenchUpperBounds
{
typedef vtkm::cont::ArrayHandle<Value, StorageTag> ValueArrayHandle;
const vtkm::Id N_VALS;
@ -503,26 +569,30 @@ private:
IdArrayHandle OutHandle;
VTKM_CONT
BenchUpperBounds(vtkm::Id percent_vals) : N_VALS((ARRAY_SIZE * percent_vals) / 100)
BenchUpperBounds(vtkm::Id percent_vals)
: N_VALS((ARRAY_SIZE * percent_vals) / 100)
{
Algorithm::Schedule(FillTestValueKernel<Value>(
InputHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())), ARRAY_SIZE);
Algorithm::Schedule(FillScaledTestValueKernel<Value>(2,
ValueHandle.PrepareForOutput(N_VALS, DeviceAdapterTag())), N_VALS);
Algorithm::Schedule(
FillTestValueKernel<Value>(InputHandle.PrepareForOutput(ARRAY_SIZE, DeviceAdapterTag())),
ARRAY_SIZE);
Algorithm::Schedule(FillScaledTestValueKernel<Value>(
2, ValueHandle.PrepareForOutput(N_VALS, DeviceAdapterTag())),
N_VALS);
}
VTKM_CONT
vtkm::Float64 operator()(){
vtkm::Float64 operator()()
{
Timer timer;
Algorithm::UpperBounds(InputHandle, ValueHandle, OutHandle);
return timer.GetElapsedTime();
}
VTKM_CONT
std::string Description() const {
std::string Description() const
{
std::stringstream description;
description << "UpperBounds on " << ARRAY_SIZE << " input and "
<< N_VALS << " values";
description << "UpperBounds on " << ARRAY_SIZE << " input and " << N_VALS << " values";
return description.str();
}
};
@ -534,22 +604,31 @@ private:
VTKM_MAKE_BENCHMARK(UpperBounds30, BenchUpperBounds, 30);
public:
struct ValueTypes : vtkm::ListTagBase<vtkm::UInt8,
vtkm::UInt32,
vtkm::Int32,
vtkm::Int64,
vtkm::Vec<vtkm::Int32, 2>,
vtkm::Vec<vtkm::UInt8, 4>,
vtkm::Float32,
vtkm::Float64,
vtkm::Vec<vtkm::Float64, 3>,
vtkm::Vec<vtkm::Float32, 4>>
{
};
struct ValueTypes : vtkm::ListTagBase<vtkm::UInt8, vtkm::UInt32, vtkm::Int32,
vtkm::Int64, vtkm::Vec<vtkm::Int32, 2>,
vtkm::Vec<vtkm::UInt8, 4>, vtkm::Float32,
vtkm::Float64, vtkm::Vec<vtkm::Float64, 3>,
vtkm::Vec<vtkm::Float32, 4> >{};
static VTKM_CONT int Run(int benchmarks){
static VTKM_CONT int Run(int benchmarks)
{
std::cout << DIVIDER << "\nRunning DeviceAdapter benchmarks\n";
if (benchmarks & COPY) {
if (benchmarks & COPY)
{
std::cout << DIVIDER << "\nBenchmarking Copy\n";
VTKM_RUN_BENCHMARK(Copy, ValueTypes());
}
if (benchmarks & COPY_IF){
if (benchmarks & COPY_IF)
{
std::cout << "\n" << DIVIDER << "\nBenchmarking CopyIf\n";
VTKM_RUN_BENCHMARK(CopyIf5, ValueTypes());
VTKM_RUN_BENCHMARK(CopyIf10, ValueTypes());
@ -559,7 +638,8 @@ public:
VTKM_RUN_BENCHMARK(CopyIf30, ValueTypes());
}
if (benchmarks & LOWER_BOUNDS){
if (benchmarks & LOWER_BOUNDS)
{
std::cout << DIVIDER << "\nBenchmarking LowerBounds\n";
VTKM_RUN_BENCHMARK(LowerBounds5, ValueTypes());
VTKM_RUN_BENCHMARK(LowerBounds10, ValueTypes());
@ -569,12 +649,14 @@ public:
VTKM_RUN_BENCHMARK(LowerBounds30, ValueTypes());
}
if (benchmarks & REDUCE){
if (benchmarks & REDUCE)
{
std::cout << "\n" << DIVIDER << "\nBenchmarking Reduce\n";
VTKM_RUN_BENCHMARK(Reduce, ValueTypes());
}
if (benchmarks & REDUCE_BY_KEY){
if (benchmarks & REDUCE_BY_KEY)
{
std::cout << "\n" << DIVIDER << "\nBenchmarking ReduceByKey\n";
VTKM_RUN_BENCHMARK(ReduceByKey5, ValueTypes());
VTKM_RUN_BENCHMARK(ReduceByKey10, ValueTypes());
@ -584,22 +666,26 @@ public:
VTKM_RUN_BENCHMARK(ReduceByKey30, ValueTypes());
}
if (benchmarks & SCAN_INCLUSIVE){
if (benchmarks & SCAN_INCLUSIVE)
{
std::cout << "\n" << DIVIDER << "\nBenchmarking ScanInclusive\n";
VTKM_RUN_BENCHMARK(ScanInclusive, ValueTypes());
}
if (benchmarks & SCAN_EXCLUSIVE){
if (benchmarks & SCAN_EXCLUSIVE)
{
std::cout << "\n" << DIVIDER << "\nBenchmarking ScanExclusive\n";
VTKM_RUN_BENCHMARK(ScanExclusive, ValueTypes());
}
if (benchmarks & SORT){
if (benchmarks & SORT)
{
std::cout << "\n" << DIVIDER << "\nBenchmarking Sort\n";
VTKM_RUN_BENCHMARK(Sort, ValueTypes());
}
if (benchmarks & SORT_BY_KEY){
if (benchmarks & SORT_BY_KEY)
{
std::cout << "\n" << DIVIDER << "\nBenchmarking SortByKey\n";
VTKM_RUN_BENCHMARK(SortByKey5, ValueTypes());
VTKM_RUN_BENCHMARK(SortByKey10, ValueTypes());
@ -609,7 +695,8 @@ public:
VTKM_RUN_BENCHMARK(SortByKey30, ValueTypes());
}
if (benchmarks & UNIQUE){
if (benchmarks & UNIQUE)
{
std::cout << "\n" << DIVIDER << "\nBenchmarking Unique\n";
VTKM_RUN_BENCHMARK(Unique5, ValueTypes());
VTKM_RUN_BENCHMARK(Unique10, ValueTypes());
@ -619,7 +706,8 @@ public:
VTKM_RUN_BENCHMARK(Unique30, ValueTypes());
}
if (benchmarks & UPPER_BOUNDS){
if (benchmarks & UPPER_BOUNDS)
{
std::cout << "\n" << DIVIDER << "\nBenchmarking UpperBounds\n";
VTKM_RUN_BENCHMARK(UpperBounds5, ValueTypes());
VTKM_RUN_BENCHMARK(UpperBounds10, ValueTypes());
@ -633,54 +721,68 @@ public:
};
#undef ARRAY_SIZE
}
} // namespace vtkm::benchmarking
int main(int argc, char *argv[])
int main(int argc, char* argv[])
{
int benchmarks = 0;
if (argc < 2){
if (argc < 2)
{
benchmarks = vtkm::benchmarking::ALL;
}
else {
for (int i = 1; i < argc; ++i){
else
{
for (int i = 1; i < argc; ++i)
{
std::string arg = argv[i];
std::transform(arg.begin(), arg.end(), arg.begin(), ::tolower);
if (arg == "copy"){
if (arg == "copy")
{
benchmarks |= vtkm::benchmarking::COPY;
}
else if (arg == "copyif"){
else if (arg == "copyif")
{
benchmarks |= vtkm::benchmarking::COPY_IF;
}
else if (arg == "lowerbounds"){
else if (arg == "lowerbounds")
{
benchmarks |= vtkm::benchmarking::LOWER_BOUNDS;
}
else if (arg == "reduce"){
else if (arg == "reduce")
{
benchmarks |= vtkm::benchmarking::REDUCE;
}
else if (arg == "reducebykey"){
else if (arg == "reducebykey")
{
benchmarks |= vtkm::benchmarking::REDUCE_BY_KEY;
}
else if (arg == "scaninclusive"){
else if (arg == "scaninclusive")
{
benchmarks |= vtkm::benchmarking::SCAN_INCLUSIVE;
}
else if (arg == "scanexclusive"){
else if (arg == "scanexclusive")
{
benchmarks |= vtkm::benchmarking::SCAN_EXCLUSIVE;
}
else if (arg == "sort"){
else if (arg == "sort")
{
benchmarks |= vtkm::benchmarking::SORT;
}
else if (arg == "sortbykey"){
else if (arg == "sortbykey")
{
benchmarks |= vtkm::benchmarking::SORT_BY_KEY;
}
else if (arg == "unique"){
else if (arg == "unique")
{
benchmarks |= vtkm::benchmarking::UNIQUE;
}
else if (arg == "upperbounds"){
else if (arg == "upperbounds")
{
benchmarks |= vtkm::benchmarking::UPPER_BOUNDS;
}
else {
else
{
std::cout << "Unrecognized benchmark: " << argv[i] << std::endl;
return 1;
}
@ -688,7 +790,6 @@ int main(int argc, char *argv[])
}
//now actually execute the benchmarks
return vtkm::benchmarking::BenchmarkDeviceAdapter
<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>::Run(benchmarks);
return vtkm::benchmarking::BenchmarkDeviceAdapter<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>::Run(
benchmarks);
}

File diff suppressed because it is too large Load Diff

@ -24,30 +24,31 @@
#include <vtkm/cont/CellSetStructured.h>
#include <vtkm/cont/Timer.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/WorkletMapTopology.h>
#include <vtkm/worklet/DispatcherMapField.h>
#include <vtkm/worklet/DispatcherMapTopology.h>
#include <vtkm/worklet/WorkletMapField.h>
#include <vtkm/worklet/WorkletMapTopology.h>
#include <vtkm/cont/testing/Testing.h>
#include <vtkm/benchmarking/Benchmarker.h>
#include <vtkm/cont/testing/Testing.h>
#include <random>
#include <string>
namespace vtkm {
namespace benchmarking {
namespace vtkm
{
namespace benchmarking
{
#define CUBE_SIZE 256
const static std::string DIVIDER(40, '-');
enum BenchmarkName {
enum BenchmarkName
{
CELL_TO_POINT = 1 << 1,
POINT_TO_CELL = 1 << 2,
MC_CLASSIFY = 1 << 3,
ALL = CELL_TO_POINT |
POINT_TO_CELL |
MC_CLASSIFY
ALL = CELL_TO_POINT | POINT_TO_CELL | MC_CLASSIFY
};
class AveragePointToCell : public vtkm::worklet::WorkletMapPointToCell
@ -59,17 +60,16 @@ public:
typedef void ExecutionSignature(_1, PointCount, _3);
typedef _2 InputDomain;
template<typename PointValueVecType, typename OutType>
VTKM_EXEC
void operator()(const PointValueVecType &pointValues,
const vtkm::IdComponent &numPoints,
OutType &average) const
template <typename PointValueVecType, typename OutType>
VTKM_EXEC void operator()(const PointValueVecType& pointValues,
const vtkm::IdComponent& numPoints,
OutType& average) const
{
OutType sum = static_cast<OutType>(pointValues[0]);
for (vtkm::IdComponent pointIndex = 1; pointIndex < numPoints; ++pointIndex)
{
{
sum = sum + static_cast<OutType>(pointValues[pointIndex]);
}
}
average = sum / static_cast<OutType>(numPoints);
}
@ -78,17 +78,14 @@ public:
class AverageCellToPoint : public vtkm::worklet::WorkletMapCellToPoint
{
public:
typedef void ControlSignature(FieldInCell<> inCells,
CellSetIn topology,
FieldOut<> outPoints);
typedef void ControlSignature(FieldInCell<> inCells, CellSetIn topology, FieldOut<> outPoints);
typedef void ExecutionSignature(_1, _3, CellCount);
typedef _2 InputDomain;
template<typename CellVecType, typename OutType>
VTKM_EXEC
void operator()(const CellVecType &cellValues,
OutType &avgVal,
const vtkm::IdComponent &numCellIDs) const
template <typename CellVecType, typename OutType>
VTKM_EXEC void operator()(const CellVecType& cellValues,
OutType& avgVal,
const vtkm::IdComponent& numCellIDs) const
{
//simple functor that returns the average cell Value.
avgVal = static_cast<OutType>(cellValues[0]);
@ -101,107 +98,103 @@ public:
};
// -----------------------------------------------------------------------------
template<typename T>
template <typename T>
class Classification : public vtkm::worklet::WorkletMapPointToCell
{
public:
typedef void ControlSignature(
FieldInPoint<> inNodes,
CellSetIn cellset,
FieldOutCell< IdComponentType > outCaseId);
typedef void ControlSignature(FieldInPoint<> inNodes,
CellSetIn cellset,
FieldOutCell<IdComponentType> outCaseId);
typedef void ExecutionSignature(_1, _3);
typedef _2 InputDomain;
T IsoValue;
VTKM_CONT
Classification(T isovalue) :
IsoValue(isovalue)
Classification(T isovalue)
: IsoValue(isovalue)
{
}
template<typename FieldInType>
VTKM_EXEC
void operator()(const FieldInType &fieldIn,
vtkm::IdComponent &caseNumber) const
template <typename FieldInType>
VTKM_EXEC void operator()(const FieldInType& fieldIn, vtkm::IdComponent& caseNumber) const
{
typedef typename vtkm::VecTraits<FieldInType>::ComponentType FieldType;
const FieldType iso = static_cast<FieldType>(this->IsoValue);
caseNumber= ((fieldIn[0] > iso) |
(fieldIn[1] > iso) << 1 |
(fieldIn[2] > iso) << 2 |
(fieldIn[3] > iso) << 3 |
(fieldIn[4] > iso) << 4 |
(fieldIn[5] > iso) << 5 |
(fieldIn[6] > iso) << 6 |
(fieldIn[7] > iso) << 7);
caseNumber = ((fieldIn[0] > iso) | (fieldIn[1] > iso) << 1 | (fieldIn[2] > iso) << 2 |
(fieldIn[3] > iso) << 3 | (fieldIn[4] > iso) << 4 | (fieldIn[5] > iso) << 5 |
(fieldIn[6] > iso) << 6 | (fieldIn[7] > iso) << 7);
}
};
struct ValueTypes : vtkm::ListTagBase<vtkm::UInt32, vtkm::Int32, vtkm::Int64,
vtkm::Float32, vtkm::Float64 >{};
struct ValueTypes
: vtkm::ListTagBase<vtkm::UInt32, vtkm::Int32, vtkm::Int64, vtkm::Float32, vtkm::Float64>
{
};
using StorageListTag = ::vtkm::cont::StorageListTagBasic;
/// This class runs a series of micro-benchmarks to measure
/// performance of different field operations
template<class DeviceAdapterTag>
class BenchmarkTopologyAlgorithms {
template <class DeviceAdapterTag>
class BenchmarkTopologyAlgorithms
{
typedef vtkm::cont::StorageTagBasic StorageTag;
typedef vtkm::cont::DeviceAdapterAlgorithm<DeviceAdapterTag> Algorithm;
typedef vtkm::cont::Timer<DeviceAdapterTag> Timer;
using ValueDynamicHandle =
vtkm::cont::DynamicArrayHandleBase<ValueTypes, StorageListTag>;
using ValueDynamicHandle = vtkm::cont::DynamicArrayHandleBase<ValueTypes, StorageListTag>;
private:
template <typename T, typename Enable = void>
struct NumberGenerator
{
};
template<typename T, typename Enable= void> struct NumberGenerator {};
template<typename T>
struct NumberGenerator<T,
typename std::enable_if<
std::is_floating_point<T>::value
>::type
>
template <typename T>
struct NumberGenerator<T, typename std::enable_if<std::is_floating_point<T>::value>::type>
{
std::mt19937 rng;
std::uniform_real_distribution<T> distribution;
NumberGenerator(T low, T high): rng(), distribution(low,high) {}
NumberGenerator(T low, T high)
: rng()
, distribution(low, high)
{
}
T next() { return distribution(rng); }
};
template<typename T>
struct NumberGenerator<T,
typename std::enable_if<
!std::is_floating_point<T>::value
>::type
>
template <typename T>
struct NumberGenerator<T, typename std::enable_if<!std::is_floating_point<T>::value>::type>
{
std::mt19937 rng;
std::uniform_int_distribution<T> distribution;
NumberGenerator(T low, T high): rng(), distribution(low,high) {}
NumberGenerator(T low, T high)
: rng()
, distribution(low, high)
{
}
T next() { return distribution(rng); }
};
template<typename Value>
struct BenchCellToPointAvg {
std::vector< Value > input;
vtkm::cont::ArrayHandle< Value, StorageTag> InputHandle;
template <typename Value>
struct BenchCellToPointAvg
{
std::vector<Value> input;
vtkm::cont::ArrayHandle<Value, StorageTag> InputHandle;
std::size_t DomainSize;
VTKM_CONT
BenchCellToPointAvg()
{
NumberGenerator<Value> generator(static_cast<Value>(1.0),
static_cast<Value>(100.0));
NumberGenerator<Value> generator(static_cast<Value>(1.0), static_cast<Value>(100.0));
//cube size is points in each dim
this->DomainSize = (CUBE_SIZE-1)*(CUBE_SIZE-1)*(CUBE_SIZE-1);
this->input.resize( DomainSize );
for(std::size_t i=0; i < DomainSize; ++i )
this->DomainSize = (CUBE_SIZE - 1) * (CUBE_SIZE - 1) * (CUBE_SIZE - 1);
this->input.resize(DomainSize);
for (std::size_t i = 0; i < DomainSize; ++i)
{
this->input[i] = generator.next();
}
@ -212,15 +205,13 @@ private:
vtkm::Float64 operator()()
{
vtkm::cont::CellSetStructured<3> cellSet;
cellSet.SetPointDimensions( vtkm::Id3(CUBE_SIZE,CUBE_SIZE,CUBE_SIZE) );
vtkm::cont::ArrayHandle<Value,StorageTag> result;
cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
vtkm::cont::ArrayHandle<Value, StorageTag> result;
Timer timer;
vtkm::worklet::DispatcherMapTopology< AverageCellToPoint > dispatcher;
dispatcher.Invoke( this->InputHandle,
cellSet,
result);
vtkm::worklet::DispatcherMapTopology<AverageCellToPoint> dispatcher;
dispatcher.Invoke(this->InputHandle, cellSet, result);
//result.SyncControlArray();
return timer.GetElapsedTime();
@ -229,7 +220,8 @@ private:
virtual std::string Type() const { return std::string("Static"); }
VTKM_CONT
std::string Description() const {
std::string Description() const
{
std::stringstream description;
description << "Computing Cell To Point Average "
@ -239,25 +231,24 @@ private:
}
};
template<typename Value>
struct BenchCellToPointAvgDynamic : public BenchCellToPointAvg<Value> {
template <typename Value>
struct BenchCellToPointAvgDynamic : public BenchCellToPointAvg<Value>
{
VTKM_CONT
vtkm::Float64 operator()()
{
vtkm::cont::CellSetStructured<3> cellSet;
cellSet.SetPointDimensions( vtkm::Id3(CUBE_SIZE,CUBE_SIZE,CUBE_SIZE) );
cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
ValueDynamicHandle dinput(this->InputHandle);
vtkm::cont::ArrayHandle<Value,StorageTag> result;
vtkm::cont::ArrayHandle<Value, StorageTag> result;
Timer timer;
vtkm::worklet::DispatcherMapTopology< AverageCellToPoint > dispatcher;
vtkm::worklet::DispatcherMapTopology<AverageCellToPoint> dispatcher;
dispatcher.Invoke( dinput,
cellSet,
result);
dispatcher.Invoke(dinput, cellSet, result);
//result.SyncControlArray();
return timer.GetElapsedTime();
@ -269,21 +260,21 @@ private:
VTKM_MAKE_BENCHMARK(CellToPointAvg, BenchCellToPointAvg);
VTKM_MAKE_BENCHMARK(CellToPointAvgDynamic, BenchCellToPointAvgDynamic);
template<typename Value>
struct BenchPointToCellAvg {
std::vector< Value > input;
vtkm::cont::ArrayHandle< Value, StorageTag> InputHandle;
template <typename Value>
struct BenchPointToCellAvg
{
std::vector<Value> input;
vtkm::cont::ArrayHandle<Value, StorageTag> InputHandle;
std::size_t DomainSize;
VTKM_CONT
BenchPointToCellAvg()
{
NumberGenerator<Value> generator(static_cast<Value>(1.0),
static_cast<Value>(100.0));
NumberGenerator<Value> generator(static_cast<Value>(1.0), static_cast<Value>(100.0));
this->DomainSize = (CUBE_SIZE)*(CUBE_SIZE)*(CUBE_SIZE);
this->input.resize( DomainSize );
for(std::size_t i=0; i < DomainSize; ++i )
this->DomainSize = (CUBE_SIZE) * (CUBE_SIZE) * (CUBE_SIZE);
this->input.resize(DomainSize);
for (std::size_t i = 0; i < DomainSize; ++i)
{
this->input[i] = generator.next();
}
@ -294,15 +285,13 @@ private:
vtkm::Float64 operator()()
{
vtkm::cont::CellSetStructured<3> cellSet;
cellSet.SetPointDimensions( vtkm::Id3(CUBE_SIZE,CUBE_SIZE,CUBE_SIZE) );
vtkm::cont::ArrayHandle<Value,StorageTag> result;
cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
vtkm::cont::ArrayHandle<Value, StorageTag> result;
Timer timer;
vtkm::worklet::DispatcherMapTopology< AveragePointToCell > dispatcher;
dispatcher.Invoke( this->InputHandle,
cellSet,
result);
vtkm::worklet::DispatcherMapTopology<AveragePointToCell> dispatcher;
dispatcher.Invoke(this->InputHandle, cellSet, result);
//result.SyncControlArray();
return timer.GetElapsedTime();
@ -311,7 +300,8 @@ private:
virtual std::string Type() const { return std::string("Static"); }
VTKM_CONT
std::string Description() const {
std::string Description() const
{
std::stringstream description;
description << "Computing Point To Cell Average "
@ -321,24 +311,23 @@ private:
}
};
template<typename Value>
struct BenchPointToCellAvgDynamic : public BenchPointToCellAvg<Value> {
template <typename Value>
struct BenchPointToCellAvgDynamic : public BenchPointToCellAvg<Value>
{
VTKM_CONT
vtkm::Float64 operator()()
{
vtkm::cont::CellSetStructured<3> cellSet;
cellSet.SetPointDimensions( vtkm::Id3(CUBE_SIZE,CUBE_SIZE,CUBE_SIZE) );
cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
ValueDynamicHandle dinput(this->InputHandle);
vtkm::cont::ArrayHandle<Value,StorageTag> result;
vtkm::cont::ArrayHandle<Value, StorageTag> result;
Timer timer;
vtkm::worklet::DispatcherMapTopology< AveragePointToCell > dispatcher;
dispatcher.Invoke( dinput,
cellSet,
result);
vtkm::worklet::DispatcherMapTopology<AveragePointToCell> dispatcher;
dispatcher.Invoke(dinput, cellSet, result);
//result.SyncControlArray();
return timer.GetElapsedTime();
@ -350,22 +339,22 @@ private:
VTKM_MAKE_BENCHMARK(PointToCellAvg, BenchPointToCellAvg);
VTKM_MAKE_BENCHMARK(PointToCellAvgDynamic, BenchPointToCellAvgDynamic);
template<typename Value>
struct BenchClassification {
std::vector< Value > input;
vtkm::cont::ArrayHandle< Value, StorageTag> InputHandle;
template <typename Value>
struct BenchClassification
{
std::vector<Value> input;
vtkm::cont::ArrayHandle<Value, StorageTag> InputHandle;
Value IsoValue;
size_t DomainSize;
VTKM_CONT
BenchClassification()
{
NumberGenerator<Value> generator(static_cast<Value>(1.0),
static_cast<Value>(100.0));
NumberGenerator<Value> generator(static_cast<Value>(1.0), static_cast<Value>(100.0));
this->DomainSize = (CUBE_SIZE)*(CUBE_SIZE)*(CUBE_SIZE);
this->input.resize( DomainSize );
for(std::size_t i=0; i < DomainSize; ++i )
this->DomainSize = (CUBE_SIZE) * (CUBE_SIZE) * (CUBE_SIZE);
this->input.resize(DomainSize);
for (std::size_t i = 0; i < DomainSize; ++i)
{
this->input[i] = generator.next();
}
@ -377,18 +366,16 @@ private:
vtkm::Float64 operator()()
{
vtkm::cont::CellSetStructured<3> cellSet;
cellSet.SetPointDimensions( vtkm::Id3(CUBE_SIZE,CUBE_SIZE,CUBE_SIZE) );
vtkm::cont::ArrayHandle< vtkm::IdComponent, StorageTag> result;
cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
vtkm::cont::ArrayHandle<vtkm::IdComponent, StorageTag> result;
ValueDynamicHandle dinput(this->InputHandle);
Timer timer;
Classification<Value> worklet(this->IsoValue);
vtkm::worklet::DispatcherMapTopology< Classification<Value> > dispatcher(worklet);
dispatcher.Invoke( dinput,
cellSet,
result);
vtkm::worklet::DispatcherMapTopology<Classification<Value>> dispatcher(worklet);
dispatcher.Invoke(dinput, cellSet, result);
//result.SyncControlArray();
return timer.GetElapsedTime();
@ -397,7 +384,8 @@ private:
virtual std::string Type() const { return std::string("Static"); }
VTKM_CONT
std::string Description() const {
std::string Description() const
{
std::stringstream description;
description << "Computing Marching Cubes Classification "
@ -407,22 +395,21 @@ private:
}
};
template<typename Value>
struct BenchClassificationDynamic : public BenchClassification<Value> {
template <typename Value>
struct BenchClassificationDynamic : public BenchClassification<Value>
{
VTKM_CONT
vtkm::Float64 operator()()
{
vtkm::cont::CellSetStructured<3> cellSet;
cellSet.SetPointDimensions( vtkm::Id3(CUBE_SIZE,CUBE_SIZE,CUBE_SIZE) );
vtkm::cont::ArrayHandle< vtkm::IdComponent, StorageTag> result;
cellSet.SetPointDimensions(vtkm::Id3(CUBE_SIZE, CUBE_SIZE, CUBE_SIZE));
vtkm::cont::ArrayHandle<vtkm::IdComponent, StorageTag> result;
Timer timer;
Classification<Value> worklet(this->IsoValue);
vtkm::worklet::DispatcherMapTopology< Classification<Value> > dispatcher(worklet);
dispatcher.Invoke( this->InputHandle,
cellSet,
result);
vtkm::worklet::DispatcherMapTopology<Classification<Value>> dispatcher(worklet);
dispatcher.Invoke(this->InputHandle, cellSet, result);
//result.SyncControlArray();
return timer.GetElapsedTime();
@ -435,23 +422,26 @@ private:
VTKM_MAKE_BENCHMARK(ClassificationDynamic, BenchClassificationDynamic);
public:
static VTKM_CONT int Run(int benchmarks){
static VTKM_CONT int Run(int benchmarks)
{
std::cout << DIVIDER << "\nRunning Topology Algorithm benchmarks\n";
if (benchmarks & CELL_TO_POINT) {
if (benchmarks & CELL_TO_POINT)
{
std::cout << DIVIDER << "\nBenchmarking Cell To Point Average\n";
VTKM_RUN_BENCHMARK(CellToPointAvg, ValueTypes());
VTKM_RUN_BENCHMARK(CellToPointAvgDynamic, ValueTypes());
}
if (benchmarks & POINT_TO_CELL){
if (benchmarks & POINT_TO_CELL)
{
std::cout << DIVIDER << "\nBenchmarking Point to Cell Average\n";
VTKM_RUN_BENCHMARK(PointToCellAvg, ValueTypes());
VTKM_RUN_BENCHMARK(PointToCellAvgDynamic, ValueTypes());
}
if (benchmarks & MC_CLASSIFY){
if (benchmarks & MC_CLASSIFY)
{
std::cout << DIVIDER << "\nBenchmarking Hex/Voxel MC Classification\n";
VTKM_RUN_BENCHMARK(Classification, ValueTypes());
VTKM_RUN_BENCHMARK(ClassificationDynamic, ValueTypes());
@ -461,20 +451,21 @@ public:
}
};
#undef ARRAY_SIZE
}
} // namespace vtkm::benchmarking
int main(int argc, char *argv[])
int main(int argc, char* argv[])
{
int benchmarks = 0;
if (argc < 2){
if (argc < 2)
{
benchmarks = vtkm::benchmarking::ALL;
}
else {
for (int i = 1; i < argc; ++i){
else
{
for (int i = 1; i < argc; ++i)
{
std::string arg = argv[i];
std::transform(arg.begin(), arg.end(), arg.begin(), ::tolower);
if (arg == "celltopoint")
@ -489,7 +480,8 @@ int main(int argc, char *argv[])
{
benchmarks |= vtkm::benchmarking::MC_CLASSIFY;
}
else {
else
{
std::cout << "Unrecognized benchmark: " << argv[i] << std::endl;
return 1;
}
@ -497,6 +489,6 @@ int main(int argc, char *argv[])
}
//now actually execute the benchmarks
return vtkm::benchmarking::BenchmarkTopologyAlgorithms
<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>::Run(benchmarks);
return vtkm::benchmarking::BenchmarkTopologyAlgorithms<VTKM_DEFAULT_DEVICE_ADAPTER_TAG>::Run(
benchmarks);
}

@ -21,11 +21,13 @@
#ifndef vtk_m_benchmarking_Benchmarker_h
#define vtk_m_benchmarking_Benchmarker_h
#include <vtkm/ListTag.h>
#include <vtkm/Math.h>
#include <vtkm/cont/testing/Testing.h>
#include <vector>
#include <algorithm>
#include <iostream>
#include <vector>
/*
* Writing a Benchmark
@ -85,13 +87,14 @@
* instance of your benchmark for the type being benchmarked. The VA_ARGS are used to
* pass any extra arguments needed by your benchmark
*/
#define VTKM_MAKE_BENCHMARK(Name, Bench, ...) \
struct MakeBench##Name { \
template<typename Value> \
VTKM_CONT \
Bench<Value> operator()(const Value vtkmNotUsed(v)) const { \
return Bench<Value>(__VA_ARGS__); \
} \
#define VTKM_MAKE_BENCHMARK(Name, Bench, ...) \
struct MakeBench##Name \
{ \
template <typename Value> \
VTKM_CONT Bench<Value> operator()(const Value vtkmNotUsed(v)) const \
{ \
return Bench<Value>(__VA_ARGS__); \
} \
}
/*
@ -99,20 +102,26 @@
* You must have previously defined a maker functor with VTKM_MAKE_BENCHMARK that this
* macro will look for and use
*/
#define VTKM_RUN_BENCHMARK(Name, Types) \
#define VTKM_RUN_BENCHMARK(Name, Types) \
vtkm::benchmarking::BenchmarkTypes(MakeBench##Name(), (Types))
namespace vtkm {
namespace benchmarking {
namespace stats {
namespace vtkm
{
namespace benchmarking
{
namespace stats
{
// Checks that the sequence is sorted, returns true if it's sorted, false
// otherwise
template<typename ForwardIt>
bool is_sorted(ForwardIt first, ForwardIt last){
template <typename ForwardIt>
bool is_sorted(ForwardIt first, ForwardIt last)
{
ForwardIt next = first;
++next;
for (; next != last; ++next, ++first){
if (*first > *next){
for (; next != last; ++next, ++first)
{
if (*first > *next)
{
return false;
}
}
@ -121,16 +130,19 @@ bool is_sorted(ForwardIt first, ForwardIt last){
// Get the value representing the `percent` percentile of the
// sorted samples using linear interpolation
vtkm::Float64 PercentileValue(const std::vector<vtkm::Float64> &samples, const vtkm::Float64 percent){
vtkm::Float64 PercentileValue(const std::vector<vtkm::Float64>& samples,
const vtkm::Float64 percent)
{
VTKM_ASSERT(!samples.empty());
if (samples.size() == 1){
if (samples.size() == 1)
{
return samples.front();
}
VTKM_ASSERT(percent >= 0.0);
VTKM_ASSERT(percent <= 100.0);
VTKM_ASSERT(
vtkm::benchmarking::stats::is_sorted(samples.begin(), samples.end()));
if (percent == 100.0){
VTKM_ASSERT(vtkm::benchmarking::stats::is_sorted(samples.begin(), samples.end()));
if (percent == 100.0)
{
return samples.back();
}
// Find the two nearest percentile values and linearly
@ -147,45 +159,56 @@ vtkm::Float64 PercentileValue(const std::vector<vtkm::Float64> &samples, const v
// Will replace all samples below `percent` and above 100 - `percent` percentiles
// with the value at the percentile
// NOTE: Assumes the samples have been sorted, as we make use of PercentileValue
void Winsorize(std::vector<vtkm::Float64> &samples, const vtkm::Float64 percent){
void Winsorize(std::vector<vtkm::Float64>& samples, const vtkm::Float64 percent)
{
const vtkm::Float64 low_percentile = PercentileValue(samples, percent);
const vtkm::Float64 high_percentile = PercentileValue(samples, 100.0 - percent);
for (std::vector<vtkm::Float64>::iterator it = samples.begin(); it != samples.end(); ++it){
if (*it < low_percentile){
for (std::vector<vtkm::Float64>::iterator it = samples.begin(); it != samples.end(); ++it)
{
if (*it < low_percentile)
{
*it = low_percentile;
}
else if (*it > high_percentile){
else if (*it > high_percentile)
{
*it = high_percentile;
}
}
}
// Compute the mean value of the dataset
vtkm::Float64 Mean(const std::vector<vtkm::Float64> &samples){
vtkm::Float64 Mean(const std::vector<vtkm::Float64>& samples)
{
vtkm::Float64 mean = 0;
for (std::vector<vtkm::Float64>::const_iterator it = samples.begin(); it != samples.end(); ++it){
for (std::vector<vtkm::Float64>::const_iterator it = samples.begin(); it != samples.end(); ++it)
{
mean += *it;
}
return mean / static_cast<vtkm::Float64>(samples.size());
}
// Compute the sample variance of the samples
vtkm::Float64 Variance(const std::vector<vtkm::Float64> &samples){
vtkm::Float64 Variance(const std::vector<vtkm::Float64>& samples)
{
vtkm::Float64 mean = Mean(samples);
vtkm::Float64 square_deviations = 0;
for (std::vector<vtkm::Float64>::const_iterator it = samples.begin(); it != samples.end(); ++it){
for (std::vector<vtkm::Float64>::const_iterator it = samples.begin(); it != samples.end(); ++it)
{
square_deviations += vtkm::Pow(*it - mean, 2.0);
}
return square_deviations / (static_cast<vtkm::Float64>(samples.size()) - 1.0);
}
// Compute the standard deviation of the samples
vtkm::Float64 StandardDeviation(const std::vector<vtkm::Float64> &samples){
vtkm::Float64 StandardDeviation(const std::vector<vtkm::Float64>& samples)
{
return vtkm::Sqrt(Variance(samples));
}
// Compute the median absolute deviation of the dataset
vtkm::Float64 MedianAbsDeviation(const std::vector<vtkm::Float64> &samples){
vtkm::Float64 MedianAbsDeviation(const std::vector<vtkm::Float64>& samples)
{
std::vector<vtkm::Float64> abs_deviations;
abs_deviations.reserve(samples.size());
const vtkm::Float64 median = PercentileValue(samples, 50.0);
for (std::vector<vtkm::Float64>::const_iterator it = samples.begin(); it != samples.end(); ++it){
for (std::vector<vtkm::Float64>::const_iterator it = samples.begin(); it != samples.end(); ++it)
{
abs_deviations.push_back(vtkm::Abs(*it - median));
}
std::sort(abs_deviations.begin(), abs_deviations.end());
@ -200,15 +223,20 @@ vtkm::Float64 MedianAbsDeviation(const std::vector<vtkm::Float64> &samples){
* in seconds, this lets us avoid including any per-run setup time in the benchmark.
* However any one-time setup should be done in the functor's constructor
*/
struct Benchmarker {
struct Benchmarker
{
const vtkm::Float64 MAX_RUNTIME;
const size_t MAX_ITERATIONS;
Benchmarker() : MAX_RUNTIME(30), MAX_ITERATIONS(500){}
Benchmarker()
: MAX_RUNTIME(30)
, MAX_ITERATIONS(500)
{
}
template<typename Functor>
VTKM_CONT
void operator()(Functor func) const {
template <typename Functor>
VTKM_CONT void operator()(Functor func) const
{
std::vector<vtkm::Float64> samples;
// Do a warm-up run. If the benchmark allocates any additional memory
// eg. storage for output results, this will let it do that and
@ -222,50 +250,49 @@ struct Benchmarker {
// could be increased
size_t iter = 0;
for (vtkm::Float64 elapsed = 0.0; elapsed < MAX_RUNTIME && iter < MAX_ITERATIONS;
elapsed += samples.back(), ++iter)
elapsed += samples.back(), ++iter)
{
samples.push_back(func());
}
std::sort(samples.begin(), samples.end());
stats::Winsorize(samples, 5.0);
std::cout << "Benchmark \'"
<< func.Description() << "\' results:\n"
<< "\tmedian = " << stats::PercentileValue(samples, 50.0) << "s\n"
<< "\tmedian abs dev = " << stats::MedianAbsDeviation(samples) << "s\n"
<< "\tmean = " << stats::Mean(samples) << "s\n"
<< "\tstd dev = " << stats::StandardDeviation(samples) << "s\n"
<< "\tmin = " << samples.front() << "s\n"
<< "\tmax = " << samples.back() << "s\n";
std::cout << "Benchmark \'" << func.Description() << "\' results:\n"
<< "\tmedian = " << stats::PercentileValue(samples, 50.0) << "s\n"
<< "\tmedian abs dev = " << stats::MedianAbsDeviation(samples) << "s\n"
<< "\tmean = " << stats::Mean(samples) << "s\n"
<< "\tstd dev = " << stats::StandardDeviation(samples) << "s\n"
<< "\tmin = " << samples.front() << "s\n"
<< "\tmax = " << samples.back() << "s\n";
}
};
template<typename MakerFunctor>
class InternalPrintTypeAndBench {
template <typename MakerFunctor>
class InternalPrintTypeAndBench
{
MakerFunctor Maker;
public:
VTKM_CONT
InternalPrintTypeAndBench(MakerFunctor maker) : Maker(maker) {}
InternalPrintTypeAndBench(MakerFunctor maker)
: Maker(maker)
{
}
template<typename T>
VTKM_CONT
void operator()(T t) const {
std::cout << "*** "
<< vtkm::testing::TypeName<T>::Name()
<< " ***************" << std::endl;
template <typename T>
VTKM_CONT void operator()(T t) const
{
std::cout << "*** " << vtkm::testing::TypeName<T>::Name() << " ***************" << std::endl;
Benchmarker bench;
bench(Maker(t));
}
};
template<class MakerFunctor, class TypeList>
VTKM_CONT
void BenchmarkTypes(const MakerFunctor &maker, TypeList){
template <class MakerFunctor, class TypeList>
VTKM_CONT void BenchmarkTypes(const MakerFunctor& maker, TypeList)
{
vtkm::ListForEach(InternalPrintTypeAndBench<MakerFunctor>(maker), TypeList());
}
}
}
#endif

@ -19,6 +19,7 @@
##============================================================================
set(benchmark_srcs
BenchmarkArrayTransfer.cxx
BenchmarkDeviceAdapter.cxx
BenchmarkFieldAlgorithms.cxx
BenchmarkTopologyAlgorithms.cxx

@ -22,65 +22,67 @@
#include <vtkm/cont/ArrayHandle.h>
#ifdef VTKM_MSVC
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<char, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::Int8, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::UInt8, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::Int16, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::UInt16, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::Int32, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::UInt32, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::Int64, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::UInt64, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::Float32, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::Float64, vtkm::cont::StorageTagBasic>::InternalStruct >;
#define _VTKM_SHARED_PTR_INSTANTIATE(Type) \
template class VTKM_CONT_EXPORT \
std::shared_ptr<vtkm::cont::ArrayHandle<Type, vtkm::cont::StorageTagBasic>::InternalStruct>; \
template class VTKM_CONT_EXPORT std::shared_ptr< \
vtkm::cont::ArrayHandle<vtkm::Vec<Type, 2>, vtkm::cont::StorageTagBasic>::InternalStruct>; \
template class VTKM_CONT_EXPORT std::shared_ptr< \
vtkm::cont::ArrayHandle<vtkm::Vec<Type, 3>, vtkm::cont::StorageTagBasic>::InternalStruct>; \
template class VTKM_CONT_EXPORT std::shared_ptr< \
vtkm::cont::ArrayHandle<vtkm::Vec<Type, 4>, vtkm::cont::StorageTagBasic>::InternalStruct>;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Int64,2>, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Int32,2>, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32,2>, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float64,2>, vtkm::cont::StorageTagBasic>::InternalStruct >;
_VTKM_SHARED_PTR_INSTANTIATE(char)
_VTKM_SHARED_PTR_INSTANTIATE(vtkm::Int8)
_VTKM_SHARED_PTR_INSTANTIATE(vtkm::UInt8)
_VTKM_SHARED_PTR_INSTANTIATE(vtkm::Int16)
_VTKM_SHARED_PTR_INSTANTIATE(vtkm::UInt16)
_VTKM_SHARED_PTR_INSTANTIATE(vtkm::Int32)
_VTKM_SHARED_PTR_INSTANTIATE(vtkm::UInt32)
_VTKM_SHARED_PTR_INSTANTIATE(vtkm::Int64)
_VTKM_SHARED_PTR_INSTANTIATE(vtkm::UInt64)
_VTKM_SHARED_PTR_INSTANTIATE(vtkm::Float32)
_VTKM_SHARED_PTR_INSTANTIATE(vtkm::Float64)
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Int64,3>, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Int32,3>, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32,3>, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float64,3>, vtkm::cont::StorageTagBasic>::InternalStruct >;
#undef _VTKM_SHARED_PTR_INSTANTIATE
#endif // VTKM_MSVC
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<char,4>, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Int8,4>, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::UInt8,4>, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32,4>, vtkm::cont::StorageTagBasic>::InternalStruct >;
template class VTKM_CONT_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float64,4>, vtkm::cont::StorageTagBasic>::InternalStruct >;
#endif
namespace vtkm {
namespace cont {
template class VTKM_CONT_EXPORT ArrayHandle<char, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Int8, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::UInt8, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Int16, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::UInt16, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Int32, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::UInt32, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Int64, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::UInt64, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Float32, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Float64, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle< vtkm::Vec<vtkm::Int64,2>, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle< vtkm::Vec<vtkm::Int32,2>, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle< vtkm::Vec<vtkm::Float32,2>, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle< vtkm::Vec<vtkm::Float64,2>, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle< vtkm::Vec<vtkm::Int64,3>, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle< vtkm::Vec<vtkm::Int32,3>, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle< vtkm::Vec<vtkm::Float32,3>, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle< vtkm::Vec<vtkm::Float64,3>, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle< vtkm::Vec<char,4>, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle< vtkm::Vec<vtkm::Int8,4>, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle< vtkm::Vec<vtkm::UInt8,4>, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle< vtkm::Vec<vtkm::Float32,4>, StorageTagBasic>;
template class VTKM_CONT_EXPORT ArrayHandle< vtkm::Vec<vtkm::Float64,4>, StorageTagBasic>;
namespace vtkm
{
namespace cont
{
namespace internal
{
ExecutionArrayInterfaceBasicBase::ExecutionArrayInterfaceBasicBase(StorageBasicBase& storage)
: ControlStorage(storage)
{
}
}
ExecutionArrayInterfaceBasicBase::~ExecutionArrayInterfaceBasicBase()
{
}
} // end namespace internal
#define _VTKM_ARRAYHANDLE_INSTANTIATE(Type) \
template class VTKM_CONT_EXPORT ArrayHandle<Type, StorageTagBasic>; \
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Vec<Type, 2>, StorageTagBasic>; \
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Vec<Type, 3>, StorageTagBasic>; \
template class VTKM_CONT_EXPORT ArrayHandle<vtkm::Vec<Type, 4>, StorageTagBasic>;
_VTKM_ARRAYHANDLE_INSTANTIATE(char)
_VTKM_ARRAYHANDLE_INSTANTIATE(vtkm::Int8)
_VTKM_ARRAYHANDLE_INSTANTIATE(vtkm::UInt8)
_VTKM_ARRAYHANDLE_INSTANTIATE(vtkm::Int16)
_VTKM_ARRAYHANDLE_INSTANTIATE(vtkm::UInt16)
_VTKM_ARRAYHANDLE_INSTANTIATE(vtkm::Int32)
_VTKM_ARRAYHANDLE_INSTANTIATE(vtkm::UInt32)
_VTKM_ARRAYHANDLE_INSTANTIATE(vtkm::Int64)
_VTKM_ARRAYHANDLE_INSTANTIATE(vtkm::UInt64)
_VTKM_ARRAYHANDLE_INSTANTIATE(vtkm::Float32)
_VTKM_ARRAYHANDLE_INSTANTIATE(vtkm::Float64)
#undef _VTKM_ARRAYHANDLE_INSTANTIATE
}
} // end vtkm::cont

@ -31,17 +31,20 @@
#include <vtkm/cont/Storage.h>
#include <vtkm/cont/StorageBasic.h>
#include <vtkm/cont/internal/ArrayHandleExecutionManager.h>
#include <vtkm/cont/internal/DeviceAdapterTag.h>
#include <iterator>
#include <memory>
#include <vector>
#include <iterator>
namespace vtkm {
namespace cont {
#include <vtkm/cont/internal/ArrayHandleExecutionManager.h>
#include <vtkm/cont/internal/ArrayPortalFromIterators.h>
namespace internal {
namespace vtkm
{
namespace cont
{
namespace internal
{
/// \brief Base class of all ArrayHandle classes.
///
@ -49,7 +52,9 @@ namespace internal {
/// ArrayHandle class (or at least something that behaves exactly like one).
/// The \c ArrayHandle template class inherits from this.
///
class VTKM_CONT_EXPORT ArrayHandleBase { };
class VTKM_CONT_EXPORT ArrayHandleBase
{
};
/// Checks to see if the given type and storage can form a valid array handle
/// (some storage objects cannot support all types). This check is compatible
@ -57,14 +62,14 @@ class VTKM_CONT_EXPORT ArrayHandleBase { };
/// typedef named type that is either std::true_type or std::false_type.
/// Both of these have a typedef named value with the respective boolean value.
///
template<typename T, typename StorageTag>
struct IsValidArrayHandle {
template <typename T, typename StorageTag>
struct IsValidArrayHandle
{
//need to add the not
using type = std::integral_constant<bool,
!( std::is_base_of<
vtkm::cont::internal::UndefinedStorage,
vtkm::cont::internal::Storage<T,StorageTag>
>::value)>;
using type =
std::integral_constant<bool,
!(std::is_base_of<vtkm::cont::internal::UndefinedStorage,
vtkm::cont::internal::Storage<T, StorageTag>>::value)>;
};
/// Checks to see if the ArrayHandle for the given DeviceAdatper allows
@ -74,10 +79,11 @@ struct IsValidArrayHandle {
/// std::true_type or std::false_type.
/// Both of these have a typedef named value with the respective boolean value.
///
template<typename ArrayHandle, typename DeviceAdapterTag>
struct IsWriteableArrayHandle {
template <typename ArrayHandle, typename DeviceAdapterTag>
struct IsWriteableArrayHandle
{
private:
template<typename T>
template <typename T>
using ExecutionTypes = typename ArrayHandle::template ExecutionTypes<T>;
using ValueType = typename ExecutionTypes<DeviceAdapterTag>::Portal::ValueType;
@ -86,6 +92,7 @@ private:
//will have a value type of void*, which is what we are trying to detect
using RawValueType = typename std::remove_pointer<ValueType>::type;
using IsVoidType = std::is_void<RawValueType>;
public:
using type = std::integral_constant<bool, !IsVoidType::value>;
};
@ -102,22 +109,23 @@ public:
/// class is used to ensure that a given type is an \c ArrayHandle. It is
/// used internally in the VTKM_IS_ARRAY_HANDLE macro.
///
template<typename T>
template <typename T>
struct ArrayHandleCheck
{
using type = typename std::is_base_of<
::vtkm::cont::internal::ArrayHandleBase, T>::type;
using type = typename std::is_base_of<::vtkm::cont::internal::ArrayHandleBase, T>::type;
};
#define VTKM_IS_ARRAY_HANDLE(T) \
#define VTKM_IS_ARRAY_HANDLE(T) \
VTKM_STATIC_ASSERT(::vtkm::cont::internal::ArrayHandleCheck<T>::type::value)
} // namespace internal
namespace detail {
namespace detail
{
template<typename T> struct GetTypeInParentheses;
template<typename T>
template <typename T>
struct GetTypeInParentheses;
template <typename T>
struct GetTypeInParentheses<void(T)>
{
typedef T type;
@ -126,29 +134,39 @@ struct GetTypeInParentheses<void(T)>
} // namespace detail
// Implementation for VTKM_ARRAY_HANDLE_SUBCLASS macros
#define VTK_M_ARRAY_HANDLE_SUBCLASS_IMPL(classname, fullclasstype, superclass, typename__) \
typedef typename__ vtkm::cont::detail::GetTypeInParentheses<void fullclasstype>::type Thisclass;\
typedef typename__ vtkm::cont::detail::GetTypeInParentheses<void superclass>::type Superclass;\
\
VTKM_IS_ARRAY_HANDLE(Superclass); \
\
VTKM_CONT \
classname() : Superclass() { } \
\
VTKM_CONT \
classname(const Thisclass &src) : Superclass(src) { } \
\
VTKM_CONT \
classname(const vtkm::cont::ArrayHandle<typename__ Superclass::ValueType, typename__ Superclass::StorageTag> &src) : Superclass(src) { } \
\
VTKM_CONT \
Thisclass &operator=(const Thisclass &src) \
{ \
this->Superclass::operator=(src); \
return *this; \
} \
\
typedef typename__ Superclass::ValueType ValueType; \
#define VTK_M_ARRAY_HANDLE_SUBCLASS_IMPL(classname, fullclasstype, superclass, typename__) \
typedef typename__ vtkm::cont::detail::GetTypeInParentheses<void fullclasstype>::type Thisclass; \
typedef typename__ vtkm::cont::detail::GetTypeInParentheses<void superclass>::type Superclass; \
\
VTKM_IS_ARRAY_HANDLE(Superclass); \
\
VTKM_CONT \
classname() \
: Superclass() \
{ \
} \
\
VTKM_CONT \
classname(const Thisclass& src) \
: Superclass(src) \
{ \
} \
\
VTKM_CONT \
classname(const vtkm::cont::ArrayHandle<typename__ Superclass::ValueType, \
typename__ Superclass::StorageTag>& src) \
: Superclass(src) \
{ \
} \
\
VTKM_CONT \
Thisclass& operator=(const Thisclass& src) \
{ \
this->Superclass::operator=(src); \
return *this; \
} \
\
typedef typename__ Superclass::ValueType ValueType; \
typedef typename__ Superclass::StorageTag StorageTag
/// \brief Macro to make default methods in ArrayHandle subclasses.
@ -172,7 +190,7 @@ struct GetTypeInParentheses<void(T)>
/// templated. For ArrayHandle sublcasses that are not templates, use
/// VTKM_ARRAY_HANDLE_SUBCLASS_NT.
///
#define VTKM_ARRAY_HANDLE_SUBCLASS(classname, fullclasstype, superclass) \
#define VTKM_ARRAY_HANDLE_SUBCLASS(classname, fullclasstype, superclass) \
VTK_M_ARRAY_HANDLE_SUBCLASS_IMPL(classname, fullclasstype, superclass, typename)
/// \brief Macro to make default methods in ArrayHandle subclasses.
@ -195,7 +213,7 @@ struct GetTypeInParentheses<void(T)>
/// templated. For ArrayHandle sublcasses that are are templates, use
/// VTKM_ARRAY_HANDLE_SUBCLASS.
///
#define VTKM_ARRAY_HANDLE_SUBCLASS_NT(classname, superclass) \
#define VTKM_ARRAY_HANDLE_SUBCLASS_NT(classname, superclass) \
VTK_M_ARRAY_HANDLE_SUBCLASS_IMPL(classname, (classname), superclass, )
/// \brief Manages an array-worth of data.
@ -219,16 +237,20 @@ struct GetTypeInParentheses<void(T)>
/// allocated memory is released.
///
///
template<
typename T,
typename StorageTag_ = VTKM_DEFAULT_STORAGE_TAG>
template <typename T, typename StorageTag_ = VTKM_DEFAULT_STORAGE_TAG>
class VTKM_ALWAYS_EXPORT ArrayHandle : public internal::ArrayHandleBase
{
private:
typedef vtkm::cont::internal::ArrayHandleExecutionManagerBase<T,StorageTag_>
ExecutionManagerType;
// Basic storage is specialized; this template should not be instantiated
// for it. Specialization is in ArrayHandleBasicImpl.h
static_assert(!std::is_same<StorageTag_, StorageTagBasic>::value,
"StorageTagBasic should not use this implementation.");
using ExecutionManagerType =
vtkm::cont::internal::ArrayHandleExecutionManagerBase<T, StorageTag_>;
public:
typedef vtkm::cont::internal::Storage<T,StorageTag_> StorageType;
typedef vtkm::cont::internal::Storage<T, StorageTag_> StorageType;
typedef T ValueType;
typedef StorageTag_ StorageTag;
typedef typename StorageType::PortalType PortalControl;
@ -236,10 +258,9 @@ public:
template <typename DeviceAdapterTag>
struct ExecutionTypes
{
typedef typename ExecutionManagerType
::template ExecutionTypes<DeviceAdapterTag>::Portal Portal;
typedef typename ExecutionManagerType
::template ExecutionTypes<DeviceAdapterTag>::PortalConst PortalConst;
typedef typename ExecutionManagerType::template ExecutionTypes<DeviceAdapterTag>::Portal Portal;
typedef typename ExecutionManagerType::template ExecutionTypes<DeviceAdapterTag>::PortalConst
PortalConst;
};
/// Constructs an empty ArrayHandle. Typically used for output or
@ -254,7 +275,7 @@ public:
/// with CUDA), then the automatically generated copy constructor could be
/// created for all devices, and it would not be valid for all devices.
///
ArrayHandle(const vtkm::cont::ArrayHandle<ValueType,StorageTag> &src);
ArrayHandle(const vtkm::cont::ArrayHandle<ValueType, StorageTag>& src);
/// Move constructor.
///
@ -263,14 +284,13 @@ public:
/// with CUDA), then the automatically generated move constructor could be
/// created for all devices, and it would not be valid for all devices.
///
ArrayHandle(vtkm::cont::ArrayHandle<ValueType,StorageTag> &&src);
ArrayHandle(vtkm::cont::ArrayHandle<ValueType, StorageTag>&& src);
/// Special constructor for subclass specializations that need to set the
/// initial state of the control array. When this constructor is used, it
/// is assumed that the control array is valid.
///
ArrayHandle(const StorageType &storage);
ArrayHandle(const StorageType& storage);
/// Destructs an empty ArrayHandle.
///
@ -284,25 +304,25 @@ public:
/// \brief Copies an ArrayHandle
///
VTKM_CONT
vtkm::cont::ArrayHandle<ValueType,StorageTag> &
operator=(const vtkm::cont::ArrayHandle<ValueType,StorageTag> &src);
vtkm::cont::ArrayHandle<ValueType, StorageTag>& operator=(
const vtkm::cont::ArrayHandle<ValueType, StorageTag>& src);
/// \brief Move and Assignment of an ArrayHandle
///
VTKM_CONT
vtkm::cont::ArrayHandle<ValueType,StorageTag> &
operator=(vtkm::cont::ArrayHandle<ValueType,StorageTag> &&src);
vtkm::cont::ArrayHandle<ValueType, StorageTag>& operator=(
vtkm::cont::ArrayHandle<ValueType, StorageTag>&& src);
/// Like a pointer, two \c ArrayHandles are considered equal if they point
/// to the same location in memory.
///
VTKM_CONT
bool operator==(const ArrayHandle<ValueType,StorageTag> &rhs) const
bool operator==(const ArrayHandle<ValueType, StorageTag>& rhs) const
{
return (this->Internals == rhs.Internals);
}
VTKM_CONT
bool operator!=(const ArrayHandle<ValueType,StorageTag> &rhs) const
bool operator!=(const ArrayHandle<ValueType, StorageTag>& rhs) const
{
return (this->Internals != rhs.Internals);
}
@ -330,7 +350,7 @@ public:
/// Copies data into the given iterator for the control environment. This
/// method can skip copying into an internally managed control array.
///
template<typename IteratorType, typename DeviceAdapterTag>
template <typename IteratorType, typename DeviceAdapterTag>
VTKM_CONT void CopyInto(IteratorType dest, DeviceAdapterTag) const;
/// \brief Allocates an array large enough to hold the given number of values.
@ -384,16 +404,17 @@ public:
}
}
// clang-format off
/// Prepares this array to be used as an input to an operation in the
/// execution environment. If necessary, copies data to the execution
/// environment. Can throw an exception if this array does not yet contain
/// any data. Returns a portal that can be used in code running in the
/// execution environment.
///
template<typename DeviceAdapterTag>
template <typename DeviceAdapterTag>
VTKM_CONT
typename ExecutionTypes<DeviceAdapterTag>::PortalConst
PrepareForInput(DeviceAdapterTag) const;
typename ExecutionTypes<DeviceAdapterTag>::PortalConst PrepareForInput(DeviceAdapterTag) const;
// clang-format on
/// Prepares (allocates) this array to be used as an output from an operation
/// in the execution environment. The internal state of this class is set to
@ -402,10 +423,10 @@ public:
/// called). Returns a portal that can be used in code running in the
/// execution environment.
///
template<typename DeviceAdapterTag>
VTKM_CONT
typename ExecutionTypes<DeviceAdapterTag>::Portal
PrepareForOutput(vtkm::Id numberOfValues, DeviceAdapterTag);
template <typename DeviceAdapterTag>
VTKM_CONT typename ExecutionTypes<DeviceAdapterTag>::Portal PrepareForOutput(
vtkm::Id numberOfValues,
DeviceAdapterTag);
/// Prepares this array to be used in an in-place operation (both as input
/// and output) in the execution environment. If necessary, copies data to
@ -413,19 +434,16 @@ public:
/// yet contain any data. Returns a portal that can be used in code running
/// in the execution environment.
///
template<typename DeviceAdapterTag>
VTKM_CONT
typename ExecutionTypes<DeviceAdapterTag>::Portal
PrepareForInPlace(DeviceAdapterTag);
template <typename DeviceAdapterTag>
VTKM_CONT typename ExecutionTypes<DeviceAdapterTag>::Portal PrepareForInPlace(DeviceAdapterTag);
/// Gets this array handle ready to interact with the given device. If the
/// array handle has already interacted with this device, then this method
/// does nothing. Although the internal state of this class can change, the
/// method is declared const because logically the data does not.
///
template<typename DeviceAdapterTag>
VTKM_CONT
void PrepareForDevice(DeviceAdapterTag) const;
template <typename DeviceAdapterTag>
VTKM_CONT void PrepareForDevice(DeviceAdapterTag) const;
/// Synchronizes the control array with the execution array. If either the
/// user array or control array is already valid, this method does nothing
@ -450,47 +468,40 @@ public:
StorageType ControlArray;
bool ControlArrayValid;
std::unique_ptr<
vtkm::cont::internal::ArrayHandleExecutionManagerBase<
ValueType,StorageTag> > ExecutionArray;
std::unique_ptr<vtkm::cont::internal::ArrayHandleExecutionManagerBase<ValueType, StorageTag>>
ExecutionArray;
bool ExecutionArrayValid;
};
VTKM_CONT
ArrayHandle(const std::shared_ptr<InternalStruct>& i)
: Internals(i)
{ }
{
}
std::shared_ptr<InternalStruct> Internals;
};
/// A convenience function for creating an ArrayHandle from a standard C array.
///
template<typename T>
VTKM_CONT
vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>
make_ArrayHandle(const T *array,
vtkm::Id length)
template <typename T>
VTKM_CONT vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic> make_ArrayHandle(const T* array,
vtkm::Id length)
{
typedef vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>
ArrayHandleType;
typedef vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagBasic>
StorageType;
typedef vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic> ArrayHandleType;
typedef vtkm::cont::internal::Storage<T, vtkm::cont::StorageTagBasic> StorageType;
return ArrayHandleType(StorageType(array, length));
}
/// A convenience function for creating an ArrayHandle from an std::vector.
///
template<typename T,
typename Allocator>
VTKM_CONT
vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic>
make_ArrayHandle(const std::vector<T,Allocator> &array)
template <typename T, typename Allocator>
VTKM_CONT vtkm::cont::ArrayHandle<T, vtkm::cont::StorageTagBasic> make_ArrayHandle(
const std::vector<T, Allocator>& array)
{
if (!array.empty())
{
return make_ArrayHandle(&array.front(),
static_cast<vtkm::Id>(array.size()));
return make_ArrayHandle(&array.front(), static_cast<vtkm::Id>(array.size()));
}
else
{
@ -499,35 +510,32 @@ make_ArrayHandle(const std::vector<T,Allocator> &array)
}
}
namespace detail {
namespace detail
{
template<typename T>
VTKM_NEVER_EXPORT
VTKM_CONT
inline void printSummary_ArrayHandle_Value(const T &value,
std::ostream &out,
vtkm::VecTraitsTagSingleComponent)
template <typename T>
VTKM_NEVER_EXPORT VTKM_CONT inline void
printSummary_ArrayHandle_Value(const T& value, std::ostream& out, vtkm::VecTraitsTagSingleComponent)
{
out << value;
}
template<typename T>
VTKM_NEVER_EXPORT
VTKM_CONT
inline void printSummary_ArrayHandle_Value(const T &value,
std::ostream &out,
vtkm::VecTraitsTagMultipleComponents)
template <typename T>
VTKM_NEVER_EXPORT VTKM_CONT inline void printSummary_ArrayHandle_Value(
const T& value,
std::ostream& out,
vtkm::VecTraitsTagMultipleComponents)
{
using Traits = vtkm::VecTraits<T>;
using ComponentType = typename Traits::ComponentType;
using IsVecOfVec = typename vtkm::VecTraits<ComponentType>::HasMultipleComponents;
vtkm::IdComponent numComponents = Traits::GetNumberOfComponents(value);
out << "(";
printSummary_ArrayHandle_Value(Traits::GetComponent(value,0), out, IsVecOfVec());
printSummary_ArrayHandle_Value(Traits::GetComponent(value, 0), out, IsVecOfVec());
for (vtkm::IdComponent index = 1; index < numComponents; ++index)
{
out << ",";
printSummary_ArrayHandle_Value(Traits::GetComponent(value,index), out, IsVecOfVec());
printSummary_ArrayHandle_Value(Traits::GetComponent(value, index), out, IsVecOfVec());
}
out << ")";
}
@ -535,7 +543,7 @@ inline void printSummary_ArrayHandle_Value(const T &value,
VTKM_NEVER_EXPORT
VTKM_CONT
inline void printSummary_ArrayHandle_Value(UInt8 value,
std::ostream &out,
std::ostream& out,
vtkm::VecTraitsTagSingleComponent)
{
out << static_cast<int>(value);
@ -544,61 +552,53 @@ inline void printSummary_ArrayHandle_Value(UInt8 value,
VTKM_NEVER_EXPORT
VTKM_CONT
inline void printSummary_ArrayHandle_Value(Int8 value,
std::ostream &out,
std::ostream& out,
vtkm::VecTraitsTagSingleComponent)
{
out << static_cast<int>(value);
}
template<typename T1, typename T2>
VTKM_NEVER_EXPORT
VTKM_CONT
inline void printSummary_ArrayHandle_Value(const vtkm::Pair<T1,T2> &value,
std::ostream &out,
vtkm::VecTraitsTagSingleComponent)
template <typename T1, typename T2>
VTKM_NEVER_EXPORT VTKM_CONT inline void printSummary_ArrayHandle_Value(
const vtkm::Pair<T1, T2>& value,
std::ostream& out,
vtkm::VecTraitsTagSingleComponent)
{
out << "{";
printSummary_ArrayHandle_Value(
value.first,
out,
typename vtkm::VecTraits<T1>::HasMultipleComponents());
value.first, out, typename vtkm::VecTraits<T1>::HasMultipleComponents());
out << ",";
printSummary_ArrayHandle_Value(
value.second,
out,
typename vtkm::VecTraits<T2>::HasMultipleComponents());
value.second, out, typename vtkm::VecTraits<T2>::HasMultipleComponents());
out << "}";
}
} // namespace detail
template<typename T, typename StorageT>
VTKM_NEVER_EXPORT
VTKM_CONT
inline void
printSummary_ArrayHandle(const vtkm::cont::ArrayHandle<T,StorageT> &array,
std::ostream &out)
template <typename T, typename StorageT>
VTKM_NEVER_EXPORT VTKM_CONT inline void printSummary_ArrayHandle(
const vtkm::cont::ArrayHandle<T, StorageT>& array,
std::ostream& out,
bool full = false)
{
using ArrayType = vtkm::cont::ArrayHandle<T,StorageT>;
using ArrayType = vtkm::cont::ArrayHandle<T, StorageT>;
using PortalType = typename ArrayType::PortalConstControl;
using IsVec = typename vtkm::VecTraits<T>::HasMultipleComponents;
vtkm::Id sz = array.GetNumberOfValues();
out << "valueType=" << typeid(T).name()
<< " storageType=" << typeid(StorageT).name()
<< " numValues=" << sz
<< " [";
out << "valueType=" << typeid(T).name() << " storageType=" << typeid(StorageT).name()
<< " numValues=" << sz << " [";
PortalType portal = array.GetPortalConstControl();
if (sz <= 7)
if (full || sz <= 7)
{
for (vtkm::Id i = 0 ; i < sz; i++)
for (vtkm::Id i = 0; i < sz; i++)
{
detail::printSummary_ArrayHandle_Value(portal.Get(i), out, IsVec());
if (i != (sz-1))
if (i != (sz - 1))
{
out<<" ";
out << " ";
}
}
}
@ -610,84 +610,78 @@ printSummary_ArrayHandle(const vtkm::cont::ArrayHandle<T,StorageT> &array,
out << " ";
detail::printSummary_ArrayHandle_Value(portal.Get(2), out, IsVec());
out << " ... ";
detail::printSummary_ArrayHandle_Value(portal.Get(sz-3), out, IsVec());
detail::printSummary_ArrayHandle_Value(portal.Get(sz - 3), out, IsVec());
out << " ";
detail::printSummary_ArrayHandle_Value(portal.Get(sz-2), out, IsVec());
detail::printSummary_ArrayHandle_Value(portal.Get(sz - 2), out, IsVec());
out << " ";
detail::printSummary_ArrayHandle_Value(portal.Get(sz-1), out, IsVec());
detail::printSummary_ArrayHandle_Value(portal.Get(sz - 1), out, IsVec());
}
out<<"]\n";
out << "]\n";
}
}
} //namespace vtkm::cont
#include <vtkm/cont/ArrayHandle.hxx>
#include <vtkm/cont/internal/ArrayHandleBasicImpl.h>
#include <vtkm/cont/internal/ArrayExportMacros.h>
#ifndef vtkm_cont_ArrayHandle_cxx
#ifdef VTKM_MSVC
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<char, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::Int8, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::UInt8, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::Int16, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::UInt16, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::Int32, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::UInt32, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::Int64, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::UInt64, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::Float32, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle<vtkm::Float64, vtkm::cont::StorageTagBasic>::InternalStruct >;
#define _VTKM_SHARED_PTR_EXPORT(Type) \
extern template class VTKM_CONT_TEMPLATE_EXPORT \
std::shared_ptr<vtkm::cont::ArrayHandle<Type, vtkm::cont::StorageTagBasic>::InternalStruct>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< \
vtkm::cont::ArrayHandle<vtkm::Vec<Type, 2>, vtkm::cont::StorageTagBasic>::InternalStruct>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< \
vtkm::cont::ArrayHandle<vtkm::Vec<Type, 3>, vtkm::cont::StorageTagBasic>::InternalStruct>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< \
vtkm::cont::ArrayHandle<vtkm::Vec<Type, 4>, vtkm::cont::StorageTagBasic>::InternalStruct>;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Int64,2>, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Int32,2>, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32,2>, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float64,2>, vtkm::cont::StorageTagBasic>::InternalStruct >;
_VTKM_SHARED_PTR_EXPORT(char)
_VTKM_SHARED_PTR_EXPORT(vtkm::Int8)
_VTKM_SHARED_PTR_EXPORT(vtkm::UInt8)
_VTKM_SHARED_PTR_EXPORT(vtkm::Int16)
_VTKM_SHARED_PTR_EXPORT(vtkm::UInt16)
_VTKM_SHARED_PTR_EXPORT(vtkm::Int32)
_VTKM_SHARED_PTR_EXPORT(vtkm::UInt32)
_VTKM_SHARED_PTR_EXPORT(vtkm::Int64)
_VTKM_SHARED_PTR_EXPORT(vtkm::UInt64)
_VTKM_SHARED_PTR_EXPORT(vtkm::Float32)
_VTKM_SHARED_PTR_EXPORT(vtkm::Float64)
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Int64,3>, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Int32,3>, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32,3>, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float64,3>, vtkm::cont::StorageTagBasic>::InternalStruct >;
#undef _VTKM_SHARED_PTR_EXPORT
#endif // VTKM_MSVC
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<char,4>, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Int8,4>, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::UInt8,4>, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float32,4>, vtkm::cont::StorageTagBasic>::InternalStruct >;
extern template class VTKM_CONT_TEMPLATE_EXPORT std::shared_ptr< vtkm::cont::ArrayHandle< vtkm::Vec<vtkm::Float64,4>, vtkm::cont::StorageTagBasic>::InternalStruct >;
#endif
namespace vtkm
{
namespace cont
{
namespace vtkm {
namespace cont {
#define _VTKM_ARRAYHANDLE_EXPORT(Type) \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<Type, StorageTagBasic>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT \
ArrayHandle<vtkm::Vec<Type, 2>, StorageTagBasic>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT \
ArrayHandle<vtkm::Vec<Type, 3>, StorageTagBasic>; \
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Vec<Type, 4>, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<char, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Int8, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::UInt8, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Int16, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::UInt16, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Int32, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::UInt32, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Int64, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::UInt64, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Float32, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle<vtkm::Float64, StorageTagBasic>;
_VTKM_ARRAYHANDLE_EXPORT(char)
_VTKM_ARRAYHANDLE_EXPORT(vtkm::Int8)
_VTKM_ARRAYHANDLE_EXPORT(vtkm::UInt8)
_VTKM_ARRAYHANDLE_EXPORT(vtkm::Int16)
_VTKM_ARRAYHANDLE_EXPORT(vtkm::UInt16)
_VTKM_ARRAYHANDLE_EXPORT(vtkm::Int32)
_VTKM_ARRAYHANDLE_EXPORT(vtkm::UInt32)
_VTKM_ARRAYHANDLE_EXPORT(vtkm::Int64)
_VTKM_ARRAYHANDLE_EXPORT(vtkm::UInt64)
_VTKM_ARRAYHANDLE_EXPORT(vtkm::Float32)
_VTKM_ARRAYHANDLE_EXPORT(vtkm::Float64)
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle< vtkm::Vec<vtkm::Int64,2>, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle< vtkm::Vec<vtkm::Int32,2>, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle< vtkm::Vec<vtkm::Float32,2>, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle< vtkm::Vec<vtkm::Float64,2>, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle< vtkm::Vec<vtkm::Int64,3>, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle< vtkm::Vec<vtkm::Int32,3>, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle< vtkm::Vec<vtkm::Float32,3>, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle< vtkm::Vec<vtkm::Float64,3>, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle< vtkm::Vec<char,4>, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle< vtkm::Vec<vtkm::Int8,4>, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle< vtkm::Vec<vtkm::UInt8,4>, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle< vtkm::Vec<vtkm::Float32,4>, StorageTagBasic>;
extern template class VTKM_CONT_TEMPLATE_EXPORT ArrayHandle< vtkm::Vec<vtkm::Float64,4>, StorageTagBasic>;
#undef _VTKM_ARRAYHANDLE_EXPORT
}
}
#endif
} // end vtkm::cont
#include <vtkm/cont/ArrayHandle.hxx>
#endif // !vtkm_cont_ArrayHandle_cxx
#endif //vtk_m_cont_ArrayHandle_h

@ -18,29 +18,33 @@
// this software.
//============================================================================
namespace vtkm {
namespace cont {
namespace vtkm
{
namespace cont
{
template<typename T, typename S>
ArrayHandle<T,S>::ArrayHandle()
template <typename T, typename S>
ArrayHandle<T, S>::ArrayHandle()
: Internals(new InternalStruct)
{
this->Internals->ControlArrayValid = false;
this->Internals->ExecutionArrayValid = false;
}
template<typename T, typename S>
ArrayHandle<T,S>::ArrayHandle(const ArrayHandle<T,S> &src)
template <typename T, typename S>
ArrayHandle<T, S>::ArrayHandle(const ArrayHandle<T, S>& src)
: Internals(src.Internals)
{ }
{
}
template<typename T, typename S>
ArrayHandle<T,S>::ArrayHandle(ArrayHandle<T,S> &&src)
template <typename T, typename S>
ArrayHandle<T, S>::ArrayHandle(ArrayHandle<T, S>&& src)
: Internals(std::move(src.Internals))
{ }
{
}
template<typename T, typename S>
ArrayHandle<T,S>::ArrayHandle(const typename ArrayHandle<T,S>::StorageType &storage)
template <typename T, typename S>
ArrayHandle<T, S>::ArrayHandle(const typename ArrayHandle<T, S>::StorageType& storage)
: Internals(new InternalStruct)
{
this->Internals->ControlArray = storage;
@ -48,30 +52,27 @@ ArrayHandle<T,S>::ArrayHandle(const typename ArrayHandle<T,S>::StorageType &stor
this->Internals->ExecutionArrayValid = false;
}
template<typename T, typename S>
ArrayHandle<T,S>::~ArrayHandle()
template <typename T, typename S>
ArrayHandle<T, S>::~ArrayHandle()
{
}
template<typename T, typename S>
ArrayHandle<T,S>&
ArrayHandle<T,S>::operator=(const ArrayHandle<T,S> &src)
template <typename T, typename S>
ArrayHandle<T, S>& ArrayHandle<T, S>::operator=(const ArrayHandle<T, S>& src)
{
this->Internals = src.Internals;
return *this;
}
template<typename T, typename S>
ArrayHandle<T,S>&
ArrayHandle<T,S>::operator=(ArrayHandle<T,S> &&src)
template <typename T, typename S>
ArrayHandle<T, S>& ArrayHandle<T, S>::operator=(ArrayHandle<T, S>&& src)
{
this->Internals = std::move(src.Internals);
return *this;
}
template<typename T, typename S>
typename ArrayHandle<T,S>::StorageType&
ArrayHandle<T,S>::GetStorage()
template <typename T, typename S>
typename ArrayHandle<T, S>::StorageType& ArrayHandle<T, S>::GetStorage()
{
this->SyncControlArray();
if (this->Internals->ControlArrayValid)
@ -85,9 +86,8 @@ ArrayHandle<T,S>::GetStorage()
}
}
template<typename T, typename S>
const typename ArrayHandle<T,S>::StorageType&
ArrayHandle<T,S>::GetStorage() const
template <typename T, typename S>
const typename ArrayHandle<T, S>::StorageType& ArrayHandle<T, S>::GetStorage() const
{
this->SyncControlArray();
if (this->Internals->ControlArrayValid)
@ -101,9 +101,8 @@ ArrayHandle<T,S>::GetStorage() const
}
}
template<typename T, typename S>
typename ArrayHandle<T,S>::PortalControl
ArrayHandle<T,S>::GetPortalControl()
template <typename T, typename S>
typename ArrayHandle<T, S>::PortalControl ArrayHandle<T, S>::GetPortalControl()
{
this->SyncControlArray();
if (this->Internals->ControlArrayValid)
@ -117,13 +116,12 @@ ArrayHandle<T,S>::GetPortalControl()
else
{
throw vtkm::cont::ErrorInternal(
"ArrayHandle::SyncControlArray did not make control array valid.");
"ArrayHandle::SyncControlArray did not make control array valid.");
}
}
template<typename T, typename S>
typename ArrayHandle<T,S>::PortalConstControl
ArrayHandle<T,S>::GetPortalConstControl() const
template <typename T, typename S>
typename ArrayHandle<T, S>::PortalConstControl ArrayHandle<T, S>::GetPortalConstControl() const
{
this->SyncControlArray();
if (this->Internals->ControlArrayValid)
@ -133,12 +131,12 @@ ArrayHandle<T,S>::GetPortalConstControl() const
else
{
throw vtkm::cont::ErrorInternal(
"ArrayHandle::SyncControlArray did not make control array valid.");
"ArrayHandle::SyncControlArray did not make control array valid.");
}
}
template<typename T, typename S>
vtkm::Id ArrayHandle<T,S>::GetNumberOfValues() const
template <typename T, typename S>
vtkm::Id ArrayHandle<T, S>::GetNumberOfValues() const
{
if (this->Internals->ControlArrayValid)
{
@ -154,50 +152,47 @@ vtkm::Id ArrayHandle<T,S>::GetNumberOfValues() const
}
}
template<typename T, typename S>
template<typename IteratorType, typename DeviceAdapterTag>
void ArrayHandle<T,S>::CopyInto(IteratorType dest, DeviceAdapterTag) const
template <typename T, typename S>
template <typename IteratorType, typename DeviceAdapterTag>
void ArrayHandle<T, S>::CopyInto(IteratorType dest, DeviceAdapterTag) const
{
using pointer_type = typename std::iterator_traits<IteratorType>::pointer;
using value_type = typename std::remove_pointer<pointer_type>::type;
static_assert( !std::is_const<value_type>::value,
"CopyInto requires a non const iterator." );
static_assert(!std::is_const<value_type>::value, "CopyInto requires a non const iterator.");
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
if (!this->Internals->ControlArrayValid &&
!this->Internals->ExecutionArrayValid)
{
throw vtkm::cont::ErrorBadValue(
"ArrayHandle has no data to copy into Iterator.");
}
if (!this->Internals->ControlArrayValid && !this->Internals->ExecutionArrayValid)
{
throw vtkm::cont::ErrorBadValue("ArrayHandle has no data to copy into Iterator.");
}
if (!this->Internals->ControlArrayValid &&
this->Internals->ExecutionArray->IsDeviceAdapter(DeviceAdapterTag()))
{
/// Dynamically cast ArrayHandleExecutionManagerBase into a concrete
/// class and call CopyInto. The dynamic conversion will be sucessful
/// becuase the check to ensure the ExecutionArray is of the type
/// DeviceAdapterTag has already passed
typedef vtkm::cont::internal::ArrayHandleExecutionManager<
T, StorageTag, DeviceAdapterTag> ConcreteType;
ConcreteType *ConcreteExecutionArray =
dynamic_cast<ConcreteType*>(this->Internals->ExecutionArray.get());
{
/// Dynamically cast ArrayHandleExecutionManagerBase into a concrete
/// class and call CopyInto. The dynamic conversion will be sucessful
/// becuase the check to ensure the ExecutionArray is of the type
/// DeviceAdapterTag has already passed
typedef vtkm::cont::internal::ArrayHandleExecutionManager<T, StorageTag, DeviceAdapterTag>
ConcreteType;
ConcreteType* ConcreteExecutionArray =
dynamic_cast<ConcreteType*>(this->Internals->ExecutionArray.get());
ConcreteExecutionArray->CopyInto(dest);
}
ConcreteExecutionArray->CopyInto(dest);
}
else
{
{
PortalConstControl portal = this->GetPortalConstControl();
std::copy(vtkm::cont::ArrayPortalToIteratorBegin(portal),
vtkm::cont::ArrayPortalToIteratorEnd(portal),
dest);
}
}
}
template<typename T, typename S>
void ArrayHandle<T,S>::Shrink(vtkm::Id numberOfValues)
template <typename T, typename S>
void ArrayHandle<T, S>::Shrink(vtkm::Id numberOfValues)
{
VTKM_ASSERT(numberOfValues >= 0);
@ -222,8 +217,7 @@ void ArrayHandle<T,S>::Shrink(vtkm::Id numberOfValues)
}
else // numberOfValues > originalNumberOfValues
{
throw vtkm::cont::ErrorBadValue(
"ArrayHandle::Shrink cannot be used to grow array.");
throw vtkm::cont::ErrorBadValue("ArrayHandle::Shrink cannot be used to grow array.");
}
VTKM_ASSERT(this->GetNumberOfValues() == numberOfValues);
@ -237,15 +231,14 @@ void ArrayHandle<T,S>::Shrink(vtkm::Id numberOfValues)
}
}
template<typename T, typename S>
template<typename DeviceAdapterTag>
typename ArrayHandle<T,S>::template ExecutionTypes<DeviceAdapterTag>::PortalConst
ArrayHandle<T,S>::PrepareForInput(DeviceAdapterTag) const
template <typename T, typename S>
template <typename DeviceAdapterTag>
typename ArrayHandle<T, S>::template ExecutionTypes<DeviceAdapterTag>::PortalConst
ArrayHandle<T, S>::PrepareForInput(DeviceAdapterTag) const
{
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
if (!this->Internals->ControlArrayValid
&& !this->Internals->ExecutionArrayValid)
if (!this->Internals->ControlArrayValid && !this->Internals->ExecutionArrayValid)
{
// Want to use an empty array.
// Set up ArrayHandle state so this actually works.
@ -255,18 +248,18 @@ ArrayHandle<T,S>::PrepareForInput(DeviceAdapterTag) const
this->PrepareForDevice(DeviceAdapterTag());
typename ExecutionTypes<DeviceAdapterTag>::PortalConst portal =
this->Internals->ExecutionArray->PrepareForInput(
!this->Internals->ExecutionArrayValid, DeviceAdapterTag());
this->Internals->ExecutionArray->PrepareForInput(!this->Internals->ExecutionArrayValid,
DeviceAdapterTag());
this->Internals->ExecutionArrayValid = true;
return portal;
}
template<typename T, typename S>
template<typename DeviceAdapterTag>
typename ArrayHandle<T,S>::template ExecutionTypes<DeviceAdapterTag>::Portal
ArrayHandle<T,S>::PrepareForOutput(vtkm::Id numberOfValues, DeviceAdapterTag)
template <typename T, typename S>
template <typename DeviceAdapterTag>
typename ArrayHandle<T, S>::template ExecutionTypes<DeviceAdapterTag>::Portal
ArrayHandle<T, S>::PrepareForOutput(vtkm::Id numberOfValues, DeviceAdapterTag)
{
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
@ -277,8 +270,7 @@ ArrayHandle<T,S>::PrepareForOutput(vtkm::Id numberOfValues, DeviceAdapterTag)
this->PrepareForDevice(DeviceAdapterTag());
typename ExecutionTypes<DeviceAdapterTag>::Portal portal =
this->Internals->ExecutionArray->PrepareForOutput(numberOfValues,
DeviceAdapterTag());
this->Internals->ExecutionArray->PrepareForOutput(numberOfValues, DeviceAdapterTag());
// We are assuming that the calling code will fill the array using the
// iterators we are returning, so go ahead and mark the execution array as
@ -294,15 +286,14 @@ ArrayHandle<T,S>::PrepareForOutput(vtkm::Id numberOfValues, DeviceAdapterTag)
return portal;
}
template<typename T, typename S>
template<typename DeviceAdapterTag>
typename ArrayHandle<T,S>::template ExecutionTypes<DeviceAdapterTag>::Portal
ArrayHandle<T,S>::PrepareForInPlace(DeviceAdapterTag)
template <typename T, typename S>
template <typename DeviceAdapterTag>
typename ArrayHandle<T, S>::template ExecutionTypes<DeviceAdapterTag>::Portal
ArrayHandle<T, S>::PrepareForInPlace(DeviceAdapterTag)
{
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
if (!this->Internals->ControlArrayValid
&& !this->Internals->ExecutionArrayValid)
if (!this->Internals->ControlArrayValid && !this->Internals->ExecutionArrayValid)
{
// Want to use an empty array.
// Set up ArrayHandle state so this actually works.
@ -312,8 +303,8 @@ ArrayHandle<T,S>::PrepareForInPlace(DeviceAdapterTag)
this->PrepareForDevice(DeviceAdapterTag());
typename ExecutionTypes<DeviceAdapterTag>::Portal portal =
this->Internals->ExecutionArray->PrepareForInPlace(
!this->Internals->ExecutionArrayValid, DeviceAdapterTag());
this->Internals->ExecutionArray->PrepareForInPlace(!this->Internals->ExecutionArrayValid,
DeviceAdapterTag());
this->Internals->ExecutionArrayValid = true;
@ -325,9 +316,9 @@ ArrayHandle<T,S>::PrepareForInPlace(DeviceAdapterTag)
return portal;
}
template<typename T, typename S>
template<typename DeviceAdapterTag>
void ArrayHandle<T,S>::PrepareForDevice(DeviceAdapterTag) const
template <typename T, typename S>
template <typename DeviceAdapterTag>
void ArrayHandle<T, S>::PrepareForDevice(DeviceAdapterTag) const
{
if (this->Internals->ExecutionArray != nullptr)
{
@ -347,34 +338,30 @@ void ArrayHandle<T,S>::PrepareForDevice(DeviceAdapterTag) const
this->SyncControlArray();
// Need to change some state that does not change the logical state from
// an external point of view.
InternalStruct *internals
= const_cast<InternalStruct*>(this->Internals.get());
InternalStruct* internals = const_cast<InternalStruct*>(this->Internals.get());
internals->ExecutionArray.reset();
internals->ExecutionArrayValid = false;
}
}
}
VTKM_ASSERT(this->Internals->ExecutionArray == nullptr);
VTKM_ASSERT(!this->Internals->ExecutionArrayValid);
// Need to change some state that does not change the logical state from
// an external point of view.
InternalStruct *internals
= const_cast<InternalStruct*>(this->Internals.get());
InternalStruct* internals = const_cast<InternalStruct*>(this->Internals.get());
internals->ExecutionArray.reset(
new vtkm::cont::internal::ArrayHandleExecutionManager<
T, StorageTag, DeviceAdapterTag>(&internals->ControlArray));
new vtkm::cont::internal::ArrayHandleExecutionManager<T, StorageTag, DeviceAdapterTag>(
&internals->ControlArray));
}
template<typename T, typename S>
void ArrayHandle<T,S>::SyncControlArray() const
template <typename T, typename S>
void ArrayHandle<T, S>::SyncControlArray() const
{
if (!this->Internals->ControlArrayValid)
{
// Need to change some state that does not change the logical state from
// an external point of view.
InternalStruct *internals
= const_cast<InternalStruct*>(this->Internals.get());
InternalStruct* internals = const_cast<InternalStruct*>(this->Internals.get());
if (this->Internals->ExecutionArrayValid)
{
internals->ExecutionArray->RetrieveOutputData(&internals->ControlArray);
@ -390,7 +377,5 @@ void ArrayHandle<T,S>::SyncControlArray() const
}
}
}
}
}

@ -25,16 +25,19 @@
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/cont/ErrorBadAllocation.h>
namespace vtkm {
namespace exec {
namespace internal {
namespace vtkm
{
namespace exec
{
namespace internal
{
/// \brief An array portal that acts as a 3D cartesian product of 3 arrays.
///
template<typename ValueType_,
typename PortalTypeFirst_,
typename PortalTypeSecond_,
typename PortalTypeThird_>
template <typename ValueType_,
typename PortalTypeFirst_,
typename PortalTypeSecond_,
typename PortalTypeThird_>
class VTKM_ALWAYS_EXPORT ArrayPortalCartesianProduct
{
public:
@ -47,37 +50,42 @@ public:
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ArrayPortalCartesianProduct()
: PortalFirst(), PortalSecond(), PortalThird()
{ } //needs to be host and device so that cuda can create lvalue of these
: PortalFirst()
, PortalSecond()
, PortalThird()
{
} //needs to be host and device so that cuda can create lvalue of these
VTKM_CONT
ArrayPortalCartesianProduct(const PortalTypeFirst &portalfirst,
const PortalTypeSecond &portalsecond,
const PortalTypeThird &portalthird)
: PortalFirst(portalfirst), PortalSecond(portalsecond), PortalThird(portalthird)
{ }
ArrayPortalCartesianProduct(const PortalTypeFirst& portalfirst,
const PortalTypeSecond& portalsecond,
const PortalTypeThird& portalthird)
: PortalFirst(portalfirst)
, PortalSecond(portalsecond)
, PortalThird(portalthird)
{
}
/// Copy constructor for any other ArrayPortalCartesianProduct with an iterator
/// type that can be copied to this iterator type. This allows us to do any
/// type casting that the iterators do (like the non-const to const cast).
///
template<class OtherV, class OtherP1, class OtherP2, class OtherP3>
VTKM_CONT
ArrayPortalCartesianProduct(const ArrayPortalCartesianProduct<OtherV,OtherP1,OtherP2,OtherP3> &src)
: PortalFirst(src.GetPortalFirst()),
PortalSecond(src.GetPortalSecond()),
PortalThird(src.GetPortalThird())
{ }
template <class OtherV, class OtherP1, class OtherP2, class OtherP3>
VTKM_CONT ArrayPortalCartesianProduct(
const ArrayPortalCartesianProduct<OtherV, OtherP1, OtherP2, OtherP3>& src)
: PortalFirst(src.GetPortalFirst())
, PortalSecond(src.GetPortalSecond())
, PortalThird(src.GetPortalThird())
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
vtkm::Id GetNumberOfValues() const
{
return this->PortalFirst.GetNumberOfValues() *
this->PortalSecond.GetNumberOfValues() *
this->PortalThird.GetNumberOfValues();
return this->PortalFirst.GetNumberOfValues() * this->PortalSecond.GetNumberOfValues() *
this->PortalThird.GetNumberOfValues();
}
VTKM_SUPPRESS_EXEC_WARNINGS
@ -89,27 +97,26 @@ public:
vtkm::Id dim1 = this->PortalFirst.GetNumberOfValues();
vtkm::Id dim2 = this->PortalSecond.GetNumberOfValues();
vtkm::Id dim12 = dim1*dim2;
vtkm::Id dim12 = dim1 * dim2;
vtkm::Id idx12 = index % dim12;
vtkm::Id i1 = idx12 % dim1;
vtkm::Id i2 = idx12 / dim1;
vtkm::Id i3 = index / dim12;
return vtkm::make_Vec(this->PortalFirst.Get(i1),
this->PortalSecond.Get(i2),
this->PortalThird.Get(i3));
return vtkm::make_Vec(
this->PortalFirst.Get(i1), this->PortalSecond.Get(i2), this->PortalThird.Get(i3));
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
void Set(vtkm::Id index, const ValueType &value) const
void Set(vtkm::Id index, const ValueType& value) const
{
VTKM_ASSERT(index >= 0);
VTKM_ASSERT(index < this->GetNumberOfValues());
vtkm::Id dim1 = this->PortalFirst.GetNumberOfValues();
vtkm::Id dim2 = this->PortalSecond.GetNumberOfValues();
vtkm::Id dim12 = dim1*dim2;
vtkm::Id dim12 = dim1 * dim2;
vtkm::Id idx12 = index % dim12;
vtkm::Id i1 = idx12 % dim1;
@ -123,57 +130,59 @@ public:
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
const PortalTypeFirst &GetFirstPortal() const { return this->PortalFirst; }
const PortalTypeFirst& GetFirstPortal() const { return this->PortalFirst; }
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
const PortalTypeSecond &GetSecondPortal() const { return this->PortalSecond; }
const PortalTypeSecond& GetSecondPortal() const { return this->PortalSecond; }
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
const PortalTypeThird &GetThirdPortal() const { return this->PortalThird; }
const PortalTypeThird& GetThirdPortal() const { return this->PortalThird; }
private:
PortalTypeFirst PortalFirst;
PortalTypeSecond PortalSecond;
PortalTypeThird PortalThird;
};
}
}
} // namespace vtkm::exec::internal
namespace vtkm
{
namespace cont
{
namespace vtkm {
namespace cont {
namespace internal
{
namespace internal {
template<typename FirstHandleType, typename SecondHandleType, typename ThirdHandleType>
struct VTKM_ALWAYS_EXPORT StorageTagCartesianProduct { };
template <typename FirstHandleType, typename SecondHandleType, typename ThirdHandleType>
struct VTKM_ALWAYS_EXPORT StorageTagCartesianProduct
{
};
/// This helper struct defines the value type for a zip container containing
/// the given two array handles.
///
template<typename FirstHandleType, typename SecondHandleType, typename ThirdHandleType>
struct ArrayHandleCartesianProductTraits {
template <typename FirstHandleType, typename SecondHandleType, typename ThirdHandleType>
struct ArrayHandleCartesianProductTraits
{
/// The ValueType (a pair containing the value types of the two arrays).
///
typedef vtkm::Vec<typename FirstHandleType::ValueType,3> ValueType;
typedef vtkm::Vec<typename FirstHandleType::ValueType, 3> ValueType;
/// The appropriately templated tag.
///
typedef StorageTagCartesianProduct<FirstHandleType,SecondHandleType,ThirdHandleType> Tag;
typedef StorageTagCartesianProduct<FirstHandleType, SecondHandleType, ThirdHandleType> Tag;
/// The superclass for ArrayHandleCartesianProduct.
///
typedef vtkm::cont::ArrayHandle<ValueType,Tag> Superclass;
typedef vtkm::cont::ArrayHandle<ValueType, Tag> Superclass;
};
template<typename T, typename FirstHandleType, typename SecondHandleType, typename ThirdHandleType>
class Storage<T, StorageTagCartesianProduct<FirstHandleType, SecondHandleType, ThirdHandleType > >
template <typename T, typename FirstHandleType, typename SecondHandleType, typename ThirdHandleType>
class Storage<T, StorageTagCartesianProduct<FirstHandleType, SecondHandleType, ThirdHandleType>>
{
VTKM_IS_ARRAY_HANDLE(FirstHandleType);
VTKM_IS_ARRAY_HANDLE(SecondHandleType);
@ -182,60 +191,70 @@ class Storage<T, StorageTagCartesianProduct<FirstHandleType, SecondHandleType, T
public:
typedef T ValueType;
typedef vtkm::exec::internal::ArrayPortalCartesianProduct< ValueType,
typename FirstHandleType::PortalControl,
typename SecondHandleType::PortalControl,
typename ThirdHandleType::PortalControl> PortalType;
typedef vtkm::exec::internal::ArrayPortalCartesianProduct< ValueType,
typename FirstHandleType::PortalConstControl,
typename SecondHandleType::PortalConstControl,
typename ThirdHandleType::PortalConstControl>
PortalConstType;
typedef vtkm::exec::internal::ArrayPortalCartesianProduct<
ValueType,
typename FirstHandleType::PortalControl,
typename SecondHandleType::PortalControl,
typename ThirdHandleType::PortalControl>
PortalType;
typedef vtkm::exec::internal::ArrayPortalCartesianProduct<
ValueType,
typename FirstHandleType::PortalConstControl,
typename SecondHandleType::PortalConstControl,
typename ThirdHandleType::PortalConstControl>
PortalConstType;
VTKM_CONT
Storage() : FirstArray(), SecondArray(), ThirdArray() { }
VTKM_CONT
Storage(const FirstHandleType &array1, const SecondHandleType &array2, const ThirdHandleType &array3)
: FirstArray(array1), SecondArray(array2), ThirdArray(array3)
Storage()
: FirstArray()
, SecondArray()
, ThirdArray()
{
}
VTKM_CONT
Storage(const FirstHandleType& array1,
const SecondHandleType& array2,
const ThirdHandleType& array3)
: FirstArray(array1)
, SecondArray(array2)
, ThirdArray(array3)
{
}
VTKM_CONT
PortalType GetPortal()
{
return PortalType(this->FirstArray.GetPortalControl(),
this->SecondArray.GetPortalControl(),
this->ThirdArray.GetPortalControl());
return PortalType(this->FirstArray.GetPortalControl(),
this->SecondArray.GetPortalControl(),
this->ThirdArray.GetPortalControl());
}
VTKM_CONT
PortalConstType GetPortalConst() const
{
return PortalConstType(this->FirstArray.GetPortalConstControl(),
this->SecondArray.GetPortalConstControl(),
this->ThirdArray.GetPortalConstControl());
return PortalConstType(this->FirstArray.GetPortalConstControl(),
this->SecondArray.GetPortalConstControl(),
this->ThirdArray.GetPortalConstControl());
}
VTKM_CONT
vtkm::Id GetNumberOfValues() const
{
return this->FirstArray.GetNumberOfValues() *
this->SecondArray.GetNumberOfValues() *
this->ThirdArray.GetNumberOfValues();
return this->FirstArray.GetNumberOfValues() * this->SecondArray.GetNumberOfValues() *
this->ThirdArray.GetNumberOfValues();
}
VTKM_CONT
void Allocate(vtkm::Id /*numberOfValues*/)
{
throw vtkm::cont::ErrorBadAllocation("Does not make sense.");
throw vtkm::cont::ErrorBadAllocation("Does not make sense.");
}
VTKM_CONT
void Shrink(vtkm::Id /*numberOfValues*/)
{
throw vtkm::cont::ErrorBadAllocation("Does not make sense.");
throw vtkm::cont::ErrorBadAllocation("Does not make sense.");
}
VTKM_CONT
@ -246,22 +265,13 @@ public:
}
VTKM_CONT
const FirstHandleType &GetFirstArray() const
{
return this->FirstArray;
}
const FirstHandleType& GetFirstArray() const { return this->FirstArray; }
VTKM_CONT
const SecondHandleType &GetSecondArray() const
{
return this->SecondArray;
}
const SecondHandleType& GetSecondArray() const { return this->SecondArray; }
VTKM_CONT
const ThirdHandleType &GetThirdArray() const
{
return this->ThirdArray;
}
const ThirdHandleType& GetThirdArray() const { return this->ThirdArray; }
private:
FirstHandleType FirstArray;
@ -269,15 +279,16 @@ private:
ThirdHandleType ThirdArray;
};
template<typename T,
typename FirstHandleType,
typename SecondHandleType,
typename ThirdHandleType,
typename Device>
class ArrayTransfer<
T, StorageTagCartesianProduct<FirstHandleType,SecondHandleType,ThirdHandleType>, Device>
template <typename T,
typename FirstHandleType,
typename SecondHandleType,
typename ThirdHandleType,
typename Device>
class ArrayTransfer<T,
StorageTagCartesianProduct<FirstHandleType, SecondHandleType, ThirdHandleType>,
Device>
{
typedef StorageTagCartesianProduct<FirstHandleType,SecondHandleType,ThirdHandleType> StorageTag;
typedef StorageTagCartesianProduct<FirstHandleType, SecondHandleType, ThirdHandleType> StorageTag;
typedef vtkm::cont::internal::Storage<T, StorageTag> StorageType;
public:
@ -287,38 +298,37 @@ public:
typedef typename StorageType::PortalConstType PortalConstControl;
typedef vtkm::exec::internal::ArrayPortalCartesianProduct<
ValueType,
typename FirstHandleType::template ExecutionTypes<Device>::Portal,
typename SecondHandleType::template ExecutionTypes<Device>::Portal,
typename ThirdHandleType::template ExecutionTypes<Device>::Portal
> PortalExecution;
ValueType,
typename FirstHandleType::template ExecutionTypes<Device>::Portal,
typename SecondHandleType::template ExecutionTypes<Device>::Portal,
typename ThirdHandleType::template ExecutionTypes<Device>::Portal>
PortalExecution;
typedef vtkm::exec::internal::ArrayPortalCartesianProduct<
ValueType,
typename FirstHandleType::template ExecutionTypes<Device>::PortalConst,
typename SecondHandleType::template ExecutionTypes<Device>::PortalConst,
typename ThirdHandleType::template ExecutionTypes<Device>::PortalConst
> PortalConstExecution;
ValueType,
typename FirstHandleType::template ExecutionTypes<Device>::PortalConst,
typename SecondHandleType::template ExecutionTypes<Device>::PortalConst,
typename ThirdHandleType::template ExecutionTypes<Device>::PortalConst>
PortalConstExecution;
VTKM_CONT
ArrayTransfer(StorageType *storage)
: FirstArray(storage->GetFirstArray()),
SecondArray(storage->GetSecondArray()),
ThirdArray(storage->GetThirdArray())
{ }
ArrayTransfer(StorageType* storage)
: FirstArray(storage->GetFirstArray())
, SecondArray(storage->GetSecondArray())
, ThirdArray(storage->GetThirdArray())
{
}
VTKM_CONT
vtkm::Id GetNumberOfValues() const
{
return this->FirstArray.GetNumberOfValues() *
this->SecondArray.GetNumberOfValues() *
this->ThirdArray.GetNumberOfValues();
return this->FirstArray.GetNumberOfValues() * this->SecondArray.GetNumberOfValues() *
this->ThirdArray.GetNumberOfValues();
}
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData)) {
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
{
return PortalConstExecution(this->FirstArray.PrepareForInput(Device()),
this->SecondArray.PrepareForInput(Device()),
this->ThirdArray.PrepareForInput(Device()));
@ -328,20 +338,20 @@ public:
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
{
throw vtkm::cont::ErrorBadAllocation(
"Cannot write to an ArrayHandleCartesianProduct. It does not make "
"sense because there is overlap in the data.");
"Cannot write to an ArrayHandleCartesianProduct. It does not make "
"sense because there is overlap in the data.");
}
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorBadAllocation(
"Cannot write to an ArrayHandleCartesianProduct. It does not make "
"sense because there is overlap in the data.");
"Cannot write to an ArrayHandleCartesianProduct. It does not make "
"sense because there is overlap in the data.");
}
VTKM_CONT
void RetrieveOutputData(StorageType *vtkmNotUsed(storage)) const
void RetrieveOutputData(StorageType* vtkmNotUsed(storage)) const
{
// Implementation of this method should be unnecessary. The internal
// first and second array handles should automatically retrieve the
@ -351,7 +361,7 @@ public:
VTKM_CONT
void Shrink(vtkm::Id /*numberOfValues*/)
{
throw vtkm::cont::ErrorBadAllocation("Does not make sense.");
throw vtkm::cont::ErrorBadAllocation("Does not make sense.");
}
VTKM_CONT
@ -362,7 +372,6 @@ public:
this->ThirdArray.ReleaseResourcesExecution();
}
private:
FirstHandleType FirstArray;
SecondHandleType SecondArray;
@ -374,11 +383,11 @@ private:
/// array handle and makes a new handle that access the corresponding entries
/// in these arrays as a pair.
///
template<typename FirstHandleType,
typename SecondHandleType,
typename ThirdHandleType>
template <typename FirstHandleType, typename SecondHandleType, typename ThirdHandleType>
class ArrayHandleCartesianProduct
: public internal::ArrayHandleCartesianProductTraits<FirstHandleType,SecondHandleType,ThirdHandleType>::Superclass
: public internal::ArrayHandleCartesianProductTraits<FirstHandleType,
SecondHandleType,
ThirdHandleType>::Superclass
{
// If the following line gives a compile error, then the FirstHandleType
// template argument is not a valid ArrayHandle type.
@ -388,37 +397,38 @@ class ArrayHandleCartesianProduct
public:
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleCartesianProduct,
(ArrayHandleCartesianProduct<FirstHandleType,SecondHandleType,ThirdHandleType>),
(typename internal::ArrayHandleCartesianProductTraits<
FirstHandleType,SecondHandleType,ThirdHandleType>::Superclass));
ArrayHandleCartesianProduct,
(ArrayHandleCartesianProduct<FirstHandleType, SecondHandleType, ThirdHandleType>),
(typename internal::ArrayHandleCartesianProductTraits<FirstHandleType,
SecondHandleType,
ThirdHandleType>::Superclass));
private:
typedef vtkm::cont::internal::Storage<ValueType, StorageTag> StorageType;
public:
VTKM_CONT
ArrayHandleCartesianProduct(const FirstHandleType &firstArray,
const SecondHandleType &secondArray,
const ThirdHandleType &thirdArray)
: Superclass(StorageType(firstArray, secondArray, thirdArray)) { }
ArrayHandleCartesianProduct(const FirstHandleType& firstArray,
const SecondHandleType& secondArray,
const ThirdHandleType& thirdArray)
: Superclass(StorageType(firstArray, secondArray, thirdArray))
{
}
};
/// A convenience function for creating an ArrayHandleCartesianProduct. It takes the two
/// arrays to be zipped together.
///
template<typename FirstHandleType, typename SecondHandleType, typename ThirdHandleType>
template <typename FirstHandleType, typename SecondHandleType, typename ThirdHandleType>
VTKM_CONT
vtkm::cont::ArrayHandleCartesianProduct<FirstHandleType,SecondHandleType,ThirdHandleType>
make_ArrayHandleCartesianProduct(const FirstHandleType &first,
const SecondHandleType &second,
const ThirdHandleType &third)
vtkm::cont::ArrayHandleCartesianProduct<FirstHandleType, SecondHandleType, ThirdHandleType>
make_ArrayHandleCartesianProduct(const FirstHandleType& first,
const SecondHandleType& second,
const ThirdHandleType& third)
{
return ArrayHandleCartesianProduct<FirstHandleType,
SecondHandleType,
ThirdHandleType>(first, second,third);
return ArrayHandleCartesianProduct<FirstHandleType, SecondHandleType, ThirdHandleType>(
first, second, third);
}
}
} // namespace vtkm::cont

@ -24,24 +24,23 @@
#include <vtkm/cont/ArrayHandleTransform.h>
namespace vtkm {
namespace cont {
namespace vtkm
{
namespace cont
{
namespace internal {
namespace internal
{
template<typename FromType, typename ToType>
template <typename FromType, typename ToType>
struct VTKM_ALWAYS_EXPORT Cast
{
VTKM_EXEC_CONT
ToType operator()(const FromType &val) const
{
return static_cast<ToType>(val);
}
ToType operator()(const FromType& val) const { return static_cast<ToType>(val); }
};
} // namespace internal
/// \brief Cast the values of an array to the specified type, on demand.
///
/// ArrayHandleCast is a specialization of ArrayHandleTransform. Given an ArrayHandle
@ -49,39 +48,34 @@ struct VTKM_ALWAYS_EXPORT Cast
/// to the specified type.
///
template <typename T, typename ArrayHandleType>
class ArrayHandleCast :
public vtkm::cont::ArrayHandleTransform<
T,
ArrayHandleType,
internal::Cast<typename ArrayHandleType::ValueType, T>,
internal::Cast<T, typename ArrayHandleType::ValueType> >
class ArrayHandleCast
: public vtkm::cont::ArrayHandleTransform<ArrayHandleType,
internal::Cast<typename ArrayHandleType::ValueType, T>,
internal::Cast<T, typename ArrayHandleType::ValueType>>
{
public:
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleCast,
(ArrayHandleCast<T, ArrayHandleType>),
(vtkm::cont::ArrayHandleTransform<
T,
ArrayHandleType,
internal::Cast<typename ArrayHandleType::ValueType, T>,
internal::Cast<T, typename ArrayHandleType::ValueType> >));
(vtkm::cont::ArrayHandleTransform<ArrayHandleType,
internal::Cast<typename ArrayHandleType::ValueType, T>,
internal::Cast<T, typename ArrayHandleType::ValueType>>));
ArrayHandleCast(const ArrayHandleType &handle)
ArrayHandleCast(const ArrayHandleType& handle)
: Superclass(handle)
{ }
{
}
};
/// make_ArrayHandleCast is convenience function to generate an
/// ArrayHandleCast.
///
template <typename T, typename HandleType>
VTKM_CONT
ArrayHandleCast<T, HandleType> make_ArrayHandleCast(const HandleType &handle,
const T& = T())
VTKM_CONT ArrayHandleCast<T, HandleType> make_ArrayHandleCast(const HandleType& handle,
const T& = T())
{
return ArrayHandleCast<T, HandleType>(handle);
}
}
} // namespace vtkm::cont

@ -31,133 +31,140 @@
#include <sstream>
namespace vtkm {
namespace cont {
namespace vtkm
{
namespace cont
{
namespace internal {
namespace internal
{
namespace detail {
namespace detail
{
template<typename ValueType>
template <typename ValueType>
struct VTKM_ALWAYS_EXPORT CompositeVectorSwizzleFunctor
{
static const vtkm::IdComponent NUM_COMPONENTS =
vtkm::VecTraits<ValueType>::NUM_COMPONENTS;
static const vtkm::IdComponent NUM_COMPONENTS = vtkm::VecTraits<ValueType>::NUM_COMPONENTS;
typedef vtkm::Vec<vtkm::IdComponent, NUM_COMPONENTS> ComponentMapType;
// Caution! This is a reference.
const ComponentMapType &SourceComponents;
const ComponentMapType& SourceComponents;
VTKM_EXEC_CONT
CompositeVectorSwizzleFunctor(const ComponentMapType &sourceComponents)
: SourceComponents(sourceComponents) { }
CompositeVectorSwizzleFunctor(const ComponentMapType& sourceComponents)
: SourceComponents(sourceComponents)
{
}
// Currently only supporting 1-4 components.
template<typename T1>
VTKM_EXEC_CONT
ValueType operator()(const T1 &p1) const {
return ValueType(
vtkm::VecTraits<T1>::GetComponent(p1, this->SourceComponents[0]));
template <typename T1>
VTKM_EXEC_CONT ValueType operator()(const T1& p1) const
{
return ValueType(vtkm::VecTraits<T1>::GetComponent(p1, this->SourceComponents[0]));
}
template<typename T1, typename T2>
VTKM_EXEC_CONT
ValueType operator()(const T1 &p1, const T2 &p2) const {
return ValueType(
vtkm::VecTraits<T1>::GetComponent(p1, this->SourceComponents[0]),
vtkm::VecTraits<T2>::GetComponent(p2, this->SourceComponents[1]));
template <typename T1, typename T2>
VTKM_EXEC_CONT ValueType operator()(const T1& p1, const T2& p2) const
{
return ValueType(vtkm::VecTraits<T1>::GetComponent(p1, this->SourceComponents[0]),
vtkm::VecTraits<T2>::GetComponent(p2, this->SourceComponents[1]));
}
template<typename T1, typename T2, typename T3>
VTKM_EXEC_CONT
ValueType operator()(const T1 &p1, const T2 &p2, const T3 &p3) const {
return ValueType(
vtkm::VecTraits<T1>::GetComponent(p1, this->SourceComponents[0]),
vtkm::VecTraits<T2>::GetComponent(p2, this->SourceComponents[1]),
vtkm::VecTraits<T3>::GetComponent(p3, this->SourceComponents[2]));
template <typename T1, typename T2, typename T3>
VTKM_EXEC_CONT ValueType operator()(const T1& p1, const T2& p2, const T3& p3) const
{
return ValueType(vtkm::VecTraits<T1>::GetComponent(p1, this->SourceComponents[0]),
vtkm::VecTraits<T2>::GetComponent(p2, this->SourceComponents[1]),
vtkm::VecTraits<T3>::GetComponent(p3, this->SourceComponents[2]));
}
template<typename T1, typename T2, typename T3, typename T4>
VTKM_EXEC_CONT
ValueType operator()(const T1 &p1,
const T2 &p2,
const T3 &p3,
const T4 &p4) const {
return ValueType(
vtkm::VecTraits<T1>::GetComponent(p1, this->SourceComponents[0]),
vtkm::VecTraits<T2>::GetComponent(p2, this->SourceComponents[1]),
vtkm::VecTraits<T3>::GetComponent(p3, this->SourceComponents[2]),
vtkm::VecTraits<T4>::GetComponent(p4, this->SourceComponents[3]));
template <typename T1, typename T2, typename T3, typename T4>
VTKM_EXEC_CONT ValueType operator()(const T1& p1, const T2& p2, const T3& p3, const T4& p4) const
{
return ValueType(vtkm::VecTraits<T1>::GetComponent(p1, this->SourceComponents[0]),
vtkm::VecTraits<T2>::GetComponent(p2, this->SourceComponents[1]),
vtkm::VecTraits<T3>::GetComponent(p3, this->SourceComponents[2]),
vtkm::VecTraits<T4>::GetComponent(p4, this->SourceComponents[3]));
}
};
template<typename ReturnValueType>
template <typename ReturnValueType>
struct VTKM_ALWAYS_EXPORT CompositeVectorPullValueFunctor
{
vtkm::Id Index;
VTKM_EXEC
CompositeVectorPullValueFunctor(vtkm::Id index) : Index(index) { }
CompositeVectorPullValueFunctor(vtkm::Id index)
: Index(index)
{
}
// This form is to pull values out of array arguments.
VTKM_SUPPRESS_EXEC_WARNINGS
template<typename PortalType>
VTKM_EXEC_CONT
typename PortalType::ValueType operator()(const PortalType &portal) const {
template <typename PortalType>
VTKM_EXEC_CONT typename PortalType::ValueType operator()(const PortalType& portal) const
{
return portal.Get(this->Index);
}
// This form is an identity to pass the return value back.
VTKM_EXEC_CONT
const ReturnValueType &operator()(const ReturnValueType &value) const {
return value;
}
const ReturnValueType& operator()(const ReturnValueType& value) const { return value; }
};
struct CompositeVectorArrayToPortalCont {
template<typename ArrayHandleType, vtkm::IdComponent Index>
struct ReturnType {
struct CompositeVectorArrayToPortalCont
{
template <typename ArrayHandleType, vtkm::IdComponent Index>
struct ReturnType
{
typedef typename ArrayHandleType::PortalConstControl type;
};
template<typename ArrayHandleType, vtkm::IdComponent Index>
VTKM_CONT
typename ReturnType<ArrayHandleType, Index>::type
operator()(const ArrayHandleType &array,
vtkm::internal::IndexTag<Index>) const {
template <typename ArrayHandleType, vtkm::IdComponent Index>
VTKM_CONT typename ReturnType<ArrayHandleType, Index>::type operator()(
const ArrayHandleType& array,
vtkm::internal::IndexTag<Index>) const
{
return array.GetPortalConstControl();
}
};
template<typename DeviceAdapterTag>
struct CompositeVectorArrayToPortalExec {
template<typename ArrayHandleType, vtkm::IdComponent Index>
struct ReturnType {
typedef typename ArrayHandleType::template ExecutionTypes<
DeviceAdapterTag>::PortalConst type;
template <typename DeviceAdapterTag>
struct CompositeVectorArrayToPortalExec
{
template <typename ArrayHandleType, vtkm::IdComponent Index>
struct ReturnType
{
typedef typename ArrayHandleType::template ExecutionTypes<DeviceAdapterTag>::PortalConst type;
};
template<typename ArrayHandleType, vtkm::IdComponent Index>
VTKM_CONT
typename ReturnType<ArrayHandleType, Index>::type
operator()(const ArrayHandleType &array,
vtkm::internal::IndexTag<Index>) const {
template <typename ArrayHandleType, vtkm::IdComponent Index>
VTKM_CONT typename ReturnType<ArrayHandleType, Index>::type operator()(
const ArrayHandleType& array,
vtkm::internal::IndexTag<Index>) const
{
return array.PrepareForInput(DeviceAdapterTag());
}
};
struct CheckArraySizeFunctor {
struct CheckArraySizeFunctor
{
vtkm::Id ExpectedSize;
CheckArraySizeFunctor(vtkm::Id expectedSize) : ExpectedSize(expectedSize) { }
CheckArraySizeFunctor(vtkm::Id expectedSize)
: ExpectedSize(expectedSize)
{
}
template<typename T, vtkm::IdComponent Index>
void operator()(const T &a, vtkm::internal::IndexTag<Index>) const {
template <typename T, vtkm::IdComponent Index>
void operator()(const T& a, vtkm::internal::IndexTag<Index>) const
{
if (a.GetNumberOfValues() != this->ExpectedSize)
{
std::stringstream message;
message << "All input arrays to ArrayHandleCompositeVector must be the same size.\n"
<< "Array " << Index-1 << " has " << a.GetNumberOfValues()
<< ". Expected " << this->ExpectedSize << ".";
<< "Array " << Index - 1 << " has " << a.GetNumberOfValues() << ". Expected "
<< this->ExpectedSize << ".";
throw vtkm::cont::ErrorBadValue(message.str().c_str());
}
}
@ -169,15 +176,14 @@ struct CheckArraySizeFunctor {
///
/// This is the portal used within ArrayHandleCompositeVector.
///
template<typename SignatureWithPortals>
template <typename SignatureWithPortals>
class VTKM_ALWAYS_EXPORT ArrayPortalCompositeVector
{
typedef vtkm::internal::FunctionInterface<SignatureWithPortals> PortalTypes;
public:
typedef typename PortalTypes::ResultType ValueType;
static const vtkm::IdComponent NUM_COMPONENTS =
vtkm::VecTraits<ValueType>::NUM_COMPONENTS;
static const vtkm::IdComponent NUM_COMPONENTS = vtkm::VecTraits<ValueType>::NUM_COMPONENTS;
// Used internally.
typedef vtkm::Vec<vtkm::IdComponent, NUM_COMPONENTS> ComponentMapType;
@ -186,61 +192,64 @@ public:
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ArrayPortalCompositeVector() { }
ArrayPortalCompositeVector() {}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_CONT
ArrayPortalCompositeVector(
const PortalTypes portals,
vtkm::Vec<vtkm::IdComponent, NUM_COMPONENTS> sourceComponents)
: Portals(portals), SourceComponents(sourceComponents) { }
ArrayPortalCompositeVector(const PortalTypes portals,
vtkm::Vec<vtkm::IdComponent, NUM_COMPONENTS> sourceComponents)
: Portals(portals)
, SourceComponents(sourceComponents)
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
vtkm::Id GetNumberOfValues() const {
vtkm::Id GetNumberOfValues() const
{
return this->Portals.template GetParameter<1>().GetNumberOfValues();
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ValueType Get(vtkm::Id index) const {
ValueType Get(vtkm::Id index) const
{
// This might be inefficient because we are copying all the portals only
// because they are coupled with the return value.
PortalTypes localPortals = this->Portals;
localPortals.InvokeExec(
detail::CompositeVectorSwizzleFunctor<ValueType>(this->SourceComponents),
detail::CompositeVectorPullValueFunctor<ValueType>(index));
detail::CompositeVectorSwizzleFunctor<ValueType>(this->SourceComponents),
detail::CompositeVectorPullValueFunctor<ValueType>(index));
return localPortals.GetReturnValue();
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
void Set(vtkm::Id vtkmNotUsed(index),
const ValueType &vtkmNotUsed(value)) const
void Set(vtkm::Id vtkmNotUsed(index), const ValueType& vtkmNotUsed(value)) const
{
// There is no technical reason why this cannot be implemented. As of this
// writing no one has needed to write to a composite vector yet.
VTKM_ASSERT(false && "Set not yet implemented for composite vector. Do you volunteer to implement it?");
VTKM_ASSERT(false &&
"Set not yet implemented for composite vector. Do you volunteer to implement it?");
}
private:
PortalTypes Portals;
ComponentMapType SourceComponents;
};
template<typename SignatureWithArrays>
struct VTKM_ALWAYS_EXPORT StorageTagCompositeVector { };
template <typename SignatureWithArrays>
struct VTKM_ALWAYS_EXPORT StorageTagCompositeVector
{
};
/// A convenience class that provides a typedef to the appropriate tag for
/// a composite storage.
template<typename SignatureWithArrays>
template <typename SignatureWithArrays>
struct ArrayHandleCompositeVectorTraits
{
typedef vtkm::cont::internal::StorageTagCompositeVector<SignatureWithArrays>
Tag;
typedef typename vtkm::internal::FunctionInterface<SignatureWithArrays>::ResultType
ValueType;
typedef vtkm::cont::internal::StorageTagCompositeVector<SignatureWithArrays> Tag;
typedef typename vtkm::internal::FunctionInterface<SignatureWithArrays>::ResultType ValueType;
typedef vtkm::cont::internal::Storage<ValueType, Tag> StorageType;
typedef vtkm::cont::ArrayHandle<ValueType, Tag> Superclass;
};
@ -248,19 +257,16 @@ struct ArrayHandleCompositeVectorTraits
// It may seem weird that this specialization throws an exception for
// everything, but that is because all the functionality is handled in the
// ArrayTransfer class.
template<typename SignatureWithArrays>
class Storage<
typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ValueType,
vtkm::cont::internal::StorageTagCompositeVector<SignatureWithArrays> >
template <typename SignatureWithArrays>
class Storage<typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ValueType,
vtkm::cont::internal::StorageTagCompositeVector<SignatureWithArrays>>
{
typedef vtkm::internal::FunctionInterface<SignatureWithArrays>
FunctionInterfaceWithArrays;
typedef vtkm::internal::FunctionInterface<SignatureWithArrays> FunctionInterfaceWithArrays;
static const vtkm::IdComponent NUM_COMPONENTS = FunctionInterfaceWithArrays::ARITY;
typedef vtkm::Vec<vtkm::IdComponent, NUM_COMPONENTS> ComponentMapType;
typedef typename FunctionInterfaceWithArrays::template StaticTransformType<
detail::CompositeVectorArrayToPortalCont>::type
FunctionInterfaceWithPortals;
detail::CompositeVectorArrayToPortalCont>::type FunctionInterfaceWithPortals;
typedef typename FunctionInterfaceWithPortals::Signature SignatureWithPortals;
public:
@ -269,64 +275,71 @@ public:
typedef typename PortalType::ValueType ValueType;
VTKM_CONT
Storage() : Valid(false) { }
VTKM_CONT
Storage(const FunctionInterfaceWithArrays &arrays,
const ComponentMapType &sourceComponents)
: Arrays(arrays), SourceComponents(sourceComponents), Valid(true)
Storage()
: Valid(false)
{
arrays.ForEachCont(
detail::CheckArraySizeFunctor(this->GetNumberOfValues()));
}
VTKM_CONT
PortalType GetPortal() {
throw vtkm::cont::ErrorBadValue(
"Composite vector arrays are read only.");
Storage(const FunctionInterfaceWithArrays& arrays, const ComponentMapType& sourceComponents)
: Arrays(arrays)
, SourceComponents(sourceComponents)
, Valid(true)
{
arrays.ForEachCont(detail::CheckArraySizeFunctor(this->GetNumberOfValues()));
}
VTKM_CONT
PortalConstType GetPortalConst() const {
PortalType GetPortal()
{
throw vtkm::cont::ErrorBadValue("Composite vector arrays are read only.");
}
VTKM_CONT
PortalConstType GetPortalConst() const
{
if (!this->Valid)
{
throw vtkm::cont::ErrorBadValue(
"Tried to use an ArrayHandleCompositeHandle without dependent arrays.");
"Tried to use an ArrayHandleCompositeHandle without dependent arrays.");
}
return PortalConstType(this->Arrays.StaticTransformCont(
detail::CompositeVectorArrayToPortalCont()),
this->SourceComponents);
return PortalConstType(
this->Arrays.StaticTransformCont(detail::CompositeVectorArrayToPortalCont()),
this->SourceComponents);
}
VTKM_CONT
vtkm::Id GetNumberOfValues() const {
vtkm::Id GetNumberOfValues() const
{
if (!this->Valid)
{
throw vtkm::cont::ErrorBadValue(
"Tried to use an ArrayHandleCompositeHandle without dependent arrays.");
"Tried to use an ArrayHandleCompositeHandle without dependent arrays.");
}
return this->Arrays.template GetParameter<1>().GetNumberOfValues();
}
VTKM_CONT
void Allocate(vtkm::Id vtkmNotUsed(numberOfValues)) {
void Allocate(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorInternal(
"The allocate method for the composite vector storage should never "
"have been called. The allocate is generally only called by the "
"execution array manager, and the array transfer for the composite "
"storage should prevent the execution array manager from being "
"directly used.");
"The allocate method for the composite vector storage should never "
"have been called. The allocate is generally only called by the "
"execution array manager, and the array transfer for the composite "
"storage should prevent the execution array manager from being "
"directly used.");
}
VTKM_CONT
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues)) {
throw vtkm::cont::ErrorBadValue(
"Composite vector arrays are read-only.");
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorBadValue("Composite vector arrays are read-only.");
}
VTKM_CONT
void ReleaseResources() {
void ReleaseResources()
{
if (this->Valid)
{
// TODO: Implement this.
@ -334,13 +347,15 @@ public:
}
VTKM_CONT
const FunctionInterfaceWithArrays &GetArrays() const {
const FunctionInterfaceWithArrays& GetArrays() const
{
VTKM_ASSERT(this->Valid);
return this->Arrays;
}
VTKM_CONT
const ComponentMapType &GetSourceComponents() const {
const ComponentMapType& GetSourceComponents() const
{
VTKM_ASSERT(this->Valid);
return this->SourceComponents;
}
@ -351,27 +366,22 @@ private:
bool Valid;
};
template<typename SignatureWithArrays, typename DeviceAdapterTag>
class ArrayTransfer<
typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ValueType,
vtkm::cont::internal::StorageTagCompositeVector<SignatureWithArrays>,
DeviceAdapterTag>
template <typename SignatureWithArrays, typename DeviceAdapterTag>
class ArrayTransfer<typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ValueType,
vtkm::cont::internal::StorageTagCompositeVector<SignatureWithArrays>,
DeviceAdapterTag>
{
VTKM_IS_DEVICE_ADAPTER_TAG(DeviceAdapterTag);
typedef typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::StorageType
StorageType;
typedef typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::StorageType StorageType;
typedef vtkm::internal::FunctionInterface<SignatureWithArrays>
FunctionWithArrays;
typedef vtkm::internal::FunctionInterface<SignatureWithArrays> FunctionWithArrays;
typedef typename FunctionWithArrays::template StaticTransformType<
detail::CompositeVectorArrayToPortalExec<DeviceAdapterTag> >::type
FunctionWithPortals;
detail::CompositeVectorArrayToPortalExec<DeviceAdapterTag>>::type FunctionWithPortals;
typedef typename FunctionWithPortals::Signature SignatureWithPortals;
public:
typedef typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ValueType
ValueType;
typedef typename ArrayHandleCompositeVectorTraits<SignatureWithArrays>::ValueType ValueType;
// These are not currently fully implemented.
typedef typename StorageType::PortalType PortalControl;
@ -381,21 +391,20 @@ public:
typedef ArrayPortalCompositeVector<SignatureWithPortals> PortalConstExecution;
VTKM_CONT
ArrayTransfer(StorageType *storage) : Storage(storage) { }
ArrayTransfer(StorageType* storage)
: Storage(storage)
{
}
VTKM_CONT
vtkm::Id GetNumberOfValues() const {
return this->Storage->GetNumberOfValues();
}
vtkm::Id GetNumberOfValues() const { return this->Storage->GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData)) const
{
return
PortalConstExecution(
this->Storage->GetArrays().StaticTransformCont(
detail::CompositeVectorArrayToPortalExec<DeviceAdapterTag>()),
this->Storage->GetSourceComponents());
return PortalConstExecution(this->Storage->GetArrays().StaticTransformCont(
detail::CompositeVectorArrayToPortalExec<DeviceAdapterTag>()),
this->Storage->GetSourceComponents());
}
VTKM_CONT
@ -404,7 +413,7 @@ public:
// It may be the case a composite vector could be used for in place
// operations, but this is not implemented currently.
throw vtkm::cont::ErrorBadValue(
"Composite vector arrays cannot be used for output or in place.");
"Composite vector arrays cannot be used for output or in place.");
}
VTKM_CONT
@ -413,31 +422,26 @@ public:
// It may be the case a composite vector could be used for output if you
// want the delegate arrays to be resized, but this is not implemented
// currently.
throw vtkm::cont::ErrorBadValue(
"Composite vector arrays cannot be used for output.");
throw vtkm::cont::ErrorBadValue("Composite vector arrays cannot be used for output.");
}
VTKM_CONT
void RetrieveOutputData(StorageType *vtkmNotUsed(storage)) const
void RetrieveOutputData(StorageType* vtkmNotUsed(storage)) const
{
throw vtkm::cont::ErrorBadValue(
"Composite vector arrays cannot be used for output.");
throw vtkm::cont::ErrorBadValue("Composite vector arrays cannot be used for output.");
}
VTKM_CONT
void Shrink(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorBadValue(
"Composite vector arrays cannot be resized.");
throw vtkm::cont::ErrorBadValue("Composite vector arrays cannot be resized.");
}
VTKM_CONT
void ReleaseResources() {
this->Storage->ReleaseResources();
}
void ReleaseResources() { this->Storage->ReleaseResources(); }
private:
StorageType *Storage;
StorageType* Storage;
};
} // namespace internal
@ -452,91 +456,76 @@ private:
/// The easiest way to create and type an \c ArrayHandleCompositeVector is
/// to use the \c make_ArrayHandleCompositeVector functions.
///
template<typename Signature>
template <typename Signature>
class ArrayHandleCompositeVector
: public internal::ArrayHandleCompositeVectorTraits<Signature>::Superclass
: public internal::ArrayHandleCompositeVectorTraits<Signature>::Superclass
{
typedef typename internal::ArrayHandleCompositeVectorTraits<Signature>::StorageType
StorageType;
typedef typename internal::ArrayPortalCompositeVector<Signature>::ComponentMapType
ComponentMapType;
typedef typename internal::ArrayHandleCompositeVectorTraits<Signature>::StorageType StorageType;
typedef
typename internal::ArrayPortalCompositeVector<Signature>::ComponentMapType ComponentMapType;
public:
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleCompositeVector,
(ArrayHandleCompositeVector<Signature>),
(typename internal::ArrayHandleCompositeVectorTraits<Signature>::Superclass));
ArrayHandleCompositeVector,
(ArrayHandleCompositeVector<Signature>),
(typename internal::ArrayHandleCompositeVectorTraits<Signature>::Superclass));
VTKM_CONT
ArrayHandleCompositeVector(
const vtkm::internal::FunctionInterface<Signature> &arrays,
const ComponentMapType &sourceComponents)
ArrayHandleCompositeVector(const vtkm::internal::FunctionInterface<Signature>& arrays,
const ComponentMapType& sourceComponents)
: Superclass(StorageType(arrays, sourceComponents))
{ }
{
}
/// Template constructors for passing in types. You'll get weird compile
/// errors if the argument types do not actually match the types in the
/// signature.
///
template<typename ArrayHandleType1>
VTKM_CONT
ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
vtkm::IdComponent sourceComponent1)
template <typename ArrayHandleType1>
VTKM_CONT ArrayHandleCompositeVector(const ArrayHandleType1& array1,
vtkm::IdComponent sourceComponent1)
: Superclass(StorageType(vtkm::internal::make_FunctionInterface<ValueType>(array1),
ComponentMapType(sourceComponent1)))
{
}
template <typename ArrayHandleType1, typename ArrayHandleType2>
VTKM_CONT ArrayHandleCompositeVector(const ArrayHandleType1& array1,
vtkm::IdComponent sourceComponent1,
const ArrayHandleType2& array2,
vtkm::IdComponent sourceComponent2)
: Superclass(StorageType(vtkm::internal::make_FunctionInterface<ValueType>(array1, array2),
ComponentMapType(sourceComponent1, sourceComponent2)))
{
}
template <typename ArrayHandleType1, typename ArrayHandleType2, typename ArrayHandleType3>
VTKM_CONT ArrayHandleCompositeVector(const ArrayHandleType1& array1,
vtkm::IdComponent sourceComponent1,
const ArrayHandleType2& array2,
vtkm::IdComponent sourceComponent2,
const ArrayHandleType3& array3,
vtkm::IdComponent sourceComponent3)
: Superclass(
StorageType(vtkm::internal::make_FunctionInterface<ValueType>(array1, array2, array3),
ComponentMapType(sourceComponent1, sourceComponent2, sourceComponent3)))
{
}
template <typename ArrayHandleType1,
typename ArrayHandleType2,
typename ArrayHandleType3,
typename ArrayHandleType4>
VTKM_CONT ArrayHandleCompositeVector(const ArrayHandleType1& array1,
vtkm::IdComponent sourceComponent1,
const ArrayHandleType2& array2,
vtkm::IdComponent sourceComponent2,
const ArrayHandleType3& array3,
vtkm::IdComponent sourceComponent3,
const ArrayHandleType4& array4,
vtkm::IdComponent sourceComponent4)
: Superclass(StorageType(
vtkm::internal::make_FunctionInterface<ValueType>(array1),
ComponentMapType(sourceComponent1)))
{ }
template<typename ArrayHandleType1,
typename ArrayHandleType2>
VTKM_CONT
ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
vtkm::IdComponent sourceComponent1,
const ArrayHandleType2 &array2,
vtkm::IdComponent sourceComponent2)
: Superclass(StorageType(
vtkm::internal::make_FunctionInterface<ValueType>(
array1, array2),
ComponentMapType(sourceComponent1,
sourceComponent2)))
{ }
template<typename ArrayHandleType1,
typename ArrayHandleType2,
typename ArrayHandleType3>
VTKM_CONT
ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
vtkm::IdComponent sourceComponent1,
const ArrayHandleType2 &array2,
vtkm::IdComponent sourceComponent2,
const ArrayHandleType3 &array3,
vtkm::IdComponent sourceComponent3)
: Superclass(StorageType(
vtkm::internal::make_FunctionInterface<ValueType>(
array1, array2, array3),
ComponentMapType(sourceComponent1,
sourceComponent2,
sourceComponent3)))
{ }
template<typename ArrayHandleType1,
typename ArrayHandleType2,
typename ArrayHandleType3,
typename ArrayHandleType4>
VTKM_CONT
ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
vtkm::IdComponent sourceComponent1,
const ArrayHandleType2 &array2,
vtkm::IdComponent sourceComponent2,
const ArrayHandleType3 &array3,
vtkm::IdComponent sourceComponent3,
const ArrayHandleType4 &array4,
vtkm::IdComponent sourceComponent4)
: Superclass(StorageType(
vtkm::internal::make_FunctionInterface<ValueType>(
array1, array2, array3, array4),
ComponentMapType(sourceComponent1,
sourceComponent2,
sourceComponent3,
sourceComponent4)))
{ }
vtkm::internal::make_FunctionInterface<ValueType>(array1, array2, array3, array4),
ComponentMapType(sourceComponent1, sourceComponent2, sourceComponent3, sourceComponent4)))
{
}
};
/// \brief Get the type for an ArrayHandleCompositeVector
@ -552,164 +541,161 @@ public:
/// OutArrayType outArray = vtkm::cont::make_ArrayHandleCompositeVector(a1,a2);
/// \endcode
///
template<typename ArrayHandleType1,
typename ArrayHandleType2 = void,
typename ArrayHandleType3 = void,
typename ArrayHandleType4 = void>
template <typename ArrayHandleType1,
typename ArrayHandleType2 = void,
typename ArrayHandleType3 = void,
typename ArrayHandleType4 = void>
struct ArrayHandleCompositeVectorType
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType2);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType3);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType4);
private:
typedef typename vtkm::VecTraits<typename ArrayHandleType1::ValueType>::ComponentType
ComponentType;
typedef vtkm::Vec<ComponentType,4> Signature(
ArrayHandleType1,ArrayHandleType2,ArrayHandleType3,ArrayHandleType4);
typedef
typename vtkm::VecTraits<typename ArrayHandleType1::ValueType>::ComponentType ComponentType;
typedef vtkm::Vec<ComponentType, 4> Signature(ArrayHandleType1,
ArrayHandleType2,
ArrayHandleType3,
ArrayHandleType4);
public:
typedef vtkm::cont::ArrayHandleCompositeVector<Signature> type;
};
template<typename ArrayHandleType1,
typename ArrayHandleType2,
typename ArrayHandleType3>
struct ArrayHandleCompositeVectorType<
ArrayHandleType1,ArrayHandleType2,ArrayHandleType3>
template <typename ArrayHandleType1, typename ArrayHandleType2, typename ArrayHandleType3>
struct ArrayHandleCompositeVectorType<ArrayHandleType1, ArrayHandleType2, ArrayHandleType3>
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType2);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType3);
private:
typedef typename vtkm::VecTraits<typename ArrayHandleType1::ValueType>::ComponentType
ComponentType;
typedef vtkm::Vec<ComponentType,3> Signature(
ArrayHandleType1,ArrayHandleType2,ArrayHandleType3);
typedef
typename vtkm::VecTraits<typename ArrayHandleType1::ValueType>::ComponentType ComponentType;
typedef vtkm::Vec<ComponentType, 3> Signature(ArrayHandleType1,
ArrayHandleType2,
ArrayHandleType3);
public:
typedef vtkm::cont::ArrayHandleCompositeVector<Signature> type;
};
template<typename ArrayHandleType1,
typename ArrayHandleType2>
struct ArrayHandleCompositeVectorType<ArrayHandleType1,ArrayHandleType2>
template <typename ArrayHandleType1, typename ArrayHandleType2>
struct ArrayHandleCompositeVectorType<ArrayHandleType1, ArrayHandleType2>
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType2);
private:
typedef typename vtkm::VecTraits<typename ArrayHandleType1::ValueType>::ComponentType
ComponentType;
typedef vtkm::Vec<ComponentType,2> Signature(
ArrayHandleType1,ArrayHandleType2);
typedef
typename vtkm::VecTraits<typename ArrayHandleType1::ValueType>::ComponentType ComponentType;
typedef vtkm::Vec<ComponentType, 2> Signature(ArrayHandleType1, ArrayHandleType2);
public:
typedef vtkm::cont::ArrayHandleCompositeVector<Signature> type;
};
template<typename ArrayHandleType1>
template <typename ArrayHandleType1>
struct ArrayHandleCompositeVectorType<ArrayHandleType1>
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
private:
typedef typename vtkm::VecTraits<typename ArrayHandleType1::ValueType>::ComponentType
ComponentType;
typedef
typename vtkm::VecTraits<typename ArrayHandleType1::ValueType>::ComponentType ComponentType;
typedef ComponentType Signature(ArrayHandleType1);
public:
typedef vtkm::cont::ArrayHandleCompositeVector<Signature> type;
};
// clang-format off
/// Create a composite vector array from other arrays.
///
template<typename ValueType1, typename Storage1>
template <typename ValueType1, typename Storage1>
VTKM_CONT
typename ArrayHandleCompositeVectorType<
vtkm::cont::ArrayHandle<ValueType1,Storage1> >::type
make_ArrayHandleCompositeVector(
const vtkm::cont::ArrayHandle<ValueType1,Storage1> &array1,
vtkm::IdComponent sourceComponent1)
{
return typename ArrayHandleCompositeVectorType<
vtkm::cont::ArrayHandle<ValueType1,Storage1> >::type(array1,
sourceComponent1);
}
template<typename ArrayHandleType1>
VTKM_CONT
typename ArrayHandleCompositeVectorType<ArrayHandleType1>::type
make_ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
typename ArrayHandleCompositeVectorType<vtkm::cont::ArrayHandle<ValueType1, Storage1>>::type
make_ArrayHandleCompositeVector(const vtkm::cont::ArrayHandle<ValueType1, Storage1>& array1,
vtkm::IdComponent sourceComponent1)
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
return typename ArrayHandleCompositeVectorType<
ArrayHandleType1>::type(array1, sourceComponent1);
return
typename ArrayHandleCompositeVectorType<vtkm::cont::ArrayHandle<ValueType1, Storage1>>::type(
array1, sourceComponent1);
}
template<typename ArrayHandleType1,
typename ArrayHandleType2>
VTKM_CONT
typename ArrayHandleCompositeVectorType<
ArrayHandleType1, ArrayHandleType2>::type
make_ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
// clang-format on
template <typename ArrayHandleType1>
VTKM_CONT typename ArrayHandleCompositeVectorType<ArrayHandleType1>::type
make_ArrayHandleCompositeVector(const ArrayHandleType1& array1, vtkm::IdComponent sourceComponent1)
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
return typename ArrayHandleCompositeVectorType<ArrayHandleType1>::type(array1, sourceComponent1);
}
template <typename ArrayHandleType1, typename ArrayHandleType2>
VTKM_CONT typename ArrayHandleCompositeVectorType<ArrayHandleType1, ArrayHandleType2>::type
make_ArrayHandleCompositeVector(const ArrayHandleType1& array1,
vtkm::IdComponent sourceComponent1,
const ArrayHandleType2 &array2,
const ArrayHandleType2& array2,
vtkm::IdComponent sourceComponent2)
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType2);
return typename ArrayHandleCompositeVectorType<
ArrayHandleType1,
ArrayHandleType2>::type(array1, sourceComponent1,
array2, sourceComponent2);
return typename ArrayHandleCompositeVectorType<ArrayHandleType1, ArrayHandleType2>::type(
array1, sourceComponent1, array2, sourceComponent2);
}
template<typename ArrayHandleType1,
typename ArrayHandleType2,
typename ArrayHandleType3>
VTKM_CONT
typename ArrayHandleCompositeVectorType<
ArrayHandleType1, ArrayHandleType2, ArrayHandleType3>::type
make_ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
template <typename ArrayHandleType1, typename ArrayHandleType2, typename ArrayHandleType3>
VTKM_CONT typename ArrayHandleCompositeVectorType<ArrayHandleType1,
ArrayHandleType2,
ArrayHandleType3>::type
make_ArrayHandleCompositeVector(const ArrayHandleType1& array1,
vtkm::IdComponent sourceComponent1,
const ArrayHandleType2 &array2,
const ArrayHandleType2& array2,
vtkm::IdComponent sourceComponent2,
const ArrayHandleType3 &array3,
const ArrayHandleType3& array3,
vtkm::IdComponent sourceComponent3)
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType2);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType3);
return typename ArrayHandleCompositeVectorType<
ArrayHandleType1,
ArrayHandleType2,
ArrayHandleType3>::type(array1, sourceComponent1,
array2, sourceComponent2,
array3, sourceComponent3);
return
typename ArrayHandleCompositeVectorType<ArrayHandleType1, ArrayHandleType2, ArrayHandleType3>::
type(array1, sourceComponent1, array2, sourceComponent2, array3, sourceComponent3);
}
template<typename ArrayHandleType1,
typename ArrayHandleType2,
typename ArrayHandleType3,
typename ArrayHandleType4>
VTKM_CONT
typename ArrayHandleCompositeVectorType<
ArrayHandleType1, ArrayHandleType2, ArrayHandleType3, ArrayHandleType4>::type
make_ArrayHandleCompositeVector(const ArrayHandleType1 &array1,
template <typename ArrayHandleType1,
typename ArrayHandleType2,
typename ArrayHandleType3,
typename ArrayHandleType4>
VTKM_CONT typename ArrayHandleCompositeVectorType<ArrayHandleType1,
ArrayHandleType2,
ArrayHandleType3,
ArrayHandleType4>::type
make_ArrayHandleCompositeVector(const ArrayHandleType1& array1,
vtkm::IdComponent sourceComponent1,
const ArrayHandleType2 &array2,
const ArrayHandleType2& array2,
vtkm::IdComponent sourceComponent2,
const ArrayHandleType3 &array3,
const ArrayHandleType3& array3,
vtkm::IdComponent sourceComponent3,
const ArrayHandleType4 &array4,
const ArrayHandleType4& array4,
vtkm::IdComponent sourceComponent4)
{
VTKM_IS_ARRAY_HANDLE(ArrayHandleType1);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType2);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType3);
VTKM_IS_ARRAY_HANDLE(ArrayHandleType4);
return typename ArrayHandleCompositeVectorType<
ArrayHandleType1,
ArrayHandleType2,
ArrayHandleType3,
ArrayHandleType4>::type(array1, sourceComponent1,
array2, sourceComponent2,
array3, sourceComponent3,
array4, sourceComponent4);
return typename ArrayHandleCompositeVectorType<ArrayHandleType1,
ArrayHandleType2,
ArrayHandleType3,
ArrayHandleType4>::type(array1,
sourceComponent1,
array2,
sourceComponent2,
array3,
sourceComponent3,
array4,
sourceComponent4);
}
}
} // namespace vtkm::cont

@ -24,243 +24,253 @@
#include <vtkm/cont/ArrayHandle.h>
namespace vtkm {
namespace cont {
namespace internal {
namespace vtkm
{
namespace cont
{
namespace internal
{
template< typename PortalType1, typename PortalType2 >
template <typename PortalType1, typename PortalType2>
class VTKM_ALWAYS_EXPORT ArrayPortalConcatenate
{
public:
typedef typename PortalType1::ValueType ValueType;
VTKM_EXEC_CONT
ArrayPortalConcatenate() : portal1(), portal2() {}
ArrayPortalConcatenate()
: portal1()
, portal2()
{
}
VTKM_EXEC_CONT
ArrayPortalConcatenate( const PortalType1 &p1, const PortalType2 &p2 )
: portal1( p1 ), portal2( p2 ) {}
ArrayPortalConcatenate(const PortalType1& p1, const PortalType2& p2)
: portal1(p1)
, portal2(p2)
{
}
// Copy constructor
template< typename OtherP1, typename OtherP2 >
VTKM_EXEC_CONT
ArrayPortalConcatenate( const ArrayPortalConcatenate< OtherP1, OtherP2 > &src )
: portal1( src.GetPortal1() ), portal2( src.GetPortal2() ) {}
template <typename OtherP1, typename OtherP2>
VTKM_EXEC_CONT ArrayPortalConcatenate(const ArrayPortalConcatenate<OtherP1, OtherP2>& src)
: portal1(src.GetPortal1())
, portal2(src.GetPortal2())
{
}
VTKM_EXEC_CONT
vtkm::Id GetNumberOfValues() const
{
return this->portal1.GetNumberOfValues() +
this->portal2.GetNumberOfValues() ;
return this->portal1.GetNumberOfValues() + this->portal2.GetNumberOfValues();
}
VTKM_EXEC_CONT
ValueType Get( vtkm::Id index) const
ValueType Get(vtkm::Id index) const
{
if( index < this->portal1.GetNumberOfValues() )
return this->portal1.Get( index );
if (index < this->portal1.GetNumberOfValues())
return this->portal1.Get(index);
else
return this->portal2.Get( index - this->portal1.GetNumberOfValues() );
return this->portal2.Get(index - this->portal1.GetNumberOfValues());
}
VTKM_EXEC_CONT
void Set( vtkm::Id index, const ValueType &value ) const
void Set(vtkm::Id index, const ValueType& value) const
{
if( index < this->portal1.GetNumberOfValues() )
this->portal1.Set( index, value );
if (index < this->portal1.GetNumberOfValues())
this->portal1.Set(index, value);
else
this->portal2.Set( index - this->portal1.GetNumberOfValues(), value );
this->portal2.Set(index - this->portal1.GetNumberOfValues(), value);
}
VTKM_EXEC_CONT
const PortalType1 &GetPortal1() const
{
return this->portal1;
}
const PortalType1& GetPortal1() const { return this->portal1; }
VTKM_EXEC_CONT
const PortalType2 &GetPortal2() const
{
return this->portal2;
}
const PortalType2& GetPortal2() const { return this->portal2; }
private:
PortalType1 portal1;
PortalType2 portal2;
}; // class ArrayPortalConcatenate
}; // class ArrayPortalConcatenate
} // namespace internal
} // namespace internal
template <typename ArrayHandleType1, typename ArrayHandleType2>
class StorageTagConcatenate
{
};
template< typename ArrayHandleType1, typename ArrayHandleType2 >
class StorageTagConcatenate {};
namespace internal
{
namespace internal {
template< typename ArrayHandleType1, typename ArrayHandleType2 >
class Storage< typename ArrayHandleType1::ValueType,
StorageTagConcatenate< ArrayHandleType1, ArrayHandleType2> >
template <typename ArrayHandleType1, typename ArrayHandleType2>
class Storage<typename ArrayHandleType1::ValueType,
StorageTagConcatenate<ArrayHandleType1, ArrayHandleType2>>
{
public:
typedef typename ArrayHandleType1::ValueType ValueType;
typedef ArrayPortalConcatenate< typename ArrayHandleType1::PortalControl,
typename ArrayHandleType2::PortalControl > PortalType;
typedef ArrayPortalConcatenate<
typename ArrayHandleType1::PortalConstControl,
typename ArrayHandleType2::PortalConstControl > PortalConstType;
typedef ArrayPortalConcatenate<typename ArrayHandleType1::PortalControl,
typename ArrayHandleType2::PortalControl>
PortalType;
typedef ArrayPortalConcatenate<typename ArrayHandleType1::PortalConstControl,
typename ArrayHandleType2::PortalConstControl>
PortalConstType;
VTKM_CONT
Storage() : valid( false ) { }
Storage()
: valid(false)
{
}
VTKM_CONT
Storage( const ArrayHandleType1 &a1, const ArrayHandleType2 &a2 )
: array1( a1 ), array2( a2 ), valid( true ) {};
Storage(const ArrayHandleType1& a1, const ArrayHandleType2& a2)
: array1(a1)
, array2(a2)
, valid(true){};
VTKM_CONT
PortalConstType GetPortalConst() const
{
VTKM_ASSERT( this->valid );
return PortalConstType( this->array1.GetPortalConstControl(),
this->array2.GetPortalConstControl() );
VTKM_ASSERT(this->valid);
return PortalConstType(this->array1.GetPortalConstControl(),
this->array2.GetPortalConstControl());
}
VTKM_CONT
PortalType GetPortal()
{
VTKM_ASSERT( this->valid );
return PortalType( this->array1.GetPortalControl(),
this->array2.GetPortalControl() );
VTKM_ASSERT(this->valid);
return PortalType(this->array1.GetPortalControl(), this->array2.GetPortalControl());
}
VTKM_CONT
vtkm::Id GetNumberOfValues() const
{
VTKM_ASSERT( this->valid );
VTKM_ASSERT(this->valid);
return this->array1.GetNumberOfValues() + this->array2.GetNumberOfValues();
}
VTKM_CONT
void Allocate( vtkm::Id vtkmNotUsed(numberOfValues) )
void Allocate(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorInternal(
"ArrayHandleConcatenate should not be allocated explicitly. " );
throw vtkm::cont::ErrorInternal("ArrayHandleConcatenate should not be allocated explicitly. ");
}
VTKM_CONT
void Shrink( vtkm::Id numberOfValues )
void Shrink(vtkm::Id numberOfValues)
{
VTKM_ASSERT( this->valid );
if( numberOfValues < this->array1.GetNumberOfValues() )
VTKM_ASSERT(this->valid);
if (numberOfValues < this->array1.GetNumberOfValues())
{
this->array1.Shrink( numberOfValues );
this->array2.Shrink( 0 );
this->array1.Shrink(numberOfValues);
this->array2.Shrink(0);
}
else
this->array2.Shrink( numberOfValues - this->array1.GetNumberOfValues() );
this->array2.Shrink(numberOfValues - this->array1.GetNumberOfValues());
}
VTKM_CONT
void ReleaseResources( )
void ReleaseResources()
{
VTKM_ASSERT( this->valid );
VTKM_ASSERT(this->valid);
this->array1.ReleaseResources();
this->array2.ReleaseResources();
}
VTKM_CONT
const ArrayHandleType1 &GetArray1() const
const ArrayHandleType1& GetArray1() const
{
VTKM_ASSERT( this->valid );
VTKM_ASSERT(this->valid);
return this->array1;
}
VTKM_CONT
const ArrayHandleType2 &GetArray2() const
const ArrayHandleType2& GetArray2() const
{
VTKM_ASSERT( this->valid );
VTKM_ASSERT(this->valid);
return this->array2;
}
private:
ArrayHandleType1 array1;
ArrayHandleType2 array2;
bool valid;
}; // class Storage
bool valid;
}; // class Storage
template< typename ArrayHandleType1, typename ArrayHandleType2, typename Device >
class ArrayTransfer< typename ArrayHandleType1::ValueType,
StorageTagConcatenate< ArrayHandleType1, ArrayHandleType2>,
Device >
template <typename ArrayHandleType1, typename ArrayHandleType2, typename Device>
class ArrayTransfer<typename ArrayHandleType1::ValueType,
StorageTagConcatenate<ArrayHandleType1, ArrayHandleType2>,
Device>
{
public:
typedef typename ArrayHandleType1::ValueType ValueType;
private:
typedef StorageTagConcatenate< ArrayHandleType1, ArrayHandleType2 > StorageTag;
typedef vtkm::cont::internal::Storage< ValueType, StorageTag> StorageType;
typedef StorageTagConcatenate<ArrayHandleType1, ArrayHandleType2> StorageTag;
typedef vtkm::cont::internal::Storage<ValueType, StorageTag> StorageType;
public:
typedef typename StorageType::PortalType PortalControl;
typedef typename StorageType::PortalConstType PortalConstControl;
typedef ArrayPortalConcatenate<typename ArrayHandleType1::template ExecutionTypes<Device>::Portal,
typename ArrayHandleType2::template ExecutionTypes<Device>::Portal>
PortalExecution;
typedef ArrayPortalConcatenate<
typename ArrayHandleType1::template ExecutionTypes< Device >::Portal,
typename ArrayHandleType2::template ExecutionTypes< Device >::Portal >
PortalExecution;
typedef ArrayPortalConcatenate<
typename ArrayHandleType1::template ExecutionTypes< Device >::PortalConst,
typename ArrayHandleType2::template ExecutionTypes< Device >::PortalConst >
PortalConstExecution;
typename ArrayHandleType1::template ExecutionTypes<Device>::PortalConst,
typename ArrayHandleType2::template ExecutionTypes<Device>::PortalConst>
PortalConstExecution;
VTKM_CONT
ArrayTransfer( StorageType* storage )
: array1( storage->GetArray1() ), array2( storage->GetArray2() ) {}
ArrayTransfer(StorageType* storage)
: array1(storage->GetArray1())
, array2(storage->GetArray2())
{
}
VTKM_CONT
vtkm::Id GetNumberOfValues() const
{
return this->array1.GetNumberOfValues() + this->array2.GetNumberOfValues() ;
return this->array1.GetNumberOfValues() + this->array2.GetNumberOfValues();
}
VTKM_CONT
PortalConstExecution PrepareForInput( bool vtkmNotUsed( updateData ) )
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
{
return PortalConstExecution( this->array1.PrepareForInput( Device() ),
this->array2.PrepareForInput( Device() ));
return PortalConstExecution(this->array1.PrepareForInput(Device()),
this->array2.PrepareForInput(Device()));
}
VTKM_CONT
PortalExecution PrepareForInPlace( bool vtkmNotUsed( updateData ) )
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
{
return PortalExecution( this->array1.PrepareForInPlace( Device() ),
this->array2.PrepareForInPlace( Device() ));
return PortalExecution(this->array1.PrepareForInPlace(Device()),
this->array2.PrepareForInPlace(Device()));
}
VTKM_CONT
PortalExecution PrepareForOutput( vtkm::Id vtkmNotUsed(numberOfValues) )
PortalExecution PrepareForOutput(vtkm::Id vtkmNotUsed(numberOfValues))
{
throw vtkm::cont::ErrorInternal(
"ArrayHandleConcatenate is derived and read-only. " );
throw vtkm::cont::ErrorInternal("ArrayHandleConcatenate is derived and read-only. ");
}
VTKM_CONT
void RetrieveOutputData( StorageType* vtkmNotUsed(storage) ) const
void RetrieveOutputData(StorageType* vtkmNotUsed(storage)) const
{
// not need to implement
}
VTKM_CONT
void Shrink( vtkm::Id numberOfValues )
void Shrink(vtkm::Id numberOfValues)
{
if( numberOfValues < this->array1.GetNumberOfValues() )
if (numberOfValues < this->array1.GetNumberOfValues())
{
this->array1.Shrink( numberOfValues );
this->array2.Shrink( 0 );
this->array1.Shrink(numberOfValues);
this->array2.Shrink(0);
}
else
this->array2.Shrink( numberOfValues - this->array1.GetNumberOfValues() );
this->array2.Shrink(numberOfValues - this->array1.GetNumberOfValues());
}
VTKM_CONT
@ -273,53 +283,47 @@ public:
private:
ArrayHandleType1 array1;
ArrayHandleType2 array2;
};
}
}
} // namespace vtkm::cont::internal
namespace vtkm
{
namespace cont
{
namespace vtkm {
namespace cont {
template< typename ArrayHandleType1, typename ArrayHandleType2 >
template <typename ArrayHandleType1, typename ArrayHandleType2>
class ArrayHandleConcatenate
: public vtkm::cont::ArrayHandle< typename ArrayHandleType1::ValueType,
StorageTagConcatenate< ArrayHandleType1, ArrayHandleType2> >
: public vtkm::cont::ArrayHandle<typename ArrayHandleType1::ValueType,
StorageTagConcatenate<ArrayHandleType1, ArrayHandleType2>>
{
public:
VTKM_ARRAY_HANDLE_SUBCLASS( ArrayHandleConcatenate,
( ArrayHandleConcatenate< ArrayHandleType1, ArrayHandleType2> ),
( vtkm::cont::ArrayHandle< typename ArrayHandleType1::ValueType,
StorageTagConcatenate< ArrayHandleType1, ArrayHandleType2 > > ));
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleConcatenate,
(ArrayHandleConcatenate<ArrayHandleType1, ArrayHandleType2>),
(vtkm::cont::ArrayHandle<typename ArrayHandleType1::ValueType,
StorageTagConcatenate<ArrayHandleType1, ArrayHandleType2>>));
protected:
typedef vtkm::cont::internal::Storage< ValueType, StorageTag > StorageType;
typedef vtkm::cont::internal::Storage<ValueType, StorageTag> StorageType;
public:
VTKM_CONT
ArrayHandleConcatenate( const ArrayHandleType1 &array1,
const ArrayHandleType2 &array2 )
: Superclass( StorageType( array1, array2 ) )
{}
ArrayHandleConcatenate(const ArrayHandleType1& array1, const ArrayHandleType2& array2)
: Superclass(StorageType(array1, array2))
{
}
};
template< typename ArrayHandleType1, typename ArrayHandleType2 >
VTKM_CONT
ArrayHandleConcatenate< ArrayHandleType1, ArrayHandleType2 >
make_ArrayHandleConcatenate( const ArrayHandleType1 &array1,
const ArrayHandleType2 &array2 )
template <typename ArrayHandleType1, typename ArrayHandleType2>
VTKM_CONT ArrayHandleConcatenate<ArrayHandleType1, ArrayHandleType2> make_ArrayHandleConcatenate(
const ArrayHandleType1& array1,
const ArrayHandleType2& array2)
{
return ArrayHandleConcatenate< ArrayHandleType1, ArrayHandleType2 >( array1, array2 );
return ArrayHandleConcatenate<ArrayHandleType1, ArrayHandleType2>(array1, array2);
}
}
} // namespace vtkm::cont
} // namespace vtkm::cont
#endif //vtk_m_ArrayHandleConcatenate_h

@ -24,22 +24,25 @@
#include <vtkm/cont/ArrayHandleImplicit.h>
namespace vtkm {
namespace cont {
namespace vtkm
{
namespace cont
{
namespace detail {
namespace detail
{
template<typename ValueType>
template <typename ValueType>
struct VTKM_ALWAYS_EXPORT ConstantFunctor
{
VTKM_EXEC_CONT
ConstantFunctor(const ValueType &value = ValueType()) : Value(value) { }
ConstantFunctor(const ValueType& value = ValueType())
: Value(value)
{
}
VTKM_EXEC_CONT
ValueType operator()(vtkm::Id vtkmNotUsed(index)) const
{
return this->Value;
}
ValueType operator()(vtkm::Id vtkmNotUsed(index)) const { return this->Value; }
private:
ValueType Value;
@ -55,32 +58,30 @@ private:
/// given in the constructor. The array is defined implicitly, so there it
/// takes (almost) no memory.
///
template<typename T>
class ArrayHandleConstant
: public vtkm::cont::ArrayHandleImplicit<T, detail::ConstantFunctor<T> >
template <typename T>
class ArrayHandleConstant : public vtkm::cont::ArrayHandleImplicit<detail::ConstantFunctor<T>>
{
public:
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleConstant,
(ArrayHandleConstant<T>),
(vtkm::cont::ArrayHandleImplicit<T, detail::ConstantFunctor<T> >));
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleConstant,
(ArrayHandleConstant<T>),
(vtkm::cont::ArrayHandleImplicit<detail::ConstantFunctor<T>>));
VTKM_CONT
ArrayHandleConstant(T value, vtkm::Id numberOfValues = 0)
: Superclass(detail::ConstantFunctor<T>(value), numberOfValues) { }
: Superclass(detail::ConstantFunctor<T>(value), numberOfValues)
{
}
};
/// make_ArrayHandleConstant is convenience function to generate an
/// ArrayHandleImplicit. It takes a functor and the virtual length of the
/// array.
///
template<typename T>
vtkm::cont::ArrayHandleConstant<T>
make_ArrayHandleConstant(T value, vtkm::Id numberOfValues)
template <typename T>
vtkm::cont::ArrayHandleConstant<T> make_ArrayHandleConstant(T value, vtkm::Id numberOfValues)
{
return vtkm::cont::ArrayHandleConstant<T>(value, numberOfValues);
}
}
} // vtkm::cont

@ -25,49 +25,52 @@
#include <vtkm/VecTraits.h>
namespace vtkm {
namespace cont {
namespace vtkm
{
namespace cont
{
namespace internal {
namespace internal
{
/// \brief An implicit array portal that returns an counting value.
template <class CountingValueType>
class VTKM_ALWAYS_EXPORT ArrayPortalCounting
{
typedef typename vtkm::VecTraits<CountingValueType>::ComponentType
ComponentType;
typedef typename vtkm::VecTraits<CountingValueType>::ComponentType ComponentType;
public:
typedef CountingValueType ValueType;
VTKM_EXEC_CONT
ArrayPortalCounting() :
Start(0),
Step(1),
NumberOfValues(0)
{ }
VTKM_EXEC_CONT
ArrayPortalCounting(ValueType start, ValueType step, vtkm::Id numValues) :
Start(start),
Step(step),
NumberOfValues(numValues)
{ }
template<typename OtherValueType>
VTKM_EXEC_CONT
ArrayPortalCounting(const ArrayPortalCounting<OtherValueType> &src)
: Start(src.Start),
Step(src.Step),
NumberOfValues(src.NumberOfValues)
{ }
template<typename OtherValueType>
VTKM_EXEC_CONT
ArrayPortalCounting<ValueType> &operator=(
const ArrayPortalCounting<OtherValueType> &src)
ArrayPortalCounting()
: Start(0)
, Step(1)
, NumberOfValues(0)
{
this->Start= src.Start;
}
VTKM_EXEC_CONT
ArrayPortalCounting(ValueType start, ValueType step, vtkm::Id numValues)
: Start(start)
, Step(step)
, NumberOfValues(numValues)
{
}
template <typename OtherValueType>
VTKM_EXEC_CONT ArrayPortalCounting(const ArrayPortalCounting<OtherValueType>& src)
: Start(src.Start)
, Step(src.Step)
, NumberOfValues(src.NumberOfValues)
{
}
template <typename OtherValueType>
VTKM_EXEC_CONT ArrayPortalCounting<ValueType>& operator=(
const ArrayPortalCounting<OtherValueType>& src)
{
this->Start = src.Start;
this->Step = src.Step;
this->NumberOfValues = src.NumberOfValues;
return *this;
@ -77,14 +80,13 @@ public:
vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }
VTKM_EXEC_CONT
ValueType Get(vtkm::Id index) const {
return ValueType(this->Start +
this->Step*ValueType(static_cast<ComponentType>(index)));
ValueType Get(vtkm::Id index) const
{
return ValueType(this->Start + this->Step * ValueType(static_cast<ComponentType>(index)));
}
VTKM_EXEC_CONT
void Set(vtkm::Id vtkmNotUsed(index),
const ValueType &vtkmNotUsed(value)) const
void Set(vtkm::Id vtkmNotUsed(index), const ValueType& vtkmNotUsed(value)) const
{
VTKM_ASSERT(false && "Cannot write to read-only counting array.");
}
@ -97,11 +99,12 @@ private:
/// A convenience class that provides a typedef to the appropriate tag for
/// a counting storage.
template<typename ConstantValueType>
template <typename ConstantValueType>
struct ArrayHandleCountingTraits
{
typedef vtkm::cont::StorageTagImplicit<
vtkm::cont::internal::ArrayPortalCounting<ConstantValueType> > Tag;
vtkm::cont::internal::ArrayPortalCounting<ConstantValueType>>
Tag;
};
} // namespace internal
@ -110,44 +113,33 @@ struct ArrayHandleCountingTraits
/// contains a increment value, that is increment for each step between zero
/// and the passed in length
template <typename CountingValueType>
class ArrayHandleCounting
: public vtkm::cont::ArrayHandle <
CountingValueType,
typename internal::ArrayHandleCountingTraits<CountingValueType>::Tag
>
class ArrayHandleCounting : public vtkm::cont::ArrayHandle<
CountingValueType,
typename internal::ArrayHandleCountingTraits<CountingValueType>::Tag>
{
public:
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleCounting,
(ArrayHandleCounting<CountingValueType>),
(vtkm::cont::ArrayHandle<
CountingValueType,
typename internal::ArrayHandleCountingTraits<CountingValueType>::Tag
>));
ArrayHandleCounting,
(ArrayHandleCounting<CountingValueType>),
(vtkm::cont::ArrayHandle<
CountingValueType,
typename internal::ArrayHandleCountingTraits<CountingValueType>::Tag>));
VTKM_CONT
ArrayHandleCounting(CountingValueType start,
CountingValueType step,
vtkm::Id length)
:Superclass(typename Superclass::PortalConstControl(start, step, length))
ArrayHandleCounting(CountingValueType start, CountingValueType step, vtkm::Id length)
: Superclass(typename Superclass::PortalConstControl(start, step, length))
{
}
};
/// A convenience function for creating an ArrayHandleCounting. It takes the
/// value to start counting from and and the number of times to increment.
template<typename CountingValueType>
VTKM_CONT
vtkm::cont::ArrayHandleCounting<CountingValueType>
make_ArrayHandleCounting(CountingValueType start,
CountingValueType step,
vtkm::Id length)
template <typename CountingValueType>
VTKM_CONT vtkm::cont::ArrayHandleCounting<CountingValueType>
make_ArrayHandleCounting(CountingValueType start, CountingValueType step, vtkm::Id length)
{
return vtkm::cont::ArrayHandleCounting<CountingValueType>(start,
step,
length);
return vtkm::cont::ArrayHandleCounting<CountingValueType>(start, step, length);
}
}
} // namespace vtkm::cont

@ -20,12 +20,15 @@
#ifndef vtk_m_cont_ArrayHandleDiscard_h
#define vtk_m_cont_ArrayHandleDiscard_h
#include <vtkm/cont/ArrayHandle.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/cont/ArrayHandle.h>
namespace vtkm {
namespace exec {
namespace internal {
namespace vtkm
{
namespace exec
{
namespace internal
{
/// \brief An output-only array portal with no storage. All written values are
/// discarded.
@ -39,30 +42,30 @@ public:
VTKM_EXEC_CONT
ArrayPortalDiscard()
: NumberOfValues(0)
{ } // needs to be host and device so that cuda can create lvalue of these
{
} // needs to be host and device so that cuda can create lvalue of these
VTKM_CONT
explicit ArrayPortalDiscard(vtkm::Id numValues)
: NumberOfValues(numValues)
{ }
{
}
/// Copy constructor for any other ArrayPortalDiscard with an iterator
/// type that can be copied to this iterator type. This allows us to do any
/// type casting that the iterators do (like the non-const to const cast).
///
template<class OtherV>
VTKM_CONT
ArrayPortalDiscard(const ArrayPortalDiscard<OtherV> &src)
template <class OtherV>
VTKM_CONT ArrayPortalDiscard(const ArrayPortalDiscard<OtherV>& src)
: NumberOfValues(src.NumberOfValues)
{ }
VTKM_EXEC_CONT
vtkm::Id GetNumberOfValues() const
{
return this->NumberOfValues;
}
ValueType Get(vtkm::Id index) const {
VTKM_EXEC_CONT
vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }
ValueType Get(vtkm::Id index) const
{
VTKM_ASSERT(index < this->GetNumberOfValues());
VTKM_ASSERT("Method not supported for ArrayPortalDiscard." && false);
(void)index;
@ -70,7 +73,7 @@ public:
}
VTKM_EXEC
void Set(vtkm::Id index, const ValueType &) const
void Set(vtkm::Id index, const ValueType&) const
{
VTKM_ASSERT(index < this->GetNumberOfValues());
(void)index;
@ -84,11 +87,15 @@ private:
} // end namespace internal
} // end namespace exec
namespace cont {
namespace cont
{
namespace internal {
namespace internal
{
struct VTKM_ALWAYS_EXPORT StorageTagDiscard { };
struct VTKM_ALWAYS_EXPORT StorageTagDiscard
{
};
template <typename ValueType_>
class Storage<ValueType_, StorageTagDiscard>
@ -99,43 +106,25 @@ public:
using PortalConstType = vtkm::exec::internal::ArrayPortalDiscard<ValueType>;
VTKM_CONT
Storage() { }
Storage() {}
VTKM_CONT
PortalType GetPortal()
{
return PortalType(this->NumberOfValues);
}
PortalType GetPortal() { return PortalType(this->NumberOfValues); }
VTKM_CONT
PortalConstType GetPortalConst()
{
return PortalConstType(this->NumberOfValues);
}
PortalConstType GetPortalConst() { return PortalConstType(this->NumberOfValues); }
VTKM_CONT
vtkm::Id GetNumberOfValues() const
{
return this->NumberOfValues;
}
vtkm::Id GetNumberOfValues() const { return this->NumberOfValues; }
VTKM_CONT
void Allocate(vtkm::Id numValues)
{
this->NumberOfValues = numValues;
}
void Allocate(vtkm::Id numValues) { this->NumberOfValues = numValues; }
VTKM_CONT
void Shrink(vtkm::Id numValues)
{
this->NumberOfValues = numValues;
}
void Shrink(vtkm::Id numValues) { this->NumberOfValues = numValues; }
VTKM_CONT
void ReleaseResources()
{
this->NumberOfValues = 0;
}
void ReleaseResources() { this->NumberOfValues = 0; }
private:
vtkm::Id NumberOfValues;
@ -155,9 +144,10 @@ public:
using PortalConstExecution = vtkm::exec::internal::ArrayPortalDiscard<ValueType>;
VTKM_CONT
ArrayTransfer(StorageType *storage)
ArrayTransfer(StorageType* storage)
: Internal(storage)
{ }
{
}
VTKM_CONT
vtkm::Id GetNumberOfValues() const
@ -169,17 +159,15 @@ public:
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
{
throw vtkm::cont::ErrorBadValue(
"Input access not supported: "
"Cannot read from an ArrayHandleDiscard.");
throw vtkm::cont::ErrorBadValue("Input access not supported: "
"Cannot read from an ArrayHandleDiscard.");
}
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
{
throw vtkm::cont::ErrorBadValue(
"InPlace access not supported: "
"Cannot read from an ArrayHandleDiscard.");
throw vtkm::cont::ErrorBadValue("InPlace access not supported: "
"Cannot read from an ArrayHandleDiscard.");
}
VTKM_CONT
@ -191,7 +179,7 @@ public:
}
VTKM_CONT
void RetrieveOutputData(StorageType *storage) const
void RetrieveOutputData(StorageType* storage) const
{
VTKM_ASSERT(storage == this->Internal);
(void)storage;
@ -213,7 +201,7 @@ public:
}
private:
StorageType *Internal;
StorageType* Internal;
};
template <typename ValueType_>
@ -230,14 +218,12 @@ struct ArrayHandleDiscardTraits
/// it. This can be used to save memory when a filter provides optional outputs
/// that are not needed.
template <typename ValueType_>
class ArrayHandleDiscard
: public internal::ArrayHandleDiscardTraits<ValueType_>::Superclass
class ArrayHandleDiscard : public internal::ArrayHandleDiscardTraits<ValueType_>::Superclass
{
public:
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleDiscard,
(ArrayHandleDiscard<ValueType_>),
(typename internal::ArrayHandleDiscardTraits<ValueType_>::Superclass));
VTKM_ARRAY_HANDLE_SUBCLASS(ArrayHandleDiscard,
(ArrayHandleDiscard<ValueType_>),
(typename internal::ArrayHandleDiscardTraits<ValueType_>::Superclass));
};
} // end namespace cont

@ -24,47 +24,54 @@
#include <vtkm/cont/ArrayPortal.h>
#include <vtkm/cont/ErrorBadValue.h>
namespace vtkm {
namespace exec {
namespace vtkm
{
namespace exec
{
namespace internal {
namespace internal
{
template<typename _SourcePortalType, vtkm::IdComponent _NUM_COMPONENTS>
template <typename _SourcePortalType, vtkm::IdComponent _NUM_COMPONENTS>
class VTKM_ALWAYS_EXPORT ArrayPortalGroupVec
{
public:
static const vtkm::IdComponent NUM_COMPONENTS = _NUM_COMPONENTS;
typedef _SourcePortalType SourcePortalType;
typedef typename
std::remove_const<typename SourcePortalType::ValueType>::type
ComponentType;
typedef typename std::remove_const<typename SourcePortalType::ValueType>::type ComponentType;
typedef vtkm::Vec<ComponentType, NUM_COMPONENTS> ValueType;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ArrayPortalGroupVec() : SourcePortal() { }
ArrayPortalGroupVec()
: SourcePortal()
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ArrayPortalGroupVec(const SourcePortalType &sourcePortal)
: SourcePortal(sourcePortal) { }
ArrayPortalGroupVec(const SourcePortalType& sourcePortal)
: SourcePortal(sourcePortal)
{
}
/// Copy constructor for any other ArrayPortalConcatenate with a portal type
/// that can be copied to this portal type. This allows us to do any type
/// casting that the portals do (like the non-const to const cast).
VTKM_SUPPRESS_EXEC_WARNINGS
template<typename OtherSourcePortalType>
VTKM_EXEC_CONT
ArrayPortalGroupVec(
const ArrayPortalGroupVec<OtherSourcePortalType, NUM_COMPONENTS> &src)
: SourcePortal(src.GetPortal()) { }
template <typename OtherSourcePortalType>
VTKM_EXEC_CONT ArrayPortalGroupVec(
const ArrayPortalGroupVec<OtherSourcePortalType, NUM_COMPONENTS>& src)
: SourcePortal(src.GetPortal())
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
vtkm::Id GetNumberOfValues() const
{
return this->SourcePortal.GetNumberOfValues()/NUM_COMPONENTS;
return this->SourcePortal.GetNumberOfValues() / NUM_COMPONENTS;
}
VTKM_SUPPRESS_EXEC_WARNINGS
@ -72,10 +79,8 @@ public:
ValueType Get(vtkm::Id index) const
{
ValueType result;
vtkm::Id sourceIndex = index*NUM_COMPONENTS;
for (vtkm::IdComponent componentIndex = 0;
componentIndex < NUM_COMPONENTS;
componentIndex++)
vtkm::Id sourceIndex = index * NUM_COMPONENTS;
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; componentIndex++)
{
result[componentIndex] = this->SourcePortal.Get(sourceIndex);
sourceIndex++;
@ -85,12 +90,10 @@ public:
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
void Set(vtkm::Id index, const ValueType &value) const
void Set(vtkm::Id index, const ValueType& value) const
{
vtkm::Id sourceIndex = index*NUM_COMPONENTS;
for (vtkm::IdComponent componentIndex = 0;
componentIndex < NUM_COMPONENTS;
componentIndex++)
vtkm::Id sourceIndex = index * NUM_COMPONENTS;
for (vtkm::IdComponent componentIndex = 0; componentIndex < NUM_COMPONENTS; componentIndex++)
{
this->SourcePortal.Set(sourceIndex, value[componentIndex]);
sourceIndex++;
@ -99,49 +102,56 @@ public:
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
const SourcePortalType &GetPortal() const { return this->SourcePortal; }
const SourcePortalType& GetPortal() const { return this->SourcePortal; }
private:
SourcePortalType SourcePortal;
};
}
}
} // namespace vtkm::exec::internal
namespace vtkm {
namespace cont {
namespace vtkm
{
namespace cont
{
namespace internal {
namespace internal
{
template<typename SourceArrayHandleType, vtkm::IdComponent NUM_COMPONENTS>
struct VTKM_ALWAYS_EXPORT StorageTagGroupVec { };
template <typename SourceArrayHandleType, vtkm::IdComponent NUM_COMPONENTS>
struct VTKM_ALWAYS_EXPORT StorageTagGroupVec
{
};
template<typename SourceArrayHandleType,
vtkm::IdComponent NUM_COMPONENTS>
class Storage<
vtkm::Vec<typename SourceArrayHandleType::ValueType,NUM_COMPONENTS>,
vtkm::cont::internal::StorageTagGroupVec<
SourceArrayHandleType, NUM_COMPONENTS> >
template <typename SourceArrayHandleType, vtkm::IdComponent NUM_COMPONENTS>
class Storage<vtkm::Vec<typename SourceArrayHandleType::ValueType, NUM_COMPONENTS>,
vtkm::cont::internal::StorageTagGroupVec<SourceArrayHandleType, NUM_COMPONENTS>>
{
typedef typename SourceArrayHandleType::ValueType ComponentType;
public:
typedef vtkm::Vec<ComponentType,NUM_COMPONENTS> ValueType;
typedef vtkm::Vec<ComponentType, NUM_COMPONENTS> ValueType;
typedef vtkm::exec::internal::ArrayPortalGroupVec<
typename SourceArrayHandleType::PortalControl,
NUM_COMPONENTS> PortalType;
typedef vtkm::exec::internal::ArrayPortalGroupVec<
typename SourceArrayHandleType::PortalConstControl,
NUM_COMPONENTS> PortalConstType;
typedef vtkm::exec::internal::ArrayPortalGroupVec<typename SourceArrayHandleType::PortalControl,
NUM_COMPONENTS>
PortalType;
typedef vtkm::exec::internal::
ArrayPortalGroupVec<typename SourceArrayHandleType::PortalConstControl, NUM_COMPONENTS>
PortalConstType;
VTKM_CONT
Storage() : Valid(false) { }
Storage()
: Valid(false)
{
}
VTKM_CONT
Storage(const SourceArrayHandleType &sourceArray)
: SourceArray(sourceArray), Valid(true) { }
Storage(const SourceArrayHandleType& sourceArray)
: SourceArray(sourceArray)
, Valid(true)
{
}
VTKM_CONT
PortalType GetPortal()
@ -162,26 +172,26 @@ public:
{
VTKM_ASSERT(this->Valid);
vtkm::Id sourceSize = this->SourceArray.GetNumberOfValues();
if(sourceSize%NUM_COMPONENTS != 0)
if (sourceSize % NUM_COMPONENTS != 0)
{
throw vtkm::cont::ErrorBadValue(
"ArrayHandleGroupVec's source array does not divide evenly into Vecs.");
"ArrayHandleGroupVec's source array does not divide evenly into Vecs.");
}
return sourceSize/NUM_COMPONENTS;
return sourceSize / NUM_COMPONENTS;
}
VTKM_CONT
void Allocate(vtkm::Id numberOfValues)
{
VTKM_ASSERT(this->Valid);
this->SourceArray.Allocate(numberOfValues*NUM_COMPONENTS);
this->SourceArray.Allocate(numberOfValues * NUM_COMPONENTS);
}
VTKM_CONT
void Shrink(vtkm::Id numberOfValues)
{
VTKM_ASSERT(this->Valid);
this->SourceArray.Shrink(numberOfValues*NUM_COMPONENTS);
this->SourceArray.Shrink(numberOfValues * NUM_COMPONENTS);
}
VTKM_CONT
@ -195,7 +205,7 @@ public:
// Required for later use in ArrayTransfer class
VTKM_CONT
const SourceArrayHandleType &GetSourceArray() const
const SourceArrayHandleType& GetSourceArray() const
{
VTKM_ASSERT(this->Valid);
return this->SourceArray;
@ -206,22 +216,18 @@ private:
bool Valid;
};
template<typename SourceArrayHandleType,
vtkm::IdComponent NUM_COMPONENTS,
typename Device>
class ArrayTransfer<
vtkm::Vec<typename SourceArrayHandleType::ValueType, NUM_COMPONENTS>,
vtkm::cont::internal::StorageTagGroupVec<
SourceArrayHandleType, NUM_COMPONENTS>,
Device>
template <typename SourceArrayHandleType, vtkm::IdComponent NUM_COMPONENTS, typename Device>
class ArrayTransfer<vtkm::Vec<typename SourceArrayHandleType::ValueType, NUM_COMPONENTS>,
vtkm::cont::internal::StorageTagGroupVec<SourceArrayHandleType, NUM_COMPONENTS>,
Device>
{
public:
typedef typename SourceArrayHandleType::ValueType ComponentType;
typedef vtkm::Vec<ComponentType, NUM_COMPONENTS> ValueType;
private:
typedef vtkm::cont::internal::StorageTagGroupVec<
SourceArrayHandleType, NUM_COMPONENTS> StorageTag;
typedef vtkm::cont::internal::StorageTagGroupVec<SourceArrayHandleType, NUM_COMPONENTS>
StorageTag;
typedef vtkm::cont::internal::Storage<ValueType, StorageTag> StorageType;
public:
@ -229,37 +235,39 @@ public:
typedef typename StorageType::PortalConstType PortalConstControl;
typedef vtkm::exec::internal::ArrayPortalGroupVec<
typename SourceArrayHandleType::template ExecutionTypes<Device>::Portal,
NUM_COMPONENTS>
typename SourceArrayHandleType::template ExecutionTypes<Device>::Portal,
NUM_COMPONENTS>
PortalExecution;
typedef vtkm::exec::internal::ArrayPortalGroupVec<
typename SourceArrayHandleType::template ExecutionTypes<Device>::PortalConst,
NUM_COMPONENTS>
typename SourceArrayHandleType::template ExecutionTypes<Device>::PortalConst,
NUM_COMPONENTS>
PortalConstExecution;
VTKM_CONT
ArrayTransfer(StorageType *storage)
: SourceArray(storage->GetSourceArray()) { }
ArrayTransfer(StorageType* storage)
: SourceArray(storage->GetSourceArray())
{
}
VTKM_CONT
vtkm::Id GetNumberOfValues() const
{
vtkm::Id sourceSize = this->SourceArray.GetNumberOfValues();
if (sourceSize%NUM_COMPONENTS != 0)
if (sourceSize % NUM_COMPONENTS != 0)
{
throw vtkm::cont::ErrorBadValue(
"ArrayHandleGroupVec's source array does not divide evenly into Vecs.");
"ArrayHandleGroupVec's source array does not divide evenly into Vecs.");
}
return sourceSize/NUM_COMPONENTS;
return sourceSize / NUM_COMPONENTS;
}
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
{
if (this->SourceArray.GetNumberOfValues()%NUM_COMPONENTS != 0)
if (this->SourceArray.GetNumberOfValues() % NUM_COMPONENTS != 0)
{
throw vtkm::cont::ErrorBadValue(
"ArrayHandleGroupVec's source array does not divide evenly into Vecs.");
"ArrayHandleGroupVec's source array does not divide evenly into Vecs.");
}
return PortalConstExecution(this->SourceArray.PrepareForInput(Device()));
}
@ -267,10 +275,10 @@ public:
VTKM_CONT
PortalExecution PrepareForInPlace(bool vtkmNotUsed(updateData))
{
if (this->SourceArray.GetNumberOfValues()%NUM_COMPONENTS != 0)
if (this->SourceArray.GetNumberOfValues() % NUM_COMPONENTS != 0)
{
throw vtkm::cont::ErrorBadValue(
"ArrayHandleGroupVec's source array does not divide evenly into Vecs.");
"ArrayHandleGroupVec's source array does not divide evenly into Vecs.");
}
return PortalExecution(this->SourceArray.PrepareForInPlace(Device()));
}
@ -278,12 +286,12 @@ public:
VTKM_CONT
PortalExecution PrepareForOutput(vtkm::Id numberOfValues)
{
return PortalExecution(this->SourceArray.PrepareForOutput(
numberOfValues*NUM_COMPONENTS, Device()));
return PortalExecution(
this->SourceArray.PrepareForOutput(numberOfValues * NUM_COMPONENTS, Device()));
}
VTKM_CONT
void RetrieveOutputData(StorageType *vtkmNotUsed(storage)) const
void RetrieveOutputData(StorageType* vtkmNotUsed(storage)) const
{
// Implementation of this method should be unnecessary. The internal
// array handles should automatically retrieve the output data as
@ -293,14 +301,11 @@ public:
VTKM_CONT
void Shrink(vtkm::Id numberOfValues)
{
this->SourceArray.Shrink(numberOfValues*NUM_COMPONENTS);
this->SourceArray.Shrink(numberOfValues * NUM_COMPONENTS);
}
VTKM_CONT
void ReleaseResources()
{
this->SourceArray.ReleaseResourcesExecution();
}
void ReleaseResources() { this->SourceArray.ReleaseResourcesExecution(); }
private:
SourceArrayHandleType SourceArray;
@ -320,23 +325,21 @@ private:
/// to 3, you get an array that looks like it contains two values of \c Vec
/// values of size 3 with the data [0,1,2], [3,4,5].
///
template<typename SourceArrayHandleType, vtkm::IdComponent NUM_COMPONENTS>
template <typename SourceArrayHandleType, vtkm::IdComponent NUM_COMPONENTS>
class ArrayHandleGroupVec
: public vtkm::cont::ArrayHandle<
vtkm::Vec<typename SourceArrayHandleType::ValueType, NUM_COMPONENTS>,
vtkm::cont::internal::StorageTagGroupVec<
SourceArrayHandleType, NUM_COMPONENTS> >
: public vtkm::cont::ArrayHandle<
vtkm::Vec<typename SourceArrayHandleType::ValueType, NUM_COMPONENTS>,
vtkm::cont::internal::StorageTagGroupVec<SourceArrayHandleType, NUM_COMPONENTS>>
{
VTKM_IS_ARRAY_HANDLE(SourceArrayHandleType);
public:
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleGroupVec,
(ArrayHandleGroupVec<SourceArrayHandleType, NUM_COMPONENTS>),
(vtkm::cont::ArrayHandle<
vtkm::Vec<typename SourceArrayHandleType::ValueType, NUM_COMPONENTS>,
vtkm::cont::internal::StorageTagGroupVec<
SourceArrayHandleType, NUM_COMPONENTS> >));
ArrayHandleGroupVec,
(ArrayHandleGroupVec<SourceArrayHandleType, NUM_COMPONENTS>),
(vtkm::cont::ArrayHandle<
vtkm::Vec<typename SourceArrayHandleType::ValueType, NUM_COMPONENTS>,
vtkm::cont::internal::StorageTagGroupVec<SourceArrayHandleType, NUM_COMPONENTS>>));
typedef typename SourceArrayHandleType::ValueType ComponentType;
@ -345,8 +348,10 @@ private:
public:
VTKM_CONT
ArrayHandleGroupVec(const SourceArrayHandleType &sourceArray)
: Superclass(StorageType(sourceArray)) { }
ArrayHandleGroupVec(const SourceArrayHandleType& sourceArray)
: Superclass(StorageType(sourceArray))
{
}
};
/// \c make_ArrayHandleGroupVec is convenience function to generate an
@ -354,15 +359,12 @@ public:
/// (as a specified template parameter), and returns an array handle with
/// consecutive entries grouped in a Vec.
///
template<vtkm::IdComponent NUM_COMPONENTS,
typename ArrayHandleType>
VTKM_CONT
vtkm::cont::ArrayHandleGroupVec<ArrayHandleType, NUM_COMPONENTS>
make_ArrayHandleGroupVec(const ArrayHandleType &array)
template <vtkm::IdComponent NUM_COMPONENTS, typename ArrayHandleType>
VTKM_CONT vtkm::cont::ArrayHandleGroupVec<ArrayHandleType, NUM_COMPONENTS> make_ArrayHandleGroupVec(
const ArrayHandleType& array)
{
return vtkm::cont::ArrayHandleGroupVec<ArrayHandleType,NUM_COMPONENTS>(array);
return vtkm::cont::ArrayHandleGroupVec<ArrayHandleType, NUM_COMPONENTS>(array);
}
}
} // namespace vtkm::cont

@ -32,47 +32,53 @@
#include <vtkm/exec/arg/FetchTagArrayDirectOut.h>
namespace vtkm {
namespace exec {
namespace vtkm
{
namespace exec
{
namespace internal {
namespace internal
{
template<typename SourcePortalType, typename OffsetsPortalType>
template <typename SourcePortalType, typename OffsetsPortalType>
class VTKM_ALWAYS_EXPORT ArrayPortalGroupVecVariable
{
public:
using ComponentType =
typename std::remove_const<typename SourcePortalType::ValueType>::type;
using ComponentType = typename std::remove_const<typename SourcePortalType::ValueType>::type;
using ValueType = vtkm::VecFromPortal<SourcePortalType>;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ArrayPortalGroupVecVariable() : SourcePortal(), OffsetsPortal() { }
ArrayPortalGroupVecVariable()
: SourcePortal()
, OffsetsPortal()
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
ArrayPortalGroupVecVariable(const SourcePortalType &sourcePortal,
const OffsetsPortalType &offsetsPortal)
: SourcePortal(sourcePortal), OffsetsPortal(offsetsPortal) { }
ArrayPortalGroupVecVariable(const SourcePortalType& sourcePortal,
const OffsetsPortalType& offsetsPortal)
: SourcePortal(sourcePortal)
, OffsetsPortal(offsetsPortal)
{
}
/// Copy constructor for any other ArrayPortalConcatenate with a portal type
/// that can be copied to this portal type. This allows us to do any type
/// casting that the portals do (like the non-const to const cast).
VTKM_SUPPRESS_EXEC_WARNINGS
template<typename OtherSourcePortalType, typename OtherOffsetsPortalType>
VTKM_EXEC_CONT
ArrayPortalGroupVecVariable(
const ArrayPortalGroupVecVariable<OtherSourcePortalType, OtherOffsetsPortalType> &src)
: SourcePortal(src.GetSourcePortal()),
OffsetsPortal(src.GetOffsetsPortal())
{ }
template <typename OtherSourcePortalType, typename OtherOffsetsPortalType>
VTKM_EXEC_CONT ArrayPortalGroupVecVariable(
const ArrayPortalGroupVecVariable<OtherSourcePortalType, OtherOffsetsPortalType>& src)
: SourcePortal(src.GetSourcePortal())
, OffsetsPortal(src.GetOffsetsPortal())
{
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
vtkm::Id GetNumberOfValues() const
{
return this->OffsetsPortal.GetNumberOfValues();
}
vtkm::Id GetNumberOfValues() const { return this->OffsetsPortal.GetNumberOfValues(); }
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
@ -80,25 +86,23 @@ public:
{
vtkm::Id offsetIndex = this->OffsetsPortal.Get(index);
vtkm::Id nextOffsetIndex;
if (index+1 < this->GetNumberOfValues())
if (index + 1 < this->GetNumberOfValues())
{
nextOffsetIndex = this->OffsetsPortal.Get(index+1);
nextOffsetIndex = this->OffsetsPortal.Get(index + 1);
}
else
{
nextOffsetIndex = this->SourcePortal.GetNumberOfValues();
}
return
ValueType(this->SourcePortal,
static_cast<vtkm::IdComponent>(nextOffsetIndex-offsetIndex),
offsetIndex);
return ValueType(this->SourcePortal,
static_cast<vtkm::IdComponent>(nextOffsetIndex - offsetIndex),
offsetIndex);
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
void Set(vtkm::Id vtkmNotUsed(index),
const ValueType &vtkmNotUsed(value)) const
void Set(vtkm::Id vtkmNotUsed(index), const ValueType& vtkmNotUsed(value)) const
{
// The ValueType (VecFromPortal) operates on demand. Thus, if you set
// something in the value, it has already been passed to the array. Perhaps
@ -108,17 +112,11 @@ public:
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
const SourcePortalType &GetSourcePortal() const
{
return this->SourcePortal;
}
const SourcePortalType& GetSourcePortal() const { return this->SourcePortal; }
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC_CONT
const OffsetsPortalType &GetOffsetsPortal() const
{
return this->OffsetsPortal;
}
const OffsetsPortalType& GetOffsetsPortal() const { return this->OffsetsPortal; }
private:
SourcePortalType SourcePortal;
@ -127,7 +125,8 @@ private:
} // namespace internal (in vtkm::exec)
namespace arg {
namespace arg
{
// We need to override the fetch for output fields using
// ArrayPortalGroupVecVariable because this portal does not behave like most
@ -136,33 +135,26 @@ namespace arg {
// Instead, you need to implement the Load to point to the array portal. You
// can also ignore the Store because the data is already set in the array at
// that point.
template<typename ThreadIndicesType,
typename SourcePortalType,
typename OffsetsPortalType>
struct Fetch<
vtkm::exec::arg::FetchTagArrayDirectOut,
vtkm::exec::arg::AspectTagDefault,
ThreadIndicesType,
vtkm::exec::internal::ArrayPortalGroupVecVariable<SourcePortalType,OffsetsPortalType> >
template <typename ThreadIndicesType, typename SourcePortalType, typename OffsetsPortalType>
struct Fetch<vtkm::exec::arg::FetchTagArrayDirectOut,
vtkm::exec::arg::AspectTagDefault,
ThreadIndicesType,
vtkm::exec::internal::ArrayPortalGroupVecVariable<SourcePortalType, OffsetsPortalType>>
{
using ExecObjectType =
vtkm::exec::internal::ArrayPortalGroupVecVariable<
SourcePortalType,OffsetsPortalType>;
vtkm::exec::internal::ArrayPortalGroupVecVariable<SourcePortalType, OffsetsPortalType>;
using ValueType = typename ExecObjectType::ValueType;
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC
ValueType Load(const ThreadIndicesType &indices,
const ExecObjectType &arrayPortal) const
ValueType Load(const ThreadIndicesType& indices, const ExecObjectType& arrayPortal) const
{
return arrayPortal.Get(indices.GetOutputIndex());
}
VTKM_SUPPRESS_EXEC_WARNINGS
VTKM_EXEC
void Store(const ThreadIndicesType &,
const ExecObjectType &,
const ValueType &) const
void Store(const ThreadIndicesType&, const ExecObjectType&, const ValueType&) const
{
// We can actually ignore this because the VecFromPortal will already have
// set new values in the array.
@ -170,52 +162,57 @@ struct Fetch<
};
} // namespace arg (in vtkm::exec)
}
} // namespace vtkm::exec
namespace vtkm {
namespace cont {
namespace vtkm
{
namespace cont
{
namespace internal {
namespace internal
{
template<typename SourceArrayHandleType, typename OffsetsArrayHandleType>
struct VTKM_ALWAYS_EXPORT StorageTagGroupVecVariable { };
template <typename SourceArrayHandleType, typename OffsetsArrayHandleType>
struct VTKM_ALWAYS_EXPORT StorageTagGroupVecVariable
{
};
template<typename SourceArrayHandleType, typename OffsetsArrayHandleType>
template <typename SourceArrayHandleType, typename OffsetsArrayHandleType>
class Storage<
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>,
vtkm::cont::internal::StorageTagGroupVecVariable<
SourceArrayHandleType, OffsetsArrayHandleType> >
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>,
vtkm::cont::internal::StorageTagGroupVecVariable<SourceArrayHandleType, OffsetsArrayHandleType>>
{
using ComponentType = typename SourceArrayHandleType::ValueType;
public:
using ValueType =
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>;
using ValueType = vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>;
using PortalType =
vtkm::exec::internal::ArrayPortalGroupVecVariable<
typename SourceArrayHandleType::PortalControl,
typename OffsetsArrayHandleType::PortalControl>;
using PortalConstType =
vtkm::exec::internal::ArrayPortalGroupVecVariable<
typename SourceArrayHandleType::PortalConstControl,
typename OffsetsArrayHandleType::PortalConstControl>;
using PortalType = vtkm::exec::internal::ArrayPortalGroupVecVariable<
typename SourceArrayHandleType::PortalControl,
typename OffsetsArrayHandleType::PortalControl>;
using PortalConstType = vtkm::exec::internal::ArrayPortalGroupVecVariable<
typename SourceArrayHandleType::PortalConstControl,
typename OffsetsArrayHandleType::PortalConstControl>;
VTKM_CONT
Storage() : Valid(false) { }
Storage()
: Valid(false)
{
}
VTKM_CONT
Storage(const SourceArrayHandleType &sourceArray,
const OffsetsArrayHandleType &offsetsArray)
: SourceArray(sourceArray), OffsetsArray(offsetsArray), Valid(true) { }
Storage(const SourceArrayHandleType& sourceArray, const OffsetsArrayHandleType& offsetsArray)
: SourceArray(sourceArray)
, OffsetsArray(offsetsArray)
, Valid(true)
{
}
VTKM_CONT
PortalType GetPortal()
{
return PortalType(this->SourceArray.GetPortalControl(),
this->OffsetsArray.GetPortalControl());
return PortalType(this->SourceArray.GetPortalControl(), this->OffsetsArray.GetPortalControl());
}
VTKM_CONT
@ -235,8 +232,7 @@ public:
VTKM_CONT
void Allocate(vtkm::Id vtkmNotUsed(numberOfValues))
{
VTKM_ASSERT(
"Allocate not supported for ArrayhandleGroupVecVariable" && false);
VTKM_ASSERT("Allocate not supported for ArrayhandleGroupVecVariable" && false);
}
VTKM_CONT
@ -258,7 +254,7 @@ public:
// Required for later use in ArrayTransfer class
VTKM_CONT
const SourceArrayHandleType &GetSourceArray() const
const SourceArrayHandleType& GetSourceArray() const
{
VTKM_ASSERT(this->Valid);
return this->SourceArray;
@ -266,7 +262,7 @@ public:
// Required for later use in ArrayTransfer class
VTKM_CONT
const OffsetsArrayHandleType &GetOffsetsArray() const
const OffsetsArrayHandleType& GetOffsetsArray() const
{
VTKM_ASSERT(this->Valid);
return this->OffsetsArray;
@ -278,51 +274,42 @@ private:
bool Valid;
};
template<typename SourceArrayHandleType,
typename OffsetsArrayHandleType,
typename Device>
template <typename SourceArrayHandleType, typename OffsetsArrayHandleType, typename Device>
class ArrayTransfer<
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>,
vtkm::cont::internal::StorageTagGroupVecVariable<
SourceArrayHandleType, OffsetsArrayHandleType>,
Device>
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>,
vtkm::cont::internal::StorageTagGroupVecVariable<SourceArrayHandleType, OffsetsArrayHandleType>,
Device>
{
public:
using ComponentType = typename SourceArrayHandleType::ValueType;
using ValueType =
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>;
using ValueType = vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>;
private:
using StorageTag =
vtkm::cont::internal::StorageTagGroupVecVariable<
SourceArrayHandleType, OffsetsArrayHandleType>;
vtkm::cont::internal::StorageTagGroupVecVariable<SourceArrayHandleType, OffsetsArrayHandleType>;
using StorageType = vtkm::cont::internal::Storage<ValueType, StorageTag>;
public:
using PortalControl = typename StorageType::PortalType;
using PortalConstControl = typename StorageType::PortalConstType;
using PortalExecution =
vtkm::exec::internal::ArrayPortalGroupVecVariable<
typename SourceArrayHandleType::template ExecutionTypes<Device>::Portal,
typename OffsetsArrayHandleType::template ExecutionTypes<Device>::PortalConst>;
using PortalConstExecution =
vtkm::exec::internal::ArrayPortalGroupVecVariable<
typename SourceArrayHandleType::template ExecutionTypes<Device>::PortalConst,
typename OffsetsArrayHandleType::template ExecutionTypes<Device>::PortalConst>;
using PortalExecution = vtkm::exec::internal::ArrayPortalGroupVecVariable<
typename SourceArrayHandleType::template ExecutionTypes<Device>::Portal,
typename OffsetsArrayHandleType::template ExecutionTypes<Device>::PortalConst>;
using PortalConstExecution = vtkm::exec::internal::ArrayPortalGroupVecVariable<
typename SourceArrayHandleType::template ExecutionTypes<Device>::PortalConst,
typename OffsetsArrayHandleType::template ExecutionTypes<Device>::PortalConst>;
VTKM_CONT
ArrayTransfer(StorageType *storage)
: SourceArray(storage->GetSourceArray()),
OffsetsArray(storage->GetOffsetsArray())
{ }
VTKM_CONT
vtkm::Id GetNumberOfValues() const
ArrayTransfer(StorageType* storage)
: SourceArray(storage->GetSourceArray())
, OffsetsArray(storage->GetOffsetsArray())
{
return this->OffsetsArray.GetNumberOfValues();
}
VTKM_CONT
vtkm::Id GetNumberOfValues() const { return this->OffsetsArray.GetNumberOfValues(); }
VTKM_CONT
PortalConstExecution PrepareForInput(bool vtkmNotUsed(updateData))
{
@ -342,13 +329,13 @@ public:
{
// Cannot reallocate an ArrayHandleGroupVecVariable
VTKM_ASSERT(numberOfValues == this->OffsetsArray.GetNumberOfValues());
return PortalExecution(this->SourceArray.PrepareForOutput(
this->SourceArray.GetNumberOfValues(), Device()),
this->OffsetsArray.PrepareForInput(Device()));
return PortalExecution(
this->SourceArray.PrepareForOutput(this->SourceArray.GetNumberOfValues(), Device()),
this->OffsetsArray.PrepareForInput(Device()));
}
VTKM_CONT
void RetrieveOutputData(StorageType *vtkmNotUsed(storage)) const
void RetrieveOutputData(StorageType* vtkmNotUsed(storage)) const
{
// Implementation of this method should be unnecessary. The internal
// array handles should automatically retrieve the output data as
@ -356,10 +343,7 @@ public:
}
VTKM_CONT
void Shrink(vtkm::Id numberOfValues)
{
this->OffsetsArray.Shrink(numberOfValues);
}
void Shrink(vtkm::Id numberOfValues) { this->OffsetsArray.Shrink(numberOfValues); }
VTKM_CONT
void ReleaseResources()
@ -407,24 +391,24 @@ private:
/// components for each entry) and get an array of offsets needed for \c
/// ArrayHandleGroupVecVariable.
///
template<typename SourceArrayHandleType, typename OffsetsArrayHandleType>
template <typename SourceArrayHandleType, typename OffsetsArrayHandleType>
class ArrayHandleGroupVecVariable
: public vtkm::cont::ArrayHandle<
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>,
vtkm::cont::internal::StorageTagGroupVecVariable<
SourceArrayHandleType, OffsetsArrayHandleType> >
: public vtkm::cont::ArrayHandle<
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>,
vtkm::cont::internal::StorageTagGroupVecVariable<SourceArrayHandleType,
OffsetsArrayHandleType>>
{
VTKM_IS_ARRAY_HANDLE(SourceArrayHandleType);
VTKM_IS_ARRAY_HANDLE(OffsetsArrayHandleType);
public:
VTKM_ARRAY_HANDLE_SUBCLASS(
ArrayHandleGroupVecVariable,
(ArrayHandleGroupVecVariable<SourceArrayHandleType, OffsetsArrayHandleType>),
(vtkm::cont::ArrayHandle<
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>,
vtkm::cont::internal::StorageTagGroupVecVariable<
SourceArrayHandleType, OffsetsArrayHandleType> >));
ArrayHandleGroupVecVariable,
(ArrayHandleGroupVecVariable<SourceArrayHandleType, OffsetsArrayHandleType>),
(vtkm::cont::ArrayHandle<
vtkm::VecFromPortal<typename SourceArrayHandleType::PortalControl>,
vtkm::cont::internal::StorageTagGroupVecVariable<SourceArrayHandleType,
OffsetsArrayHandleType>>));
using ComponentType = typename SourceArrayHandleType::ValueType;
@ -433,9 +417,11 @@ private:
public:
VTKM_CONT
ArrayHandleGroupVecVariable(const SourceArrayHandleType &sourceArray,
const OffsetsArrayHandleType &offsetsArray)
: Superclass(StorageType(sourceArray, offsetsArray)) { }
ArrayHandleGroupVecVariable(const SourceArrayHandleType& sourceArray,
const OffsetsArrayHandleType& offsetsArray)
: Superclass(StorageType(sourceArray, offsetsArray))
{
}
};
/// \c make_ArrayHandleGroupVecVariable is convenience function to generate an
@ -443,21 +429,19 @@ public:
/// array handle of offsets and returns an array handle with consecutive
/// entries grouped in a Vec.
///
template<typename SourceArrayHandleType, typename OffsetsArrayHandleType>
VTKM_CONT
vtkm::cont::ArrayHandleGroupVecVariable<
SourceArrayHandleType, OffsetsArrayHandleType>
make_ArrayHandleGroupVecVariable(const SourceArrayHandleType &sourceArray,
const OffsetsArrayHandleType &offsetsArray)
template <typename SourceArrayHandleType, typename OffsetsArrayHandleType>
VTKM_CONT vtkm::cont::ArrayHandleGroupVecVariable<SourceArrayHandleType, OffsetsArrayHandleType>
make_ArrayHandleGroupVecVariable(const SourceArrayHandleType& sourceArray,
const OffsetsArrayHandleType& offsetsArray)
{
return vtkm::cont::ArrayHandleGroupVecVariable<
SourceArrayHandleType, OffsetsArrayHandleType>(sourceArray, offsetsArray);
return vtkm::cont::ArrayHandleGroupVecVariable<SourceArrayHandleType, OffsetsArrayHandleType>(
sourceArray, offsetsArray);
}
namespace detail {
namespace detail
{
template<typename NumComponentsArrayType,
typename OffsetsArrayType>
template <typename NumComponentsArrayType, typename OffsetsArrayType>
struct ConvertNumComponentsToOffsetsFunctor
{
const NumComponentsArrayType NumComponentsArray;
@ -465,43 +449,38 @@ struct ConvertNumComponentsToOffsetsFunctor
vtkm::Id SourceArraySize;
VTKM_CONT
ConvertNumComponentsToOffsetsFunctor(
const NumComponentsArrayType &numCompArray)
: NumComponentsArray(numCompArray), SourceArraySize(0)
{ }
template<typename Device>
VTKM_CONT
bool operator()(Device)
ConvertNumComponentsToOffsetsFunctor(const NumComponentsArrayType& numCompArray)
: NumComponentsArray(numCompArray)
, SourceArraySize(0)
{
this->SourceArraySize =
vtkm::cont::DeviceAdapterAlgorithm<Device>::
ScanExclusive(this->NumComponentsArray, this->OffsetsArray);
}
template <typename Device>
VTKM_CONT bool operator()(Device)
{
this->SourceArraySize = vtkm::cont::DeviceAdapterAlgorithm<Device>::ScanExclusive(
this->NumComponentsArray, this->OffsetsArray);
return true;
}
};
template<typename NumComponentsArrayType,
typename OffsetsArrayType>
VTKM_CONT
void DoConvertNumComponentsToOffsets(
const NumComponentsArrayType &numComponentsArray,
OffsetsArrayType &offsetsArray,
vtkm::Id &sourceArraySize)
template <typename NumComponentsArrayType, typename OffsetsArrayType>
VTKM_CONT void DoConvertNumComponentsToOffsets(const NumComponentsArrayType& numComponentsArray,
OffsetsArrayType& offsetsArray,
vtkm::Id& sourceArraySize)
{
VTKM_IS_ARRAY_HANDLE(NumComponentsArrayType);
VTKM_IS_ARRAY_HANDLE(OffsetsArrayType);
detail::ConvertNumComponentsToOffsetsFunctor<
NumComponentsArrayType,OffsetsArrayType> functor(numComponentsArray);
detail::ConvertNumComponentsToOffsetsFunctor<NumComponentsArrayType, OffsetsArrayType> functor(
numComponentsArray);
bool success = vtkm::cont::TryExecute(functor);
if (!success)
{
// Internal error? Maybe need to make a failed to execute error.
throw vtkm::cont::ErrorInternal(
"Failed to run ExclusiveScan on any device.");
throw vtkm::cont::ErrorInternal("Failed to run ExclusiveScan on any device.");
}
sourceArraySize = functor.SourceArraySize;
@ -518,54 +497,43 @@ void DoConvertNumComponentsToOffsets(
/// If an optional second parameter is given, the expected size of the source
/// values array is returned in it.
///
template<typename NumComponentsArrayType,
typename OffsetsStorage>
VTKM_CONT
void ConvertNumComponentsToOffsets(
const NumComponentsArrayType &numComponentsArray,
vtkm::cont::ArrayHandle<vtkm::Id,OffsetsStorage> &offsetsArray,
vtkm::Id &sourceArraySize)
template <typename NumComponentsArrayType, typename OffsetsStorage>
VTKM_CONT void ConvertNumComponentsToOffsets(
const NumComponentsArrayType& numComponentsArray,
vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorage>& offsetsArray,
vtkm::Id& sourceArraySize)
{
VTKM_IS_ARRAY_HANDLE(NumComponentsArrayType);
detail::DoConvertNumComponentsToOffsets(
vtkm::cont::make_ArrayHandleCast<vtkm::Id>(numComponentsArray),
offsetsArray,
sourceArraySize);
vtkm::cont::make_ArrayHandleCast<vtkm::Id>(numComponentsArray), offsetsArray, sourceArraySize);
}
template<typename NumComponentsArrayType,
typename OffsetsStorage>
VTKM_CONT
void ConvertNumComponentsToOffsets(
const NumComponentsArrayType &numComponentsArray,
vtkm::cont::ArrayHandle<vtkm::Id,OffsetsStorage> &offsetsArray)
template <typename NumComponentsArrayType, typename OffsetsStorage>
VTKM_CONT void ConvertNumComponentsToOffsets(
const NumComponentsArrayType& numComponentsArray,
vtkm::cont::ArrayHandle<vtkm::Id, OffsetsStorage>& offsetsArray)
{
vtkm::Id dummy;
vtkm::cont::ConvertNumComponentsToOffsets(
numComponentsArray, offsetsArray, dummy);
vtkm::cont::ConvertNumComponentsToOffsets(numComponentsArray, offsetsArray, dummy);
}
template<typename NumComponentsArrayType>
VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Id>
ConvertNumComponentsToOffsets(const NumComponentsArrayType &numComponentsArray,
vtkm::Id &sourceArraySize)
template <typename NumComponentsArrayType>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Id> ConvertNumComponentsToOffsets(
const NumComponentsArrayType& numComponentsArray,
vtkm::Id& sourceArraySize)
{
VTKM_IS_ARRAY_HANDLE(NumComponentsArrayType);
vtkm::cont::ArrayHandle<vtkm::Id> offsetsArray;
vtkm::cont::ConvertNumComponentsToOffsets(
numComponentsArray, offsetsArray, sourceArraySize);
vtkm::cont::ConvertNumComponentsToOffsets(numComponentsArray, offsetsArray, sourceArraySize);
return offsetsArray;
}
template<typename NumComponentsArrayType>
VTKM_CONT
vtkm::cont::ArrayHandle<vtkm::Id>
ConvertNumComponentsToOffsets(const NumComponentsArrayType &numComponentsArray)
template <typename NumComponentsArrayType>
VTKM_CONT vtkm::cont::ArrayHandle<vtkm::Id> ConvertNumComponentsToOffsets(
const NumComponentsArrayType& numComponentsArray)
{
vtkm::Id dummy;
return vtkm::cont::ConvertNumComponentsToOffsets(numComponentsArray, dummy);
}
}
} // namespace vtkm::cont

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