diff --git CMakeLists.txt CMakeLists.txt index 55dac92..79cf92e 100644 --- CMakeLists.txt +++ CMakeLists.txt @@ -5,7 +5,7 @@ ## This source code is released under the New BSD License. # -CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) # Turn off policy 0017, which makes modules packaged with CMake find # any module rather than just others packaged with CMake. This is @@ -18,10 +18,16 @@ PROJECT(ICET C) # Set the current IceT version. SET(ICET_MAJOR_VERSION 2) -SET(ICET_MINOR_VERSION 1) -SET(ICET_PATCH_VERSION 1) +SET(ICET_MINOR_VERSION 2) +SET(ICET_PATCH_VERSION 0) SET(ICET_VERSION "${ICET_MAJOR_VERSION}.${ICET_MINOR_VERSION}.${ICET_PATCH_VERSION}") +# CMake 2.8.12 and later supports an rpath mechanism on Mac OSX that allows +# build and install targets to point to dependent libraries that are not +# dependent on DYLD_LIBRARY_PATH. This variable turns that behavior on by +# default and also suppresses CMake policy warning 0042. +SET(CMAKE_MACOSX_RPATH ON) + # Set output paths. SET(LIBRARY_OUTPUT_PATH ${ICET_BINARY_DIR}/lib CACHE PATH "Output directory for building all libraries.") @@ -30,14 +36,6 @@ SET(EXECUTABLE_OUTPUT_PATH ${ICET_BINARY_DIR}/bin CACHE PATH MARK_AS_ADVANCED(LIBRARY_OUTPUT_PATH EXECUTABLE_OUTPUT_PATH) SET(ICET_LIBRARY_DIR ${LIBRARY_OUTPUT_PATH}) SET(ICET_EXECUTABLE_DIR ${EXECUTABLE_OUTPUT_PATH}) -SET(C_TEST_PATH ${EXECUTABLE_OUTPUT_PATH}) - -# CMAKE_CONFIGURATION_TYPES is set for generators that support multiple -# configurations e.g. Visual Studio. In that case we update the C_TEST_PATH to -# include the configuration type (CTEST_CONFIGURATION_TYPE) -IF (CMAKE_CONFIGURATION_TYPES) - SET (C_TEST_PATH ${C_TEST_PATH}/\${CTEST_CONFIGURATION_TYPE}) -ENDIF(CMAKE_CONFIGURATION_TYPES) SET(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} @@ -50,6 +48,8 @@ SET(ICET_BUILD_SHARED_LIBS ${BUILD_SHARED_LIBS}) # Options controlling support libraries OPTION(ICET_USE_OPENGL "Build OpenGL support layer for IceT." ON) +OPTION(ICET_USE_OSMESA "Use OffScreen Mesa" OFF) +OPTION(ICET_USE_OFFSCREEN_EGL "Use OffScreen rendering through EGL" OFF) OPTION(ICET_USE_MPI "Build MPI communication layer for IceT." ON) # Option to set the preferred K value to use in the radix-k algorithm @@ -98,19 +98,19 @@ ENDIF (UNIX) # Configure OpenGL support. IF (ICET_USE_OPENGL) - FIND_PACKAGE(OpenGL) - IF (OPENGL_FOUND) + IF (ICET_USE_OSMESA) + FIND_PACKAGE(OSMesa REQUIRED) + INCLUDE_DIRECTORIES(${OSMESA_INCLUDE_DIR}) + SET(ICET_OPENGL_LIBRARIES ${OSMESA_LIBRARY}) + ELSEIF (ICET_USE_OFFSCREEN_EGL) + FIND_PACKAGE(EGL REQUIRED) + INCLUDE_DIRECTORIES(${EGL_INCLUDE_DIR}) + SET(ICET_OPENGL_LIBRARIES ${EGL_LIBRARIES}) + ELSE() + FIND_PACKAGE(OpenGL REQUIRED) INCLUDE_DIRECTORIES(${OPENGL_INCLUDE_DIR}) SET(ICET_OPENGL_LIBRARIES ${OPENGL_LIBRARIES}) - ELSE (OPENGL_FOUND) - FIND_PACKAGE(OSMesa) - IF (OSMESA_INCLUDE_DIR AND OSMESA_LIBRARY) - INCLUDE_DIRECTORIES(${OSMESA_INCLUDE_DIR}) - SET(ICET_OPENGL_LIBRARIES ${OSMESA_LIBRARY}) - ELSE(OSMESA_INCLUDE_DIR AND OSMESA_LIBRARY) - MESSAGE(SEND_ERROR "Could not find OpenGL or OSMesa, which is required when ICET_USE_OPENGL is ON.") - ENDIF (OSMESA_INCLUDE_DIR AND OSMESA_LIBRARY) - ENDIF (OPENGL_FOUND) + ENDIF() ENDIF (ICET_USE_OPENGL) # Configure MPI support. @@ -169,9 +169,13 @@ ENDIF (ICET_USE_MPI) # Add extra warnings when possible. The IceT build should be clean. I expect # no warnings when bulding this code. -IF (CMAKE_COMPILER_IS_GNUCC) - SET(ICET_C_FLAGS_WARN "-ansi -Wall -Wno-long-long -Wcast-align -Wextra -Wformat-security -Wshadow -Wunused -Wreturn-type -Wpointer-arith -Wdeclaration-after-statement") -ENDIF (CMAKE_COMPILER_IS_GNUCC) +IF(CMAKE_C_COMPILER_ID STREQUAL "Clang") + SET(CMAKE_COMPILER_IS_CLANG 1) +ENDIF() + +IF (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) + SET(ICET_C_FLAGS_WARN "-ansi -Wall -Wno-long-long -Wextra -Wformat-security -Wshadow -Wunused -Wreturn-type -Wpointer-arith -Wdeclaration-after-statement") +ENDIF (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) # Configure testing support. IF (BUILD_TESTING) @@ -329,7 +333,7 @@ IF (NOT ICET_INSTALL_NO_DEVELOPMENT) ENDIF (NOT ICET_INSTALL_NO_DEVELOPMENT) # Enable CPack packaging. -SET(CPACK_PACKAGE_DESCRIPTION_FILE ${ICET_SOURCE_DIR}/README) +SET(CPACK_PACKAGE_DESCRIPTION_FILE ${ICET_SOURCE_DIR}/README.md) SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "The Image Composition Engine for Tiles") SET(CPACK_PACKAGE_NAME "IceT") SET(CPACK_PACKAGE_VENDOR "Sandia National Laboratories") diff --git History History index 928c24e..a921f95 100644 --- History +++ History @@ -10,25 +10,29 @@ ** ***************************************************************************** +Revision 2.2: + Added the icetCompositeImage function to allow IceT to operate on + pre-rendered images rather than rely on a rendering callback. + Revision 2.1: - Added Radix-k as a single-image strategy. + Added Radix-k as a single-image strategy. - Changed the collection method for single image compositing to use - the built-in gather functions of MPI. The old method had memory - problems with large numbers of processes and would probably be - inefficient anyway. + Changed the collection method for single image compositing to use + the built-in gather functions of MPI. The old method had memory + problems with large numbers of processes and would probably be + inefficient anyway. - Changed the single image compositing methods to work strictly with - compressed images. This prevents having to pad images with - background only to then test that same background later during - compression. + Changed the single image compositing methods to work strictly with + compressed images. This prevents having to pad images with + background only to then test that same background later during + compression. - Added interlace images option that provides a hint to the - compositing algorithms to try shuffling the pixels in images to - better load balance the active pixels during compositing. + Added interlace images option that provides a hint to the + compositing algorithms to try shuffling the pixels in images to + better load balance the active pixels during compositing. - Patch 1: Fixed compatibility issue with compiling against MPI - version 1. Fixed build issues for Windows. + Patch 1: Fixed compatibility issue with compiling against MPI + version 1. Fixed build issues for Windows. Revision 2.0: A major restructuring of the IceT code comprising the following changes: diff --git README README deleted file mode 100644 index 123107e..0000000 --- README +++ /dev/null @@ -1,33 +0,0 @@ -** -*- text -*- ************************************************************* -** -** README and installation instructions for IceT -** -** Author: Kenneth Moreland (kmorel@sandia.gov) -** -** Copyright 2003 Sandia Coporation -** Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, -** the U.S. Government retains certain rights in this software. -** -** This source code is released under the New BSD License. -** -***************************************************************************** - -Welcome to the IceT build process. IceT uses CMake to automatically -tailor itself to your system, so compiling should be relatively painless. -Before building IceT you will need to install CMake on your system. You -can get CMake from www.cmake.org. - -Once CMake is installed and the IceT source is extracted, run the -interactive CMake configuration tool. On UNIX, run ccmake. On Win32, run -the CMake program on the desktop or in the start menu. Note that when -using the interactive configuration tool, you will need to ``configure'' -several times before you can generate the build files. This is because as -more information is retrieved, futher options are revealed. - -After CMake generates build files, compile the applications as applicable -for your system. - - -IceT is released under the New BSD License. Any contributions to IceT will -also be considered to fall under this license, and it is the responsibility -of the authors to secure the necessary permissions before contributing. diff --git README.md README.md new file mode 100644 index 0000000..bbb3afa --- /dev/null +++ README.md @@ -0,0 +1,37 @@ +> ***************************************************************************** +> +> README and installation instructions for IceT +> +> Author: Kenneth Moreland (kmorel@sandia.gov) +> +> Copyright 2003 Sandia Coporation +> +> Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +> the U.S. Government retains certain rights in this software. +> +> This source code is released under the [New BSD License](bsd). +> +> ***************************************************************************** + +Welcome to the IceT build process. IceT uses [CMake](cmake) to automatically +tailor itself to your system, so compiling should be relatively painless. +Before building IceT you will need to install CMake on your system. You +can get CMake from [here](cmake-download). + +Once CMake is installed and the IceT source is extracted, run the +interactive CMake configuration tool. On UNIX, run `ccmake`. On Win32, run +the CMake program on the desktop or in the start menu. Note that when +using the interactive configuration tool, you will need to *configure* +several times before you can generate the build files. This is because as +more information is retrieved, futher options are revealed. + +After CMake generates build files, compile the applications as applicable +for your system. + +IceT is released under the [New BSD License](bsd). Any contributions to IceT will +also be considered to fall under this license, and it is the responsibility +of the authors to secure the necessary permissions before contributing. + +[bsd]: http://opensource.org/licenses/BSD-3-Clause +[cmake]: http://www.cmake.org/ +[cmake-download]: http://www.cmake.org/download/ diff --git doc/man/man3/icetAddTile.3 doc/man/man3/icetAddTile.3 index e2c921d..e3302e7 100644 --- doc/man/man3/icetAddTile.3 +++ doc/man/man3/icetAddTile.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:53 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:52 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetBoundingBox.3 doc/man/man3/icetBoundingBox.3 index 4843e4d..7fdd198 100644 --- doc/man/man3/icetBoundingBox.3 +++ doc/man/man3/icetBoundingBox.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:53 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:52 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetBoundingBoxd.3 doc/man/man3/icetBoundingBoxd.3 index 4843e4d..7fdd198 100644 --- doc/man/man3/icetBoundingBoxd.3 +++ doc/man/man3/icetBoundingBoxd.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:53 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:52 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetBoundingBoxf.3 doc/man/man3/icetBoundingBoxf.3 index 4843e4d..7fdd198 100644 --- doc/man/man3/icetBoundingBoxf.3 +++ doc/man/man3/icetBoundingBoxf.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:53 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:52 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetBoundingVertices.3 doc/man/man3/icetBoundingVertices.3 index edd1f77..c902139 100644 --- doc/man/man3/icetBoundingVertices.3 +++ doc/man/man3/icetBoundingVertices.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:52 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetCompositeImage.3 doc/man/man3/icetCompositeImage.3 new file mode 100644 index 0000000..69dea97 --- /dev/null +++ doc/man/man3/icetCompositeImage.3 @@ -0,0 +1,290 @@ +'\" t +.\" Manual page created with latex2man on Thu Oct 9 15:41:59 MDT 2014 +.\" NOTE: This file is generated, DO NOT EDIT. +.de Vb +.ft CW +.nf +.. +.de Ve +.ft R + +.fi +.. +.TH "icetCompositeImage" "3" "October 9, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" +.SH NAME + +\fBicetCompositeImage \-\- composites a pre\-rendered image\fP +.PP +.SH Synopsis + +.PP +#include +.PP +.TS H +l l l . +\fBIceTImage\fP \fBicetCompositeImage\fP( + const IceTVoid * \fIcolor_buffer\fP, + const IceTVoid * \fIdepth_buffer\fP, + const IceTInt * \fIvalid_pixels_viewport\fP, + const IceTDouble * \fIprojection_matrix\fP, + const IceTDouble * \fImodelview_matrix\fP, + const IceTFloat * \fIbackground_color\fP ); +.TE +.PP +.SH Description + +.PP +The \fBicetCompositeImage\fP +function takes image buffer data and +composites it to a single image. This function behaves similarly to +\fBicetDrawFrame\fP +except that instead of using callback functions to +render and retrieve image data, the images are pre\-rendered and passed +directly to \fBicetCompositeImage\fP\&. +Although it is more efficient to +allow \fBIceT \fPto determine rendering projections and use callbacks, it is +often more convenient for applications to integrate \fBIceT \fPas a separate +compositing step after the rendering. +.PP +Before \fBIceT \fPmay composite an image, the display needs to be defined +(using \fBicetAddTile\fP), +the buffer formats need to be specified +(using \fBicetSetColorFormat\fPand \fBicetSetDepthFormat\fP),and the composite +strategy must be set (using \fBicetStrategy\fP). +The single image +sub\-strategy may also optionally be set (using +\fBicetSingleImageStrategy\fP). +.PP +All process must call \fBicetCompositeImage\fP +for the operation to +complete on any process in a parallel job. +.PP +The \fIcolor_buffer\fP +and \fIdepth_buffer\fP +arguments point to +memory buffers that contain the image data. The image data is always +stored in densely packed arrays in row\-major order (a.k.a. x\-major order +or by scan\-lines). The first horizontal scan\-line is at the bottom of the +image with subsequent scan\-lines moving up. The size of each image buffer +is expected to be the width and the height of the global viewport (which +is set indirectly with \fBicetAddTile\fP). +The global viewport is +stored in the \fBICET_GLOBAL_VIEWPORT\fP +state variable. If only one +tile is specified, then the width and height of the global viewport will +be the same as this one tile. +.PP +The format for \fIcolor_buffer\fP +is expected to be the same as what is +set with \fBicetSetColorFormat\fP\&.The following formats and their +interpretations with respect to \fIcolor_buffer\fP +are as follows. +.PP +.TP +\fBICET_IMAGE_COLOR_RGBA_UBYTE\fP + Each entry is an RGBA +color tuple. Each component is valued in the range from 0 to 255 +and is stored as an 8\-bit integer. The buffer will always be allocated +on memory boundaries such that each color value can be treated as a +single 32\-bit integer. +.TP +\fBICET_IMAGE_COLOR_RGBA_FLOAT\fP + Each entry is an RGBA +color tuple. Each component is in the range from 0.0 to 1.0 and is +stored as a 32\-bit float. +.TP +\fBICET_IMAGE_COLOR_NONE\fP + No color values are stored in the +image. +.PP +Likewise, the format for \fIdepth_buffer\fP +is expected to be the same +as what is set with \fBicetSetDepthFormat\fP\&.The following formats and +their interpretations with respect to \fIdepth_buffer\fP +are as +follows. +.PP +.TP +\fBICET_IMAGE_DEPTH_FLOAT\fP + Each entry is in the range from +0.0 (near plane) to 1.0 (far plane) and is stored as a 32\-bit +float. +.TP +\fBICET_IMAGE_DEPTH_NONE\fP + No depth values are stored in the +image. +.PP +If the current format does not have a color or depth, then the respective +buffer argument should be set to NULL\&. +.PP +Care should be taken to make sure that the color and depth buffer formats +are consistent to the formats expected by \fBIceT \fP\&.Mismatched formats will +result in garbage images and possible memory faults. +.PP +Also note that when compositing with color blending +(\fBicetCompositeMode\fP +is set to +\fBICET_COMPOSITE_MODE_BLEND\fP), +the color buffer must be rendered +with a black background in order for the composite to complete +correctly. A colored background can later be added using the +\fIbackground_color\fP +as described below. +.PP +\fIvalid_pixels_viewport\fP +is an optional argument that makes it +possible to specify a subset of pixels that are valid. In parallel +rendering it is common for a single process to render geometry in only a +small portion of the image, and \fBIceT \fPcan take advantage of this +information. If the rendering system identifies such a region, it can be +specified with \fIvalid_pixels_viewport\fP\&. +.PP +Like all viewports in \fBIceT \fP,\fIvalid_pixels_viewport\fP +is an array +of 4 integers in the form $$.This +viewport is given in relation to the image passed in the +\fIcolor_buffer\fP +and \fIdepth_buffer\fP +arguments. Everything +outside of this rectangular region will be ignored. For example, if the +\fIvalid_pixels_viewport\fP +$<10, 20, 150, 100 >$is +given, then \fBicetCompositeImage\fP +will ignore all pixels in the +bottom 10 rows, the left 20 columns, anything above the +$160^th$ +(10+150) row, and anything to the right of the +$120^th$ +(20+100) column. +.PP +If \fIvalid_pixels_viewport\fP +is NULL, +then all pixels in the +input image are assumed to be valid. +.PP +\fIprojection_matrix\fP +and \fImodelview_matrix\fP +are optional +arguments that specify the projection that was used during rendering. +When applied to the geometry bounds information given with +\fBicetBoundingBox\fP +or \fBicetBoundingVertices\fP, +this provides +\fBIceT \fPwith further information on local image projections. If the given +matrices are not the same used in the rendering or the given bounds do +not contain the geometry, \fBIceT \fPmay clip the geometry in surprising ways. +If these arguments are set to NULL, +then geometry projection will +not be considered when determining what parts of images are valid. +.PP +The \fIbackground_color\fP +argument specifies the desired background +color for the image. It is given as an array of 4 floating point values +specifying, in order, the red, green, blue, and alpha channels of the +color in the range from 0.0 to 1.0\&. +.PP +When rendering using a depth buffer, the background color is used to fill +in empty regions of images. When rendering using color blending, the +background color is used to correct colored backgrounds. +.PP +As stated previously, color blended compositing only works correctly if +the images are rendered with a clear black background. Otherwise the +background color will be added multiple times by each process that +contains geometry in that pixel. If the +\fBICET_CORRECT_COLORED_BACKGROUND\fP +feature is enabled, this +background color is blended back into the final composited image. +.PP +.SH Return Value + +.PP +On each .igdisplay processdisplay +process (as defined by +\fBicetAddTile\fP), +\fBicetCompositeImage\fP +returns the fully +composited image in an \fBIceTImage\fP +object. The contents of the +image are undefined for any non\-display process. +.PP +If the \fBICET_COMPOSITE_ONE_BUFFER\fP +option is on and both a color +and depth buffer is specified with \fBicetSetColorFormat\fPand +\fBicetSetDepthFormat\fP,then the returned image might be missing the depth +buffer. The rational behind this option is that often both the color and +depth buffer is necessary in order to composite the color buffer, but the +composited depth buffer is not needed. In this case, the compositing +might save some time by not transferring depth information at the latter +stage of compositing. +.PP +The returned image uses memory buffers that will be reclaimed the next +time \fBIceT \fPrenders or composites a frame. Do not use this image after +the next call to \fBicetCompositeImage\fP +(unless you have changed the +\fBIceT \fPcontext). +.PP +.SH Errors + +.PP +.TP +\fBICET_INVALID_VALUE\fP + An argument is set to NULL +where data is required. +.TP +\fBICET_OUT_OF_MEMORY\fP + Not enough memory left to hold intermittent frame buffers and other +temporary data. +.PP +\fBicetDrawFrame\fP +may also indirectly raise an error if there is an +issue with the strategy or callback. +.PP +.SH Warnings + +.PP +.TP +\fBICET_INVALID_VALUE\fP + An argument to \fBicetCompositeImage\fP +is inconsistent with the +current \fBIceT \fPstate. +.PP +.SH Bugs + +.PP +The images provided must match the format expected by \fBIceT \fPor else +unpredictable behavior may occur. The images must also be carefully +rendered to follow the provided viewport and projections. Images that a +color blended must be rendered with a black background and rendered with +the correct alpha value. +.PP +If compositing with color blending on, the image returned may have a +black background instead of the \fIbackground_color\fP +requested. This +can be corrected by blending the returned image over the desired +background. This will be done for you if the +\fBICET_CORRECT_COLORED_BACKGROUND\fP +feature is enabled. +.PP +.SH Copyright + +Copyright (C)2014 Sandia Corporation +.PP +Under the terms of Contract DE\-AC04\-94AL85000 with Sandia Corporation, the +U.S. Government retains certain rights in this software. +.PP +This source code is released under the New BSD License. +.PP +.SH See Also + +.PP +\fIicetAddTile\fP(3), +\fIicetBoundingBox\fP(3), +\fIicetBoundingVertices\fP(3), +\fIicetDrawCallback\fP(3), +\fIicetDrawFrame\fP(3), +\fIicetSetColorFormat\fP(3), +\fIicetSetDepthFormat\fP(3), +\fIicetSingleImageStrategy\fP(3), +\fIicetStrategy\fP(3) +.PP +.\" NOTE: This file is generated, DO NOT EDIT. diff --git doc/man/man3/icetCompositeMode.3 doc/man/man3/icetCompositeMode.3 index 4a38471..0b15af6 100644 --- doc/man/man3/icetCompositeMode.3 +++ doc/man/man3/icetCompositeMode.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Fri Sep 26 14:31:02 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetCompositeMode" "3" "August 9, 2010" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetCompositeMode" "3" "September 26, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetCompositeMode \-\- set the type of operation used for compositing\fP @@ -91,11 +91,11 @@ None. \fBicetCompositeMode\fP will let you set a mode even if it is incompatible with other current settings. Some settings will be checked -during a call to \fBicetDrawFrame\fP\&. -For example, if the image -format (specified with \fBicetSetColorFormat\fPand \fBicetSetDepthFormat\fP)does -not support the composite mode picked, you will get an error during the -call to \fBicetDrawFrame\fP\&. +during a call to \fBicetDrawFrame\fP +or \fBicetCompositeImage\fP\&. +For example, if the image format (specified with \fBicetSetColorFormat\fPand +\fBicetSetDepthFormat\fP)does not support the composite mode picked, you will +get an error during the call to \fBicetDrawFrame\fP\&. .PP Other incompatibilities are also not checked. For example, if the composite mode is set to \fBICET_COMPOSITE_MODE_BLEND\fP, diff --git doc/man/man3/icetCompositeOrder.3 doc/man/man3/icetCompositeOrder.3 index b547396..1261570 100644 --- doc/man/man3/icetCompositeOrder.3 +++ doc/man/man3/icetCompositeOrder.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:52 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetCopyState.3 doc/man/man3/icetCopyState.3 index 6319602..22a3f82 100644 --- doc/man/man3/icetCopyState.3 +++ doc/man/man3/icetCopyState.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:52 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetCreateContext.3 doc/man/man3/icetCreateContext.3 index 0dfbfbc..c183dba 100644 --- doc/man/man3/icetCreateContext.3 +++ doc/man/man3/icetCreateContext.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:52 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetCreateMPICommunicator.3 doc/man/man3/icetCreateMPICommunicator.3 index b0c470b..3863b63 100644 --- doc/man/man3/icetCreateMPICommunicator.3 +++ doc/man/man3/icetCreateMPICommunicator.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:53 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetDataReplicationGroup.3 doc/man/man3/icetDataReplicationGroup.3 index b0b383b..ee664e1 100644 --- doc/man/man3/icetDataReplicationGroup.3 +++ doc/man/man3/icetDataReplicationGroup.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:53 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetDataReplicationGroupColor.3 doc/man/man3/icetDataReplicationGroupColor.3 index 444dc1d..b68306c 100644 --- doc/man/man3/icetDataReplicationGroupColor.3 +++ doc/man/man3/icetDataReplicationGroupColor.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:53 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetDestroyContext.3 doc/man/man3/icetDestroyContext.3 index c315131..2e9c938 100644 --- doc/man/man3/icetDestroyContext.3 +++ doc/man/man3/icetDestroyContext.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 17:14:18 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetDestroyContext" "3" "August 9, 2010" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetDestroyContext" "3" "September 22, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetDestroyContext \-\- delete a context.\fP @@ -22,7 +22,7 @@ .PP .TS H l l l . -void \fBicetDestroyContext\fP( \fBIceTContext\fP \fIcontext\fP ; +void \fBicetDestroyContext\fP( \fBIceTContext\fP \fIcontext\fP ); .TE .PP .SH Description diff --git doc/man/man3/icetDestroyMPICommunicator.3 doc/man/man3/icetDestroyMPICommunicator.3 index c08663b..a8132ba 100644 --- doc/man/man3/icetDestroyMPICommunicator.3 +++ doc/man/man3/icetDestroyMPICommunicator.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:53 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetDiagnostics.3 doc/man/man3/icetDiagnostics.3 index d5489ce..061c655 100644 --- doc/man/man3/icetDiagnostics.3 +++ doc/man/man3/icetDiagnostics.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:53 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetDisable.3 doc/man/man3/icetDisable.3 index 02b9560..869921a 100644 --- doc/man/man3/icetDisable.3 +++ doc/man/man3/icetDisable.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Fri Sep 26 14:31:02 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetEnable" "3" "July 11, 2011" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetEnable" "3" "September 26, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetEnable\fP,\fBicetDisable\fP\-\- enable/disable an \fBIceT \fPfeature. @@ -44,17 +44,18 @@ are: images partitions are always collected to display processes. When this option is turned off, the strategy has the option of leaving images partitioned among processes. Each process containing part of a tile\&'s -image will return the entire buffer from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP -in an \fBIceTImage\fP -object. However, only -certain pixels will be valid. The state variables -\fBICET_VALID_PIXELS_TILE\fP, +image will return the entire buffer from \fBicetDrawFrame\fP, +\fBicetGLDrawFrame\fP, +or \fBicetCompositeImage\fP +in an +\fBIceTImage\fP +object. However, only certain pixels will be valid. +The state variables \fBICET_VALID_PIXELS_TILE\fP, \fBICET_VALID_PIXELS_OFFSET\fP, -and \fBICET_VALID_PIXELS_NUM\fP -give which tile the pixels belong -to and what range of pixels are valid. +and +\fBICET_VALID_PIXELS_NUM\fP +give which tile the pixels belong to +and what range of pixels are valid. .TP \fBICET_COMPOSITE_ONE_BUFFER\fP Turn this option on when @@ -72,10 +73,11 @@ cause the color to be blended back into the resulting images. This flag is disabled by default. .TP \fBICET_FLOATING_VIEWPORT\fP - If enabled, the projection will -be shifted such that the geometry will be rendered in one shot whenever -possible, even if the geometry straddles up to four tiles. This flag -is enabled by default. + .igfloating viewport +If +enabled, the projection will be shifted such that the geometry will be +rendered in one shot whenever possible, even if the geometry straddles +up to four tiles. This flag is enabled by default. .TP \fBICET_INTERLACE_IMAGES\fP If enabled, pixels in images @@ -95,6 +97,26 @@ enabled, you should call \fBicetCompositeOrder\fP between each frame to update the image order as camera angles change. This flag is disabled by default. +.TP +\fBICET_RENDER_EMPTY_IMAGES\fP + If disabled, \fBIceT \fPwill never +invoke the drawing callback.igdrawing callback +if all geometry is +outside the clipping planes of the current projection. If enabled, +\fBIceT \fPwill still invoke the drawing callback \fIif\fP +the compositing +strategy has requested the tile. However, most compositing strategies +do not request images for all tiles. The floating viewport can also +consolidate up to four renderings into one. To ensure that the drawing +callback is invoked for all tiles on all processes, enable +\fBICET_RENDER_EMPTY_IMAGES\fP, +disable +\fBICET_FLOATING_VIEWPORT\fP, +and set the strategy (using +\fBicetStrategy\fP) +to \fBICET_STRATEGY_SEQUENTIAL\fP\&. +This flag +is disabled by default. .PP In addition, if you are using the \fbOpenGL \fPlayer (i.e., have called \fBicetGLInitialize\fP), diff --git doc/man/man3/icetDrawCallback.3 doc/man/man3/icetDrawCallback.3 index 4a001cb..3444dcb 100644 --- doc/man/man3/icetDrawCallback.3 +++ doc/man/man3/icetDrawCallback.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:53 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetDrawFrame.3 doc/man/man3/icetDrawFrame.3 index 6bf89e5..3e93ed7 100644 --- doc/man/man3/icetDrawFrame.3 +++ doc/man/man3/icetDrawFrame.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Fri Sep 26 14:31:02 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetDrawFrame" "3" "August 9, 2010" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetDrawFrame" "3" "September 22, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetDrawFrame \-\- renders and composites a frame\fP @@ -68,16 +68,32 @@ to \fBicetDrawFrame\fP and then use the version passed to the drawing callback. .PP +The \fIbackground_color\fP +argument specifies the desired background +color for the image. It is given as an array of 4 floating point values +specifying, in order, the red, green, blue, and alpha channels of the +color in the range from 0.0 to 1.0\&. +.PP +When rendering using a depth buffer, the background color is used to fill +in empty regions of images. When rendering using color blending, the +background color is changed to transparent black during rendering to +prevent the background from being blended multiple times from different +renderings. If the \fBICET_CORRECT_COLORED_BACKGROUND\fP +feature is +enabled, this background color is blended back into the final composited +image. +.PP .SH Return Value .PP On each .igdisplay processdisplay process (as defined by -\fBicetAddTile\fP, +\fBicetAddTile\fP), \fBicetDrawFrame\fP -returns an image of the fully -composited image. The contents of the image are undefined for any -non\-display process. +returns the fully composited +image in an \fBIceTImage\fP +object. The contents of the image are +undefined for any non\-display process. .PP If the \fBICET_COMPOSITE_ONE_BUFFER\fP option is on and both a color @@ -90,18 +106,17 @@ might save some time by not transferring depth information at the latter stage of compositing. .PP The returned image uses memory buffers that will be reclaimed the next -time \fBIceT \fPrenders a frame. Do not use this image after the next call to -\fBicetDrawFrame\fP -(unless you have changed the \fBIceT \fPcontext). +time \fBIceT \fPrenders or composites a frame. Do not use this image after +the next call to \fBicetDrawFrame\fP +(unless you have changed the \fBIceT \fP +context). .PP .SH Errors .PP .TP \fBICET_INVALID_OPERATION\fP - Raised if the \fBicetGLInitialize\fP -has not been called or if the -drawing callback has not been set. Also can be raised if + Raised if the drawing callback has not been set. Also can be raised if \fBicetDrawFrame\fP is called recursively, probably from within the drawing callback. @@ -128,7 +143,7 @@ requested. This can be corrected by blending the returned image over the desired background. This will be done for you if the \fBICET_CORRECT_COLORED_BACKGROUND\fP -is on. +feature is enabled. .PP .SH Copyright @@ -145,6 +160,7 @@ This source code is released under the New BSD License. \fIicetAddTile\fP(3), \fIicetBoundingBox\fP(3), \fIicetBoundingVertices\fP(3), +\fIicetCompositeImage\fP(3), \fIicetDrawCallback\fP(3), \fIicetGLDrawFrame\fP(3), \fIicetSingleImageStrategy\fP(3), diff --git doc/man/man3/icetEnable.3 doc/man/man3/icetEnable.3 index 02b9560..869921a 100644 --- doc/man/man3/icetEnable.3 +++ doc/man/man3/icetEnable.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Fri Sep 26 14:31:02 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetEnable" "3" "July 11, 2011" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetEnable" "3" "September 26, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetEnable\fP,\fBicetDisable\fP\-\- enable/disable an \fBIceT \fPfeature. @@ -44,17 +44,18 @@ are: images partitions are always collected to display processes. When this option is turned off, the strategy has the option of leaving images partitioned among processes. Each process containing part of a tile\&'s -image will return the entire buffer from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP -in an \fBIceTImage\fP -object. However, only -certain pixels will be valid. The state variables -\fBICET_VALID_PIXELS_TILE\fP, +image will return the entire buffer from \fBicetDrawFrame\fP, +\fBicetGLDrawFrame\fP, +or \fBicetCompositeImage\fP +in an +\fBIceTImage\fP +object. However, only certain pixels will be valid. +The state variables \fBICET_VALID_PIXELS_TILE\fP, \fBICET_VALID_PIXELS_OFFSET\fP, -and \fBICET_VALID_PIXELS_NUM\fP -give which tile the pixels belong -to and what range of pixels are valid. +and +\fBICET_VALID_PIXELS_NUM\fP +give which tile the pixels belong to +and what range of pixels are valid. .TP \fBICET_COMPOSITE_ONE_BUFFER\fP Turn this option on when @@ -72,10 +73,11 @@ cause the color to be blended back into the resulting images. This flag is disabled by default. .TP \fBICET_FLOATING_VIEWPORT\fP - If enabled, the projection will -be shifted such that the geometry will be rendered in one shot whenever -possible, even if the geometry straddles up to four tiles. This flag -is enabled by default. + .igfloating viewport +If +enabled, the projection will be shifted such that the geometry will be +rendered in one shot whenever possible, even if the geometry straddles +up to four tiles. This flag is enabled by default. .TP \fBICET_INTERLACE_IMAGES\fP If enabled, pixels in images @@ -95,6 +97,26 @@ enabled, you should call \fBicetCompositeOrder\fP between each frame to update the image order as camera angles change. This flag is disabled by default. +.TP +\fBICET_RENDER_EMPTY_IMAGES\fP + If disabled, \fBIceT \fPwill never +invoke the drawing callback.igdrawing callback +if all geometry is +outside the clipping planes of the current projection. If enabled, +\fBIceT \fPwill still invoke the drawing callback \fIif\fP +the compositing +strategy has requested the tile. However, most compositing strategies +do not request images for all tiles. The floating viewport can also +consolidate up to four renderings into one. To ensure that the drawing +callback is invoked for all tiles on all processes, enable +\fBICET_RENDER_EMPTY_IMAGES\fP, +disable +\fBICET_FLOATING_VIEWPORT\fP, +and set the strategy (using +\fBicetStrategy\fP) +to \fBICET_STRATEGY_SEQUENTIAL\fP\&. +This flag +is disabled by default. .PP In addition, if you are using the \fbOpenGL \fPlayer (i.e., have called \fBicetGLInitialize\fP), diff --git doc/man/man3/icetGLDrawCallback.3 doc/man/man3/icetGLDrawCallback.3 index e73b1d9..f4a57d5 100644 --- doc/man/man3/icetGLDrawCallback.3 +++ doc/man/man3/icetGLDrawCallback.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:53 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetGLDrawFrame.3 doc/man/man3/icetGLDrawFrame.3 index 5c98986..91e0e74 100644 --- doc/man/man3/icetGLDrawFrame.3 +++ doc/man/man3/icetGLDrawFrame.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Fri Sep 26 14:31:03 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetGLDrawFrame" "3" "September 20, 2010" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetGLDrawFrame" "3" "September 26, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetGLDrawFrame \-\- renders and composites a frame using \fbOpenGL \fP\fP @@ -86,8 +86,10 @@ tile. .PP .TP \fBICET_INVALID_OPERATION\fP - Raised if the drawing callback has not been set. Also can be raised if -\fBicetDrawFrame\fP + Raised if the \fBicetGLInitialize\fP +has not been called or if the +drawing callback has not been set. Also can be raised if +\fBicetGLDrawFrame\fP is called recursively, probably from within the drawing callback. .TP diff --git doc/man/man3/icetGLInitialize.3 doc/man/man3/icetGLInitialize.3 index ed28d1d..0f19a8d 100644 --- doc/man/man3/icetGLInitialize.3 +++ doc/man/man3/icetGLInitialize.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetGLIsInitialized.3 doc/man/man3/icetGLIsInitialized.3 index 99193de..6bfa2fb 100644 --- doc/man/man3/icetGLIsInitialized.3 +++ doc/man/man3/icetGLIsInitialized.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetGLSetReadBuffer.3 doc/man/man3/icetGLSetReadBuffer.3 index e483ad3..665ea11 100644 --- doc/man/man3/icetGLSetReadBuffer.3 +++ doc/man/man3/icetGLSetReadBuffer.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetGet.3 doc/man/man3/icetGet.3 index a419be2..7368ac5 100644 --- doc/man/man3/icetGet.3 +++ doc/man/man3/icetGet.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Fri Sep 26 14:33:26 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetGet" "3" "July 11, 2011" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetGet" "3" "September 26, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetGet \-\- get an \fBIceT \fPstate parameter\fP @@ -90,11 +90,12 @@ description of the associated state parameter. The color that \fBIceT \fPis currently assuming is the background color. It is an RGBA value that is stored as four floating point values. This value is set either to the last -value passed to \fBicetDrawFrame\fP, -the \fbOpenGL \fPbackground color if -\fBicetGLDrawFrame\fP -was called, or to black for color blending. -(The correct background color is restored later.) +value passed to \fBicetDrawFrame\fP +or \fBicetCompositeImage\fP, +the \fbOpenGL \fPbackground color if \fBicetGLDrawFrame\fP +was called, or +to black for color blending. (The correct background color is restored +later.) .TP \fBICET_BACKGROUND_COLOR_WORD\fP The same as @@ -106,40 +107,48 @@ rapidly fill the background of color buffers. \fBICET_BLEND_TIME\fP The total time, in seconds, spent in performing color blending of images during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a double. -An alias for this value is \fBICET_COMPARE_TIME\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. An alias for this value +is \fBICET_COMPARE_TIME\fP\&. .TP \fBICET_BUFFER_READ_TIME\fP The total time, in seconds, spent copying buffer data and reading from \fbOpenGL \fPbuffers during the last -call to \fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a -double. +call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. .TP \fBICET_BUFFER_WRITE_TIME\fP The total time, in seconds, spent writing to \fbOpenGL \fPbuffers during the last call to \fBicetGLDrawFrame\fP\&. Always set to 0.0 after a call to -\fBicetDrawFrame\fP\&. -Stored as a double. +\fBicetDrawFrame\fP +or \fBicetCompositeImage\fP\&. +Stored as a +double. .TP \fBICET_BYTES_SENT\fP The total number of bytes sent by the calling process for transferring image data during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as an -integer. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as an integer. .TP \fBICET_COLLECT_TIME\fP The total time spent in collecting image fragments to display processes during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. .TP \fBICET_COLOR_FORMAT\fP The color format of images to be @@ -153,10 +162,12 @@ particular image. \fBICET_COMPARE_TIME\fP The total time, in seconds, spent in performing Z comparisons of images during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a double. -An alias for this value is \fBICET_BLEND_TIME\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. An alias for this value +is \fBICET_BLEND_TIME\fP\&. .TP \fBICET_COMPOSITE_MODE\fP The composite mode set by @@ -178,22 +189,24 @@ image generated by process j\&. .TP \fBICET_COMPOSITE_TIME\fP The total time, in seconds, spent in -compositing during the last call to \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Equal to $\fBICET_TOTAL_DRAW_TIME\fP -\- -\fBICET_RENDER_TIME\fP -\- \fBICET_BUFFER_READ_TIME\fP +compositing during the last call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Equal to +$\fBICET_TOTAL_DRAW_TIME\fP +\- \fBICET_RENDER_TIME\fP \- -\fBICET_BUFFER_WRITE_TIME\fP$. +\fBICET_BUFFER_READ_TIME\fP +\- \fBICET_BUFFER_WRITE_TIME\fP$. Stored as a double. .TP \fBICET_COMPRESS_TIME\fP The total time, in seconds, spent in compressing image data using active pixel encoding during the last call -to \fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. +to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. Stored as a double. .TP \fBICET_DATA_REPLICATION_GROUP\fP @@ -240,10 +253,11 @@ function, as set by \fBicetDrawCallback\fP\&. .TP \fBICET_FRAME_COUNT\fP The number of times -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP -has been called for -the current context. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP +has been called for the current context. .TP \fBICET_GEOMETRY_BOUNDS\fP An array of vertices whose convex @@ -324,6 +338,8 @@ object associated with the current context. the drawing callback during the last call to \fBicetDrawFrame\fP or \fBicetGLDrawFrame\fP\&. +Always set to 0.0 after a call to +\fBicetCompositeImage\fP\&. Stored as a double. .TP \fBICET_SINGLE_IMAGE_STRATEGY\fP @@ -377,39 +393,41 @@ viewports are listed in the same order as the tiles were defined with .TP \fBICET_TOTAL_DRAW_TIME\fP Time spent in the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -This includes all -the time to render, read back, compress, and composite images. Stored -as a double. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +This includes all the time to render, read +back, compress, and composite images. Stored as a double. .TP \fBICET_VALID_PIXELS_NUM\fP In conjunction with \fBICET_VALID_PIXELS_OFFSET\fP, gives the range of valid pixels -for the last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Given the arrays of pixels returned with the -\fBicetImageGetColor\fP -and \fBicetImageGetDepth\fP -functions, the -valid pixels start at the pixel indexed by -\fBICET_VALID_PIXELS_OFFSET\fP +for the last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Given the +arrays of pixels returned with the \fBicetImageGetColor\fP +and +\fBicetImageGetDepth\fP +functions, the valid pixels start at the +pixel indexed by \fBICET_VALID_PIXELS_OFFSET\fP and continue for \fBICET_VALID_PIXELS_NUM\fP\&. The tile to which these pixels belong are captured in the \fBICET_VALID_PIXELS_TILE\fP state -variable. If the last call to \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP -did not return pixels for the local process, -\fBICET_VALID_PIXELS_NUM\fP -is set to 0\&. This state variable is -only useful when \fBICET_COLLECT_IMAGES\fP -is off. If on, it can -be assumed that all display processes contain all pixels in the image +variable. If the last call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP +did not return +pixels for the local process, \fBICET_VALID_PIXELS_NUM\fP +is set +to 0\&. This state variable is only useful when +\fBICET_COLLECT_IMAGES\fP +is off. If on, it can be assumed that +all display processes contain all pixels in the image (\fBICET_VALID_PIXELS_NUM\fP is the number of pixels in the image), and all other processes have no pixel data. @@ -418,15 +436,15 @@ image), and all other processes have no pixel data. In conjunction with \fBICET_VALID_PIXELS_NUM\fP, gives the range of valid pixels for -the last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Given the arrays of pixels returned with the -\fBicetImageGetColor\fP -and \fBicetImageGetDepth\fP -functions, the -valid pixels start at the pixel indexed by -\fBICET_VALID_PIXELS_OFFSET\fP +the last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Given the +arrays of pixels returned with the \fBicetImageGetColor\fP +and +\fBicetImageGetDepth\fP +functions, the valid pixels start at the +pixel indexed by \fBICET_VALID_PIXELS_OFFSET\fP and continue for \fBICET_VALID_PIXELS_NUM\fP\&. The tile to which these pixels @@ -442,11 +460,13 @@ have no pixel data. .TP \fBICET_VALID_PIXELS_TILE\fP Gives the tile for which the -last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP -contains pixels. Each process has its own -value. If the last call to \fBicetDrawFrame\fP +last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP +contains pixels. +Each process has its own value. If the last call to +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, or \fBicetGLDrawFrame\fP did not return pixels for the local process, diff --git doc/man/man3/icetGetBooleanv.3 doc/man/man3/icetGetBooleanv.3 index a419be2..7368ac5 100644 --- doc/man/man3/icetGetBooleanv.3 +++ doc/man/man3/icetGetBooleanv.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Fri Sep 26 14:33:26 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetGet" "3" "July 11, 2011" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetGet" "3" "September 26, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetGet \-\- get an \fBIceT \fPstate parameter\fP @@ -90,11 +90,12 @@ description of the associated state parameter. The color that \fBIceT \fPis currently assuming is the background color. It is an RGBA value that is stored as four floating point values. This value is set either to the last -value passed to \fBicetDrawFrame\fP, -the \fbOpenGL \fPbackground color if -\fBicetGLDrawFrame\fP -was called, or to black for color blending. -(The correct background color is restored later.) +value passed to \fBicetDrawFrame\fP +or \fBicetCompositeImage\fP, +the \fbOpenGL \fPbackground color if \fBicetGLDrawFrame\fP +was called, or +to black for color blending. (The correct background color is restored +later.) .TP \fBICET_BACKGROUND_COLOR_WORD\fP The same as @@ -106,40 +107,48 @@ rapidly fill the background of color buffers. \fBICET_BLEND_TIME\fP The total time, in seconds, spent in performing color blending of images during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a double. -An alias for this value is \fBICET_COMPARE_TIME\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. An alias for this value +is \fBICET_COMPARE_TIME\fP\&. .TP \fBICET_BUFFER_READ_TIME\fP The total time, in seconds, spent copying buffer data and reading from \fbOpenGL \fPbuffers during the last -call to \fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a -double. +call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. .TP \fBICET_BUFFER_WRITE_TIME\fP The total time, in seconds, spent writing to \fbOpenGL \fPbuffers during the last call to \fBicetGLDrawFrame\fP\&. Always set to 0.0 after a call to -\fBicetDrawFrame\fP\&. -Stored as a double. +\fBicetDrawFrame\fP +or \fBicetCompositeImage\fP\&. +Stored as a +double. .TP \fBICET_BYTES_SENT\fP The total number of bytes sent by the calling process for transferring image data during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as an -integer. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as an integer. .TP \fBICET_COLLECT_TIME\fP The total time spent in collecting image fragments to display processes during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. .TP \fBICET_COLOR_FORMAT\fP The color format of images to be @@ -153,10 +162,12 @@ particular image. \fBICET_COMPARE_TIME\fP The total time, in seconds, spent in performing Z comparisons of images during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a double. -An alias for this value is \fBICET_BLEND_TIME\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. An alias for this value +is \fBICET_BLEND_TIME\fP\&. .TP \fBICET_COMPOSITE_MODE\fP The composite mode set by @@ -178,22 +189,24 @@ image generated by process j\&. .TP \fBICET_COMPOSITE_TIME\fP The total time, in seconds, spent in -compositing during the last call to \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Equal to $\fBICET_TOTAL_DRAW_TIME\fP -\- -\fBICET_RENDER_TIME\fP -\- \fBICET_BUFFER_READ_TIME\fP +compositing during the last call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Equal to +$\fBICET_TOTAL_DRAW_TIME\fP +\- \fBICET_RENDER_TIME\fP \- -\fBICET_BUFFER_WRITE_TIME\fP$. +\fBICET_BUFFER_READ_TIME\fP +\- \fBICET_BUFFER_WRITE_TIME\fP$. Stored as a double. .TP \fBICET_COMPRESS_TIME\fP The total time, in seconds, spent in compressing image data using active pixel encoding during the last call -to \fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. +to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. Stored as a double. .TP \fBICET_DATA_REPLICATION_GROUP\fP @@ -240,10 +253,11 @@ function, as set by \fBicetDrawCallback\fP\&. .TP \fBICET_FRAME_COUNT\fP The number of times -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP -has been called for -the current context. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP +has been called for the current context. .TP \fBICET_GEOMETRY_BOUNDS\fP An array of vertices whose convex @@ -324,6 +338,8 @@ object associated with the current context. the drawing callback during the last call to \fBicetDrawFrame\fP or \fBicetGLDrawFrame\fP\&. +Always set to 0.0 after a call to +\fBicetCompositeImage\fP\&. Stored as a double. .TP \fBICET_SINGLE_IMAGE_STRATEGY\fP @@ -377,39 +393,41 @@ viewports are listed in the same order as the tiles were defined with .TP \fBICET_TOTAL_DRAW_TIME\fP Time spent in the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -This includes all -the time to render, read back, compress, and composite images. Stored -as a double. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +This includes all the time to render, read +back, compress, and composite images. Stored as a double. .TP \fBICET_VALID_PIXELS_NUM\fP In conjunction with \fBICET_VALID_PIXELS_OFFSET\fP, gives the range of valid pixels -for the last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Given the arrays of pixels returned with the -\fBicetImageGetColor\fP -and \fBicetImageGetDepth\fP -functions, the -valid pixels start at the pixel indexed by -\fBICET_VALID_PIXELS_OFFSET\fP +for the last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Given the +arrays of pixels returned with the \fBicetImageGetColor\fP +and +\fBicetImageGetDepth\fP +functions, the valid pixels start at the +pixel indexed by \fBICET_VALID_PIXELS_OFFSET\fP and continue for \fBICET_VALID_PIXELS_NUM\fP\&. The tile to which these pixels belong are captured in the \fBICET_VALID_PIXELS_TILE\fP state -variable. If the last call to \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP -did not return pixels for the local process, -\fBICET_VALID_PIXELS_NUM\fP -is set to 0\&. This state variable is -only useful when \fBICET_COLLECT_IMAGES\fP -is off. If on, it can -be assumed that all display processes contain all pixels in the image +variable. If the last call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP +did not return +pixels for the local process, \fBICET_VALID_PIXELS_NUM\fP +is set +to 0\&. This state variable is only useful when +\fBICET_COLLECT_IMAGES\fP +is off. If on, it can be assumed that +all display processes contain all pixels in the image (\fBICET_VALID_PIXELS_NUM\fP is the number of pixels in the image), and all other processes have no pixel data. @@ -418,15 +436,15 @@ image), and all other processes have no pixel data. In conjunction with \fBICET_VALID_PIXELS_NUM\fP, gives the range of valid pixels for -the last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Given the arrays of pixels returned with the -\fBicetImageGetColor\fP -and \fBicetImageGetDepth\fP -functions, the -valid pixels start at the pixel indexed by -\fBICET_VALID_PIXELS_OFFSET\fP +the last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Given the +arrays of pixels returned with the \fBicetImageGetColor\fP +and +\fBicetImageGetDepth\fP +functions, the valid pixels start at the +pixel indexed by \fBICET_VALID_PIXELS_OFFSET\fP and continue for \fBICET_VALID_PIXELS_NUM\fP\&. The tile to which these pixels @@ -442,11 +460,13 @@ have no pixel data. .TP \fBICET_VALID_PIXELS_TILE\fP Gives the tile for which the -last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP -contains pixels. Each process has its own -value. If the last call to \fBicetDrawFrame\fP +last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP +contains pixels. +Each process has its own value. If the last call to +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, or \fBicetGLDrawFrame\fP did not return pixels for the local process, diff --git doc/man/man3/icetGetContext.3 doc/man/man3/icetGetContext.3 index 1b7654a..32405e6 100644 --- doc/man/man3/icetGetContext.3 +++ doc/man/man3/icetGetContext.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:53 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetGetDoublev.3 doc/man/man3/icetGetDoublev.3 index a419be2..7368ac5 100644 --- doc/man/man3/icetGetDoublev.3 +++ doc/man/man3/icetGetDoublev.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Fri Sep 26 14:33:26 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetGet" "3" "July 11, 2011" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetGet" "3" "September 26, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetGet \-\- get an \fBIceT \fPstate parameter\fP @@ -90,11 +90,12 @@ description of the associated state parameter. The color that \fBIceT \fPis currently assuming is the background color. It is an RGBA value that is stored as four floating point values. This value is set either to the last -value passed to \fBicetDrawFrame\fP, -the \fbOpenGL \fPbackground color if -\fBicetGLDrawFrame\fP -was called, or to black for color blending. -(The correct background color is restored later.) +value passed to \fBicetDrawFrame\fP +or \fBicetCompositeImage\fP, +the \fbOpenGL \fPbackground color if \fBicetGLDrawFrame\fP +was called, or +to black for color blending. (The correct background color is restored +later.) .TP \fBICET_BACKGROUND_COLOR_WORD\fP The same as @@ -106,40 +107,48 @@ rapidly fill the background of color buffers. \fBICET_BLEND_TIME\fP The total time, in seconds, spent in performing color blending of images during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a double. -An alias for this value is \fBICET_COMPARE_TIME\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. An alias for this value +is \fBICET_COMPARE_TIME\fP\&. .TP \fBICET_BUFFER_READ_TIME\fP The total time, in seconds, spent copying buffer data and reading from \fbOpenGL \fPbuffers during the last -call to \fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a -double. +call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. .TP \fBICET_BUFFER_WRITE_TIME\fP The total time, in seconds, spent writing to \fbOpenGL \fPbuffers during the last call to \fBicetGLDrawFrame\fP\&. Always set to 0.0 after a call to -\fBicetDrawFrame\fP\&. -Stored as a double. +\fBicetDrawFrame\fP +or \fBicetCompositeImage\fP\&. +Stored as a +double. .TP \fBICET_BYTES_SENT\fP The total number of bytes sent by the calling process for transferring image data during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as an -integer. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as an integer. .TP \fBICET_COLLECT_TIME\fP The total time spent in collecting image fragments to display processes during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. .TP \fBICET_COLOR_FORMAT\fP The color format of images to be @@ -153,10 +162,12 @@ particular image. \fBICET_COMPARE_TIME\fP The total time, in seconds, spent in performing Z comparisons of images during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a double. -An alias for this value is \fBICET_BLEND_TIME\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. An alias for this value +is \fBICET_BLEND_TIME\fP\&. .TP \fBICET_COMPOSITE_MODE\fP The composite mode set by @@ -178,22 +189,24 @@ image generated by process j\&. .TP \fBICET_COMPOSITE_TIME\fP The total time, in seconds, spent in -compositing during the last call to \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Equal to $\fBICET_TOTAL_DRAW_TIME\fP -\- -\fBICET_RENDER_TIME\fP -\- \fBICET_BUFFER_READ_TIME\fP +compositing during the last call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Equal to +$\fBICET_TOTAL_DRAW_TIME\fP +\- \fBICET_RENDER_TIME\fP \- -\fBICET_BUFFER_WRITE_TIME\fP$. +\fBICET_BUFFER_READ_TIME\fP +\- \fBICET_BUFFER_WRITE_TIME\fP$. Stored as a double. .TP \fBICET_COMPRESS_TIME\fP The total time, in seconds, spent in compressing image data using active pixel encoding during the last call -to \fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. +to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. Stored as a double. .TP \fBICET_DATA_REPLICATION_GROUP\fP @@ -240,10 +253,11 @@ function, as set by \fBicetDrawCallback\fP\&. .TP \fBICET_FRAME_COUNT\fP The number of times -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP -has been called for -the current context. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP +has been called for the current context. .TP \fBICET_GEOMETRY_BOUNDS\fP An array of vertices whose convex @@ -324,6 +338,8 @@ object associated with the current context. the drawing callback during the last call to \fBicetDrawFrame\fP or \fBicetGLDrawFrame\fP\&. +Always set to 0.0 after a call to +\fBicetCompositeImage\fP\&. Stored as a double. .TP \fBICET_SINGLE_IMAGE_STRATEGY\fP @@ -377,39 +393,41 @@ viewports are listed in the same order as the tiles were defined with .TP \fBICET_TOTAL_DRAW_TIME\fP Time spent in the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -This includes all -the time to render, read back, compress, and composite images. Stored -as a double. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +This includes all the time to render, read +back, compress, and composite images. Stored as a double. .TP \fBICET_VALID_PIXELS_NUM\fP In conjunction with \fBICET_VALID_PIXELS_OFFSET\fP, gives the range of valid pixels -for the last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Given the arrays of pixels returned with the -\fBicetImageGetColor\fP -and \fBicetImageGetDepth\fP -functions, the -valid pixels start at the pixel indexed by -\fBICET_VALID_PIXELS_OFFSET\fP +for the last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Given the +arrays of pixels returned with the \fBicetImageGetColor\fP +and +\fBicetImageGetDepth\fP +functions, the valid pixels start at the +pixel indexed by \fBICET_VALID_PIXELS_OFFSET\fP and continue for \fBICET_VALID_PIXELS_NUM\fP\&. The tile to which these pixels belong are captured in the \fBICET_VALID_PIXELS_TILE\fP state -variable. If the last call to \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP -did not return pixels for the local process, -\fBICET_VALID_PIXELS_NUM\fP -is set to 0\&. This state variable is -only useful when \fBICET_COLLECT_IMAGES\fP -is off. If on, it can -be assumed that all display processes contain all pixels in the image +variable. If the last call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP +did not return +pixels for the local process, \fBICET_VALID_PIXELS_NUM\fP +is set +to 0\&. This state variable is only useful when +\fBICET_COLLECT_IMAGES\fP +is off. If on, it can be assumed that +all display processes contain all pixels in the image (\fBICET_VALID_PIXELS_NUM\fP is the number of pixels in the image), and all other processes have no pixel data. @@ -418,15 +436,15 @@ image), and all other processes have no pixel data. In conjunction with \fBICET_VALID_PIXELS_NUM\fP, gives the range of valid pixels for -the last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Given the arrays of pixels returned with the -\fBicetImageGetColor\fP -and \fBicetImageGetDepth\fP -functions, the -valid pixels start at the pixel indexed by -\fBICET_VALID_PIXELS_OFFSET\fP +the last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Given the +arrays of pixels returned with the \fBicetImageGetColor\fP +and +\fBicetImageGetDepth\fP +functions, the valid pixels start at the +pixel indexed by \fBICET_VALID_PIXELS_OFFSET\fP and continue for \fBICET_VALID_PIXELS_NUM\fP\&. The tile to which these pixels @@ -442,11 +460,13 @@ have no pixel data. .TP \fBICET_VALID_PIXELS_TILE\fP Gives the tile for which the -last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP -contains pixels. Each process has its own -value. If the last call to \fBicetDrawFrame\fP +last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP +contains pixels. +Each process has its own value. If the last call to +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, or \fBicetGLDrawFrame\fP did not return pixels for the local process, diff --git doc/man/man3/icetGetError.3 doc/man/man3/icetGetError.3 index 96c14be..53a622d 100644 --- doc/man/man3/icetGetError.3 +++ doc/man/man3/icetGetError.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:53 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetGetFloatv.3 doc/man/man3/icetGetFloatv.3 index a419be2..7368ac5 100644 --- doc/man/man3/icetGetFloatv.3 +++ doc/man/man3/icetGetFloatv.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Fri Sep 26 14:33:26 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetGet" "3" "July 11, 2011" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetGet" "3" "September 26, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetGet \-\- get an \fBIceT \fPstate parameter\fP @@ -90,11 +90,12 @@ description of the associated state parameter. The color that \fBIceT \fPis currently assuming is the background color. It is an RGBA value that is stored as four floating point values. This value is set either to the last -value passed to \fBicetDrawFrame\fP, -the \fbOpenGL \fPbackground color if -\fBicetGLDrawFrame\fP -was called, or to black for color blending. -(The correct background color is restored later.) +value passed to \fBicetDrawFrame\fP +or \fBicetCompositeImage\fP, +the \fbOpenGL \fPbackground color if \fBicetGLDrawFrame\fP +was called, or +to black for color blending. (The correct background color is restored +later.) .TP \fBICET_BACKGROUND_COLOR_WORD\fP The same as @@ -106,40 +107,48 @@ rapidly fill the background of color buffers. \fBICET_BLEND_TIME\fP The total time, in seconds, spent in performing color blending of images during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a double. -An alias for this value is \fBICET_COMPARE_TIME\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. An alias for this value +is \fBICET_COMPARE_TIME\fP\&. .TP \fBICET_BUFFER_READ_TIME\fP The total time, in seconds, spent copying buffer data and reading from \fbOpenGL \fPbuffers during the last -call to \fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a -double. +call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. .TP \fBICET_BUFFER_WRITE_TIME\fP The total time, in seconds, spent writing to \fbOpenGL \fPbuffers during the last call to \fBicetGLDrawFrame\fP\&. Always set to 0.0 after a call to -\fBicetDrawFrame\fP\&. -Stored as a double. +\fBicetDrawFrame\fP +or \fBicetCompositeImage\fP\&. +Stored as a +double. .TP \fBICET_BYTES_SENT\fP The total number of bytes sent by the calling process for transferring image data during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as an -integer. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as an integer. .TP \fBICET_COLLECT_TIME\fP The total time spent in collecting image fragments to display processes during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. .TP \fBICET_COLOR_FORMAT\fP The color format of images to be @@ -153,10 +162,12 @@ particular image. \fBICET_COMPARE_TIME\fP The total time, in seconds, spent in performing Z comparisons of images during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a double. -An alias for this value is \fBICET_BLEND_TIME\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. An alias for this value +is \fBICET_BLEND_TIME\fP\&. .TP \fBICET_COMPOSITE_MODE\fP The composite mode set by @@ -178,22 +189,24 @@ image generated by process j\&. .TP \fBICET_COMPOSITE_TIME\fP The total time, in seconds, spent in -compositing during the last call to \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Equal to $\fBICET_TOTAL_DRAW_TIME\fP -\- -\fBICET_RENDER_TIME\fP -\- \fBICET_BUFFER_READ_TIME\fP +compositing during the last call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Equal to +$\fBICET_TOTAL_DRAW_TIME\fP +\- \fBICET_RENDER_TIME\fP \- -\fBICET_BUFFER_WRITE_TIME\fP$. +\fBICET_BUFFER_READ_TIME\fP +\- \fBICET_BUFFER_WRITE_TIME\fP$. Stored as a double. .TP \fBICET_COMPRESS_TIME\fP The total time, in seconds, spent in compressing image data using active pixel encoding during the last call -to \fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. +to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. Stored as a double. .TP \fBICET_DATA_REPLICATION_GROUP\fP @@ -240,10 +253,11 @@ function, as set by \fBicetDrawCallback\fP\&. .TP \fBICET_FRAME_COUNT\fP The number of times -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP -has been called for -the current context. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP +has been called for the current context. .TP \fBICET_GEOMETRY_BOUNDS\fP An array of vertices whose convex @@ -324,6 +338,8 @@ object associated with the current context. the drawing callback during the last call to \fBicetDrawFrame\fP or \fBicetGLDrawFrame\fP\&. +Always set to 0.0 after a call to +\fBicetCompositeImage\fP\&. Stored as a double. .TP \fBICET_SINGLE_IMAGE_STRATEGY\fP @@ -377,39 +393,41 @@ viewports are listed in the same order as the tiles were defined with .TP \fBICET_TOTAL_DRAW_TIME\fP Time spent in the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -This includes all -the time to render, read back, compress, and composite images. Stored -as a double. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +This includes all the time to render, read +back, compress, and composite images. Stored as a double. .TP \fBICET_VALID_PIXELS_NUM\fP In conjunction with \fBICET_VALID_PIXELS_OFFSET\fP, gives the range of valid pixels -for the last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Given the arrays of pixels returned with the -\fBicetImageGetColor\fP -and \fBicetImageGetDepth\fP -functions, the -valid pixels start at the pixel indexed by -\fBICET_VALID_PIXELS_OFFSET\fP +for the last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Given the +arrays of pixels returned with the \fBicetImageGetColor\fP +and +\fBicetImageGetDepth\fP +functions, the valid pixels start at the +pixel indexed by \fBICET_VALID_PIXELS_OFFSET\fP and continue for \fBICET_VALID_PIXELS_NUM\fP\&. The tile to which these pixels belong are captured in the \fBICET_VALID_PIXELS_TILE\fP state -variable. If the last call to \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP -did not return pixels for the local process, -\fBICET_VALID_PIXELS_NUM\fP -is set to 0\&. This state variable is -only useful when \fBICET_COLLECT_IMAGES\fP -is off. If on, it can -be assumed that all display processes contain all pixels in the image +variable. If the last call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP +did not return +pixels for the local process, \fBICET_VALID_PIXELS_NUM\fP +is set +to 0\&. This state variable is only useful when +\fBICET_COLLECT_IMAGES\fP +is off. If on, it can be assumed that +all display processes contain all pixels in the image (\fBICET_VALID_PIXELS_NUM\fP is the number of pixels in the image), and all other processes have no pixel data. @@ -418,15 +436,15 @@ image), and all other processes have no pixel data. In conjunction with \fBICET_VALID_PIXELS_NUM\fP, gives the range of valid pixels for -the last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Given the arrays of pixels returned with the -\fBicetImageGetColor\fP -and \fBicetImageGetDepth\fP -functions, the -valid pixels start at the pixel indexed by -\fBICET_VALID_PIXELS_OFFSET\fP +the last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Given the +arrays of pixels returned with the \fBicetImageGetColor\fP +and +\fBicetImageGetDepth\fP +functions, the valid pixels start at the +pixel indexed by \fBICET_VALID_PIXELS_OFFSET\fP and continue for \fBICET_VALID_PIXELS_NUM\fP\&. The tile to which these pixels @@ -442,11 +460,13 @@ have no pixel data. .TP \fBICET_VALID_PIXELS_TILE\fP Gives the tile for which the -last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP -contains pixels. Each process has its own -value. If the last call to \fBicetDrawFrame\fP +last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP +contains pixels. +Each process has its own value. If the last call to +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, or \fBicetGLDrawFrame\fP did not return pixels for the local process, diff --git doc/man/man3/icetGetIntegerv.3 doc/man/man3/icetGetIntegerv.3 index a419be2..7368ac5 100644 --- doc/man/man3/icetGetIntegerv.3 +++ doc/man/man3/icetGetIntegerv.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Fri Sep 26 14:33:26 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetGet" "3" "July 11, 2011" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetGet" "3" "September 26, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetGet \-\- get an \fBIceT \fPstate parameter\fP @@ -90,11 +90,12 @@ description of the associated state parameter. The color that \fBIceT \fPis currently assuming is the background color. It is an RGBA value that is stored as four floating point values. This value is set either to the last -value passed to \fBicetDrawFrame\fP, -the \fbOpenGL \fPbackground color if -\fBicetGLDrawFrame\fP -was called, or to black for color blending. -(The correct background color is restored later.) +value passed to \fBicetDrawFrame\fP +or \fBicetCompositeImage\fP, +the \fbOpenGL \fPbackground color if \fBicetGLDrawFrame\fP +was called, or +to black for color blending. (The correct background color is restored +later.) .TP \fBICET_BACKGROUND_COLOR_WORD\fP The same as @@ -106,40 +107,48 @@ rapidly fill the background of color buffers. \fBICET_BLEND_TIME\fP The total time, in seconds, spent in performing color blending of images during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a double. -An alias for this value is \fBICET_COMPARE_TIME\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. An alias for this value +is \fBICET_COMPARE_TIME\fP\&. .TP \fBICET_BUFFER_READ_TIME\fP The total time, in seconds, spent copying buffer data and reading from \fbOpenGL \fPbuffers during the last -call to \fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a -double. +call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. .TP \fBICET_BUFFER_WRITE_TIME\fP The total time, in seconds, spent writing to \fbOpenGL \fPbuffers during the last call to \fBicetGLDrawFrame\fP\&. Always set to 0.0 after a call to -\fBicetDrawFrame\fP\&. -Stored as a double. +\fBicetDrawFrame\fP +or \fBicetCompositeImage\fP\&. +Stored as a +double. .TP \fBICET_BYTES_SENT\fP The total number of bytes sent by the calling process for transferring image data during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as an -integer. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as an integer. .TP \fBICET_COLLECT_TIME\fP The total time spent in collecting image fragments to display processes during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. .TP \fBICET_COLOR_FORMAT\fP The color format of images to be @@ -153,10 +162,12 @@ particular image. \fBICET_COMPARE_TIME\fP The total time, in seconds, spent in performing Z comparisons of images during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a double. -An alias for this value is \fBICET_BLEND_TIME\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. An alias for this value +is \fBICET_BLEND_TIME\fP\&. .TP \fBICET_COMPOSITE_MODE\fP The composite mode set by @@ -178,22 +189,24 @@ image generated by process j\&. .TP \fBICET_COMPOSITE_TIME\fP The total time, in seconds, spent in -compositing during the last call to \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Equal to $\fBICET_TOTAL_DRAW_TIME\fP -\- -\fBICET_RENDER_TIME\fP -\- \fBICET_BUFFER_READ_TIME\fP +compositing during the last call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Equal to +$\fBICET_TOTAL_DRAW_TIME\fP +\- \fBICET_RENDER_TIME\fP \- -\fBICET_BUFFER_WRITE_TIME\fP$. +\fBICET_BUFFER_READ_TIME\fP +\- \fBICET_BUFFER_WRITE_TIME\fP$. Stored as a double. .TP \fBICET_COMPRESS_TIME\fP The total time, in seconds, spent in compressing image data using active pixel encoding during the last call -to \fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. +to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. Stored as a double. .TP \fBICET_DATA_REPLICATION_GROUP\fP @@ -240,10 +253,11 @@ function, as set by \fBicetDrawCallback\fP\&. .TP \fBICET_FRAME_COUNT\fP The number of times -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP -has been called for -the current context. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP +has been called for the current context. .TP \fBICET_GEOMETRY_BOUNDS\fP An array of vertices whose convex @@ -324,6 +338,8 @@ object associated with the current context. the drawing callback during the last call to \fBicetDrawFrame\fP or \fBicetGLDrawFrame\fP\&. +Always set to 0.0 after a call to +\fBicetCompositeImage\fP\&. Stored as a double. .TP \fBICET_SINGLE_IMAGE_STRATEGY\fP @@ -377,39 +393,41 @@ viewports are listed in the same order as the tiles were defined with .TP \fBICET_TOTAL_DRAW_TIME\fP Time spent in the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -This includes all -the time to render, read back, compress, and composite images. Stored -as a double. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +This includes all the time to render, read +back, compress, and composite images. Stored as a double. .TP \fBICET_VALID_PIXELS_NUM\fP In conjunction with \fBICET_VALID_PIXELS_OFFSET\fP, gives the range of valid pixels -for the last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Given the arrays of pixels returned with the -\fBicetImageGetColor\fP -and \fBicetImageGetDepth\fP -functions, the -valid pixels start at the pixel indexed by -\fBICET_VALID_PIXELS_OFFSET\fP +for the last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Given the +arrays of pixels returned with the \fBicetImageGetColor\fP +and +\fBicetImageGetDepth\fP +functions, the valid pixels start at the +pixel indexed by \fBICET_VALID_PIXELS_OFFSET\fP and continue for \fBICET_VALID_PIXELS_NUM\fP\&. The tile to which these pixels belong are captured in the \fBICET_VALID_PIXELS_TILE\fP state -variable. If the last call to \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP -did not return pixels for the local process, -\fBICET_VALID_PIXELS_NUM\fP -is set to 0\&. This state variable is -only useful when \fBICET_COLLECT_IMAGES\fP -is off. If on, it can -be assumed that all display processes contain all pixels in the image +variable. If the last call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP +did not return +pixels for the local process, \fBICET_VALID_PIXELS_NUM\fP +is set +to 0\&. This state variable is only useful when +\fBICET_COLLECT_IMAGES\fP +is off. If on, it can be assumed that +all display processes contain all pixels in the image (\fBICET_VALID_PIXELS_NUM\fP is the number of pixels in the image), and all other processes have no pixel data. @@ -418,15 +436,15 @@ image), and all other processes have no pixel data. In conjunction with \fBICET_VALID_PIXELS_NUM\fP, gives the range of valid pixels for -the last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Given the arrays of pixels returned with the -\fBicetImageGetColor\fP -and \fBicetImageGetDepth\fP -functions, the -valid pixels start at the pixel indexed by -\fBICET_VALID_PIXELS_OFFSET\fP +the last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Given the +arrays of pixels returned with the \fBicetImageGetColor\fP +and +\fBicetImageGetDepth\fP +functions, the valid pixels start at the +pixel indexed by \fBICET_VALID_PIXELS_OFFSET\fP and continue for \fBICET_VALID_PIXELS_NUM\fP\&. The tile to which these pixels @@ -442,11 +460,13 @@ have no pixel data. .TP \fBICET_VALID_PIXELS_TILE\fP Gives the tile for which the -last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP -contains pixels. Each process has its own -value. If the last call to \fBicetDrawFrame\fP +last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP +contains pixels. +Each process has its own value. If the last call to +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, or \fBicetGLDrawFrame\fP did not return pixels for the local process, diff --git doc/man/man3/icetGetPointerv.3 doc/man/man3/icetGetPointerv.3 index a419be2..7368ac5 100644 --- doc/man/man3/icetGetPointerv.3 +++ doc/man/man3/icetGetPointerv.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:54 MDT 2011 +.\" Manual page created with latex2man on Fri Sep 26 14:33:26 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetGet" "3" "July 11, 2011" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetGet" "3" "September 26, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetGet \-\- get an \fBIceT \fPstate parameter\fP @@ -90,11 +90,12 @@ description of the associated state parameter. The color that \fBIceT \fPis currently assuming is the background color. It is an RGBA value that is stored as four floating point values. This value is set either to the last -value passed to \fBicetDrawFrame\fP, -the \fbOpenGL \fPbackground color if -\fBicetGLDrawFrame\fP -was called, or to black for color blending. -(The correct background color is restored later.) +value passed to \fBicetDrawFrame\fP +or \fBicetCompositeImage\fP, +the \fbOpenGL \fPbackground color if \fBicetGLDrawFrame\fP +was called, or +to black for color blending. (The correct background color is restored +later.) .TP \fBICET_BACKGROUND_COLOR_WORD\fP The same as @@ -106,40 +107,48 @@ rapidly fill the background of color buffers. \fBICET_BLEND_TIME\fP The total time, in seconds, spent in performing color blending of images during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a double. -An alias for this value is \fBICET_COMPARE_TIME\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. An alias for this value +is \fBICET_COMPARE_TIME\fP\&. .TP \fBICET_BUFFER_READ_TIME\fP The total time, in seconds, spent copying buffer data and reading from \fbOpenGL \fPbuffers during the last -call to \fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a -double. +call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. .TP \fBICET_BUFFER_WRITE_TIME\fP The total time, in seconds, spent writing to \fbOpenGL \fPbuffers during the last call to \fBicetGLDrawFrame\fP\&. Always set to 0.0 after a call to -\fBicetDrawFrame\fP\&. -Stored as a double. +\fBicetDrawFrame\fP +or \fBicetCompositeImage\fP\&. +Stored as a +double. .TP \fBICET_BYTES_SENT\fP The total number of bytes sent by the calling process for transferring image data during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as an -integer. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as an integer. .TP \fBICET_COLLECT_TIME\fP The total time spent in collecting image fragments to display processes during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. .TP \fBICET_COLOR_FORMAT\fP The color format of images to be @@ -153,10 +162,12 @@ particular image. \fBICET_COMPARE_TIME\fP The total time, in seconds, spent in performing Z comparisons of images during the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Stored as a double. -An alias for this value is \fBICET_BLEND_TIME\fP\&. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +Stored as a double. An alias for this value +is \fBICET_BLEND_TIME\fP\&. .TP \fBICET_COMPOSITE_MODE\fP The composite mode set by @@ -178,22 +189,24 @@ image generated by process j\&. .TP \fBICET_COMPOSITE_TIME\fP The total time, in seconds, spent in -compositing during the last call to \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Equal to $\fBICET_TOTAL_DRAW_TIME\fP -\- -\fBICET_RENDER_TIME\fP -\- \fBICET_BUFFER_READ_TIME\fP +compositing during the last call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Equal to +$\fBICET_TOTAL_DRAW_TIME\fP +\- \fBICET_RENDER_TIME\fP \- -\fBICET_BUFFER_WRITE_TIME\fP$. +\fBICET_BUFFER_READ_TIME\fP +\- \fBICET_BUFFER_WRITE_TIME\fP$. Stored as a double. .TP \fBICET_COMPRESS_TIME\fP The total time, in seconds, spent in compressing image data using active pixel encoding during the last call -to \fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. +to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. Stored as a double. .TP \fBICET_DATA_REPLICATION_GROUP\fP @@ -240,10 +253,11 @@ function, as set by \fBicetDrawCallback\fP\&. .TP \fBICET_FRAME_COUNT\fP The number of times -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP -has been called for -the current context. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP +has been called for the current context. .TP \fBICET_GEOMETRY_BOUNDS\fP An array of vertices whose convex @@ -324,6 +338,8 @@ object associated with the current context. the drawing callback during the last call to \fBicetDrawFrame\fP or \fBicetGLDrawFrame\fP\&. +Always set to 0.0 after a call to +\fBicetCompositeImage\fP\&. Stored as a double. .TP \fBICET_SINGLE_IMAGE_STRATEGY\fP @@ -377,39 +393,41 @@ viewports are listed in the same order as the tiles were defined with .TP \fBICET_TOTAL_DRAW_TIME\fP Time spent in the last call to -\fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -This includes all -the time to render, read back, compress, and composite images. Stored -as a double. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or +\fBicetGLDrawFrame\fP\&. +This includes all the time to render, read +back, compress, and composite images. Stored as a double. .TP \fBICET_VALID_PIXELS_NUM\fP In conjunction with \fBICET_VALID_PIXELS_OFFSET\fP, gives the range of valid pixels -for the last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Given the arrays of pixels returned with the -\fBicetImageGetColor\fP -and \fBicetImageGetDepth\fP -functions, the -valid pixels start at the pixel indexed by -\fBICET_VALID_PIXELS_OFFSET\fP +for the last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Given the +arrays of pixels returned with the \fBicetImageGetColor\fP +and +\fBicetImageGetDepth\fP +functions, the valid pixels start at the +pixel indexed by \fBICET_VALID_PIXELS_OFFSET\fP and continue for \fBICET_VALID_PIXELS_NUM\fP\&. The tile to which these pixels belong are captured in the \fBICET_VALID_PIXELS_TILE\fP state -variable. If the last call to \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP -did not return pixels for the local process, -\fBICET_VALID_PIXELS_NUM\fP -is set to 0\&. This state variable is -only useful when \fBICET_COLLECT_IMAGES\fP -is off. If on, it can -be assumed that all display processes contain all pixels in the image +variable. If the last call to \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP +did not return +pixels for the local process, \fBICET_VALID_PIXELS_NUM\fP +is set +to 0\&. This state variable is only useful when +\fBICET_COLLECT_IMAGES\fP +is off. If on, it can be assumed that +all display processes contain all pixels in the image (\fBICET_VALID_PIXELS_NUM\fP is the number of pixels in the image), and all other processes have no pixel data. @@ -418,15 +436,15 @@ image), and all other processes have no pixel data. In conjunction with \fBICET_VALID_PIXELS_NUM\fP, gives the range of valid pixels for -the last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP\&. -Given the arrays of pixels returned with the -\fBicetImageGetColor\fP -and \fBicetImageGetDepth\fP -functions, the -valid pixels start at the pixel indexed by -\fBICET_VALID_PIXELS_OFFSET\fP +the last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP\&. +Given the +arrays of pixels returned with the \fBicetImageGetColor\fP +and +\fBicetImageGetDepth\fP +functions, the valid pixels start at the +pixel indexed by \fBICET_VALID_PIXELS_OFFSET\fP and continue for \fBICET_VALID_PIXELS_NUM\fP\&. The tile to which these pixels @@ -442,11 +460,13 @@ have no pixel data. .TP \fBICET_VALID_PIXELS_TILE\fP Gives the tile for which the -last image returned from \fBicetDrawFrame\fP -or -\fBicetGLDrawFrame\fP -contains pixels. Each process has its own -value. If the last call to \fBicetDrawFrame\fP +last image returned from \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP +contains pixels. +Each process has its own value. If the last call to +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, or \fBicetGLDrawFrame\fP did not return pixels for the local process, diff --git doc/man/man3/icetGetSingleImageStrategyName.3 doc/man/man3/icetGetSingleImageStrategyName.3 index f325b07..dafe900 100644 --- doc/man/man3/icetGetSingleImageStrategyName.3 +++ doc/man/man3/icetGetSingleImageStrategyName.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:53 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetGetStrategyName.3 doc/man/man3/icetGetStrategyName.3 index 226c2e8..70a4561 100644 --- doc/man/man3/icetGetStrategyName.3 +++ doc/man/man3/icetGetStrategyName.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:53 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageCopyColor.3 doc/man/man3/icetImageCopyColor.3 index d08aed1..dd5481c 100644 --- doc/man/man3/icetImageCopyColor.3 +++ doc/man/man3/icetImageCopyColor.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageCopyColorf.3 doc/man/man3/icetImageCopyColorf.3 index d08aed1..dd5481c 100644 --- doc/man/man3/icetImageCopyColorf.3 +++ doc/man/man3/icetImageCopyColorf.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageCopyColorub.3 doc/man/man3/icetImageCopyColorub.3 index d08aed1..dd5481c 100644 --- doc/man/man3/icetImageCopyColorub.3 +++ doc/man/man3/icetImageCopyColorub.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageCopyDepth.3 doc/man/man3/icetImageCopyDepth.3 index d08aed1..dd5481c 100644 --- doc/man/man3/icetImageCopyDepth.3 +++ doc/man/man3/icetImageCopyDepth.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageCopyDepthf.3 doc/man/man3/icetImageCopyDepthf.3 index d08aed1..dd5481c 100644 --- doc/man/man3/icetImageCopyDepthf.3 +++ doc/man/man3/icetImageCopyDepthf.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageGetColor.3 doc/man/man3/icetImageGetColor.3 index a268f14..23bf851 100644 --- doc/man/man3/icetImageGetColor.3 +++ doc/man/man3/icetImageGetColor.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageGetColorFormat.3 doc/man/man3/icetImageGetColorFormat.3 index cf6d005..7ba18f6 100644 --- doc/man/man3/icetImageGetColorFormat.3 +++ doc/man/man3/icetImageGetColorFormat.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageGetColorcf.3 doc/man/man3/icetImageGetColorcf.3 index a268f14..23bf851 100644 --- doc/man/man3/icetImageGetColorcf.3 +++ doc/man/man3/icetImageGetColorcf.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageGetColorcub.3 doc/man/man3/icetImageGetColorcub.3 index a268f14..23bf851 100644 --- doc/man/man3/icetImageGetColorcub.3 +++ doc/man/man3/icetImageGetColorcub.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageGetColorcui.3 doc/man/man3/icetImageGetColorcui.3 index a268f14..23bf851 100644 --- doc/man/man3/icetImageGetColorcui.3 +++ doc/man/man3/icetImageGetColorcui.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageGetColorf.3 doc/man/man3/icetImageGetColorf.3 index a268f14..23bf851 100644 --- doc/man/man3/icetImageGetColorf.3 +++ doc/man/man3/icetImageGetColorf.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageGetColorub.3 doc/man/man3/icetImageGetColorub.3 index a268f14..23bf851 100644 --- doc/man/man3/icetImageGetColorub.3 +++ doc/man/man3/icetImageGetColorub.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageGetColorui.3 doc/man/man3/icetImageGetColorui.3 index a268f14..23bf851 100644 --- doc/man/man3/icetImageGetColorui.3 +++ doc/man/man3/icetImageGetColorui.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageGetDepth.3 doc/man/man3/icetImageGetDepth.3 index a268f14..23bf851 100644 --- doc/man/man3/icetImageGetDepth.3 +++ doc/man/man3/icetImageGetDepth.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageGetDepthFormat.3 doc/man/man3/icetImageGetDepthFormat.3 index cf6d005..7ba18f6 100644 --- doc/man/man3/icetImageGetDepthFormat.3 +++ doc/man/man3/icetImageGetDepthFormat.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageGetDepthcf.3 doc/man/man3/icetImageGetDepthcf.3 index a268f14..23bf851 100644 --- doc/man/man3/icetImageGetDepthcf.3 +++ doc/man/man3/icetImageGetDepthcf.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageGetDepthf.3 doc/man/man3/icetImageGetDepthf.3 index a268f14..23bf851 100644 --- doc/man/man3/icetImageGetDepthf.3 +++ doc/man/man3/icetImageGetDepthf.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageGetHeight.3 doc/man/man3/icetImageGetHeight.3 index 1ffae0e..e4992c9 100644 --- doc/man/man3/icetImageGetHeight.3 +++ doc/man/man3/icetImageGetHeight.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageGetNumPixels.3 doc/man/man3/icetImageGetNumPixels.3 index 1ffae0e..e4992c9 100644 --- doc/man/man3/icetImageGetNumPixels.3 +++ doc/man/man3/icetImageGetNumPixels.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageGetWidth.3 doc/man/man3/icetImageGetWidth.3 index 1ffae0e..e4992c9 100644 --- doc/man/man3/icetImageGetWidth.3 +++ doc/man/man3/icetImageGetWidth.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageIsNull.3 doc/man/man3/icetImageIsNull.3 index cd0e92c..d8f5bfb 100644 --- doc/man/man3/icetImageIsNull.3 +++ doc/man/man3/icetImageIsNull.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetImageNull.3 doc/man/man3/icetImageNull.3 index 0f212e6..7575191 100644 --- doc/man/man3/icetImageNull.3 +++ doc/man/man3/icetImageNull.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetIsEnabled.3 doc/man/man3/icetIsEnabled.3 index e8752ae..0f36aea 100644 --- doc/man/man3/icetIsEnabled.3 +++ doc/man/man3/icetIsEnabled.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:55 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetPhysicalRenderSize.3 doc/man/man3/icetPhysicalRenderSize.3 index dcc5181..ba7b4f8 100644 --- doc/man/man3/icetPhysicalRenderSize.3 +++ doc/man/man3/icetPhysicalRenderSize.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:56 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetResetTiles.3 doc/man/man3/icetResetTiles.3 index 38966c4..c78f80e 100644 --- doc/man/man3/icetResetTiles.3 +++ doc/man/man3/icetResetTiles.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:56 MDT 2011 +.\" Manual page created with latex2man on Fri Sep 26 14:31:03 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetResetTiles" "3" "August 9, 2010" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetResetTiles" "3" "September 26, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetResetTiles \-\- clears out all tile definitions.\fP @@ -63,8 +63,11 @@ None known. As a rule, a call to \fBicetResetTiles\fP should always be followed with one or more calls to \fBicetAddTile\fP\&. -\fBicetDrawFrame\fP -will not work properly if no tiles are in existence. +\fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +and \fBicetGLDrawFrame\fP +will not work +properly if no tiles are in existence. .PP .SH Copyright diff --git doc/man/man3/icetSetColorFormat.3 doc/man/man3/icetSetColorFormat.3 index 46dbca2..b78a1e3 100644 --- doc/man/man3/icetSetColorFormat.3 +++ doc/man/man3/icetSetColorFormat.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:56 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetSetColorFormat" "3" "August 9, 2010" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetSetColorFormat" "3" "September 22, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetSetColorFormat\fP,\fBicetSetDepthFormat\fP\-\- specifies the buffer formats for \fBIceT \fPto use when creating images @@ -41,6 +41,8 @@ and of images returned from frame drawing functions (\fBicetDrawFrame\fP or \fBicetGLDrawFrame\fP). +It is also the format expected for image +buffers passed to \fBicetCompositeImage\fP\&. .PP The following \fIcolor_format\fPs are valid for use in @@ -114,10 +116,12 @@ Calling either \fBicetSetColorFormat\fPor \fBicetSetDepthFormat\fPdoes \fInot\fP change the format of any existing images. It only changes any subsequently created images. .PP -The color format must be set before calling either \fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Doing otherwise would create inconsistencies -in the images created and composed together. +The color format must be set before calling \fBicetDrawFrame\fP, +\fBicetGLDrawFrame\fP, +or \fBicetCompositeImage\fP\&. +Doing otherwise +would create inconsistencies in the images created and composited +together. .PP .SH Copyright diff --git doc/man/man3/icetSetContext.3 doc/man/man3/icetSetContext.3 index a53dcb6..0808927 100644 --- doc/man/man3/icetSetContext.3 +++ doc/man/man3/icetSetContext.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:56 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git doc/man/man3/icetSetDepthFormat.3 doc/man/man3/icetSetDepthFormat.3 index 46dbca2..b78a1e3 100644 --- doc/man/man3/icetSetDepthFormat.3 +++ doc/man/man3/icetSetDepthFormat.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:56 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:54 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetSetColorFormat" "3" "August 9, 2010" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetSetColorFormat" "3" "September 22, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetSetColorFormat\fP,\fBicetSetDepthFormat\fP\-\- specifies the buffer formats for \fBIceT \fPto use when creating images @@ -41,6 +41,8 @@ and of images returned from frame drawing functions (\fBicetDrawFrame\fP or \fBicetGLDrawFrame\fP). +It is also the format expected for image +buffers passed to \fBicetCompositeImage\fP\&. .PP The following \fIcolor_format\fPs are valid for use in @@ -114,10 +116,12 @@ Calling either \fBicetSetColorFormat\fPor \fBicetSetDepthFormat\fPdoes \fInot\fP change the format of any existing images. It only changes any subsequently created images. .PP -The color format must be set before calling either \fBicetDrawFrame\fP -or \fBicetGLDrawFrame\fP\&. -Doing otherwise would create inconsistencies -in the images created and composed together. +The color format must be set before calling \fBicetDrawFrame\fP, +\fBicetGLDrawFrame\fP, +or \fBicetCompositeImage\fP\&. +Doing otherwise +would create inconsistencies in the images created and composited +together. .PP .SH Copyright diff --git doc/man/man3/icetSingleImageStrategy.3 doc/man/man3/icetSingleImageStrategy.3 index 77d836f..bd2fa07 100644 --- doc/man/man3/icetSingleImageStrategy.3 +++ doc/man/man3/icetSingleImageStrategy.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:56 MDT 2011 +.\" Manual page created with latex2man on Fri Sep 26 14:31:04 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetSingleImageStrategy" "3" "August 9, 2010" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetSingleImageStrategy" "3" "September 26, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetSingleImageStrategy \-\- set the sub\-strategy used to composite the image for a single tile.\fP @@ -110,8 +110,10 @@ This source code is released under the New BSD License. .SH See Also .PP +\fIicetCompositeImage\fP(3), \fIicetDrawFrame\fP(3), -\fIicetGetStrategyName\fP(3) +\fIicetGetStrategyName\fP(3), +\fIicetGLDrawFrame\fP(3), \fIicetSingleImageStrategy\fP(3) .PP .\" NOTE: This file is generated, DO NOT EDIT. diff --git doc/man/man3/icetStrategy.3 doc/man/man3/icetStrategy.3 index deafcb9..c67f36d 100644 --- doc/man/man3/icetStrategy.3 +++ doc/man/man3/icetStrategy.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:56 MDT 2011 +.\" Manual page created with latex2man on Fri Sep 26 14:31:04 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW @@ -10,7 +10,7 @@ .fi .. -.TH "icetStrategy" "3" "August 9, 2010" "\fBIceT \fPReference" "\fBIceT \fPReference" +.TH "icetStrategy" "3" "September 26, 2014" "\fBIceT \fPReference" "\fBIceT \fPReference" .SH NAME \fBicetStrategy \-\- set the strategy used to composite images.\fP @@ -33,7 +33,9 @@ images. The algorithm to use is determined by selecting a \fIstrategy\fP\&. The strategy is selected with \fBicetStrategy\fP\&. A -strategy must be selected before \fBicetDrawFrame\fP +strategy must be selected before \fBicetDrawFrame\fP, +\fBicetCompositeImage\fP, +or \fBicetGLDrawFrame\fP is called. .PP A strategy is chosen from one of the following provided enumerated @@ -141,8 +143,10 @@ This source code is released under the New BSD License. .SH See Also .PP +\fIicetCompositeImage\fP(3), \fIicetDrawFrame\fP(3), -\fIicetGetStrategyName\fP(3) +\fIicetGetStrategyName\fP(3), +\fIicetGLDrawFrame\fP(3), \fIicetSingleImageStrategy\fP(3) .PP .\" NOTE: This file is generated, DO NOT EDIT. diff --git doc/man/man3/icetWallTime.3 doc/man/man3/icetWallTime.3 index cf4e8d6..7e09c4d 100644 --- doc/man/man3/icetWallTime.3 +++ doc/man/man3/icetWallTime.3 @@ -1,5 +1,5 @@ '\" t -.\" Manual page created with latex2man on Tue Jul 19 13:11:56 MDT 2011 +.\" Manual page created with latex2man on Mon Sep 22 15:51:55 MDT 2014 .\" NOTE: This file is generated, DO NOT EDIT. .de Vb .ft CW diff --git src/communication/CMakeLists.txt src/communication/CMakeLists.txt index 864a46c..a96511f 100644 --- src/communication/CMakeLists.txt +++ src/communication/CMakeLists.txt @@ -9,8 +9,16 @@ SET(ICET_MPI_SRCS mpi.c ) +SET(ICET_MPI_HEADERS + ../include/IceTMPI.h + ) + IF (ICET_USE_MPI) - ICET_ADD_LIBRARY(IceTMPI ${ICET_MPI_SRCS}) + ICET_ADD_LIBRARY(IceTMPI ${ICET_MPI_SRCS} ${ICET_MPI_HEADERS}) + + SET_SOURCE_FILES_PROPERTIES(${ICET_MPI_HEADERS} + PROPERTIES HEADER_FILE_ONLY TRUE + ) TARGET_LINK_LIBRARIES(IceTMPI IceTCore diff --git src/communication/mpi.c src/communication/mpi.c index 2bc24d3..fcc0696 100644 --- src/communication/mpi.c +++ src/communication/mpi.c @@ -29,73 +29,76 @@ #define ICET_MPI_TEMP_BUFFER_0 (ICET_COMMUNICATION_LAYER_START | (IceTEnum)0x00) -static IceTCommunicator Duplicate(IceTCommunicator self); -static void Destroy(IceTCommunicator self); -static void Barrier(IceTCommunicator self); -static void Send(IceTCommunicator self, - const void *buf, - int count, - IceTEnum datatype, - int dest, - int tag); -static void Recv(IceTCommunicator self, - void *buf, - int count, - IceTEnum datatype, - int src, - int tag); -static void Sendrecv(IceTCommunicator self, - const void *sendbuf, - int sendcount, - IceTEnum sendtype, - int dest, - int sendtag, - void *recvbuf, - int recvcount, - IceTEnum recvtype, - int src, - int recvtag); -static void Gather(IceTCommunicator self, - const void *sendbuf, - int sendcount, - IceTEnum datatype, - void *recvbuf, - int root); -static void Gatherv(IceTCommunicator self, - const void *sendbuf, - int sendcount, +static IceTCommunicator MPIDuplicate(IceTCommunicator self); +static IceTCommunicator MPISubset(IceTCommunicator self, + int count, + const IceTInt32 *ranks); +static void MPIDestroy(IceTCommunicator self); +static void MPIBarrier(IceTCommunicator self); +static void MPISend(IceTCommunicator self, + const void *buf, + int count, IceTEnum datatype, - void *recvbuf, - const int *recvcounts, - const int *recvoffsets, - int root); -static void Allgather(IceTCommunicator self, + int dest, + int tag); +static void MPIRecv(IceTCommunicator self, + void *buf, + int count, + IceTEnum datatype, + int src, + int tag); +static void MPISendrecv(IceTCommunicator self, + const void *sendbuf, + int sendcount, + IceTEnum sendtype, + int dest, + int sendtag, + void *recvbuf, + int recvcount, + IceTEnum recvtype, + int src, + int recvtag); +static void MPIGather(IceTCommunicator self, const void *sendbuf, int sendcount, IceTEnum datatype, - void *recvbuf); -static void Alltoall(IceTCommunicator self, - const void *sendbuf, - int sendcount, - IceTEnum datatype, - void *recvbuf); -static IceTCommRequest Isend(IceTCommunicator self, - const void *buf, - int count, - IceTEnum datatype, - int dest, - int tag); -static IceTCommRequest Irecv(IceTCommunicator self, - void *buf, - int count, - IceTEnum datatype, - int src, - int tag); -static void Waitone(IceTCommunicator self, IceTCommRequest *request); -static int Waitany(IceTCommunicator self, - int count, IceTCommRequest *array_of_requests); -static int Comm_size(IceTCommunicator self); -static int Comm_rank(IceTCommunicator self); + void *recvbuf, + int root); +static void MPIGatherv(IceTCommunicator self, + const void *sendbuf, + int sendcount, + IceTEnum datatype, + void *recvbuf, + const int *recvcounts, + const int *recvoffsets, + int root); +static void MPIAllgather(IceTCommunicator self, + const void *sendbuf, + int sendcount, + IceTEnum datatype, + void *recvbuf); +static void MPIAlltoall(IceTCommunicator self, + const void *sendbuf, + int sendcount, + IceTEnum datatype, + void *recvbuf); +static IceTCommRequest MPIIsend(IceTCommunicator self, + const void *buf, + int count, + IceTEnum datatype, + int dest, + int tag); +static IceTCommRequest MPIIrecv(IceTCommunicator self, + void *buf, + int count, + IceTEnum datatype, + int src, + int tag); +static void MPIWaitone(IceTCommunicator self, IceTCommRequest *request); +static int MPIWaitany(IceTCommunicator self, + int count, IceTCommRequest *array_of_requests); +static int MPIComm_size(IceTCommunicator self); +static int MPIComm_rank(IceTCommunicator self); typedef struct IceTMPICommRequestInternalsStruct { MPI_Request request; @@ -189,33 +192,39 @@ static void ErrorHandler(MPI_Comm *comm, int *errorno, ...) IceTCommunicator icetCreateMPICommunicator(MPI_Comm mpi_comm) { - IceTCommunicator comm = malloc(sizeof(struct IceTCommunicatorStruct)); + IceTCommunicator comm; #ifdef BREAK_ON_MPI_ERROR MPI_Errhandler eh; #endif + if (mpi_comm == MPI_COMM_NULL) { + return ICET_COMM_NULL; + } + + comm = malloc(sizeof(struct IceTCommunicatorStruct)); if (comm == NULL) { icetRaiseError("Could not allocate memory for IceTCommunicator.", ICET_OUT_OF_MEMORY); return NULL; } - comm->Duplicate = Duplicate; - comm->Destroy = Destroy; - comm->Barrier = Barrier; - comm->Send = Send; - comm->Recv = Recv; - comm->Sendrecv = Sendrecv; - comm->Gather = Gather; - comm->Gatherv = Gatherv; - comm->Allgather = Allgather; - comm->Alltoall = Alltoall; - comm->Isend = Isend; - comm->Irecv = Irecv; - comm->Wait = Waitone; - comm->Waitany = Waitany; - comm->Comm_size = Comm_size; - comm->Comm_rank = Comm_rank; + comm->Duplicate = MPIDuplicate; + comm->Subset = MPISubset; + comm->Destroy = MPIDestroy; + comm->Barrier = MPIBarrier; + comm->Send = MPISend; + comm->Recv = MPIRecv; + comm->Sendrecv = MPISendrecv; + comm->Gather = MPIGather; + comm->Gatherv = MPIGatherv; + comm->Allgather = MPIAllgather; + comm->Alltoall = MPIAlltoall; + comm->Isend = MPIIsend; + comm->Irecv = MPIIrecv; + comm->Wait = MPIWaitone; + comm->Waitany = MPIWaitany; + comm->Comm_size = MPIComm_size; + comm->Comm_rank = MPIComm_rank; comm->data = malloc(sizeof(MPI_Comm)); if (comm->data == NULL) { @@ -227,9 +236,15 @@ IceTCommunicator icetCreateMPICommunicator(MPI_Comm mpi_comm) MPI_Comm_dup(mpi_comm, (MPI_Comm *)comm->data); #ifdef BREAK_ON_MPI_ERROR +#if MPI_VERSION < 2 MPI_Errhandler_create(ErrorHandler, &eh); MPI_Errhandler_set(*((MPI_Comm *)comm->data), eh); MPI_Errhandler_free(&eh); +#else /* MPI_VERSION >= 2 */ + MPI_Comm_create_errhandler(ErrorHandler, &eh); + MPI_Comm_set_errhandler(*((MPI_Comm *)comm->data), eh); + MPI_Errhandler_free(&eh); +#endif /* MPI_VERSION >= 2 */ #endif return comm; @@ -237,25 +252,56 @@ IceTCommunicator icetCreateMPICommunicator(MPI_Comm mpi_comm) void icetDestroyMPICommunicator(IceTCommunicator comm) { - comm->Destroy(comm); + if (comm != ICET_COMM_NULL) { + comm->Destroy(comm); + } } #define MPI_COMM (*((MPI_Comm *)self->data)) -static IceTCommunicator Duplicate(IceTCommunicator self) +static IceTCommunicator MPIDuplicate(IceTCommunicator self) +{ + if (self != ICET_COMM_NULL) { + return icetCreateMPICommunicator(MPI_COMM); + } else { + return ICET_COMM_NULL; + } +} + +static IceTCommunicator MPISubset(IceTCommunicator self, + int count, + const IceTInt32 *ranks) { - return icetCreateMPICommunicator(MPI_COMM); + MPI_Group original_group; + MPI_Group subset_group; + MPI_Comm subset_comm; + IceTCommunicator result; + + MPI_Comm_group(MPI_COMM, &original_group); + MPI_Group_incl(original_group, count, (IceTInt32 *)ranks, &subset_group); + MPI_Comm_create(MPI_COMM, subset_group, &subset_comm); + + result = icetCreateMPICommunicator(subset_comm); + + if (subset_comm != MPI_COMM_NULL) { + MPI_Comm_free(&subset_comm); + } + + MPI_Group_free(&subset_group); + MPI_Group_free(&original_group); + + return result; } -static void Destroy(IceTCommunicator self) +static void MPIDestroy(IceTCommunicator self) { MPI_Comm_free((MPI_Comm *)self->data); free(self->data); free(self); } -static void Barrier(IceTCommunicator self) +static void MPIBarrier(IceTCommunicator self) { MPI_Barrier(MPI_COMM); } @@ -275,41 +321,41 @@ static void Barrier(IceTCommunicator self) break; \ } -static void Send(IceTCommunicator self, - const void *buf, - int count, - IceTEnum datatype, - int dest, - int tag) +static void MPISend(IceTCommunicator self, + const void *buf, + int count, + IceTEnum datatype, + int dest, + int tag) { MPI_Datatype mpidatatype; CONVERT_DATATYPE(datatype, mpidatatype); MPI_Send((void *)buf, count, mpidatatype, dest, tag, MPI_COMM); } -static void Recv(IceTCommunicator self, - void *buf, - int count, - IceTEnum datatype, - int src, - int tag) +static void MPIRecv(IceTCommunicator self, + void *buf, + int count, + IceTEnum datatype, + int src, + int tag) { MPI_Datatype mpidatatype; CONVERT_DATATYPE(datatype, mpidatatype); MPI_Recv(buf, count, mpidatatype, src, tag, MPI_COMM, MPI_STATUS_IGNORE); } -static void Sendrecv(IceTCommunicator self, - const void *sendbuf, - int sendcount, - IceTEnum sendtype, - int dest, - int sendtag, - void *recvbuf, - int recvcount, - IceTEnum recvtype, - int src, - int recvtag) +static void MPISendrecv(IceTCommunicator self, + const void *sendbuf, + int sendcount, + IceTEnum sendtype, + int dest, + int sendtag, + void *recvbuf, + int recvcount, + IceTEnum recvtype, + int src, + int recvtag) { MPI_Datatype mpisendtype; MPI_Datatype mpirecvtype; @@ -321,12 +367,12 @@ static void Sendrecv(IceTCommunicator self, MPI_STATUS_IGNORE); } -static void Gather(IceTCommunicator self, - const void *sendbuf, - int sendcount, - IceTEnum datatype, - void *recvbuf, - int root) +static void MPIGather(IceTCommunicator self, + const void *sendbuf, + int sendcount, + IceTEnum datatype, + void *recvbuf, + int root) { MPI_Datatype mpitype; CONVERT_DATATYPE(datatype, mpitype); @@ -350,14 +396,14 @@ static void Gather(IceTCommunicator self, MPI_COMM); } -static void Gatherv(IceTCommunicator self, - const void *sendbuf, - int sendcount, - IceTEnum datatype, - void *recvbuf, - const int *recvcounts, - const int *recvoffsets, - int root) +static void MPIGatherv(IceTCommunicator self, + const void *sendbuf, + int sendcount, + IceTEnum datatype, + void *recvbuf, + const int *recvcounts, + const int *recvoffsets, + int root) { MPI_Datatype mpitype; CONVERT_DATATYPE(datatype, mpitype); @@ -382,11 +428,11 @@ static void Gatherv(IceTCommunicator self, root, MPI_COMM); } -static void Allgather(IceTCommunicator self, - const void *sendbuf, - int sendcount, - IceTEnum datatype, - void *recvbuf) +static void MPIAllgather(IceTCommunicator self, + const void *sendbuf, + int sendcount, + IceTEnum datatype, + void *recvbuf) { MPI_Datatype mpitype; CONVERT_DATATYPE(datatype, mpitype); @@ -410,11 +456,11 @@ static void Allgather(IceTCommunicator self, MPI_COMM); } -static void Alltoall(IceTCommunicator self, - const void *sendbuf, - int sendcount, - IceTEnum datatype, - void *recvbuf) +static void MPIAlltoall(IceTCommunicator self, + const void *sendbuf, + int sendcount, + IceTEnum datatype, + void *recvbuf) { MPI_Datatype mpitype; CONVERT_DATATYPE(datatype, mpitype); @@ -424,12 +470,12 @@ static void Alltoall(IceTCommunicator self, MPI_COMM); } -static IceTCommRequest Isend(IceTCommunicator self, - const void *buf, - int count, - IceTEnum datatype, - int dest, - int tag) +static IceTCommRequest MPIIsend(IceTCommunicator self, + const void *buf, + int count, + IceTEnum datatype, + int dest, + int tag) { IceTCommRequest icet_request; MPI_Request mpi_request; @@ -445,12 +491,12 @@ static IceTCommRequest Isend(IceTCommunicator self, return icet_request; } -static IceTCommRequest Irecv(IceTCommunicator self, - void *buf, - int count, - IceTEnum datatype, - int src, - int tag) +static IceTCommRequest MPIIrecv(IceTCommunicator self, + void *buf, + int count, + IceTEnum datatype, + int src, + int tag) { IceTCommRequest icet_request; MPI_Request mpi_request; @@ -466,7 +512,7 @@ static IceTCommRequest Irecv(IceTCommunicator self, return icet_request; } -static void Waitone(IceTCommunicator self, IceTCommRequest *icet_request) +static void MPIWaitone(IceTCommunicator self, IceTCommRequest *icet_request) { MPI_Request mpi_request; @@ -483,8 +529,8 @@ static void Waitone(IceTCommunicator self, IceTCommRequest *icet_request) *icet_request = ICET_COMM_REQUEST_NULL; } -static int Waitany(IceTCommunicator self, - int count, IceTCommRequest *array_of_requests) +static int MPIWaitany(IceTCommunicator self, + int count, IceTCommRequest *array_of_requests) { MPI_Request *mpi_requests; int idx; @@ -514,14 +560,14 @@ static int Waitany(IceTCommunicator self, return idx; } -static int Comm_size(IceTCommunicator self) +static int MPIComm_size(IceTCommunicator self) { int size; MPI_Comm_size(MPI_COMM, &size); return size; } -static int Comm_rank(IceTCommunicator self) +static int MPIComm_rank(IceTCommunicator self) { int rank; MPI_Comm_rank(MPI_COMM, &rank); diff --git src/gl/CMakeLists.txt src/gl/CMakeLists.txt index 9ee69e0..beae65d 100644 --- src/gl/CMakeLists.txt +++ src/gl/CMakeLists.txt @@ -6,12 +6,20 @@ # SET(ICET_GL_SRCS - gl_state.c - gl_draw.c - gl_image.c -) + gl_state.c + gl_draw.c + gl_image.c + ) + +SET(ICET_GL_HEADERS + ../include/IceTGL.h + ) -ICET_ADD_LIBRARY(IceTGL ${ICET_GL_SRCS}) +ICET_ADD_LIBRARY(IceTGL ${ICET_GL_SRCS} ${ICET_GL_HEADERS}) + +SET_SOURCE_FILES_PROPERTIES(${ICET_GL_HEADERS} + PROPERTIES HEADER_FILE_ONLY TRUE + ) TARGET_LINK_LIBRARIES(IceTGL IceTCore diff --git src/ice-t/CMakeLists.txt src/ice-t/CMakeLists.txt index ebb1462..1aef689 100644 --- src/ice-t/CMakeLists.txt +++ src/ice-t/CMakeLists.txt @@ -6,32 +6,61 @@ # SET(ICET_SRCS - porting.c - context.c - state.c - diagnostics.c - communication.c - tiles.c - timing.c - matrix.c - projections.c - draw.c - image.c - - ../strategies/common.c - ../strategies/select.c - ../strategies/direct.c - ../strategies/sequential.c - ../strategies/split.c - ../strategies/reduce.c - ../strategies/vtree.c - ../strategies/bswap.c - ../strategies/radixk.c - ../strategies/tree.c - ../strategies/automatic.c -) - -ICET_ADD_LIBRARY(IceTCore ${ICET_SRCS}) + porting.c + context.c + state.c + diagnostics.c + communication.c + tiles.c + timing.c + matrix.c + projections.c + draw.c + image.c + + ../strategies/common.c + ../strategies/select.c + ../strategies/direct.c + ../strategies/sequential.c + ../strategies/split.c + ../strategies/reduce.c + ../strategies/vtree.c + ../strategies/bswap.c + ../strategies/radixk.c + ../strategies/radixkr.c + ../strategies/tree.c + ../strategies/automatic.c + ) + +SET(ICET_HEADERS + ../include/IceT.h + ../include/IceTDevCommunication.h + ../include/IceTDevContext.h + ../include/IceTDevDiagnostics.h + ../include/IceTDevGLImage.h + ../include/IceTDevImage.h + ../include/IceTDevMatrix.h + ../include/IceTDevPorting.h + ../include/IceTDevProjections.h + ../include/IceTDevState.h + ../include/IceTDevStrategySelect.h + ../include/IceTDevTiming.h + + cc_composite_func_body.h + cc_composite_template_body.h + compress_func_body.h + compress_template_body.h + decompress_func_body.h + decompress_template_body.h + + ../strategies/common.h + ) + +ICET_ADD_LIBRARY(IceTCore ${ICET_SRCS} ${ICET_HEADERS}) + +SET_SOURCE_FILES_PROPERTIES(${ICET_HEADERS} + PROPERTIES HEADER_FILE_ONLY TRUE + ) IF (UNIX) # Depend on the math library under Unix. diff --git src/ice-t/communication.c src/ice-t/communication.c index 05e558f..7370e83 100644 --- src/ice-t/communication.c +++ src/ice-t/communication.c @@ -34,6 +34,12 @@ IceTCommunicator icetCommDuplicate() return comm->Duplicate(comm); } +IceTCommunicator icetCommSubset(int count, const IceTInt32 *ranks) +{ + IceTCommunicator comm = icetGetCommunicator(); + return comm->Subset(comm, count, ranks); +} + void icetCommBarrier() { IceTCommunicator comm = icetGetCommunicator(); diff --git src/ice-t/compress_func_body.h src/ice-t/compress_func_body.h index e89b172..8a4c87b 100644 --- src/ice-t/compress_func_body.h +++ src/ice-t/compress_func_body.h @@ -118,7 +118,7 @@ if (_composite_mode == ICET_COMPOSITE_MODE_Z_BUFFER) { if (_depth_format == ICET_IMAGE_DEPTH_FLOAT) { /* Use Z buffer for active pixel testing. */ - const IceTFloat *_depth = icetImageGetDepthf(INPUT_IMAGE); + const IceTFloat *_depth = icetImageGetDepthcf(INPUT_IMAGE); #ifdef OFFSET _depth += OFFSET; #endif @@ -129,7 +129,7 @@ #ifdef REGION IceTSizeType _region_count = 0; #endif - _color = icetImageGetColorui(INPUT_IMAGE); + _color = icetImageGetColorcui(INPUT_IMAGE); #ifdef OFFSET _color += OFFSET; #endif @@ -171,7 +171,7 @@ #ifdef REGION IceTSizeType _region_count = 0; #endif - _color = icetImageGetColorf(INPUT_IMAGE); + _color = icetImageGetColorcf(INPUT_IMAGE); #ifdef OFFSET _color += 4*(OFFSET); #endif @@ -265,7 +265,7 @@ #ifdef REGION IceTSizeType _region_count = 0; #endif - _color = icetImageGetColorui(INPUT_IMAGE); + _color = icetImageGetColorcui(INPUT_IMAGE); #ifdef OFFSET _color += OFFSET; #endif @@ -303,7 +303,7 @@ #ifdef REGION IceTSizeType _region_count = 0; #endif - _color = icetImageGetColorf(INPUT_IMAGE); + _color = icetImageGetColorcf(INPUT_IMAGE); #ifdef OFFSET _color += 4*(OFFSET); #endif diff --git src/ice-t/decompress_func_body.h src/ice-t/decompress_func_body.h index bf312c4..5631230 100644 --- src/ice-t/decompress_func_body.h +++ src/ice-t/decompress_func_body.h @@ -75,21 +75,31 @@ _depth_format = icetSparseImageGetDepthFormat(INPUT_SPARSE_IMAGE); _pixel_count = icetSparseImageGetNumPixels(INPUT_SPARSE_IMAGE); - if ( (_color_format != icetImageGetColorFormat(OUTPUT_IMAGE)) - || (_depth_format != icetImageGetDepthFormat(OUTPUT_IMAGE)) + if (_color_format != icetImageGetColorFormat(OUTPUT_IMAGE)) { + icetRaiseError("Input/output buffers have different color formats.", + ICET_SANITY_CHECK_FAIL); + } + if (_depth_format != icetImageGetDepthFormat(OUTPUT_IMAGE)) { + icetRaiseError("Input/output buffers have different depth formats.", + ICET_SANITY_CHECK_FAIL); + } #ifdef PIXEL_COUNT - || (_pixel_count != PIXEL_COUNT) + if (_pixel_count != PIXEL_COUNT) { + icetRaiseError("Unexpected input pixel count.", + ICET_SANITY_CHECK_FAIL); + } #else - || (_pixel_count != icetImageGetNumPixels(OUTPUT_IMAGE)) + if (_pixel_count != icetImageGetNumPixels(OUTPUT_IMAGE)) { + icetRaiseError("Unexpected input pixel count.", + ICET_SANITY_CHECK_FAIL); + } #endif #ifdef OFFSET - || (_pixel_count > icetImageGetNumPixels(OUTPUT_IMAGE) - OFFSET) -#endif - ) - { - icetRaiseError("Input/output buffers do not agree for decompression.", + if (_pixel_count > icetImageGetNumPixels(OUTPUT_IMAGE) - OFFSET) { + icetRaiseError("Offset pixels outside range of output image.", ICET_SANITY_CHECK_FAIL); } +#endif if (_composite_mode == ICET_COMPOSITE_MODE_Z_BUFFER) { if (_depth_format == ICET_IMAGE_DEPTH_FLOAT) { diff --git src/ice-t/diagnostics.c src/ice-t/diagnostics.c index 354019c..775d280 100644 --- src/ice-t/diagnostics.c +++ src/ice-t/diagnostics.c @@ -20,6 +20,10 @@ #include +#ifndef WIN32 +#include +#endif + static IceTEnum currentError = ICET_NO_ERROR; static IceTEnum currentLevel; @@ -125,5 +129,9 @@ void icetDiagnostics(IceTBitField mask) void icetDebugBreak(void) { +#if 0 + printf("Waiting for debugger in process %d\n", getpid()); + sleep(100); +#endif raise(SIGSEGV); } diff --git src/ice-t/draw.c src/ice-t/draw.c index e8e3cfe..deedf90 100644 --- src/ice-t/draw.c +++ src/ice-t/draw.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -161,6 +162,43 @@ void icetDataReplicationGroupColor(IceTInt color) icetDataReplicationGroup(size, mygroup); } +static void drawUseMatrices(const IceTDouble *projection_matrix, + const IceTDouble *modelview_matrix) +{ + if ((projection_matrix != NULL) && (modelview_matrix != NULL)) { + icetStateSetDoublev(ICET_PROJECTION_MATRIX, 16, projection_matrix); + icetStateSetDoublev(ICET_MODELVIEW_MATRIX, 16, modelview_matrix); + } else { + IceTDouble identity[16]; + icetMatrixIdentity(identity); + if (projection_matrix == NULL) { + icetStateSetDoublev(ICET_PROJECTION_MATRIX, 16, identity); + } else { + icetRaiseWarning("Drawing with a projection matrix but no " + "modelview matrix. Confused on what to do.", + ICET_INVALID_VALUE); + icetStateSetDoublev(ICET_PROJECTION_MATRIX, 16, projection_matrix); + } + if (modelview_matrix == NULL) { + icetStateSetDoublev(ICET_MODELVIEW_MATRIX, 16, identity); + } else { + icetRaiseWarning("Drawing with a modelview matrix but no " + "projection matrix. Confused on what to do.", + ICET_INVALID_VALUE); + icetStateSetDoublev(ICET_MODELVIEW_MATRIX, 16, projection_matrix); + } + if (*icetUnsafeStateGetInteger(ICET_NUM_BOUNDING_VERTS) != 0) { + icetRaiseWarning( + "Geometry bounds were given (with icetBoundingBox or icetBoundingVertices)\n" + "but projection matrices not given to icetCompositeImage. Clearing out the\n" + "bounding information. (Use icetBoundingVertices(0, ICET_VOID, 0, 0, NULL)\n" + "to avoid this error.)", + ICET_INVALID_VALUE); + icetBoundingVertices(0, ICET_VOID, 0, 0, NULL); + } + } +} + static IceTFloat black[] = {0.0f, 0.0f, 0.0f, 0.0f}; static void drawUseBackgroundColor(const IceTFloat *background_color) @@ -581,30 +619,37 @@ static void drawProjectBounds(void) sizeof(IceTBoolean)*num_tiles); if (num_bounding_verts < 1) { - /* User never set bounding vertices. Assume image covers all tiles. */ - IceTInt i; - for (i = 0; i < num_tiles; i++) { - contained_list[i] = i; - contained_mask[i] = 1; - } + /* User never set bounding vertices. Assume image covers global + * viewport. */ icetGetIntegerv(ICET_GLOBAL_VIEWPORT, contained_viewport); znear = -1.0; zfar = 1.0; - num_contained = num_tiles; } else { /* Figure out how the geometry projects onto the display. */ drawFindContainedViewport(contained_viewport, &znear, &zfar); + } - /* Now use this information to figure out which tiles need to be - drawn. */ - drawDetermineContainedTiles(contained_viewport, - znear, - zfar, - contained_list, - contained_mask, - &num_contained); + if ( icetUnsafeStateGetBoolean(ICET_PRE_RENDERED)[0] + && (icetStateGetNumEntries(ICET_RENDERED_VIEWPORT) == 4) ) { + /* If we are using a pre-rendered image (from icetCompositeImage) and + * a valid pixels viewport was given, then clip the current contained + * viewport with that one. */ + const IceTInt *rendered_viewport = + icetUnsafeStateGetInteger(ICET_RENDERED_VIEWPORT); + icetIntersectViewports(rendered_viewport, + contained_viewport, + contained_viewport); } + /* Now use this information to figure out which tiles need to be + drawn. */ + drawDetermineContainedTiles(contained_viewport, + znear, + zfar, + contained_list, + contained_mask, + &num_contained); + icetRaiseDebug4("contained_viewport = %d %d %d %d", (int)contained_viewport[0], (int)contained_viewport[1], (int)contained_viewport[2], (int)contained_viewport[3]); @@ -632,6 +677,18 @@ static void drawCollectTileInformation(void) IceTInt num_proc; IceTInt num_tiles; + { + IceTEnum strategy; + icetGetEnumv(ICET_STRATEGY, &strategy); + + /* This function performs allgathers to collect information about + * all tiles on all processes, which IceT strategies need to cull + * out unused tiles and set up communication patterns. However, + * the sequential strategy ignores this information and just uses + * all processes for all tiles, so we can skip this step. */ + if (strategy == ICET_STRATEGY_SEQUENTIAL) { return; } + } + icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc); icetGetIntegerv(ICET_NUM_TILES, &num_tiles); @@ -680,7 +737,8 @@ static IceTImage drawInvokeStrategy(void) IceTInt valid_tile; icetGetPointerv(ICET_DRAW_FUNCTION, &value); - if (value == NULL) { + if ( (value == NULL) + && !icetUnsafeStateGetBoolean(ICET_PRE_RENDERED)[0]) { icetRaiseError("Drawing function not set. Call icetDrawCallback.", ICET_INVALID_OPERATION); return icetImageNull(); @@ -728,9 +786,9 @@ static IceTImage drawInvokeStrategy(void) return image; } -IceTImage icetDrawFrame(const IceTDouble *projection_matrix, - const IceTDouble *modelview_matrix, - const IceTFloat *background_color) +static IceTImage drawDoFrame(const IceTDouble *projection_matrix, + const IceTDouble *modelview_matrix, + const IceTFloat *background_color) { IceTInt frame_count; IceTImage image; @@ -739,8 +797,6 @@ IceTImage icetDrawFrame(const IceTDouble *projection_matrix, IceTDouble compose_time; IceTDouble total_time; - icetRaiseDebug("In icetDrawFrame"); - { IceTBoolean isDrawing; icetGetBooleanv(ICET_IS_DRAWING_FRAME, &isDrawing); @@ -754,8 +810,7 @@ IceTImage icetDrawFrame(const IceTDouble *projection_matrix, icetStateResetTiming(); icetTimingDrawFrameBegin(); - icetStateSetDoublev(ICET_PROJECTION_MATRIX, 16, projection_matrix); - icetStateSetDoublev(ICET_MODELVIEW_MATRIX, 16, modelview_matrix); + drawUseMatrices(projection_matrix, modelview_matrix); drawUseBackgroundColor(background_color); @@ -765,21 +820,7 @@ IceTImage icetDrawFrame(const IceTDouble *projection_matrix, drawProjectBounds(); - { - IceTEnum strategy; - icetGetEnumv(ICET_STRATEGY, &strategy); - - /* drawCollectTileInformation does an allgather to get information - * about the tiles in other processes. These variables are - * ICET_ALL_CONTAINED_TILES_MASKS, ICET_TILE_CONTRIB_COUNTS, and - * ICET_TOTAL_IMAGE_COUNT. However, the sequential strategy ignores - * this information and just uses all processes for all tiles. When - * compositing a single tile, this is a fine strategy and we can save - * a significant proportion of frame time by skipping this step. */ - if (strategy != ICET_STRATEGY_SEQUENTIAL) { - drawCollectTileInformation(); - } - } + drawCollectTileInformation(); { IceTInt tile_displayed; @@ -819,3 +860,42 @@ IceTImage icetDrawFrame(const IceTDouble *projection_matrix, return image; } + +IceTImage icetDrawFrame(const IceTDouble *projection_matrix, + const IceTDouble *modelview_matrix, + const IceTFloat *background_color) +{ + icetRaiseDebug("In icetDrawFrame"); + + icetStateSetBoolean(ICET_PRE_RENDERED, ICET_FALSE); + + return drawDoFrame(projection_matrix, modelview_matrix, background_color); +} + +IceTImage icetCompositeImage(const IceTVoid *color_buffer, + const IceTVoid *depth_buffer, + const IceTInt *valid_pixels_viewport, + const IceTDouble *projection_matrix, + const IceTDouble *modelview_matrix, + const IceTFloat *background_color) +{ + IceTInt global_viewport[4]; + + icetRaiseDebug("In icetCompositeImage"); + + icetGetIntegerv(ICET_GLOBAL_VIEWPORT, global_viewport); + + icetStateSetBoolean(ICET_PRE_RENDERED, ICET_TRUE); + icetGetStatePointerImage(ICET_RENDER_BUFFER, + global_viewport[2], + global_viewport[3], + color_buffer, + depth_buffer); + if (valid_pixels_viewport) { + icetStateSetIntegerv(ICET_RENDERED_VIEWPORT, 4, valid_pixels_viewport); + } else { + icetStateSetIntegerv(ICET_RENDERED_VIEWPORT, 0, NULL); + } + + return drawDoFrame(projection_matrix, modelview_matrix, background_color); +} diff --git src/ice-t/image.c src/ice-t/image.c index 941e2e9..cd80174 100644 --- src/ice-t/image.c +++ src/ice-t/image.c @@ -21,6 +21,7 @@ #include #define ICET_IMAGE_MAGIC_NUM (IceTEnum)0x004D5000 +#define ICET_IMAGE_POINTERS_MAGIC_NUM (IceTEnum)0x004D5100 #define ICET_SPARSE_IMAGE_MAGIC_NUM (IceTEnum)0x004D6000 #define ICET_IMAGE_MAGIC_NUM_INDEX 0 @@ -46,8 +47,10 @@ typedef IceTUnsignedInt32 IceTRunLengthType; static void ICET_TEST_IMAGE_HEADER(IceTImage image) { if (!icetImageIsNull(image)) { - if ( ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX] - != ICET_IMAGE_MAGIC_NUM ) { + IceTEnum magic_num = + ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX]; + if ( (magic_num != ICET_IMAGE_MAGIC_NUM) + && (magic_num != ICET_IMAGE_POINTERS_MAGIC_NUM) ) { icetRaiseError("Detected invalid image header.", ICET_SANITY_CHECK_FAIL); } @@ -140,7 +143,7 @@ static void icetSparseImageSetActualSize(IceTSparseImage image, * to the last run length. This parameter is optional. If set to NULL, * it is assumed that out_data_p will initially point to a run length. * This parameter is ignored if out_data_p is NULL. - */ + */ static void icetSparseImageScanPixels(const IceTVoid **in_data_p, IceTSizeType *inactive_before_p, IceTSizeType *active_till_next_runl_p, @@ -188,6 +191,18 @@ static void icetSparseImageSplitChoosePartitions( IceTSizeType first_offset, IceTSizeType *offsets); +/* This function is used to get the image for a tile. It will either render + the tile on demand (with renderTile) or get the image from a pre-rendered + image (with prerenderedTile). The screen_viewport is set to the region of + valid pixels in the returned image. The tile_viewport gives the region + where the pixels reside in the tile. (The width and height of the two + viewports will be the same.) Pixels outside of these viewports are + undefined. */ +static IceTImage generateTile(int tile, + IceTInt *screen_viewport, + IceTInt *target_viewport, + IceTImage tile_buffer); + /* Renders the geometry for a tile and returns an image of the rendered data. If IceT determines that it is most efficient to render the data directly to the tile projection, then screen_viewport and tile_viewport will be set to @@ -196,15 +211,23 @@ static void icetSparseImageSplitChoosePartitions( cleared to the background before used. If tile_buffer is not a null image, that image will be used to render and be returned. If IceT determines that it is most efficient to render a projection that does not exactly fit a tile, - tile_buffer will be ignored an image with an internal buffer will be + tile_buffer will be ignored and image with an internal buffer will be returned. screen_viewport will give the offset and dimensions of the valid pixels in the returned buffer. tile_viewport gives the offset and dimensions - where these pixels reside in the tile. (The dimensions for both will be the - same.) As before, pixels outside of these viewports are undefined. */ + where these pixels reside in the tile. (The width and height for both will + be the same.) As before, pixels outside of these viewports are undefined. */ static IceTImage renderTile(int tile, IceTInt *screen_viewport, - IceTInt *tile_viewport, + IceTInt *target_viewport, IceTImage tile_buffer); + +/* Returns the pre-rendered image, the region of valid pixels in the tile in + screen_viewport, and the region where the pixels reside in the tile in + tile_viewport. */ +static IceTImage prerenderedTile(int tile, + IceTInt *screen_viewport, + IceTInt *target_viewport); + /* Gets an image buffer attached to this context. */ static IceTImage getRenderBuffer(void); @@ -254,6 +277,12 @@ IceTSizeType icetImageBufferSizeType(IceTEnum color_format, + width*height*(color_pixel_size + depth_pixel_size) ); } +IceTSizeType icetImagePointerBufferSize(void) +{ + return ( ICET_IMAGE_DATA_START_INDEX*sizeof(IceTUInt) + + 2*(sizeof(const IceTVoid *)) ); +} + IceTSizeType icetSparseImageBufferSize(IceTSizeType width, IceTSizeType height) { IceTEnum color_format, depth_format; @@ -309,6 +338,28 @@ IceTImage icetGetStateBufferImage(IceTEnum pname, return icetImageAssignBuffer(buffer, width, height); } +IceTImage icetRetrieveStateImage(IceTEnum pname) +{ + return icetImageUnpackageFromReceive( + (IceTVoid *)icetUnsafeStateGetBuffer(pname)); +} + +IceTImage icetGetStatePointerImage(IceTEnum pname, + IceTSizeType width, + IceTSizeType height, + const IceTVoid *color_buffer, + const IceTVoid *depth_buffer) +{ + IceTVoid *buffer; + IceTSizeType buffer_size; + + buffer_size = icetImagePointerBufferSize(); + buffer = icetGetStateBuffer(pname, buffer_size); + + return icetImagePointerAssignBuffer( + buffer, width, height, color_buffer, depth_buffer); +} + IceTImage icetImageAssignBuffer(IceTVoid *buffer, IceTSizeType width, IceTSizeType height) @@ -357,6 +408,62 @@ IceTImage icetImageAssignBuffer(IceTVoid *buffer, return image; } +IceTImage icetImagePointerAssignBuffer(IceTVoid *buffer, + IceTSizeType width, + IceTSizeType height, + const IceTVoid *color_buffer, + const IceTVoid *depth_buffer) +{ + /* This is a bit hacky, but most of the entries for regular images and + * pointer images are the same. Use that function to fill in most of + * the entries and fix those that are different. */ + IceTImage image = icetImageAssignBuffer(buffer, width, height); + + { + IceTInt *header = ICET_IMAGE_HEADER(image); + /* Our magic number is different. */ + header[ICET_IMAGE_MAGIC_NUM_INDEX] = ICET_IMAGE_POINTERS_MAGIC_NUM; + /* It is invalid to use this type of image as a single buffer. */ + header[ICET_IMAGE_ACTUAL_BUFFER_SIZE_INDEX] = -1; + } + + /* Check that the image buffers make sense. */ + if (icetImageGetColorFormat(image) == ICET_IMAGE_COLOR_NONE) { + if (color_buffer != NULL) { + icetRaiseError( + "Given a color buffer when color format is set to none.", + ICET_INVALID_VALUE); + } + } else { + if (color_buffer == NULL) { + icetRaiseError( + "Not given a color buffer when color format requires one.", + ICET_INVALID_VALUE); + } + } + if (icetImageGetDepthFormat(image) == ICET_IMAGE_DEPTH_NONE) { + if (depth_buffer != NULL) { + icetRaiseError( + "Given a depth buffer when depth format is set to none.", + ICET_INVALID_VALUE); + } + } else { + if (depth_buffer == NULL) { + icetRaiseError( + "Not given a depth buffer when depth format requires one.", + ICET_INVALID_VALUE); + } + } + + { + const IceTVoid **data = ICET_IMAGE_DATA(image); + data[0] = color_buffer; + data[1] = depth_buffer; + } + + return image; +} + IceTImage icetImageNull(void) { IceTImage image; @@ -584,11 +691,14 @@ void icetImageSetDimensions(IceTImage image, ICET_IMAGE_HEADER(image)[ICET_IMAGE_WIDTH_INDEX] = (IceTInt)width; ICET_IMAGE_HEADER(image)[ICET_IMAGE_HEIGHT_INDEX] = (IceTInt)height; - ICET_IMAGE_HEADER(image)[ICET_IMAGE_ACTUAL_BUFFER_SIZE_INDEX] - = (IceTInt)icetImageBufferSizeType(icetImageGetColorFormat(image), - icetImageGetDepthFormat(image), - width, - height); + if ( ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX] + == ICET_IMAGE_MAGIC_NUM) { + ICET_IMAGE_HEADER(image)[ICET_IMAGE_ACTUAL_BUFFER_SIZE_INDEX] + = (IceTInt)icetImageBufferSizeType(icetImageGetColorFormat(image), + icetImageGetDepthFormat(image), + width, + height); + } } void icetSparseImageSetDimensions(IceTSparseImage image, @@ -638,12 +748,29 @@ const IceTVoid *icetImageGetColorConstVoid(const IceTImage image, *pixel_size = colorPixelSize(color_format); } - return ICET_IMAGE_DATA(image); + switch (ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX]) { + case ICET_IMAGE_MAGIC_NUM: + return ICET_IMAGE_DATA(image); + case ICET_IMAGE_POINTERS_MAGIC_NUM: + return ((const IceTVoid **)ICET_IMAGE_DATA(image))[0]; + default: + icetRaiseError("Detected invalid image header.", + ICET_SANITY_CHECK_FAIL); + return NULL; + } } IceTVoid *icetImageGetColorVoid(IceTImage image, IceTSizeType *pixel_size) { const IceTVoid *const_buffer = icetImageGetColorConstVoid(image, pixel_size); + /* Raise an exception for images made of pointers, which we set as constant + * since all internally made pointers are single buffers. */ + if ( ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX] + == ICET_IMAGE_POINTERS_MAGIC_NUM) { + icetRaiseError("Images of pointers are for reading only.", + ICET_SANITY_CHECK_FAIL); + } + /* This const cast is OK because we actually got the pointer from a non-const image. */ return (IceTVoid *)const_buffer; @@ -663,11 +790,15 @@ const IceTUByte *icetImageGetColorcub(const IceTImage image) } IceTUByte *icetImageGetColorub(IceTImage image) { - const IceTUByte *const_buffer = icetImageGetColorcub(image); + IceTEnum color_format = icetImageGetColorFormat(image); - /* This const cast is OK because we actually got the pointer from a - non-const image. */ - return (IceTUByte *)const_buffer; + if (color_format != ICET_IMAGE_COLOR_RGBA_UBYTE) { + icetRaiseError("Color format is not of type ubyte.", + ICET_INVALID_OPERATION); + return NULL; + } + + return icetImageGetColorVoid(image, NULL); } const IceTUInt *icetImageGetColorcui(const IceTImage image) { @@ -691,41 +822,62 @@ const IceTFloat *icetImageGetColorcf(const IceTImage image) } IceTFloat *icetImageGetColorf(IceTImage image) { - const IceTFloat *const_buffer = icetImageGetColorcf(image); + IceTEnum color_format = icetImageGetColorFormat(image); - - /* This const cast is OK because we actually got the pointer from a - non-const image. */ - return (IceTFloat *)const_buffer; + if (color_format != ICET_IMAGE_COLOR_RGBA_FLOAT) { + icetRaiseError("Color format is not of type float.", + ICET_INVALID_OPERATION); + return NULL; + } + + return icetImageGetColorVoid(image, NULL); } const IceTVoid *icetImageGetDepthConstVoid(const IceTImage image, IceTSizeType *pixel_size) { IceTEnum color_format = icetImageGetColorFormat(image); - IceTSizeType color_format_bytes; - const IceTByte *image_data_pointer; if (pixel_size) { IceTEnum depth_format = icetImageGetDepthFormat(image); *pixel_size = depthPixelSize(depth_format); } - color_format_bytes = ( icetImageGetNumPixels(image) - * colorPixelSize(color_format) ); + switch (ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX]) { + case ICET_IMAGE_MAGIC_NUM: + { + IceTSizeType color_format_bytes = ( icetImageGetNumPixels(image) + * colorPixelSize(color_format) ); - /* Cast to IceTByte to ensure pointer arithmetic is correct. */ - image_data_pointer = (const IceTByte*)ICET_IMAGE_DATA(image); + /* Cast to IceTByte to ensure pointer arithmetic is correct. */ + const IceTByte *image_data_pointer = + (const IceTByte*)ICET_IMAGE_DATA(image); - return image_data_pointer + color_format_bytes; + return image_data_pointer + color_format_bytes; + } + case ICET_IMAGE_POINTERS_MAGIC_NUM: + return ((const IceTVoid **)ICET_IMAGE_DATA(image))[1]; + default: + icetRaiseError("Detected invalid image header.", + ICET_SANITY_CHECK_FAIL); + return NULL; + } } IceTVoid *icetImageGetDepthVoid(IceTImage image, IceTSizeType *pixel_size) { const IceTVoid *const_buffer =icetImageGetDepthConstVoid(image, pixel_size); + /* Raise an exception for images made of pointers, which we set as constant + * since all internally made pointers are single buffers. */ + if ( ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX] + == ICET_IMAGE_POINTERS_MAGIC_NUM) { + icetRaiseError("Images of pointers are for reading only.", + ICET_SANITY_CHECK_FAIL); + } + /* This const cast is OK because we actually got the pointer from a non-const image. */ - return (IceTVoid *)const_buffer; + return (IceTVoid *)const_buffer; } const IceTFloat *icetImageGetDepthcf(const IceTImage image) { @@ -741,12 +893,15 @@ const IceTFloat *icetImageGetDepthcf(const IceTImage image) } IceTFloat *icetImageGetDepthf(IceTImage image) { - const IceTFloat *const_buffer = icetImageGetDepthcf(image); + IceTEnum depth_format = icetImageGetDepthFormat(image); - - /* This const cast is OK because we actually got the pointer from a - non-const image. */ - return (IceTFloat *)const_buffer; + if (depth_format != ICET_IMAGE_DEPTH_FLOAT) { + icetRaiseError("Depth format is not of type float.", + ICET_INVALID_OPERATION); + return NULL; + } + + return icetImageGetDepthVoid(image, NULL); } void icetImageCopyColorub(const IceTImage image, @@ -889,7 +1044,7 @@ void icetImageCopyPixels(const IceTImage in_image, IceTSizeType in_offset, const IceTByte *in_colors; /* Use IceTByte for pointer arithmetic */ IceTByte *out_colors; IceTSizeType pixel_size; - in_colors = icetImageGetColorVoid(in_image, &pixel_size); + in_colors = icetImageGetColorConstVoid(in_image, &pixel_size); out_colors = icetImageGetColorVoid(out_image, NULL); memcpy(out_colors + pixel_size*out_offset, in_colors + pixel_size*in_offset, @@ -900,7 +1055,7 @@ void icetImageCopyPixels(const IceTImage in_image, IceTSizeType in_offset, const IceTByte *in_depths; /* Use IceTByte for pointer arithmetic */ IceTByte *out_depths; IceTSizeType pixel_size; - in_depths = icetImageGetDepthVoid(in_image, &pixel_size); + in_depths = icetImageGetDepthConstVoid(in_image, &pixel_size); out_depths = icetImageGetDepthVoid(out_image, NULL); memcpy(out_depths + pixel_size*out_offset, in_depths + pixel_size*in_offset, @@ -933,7 +1088,7 @@ void icetImageCopyRegion(const IceTImage in_image, if (color_format != ICET_IMAGE_COLOR_NONE) { IceTSizeType pixel_size; /* Use IceTByte for byte-based pointer arithmetic. */ - const IceTByte *src = icetImageGetColorVoid(in_image, &pixel_size); + const IceTByte *src = icetImageGetColorConstVoid(in_image, &pixel_size); IceTByte *dest = icetImageGetColorVoid(out_image, &pixel_size); IceTSizeType y; @@ -955,7 +1110,7 @@ void icetImageCopyRegion(const IceTImage in_image, if (depth_format != ICET_IMAGE_DEPTH_NONE) { IceTSizeType pixel_size; /* Use IceTByte for byte-based pointer arithmetic. */ - const IceTByte *src = icetImageGetDepthVoid(in_image, &pixel_size); + const IceTByte *src = icetImageGetDepthConstVoid(in_image, &pixel_size); IceTByte *dest = icetImageGetDepthVoid(out_image, &pixel_size); IceTSizeType y; @@ -1096,6 +1251,14 @@ void icetImagePackageForSend(IceTImage image, *buffer = image.opaque_internals; *size = ICET_IMAGE_HEADER(image)[ICET_IMAGE_ACTUAL_BUFFER_SIZE_INDEX]; + if (*size < 0) { + /* Images of pointers have less than zero size to alert they are not + * real buffers. */ + icetRaiseError( + "Attempting to package an image that is not a single buffer.", + ICET_SANITY_CHECK_FAIL); + } + if (*size != icetImageBufferSizeType(icetImageGetColorFormat(image), icetImageGetDepthFormat(image), icetImageGetWidth(image), @@ -1108,13 +1271,15 @@ void icetImagePackageForSend(IceTImage image, IceTImage icetImageUnpackageFromReceive(IceTVoid *buffer) { IceTImage image; + IceTEnum magic_number; IceTEnum color_format, depth_format; image.opaque_internals = buffer; /* Check the image for validity. */ - if ( ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX] - != ICET_IMAGE_MAGIC_NUM ) { + magic_number = ICET_IMAGE_HEADER(image)[ICET_IMAGE_MAGIC_NUM_INDEX]; + if ( (magic_number != ICET_IMAGE_MAGIC_NUM) + && (magic_number != ICET_IMAGE_POINTERS_MAGIC_NUM) ) { icetRaiseError("Invalid image buffer: no magic number.", ICET_INVALID_VALUE); image.opaque_internals = NULL; @@ -1140,13 +1305,26 @@ IceTImage icetImageUnpackageFromReceive(IceTVoid *buffer) return image; } - if ( icetImageBufferSizeType(color_format, depth_format, - icetImageGetWidth(image), - icetImageGetHeight(image)) - != ICET_IMAGE_HEADER(image)[ICET_IMAGE_ACTUAL_BUFFER_SIZE_INDEX] ) { - icetRaiseError("Inconsistent sizes in image data.", ICET_INVALID_VALUE); - image.opaque_internals = NULL; - return image; + if (magic_number == ICET_IMAGE_MAGIC_NUM) { + IceTSizeType buffer_size = + ICET_IMAGE_HEADER(image)[ICET_IMAGE_ACTUAL_BUFFER_SIZE_INDEX]; + if ( icetImageBufferSizeType(color_format, depth_format, + icetImageGetWidth(image), + icetImageGetHeight(image)) + != buffer_size ) { + icetRaiseError("Inconsistent sizes in image data.", ICET_INVALID_VALUE); + image.opaque_internals = NULL; + return image; + } + } else { + IceTSizeType buffer_size = + ICET_IMAGE_HEADER(image)[ICET_IMAGE_ACTUAL_BUFFER_SIZE_INDEX]; + if (buffer_size != -1) { + icetRaiseError("Size information not consistent with image type.", + ICET_INVALID_VALUE); + image.opaque_internals = NULL; + return image; + } } /* The source may have used a bigger buffer than allocated here at the @@ -1261,7 +1439,7 @@ static void icetSparseImageScanPixels(const IceTVoid **in_data_p, out_data += RUN_LENGTH_SIZE; \ INACTIVE_RUN_LENGTH(last_out_run_length) = 0; \ ACTIVE_RUN_LENGTH(last_out_run_length) = 0; \ - } + } if (out_data_p != NULL) { out_data = *out_data_p; @@ -1656,6 +1834,8 @@ void icetSparseImageInterlace(const IceTSparseImage in_image, return; } + icetTimingInterlaceBegin(); + pixel_size = colorPixelSize(color_format) + depthPixelSize(depth_format); { @@ -1746,6 +1926,8 @@ void icetSparseImageInterlace(const IceTSparseImage in_image, } icetSparseImageSetActualSize(out_image, out_data); + + icetTimingInterlaceEnd(); } IceTSizeType icetGetInterlaceOffset(IceTInt partition_index, @@ -1763,6 +1945,8 @@ IceTSizeType icetGetInterlaceOffset(IceTInt partition_index, return 0; } + icetTimingInterlaceBegin(); + lower_partition_size = original_image_size/eventual_num_partitions; remaining_pixels = original_image_size%eventual_num_partitions; @@ -1782,6 +1966,7 @@ IceTSizeType icetGetInterlaceOffset(IceTInt partition_index, if (interlaced_partition_idx == partition_index) { /* Found any partitions before this one. */ + icetTimingInterlaceEnd(); return offset; } @@ -1795,6 +1980,7 @@ IceTSizeType icetGetInterlaceOffset(IceTInt partition_index, /* Should never get here. */ icetRaiseError("Could not find partition index.", ICET_SANITY_CHECK_FAIL); + icetTimingInterlaceEnd(); return 0; } @@ -1877,7 +2063,8 @@ void icetGetTileImage(IceTInt tile, IceTImage image) height = viewports[4*tile+3]; icetImageSetDimensions(image, width, height); - rendered_image = renderTile(tile, screen_viewport, target_viewport, image); + rendered_image = + generateTile(tile, screen_viewport, target_viewport, image); icetTimingBufferReadBegin(); @@ -1887,7 +2074,7 @@ void icetGetTileImage(IceTInt tile, IceTImage image) || (screen_viewport[1] != target_viewport[1]) || (screen_viewport[2] != target_viewport[2]) || (screen_viewport[3] != target_viewport[3]) ) { - icetRaiseError("Inconsistent values returned from renderTile.", + icetRaiseError("Inconsistent values returned from generateTile.", ICET_SANITY_CHECK_FAIL); } } else { @@ -1914,8 +2101,8 @@ void icetGetCompressedTileImage(IceTInt tile, IceTSparseImage compressed_image) height = viewports[4*tile+3]; icetSparseImageSetDimensions(compressed_image, width, height); - raw_image = renderTile(tile, screen_viewport, target_viewport, - icetImageNull()); + raw_image = generateTile(tile, screen_viewport, target_viewport, + icetImageNull()); if ((target_viewport[2] < 1) || (target_viewport[3] < 1)) { /* Tile empty. Just clear result. */ @@ -2297,6 +2484,20 @@ void icetClearImageTrueBackground(IceTImage image) icetStateSetInteger(ICET_BACKGROUND_COLOR_WORD, original_background_word); } +static IceTImage generateTile(int tile, + IceTInt *screen_viewport, + IceTInt *target_viewport, + IceTImage tile_buffer) +{ + IceTBoolean use_prerender; + icetGetBooleanv(ICET_PRE_RENDERED, &use_prerender); + if (use_prerender) { + return prerenderedTile(tile, screen_viewport, target_viewport); + } else { + return renderTile(tile, screen_viewport, target_viewport, tile_buffer); + } +} + static IceTImage renderTile(int tile, IceTInt *screen_viewport, IceTInt *target_viewport, @@ -2340,12 +2541,17 @@ static IceTImage renderTile(int tile, || (contained_viewport[1] > tile_viewport[1] + tile_viewport[3]) ) { /* Case 0: geometry completely outside tile. */ icetRaiseDebug("Case 0: geometry completely outside tile."); - screen_viewport[0] = target_viewport[0] = 0; - screen_viewport[1] = target_viewport[1] = 0; - screen_viewport[2] = target_viewport[2] = 0; - screen_viewport[3] = target_viewport[3] = 0; - /* Don't bother to render. */ - return tile_buffer; + readback_viewport[0] = screen_viewport[0] = target_viewport[0] = 0; + readback_viewport[1] = screen_viewport[1] = target_viewport[1] = 0; + readback_viewport[2] = screen_viewport[2] = target_viewport[2] = 0; + readback_viewport[3] = screen_viewport[3] = target_viewport[3] = 0; + if (!icetIsEnabled(ICET_RENDER_EMPTY_IMAGES)) { + /* Don't bother to render. */ + return tile_buffer; + } else { + /* Give renderer right projection even if we ignore the result. */ + icetProjectTile(tile, projection_matrix); + } #if 1 } else if ( (contained_viewport[0] >= tile_viewport[0]) && (contained_viewport[1] >= tile_viewport[1]) @@ -2522,42 +2728,47 @@ static IceTImage renderTile(int tile, return render_buffer; } -/* This function is full of hackery. */ +static IceTImage prerenderedTile(int tile, + IceTInt *screen_viewport, + IceTInt *target_viewport) +{ + const IceTInt *contained_viewport; + const IceTInt *tile_viewport; + + icetRaiseDebug1("Getting viewport for tile %d in prerendered image", tile); + contained_viewport = icetUnsafeStateGetInteger(ICET_CONTAINED_VIEWPORT); + tile_viewport = icetUnsafeStateGetInteger(ICET_TILE_VIEWPORTS) + 4*tile; + + /* The screen viewport is the intersection of the tile viewport with the + * contained viewport. */ + icetIntersectViewports(tile_viewport, contained_viewport, screen_viewport); + + /* The target viewport is the same width-height as the screen viewport. + * It is offset by the same amount the screen viewport is offset from the + * tile viewport. */ + target_viewport[0] = screen_viewport[0] - tile_viewport[0]; + target_viewport[1] = screen_viewport[1] - tile_viewport[1]; + target_viewport[2] = screen_viewport[2]; + target_viewport[3] = screen_viewport[3]; + + return icetRetrieveStateImage(ICET_RENDER_BUFFER); +} + static IceTImage getRenderBuffer(void) { /* Check to see if we are in the same frame as the last time we returned this buffer. In that case, just restore the buffer because it still has the image we need. */ - if ( icetStateGetTime(ICET_RENDER_BUFFER_HOLD) + if ( icetStateGetTime(ICET_RENDER_BUFFER) > icetStateGetTime(ICET_IS_DRAWING_FRAME) ) { - /* A little bit of hackery: this assumes that a buffer initialized is the - same one returned from icetImagePackageForSend. It (currently) - does. */ - IceTVoid *buffer; - icetRaiseDebug("Last render should still be good."); - icetGetPointerv(ICET_RENDER_BUFFER_HOLD, &buffer); - return icetImageUnpackageFromReceive(buffer); + return icetRetrieveStateImage(ICET_RENDER_BUFFER); } else { IceTInt dim[2]; - IceTImage image; - IceTVoid *buffer; - IceTSizeType dummy_size; icetGetIntegerv(ICET_PHYSICAL_RENDER_WIDTH, &dim[0]); icetGetIntegerv(ICET_PHYSICAL_RENDER_HEIGHT, &dim[1]); /* Create a new image object. */ - image = icetGetStateBufferImage(ICET_RENDER_BUFFER, dim[0], dim[1]); - - /* Record image size and pointer to memory. It is important to "touch" - ICET_RENDER_BUFFER_HOLD to signify the time we created the image so - that the above check works on the next call. */ - - icetStateSetIntegerv(ICET_RENDER_BUFFER_SIZE, 2, dim); - - icetImagePackageForSend(image, &buffer, &dummy_size); - icetStateSetPointer(ICET_RENDER_BUFFER_HOLD, buffer); - - return image; + return icetGetStateBufferImage(ICET_RENDER_BUFFER, dim[0], dim[1]); } } diff --git src/ice-t/projections.c src/ice-t/projections.c index 8fe46d4..14fafc5 100644 --- src/ice-t/projections.c +++ src/ice-t/projections.c @@ -18,6 +18,13 @@ #include #include +#ifndef MIN +#define MIN(x, y) ((x) < (y) ? (x) : (y)) +#endif +#ifndef MAX +#define MAX(x, y) ((x) < (y) ? (y) : (x)) +#endif + static void update_tile_projections(void); @@ -173,3 +180,36 @@ static void update_tile_projections(void) tile_projections + 16*tile_idx); } } + +void icetIntersectViewports(const IceTInt *src_viewport1, + const IceTInt *src_viewport2, + IceTInt *dest_viewport) +{ + const IceTInt min_x1 = src_viewport1[0]; + const IceTInt max_x1 = min_x1 + src_viewport1[2]; + const IceTInt min_y1 = src_viewport1[1]; + const IceTInt max_y1 = min_y1 + src_viewport1[3]; + + const IceTInt min_x2 = src_viewport2[0]; + const IceTInt max_x2 = min_x2 + src_viewport2[2]; + const IceTInt min_y2 = src_viewport2[1]; + const IceTInt max_y2 = min_y2 + src_viewport2[3]; + + const IceTInt min_x = MAX(min_x1, min_x2); + const IceTInt min_y = MAX(min_y1, min_y2); + const IceTInt max_x = MIN(max_x1, max_x2); + const IceTInt max_y = MIN(max_y1, max_y2); + + const IceTInt width = max_x - min_x; + const IceTInt height = max_y - min_y; + + if ((width > 0) && (height > 0)) { + dest_viewport[0] = min_x; + dest_viewport[1] = min_y; + dest_viewport[2] = width; + dest_viewport[3] = height; + } else { + dest_viewport[0] = dest_viewport[1] = -1000000; + dest_viewport[2] = dest_viewport[3] = 0; + } +} diff --git src/ice-t/state.c src/ice-t/state.c index d6b111b..29aa88d 100644 --- src/ice-t/state.c +++ src/ice-t/state.c @@ -28,6 +28,7 @@ struct IceTStateValue { IceTEnum type; IceTSizeType num_entries; + IceTSizeType buffer_size; void *data; IceTTimeStamp mod_time; }; @@ -194,9 +195,9 @@ void icetStateSetDefaults(void) icetEnable(ICET_COMPOSITE_ONE_BUFFER); icetEnable(ICET_INTERLACE_IMAGES); icetEnable(ICET_COLLECT_IMAGES); + icetDisable(ICET_RENDER_EMPTY_IMAGES); icetStateSetBoolean(ICET_IS_DRAWING_FRAME, 0); - icetStateSetBoolean(ICET_RENDER_BUFFER_SIZE, 0); icetStateSetInteger(ICET_VALID_PIXELS_TILE, -1); icetStateSetInteger(ICET_VALID_PIXELS_OFFSET, 0); @@ -450,7 +451,7 @@ static const IceTByte g_post_padding[STATE_PADDING_SIZE] = { static void stateCheck(IceTEnum pname, const IceTState state) { if (state[pname].type != ICET_NULL) { - if (state[pname].num_entries > 0) { + if (state[pname].buffer_size > 0) { IceTSizeType i; IceTByte *padding; padding = STATE_DATA_PRE_PADDING(pname, state); @@ -479,7 +480,7 @@ static void stateCheck(IceTEnum pname, const IceTState state) if (state[pname].data != NULL) { char message[256]; sprintf(message, - "State variable 0x%X has zero entries but" + "State variable 0x%X has zero sized buffer but" " non-null pointer.", pname); icetRaiseError(message, ICET_SANITY_CHECK_FAIL); @@ -503,6 +504,15 @@ static void stateCheck(IceTEnum pname, const IceTState state) (int)state[pname].num_entries); icetRaiseError(message, ICET_SANITY_CHECK_FAIL); } + if (state[pname].buffer_size != 0) { + char message[256]; + sprintf(message, + "State variable 0x%X has ICET_NULL type but" + " also has a buffer of size %d (!= 0).", + pname, + (int)state[pname].buffer_size); + icetRaiseError(message, ICET_SANITY_CHECK_FAIL); + } } } #else /* ICET_STATE_CHECK_MEM */ @@ -517,32 +527,43 @@ static IceTVoid *stateAllocate(IceTEnum pname, IceTEnum type, IceTState state) { - IceTVoid *buffer; - stateCheck(pname, state); + if (num_entries < 0) { + icetRaiseError("Asked to allocate buffer of negative size", + ICET_SANITY_CHECK_FAIL); + } + if ( (num_entries == state[pname].num_entries) && (type == state[pname].type) ) { - /* Return the current buffer. */ + /* Current buffer already configured correctly. */ state[pname].mod_time = icetGetTimeStamp(); - buffer = state[pname].data; - } else if (num_entries > 0) { - stateFree(pname, state); - /* Create a new buffer. */ - buffer = malloc(STATE_DATA_ALLOCATE(type, num_entries)); - if (buffer == NULL) { - icetRaiseError("Could not allocate memory for state variable.", - ICET_OUT_OF_MEMORY); - return NULL; - } + } else if ((num_entries > 0) || (state[pname].buffer_size > 0)) { + IceTSizeType buffer_size = STATE_DATA_ALLOCATE(type, num_entries); + if (buffer_size < state[pname].buffer_size) { + /* Reuse larger buffer. */ + stateCheck(pname, state); + } else { + /* Create a new buffer. */ + IceTVoid *buffer; + + stateFree(pname, state); + buffer = malloc(STATE_DATA_ALLOCATE(type, num_entries)); + if (buffer == NULL) { + icetRaiseError("Could not allocate memory for state variable.", + ICET_OUT_OF_MEMORY); + return NULL; + } #ifdef ICET_STATE_CHECK_MEM - /* Skip past padding. */ - buffer = (IceTByte *)buffer + STATE_PADDING_SIZE; + /* Skip past padding. */ + buffer = (IceTByte *)buffer + STATE_PADDING_SIZE; #endif + state[pname].buffer_size = buffer_size; + state[pname].data = buffer; + } state[pname].type = type; state[pname].num_entries = num_entries; - state[pname].data = buffer; state[pname].mod_time = icetGetTimeStamp(); #ifdef ICET_STATE_CHECK_MEM @@ -561,25 +582,24 @@ static IceTVoid *stateAllocate(IceTEnum pname, } #endif } else { /* num_entries <= 0 */ - buffer = NULL; - state[pname].type = type; state[pname].num_entries = 0; - state[pname].data = buffer; + state[pname].buffer_size = 0; + state[pname].data = NULL; state[pname].mod_time = icetGetTimeStamp(); } #ifdef ICET_STATE_CHECK_MEM - memset(buffer, 0xDC, STATE_DATA_WIDTH(type, num_entries)); + memset(state[pname].data, 0xDC, STATE_DATA_WIDTH(type, num_entries)); #endif - return buffer; + return state[pname].data; } static void stateFree(IceTEnum pname, IceTState state) { stateCheck(pname, state); - if ((state[pname].type != ICET_NULL) && (state[pname].num_entries > 0)) { + if ((state[pname].type != ICET_NULL) && (state[pname].buffer_size > 0)) { #ifdef ICET_STATE_CHECK_MEM free(STATE_DATA_PRE_PADDING(pname, state)); #else @@ -587,6 +607,7 @@ static void stateFree(IceTEnum pname, IceTState state) #endif state[pname].type = ICET_NULL; state[pname].num_entries = 0; + state[pname].buffer_size = 0; state[pname].data = NULL; state[pname].mod_time = 0; } @@ -612,9 +633,9 @@ static void *icetUnsafeStateGet(IceTEnum pname, IceTEnum type) stateCheck(pname, icetGetState()); if (icetGetState()[pname].type != type) { - icetRaiseError("Mismatched types in unsafe state get.", - ICET_SANITY_CHECK_FAIL); - return NULL; + icetRaiseError("Mismatched types in unsafe state get.", + ICET_SANITY_CHECK_FAIL); + return NULL; } return icetGetState()[pname].data; } @@ -639,6 +660,10 @@ const IceTVoid **icetUnsafeStateGetPointer(IceTEnum pname) { return icetUnsafeStateGet(pname, ICET_POINTER); } +const IceTVoid *icetUnsafeStateGetBuffer(IceTEnum pname) +{ + return icetUnsafeStateGet(pname, ICET_VOID); +} IceTDouble *icetStateAllocateDouble(IceTEnum pname, IceTSizeType num_entries) { @@ -663,16 +688,6 @@ IceTVoid **icetStateAllocatePointer(IceTEnum pname, IceTSizeType num_entries) IceTVoid *icetGetStateBuffer(IceTEnum pname, IceTSizeType num_bytes) { - if ( (icetStateGetType(pname) == ICET_VOID) - && (icetStateGetNumEntries(pname) >= num_bytes) ) { - /* A big enough buffer is already allocated. */ - IceTVoid *buffer = icetUnsafeStateGet(pname, ICET_VOID); -#ifdef ICET_STATE_CHECK_MEM - memset(buffer, 0xDC, num_bytes); -#endif - return buffer; - } - /* Check to make sure this state variable has not been used for anything * besides a buffer. */ if ( (icetStateGetType(pname) != ICET_VOID) diff --git src/ice-t/tiles.c src/ice-t/tiles.c index 916f65c..d0b3c0a 100644 --- src/ice-t/tiles.c +++ src/ice-t/tiles.c @@ -40,7 +40,7 @@ void icetResetTiles(void) #define MAX(x, y) ((x) >= (y) ? (x) : (y)) #endif int icetAddTile(IceTInt x, IceTInt y, IceTSizeType width, IceTSizeType height, - int display_rank) + int display_rank) { IceTInt num_tiles; IceTInt *viewports; @@ -69,26 +69,26 @@ int icetAddTile(IceTInt x, IceTInt y, IceTSizeType width, IceTSizeType height, /* Check and update display ranks. */ if (display_rank >= num_processors) { - sprintf(msg, "icetDisplayNodes: Invalid rank for tile %d.", - (int)num_tiles); - icetRaiseError(msg, ICET_INVALID_VALUE); - free(display_nodes); - return -1; + sprintf(msg, "icetDisplayNodes: Invalid rank for tile %d.", + (int)num_tiles); + icetRaiseError(msg, ICET_INVALID_VALUE); + free(display_nodes); + return -1; } for (i = 0; i < num_tiles; i++) { - if (display_nodes[i] == display_rank) { - sprintf(msg, "icetDisplayNodes: Rank %d used for tiles %d and %d.", - display_rank, i, (int)num_tiles); - icetRaiseError(msg, ICET_INVALID_VALUE); - free(display_nodes); - return -1; - } + if (display_nodes[i] == display_rank) { + sprintf(msg, "icetDisplayNodes: Rank %d used for tiles %d and %d.", + display_rank, i, (int)num_tiles); + icetRaiseError(msg, ICET_INVALID_VALUE); + free(display_nodes); + return -1; + } } display_nodes[num_tiles] = display_rank; icetStateSetIntegerv(ICET_DISPLAY_NODES, num_tiles+1, display_nodes); free(display_nodes); if (display_rank == rank) { - icetStateSetInteger(ICET_TILE_DISPLAYED, num_tiles); + icetStateSetInteger(ICET_TILE_DISPLAYED, num_tiles); } /* Get viewports. */ @@ -99,10 +99,10 @@ int icetAddTile(IceTInt x, IceTInt y, IceTSizeType width, IceTSizeType height, gvp[0] = x; gvp[1] = y; gvp[2] = x + (IceTInt)width; gvp[3] = y + (IceTInt)height; for (i = 0; i < num_tiles; i++) { - gvp[0] = MIN(gvp[0], viewports[i*4+0]); - gvp[1] = MIN(gvp[1], viewports[i*4+1]); - gvp[2] = MAX(gvp[2], viewports[i*4+0] + viewports[i*4+2]); - gvp[3] = MAX(gvp[3], viewports[i*4+1] + viewports[i*4+3]); + gvp[0] = MIN(gvp[0], viewports[i*4+0]); + gvp[1] = MIN(gvp[1], viewports[i*4+1]); + gvp[2] = MAX(gvp[2], viewports[i*4+0] + viewports[i*4+2]); + gvp[3] = MAX(gvp[3], viewports[i*4+1] + viewports[i*4+3]); } gvp[2] -= gvp[0]; gvp[3] -= gvp[1]; @@ -142,8 +142,8 @@ void icetPhysicalRenderSize(IceTInt width, IceTInt height) icetGetIntegerv(ICET_TILE_MAX_WIDTH, &max_width); icetGetIntegerv(ICET_TILE_MAX_HEIGHT, &max_height); if ((width < max_width) || (height < max_height)) { - icetRaiseWarning("Physical render dimensions not large enough" - " to render all tiles.", ICET_INVALID_VALUE); + icetRaiseWarning("Physical render dimensions not large enough" + " to render all tiles.", ICET_INVALID_VALUE); } icetStateSetInteger(ICET_PHYSICAL_RENDER_WIDTH, width); @@ -151,8 +151,8 @@ void icetPhysicalRenderSize(IceTInt width, IceTInt height) } void icetBoundingBoxd(IceTDouble x_min, IceTDouble x_max, - IceTDouble y_min, IceTDouble y_max, - IceTDouble z_min, IceTDouble z_max) + IceTDouble y_min, IceTDouble y_max, + IceTDouble z_min, IceTDouble z_max) { IceTDouble vertices[8*3]; @@ -170,26 +170,33 @@ void icetBoundingBoxd(IceTDouble x_min, IceTDouble x_max, } void icetBoundingBoxf(IceTFloat x_min, IceTFloat x_max, - IceTFloat y_min, IceTFloat y_max, - IceTFloat z_min, IceTFloat z_max) + IceTFloat y_min, IceTFloat y_max, + IceTFloat z_min, IceTFloat z_max) { icetBoundingBoxd(x_min, x_max, y_min, y_max, z_min, z_max); } void icetBoundingVertices(IceTInt size, IceTEnum type, IceTSizeType stride, - IceTSizeType count, const IceTVoid *pointer) + IceTSizeType count, const IceTVoid *pointer) { IceTDouble *verts; int i, j; + if (count < 1) { + /* No vertices. (Must be clearing them out.) */ + icetStateSetDoublev(ICET_GEOMETRY_BOUNDS, 0, NULL); + icetStateSetInteger(ICET_NUM_BOUNDING_VERTS, 0); + return; + } + if (stride < 1) { stride = size*icetTypeWidth(type); } verts = malloc(count*3*sizeof(IceTDouble)); for (i = 0; i < count; i++) { - for (j = 0; j < 3; j++) { - switch (type) { + for (j = 0; j < 3; j++) { + switch (type) { #define castcopy(ptype) \ if (j < size) { \ verts[i*3+j] = ((ptype *)pointer)[i*stride/sizeof(type)+j]; \ @@ -200,21 +207,21 @@ void icetBoundingVertices(IceTInt size, IceTEnum type, IceTSizeType stride, verts[i*3+j] /= ((ptype *)pointer)[i*stride/sizeof(type)+4]; \ } \ break; - case ICET_SHORT: - castcopy(IceTShort); - case ICET_INT: - castcopy(IceTInt); - case ICET_FLOAT: - castcopy(IceTFloat); - case ICET_DOUBLE: - castcopy(IceTDouble); - default: - icetRaiseError("Bad type to icetBoundingVertices.", - ICET_INVALID_ENUM); - free(verts); - return; - } - } + case ICET_SHORT: + castcopy(IceTShort); + case ICET_INT: + castcopy(IceTInt); + case ICET_FLOAT: + castcopy(IceTFloat); + case ICET_DOUBLE: + castcopy(IceTDouble); + default: + icetRaiseError("Bad type to icetBoundingVertices.", + ICET_INVALID_ENUM); + free(verts); + return; + } + } } icetStateSetDoublev(ICET_GEOMETRY_BOUNDS, count*3, verts); diff --git src/ice-t/timing.c src/ice-t/timing.c index 445b56c..25af7ca 100644 --- src/ice-t/timing.c +++ src/ice-t/timing.c @@ -34,6 +34,7 @@ void icetStateResetTiming(void) icetStateSetDouble(ICET_BUFFER_READ_TIME, 0.0); icetStateSetDouble(ICET_BUFFER_WRITE_TIME, 0.0); icetStateSetDouble(ICET_COMPRESS_TIME, 0.0); + icetStateSetDouble(ICET_INTERLACE_TIME, 0.0); icetStateSetDouble(ICET_BLEND_TIME, 0.0); icetStateSetDouble(ICET_COMPOSITE_TIME, 0.0); icetStateSetDouble(ICET_COLLECT_TIME, 0.0); @@ -103,7 +104,8 @@ static void icetTimingEnd(IceTEnum start_pname, IceTDouble old_time; icetGetDoublev(start_pname, &start_time); icetGetDoublev(result_pname, &old_time); - icetStateSetDouble(result_pname, icetWallTime() - start_time); + icetStateSetDouble(result_pname, + old_time + (icetWallTime() - start_time)); } } @@ -167,6 +169,21 @@ void icetTimingCompressEnd(void) "compress"); } +void icetTimingInterlaceBegin(void) +{ + icetTimingBegin(ICET_SUBFUNC_START_TIME, + ICET_SUBFUNC_TIME_ID, + ICET_INTERLACE_TIME, + "interlace"); +} +void icetTimingInterlaceEnd(void) +{ + icetTimingEnd(ICET_SUBFUNC_START_TIME, + ICET_SUBFUNC_TIME_ID, + ICET_INTERLACE_TIME, + "interlace"); +} + void icetTimingBlendBegin(void) { icetTimingBegin(ICET_SUBFUNC_START_TIME, diff --git src/include/IceT.h src/include/IceT.h index 3e4e70e..fb50663 100644 --- src/include/IceT.h +++ src/include/IceT.h @@ -50,6 +50,10 @@ struct IceTCommunicatorStruct { struct IceTCommunicatorStruct * (*Duplicate)(struct IceTCommunicatorStruct *self); void (*Destroy)(struct IceTCommunicatorStruct *self); + struct IceTCommunicatorStruct * + (*Subset)(struct IceTCommunicatorStruct *self, + int count, + const IceTInt32 *ranks); void (*Barrier)(struct IceTCommunicatorStruct *self); void (*Send)(struct IceTCommunicatorStruct *self, const void *buf, @@ -123,6 +127,7 @@ struct IceTCommunicatorStruct { }; typedef struct IceTCommunicatorStruct *IceTCommunicator; +#define ICET_COMM_NULL ((IceTCommunicator)NULL) ICET_EXPORT IceTDouble icetWallTime(void); @@ -214,6 +219,8 @@ ICET_EXPORT const char *icetGetStrategyName(void); #define ICET_SINGLE_IMAGE_STRATEGY_BSWAP (IceTEnum)0x7002 #define ICET_SINGLE_IMAGE_STRATEGY_TREE (IceTEnum)0x7003 #define ICET_SINGLE_IMAGE_STRATEGY_RADIXK (IceTEnum)0x7004 +#define ICET_SINGLE_IMAGE_STRATEGY_RADIXKR (IceTEnum)0x7005 +#define ICET_SINGLE_IMAGE_STRATEGY_BSWAP_FOLDING (IceTEnum)0x7006 ICET_EXPORT void icetSingleImageStrategy(IceTEnum strategy); @@ -241,6 +248,13 @@ ICET_EXPORT IceTImage icetDrawFrame(const IceTDouble *projection_matrix, const IceTDouble *modelview_matrix, const IceTFloat *background_color); +ICET_EXPORT IceTImage icetCompositeImage(const IceTVoid *color_buffer, + const IceTVoid *depth_buffer, + const IceTInt *valid_pixels_viewport, + const IceTDouble *projection_matrix, + const IceTDouble *modelview_matrix, + const IceTFloat *background_color); + #define ICET_DIAG_OFF (IceTEnum)0x0000 #define ICET_DIAG_ERRORS (IceTEnum)0x0001 #define ICET_DIAG_WARNINGS (IceTEnum)0x0003 @@ -315,9 +329,8 @@ ICET_EXPORT void icetDiagnostics(IceTBitField mask); #define ICET_RENDERED_VIEWPORT (ICET_STATE_FRAME_START | (IceTEnum)0x0020) #define ICET_RENDER_BUFFER (ICET_STATE_FRAME_START | (IceTEnum)0x0021) -#define ICET_RENDER_BUFFER_SIZE (ICET_STATE_FRAME_START | (IceTEnum)0x0022) -#define ICET_RENDER_BUFFER_HOLD (ICET_STATE_FRAME_START | (IceTEnum)0x0023) -#define ICET_TILE_PROJECTIONS (ICET_STATE_FRAME_START | (IceTEnum)0x0024) +#define ICET_PRE_RENDERED (ICET_STATE_FRAME_START | (IceTEnum)0x0022) +#define ICET_TILE_PROJECTIONS (ICET_STATE_FRAME_START | (IceTEnum)0x0023) #define ICET_STATE_TIMING_START (IceTEnum)0x000000C0 @@ -325,12 +338,13 @@ ICET_EXPORT void icetDiagnostics(IceTBitField mask); #define ICET_BUFFER_READ_TIME (ICET_STATE_TIMING_START | (IceTEnum)0x0002) #define ICET_BUFFER_WRITE_TIME (ICET_STATE_TIMING_START | (IceTEnum)0x0003) #define ICET_COMPRESS_TIME (ICET_STATE_TIMING_START | (IceTEnum)0x0004) -#define ICET_COMPARE_TIME (ICET_STATE_TIMING_START | (IceTEnum)0x0005) +#define ICET_INTERLACE_TIME (ICET_STATE_TIMING_START | (IceTEnum)0x0005) +#define ICET_COMPARE_TIME (ICET_STATE_TIMING_START | (IceTEnum)0x0006) #define ICET_BLEND_TIME ICET_COMPARE_TIME -#define ICET_COMPOSITE_TIME (ICET_STATE_TIMING_START | (IceTEnum)0x0006) -#define ICET_COLLECT_TIME (ICET_STATE_TIMING_START | (IceTEnum)0x0007) -#define ICET_TOTAL_DRAW_TIME (ICET_STATE_TIMING_START | (IceTEnum)0x0008) -#define ICET_BYTES_SENT (ICET_STATE_TIMING_START | (IceTEnum)0x0009) +#define ICET_COMPOSITE_TIME (ICET_STATE_TIMING_START | (IceTEnum)0x0007) +#define ICET_COLLECT_TIME (ICET_STATE_TIMING_START | (IceTEnum)0x0008) +#define ICET_TOTAL_DRAW_TIME (ICET_STATE_TIMING_START | (IceTEnum)0x0009) +#define ICET_BYTES_SENT (ICET_STATE_TIMING_START | (IceTEnum)0x000A) #define ICET_DRAW_START_TIME (ICET_STATE_TIMING_START | (IceTEnum)0x0010) #define ICET_DRAW_TIME_ID (ICET_STATE_TIMING_START | (IceTEnum)0x0011) @@ -350,6 +364,7 @@ ICET_EXPORT void icetDiagnostics(IceTBitField mask); #define ICET_COMPOSITE_ONE_BUFFER (ICET_STATE_ENABLE_START | (IceTEnum)0x0004) #define ICET_INTERLACE_IMAGES (ICET_STATE_ENABLE_START | (IceTEnum)0x0005) #define ICET_COLLECT_IMAGES (ICET_STATE_ENABLE_START | (IceTEnum)0x0006) +#define ICET_RENDER_EMPTY_IMAGES (ICET_STATE_ENABLE_START | (IceTEnum)0x0007) /* This set of enable state variables are reserved for the rendering layer. */ #define ICET_RENDER_LAYER_ENABLE_START (ICET_STATE_ENABLE_START | (IceTEnum)0x0030) diff --git src/include/IceTDevCommunication.h src/include/IceTDevCommunication.h index 1cbbc12..97cecc3 100644 --- src/include/IceTDevCommunication.h +++ src/include/IceTDevCommunication.h @@ -22,6 +22,8 @@ extern "C" { /* All of these methods call the associated method in the communicator for the current context. */ ICET_EXPORT IceTCommunicator icetCommDuplicate(); +ICET_EXPORT IceTCommunicator icetCommSubset(int count, + const IceTInt32 *ranks); ICET_EXPORT void icetCommBarrier(); ICET_EXPORT void icetCommSend(const void *buf, IceTSizeType count, diff --git src/include/IceTDevImage.h src/include/IceTDevImage.h index 8448c7f..03d88a4 100644 --- src/include/IceTDevImage.h +++ src/include/IceTDevImage.h @@ -23,9 +23,10 @@ extern "C" { #define ICET_SRC_ON_TOP ICET_TRUE #define ICET_DEST_ON_TOP ICET_FALSE -ICET_EXPORT IceTImage icetGetStateBufferImage(IceTEnum pname, - IceTSizeType width, - IceTSizeType height); +ICET_EXPORT IceTImage icetGetStateBufferImage(IceTEnum pname, + IceTSizeType width, + IceTSizeType height); +ICET_EXPORT IceTImage icetRetrieveStateImage(IceTEnum pname); ICET_EXPORT IceTSizeType icetImageBufferSize(IceTSizeType width, IceTSizeType height); ICET_EXPORT IceTSizeType icetImageBufferSizeType(IceTEnum color_format, @@ -35,6 +36,17 @@ ICET_EXPORT IceTSizeType icetImageBufferSizeType(IceTEnum color_format, ICET_EXPORT IceTImage icetImageAssignBuffer(IceTVoid *buffer, IceTSizeType width, IceTSizeType height); +ICET_EXPORT IceTImage icetGetStatePointerImage(IceTEnum pname, + IceTSizeType width, + IceTSizeType height, + const IceTVoid *color_buffer, + const IceTVoid *depth_buffer); +ICET_EXPORT IceTSizeType icetImagePointerBufferSize(void); +ICET_EXPORT IceTImage icetImagePointerAssignBuffer(IceTVoid *buffer, + IceTSizeType width, + IceTSizeType height, + const IceTVoid *color_buf, + const IceTVoid *depth_buf); ICET_EXPORT void icetImageAdjustForOutput(IceTImage image); ICET_EXPORT void icetImageAdjustForInput(IceTImage image); ICET_EXPORT void icetImageSetDimensions(IceTImage image, diff --git src/include/IceTDevProjections.h src/include/IceTDevProjections.h index 2b0edf7..2bf7df3 100644 --- src/include/IceTDevProjections.h +++ src/include/IceTDevProjections.h @@ -19,11 +19,25 @@ extern "C" { } #endif +/* Given the index to a tile, returns an adjusted ICET_PROJECTION_MATRIX + for the tile. If the physical render size is larger than the tile, + then the tile projection occurs in the lower left corner. */ ICET_EXPORT void icetProjectTile(IceTInt tile, IceTDouble *mat_out); +/* Given a viewport (defined by x, y, width, and height), return a matrix + transforms a projection from the global display to the display provided. */ ICET_EXPORT void icetGetViewportProject(IceTInt x, IceTInt y, - IceTSizeType width, IceTSizeType height, - IceTDouble *mat_out); + IceTSizeType width, IceTSizeType height, + IceTDouble *mat_out); + +/* Given two viewports, returns the region that is their intersection. It + is OK if either of the two src_viewport pointer point to the same memory + as dest_viewport. If the intersection is empty, the width and height + of dest_viewport will be 0 and the x and y will be set to -1000000 (to + place them outside of reasonable viewports). */ +ICET_EXPORT void icetIntersectViewports(const IceTInt *src_viewport1, + const IceTInt *src_viewport2, + IceTInt *dest_viewport); #ifdef __cplusplus } diff --git src/include/IceTDevState.h src/include/IceTDevState.h index 02c4e93..159c99a 100644 --- src/include/IceTDevState.h +++ src/include/IceTDevState.h @@ -62,6 +62,7 @@ ICET_EXPORT const IceTFloat *icetUnsafeStateGetFloat(IceTEnum pname); ICET_EXPORT const IceTInt *icetUnsafeStateGetInteger(IceTEnum pname); ICET_EXPORT const IceTBoolean *icetUnsafeStateGetBoolean(IceTEnum pname); ICET_EXPORT const IceTVoid **icetUnsafeStateGetPointer(IceTEnum pname); +ICET_EXPORT const IceTVoid *icetUnsafeStateGetBuffer(IceTEnum pname); ICET_EXPORT IceTDouble *icetStateAllocateDouble(IceTEnum pname, IceTSizeType num_entries); diff --git src/include/IceTDevTiming.h src/include/IceTDevTiming.h index ad5edd5..d1903c0 100644 --- src/include/IceTDevTiming.h +++ src/include/IceTDevTiming.h @@ -32,6 +32,9 @@ ICET_EXPORT void icetTimingBufferWriteEnd(void); ICET_EXPORT void icetTimingCompressBegin(void); ICET_EXPORT void icetTimingCompressEnd(void); +ICET_EXPORT void icetTimingInterlaceBegin(void); +ICET_EXPORT void icetTimingInterlaceEnd(void); + ICET_EXPORT void icetTimingBlendBegin(void); ICET_EXPORT void icetTimingBlendEnd(void); diff --git src/strategies/automatic.c src/strategies/automatic.c index aee27f8..74d5bc0 100644 --- src/strategies/automatic.c +++ src/strategies/automatic.c @@ -21,8 +21,8 @@ void icetAutomaticCompose(const IceTInt *compose_group, IceTSizeType *piece_offset) { if (group_size > 1) { - icetRaiseDebug("Doing radix-k compose"); - icetInvokeSingleImageStrategy(ICET_SINGLE_IMAGE_STRATEGY_RADIXK, + icetRaiseDebug("Doing radix-kr compose"); + icetInvokeSingleImageStrategy(ICET_SINGLE_IMAGE_STRATEGY_RADIXKR, compose_group, group_size, image_dest, @@ -34,7 +34,7 @@ void icetAutomaticCompose(const IceTInt *compose_group, *result_image = input_image; *piece_offset = 0; } else { - icetRaiseDebug("Clearing pixels"); + icetRaiseDebug("Clearing pixels"); icetClearSparseImage(input_image); *result_image = input_image; *piece_offset = 0; diff --git src/strategies/bswap.c src/strategies/bswap.c index b8960c8..8a8fb16 100644 --- src/strategies/bswap.c +++ src/strategies/bswap.c @@ -13,14 +13,18 @@ #include #include +#include + #define BSWAP_INCOMING_IMAGES_BUFFER ICET_SI_STRATEGY_BUFFER_0 #define BSWAP_OUTGOING_IMAGES_BUFFER ICET_SI_STRATEGY_BUFFER_1 #define BSWAP_SPARE_WORKING_IMAGE_BUFFER ICET_SI_STRATEGY_BUFFER_2 #define BSWAP_IMAGE_ARRAY ICET_SI_STRATEGY_BUFFER_3 #define BSWAP_DUMMY_ARRAY ICET_SI_STRATEGY_BUFFER_4 +#define BSWAP_COMPOSE_GROUP_BUFFER ICET_SI_STRATEGY_BUFFER_5 #define BSWAP_SWAP_IMAGES 21 #define BSWAP_TELESCOPE 22 +#define BSWAP_FOLD 23 #define BIT_REVERSE(result, x, max_val_plus_one) \ { \ @@ -554,7 +558,7 @@ static void bswapComposeNoCombine(const IceTInt *compose_group, input_image = working_image; available_image = icetSparseImageNull(); } - + /* I am part of the lower group. Do the actual binary swap. */ bswapComposePow2(compose_group, @@ -594,7 +598,7 @@ void icetBswapCompose(const IceTInt *compose_group, IceTSparseImage *result_image, IceTSizeType *piece_offset) { - icetRaiseDebug("In bswapCompose"); + icetRaiseDebug("In binary-swap compose"); /* Remove warning about unused parameter. Binary swap leaves images evenly * partitioned, so we have no use of the image_dest parameter. */ @@ -608,3 +612,141 @@ void icetBswapCompose(const IceTInt *compose_group, result_image, piece_offset); } + + +void icetBswapFoldingCompose(const IceTInt *compose_group, + IceTInt group_size, + IceTInt image_dest, + IceTSparseImage input_image, + IceTSparseImage *result_image, + IceTSizeType *piece_offset) +{ + IceTInt group_rank = icetFindMyRankInGroup(compose_group, group_size); + IceTInt pow2size = bswapFindPower2(group_size); + IceTInt extra_proc = group_size - pow2size; + IceTBoolean use_interlace; + IceTSparseImage working_image; + IceTSparseImage available_image; + IceTSparseImage spare_image; + IceTSizeType total_num_pixels = icetSparseImageGetNumPixels(input_image); + IceTInt *pow2group; + + icetRaiseDebug("In binary-swap folding compose"); + + (void)image_dest; /* not used */ + + if (group_size < 2) { + *result_image = input_image; + *piece_offset = 0; + return; + } + + /* Interlace images when requested. */ + use_interlace = (pow2size > 2) && icetIsEnabled(ICET_INTERLACE_IMAGES); + if (use_interlace) { + IceTSparseImage interlaced_image = icetGetStateBufferSparseImage( + BSWAP_SPARE_WORKING_IMAGE_BUFFER, + icetSparseImageGetWidth(input_image), + icetSparseImageGetHeight(input_image)); + icetSparseImageInterlace(input_image, + pow2size, + BSWAP_DUMMY_ARRAY, + interlaced_image); + working_image = interlaced_image; + available_image = input_image; + } else { + /* Allocate available (scratch) image buffer. */ + available_image = icetGetStateBufferSparseImage( + BSWAP_SPARE_WORKING_IMAGE_BUFFER, + icetSparseImageGetWidth(input_image), + icetSparseImageGetHeight(input_image)); + working_image = input_image; + } + + /* Fold the existing number of processes into a subset that is the maximum + * power of 2. */ + pow2group = icetGetStateBuffer(BSWAP_COMPOSE_GROUP_BUFFER, + sizeof(IceTInt)*pow2size); + { + IceTInt whole_group_index = 0; + IceTInt pow2group_index = 0; + while (pow2group_index < extra_proc) { + pow2group[pow2group_index] = compose_group[whole_group_index]; + + if (group_rank == whole_group_index) { + /* I need to receive a folded image and composite it. */ + IceTSizeType incoming_size + = icetSparseImageBufferSize(total_num_pixels, 1); + IceTVoid *in_image_buffer + = icetGetStateBuffer(BSWAP_INCOMING_IMAGES_BUFFER, + incoming_size); + IceTSparseImage in_image; + IceTSparseImage old_working_image; + + icetCommRecv(in_image_buffer, + incoming_size, + ICET_BYTE, + compose_group[whole_group_index+1], + BSWAP_FOLD); + in_image = icetSparseImageUnpackageFromReceive(in_image_buffer); + + icetCompressedCompressedComposite(working_image, + in_image, + available_image); + old_working_image = working_image; + working_image = available_image; + available_image = old_working_image; + } else if (group_rank == whole_group_index + 1) { + /* I need to send my image to get folded then drop out. */ + IceTVoid *package_buffer; + IceTSizeType package_size; + + icetSparseImagePackageForSend(working_image, + &package_buffer, &package_size); + + icetCommSend(package_buffer, + package_size, + ICET_BYTE, + compose_group[whole_group_index], + BSWAP_FOLD); + + *result_image = icetSparseImageNull(); + *piece_offset = 0; + return; + } + + whole_group_index += 2; + pow2group_index++; + } + + /* That handles all the folded images. The rest of the group can just + * copy over. Do a sanity check too to make sure that we haven't messed + * up our indexing. */ + if ((group_size - whole_group_index) != (pow2size - pow2group_index)) { + icetRaiseError("Miscounted indices while folding.", + ICET_SANITY_CHECK_FAIL); + } + memcpy(&pow2group[pow2group_index], + &compose_group[whole_group_index], + sizeof(IceTInt)*(group_size-whole_group_index)); + } + + /* Time to do the actual binary-swap on our new power of two group. */ + bswapComposePow2(pow2group, + pow2size, + pow2size, + working_image, + available_image, + result_image, + piece_offset, + &spare_image); + + if (use_interlace) { + IceTInt global_partition; + IceTInt pow2rank = icetFindMyRankInGroup(pow2group, pow2size); + BIT_REVERSE(global_partition, pow2rank, pow2size); + *piece_offset = icetGetInterlaceOffset(global_partition, + pow2size, + total_num_pixels); + } +} diff --git src/strategies/radixk.c src/strategies/radixk.c index d467e8f..b844a12 100644 --- src/strategies/radixk.c +++ src/strategies/radixk.c @@ -30,6 +30,8 @@ #include #include +/* #define RADIXK_USE_TELESCOPE */ + #define RADIXK_SWAP_IMAGE_TAG_START 2200 #define RADIXK_TELESCOPE_IMAGE_TAG 2300 @@ -91,6 +93,7 @@ typedef struct radixkPartnerInfoStruct { } \ } +#ifdef RADIXK_USE_TELESCOPE /* Finds the largest power of 2 equal to or smaller than x. */ static IceTInt radixkFindPower2(IceTInt x) { @@ -99,6 +102,7 @@ static IceTInt radixkFindPower2(IceTInt x) pow2 = pow2 >> 1; return pow2; } +#endif static IceTInt radixkFindFloorPow2(IceTInt x) { @@ -784,14 +788,13 @@ static void radixkCompositeIncomingImages(radixkPartnerInfo *partners, } } -static void icetRadixkBasicCompose(const IceTInt *compose_group, +static void icetRadixkBasicCompose(const radixkInfo *info, + const IceTInt *compose_group, IceTInt group_size, IceTInt total_num_partitions, IceTSparseImage working_image, IceTSizeType *piece_offset) { - radixkInfo info = { NULL, 0 }; - IceTSizeType my_offset; IceTInt current_round; IceTInt remaining_partitions; @@ -812,10 +815,8 @@ static void icetRadixkBasicCompose(const IceTInt *compose_group, return; } - info = radixkGetK(group_size, group_rank); - /* num_rounds > 0 is assumed several places throughout this function */ - if (info.num_rounds <= 0) { + if (info->num_rounds <= 0) { icetRaiseError("Radix-k has no rounds?", ICET_SANITY_CHECK_FAIL); } @@ -826,9 +827,9 @@ static void icetRadixkBasicCompose(const IceTInt *compose_group, my_offset = 0; remaining_partitions = total_num_partitions; - for (current_round = 0; current_round < info.num_rounds; current_round++) { + for (current_round = 0; current_round < info->num_rounds; current_round++) { IceTSizeType my_size = icetSparseImageGetNumPixels(working_image); - const radixkRoundInfo *round_info = &info.rounds[current_round]; + const radixkRoundInfo *round_info = &info->rounds[current_round]; radixkPartnerInfo *partners = radixkGetPartners(round_info, remaining_partitions, compose_group, @@ -875,6 +876,8 @@ static void icetRadixkBasicCompose(const IceTInt *compose_group, return; } +#ifdef RADIXK_USE_TELESCOPE + static IceTInt icetRadixkTelescopeFindUpperGroupSender( const IceTInt *my_group, IceTInt my_group_size, @@ -971,9 +974,15 @@ static void icetRadixkTelescopeComposeReceive(const IceTInt *my_group, { IceTSparseImage working_image = input_image; IceTInt upper_sender; + radixkInfo info; + IceTInt my_group_rank; + + my_group_rank = icetFindMyRankInGroup(my_group, my_group_size); + info = radixkGetK(my_group_size, my_group_rank); /* Start with the basic compose of my group. */ - icetRadixkBasicCompose(my_group, + icetRadixkBasicCompose(&info, + my_group, my_group_size, total_num_partitions, working_image, @@ -1206,7 +1215,7 @@ static void icetRadixkTelescopeCompose(const IceTInt *compose_group, /* Here is a convenient place to determine the final number of partitions. */ { - /* Middle argument does not matter. */ + /* Group rank does not matter for our purposes. */ radixkInfo info = radixkGetK(main_group_size, 0); total_num_partitions = radixkGetTotalNumPartitions(&info); } @@ -1254,7 +1263,7 @@ static void icetRadixkTelescopeCompose(const IceTInt *compose_group, result_image, piece_offset); } else { - /* In the sub group. */\ + /* In the sub group. */ icetRadixkTelescopeComposeSend(main_group, main_group_size, sub_group, @@ -1280,12 +1289,11 @@ static void icetRadixkTelescopeCompose(const IceTInt *compose_group, return; } - info = radixkGetK(main_group_size, - main_group_rank); + info = radixkGetK(main_group_size, main_group_rank); global_partition = radixkGetFinalPartitionIndex(&info); *piece_offset = icetGetInterlaceOffset(global_partition, - main_group_size, + total_num_partitions, original_image_size); } @@ -1293,6 +1301,7 @@ static void icetRadixkTelescopeCompose(const IceTInt *compose_group, } + void icetRadixkCompose(const IceTInt *compose_group, IceTInt group_size, IceTInt image_dest, @@ -1308,6 +1317,59 @@ void icetRadixkCompose(const IceTInt *compose_group, piece_offset); } +#else + +void icetRadixkCompose(const IceTInt *compose_group, + IceTInt group_size, + IceTInt image_dest, + IceTSparseImage input_image, + IceTSparseImage *result_image, + IceTSizeType *piece_offset) +{ + IceTInt group_rank = icetFindMyRankInGroup(compose_group, group_size); + radixkInfo info = radixkGetK(group_size, group_rank); + IceTInt total_num_partitions = radixkGetTotalNumPartitions(&info); + IceTBoolean use_interlace = icetIsEnabled(ICET_INTERLACE_IMAGES); + IceTSparseImage working_image = input_image; + IceTSizeType original_image_size = icetSparseImageGetNumPixels(input_image); + + (void)image_dest; /* Not used. */ + + if (use_interlace) { + use_interlace = (info.num_rounds > 1); + } + + if (use_interlace) { + IceTSparseImage interlaced_image = icetGetStateBufferSparseImage( + RADIXK_INTERLACED_IMAGE_BUFFER, + icetSparseImageGetWidth(working_image), + icetSparseImageGetHeight(working_image)); + icetSparseImageInterlace(working_image, + total_num_partitions, + RADIXK_SPLIT_OFFSET_ARRAY_BUFFER, + interlaced_image); + working_image = interlaced_image; + } + + icetRadixkBasicCompose(&info, + compose_group, + group_size, + total_num_partitions, + working_image, + piece_offset); + + *result_image = working_image; + + if (use_interlace && (0 < icetSparseImageGetNumPixels(working_image))) { + IceTInt global_partition = radixkGetFinalPartitionIndex(&info); + *piece_offset = icetGetInterlaceOffset(global_partition, + total_num_partitions, + original_image_size); + } +} + +#endif + static IceTBoolean radixkTryPartitionLookup(IceTInt group_size) { IceTInt *partition_assignments; @@ -1422,6 +1484,8 @@ ICET_EXPORT IceTBoolean icetRadixkPartitionLookupUnitTest(void) return ICET_TRUE; } +#ifdef RADIXK_USE_TELESCOPE + #define MAIN_GROUP_RANK(idx) (10000 + idx) #define SUB_GROUP_RANK(idx) (20000 + idx) static IceTBoolean radixkTryTelescopeSendReceive(IceTInt *main_group, @@ -1495,7 +1559,7 @@ static IceTBoolean radixkTryTelescopeSendReceive(IceTInt *main_group, return ICET_TRUE; } -ICET_EXPORT IceTBoolean icetRadixTelescopeSendReceiveTest(void) +ICET_EXPORT IceTBoolean icetRadixkTelescopeSendReceiveTest(void) { IceTInt main_group_size; @@ -1556,3 +1620,13 @@ ICET_EXPORT IceTBoolean icetRadixTelescopeSendReceiveTest(void) return ICET_TRUE; } + +#else /*!RADIXK_USE_TELESCOPE*/ + +ICET_EXPORT IceTBoolean icetRadixkTelescopeSendReceiveTest(void) +{ + /* Telescope method disabled. */ + return ICET_TRUE; +} + +#endif /*!RADIXK_USE_TELESCOPE*/ diff --git src/strategies/radixkr.c src/strategies/radixkr.c new file mode 100644 index 0000000..e34bc00 --- /dev/null +++ src/strategies/radixkr.c @@ -0,0 +1,1037 @@ +/* -*- c -*- *******************************************************/ +/* + * Copyright (C) 2010 Sandia Corporation + * Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, + * the U.S. Government retains certain rights in this software. + * + * This source code is released under the New BSD License. + */ + +/* The Radix-k algorithm was designed by Tom Peterka at Argonne National + Laboratory. + + Copyright (c) University of Chicago + Permission is hereby granted to use, reproduce, prepare derivative works, and + to redistribute to others. + + The Radix-k algorithm was ported to IceT by Wesley Kendall from University + of Tennessee at Knoxville. + + The derived Radix-kr algorithm was designed by Kenneth Moreland at Sandia + National Laboratories. +*/ + +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#define RADIXKR_SWAP_IMAGE_TAG_START 2200 + +#define RADIXKR_RECEIVE_BUFFER ICET_SI_STRATEGY_BUFFER_0 +#define RADIXKR_SEND_BUFFER ICET_SI_STRATEGY_BUFFER_1 +#define RADIXKR_SPARE_BUFFER ICET_SI_STRATEGY_BUFFER_2 +#define RADIXKR_INTERLACED_IMAGE_BUFFER ICET_SI_STRATEGY_BUFFER_3 +#define RADIXKR_PARTITION_INFO_BUFFER ICET_SI_STRATEGY_BUFFER_4 +#define RADIXKR_RECEIVE_REQUEST_BUFFER ICET_SI_STRATEGY_BUFFER_5 +#define RADIXKR_SEND_REQUEST_BUFFER ICET_SI_STRATEGY_BUFFER_6 +#define RADIXKR_FACTORS_ARRAY_BUFFER ICET_SI_STRATEGY_BUFFER_7 +#define RADIXKR_SPLIT_OFFSET_ARRAY_BUFFER ICET_SI_STRATEGY_BUFFER_8 +#define RADIXKR_SPLIT_IMAGE_ARRAY_BUFFER ICET_SI_STRATEGY_BUFFER_9 + +typedef struct radixkrRoundInfoStruct { + IceTInt k; /* k value for this round. */ + IceTInt r; /* remainder for this round (number of processes dropped). */ + IceTInt step; /* Ranks jump by this much in this round. */ + IceTInt split_factor; /* Number of new image partitions made from each partition. */ + IceTBoolean has_image; /* True if local process collects image data this round. */ + IceTBoolean last_partition; /* True if local process is part of the last partition. */ + IceTInt first_rank; /* The lowest rank of those participating with this process this round. */ + IceTInt partition_index; /* Index of partition at this round (if has_image true). */ +} radixkrRoundInfo; + +typedef struct radixkrInfoStruct { + radixkrRoundInfo *rounds; /* Array of per round info. */ + IceTInt num_rounds; +} radixkrInfo; + +typedef struct radixkrPartnerInfoStruct { + IceTInt rank; /* Rank of partner. */ + IceTSizeType offset; /* Offset of partner's partition in image. */ + IceTVoid *receiveBuffer; /* A buffer for receiving data from partner. */ + IceTSparseImage sendImage; /* A buffer to hold data being sent to partner */ + IceTSparseImage receiveImage; /* Hold for received non-composited image. */ + IceTInt compositeLevel; /* Level in compositing tree for round. */ +} radixkrPartnerInfo; + +typedef struct radixkrPartnerGroupInfoStruct { + radixkrPartnerInfo *partners; /* Array of partners in this group. */ + IceTInt num_partners; /* Number of partners in this group. */ +} radixkrPartnerGroupInfo; + +/* BEGIN_PIVOT_FOR(loop_var, low, pivot, high)...END_PIVOT_FOR() provides a + special looping mechanism that iterates over the numbers pivot, pivot-1, + pivot+1, pivot-2, pivot-3,... until all numbers between low (inclusive) and + high (exclusive) are visited. Any numbers outside [low,high) are skipped. */ +#define BEGIN_PIVOT_FOR(loop_var, low, pivot, high) \ + { \ + IceTInt loop_var##_true_iter; \ + IceTInt loop_var##_max = 2*( ((pivot) < ((high)+(low))/2) \ + ? ((high)-(pivot)) : ((pivot)-(low)+1) ); \ + for (loop_var##_true_iter = 1; \ + loop_var##_true_iter < loop_var##_max; \ + loop_var##_true_iter ++) { \ + if ((loop_var##_true_iter % 2) == 0) { \ + loop_var = (pivot) - loop_var##_true_iter/2; \ + if (loop_var < (low)) continue; \ + } else { \ + loop_var = (pivot) + loop_var##_true_iter/2; \ + if ((high) <= loop_var) continue; \ + } + +#define END_PIVOT_FOR() \ + } \ + } + +static IceTInt radixkrFindFloorLog2(IceTInt x) +{ + IceTInt lg; + for (lg = 0; (IceTUInt)(1 << lg) <= (IceTUInt)x; lg++); + lg--; + return lg; +} + +static void radixkrSwapImages(IceTSparseImage *image1, IceTSparseImage *image2) +{ + IceTSparseImage old_image1 = *image1; + *image1 = *image2; + *image2 = old_image1; +} + +/* radixkrGetPartitionIndices + + my position in each round forms an num_rounds-dimensional vector + [round 0 pos, round 1 pos, ... round num_rounds-1 pos] + where pos is my position in the group of partners within that round + + inputs: + info: holds the number of rounds and k values for each round + group_rank: my rank in composite order (compose_group in icetRadixkrCompose) + + outputs: + fills info with step, split_factor, has_image, and partition_index for + each round. +*/ +static void radixkrGetPartitionIndices(radixkrInfo info, + IceTInt group_size, + IceTInt group_rank) +{ + + IceTInt step; /* step size in rank for a lattice direction */ + IceTInt total_partitions; + IceTInt current_group_size; + IceTInt current_round; + IceTInt max_image_split; + + icetGetIntegerv(ICET_MAX_IMAGE_SPLIT, &max_image_split); + + total_partitions = 1; + /* Procs with the same image partition are step ranks from each other. */ + step = 1; + current_group_size = group_size; + current_round = 0; + while (current_round < info.num_rounds) { + radixkrRoundInfo *round_info = &info.rounds[current_round]; + IceTInt split; + IceTInt next_step = step*round_info->k; + IceTInt next_group_size = current_group_size / round_info->k; + IceTInt end_of_groups = next_step*next_group_size; + IceTInt first_rank; + + first_rank = group_rank % step + (group_rank/next_step)*next_step; + if (first_rank >= end_of_groups) { + first_rank -= next_step; + } + + if ((max_image_split < 1) + || (total_partitions * round_info->k <= max_image_split)) { + split = round_info->k; + } else { + split = max_image_split/total_partitions; + } + + total_partitions *= split; + round_info->split_factor = split; + round_info->first_rank = first_rank; + round_info->partition_index = (group_rank - first_rank)/step; + round_info->last_partition = ((first_rank+next_step) >= end_of_groups); + round_info->step = step; + current_group_size = next_group_size; + step = next_step; + /* The has_image test must follow the changes to current_group_size and + step so that the group sizes gets rounded and the local rank will + pop out of the last partition. */ + round_info->has_image = (group_rank < (step * current_group_size)); + round_info->has_image &= (round_info->partition_index < split); + + current_round++; + } + +} + +static radixkrInfo radixkrGetK(IceTInt compose_group_size, + IceTInt group_rank) +{ + /* Divide the world size into groups that are closest to the magic k + value. */ + radixkrInfo info; + IceTInt magic_k; + IceTInt max_num_k; + IceTInt next_divide; + + /* Special case of when compose_group_size == 1. */ + if (compose_group_size < 2) { + info.rounds = icetGetStateBuffer(RADIXKR_FACTORS_ARRAY_BUFFER, + sizeof(radixkrRoundInfo) * 1); + info.rounds[0].k = 1; + info.rounds[0].r = 0; + info.rounds[0].step = 1; + info.rounds[0].split_factor = 1; + info.rounds[0].has_image = ICET_TRUE; + info.rounds[0].partition_index = 0; + info.num_rounds = 1; + return info; + } + + info.num_rounds = 0; + + icetGetIntegerv(ICET_MAGIC_K, &magic_k); + + /* The maximum number of factors possible is the floor of log base 2. */ + max_num_k = radixkrFindFloorLog2(compose_group_size); + info.rounds = icetGetStateBuffer(RADIXKR_FACTORS_ARRAY_BUFFER, + sizeof(radixkrRoundInfo) * max_num_k); + + next_divide = compose_group_size; + while (next_divide > 1) { + IceTInt next_k; + IceTInt next_r; + + if (next_divide > magic_k) { + /* First guess is the magic k. */ + next_k = magic_k; + next_r = next_divide % magic_k; + } else { + /* Can't do better than doing direct send. */ + next_k = next_divide; + next_r = 0; + } + + /* If the k value we picked is not a perfect factor, try to find + * another value that is a perfect factor or has a smaller remainder. + */ + if (next_r > 0) { + IceTInt try_k; + for (try_k = magic_k-1; try_k >= 2; try_k--) { + IceTInt try_r = next_divide % try_k; + if (try_r < next_r) { + next_k = try_k; + next_r = try_r; + if (next_r == 0) { break; } + } + } + } + + /* Set the k value in the array. */ + info.rounds[info.num_rounds].k = next_k; + info.rounds[info.num_rounds].r = next_r; + next_divide /= next_k; + info.num_rounds++; + + if (info.num_rounds > max_num_k) { + icetRaiseError("Somehow we got more factors than possible.", + ICET_SANITY_CHECK_FAIL); + } + } + + /* Sanity check to make sure that the k's actually multiply to the number + * of processes. */ + { + IceTInt product = 1; + IceTInt round; + for (round = info.num_rounds-1; round >= 0; --round) { + product = product*info.rounds[round].k + info.rounds[round].r; + } + if (product != compose_group_size) { + icetRaiseError("Product of k's not equal to number of processes.", + ICET_SANITY_CHECK_FAIL); + } + } + + radixkrGetPartitionIndices(info, compose_group_size, group_rank); + + return info; +} + +/* radixkrGetFinalPartitionIndex + + After radix-k completes on a group of size p, the image is partitioned into + p pieces (with a caveat for the maximum number of partitions and remainder). + This function finds the index for the final partition (with respect to all + partitions, not just one within a round) for a given rank. + + inputs: + info: information about rounds + + returns: + index of final global partition. -1 if this process does not end up with + a piece. +*/ +static IceTInt radixkrGetFinalPartitionIndex(const radixkrInfo *info) +{ + IceTInt current_round; + IceTInt partition_index; + + partition_index = 0; + for (current_round = 0; current_round < info->num_rounds; current_round++) { + const radixkrRoundInfo *r = &info->rounds[current_round]; + if (r->has_image) { + partition_index *= r->split_factor; + partition_index += r->partition_index; + } else /* !r->has_image */ { + /* local process has no partition */ + return -1; + } + } + + return partition_index; +} + +/* radixkrGetTotalNumPartitions + + After radix-kr completes on a group of size p, the image is partitioned into + p pieces with some set maximum. This function finds the index for the final + partition (with respect to all partitions, not just one within a round) for + a given rank. + + inputs: + info: information about rounds + + returns: + total number of partitions created +*/ +static IceTInt radixkrGetTotalNumPartitions(const radixkrInfo *info) +{ + IceTInt current_round; + IceTInt num_partitions; + + num_partitions = 1; + for (current_round = 0; current_round < info->num_rounds; current_round++) { + num_partitions *= info->rounds[current_round].split_factor; + } + + return num_partitions; +} + +/* radixkrGetGroupRankForFinalPartitionIndex + + After radix-kr completes on a group of size p, the image is partitioned into + p pieces. This function finds the group rank for the given index of the + final partition. This function is the inverse if + radixkrGetFinalPartitionIndex. + + inputs: + info: information about rounds + partition_index: index of final global partition + + returns: + group rank holding partition_index +*/ +static IceTInt radixkrGetGroupRankForFinalPartitionIndex( + const radixkrInfo *info, IceTInt partition_index) +{ + IceTInt current_round; + IceTInt partition_up_to_round; + IceTInt group_rank; + + partition_up_to_round = partition_index; + group_rank = 0; + for (current_round = info->num_rounds - 1; + current_round >= 0; + current_round--) { + const IceTInt step = info->rounds[current_round].step; + const IceTInt split = info->rounds[current_round].split_factor; + group_rank += step * (partition_up_to_round % split); + partition_up_to_round /= split; + } + + return group_rank; +} + +/* radixkrGetPartners + gets the ranks of my trading partners + + inputs: + round_info: structure with information on the current round + remaining_partitions: Number of pieces the image will be split into by + the end of the algorithm. + compose_group: array of world ranks representing the group of processes + participating in compositing (passed into icetRadixkrCompose) + group_rank: Index in compose_group that represents me + start_size: Size of image partition that is being divided in current_round + + output: + partner_group: Structure of information about the group of processes that + are partnering in this round. +*/ +static radixkrPartnerGroupInfo radixkrGetPartners( + const radixkrRoundInfo *round_info, + IceTInt remaining_partitions, + const IceTInt *compose_group, + IceTSizeType start_size) +{ + const IceTInt current_k = round_info->k; + const IceTInt current_r = round_info->r; + const IceTInt split_factor = round_info->split_factor; + const IceTInt step = round_info->step; + radixkrPartnerGroupInfo p_group; + IceTInt num_partners; + IceTBoolean receiving_data; + IceTBoolean sending_data; + IceTVoid *recv_buf_pool; + IceTVoid *send_buf_pool; + IceTSizeType partition_num_pixels; + IceTSizeType sparse_image_size; + IceTInt i; + + num_partners = current_k; + if (round_info->last_partition) { + num_partners += current_r; + } + + p_group.partners = icetGetStateBuffer( + RADIXKR_PARTITION_INFO_BUFFER, + sizeof(radixkrPartnerInfo) * num_partners); + p_group.num_partners = num_partners; + + /* Allocate arrays that can be used as send/receive buffers. */ + receiving_data = round_info->has_image; + if (split_factor > 1) { + partition_num_pixels + = icetSparseImageSplitPartitionNumPixels(start_size, + split_factor, + remaining_partitions); + sending_data = ICET_TRUE; + } else { + /* Not really splitting image, and the receiver does not need to send + * at all. */ + partition_num_pixels = start_size; + sending_data = !receiving_data; + } + sparse_image_size = icetSparseImageBufferSize(partition_num_pixels, 1); + if (receiving_data) { + recv_buf_pool = icetGetStateBuffer(RADIXKR_RECEIVE_BUFFER, + sparse_image_size * num_partners); + } else { + recv_buf_pool = NULL; + } + if (sending_data) { + /* Only need send buff when splitting, always need when splitting. */ + send_buf_pool = icetGetStateBuffer(RADIXKR_SEND_BUFFER, + sparse_image_size * split_factor); + } else { + send_buf_pool = NULL; + } + + for (i = 0; i < num_partners; i++) { + radixkrPartnerInfo *p = &p_group.partners[i]; + IceTInt partner_group_rank = round_info->first_rank + i*step; + + p->rank = compose_group[partner_group_rank]; + + /* To be filled later. */ + p->offset = -1; + + if (receiving_data) { + p->receiveBuffer = ((IceTByte*)recv_buf_pool + i*sparse_image_size); + } else { + p->receiveBuffer = NULL; + } + + if (sending_data && (i < split_factor)) { + IceTVoid *send_buffer + = ((IceTByte*)send_buf_pool + i*sparse_image_size); + p->sendImage = icetSparseImageAssignBuffer(send_buffer, + partition_num_pixels, 1); + } else { + p->sendImage = icetSparseImageNull(); + } + + p->receiveImage = icetSparseImageNull(); + + p->compositeLevel = -1; + } + + return p_group; +} + +/* As applicable, posts an asynchronous receive for each process from which + we are receiving an image piece. */ +static IceTCommRequest *radixkrPostReceives(radixkrPartnerGroupInfo p_group, + const radixkrRoundInfo *round_info, + IceTInt current_round, + IceTInt remaining_partitions, + IceTSizeType start_size) +{ + IceTCommRequest *receive_requests; + IceTSizeType partition_num_pixels; + IceTSizeType sparse_image_size; + IceTInt tag; + IceTInt i; + + /* If not collecting any image partition, post no receives. */ + if (!round_info->has_image) { return NULL; } + + receive_requests =icetGetStateBuffer( + RADIXKR_RECEIVE_REQUEST_BUFFER, + p_group.num_partners * sizeof(IceTCommRequest)); + + if (round_info->split_factor) { + partition_num_pixels + = icetSparseImageSplitPartitionNumPixels(start_size, + round_info->split_factor, + remaining_partitions); + } else { + partition_num_pixels = start_size; + } + sparse_image_size = icetSparseImageBufferSize(partition_num_pixels, 1); + + tag = RADIXKR_SWAP_IMAGE_TAG_START + current_round; + + for (i = 0; i < p_group.num_partners; i++) { + radixkrPartnerInfo *p = &p_group.partners[i]; + if (i != round_info->partition_index) { + receive_requests[i] = icetCommIrecv(p->receiveBuffer, + sparse_image_size, + ICET_BYTE, + p->rank, + tag); + p->compositeLevel = -1; + } else { + /* No need to send to myself. */ + receive_requests[i] = ICET_COMM_REQUEST_NULL; + } + } + + return receive_requests; +} + +/* As applicable, posts an asynchronous send for each process to which we are + sending an image piece. */ +static IceTCommRequest *radixkrPostSends(radixkrPartnerGroupInfo p_group, + const radixkrRoundInfo *round_info, + IceTInt current_round, + IceTInt remaining_partitions, + IceTSizeType start_offset, + const IceTSparseImage image) +{ + IceTCommRequest *send_requests; + IceTInt *piece_offsets; + IceTSparseImage *image_pieces; + IceTInt tag; + IceTInt i; + + tag = RADIXKR_SWAP_IMAGE_TAG_START + current_round; + + if (round_info->split_factor > 1) { + send_requests=icetGetStateBuffer( + RADIXKR_SEND_REQUEST_BUFFER, + round_info->split_factor * sizeof(IceTCommRequest)); + + piece_offsets = icetGetStateBuffer( + RADIXKR_SPLIT_OFFSET_ARRAY_BUFFER, + round_info->split_factor * sizeof(IceTInt)); + image_pieces = icetGetStateBuffer( + RADIXKR_SPLIT_IMAGE_ARRAY_BUFFER, + round_info->split_factor * sizeof(IceTSparseImage)); + for (i = 0; i < round_info->split_factor; i++) { + image_pieces[i] = p_group.partners[i].sendImage; + } + icetSparseImageSplit(image, + start_offset, + round_info->split_factor, + remaining_partitions, + image_pieces, + piece_offsets); + + /* The pivot for loop arranges the sends to happen in an order such that + those to be composited first in their destinations will be sent + first. This serves little purpose other than to try to stagger the + order of sending images so that not everyone sends to the same + process first. */ + BEGIN_PIVOT_FOR(i, + 0, + round_info->partition_index % round_info->split_factor, + round_info->split_factor) { + radixkrPartnerInfo *p = &p_group.partners[i]; + p->offset = piece_offsets[i]; + if (i != round_info->partition_index) { + IceTVoid *package_buffer; + IceTSizeType package_size; + + icetSparseImagePackageForSend(image_pieces[i], + &package_buffer, &package_size); + + send_requests[i] = icetCommIsend(package_buffer, + package_size, + ICET_BYTE, + p->rank, + tag); + } else { + /* Implicitly send to myself. */ + send_requests[i] = ICET_COMM_REQUEST_NULL; + p->receiveImage = p->sendImage; + p->compositeLevel = 0; + } + } END_PIVOT_FOR(); + } else { /* round_info->split_factor == 1 */ + radixkrPartnerInfo *p = &p_group.partners[round_info->partition_index]; + send_requests = icetGetStateBuffer(RADIXKR_SEND_REQUEST_BUFFER, + sizeof(IceTCommRequest)); + if (round_info->has_image) { + send_requests[0] = ICET_COMM_REQUEST_NULL; + p->receiveImage = p->sendImage = image; + p->offset = start_offset; + p->compositeLevel = 0; + } else { + IceTVoid *package_buffer; + IceTSizeType package_size; + IceTInt recv_rank = p_group.partners[0].rank; + + icetSparseImagePackageForSend(image,&package_buffer,&package_size); + + send_requests[0] = icetCommIsend(package_buffer, + package_size, + ICET_BYTE, + recv_rank, + tag); + + p->offset = 0; + } + } + + return send_requests; +} + +/* When compositing incoming images, we pair up the images and composite in + a tree. This minimizes the amount of times non-overlapping pixels need + to be copied. Returns true when all images are composited */ +static IceTBoolean radixkrTryCompositeIncoming( + radixkrPartnerGroupInfo p_group, + IceTInt incoming_index, + IceTSparseImage *spare_image_p, + IceTSparseImage final_image) +{ + const IceTInt num_partners = p_group.num_partners; + radixkrPartnerInfo *partners = p_group.partners; + IceTSparseImage spare_image = *spare_image_p; + IceTInt to_composite_index = incoming_index; + + while (ICET_TRUE) { + IceTInt level = partners[to_composite_index].compositeLevel; + IceTInt dist_to_sibling = (1 << level); + IceTInt subtree_size = (dist_to_sibling << 1); + IceTInt front_index; + IceTInt back_index; + + if (to_composite_index%subtree_size == 0) { + front_index = to_composite_index; + back_index = to_composite_index + dist_to_sibling; + + if (back_index >= num_partners) { + /* This image has no partner at this level. Just promote + the level and continue. */ + if (front_index == 0) { + /* Special case. When index 0 has no partner, we must + be at the top of the tree and we are done. */ + break; + } + partners[to_composite_index].compositeLevel++; + continue; + } + } else { + back_index = to_composite_index; + front_index = to_composite_index - dist_to_sibling; + } + + if ( partners[front_index].compositeLevel + != partners[back_index].compositeLevel ) { + /* Paired images are not on the same level. Cannot composite + until more images come in. We are done for now. */ + break; + } + + if ((front_index == 0) && (subtree_size >= num_partners)) { + /* This will be the last image composited. Composite to final + location. */ + spare_image = final_image; + } + icetCompressedCompressedComposite(partners[front_index].receiveImage, + partners[back_index].receiveImage, + spare_image); + radixkrSwapImages(&partners[front_index].receiveImage, &spare_image); + if (icetSparseImageEqual(spare_image, final_image)) { + /* Special case, front image was sharing buffer with final. + Use back image for next spare. */ + spare_image = partners[back_index].receiveImage; + partners[back_index].receiveImage = icetSparseImageNull(); + } + partners[front_index].compositeLevel++; + to_composite_index = front_index; + } + + *spare_image_p = spare_image; + return ((1 << partners[0].compositeLevel) >= num_partners); +} + +static void radixkrCompositeIncomingImages(radixkrPartnerGroupInfo p_group, + IceTCommRequest *receive_requests, + const radixkrRoundInfo *round_info, + IceTSparseImage image) +{ + radixkrPartnerInfo *partners = p_group.partners; + IceTInt num_partners = p_group.num_partners; + radixkrPartnerInfo *me = &partners[round_info->partition_index]; + + IceTSparseImage spare_image; + IceTInt total_composites; + + IceTSizeType width; + IceTSizeType height; + + IceTBoolean composites_done; + + /* If not receiving an image, return right away. */ + if (!round_info->has_image) { + return; + } + + /* Regardless of order, there are num_partners-1 composite operations to + perform. */ + total_composites = num_partners - 1; + + /* We will be reusing buffers like crazy, but we'll need at least one more + for the first composite, assuming we have at least two composites. */ + width = icetSparseImageGetWidth(me->receiveImage); + height = icetSparseImageGetHeight(me->receiveImage); + if (total_composites >= 2) { + spare_image = icetGetStateBufferSparseImage(RADIXKR_SPARE_BUFFER, + width, + height); + } else { + spare_image = icetSparseImageNull(); + } + + /* Grumble. Stupid special case where there is only one composite and we + want the result to go in the same image as my receive image (which can + happen when not splitting). */ + if (icetSparseImageEqual(me->receiveImage,image) && (total_composites < 2)){ + spare_image = icetGetStateBufferSparseImage(RADIXKR_SPARE_BUFFER, + width, + height); + icetSparseImageCopyPixels(me->receiveImage, + 0, + width*height, + spare_image); + me->receiveImage = spare_image; + } + + /* Start by trying to composite the implicit receive from myself. It won't + actually composite anything, but it may change the composite level. It + will also defensively set composites_done correctly. */ + composites_done = radixkrTryCompositeIncoming(p_group, + round_info->partition_index, + &spare_image, + image); + + while (!composites_done) { + IceTInt receive_idx; + radixkrPartnerInfo *receiver; + + /* Wait for an image to come in. */ + receive_idx = icetCommWaitany(num_partners, receive_requests); + receiver = &partners[receive_idx]; + receiver->compositeLevel = 0; + receiver->receiveImage + = icetSparseImageUnpackageFromReceive(receiver->receiveBuffer); + if ( (icetSparseImageGetWidth(receiver->receiveImage) != width) + || (icetSparseImageGetHeight(receiver->receiveImage) != height) ) { + icetRaiseError("Radix-kr received image with wrong size.", + ICET_SANITY_CHECK_FAIL); + } + + /* Try to composite that image. */ + composites_done = radixkrTryCompositeIncoming(p_group, + receive_idx, + &spare_image, + image); + } +} + +void icetRadixkrCompose(const IceTInt *compose_group, + IceTInt group_size, + IceTInt image_dest, + IceTSparseImage input_image, + IceTSparseImage *result_image, + IceTSizeType *piece_offset) +{ + radixkrInfo info = { NULL, 0 }; + + IceTSizeType my_offset; + IceTInt current_round; + IceTInt total_num_partitions; + IceTInt remaining_partitions; + IceTInt group_rank; + IceTBoolean use_interlace; + IceTSparseImage working_image = input_image; + IceTSizeType original_image_size = icetSparseImageGetNumPixels(input_image); + + /* This hint of an argument is ignored. */ + (void)image_dest; + + icetRaiseDebug("In radix-kr compose"); + + /* Find your rank in your group. */ + group_rank = icetFindMyRankInGroup(compose_group, group_size); + if (group_rank < 0) { + icetRaiseError("Local process not in compose_group?", + ICET_SANITY_CHECK_FAIL); + *result_image = icetSparseImageNull(); + *piece_offset = 0; + return; + } + + if (group_size == 1) { + /* I am the only process in the group. No compositing to be done. + * Just return and the image will be complete. */ + *result_image = input_image; + *piece_offset = 0; + return; + } + + info = radixkrGetK(group_size, group_rank); + + /* num_rounds > 0 is assumed several places throughout this function */ + if (info.num_rounds <= 0) { + icetRaiseError("Radix-kr has no rounds?", ICET_SANITY_CHECK_FAIL); + } + + /* IceT does some tricks with partitioning an image so that no matter what + order we do the divisions, we end up with the same partitions. To do + that, we need to know how many divisions are going to be created in + all. */ + total_num_partitions = radixkrGetTotalNumPartitions(&info); + + /* Now that we know the total number of partitions, we can interlace the + input image to improve load balancing. */ + use_interlace = icetIsEnabled(ICET_INTERLACE_IMAGES); + use_interlace &= (info.num_rounds > 1); + + if (use_interlace) { + IceTSparseImage interlaced_image = icetGetStateBufferSparseImage( + RADIXKR_INTERLACED_IMAGE_BUFFER, + icetSparseImageGetWidth(working_image), + icetSparseImageGetHeight(working_image)); + icetSparseImageInterlace(working_image, + total_num_partitions, + RADIXKR_SPLIT_OFFSET_ARRAY_BUFFER, + interlaced_image); + working_image = interlaced_image; + } + + /* Any peer we communicate with in round i starts that round with a block of + the same size as ours prior to splitting for sends/recvs. So we can + calculate the current round's peer sizes based on our current size and + the split values in the info structure. */ + my_offset = 0; + remaining_partitions = total_num_partitions; + + for (current_round = 0; current_round < info.num_rounds; current_round++) { + IceTSizeType my_size = icetSparseImageGetNumPixels(working_image); + const radixkrRoundInfo *round_info = &info.rounds[current_round]; + radixkrPartnerGroupInfo p_group + = radixkrGetPartners(round_info, + remaining_partitions, + compose_group, + my_size); + IceTCommRequest *receive_requests; + IceTCommRequest *send_requests; + + receive_requests = radixkrPostReceives(p_group, + round_info, + current_round, + remaining_partitions, + my_size); + + send_requests = radixkrPostSends(p_group, + round_info, + current_round, + remaining_partitions, + my_offset, + working_image); + + radixkrCompositeIncomingImages(p_group, + receive_requests, + round_info, + working_image); + + icetCommWaitall(round_info->split_factor, send_requests); + + my_offset = p_group.partners[round_info->partition_index].offset; + if (round_info->has_image) { + remaining_partitions /= round_info->split_factor; + } else { + icetSparseImageSetDimensions(working_image, 0, 0); + break; + } + } /* for all rounds */ + + /* If we interlaced the image and are actually returning something, + correct the offset. */ + if (use_interlace && (icetSparseImageGetNumPixels(working_image) > 0)) { + IceTInt partition_index = radixkrGetFinalPartitionIndex(&info); + *piece_offset = icetGetInterlaceOffset(partition_index, + total_num_partitions, + original_image_size); + } else { + *piece_offset = my_offset; + } + + *result_image = working_image; + + return; +} + + +static IceTBoolean radixkrTryPartitionLookup(IceTInt group_size) +{ + IceTInt *partition_assignments; + IceTInt group_rank; + IceTInt partition_index; + IceTInt num_partitions; + + partition_assignments = malloc(group_size * sizeof(IceTInt)); + for (partition_index = 0; + partition_index < group_size; + partition_index++) { + partition_assignments[partition_index] = -1; + } + + num_partitions = 0; + for (group_rank = 0; group_rank < group_size; group_rank++) { + radixkrInfo info; + IceTInt rank_assignment; + + info = radixkrGetK(group_size, group_rank); + partition_index = radixkrGetFinalPartitionIndex(&info); + /* Check if this rank has no partition. */ + if (partition_index < 0) { continue; } + num_partitions++; + if (group_size <= partition_index) { + printf("Invalid partition for rank %d. Got partition %d.\n", + group_rank, partition_index); + return ICET_FALSE; + } + if (partition_assignments[partition_index] != -1) { + printf("Both ranks %d and %d report assigned partition %d.\n", + group_rank, + partition_assignments[partition_index], + partition_index); + return ICET_FALSE; + } + partition_assignments[partition_index] = group_rank; + + rank_assignment + = radixkrGetGroupRankForFinalPartitionIndex(&info, partition_index); + if (rank_assignment != group_rank) { + printf("Rank %d reports partition %d, but partition reports rank %d.\n", + group_rank, partition_index, rank_assignment); + return ICET_FALSE; + } + } + + { + radixkrInfo info; + info = radixkrGetK(group_size, 0); + if (num_partitions != radixkrGetTotalNumPartitions(&info)) { + printf("Expected %d partitions, found %d\n", + radixkrGetTotalNumPartitions(&info), + num_partitions); + return ICET_FALSE; + } + } + + { + IceTInt max_image_split; + + icetGetIntegerv(ICET_MAX_IMAGE_SPLIT, &max_image_split); + if (num_partitions > max_image_split) { + printf("Got %d partitions. Expected no more than %d\n", + num_partitions, max_image_split); + return ICET_FALSE; + } + } + + free(partition_assignments); + + return ICET_TRUE; +} + +ICET_EXPORT IceTBoolean icetRadixkrPartitionLookupUnitTest(void) +{ + const IceTInt group_sizes_to_try[] = { + 2, /* Base case. */ + ICET_MAGIC_K_DEFAULT, /* Largest direct send. */ + ICET_MAGIC_K_DEFAULT*2, /* Changing group sizes. */ + ICET_MAGIC_K_DEFAULT*ICET_MAGIC_K_DEFAULT*37, + /* Odd factor past some rounds. */ + 1024, /* Large(ish) power of two. */ + 576, /* Factors into 2 and 3. */ + 509 /* Prime. */ + }; + const IceTInt num_group_sizes_to_try + = sizeof(group_sizes_to_try)/sizeof(IceTInt); + IceTInt group_size_index; + + printf("\nTesting rank/partition mapping.\n"); + + for (group_size_index = 0; + group_size_index < num_group_sizes_to_try; + group_size_index++) { + IceTInt group_size = group_sizes_to_try[group_size_index]; + IceTInt max_image_split; + + printf("Trying size %d\n", group_size); + + for (max_image_split = 1; + max_image_split/2 < group_size; + max_image_split *= 2) { + icetStateSetInteger(ICET_MAX_IMAGE_SPLIT, max_image_split); + + printf(" Maximum num splits set to %d\n", max_image_split); + + if (!radixkrTryPartitionLookup(group_size)) { + return ICET_FALSE; + } + } + } + + return ICET_TRUE; +} diff --git src/strategies/select.c src/strategies/select.c index 80c8516..09bb53c 100644 --- src/strategies/select.c +++ src/strategies/select.c @@ -34,6 +34,12 @@ extern void icetBswapCompose(const IceTInt *compose_group, IceTSparseImage input_image, IceTSparseImage *result_image, IceTSizeType *piece_offset); +void icetBswapFoldingCompose(const IceTInt *compose_group, + IceTInt group_size, + IceTInt image_dest, + IceTSparseImage input_image, + IceTSparseImage *result_image, + IceTSizeType *piece_offset); extern void icetTreeCompose(const IceTInt *compose_group, IceTInt group_size, IceTInt image_dest, @@ -46,6 +52,12 @@ extern void icetRadixkCompose(const IceTInt *compose_group, IceTSparseImage input_image, IceTSparseImage *result_image, IceTSizeType *piece_offset); +extern void icetRadixkrCompose(const IceTInt *compose_group, + IceTInt group_size, + IceTInt image_dest, + IceTSparseImage input_image, + IceTSparseImage *result_image, + IceTSizeType *piece_offset); /*==================================================================*/ @@ -132,6 +144,8 @@ IceTBoolean icetSingleImageStrategyValid(IceTEnum strategy) case ICET_SINGLE_IMAGE_STRATEGY_BSWAP: case ICET_SINGLE_IMAGE_STRATEGY_TREE: case ICET_SINGLE_IMAGE_STRATEGY_RADIXK: + case ICET_SINGLE_IMAGE_STRATEGY_RADIXKR: + case ICET_SINGLE_IMAGE_STRATEGY_BSWAP_FOLDING: return ICET_TRUE; default: return ICET_FALSE; @@ -145,6 +159,8 @@ const char *icetSingleImageStrategyNameFromEnum(IceTEnum strategy) case ICET_SINGLE_IMAGE_STRATEGY_BSWAP: return "Binary Swap"; case ICET_SINGLE_IMAGE_STRATEGY_TREE: return "Binary Tree"; case ICET_SINGLE_IMAGE_STRATEGY_RADIXK: return "Radix-k"; + case ICET_SINGLE_IMAGE_STRATEGY_RADIXKR: return "Radix-kr"; + case ICET_SINGLE_IMAGE_STRATEGY_BSWAP_FOLDING: return "Folded Binary Swap"; default: icetRaiseError("Invalid single image strategy.", ICET_INVALID_ENUM); return ""; @@ -195,6 +211,22 @@ void icetInvokeSingleImageStrategy(IceTEnum strategy, result_image, piece_offset); break; + case ICET_SINGLE_IMAGE_STRATEGY_RADIXKR: + icetRadixkrCompose(compose_group, + group_size, + image_dest, + input_image, + result_image, + piece_offset); + break; + case ICET_SINGLE_IMAGE_STRATEGY_BSWAP_FOLDING: + icetBswapFoldingCompose(compose_group, + group_size, + image_dest, + input_image, + result_image, + piece_offset); + break; default: icetRaiseError("Invalid single image strategy.", ICET_INVALID_ENUM); break; diff --git src/strategies/split.c src/strategies/split.c index 4cc66de..061c3d3 100644 --- src/strategies/split.c +++ src/strategies/split.c @@ -284,7 +284,9 @@ IceTImage icetSplitCompose(void) tile_groups[num_tiles] = num_proc; /* Figure out which tile I am assigned to. */ - for (my_tile = 0; rank >= tile_groups[my_tile+1]; my_tile++); + for (my_tile = 0; rank >= tile_groups[my_tile+1]; my_tile++) { + /* Nothing to do. Just drop out of loop when my_tile is correct. */ + } icetRaiseDebug1("My tile is %d", my_tile); group_size = tile_groups[my_tile+1] - tile_groups[my_tile]; diff --git tests/BackgroundCorrect.c tests/BackgroundCorrect.c index deeb4ac..44366ce 100644 --- tests/BackgroundCorrect.c +++ tests/BackgroundCorrect.c @@ -13,7 +13,7 @@ #include #include "test_codes.h" -#include "test-util.h" +#include "test_util.h" #include #include @@ -26,9 +26,9 @@ #define PROC_REGION_WIDTH 10 #define PROC_REGION_HEIGHT 10 -const IceTFloat g_background_color[4] = { 0.5, 0.5, 0.5, 1.0 }; -const IceTFloat g_foreground_color[4] = { 0.0, 0.25, 0.5, 0.5 }; -const IceTFloat g_blended_color[4] = { 0.25, 0.5, 0.75, 1.0 }; +static const IceTFloat g_background_color[4] = { 0.5, 0.5, 0.5, 1.0 }; +static const IceTFloat g_foreground_color[4] = { 0.0, 0.25, 0.5, 0.5 }; +static const IceTFloat g_blended_color[4] = { 0.25, 0.5, 0.75, 1.0 }; static IceTBoolean ColorsEqual(const IceTFloat *color1, const IceTFloat *color2) { diff --git tests/BlankTiles.c tests/BlankTiles.c index 59d727b..d78887a 100644 --- tests/BlankTiles.c +++ tests/BlankTiles.c @@ -9,7 +9,7 @@ *****************************************************************************/ #include -#include "test-util.h" +#include "test_util.h" #include "test_codes.h" #include diff --git tests/BoundsBehindViewer.c tests/BoundsBehindViewer.c index a43592b..799c14a 100644 --- tests/BoundsBehindViewer.c +++ tests/BoundsBehindViewer.c @@ -10,7 +10,7 @@ *****************************************************************************/ #include -#include "test-util.h" +#include "test_util.h" #include "test_codes.h" #include diff --git tests/CMakeLists.txt tests/CMakeLists.txt index 6a7be2b..c182367 100644 --- tests/CMakeLists.txt +++ tests/CMakeLists.txt @@ -5,44 +5,85 @@ ## This source code is released under the New BSD License. # -IF (ICET_USE_OPENGL) - FIND_PACKAGE(GLUT) - IF (GLUT_FOUND) - SET(ICET_TESTS_USE_OPENGL 1) - ENDIF (GLUT_FOUND) -ENDIF (ICET_USE_OPENGL) +IF (ICET_USE_OPENGL AND NOT ICET_USE_OFFSCREEN_EGL) + SET(ICET_OPENGL_WINDOW_LIBRARY GLUT + CACHE STRING + "The name of the library the IceT tests will use to create windows for +OpenGL contexts. Supported values are GLUT and GLFW." + ) + SET_PROPERTY(CACHE ICET_OPENGL_WINDOW_LIBRARY + PROPERTY STRINGS GLUT GLFW + ) + MARK_AS_ADVANCED(ICET_OPENGL_WINDOW_LIBRARY) + IF (ICET_OPENGL_WINDOW_LIBRARY STREQUAL GLUT) + FIND_PACKAGE(GLUT) + IF (GLUT_FOUND) + INCLUDE_DIRECTORIES(${GLUT_INCLUDE_DIR}) + SET(ICET_TESTS_USE_OPENGL 1) + SET(ICET_TESTS_USE_GLUT 1) + ELSE (GLUT_FOUND) + MESSAGE(STATUS "Cannot find GLUT library. OpenGL tests disabled.") + ENDIF (GLUT_FOUND) + ELSEIF (ICET_OPENGL_WINDOW_LIBRARY STREQUAL GLFW) + FIND_PACKAGE(GLFW) + IF (GLFW_FOUND) + INCLUDE_DIRECTORIES(${GLFW_INCLUDE_DIR}) + SET(ICET_TESTS_USE_OPENGL 1) + SET(ICET_TESTS_USE_GLFW 1) + ELSE (GLFW_FOUND) + MESSAGE(WARNING "Cannot find GLFW library. OpenGL tests disabled.") + ENDIF (GLFW_FOUND) + ELSE () + MESSAGE(SEND_ERROR "Invalid value for ICET_OPENGL_WINDOW_LIBRARY: ${ICET_OPENGL_WINDOW_LIBRARY}") + ENDIF () +ENDIF () IF (NOT ICET_TESTS_USE_OPENGL) - MESSAGE(STATUS "Most tests require ICET_USE_OPENGL and Glut. Those tests are disabled.") + MESSAGE(STATUS "Most tests require ICET_USE_OPENGL and GLUT or GLFW. Those tests are disabled.") ENDIF (NOT ICET_TESTS_USE_OPENGL) -SET(MyTests +SET(IceTTestSrcs BackgroundCorrect.c CompressionSize.c + FloatingViewport.c Interlace.c MaxImageSplit.c OddImageSizes.c OddProcessCounts.c + PreRender.c + RadixkrUnitTests.c RadixkUnitTests.c + RenderEmpty.c SimpleTiming.c SparseImageCopy.c ) -IF (ICET_TESTS_USE_OPENGL) - SET(MyTests ${MyTests} - BlankTiles.c - BoundsBehindViewer.c - DisplayNoDraw.c - RandomTransform.c - SimpleExample.c - ) -ENDIF (ICET_TESTS_USE_OPENGL) +SET(IceTOpenGLTestSrcs + BlankTiles.c + BoundsBehindViewer.c + DisplayNoDraw.c + RandomTransform.c + SimpleExample.c + ) -SET(UTIL_SRCS init.c ppm.c) +SET(UTIL_SRCS + test_common.c + ppm.c + ) + +SET(TEST_HEADERS + test_codes.h + test_util.h + test_mpi.h + test_mpi_opengl.h + ) +SET_SOURCE_FILES_PROPERTIES(${TEST_HEADERS} + PROPERTIES HEADER_ONLY TRUE + ) CONFIGURE_FILE( - ${CMAKE_CURRENT_SOURCE_DIR}/test-config.h.in - ${CMAKE_CURRENT_BINARY_DIR}/test-config.h + ${CMAKE_CURRENT_SOURCE_DIR}/test_config.h.in + ${CMAKE_CURRENT_BINARY_DIR}/test_config.h ) INCLUDE_DIRECTORIES( @@ -50,23 +91,6 @@ INCLUDE_DIRECTORIES( ${CMAKE_CURRENT_BINARY_DIR} ) -CREATE_TEST_SOURCELIST(Tests icetTests_mpi.c ${MyTests} - EXTRA_INCLUDE mpi_comm.h - FUNCTION init_mpi_comm) - -ADD_EXECUTABLE(icetTests_mpi ${Tests} ${UTIL_SRCS}) -TARGET_LINK_LIBRARIES(icetTests_mpi - IceTCore - IceTMPI - ) -IF (ICET_TESTS_USE_OPENGL) - TARGET_LINK_LIBRARIES(icetTests_mpi - IceTGL - ${OPENGL_glu_LIBRARY} - ${GLUT_LIBRARIES} - ) -ENDIF (ICET_TESTS_USE_OPENGL) - IF (ICET_MPIRUN_EXE) SET(PRE_TEST_FLAGS ${ICET_MPIRUN_EXE} ${ICET_MPI_NUMPROC_FLAG} ${ICET_MPI_MAX_NUMPROCS} ${ICET_MPI_PREFLAGS}) SET(POST_TEST_FLAGS ${ICET_MPI_POSTFLAGS}) @@ -76,11 +100,22 @@ SET(ICET_TEST_FLAGS "" CACHE STRING "Arguments given to the test program. These MARK_AS_ADVANCED(ICET_TEST_FLAGS) SEPARATE_ARGUMENTS(ICET_TEST_FLAGS) -FOREACH (test ${MyTests}) +CREATE_TEST_SOURCELIST(Tests icetTests_mpi.c ${IceTTestSrcs} + EXTRA_INCLUDE test_mpi.h + FUNCTION init_mpi) + +ADD_EXECUTABLE(icetTests_mpi ${Tests} ${UTIL_SRCS} ${TEST_HEADERS}) +TARGET_LINK_LIBRARIES(icetTests_mpi + IceTCore + IceTMPI + ) + +FOREACH (test ${IceTTestSrcs}) GET_FILENAME_COMPONENT(TName ${test} NAME_WE) - ADD_TEST(IceT${TName} + ADD_TEST(NAME IceT${TName} + COMMAND ${PRE_TEST_FLAGS} - ${C_TEST_PATH}/icetTests_mpi ${ICET_TEST_FLAGS} ${TName} + $ ${ICET_TEST_FLAGS} ${TName} ${POST_TEST_FLAGS}) IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.1) SET_TESTS_PROPERTIES(IceT${TName} @@ -93,8 +128,46 @@ FOREACH (test ${MyTests}) ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.1) ENDFOREACH(test) -IF (WIN32) - ADD_CUSTOM_TARGET(logclean erase log.???? *.ppm) -ELSE (WIN32) - ADD_CUSTOM_TARGET(logclean rm -f log.???? *.ppm core.*) -ENDIF (WIN32) +IF (ICET_TESTS_USE_OPENGL) + CREATE_TEST_SOURCELIST(OpenGLTests icetTests_mpi_opengl.c ${IceTOpenGLTestSrcs} + EXTRA_INCLUDE test_mpi_opengl.h + FUNCTION init_mpi_opengl) + + ADD_EXECUTABLE(icetTests_mpi_opengl ${OpenGLTests} ${UTIL_SRCS} ${TEST_HEADERS}) + TARGET_LINK_LIBRARIES(icetTests_mpi_opengl + IceTCore + IceTMPI + IceTGL + ) + IF (ICET_TESTS_USE_GLUT) + TARGET_LINK_LIBRARIES(icetTests_mpi_opengl ${GLUT_LIBRARIES}) + ENDIF (ICET_TESTS_USE_GLUT) + IF (ICET_TESTS_USE_GLFW) + TARGET_LINK_LIBRARIES(icetTests_mpi_opengl ${GLFW_LIBRARY}) + ENDIF (ICET_TESTS_USE_GLFW) + + FOREACH (test ${IceTOpenGLTestSrcs}) + GET_FILENAME_COMPONENT(TName ${test} NAME_WE) + ADD_TEST(NAME IceT${TName} + COMMAND + ${PRE_TEST_FLAGS} + $ ${ICET_TEST_FLAGS} ${TName} + ${POST_TEST_FLAGS}) + IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.1) + SET_TESTS_PROPERTIES(IceT${TName} + PROPERTIES FAIL_REGULAR_EXPRESSION + ":ERROR:;TEST NOT RUN;TEST NOT PASSED;TEST FAILED" + ) + SET_TESTS_PROPERTIES(IceT${TName} + PROPERTIES PASS_REGULAR_EXPRESSION "Test Passed" + ) + ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.1) + ENDFOREACH(test) +ENDIF (ICET_TESTS_USE_OPENGL) + +ADD_CUSTOM_TARGET(logclean + ${CMAKE_COMMAND} -E remove + ${CMAKE_CURRENT_BINARY_DIR}/log.???? + ${CMAKE_CURRENT_BINARY_DIR}/*.ppm + ${CMAKE_CURRENT_BINARY_DIR}/core.* + ) diff --git tests/CompressionSize.c tests/CompressionSize.c index 949cc36..a530b82 100644 --- tests/CompressionSize.c +++ tests/CompressionSize.c @@ -10,7 +10,7 @@ *****************************************************************************/ #include "test_codes.h" -#include "test-util.h" +#include "test_util.h" #include #include diff --git tests/DisplayNoDraw.c tests/DisplayNoDraw.c index 4d0cfc2..af796e4 100644 --- tests/DisplayNoDraw.c +++ tests/DisplayNoDraw.c @@ -16,7 +16,7 @@ #include #include "test_codes.h" -#include "test-util.h" +#include "test_util.h" #include #include diff --git tests/FloatingViewport.c tests/FloatingViewport.c new file mode 100644 index 0000000..061a474 --- /dev/null +++ tests/FloatingViewport.c @@ -0,0 +1,283 @@ +/* -*- c -*- ***************************************************************** +** Copyright (C) 2014 Sandia Corporation +** Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +** the U.S. Government retains certain rights in this software. +** +** This source code is released under the New BSD License. +** +** This test makes sure that the floating viewport feature is working as +** expected. It will make sure that the render is called only once for the +** floating viewport and that the image gets renderd correctly. +*****************************************************************************/ + +#include +#include "test_codes.h" +#include "test_util.h" + +#include +#include + +#include +#include + +static const IceTFloat g_background_color[4] = { 0.5, 0.5, 0.5, 1.0 }; +static const IceTFloat g_foreground_color[4] = { 0.0, 0.25, 0.5, 1.0 }; + +static IceTInt g_num_render_callbacks; + +static IceTBoolean ColorsEqual(const IceTFloat *color1, const IceTFloat *color2) +{ + IceTBoolean result; + + result = (color1[0] == color2[0]); + result &= (color1[1] == color2[1]); + result &= (color1[2] == color2[2]); + result &= (color1[3] == color2[3]); + + return result; +} + +static IceTBoolean CheckPixel(const IceTImage image, + IceTSizeType pixel, + const IceTFloat *expected_color) +{ + const IceTFloat *colors = icetImageGetColorcf(image); + if (!ColorsEqual(colors + 4*pixel, expected_color)) { + IceTUByte *buffer; + IceTInt rank; + char filename[255]; + printrank("BAD PIXEL %d\n", pixel); + printrank(" Expected %f %f %f %f\n", + expected_color[0], + expected_color[1], + expected_color[2], + expected_color[3]); + printrank(" Got %f %f %f %f\n", + colors[4*pixel + 0], + colors[4*pixel + 1], + colors[4*pixel + 2], + colors[4*pixel + 3]); + buffer = malloc(4*icetImageGetWidth(image)*icetImageGetHeight(image)); + icetImageCopyColorub(image, buffer, ICET_IMAGE_COLOR_RGBA_UBYTE); + icetGetIntegerv(ICET_RANK, &rank); + sprintf(filename, "FloatingViewport_%d.ppm", rank); + write_ppm(filename, + buffer, + icetImageGetWidth(image), + icetImageGetHeight(image)); + free(buffer); + return ICET_FALSE; + } else { + return ICET_TRUE; + } +} + +static void RenderFloatingViewport(const IceTDouble *projection_matrix, + const IceTDouble *modelview_matrix, + const IceTFloat *background_color, + const IceTInt *readback_viewport, + IceTImage result) +{ + IceTSizeType width; + IceTSizeType height; + IceTFloat *colors; + + /* To remove warning. */ + (void)projection_matrix; + (void)modelview_matrix; + (void)background_color; + + printrank("Rendering viewport %d %d %d %d\n", + readback_viewport[0], + readback_viewport[1], + readback_viewport[2], + readback_viewport[3]); + + g_num_render_callbacks++; + + width = icetImageGetWidth(result); + height = icetImageGetHeight(result); + colors = icetImageGetColorf(result); + + /* Set all pixels in the readback_viewport. IceT will ignore the rest. */ + { + IceTSizeType line_start = width*readback_viewport[1]; + IceTSizeType line; + for (line = 0; line < readback_viewport[3]; line++) { + IceTSizeType pixel = line_start + readback_viewport[0]; + IceTSizeType column; + for (column = 0; column < readback_viewport[2]; column++) { + colors[4*pixel + 0] = g_foreground_color[0]; + colors[4*pixel + 1] = g_foreground_color[1]; + colors[4*pixel + 2] = g_foreground_color[2]; + colors[4*pixel + 3] = g_foreground_color[3]; + pixel++; + } + line_start += width; + } + } +} + +static void FloatingViewportSetupRender(void) +{ + icetCompositeMode(ICET_COMPOSITE_MODE_BLEND); + icetSetColorFormat(ICET_IMAGE_COLOR_RGBA_FLOAT); + icetSetDepthFormat(ICET_IMAGE_DEPTH_NONE); + icetDisable(ICET_ORDERED_COMPOSITE); + icetEnable(ICET_CORRECT_COLORED_BACKGROUND); + + /* The strategy should not matter for this test. */ + icetStrategy(ICET_STRATEGY_SEQUENTIAL); + + icetDrawCallback(RenderFloatingViewport); + + icetResetTiles(); + icetAddTile(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0); + icetAddTile(SCREEN_WIDTH, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 1); +} + +static void FloatingViewportGetMatrices(IceTDouble *projection_matrix, + IceTDouble *modelview_matrix) +{ + /* Identity matrices make it easy to predict where geometry is projected. */ + icetMatrixIdentity(projection_matrix); + icetMatrixIdentity(modelview_matrix); + + /* The geometry is a square straddling the two tiles. */ + icetBoundingBoxd(-0.25, 0.25, -0.5, 0.5, -0.5, 0.5); +} + +static IceTBoolean FloatingViewportCheckImage(const IceTImage image) +{ + IceTInt rank; + IceTSizeType pixel; + IceTSizeType count; + IceTSizeType width; + IceTSizeType height; + + icetGetIntegerv(ICET_RANK, &rank); + + /* Display ranks are 0 and 1. */ + if (rank > 1) { return ICET_TRUE; } + + width = icetImageGetWidth(image); + height = icetImageGetHeight(image); + + /* Not that in these checks we avoid problems with floating point + * inaccuracies by only checking parts well within regions. For example, + * we expect the bottom 25% of an image to be background, but we only + * check the bottom 20%. */ + + /* Bottom 25% of both images should be background. */ + pixel = 0; + for (count = 0; count < width*(height/5); count++) { + if (!CheckPixel(image, pixel, g_background_color)) {return ICET_FALSE;} + pixel++; + } + + /* Top 25% of both images should be background. */ + pixel = width*(4*height/5); + for (count = 0; count < width*(height/5); count++) { + if (!CheckPixel(image, pixel, g_background_color)) {return ICET_FALSE;} + pixel++; + } + + /* In the middle 50%, the left 75% is background on rank 0 and the right + * 75% is background on rank 1. */ + pixel = width*(2*height/5); + if (rank == 1) { pixel += width - 3*width/5; } + for (count = 0; count < height/5; count++) { + IceTSizeType count2; + for (count2 = 0; count2 < 3*width/5; count2++) { + if (!CheckPixel(image, pixel+count2, g_background_color)) { + return ICET_FALSE; + } + } + pixel += width; + } + + /* In the middle 50%, the right 25% is foreground on rank 0 and the left + * 25% is foreground on rank 1. */ + pixel = width*(2*height/5); + if (rank == 0) { pixel += width - width/5; } + for (count = 0; count < height/5; count++) { + IceTSizeType count2; + for (count2 = 0; count2 < width/5; count2++) { + if (!CheckPixel(image, pixel+count2, g_foreground_color)) { + return ICET_FALSE; + } + } + pixel += width; + } + + return ICET_TRUE; +} + +static IceTBoolean FloatingViewportTryRender(void) +{ + IceTDouble projection_matrix[16]; + IceTDouble modelview_matrix[16]; + IceTImage image; + + FloatingViewportSetupRender(); + FloatingViewportGetMatrices(projection_matrix, modelview_matrix); + + g_num_render_callbacks = 0; + + image = icetDrawFrame(projection_matrix, + modelview_matrix, + g_background_color); + + if (g_num_render_callbacks != 1) { + printrank("**** Rendering callback not called expected number of times. ****\n"); + printrank("Expected 1 call, got %d\n", g_num_render_callbacks); + return ICET_FALSE; + } + + return FloatingViewportCheckImage(image); +} + +static int FloatingViewportTryMultipleRenders(void) +{ + IceTBoolean success = ICET_TRUE; + IceTInt trial; + + for (trial = 0; trial < 5; trial++) { + printstat("Trial render %d\n", trial); + success &= FloatingViewportTryRender(); + } + + if (success) { + return TEST_PASSED; + } else { + return TEST_FAILED; + } +} + +static int FloatingViewportRun(void) +{ + IceTInt num_proc; + + /* Check to make sure floating viewport is on by default. */ + if (!icetIsEnabled(ICET_FLOATING_VIEWPORT)) { + printstat("The floating viewport option is not on by default."); + return TEST_FAILED; + } + + icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc); + if (num_proc < 2) { + printf("Need at least two processes to run FloatingViewport test."); + return TEST_NOT_RUN; + } + + return FloatingViewportTryMultipleRenders(); +} + +int FloatingViewport(int argc, char *argv[]) +{ + /* To remove warning. */ + (void)argc; + (void)argv; + + return run_test(FloatingViewportRun); +} diff --git tests/Interlace.c tests/Interlace.c index 3e628ec..2b9ff97 100644 --- tests/Interlace.c +++ tests/Interlace.c @@ -11,7 +11,7 @@ *****************************************************************************/ #include "test_codes.h" -#include "test-util.h" +#include "test_util.h" #include diff --git tests/MaxImageSplit.c tests/MaxImageSplit.c index 5a7dcfa..064dc14 100644 --- tests/MaxImageSplit.c +++ tests/MaxImageSplit.c @@ -12,7 +12,7 @@ #include #include "test_codes.h" -#include "test-util.h" +#include "test_util.h" #include #include @@ -183,7 +183,7 @@ static int MaxImageSplitCheckImage(const IceTImage image) IceTInt x, y; for (y = 0; y < PROC_REGION_HEIGHT; y++) { for (x = 0; x < PROC_REGION_WIDTH; x++) { - if (*pixel != proc) { + if (*pixel != (IceTUInt)proc) { printrank("**** Found bad pixel!!!! ****\n"); printrank("Region for process %d, x = %d, y = %d\n", proc, x, y); diff --git tests/OddImageSizes.c tests/OddImageSizes.c index 33d8e3d..5e07a54 100644 --- tests/OddImageSizes.c +++ tests/OddImageSizes.c @@ -11,7 +11,7 @@ #include #include "test_codes.h" -#include "test-util.h" +#include "test_util.h" #include #include diff --git tests/OddProcessCounts.c tests/OddProcessCounts.c index 423044f..7615972 100644 --- tests/OddProcessCounts.c +++ tests/OddProcessCounts.c @@ -11,7 +11,7 @@ #include #include "test_codes.h" -#include "test-util.h" +#include "test_util.h" #include #include @@ -86,7 +86,8 @@ static int OddProcessCountsTryCollectOptions(void) icetGetIntegerv(ICET_SINGLE_IMAGE_STRATEGY, &si_strategy); - if (si_strategy == ICET_SINGLE_IMAGE_STRATEGY_RADIXK) { + if ((si_strategy == ICET_SINGLE_IMAGE_STRATEGY_RADIXK) + || (si_strategy == ICET_SINGLE_IMAGE_STRATEGY_RADIXKR)) { IceTInt rank; IceTInt num_proc; IceTInt magic_k; diff --git tests/PreRender.c tests/PreRender.c new file mode 100644 index 0000000..05cd010 --- /dev/null +++ tests/PreRender.c @@ -0,0 +1,310 @@ +/* -*- c -*- ***************************************************************** +** Copyright (C) 2014 Sandia Corporation +** Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +** the U.S. Government retains certain rights in this software. +** +** This source code is released under the New BSD License. +** +** Tests the icetCompositeImage method to composite an image that has been +** pre-rendered (as opposed to rendered on demand through callbacks). +*****************************************************************************/ + +#include +#include +#include +#include "test_codes.h" +#include "test_util.h" + +#include +#include +#include + +static IceTInt g_local_valid_pixel_viewport[4]; +static IceTInt *g_all_valid_pixel_viewports; + +static void SetUpTiles(IceTInt tile_dimension) +{ + IceTInt tile_index = 0; + IceTInt tile_x; + IceTInt tile_y; + + icetResetTiles(); + for (tile_y = 0; tile_y < tile_dimension; tile_y++) { + for (tile_x = 0; tile_x < tile_dimension; tile_x++) { + icetAddTile(tile_x*SCREEN_WIDTH, + tile_y*SCREEN_HEIGHT, + SCREEN_WIDTH, + SCREEN_HEIGHT, + tile_index); + tile_index++; + } + } +} + +static void MakeValidPixelViewports() +{ + IceTInt global_viewport[4]; + IceTInt global_width; + IceTInt global_height; + IceTInt value1, value2; + + icetGetIntegerv(ICET_GLOBAL_VIEWPORT, global_viewport); + global_width = global_viewport[2]; + global_height = global_viewport[3]; + + value1 = rand()%global_width; value2 = rand()%global_height; + if (value1 < value2) { + g_local_valid_pixel_viewport[0] = value1; + g_local_valid_pixel_viewport[2] = value2 - value1; + } else { + g_local_valid_pixel_viewport[0] = value2; + g_local_valid_pixel_viewport[2] = value1 - value2; + } + + value1 = rand()%global_width; value2 = rand()%global_height; + if (value1 < value2) { + g_local_valid_pixel_viewport[1] = value1; + g_local_valid_pixel_viewport[3] = value2 - value1; + } else { + g_local_valid_pixel_viewport[1] = value2; + g_local_valid_pixel_viewport[3] = value1 - value2; + } + + icetCommAllgather(g_local_valid_pixel_viewport, + 4, + ICET_INT, + g_all_valid_pixel_viewports); +} + +static void MakeImageBuffers(IceTUInt **color_buffer_p, + IceTFloat **depth_buffer_p) +{ + IceTUInt *color_buffer; + IceTFloat *depth_buffer; + IceTInt global_viewport[4]; + IceTInt rank; + IceTInt num_proc; + IceTInt width; + IceTInt height; + IceTInt x; + IceTInt y; + IceTInt pixel; + IceTInt left; + IceTInt right; + IceTInt bottom; + IceTInt top; + + icetGetIntegerv(ICET_GLOBAL_VIEWPORT, global_viewport); + width = global_viewport[2]; + height = global_viewport[3]; + + icetGetIntegerv(ICET_RANK, &rank); + icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc); + + left = g_local_valid_pixel_viewport[0]; + right = left + g_local_valid_pixel_viewport[2]; + bottom = g_local_valid_pixel_viewport[1]; + top = bottom + g_local_valid_pixel_viewport[3]; + + color_buffer = malloc(width*height*sizeof(IceTUInt)); + depth_buffer = malloc(width*height*sizeof(IceTFloat)); + pixel = 0; + for (y = 0; y < height; y++) { + for (x = 0; x < width; x++) { + if ((x >= left) && (x < right) && (y >= bottom) && (y < top)) { + color_buffer[pixel] = rank; + depth_buffer[pixel] = ((IceTFloat)rank)/num_proc; + } else { + color_buffer[pixel] = 0xDEADDEAD; /* garbage value */ + } + pixel++; + } + } + + *color_buffer_p = color_buffer; + *depth_buffer_p = depth_buffer; +} + +static IceTBoolean CheckCompositedImage(const IceTImage image) +{ + IceTInt tile_displayed; + const IceTUInt *color_buffer; + IceTSizeType width; + IceTSizeType height; + const IceTInt *tile_viewport; + IceTInt local_x, local_y; + IceTInt global_x, global_y; + IceTInt num_proc; + + icetGetIntegerv(ICET_VALID_PIXELS_TILE, &tile_displayed); + if (tile_displayed < 0) { + /* No local tile. Nothing to compare. Just return success. */ + return ICET_TRUE; + } + + icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc); + + color_buffer = icetImageGetColorcui(image); + width = icetImageGetWidth(image); + height = icetImageGetHeight(image); + + tile_viewport = + icetUnsafeStateGetInteger(ICET_TILE_VIEWPORTS) + 4*tile_displayed; + if ((tile_viewport[2] != width) || (tile_viewport[3] != height)) { + printrank("***** Tile width or height does not match image! *****\n"); + printrank("Tile: %d x %d\n", tile_viewport[2], tile_viewport[3]); + printrank("Image: %d x %d\n", width, height); + return ICET_FALSE; + } + + for (local_y = 0, global_y = tile_viewport[1]; + local_y < height; + local_y++, global_y++) { + for (local_x = 0, global_x = tile_viewport[0]; + local_x < width; + local_x++, global_x++) { + IceTUInt image_value; + IceTUInt expected_value; + IceTInt proc_index; + + image_value = color_buffer[local_x + local_y*width]; + + expected_value = 0xFFFFFFFF; + for (proc_index = 0; proc_index < num_proc; proc_index++) { + IceTInt *proc_viewport = + g_all_valid_pixel_viewports + 4*proc_index; + if ( (global_x >= proc_viewport[0]) + && (global_x < proc_viewport[0]+proc_viewport[2]) + && (global_y >= proc_viewport[1]) + && (global_y < proc_viewport[1]+proc_viewport[3]) ) { + expected_value = proc_index; + break; + } + } + + if (image_value != expected_value) { + printrank("***** Got an unexpected value in the image *****\n"); + printrank("Located at pixel %d,%d (globally %d,%d)\n", + local_x, local_y, global_x, global_y); + printrank("Expected 0x%X. Got 0x%X\n", + expected_value, image_value); + return ICET_FALSE; + } + } + } + + return ICET_TRUE; +} + +static IceTBoolean PreRenderTryComposite(IceTUInt *color_buffer, + IceTFloat *depth_buffer) +{ + IceTFloat background_color[4] = { 1.0, 1.0, 1.0, 1.0 }; + IceTImage image; + + icetSetColorFormat(ICET_IMAGE_COLOR_RGBA_UBYTE); + icetSetDepthFormat(ICET_IMAGE_DEPTH_FLOAT); + icetCompositeMode(ICET_COMPOSITE_MODE_Z_BUFFER); + icetDisable(ICET_ORDERED_COMPOSITE); + + image = icetCompositeImage(color_buffer, + depth_buffer, + g_local_valid_pixel_viewport, + NULL, + NULL, + background_color); + + return CheckCompositedImage(image); +} + +static IceTBoolean PreRenderTryStrategy() +{ + IceTBoolean success = ICET_TRUE; + + IceTUInt *color_buffer; + IceTFloat *depth_buffer; + IceTInt strategy_index; + + MakeImageBuffers(&color_buffer, &depth_buffer); + + for (strategy_index = 0; + strategy_index < STRATEGY_LIST_SIZE; + strategy_index++) { + icetStrategy(strategy_list[strategy_index]); + printstat(" Using %s strategy.\n", icetGetStrategyName()); + + success &= PreRenderTryComposite(color_buffer, depth_buffer); + } + + free(color_buffer); + free(depth_buffer); + + return success; +} + +static IceTBoolean PreRenderTryTiles(void) +{ + IceTBoolean success = ICET_TRUE; + IceTInt num_proc; + IceTInt tile_dimension; + + icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc); + + for (tile_dimension = 1; + (tile_dimension <= 4) && (tile_dimension*tile_dimension <= num_proc); + tile_dimension++) { + printstat("\nUsing %dx%d tiles\n", tile_dimension, tile_dimension); + + SetUpTiles(tile_dimension); + MakeValidPixelViewports(); + + success &= PreRenderTryStrategy(); + } + + return success; +} + +static int PreRenderRun(void) +{ + IceTInt rank; + IceTInt num_proc; + unsigned int seed; + + icetGetIntegerv(ICET_RANK, &rank); + icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc); + + g_all_valid_pixel_viewports = malloc(4*num_proc*sizeof(IceTInt)); + + /* Establish a random seed. */ + if (rank == 0) { + IceTInt remote_process; + + seed = (int)time(NULL); + printstat("Base seed = %u\n", seed); + srand(seed); + + for (remote_process = 1; remote_process < num_proc; remote_process++) { + icetCommSend(&seed, 1, ICET_INT, remote_process, 29); + } + } else { + icetCommRecv(&seed, 1, ICET_INT, 0, 29); + srand(seed + rank); + } + + { + IceTBoolean success = PreRenderTryTiles(); + + free(g_all_valid_pixel_viewports); + + return (success ? TEST_PASSED : TEST_FAILED); + } +} + +int PreRender(int argc, char *argv[]) +{ + /* Suppress warning. */ + (void)argc; + (void)argv; + + return run_test(PreRenderRun); +} diff --git tests/RadixkUnitTests.c tests/RadixkUnitTests.c index db06891..a159f6e 100644 --- tests/RadixkUnitTests.c +++ tests/RadixkUnitTests.c @@ -10,13 +10,13 @@ #include #include "test_codes.h" -#include "test-util.h" +#include "test_util.h" #include extern ICET_EXPORT IceTBoolean icetRadixkPartitionLookupUnitTest(void); -extern ICET_EXPORT IceTBoolean icetRadixTelescopeSendReceiveTest(void); +extern ICET_EXPORT IceTBoolean icetRadixkTelescopeSendReceiveTest(void); static int RadixkUnitTestsRun(void) { @@ -31,7 +31,7 @@ static int RadixkUnitTestsRun(void) return TEST_FAILED; } - if (!icetRadixTelescopeSendReceiveTest()) { + if (!icetRadixkTelescopeSendReceiveTest()) { return TEST_FAILED; } diff --git tests/RadixkrUnitTests.c tests/RadixkrUnitTests.c new file mode 100644 index 0000000..99a70a6 --- /dev/null +++ tests/RadixkrUnitTests.c @@ -0,0 +1,42 @@ +/* -*- c -*- ***************************************************************** +** Copyright (C) 2011 Sandia Corporation +** Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +** the U.S. Government retains certain rights in this software. +** +** This source code is released under the New BSD License. +** +** This exercises the radix-k unit tests of internal functions. +*****************************************************************************/ + +#include +#include "test_codes.h" +#include "test_util.h" + +#include + +extern ICET_EXPORT IceTBoolean icetRadixkrPartitionLookupUnitTest(void); + +static int RadixkUnitTestsRun(void) +{ + IceTInt rank; + + icetGetIntegerv(ICET_RANK, &rank); + if (rank != 0) { + return TEST_PASSED; + } + + if (!icetRadixkrPartitionLookupUnitTest()) { + return TEST_FAILED; + } + + return TEST_PASSED; +} + +int RadixkrUnitTests(int argc, char *argv[]) +{ + /* To remove warning. */ + (void)argc; + (void)argv; + + return run_test(RadixkUnitTestsRun); +} diff --git tests/RandomTransform.c tests/RandomTransform.c index b2849a0..30c831c 100644 --- tests/RandomTransform.c +++ tests/RandomTransform.c @@ -14,7 +14,7 @@ #include #include #include "test_codes.h" -#include "test-util.h" +#include "test_util.h" #include #include @@ -274,34 +274,16 @@ static void check_results(int result) } } -static void RandomTransformDoRender(IceTBoolean transparent, - IceTSizeType local_width, - IceTSizeType local_height) +static void check_image(IceTImage image, + IceTBoolean transparent, + IceTSizeType local_width, + IceTSizeType local_height) { - IceTImage image; IceTInt rank; int result = TEST_PASSED; icetGetIntegerv(ICET_RANK, &rank); - printstat("Rendering frame.\n"); - if (transparent) { - glColor4f(0.5f*g_color[0], 0.5f*g_color[1], 0.5f*g_color[2], 0.5f); - } else { - glColor4f(g_color[0], g_color[1], g_color[2], 1.0f); - } - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - glOrtho(-1.0f, - (GLfloat)((2.0*local_width*g_tile_dim)/SCREEN_WIDTH-1.0), - -1.0f, - (GLfloat)((2.0*local_height*g_tile_dim)/SCREEN_HEIGHT-1.0), - -1.0f, 1.0f); - glMatrixMode(GL_MODELVIEW); - glLoadMatrixf(g_modelview); - image = icetGLDrawFrame(); - swap_buffers(); - if (rank < g_tile_dim*g_tile_dim) { if (transparent) { if (!compare_color_buffers(local_width, local_height, @@ -328,6 +310,121 @@ static void RandomTransformDoRender(IceTBoolean transparent, check_results(result); } +static void RandomTransformDoRender(IceTBoolean transparent, + IceTSizeType local_width, + IceTSizeType local_height) +{ + IceTImage image; + + if (transparent) { + glColor4f(0.5f*g_color[0], 0.5f*g_color[1], 0.5f*g_color[2], 0.5f); + } else { + glColor4f(g_color[0], g_color[1], g_color[2], 1.0f); + } + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-1.0f, + (GLfloat)((2.0*local_width*g_tile_dim)/SCREEN_WIDTH-1.0), + -1.0f, + (GLfloat)((2.0*local_height*g_tile_dim)/SCREEN_HEIGHT-1.0), + -1.0f, 1.0f); + glMatrixMode(GL_MODELVIEW); + glLoadMatrixf(g_modelview); + + printstat("Prerendering frame for composite.\n"); + { + IceTFloat background_color[4]; + IceTVoid *color_buffer = NULL; + IceTVoid *depth_buffer = NULL; + IceTEnum color_format; + IceTEnum depth_format; + IceTDouble projection_matrix[16]; + IceTDouble modelview_matrix[16]; + IceTInt physical_viewport[4]; + IceTInt global_viewport[4]; + IceTSizeType width; + IceTSizeType height; + + /* When using draw to render the image directly, we have to change */ + /* a few OpenGL state variables and then restore them. */ + glGetFloatv(GL_COLOR_CLEAR_VALUE, background_color); + if (transparent) { glClearColor(0.0, 0.0, 0.0, 0.0); } + glGetIntegerv(GL_VIEWPORT, physical_viewport); + icetGetIntegerv(ICET_GLOBAL_VIEWPORT, global_viewport); + width = global_viewport[2]; height = global_viewport[3]; + glViewport(0, 0, width, height); + draw(); + glViewport(physical_viewport[0], physical_viewport[1], + physical_viewport[2], physical_viewport[3]); + glClearColor(background_color[0], background_color[1], + background_color[2], background_color[3]); + glReadBuffer(GL_BACK); + glPixelStorei(GL_PACK_ROW_LENGTH, 0); + + icetGetEnumv(ICET_COLOR_FORMAT, &color_format); + switch (color_format) { + case ICET_IMAGE_COLOR_RGBA_UBYTE: + color_buffer = malloc(width*height*4*sizeof(IceTUByte)); + glReadPixels(0, 0, + width, height, + GL_RGBA, + GL_UNSIGNED_BYTE, + color_buffer); + break; + case ICET_IMAGE_COLOR_RGBA_FLOAT: + color_buffer = malloc(width*height*4*sizeof(IceTFloat)); + glReadPixels(0, 0, + width, height, + GL_RGBA, + GL_FLOAT, + color_buffer); + break; + case ICET_IMAGE_COLOR_NONE: + /* Do nothing. */ + break; + default: + printf("********* Invalid color format 0x%x!\n", color_format); + finalize_test(TEST_FAILED); + exit(TEST_FAILED); + } + + icetGetEnumv(ICET_DEPTH_FORMAT, &depth_format); + switch (depth_format) { + case ICET_IMAGE_DEPTH_FLOAT: + depth_buffer = malloc(width*height*sizeof(IceTFloat)); + glReadPixels(0, 0, + width, height, + GL_DEPTH_COMPONENT, + GL_FLOAT, + depth_buffer); + break; + case ICET_IMAGE_DEPTH_NONE: + /* Do nothing. */ + break; + default: + printf("********* Invalid depth format 0x%x!\n", depth_format); + finalize_test(TEST_FAILED); + exit(TEST_FAILED); + } + glGetDoublev(GL_PROJECTION_MATRIX, projection_matrix); + glGetDoublev(GL_MODELVIEW_MATRIX, modelview_matrix); + image = icetCompositeImage(color_buffer, + depth_buffer, + NULL, + projection_matrix, + modelview_matrix, + background_color); + if (color_buffer) { free(color_buffer); } + if (depth_buffer) { free(depth_buffer); } + check_image(image, transparent, local_width, local_height); + } + + printstat("Rendering frame with callbacks.\n"); + image = icetGLDrawFrame(); + swap_buffers(); + check_image(image, transparent, local_width, local_height); +} + static void RandomTransformTryInterlace(IceTBoolean transparent, IceTSizeType local_width, IceTSizeType local_height) diff --git tests/RenderEmpty.c tests/RenderEmpty.c new file mode 100644 index 0000000..87688f9 --- /dev/null +++ tests/RenderEmpty.c @@ -0,0 +1,244 @@ +/* -*- c -*- ***************************************************************** +** Copyright (C) 2013 Sandia Corporation +** Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, +** the U.S. Government retains certain rights in this software. +** +** This source code is released under the New BSD License. +** +** This tests the ICET_RENDER_EMPTY_IMAGES option. It makes sure that the +** render callback is invoked even if the option is on and not if the option +** is off. +*****************************************************************************/ + +#include +#include "test_codes.h" +#include "test_util.h" + +#include + +#include +#include +#include + +static const IceTFloat g_background_color[4] = { 0.5, 0.5, 0.5, 1.0 }; +static const IceTFloat g_foreground_color[4] = { 0.0, 0.25, 0.5, 1.0 }; + +IceTBoolean g_render_callback_invoked; +IceTBoolean g_render_callback_parameters_correct; + +static IceTBoolean ColorsEqual(const IceTFloat *color1, const IceTFloat *color2) +{ + IceTBoolean result; + + result = (color1[0] == color2[0]); + result &= (color1[1] == color2[1]); + result &= (color1[2] == color2[2]); + result &= (color1[3] == color2[3]); + + return result; +} + +static void RenderEmptyDraw(const IceTDouble *projection_matrix, + const IceTDouble *modelview_matrix, + const IceTFloat *background_color, + const IceTInt *readback_viewport, + IceTImage result) +{ + IceTSizeType width; + IceTSizeType height; + IceTFloat *colors; + + /* Report that the callback was invoked. */ + g_render_callback_invoked = ICET_TRUE; + + width = icetImageGetWidth(result); + height = icetImageGetHeight(result); + colors = icetImageGetColorf(result); + + /* Set all pixels to something invalid. IceT should be ignoring them. */ + { + IceTSizeType pixel; + for (pixel = 0; pixel < width*height; pixel++) { + colors[4*pixel + 0] = g_foreground_color[0]; + colors[4*pixel + 1] = g_foreground_color[1]; + colors[4*pixel + 2] = g_foreground_color[2]; + colors[4*pixel + 3] = g_foreground_color[3]; + } + } + + g_render_callback_parameters_correct = ICET_TRUE; + + /* Check to make sure that readback_viewport is actually empty. If it is + * not, we can expect an error later when we check the image, but put a + * warning here to help diagnose where the problem is. */ + + if ((readback_viewport[2] != 0) || (readback_viewport[3] != 0)) { + printrank("Got a readback_viewport with a positive dimension: %dx%d\n", + readback_viewport[2], readback_viewport[3]); + g_render_callback_parameters_correct = ICET_FALSE; + } + + /* Even though IceT should ignore anything in the render, it should still + * pass valid rendering parameters. Check them now. */ + if ( (background_color[0] != 0.0f) + || (background_color[1] != 0.0f) + || (background_color[2] != 0.0f) + || (background_color[3] != 0.0f)) { + printrank("Got a bad background color %f %f %f %f.\n", + background_color[0], + background_color[1], + background_color[2], + background_color[3]); + g_render_callback_parameters_correct = ICET_FALSE; + } + { + int column_index; + for (column_index = 0; column_index < 4; column_index++) { + int row_index; + for (row_index = 0; row_index < 4; row_index++) { + IceTDouble projection_value = + ICET_MATRIX(projection_matrix, row_index, column_index); + IceTDouble modelview_value = + ICET_MATRIX(modelview_matrix, row_index, column_index); + IceTDouble expected_value = + (row_index == column_index) ? 1.0 : 0.0; + if (projection_value != expected_value) { + printrank("Got bad projection matrix, " + "row=%d, column=%d, value=%lf\n", + row_index, column_index, projection_value); + } + if (modelview_value != expected_value) { + printrank("Got bad modelview matrix, " + "row=%d, column=%d, value=%lf\n", + row_index, column_index, modelview_value); + } + } + } + } +} + +static void RenderEmptySetupRender() +{ + icetCompositeMode(ICET_COMPOSITE_MODE_BLEND); + icetSetColorFormat(ICET_IMAGE_COLOR_RGBA_FLOAT); + icetSetDepthFormat(ICET_IMAGE_DEPTH_NONE); + icetDisable(ICET_ORDERED_COMPOSITE); + icetEnable(ICET_CORRECT_COLORED_BACKGROUND); + + /* Sequential rendering means that the compositor will not try to skip + * empty tiles. */ + icetStrategy(ICET_STRATEGY_SEQUENTIAL); + + icetDrawCallback(RenderEmptyDraw); + + icetResetTiles(); + icetAddTile(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0); +} + +static void RenderEmptyGetMatrices(IceTDouble *projection_matrix, + IceTDouble *modelview_matrix) +{ + /* Don't really care about the matricies. Just use identities. */ + icetMatrixIdentity(projection_matrix); + icetMatrixIdentity(modelview_matrix); + + /* Declare the geometry well outside the view. */ + icetBoundingBoxd(1000.0, 2000.0, 1000.0, 2000.0, 1000.0, 2000.0); +} + +static int RenderEmptyCheckImage(const IceTImage image) +{ + IceTInt rank; + + icetGetIntegerv(ICET_RANK, &rank); + if (rank == 0) { + const IceTFloat *buffer; + IceTSizeType x, y; + + buffer = icetImageGetColorcf(image); + + for (y = 0; y < SCREEN_HEIGHT; y++) { + for (x = 0; x < SCREEN_WIDTH; x++) { + const IceTFloat *pixel = buffer + 4*(y*SCREEN_WIDTH + x); + if (!ColorsEqual(pixel, g_background_color)) { + printrank("**** Found bad pixel!!!! ****\n"); + printrank("Region location x = %d, y = %d\n", x, y); + printrank("Got color %f %f %f %f\n", + pixel[0], pixel[1], pixel[2], pixel[3]); + printrank("Expected %f %f %f %f\n", + g_background_color[0], + g_background_color[1], + g_background_color[2], + g_background_color[3]); + return TEST_FAILED; + } + } + } + } + + return TEST_PASSED; +} + +static int RenderEmptyTryRender() +{ + IceTDouble projection_matrix[16]; + IceTDouble modelview_matrix[16]; + IceTImage image; + + RenderEmptySetupRender(); + RenderEmptyGetMatrices(projection_matrix, modelview_matrix); + + image = icetDrawFrame(projection_matrix, + modelview_matrix, + g_background_color); + + return RenderEmptyCheckImage(image); +} + +static int RenderEmptyTryOptions() +{ + int result = TEST_PASSED; + + printstat("ICET_RENDER_EMPTY_IMAGES disabled. " + "Should NOT be in draw callback.\n"); + icetDisable(ICET_RENDER_EMPTY_IMAGES); + g_render_callback_invoked = ICET_FALSE; + g_render_callback_parameters_correct = ICET_FALSE; + result += RenderEmptyTryRender(); + if (g_render_callback_invoked) { + printrank("**** The draw callback was called ****\n"); + result = TEST_FAILED; + } + + /* Second call, empty renders should be called. */ + printstat("ICET_RENDER_EMPTY_IMAGES enabled. " + "Draw callback should be invoked everywhere.\n"); + icetEnable(ICET_RENDER_EMPTY_IMAGES); + g_render_callback_invoked = ICET_FALSE; + g_render_callback_parameters_correct = ICET_FALSE; + result += RenderEmptyTryRender(); + if (!g_render_callback_invoked) { + printrank("**** The draw callback was not called ****\n"); + result = TEST_FAILED; + } + if (!g_render_callback_parameters_correct) { + printrank("**** Matricies were wrong in callback ****\n"); + result = TEST_FAILED; + } + + return result; +} + +static int RenderEmptyRun(void) +{ + return RenderEmptyTryOptions(); +} + +int RenderEmpty(int argc, char *argv[]) +{ + /* To remove warning. */ + (void)argc; + (void)argv; + + return run_test(RenderEmptyRun); +} diff --git tests/SimpleExample.c tests/SimpleExample.c index 688c710..36f1969 100644 --- tests/SimpleExample.c +++ tests/SimpleExample.c @@ -10,32 +10,83 @@ *****************************************************************************/ #include -#include "test-util.h" +#include "test_util.h" #include "test_codes.h" -#ifdef __APPLE__ -# include -# include -#else -# include -# include -#endif - #include #include +#include + +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327950288 /* pi */ +#endif IceTInt rank; IceTInt num_proc; +#define SPHERE_RESOLUTION 20 +#define SPHERE_RADIUS 0.5f +#define SPHERE_NUM_QUADS (SPHERE_RESOLUTION*SPHERE_RESOLUTION/2) +#define SPHERE_NUM_VERTICES (SPHERE_NUM_QUADS*4) + +static void GetSphereArrays(GLfloat **vertex_array_p, GLfloat **normal_array_p) +{ + static GLfloat vertex_array[SPHERE_NUM_VERTICES*3]; + static GLfloat normal_array[SPHERE_NUM_VERTICES*3]; + static GLboolean arrays_initialized = 0; + + if (!arrays_initialized) + { + GLfloat cos_table[SPHERE_RESOLUTION+1]; + GLfloat sin_table[SPHERE_RESOLUTION+1]; + int theta_index, phi_index; + + // Fill out tables. + for (theta_index = 0; theta_index <= SPHERE_RESOLUTION; theta_index++) + { + cos_table[theta_index]=cosf((2*M_PI/SPHERE_RESOLUTION)*theta_index); + sin_table[theta_index]=sinf((2*M_PI/SPHERE_RESOLUTION)*theta_index); + } + + // Compute the vertices and normals. + GLfloat *vertex_p = vertex_array; + GLfloat *normal_p = normal_array; + for (phi_index = 0; phi_index < SPHERE_RESOLUTION/2; phi_index++) + { + for (theta_index = 0; theta_index #include +#include #include -#include "test-util.h" +#include "test_util.h" #include "test_codes.h" #include @@ -36,19 +37,38 @@ struct region_divide_struct { typedef struct region_divide_struct *region_divide; +#define NAME_SIZE 32 typedef struct { + IceTInt num_proc; + char strategy_name[NAME_SIZE]; + char si_strategy_name[NAME_SIZE]; + IceTInt num_tiles_x; + IceTInt num_tiles_y; + IceTInt screen_width; + IceTInt screen_height; + IceTFloat zoom; + IceTBoolean transparent; + IceTBoolean no_interlace; + IceTBoolean no_collect; + IceTBoolean dense_images; + IceTInt max_image_split; + IceTInt frame_number; IceTDouble render_time; IceTDouble buffer_read_time; IceTDouble buffer_write_time; IceTDouble compress_time; + IceTDouble interlace_time; IceTDouble blend_time; IceTDouble draw_time; IceTDouble composite_time; IceTDouble collect_time; - IceTInt bytes_sent; + IceTInt64 bytes_sent; IceTDouble frame_time; } timings_type; +static timings_type *g_timing_log; +static IceTSizeType g_timing_log_size; + /* Array for quick opacity lookups. */ #define OPACITY_LOOKUP_SIZE 4096 #define OPACITY_MAX_DT 4 @@ -80,10 +100,13 @@ static IceTInt g_num_tiles_x; static IceTInt g_num_tiles_y; static IceTInt g_num_frames; static IceTInt g_seed; +static IceTFloat g_zoom; static IceTBoolean g_transparent; static IceTBoolean g_colored_background; static IceTBoolean g_no_interlace; static IceTBoolean g_no_collect; +static IceTBoolean g_use_callback; +static IceTBoolean g_dense_images; static IceTBoolean g_sync_render; static IceTBoolean g_write_image; static IceTEnum g_strategy; @@ -92,6 +115,9 @@ static IceTBoolean g_do_magic_k_study; static IceTInt g_max_magic_k; static IceTBoolean g_do_image_split_study; static IceTInt g_min_image_split; +static IceTBoolean g_do_scaling_study_factor_2; +static IceTBoolean g_do_scaling_study_factor_2_3; +static IceTInt g_num_scaling_study_random; static float g_color[4]; @@ -101,25 +127,40 @@ static void usage(char *argv[]) printstat("\nWhere testargs are:\n"); printstat(" -tilesx Sets the number of tiles horizontal (default 1).\n"); printstat(" -tilesy Sets the number of tiles vertical (default 1).\n"); - printstat(" -frames Sets the number of frames to render (default 2).\n"); + printstat(" -frames Sets the number of frames to render (default 2).\n"); printstat(" -seed Use the given number as the random seed.\n"); + printstat(" -zoom Set the zoom factor for the camera (larger = more zoom).\n"); printstat(" -transparent Render transparent images. (Uses 4 floats for colors.)\n"); printstat(" -colored-background Use a color for the background and correct as necessary.\n"); printstat(" -no-interlace Turn off the image interlacing optimization.\n"); printstat(" -no-collect Turn off image collection.\n"); + printstat(" -use-callback Do the drawing in an IceT callback.\n"); printstat(" -sync-render Synchronize rendering by adding a barrier to the draw callback.\n"); + printstat(" -dense-images Composite dense images by classifying no pixels as background.\n"); printstat(" -write-image Write an image on the first frame.\n"); printstat(" -reduce Use the reduce strategy (default).\n"); printstat(" -vtree Use the virtual trees strategy.\n"); printstat(" -sequential Use the sequential strategy.\n"); printstat(" -bswap Use the binary-swap single-image strategy.\n"); + printstat(" -bswapfold Use the binary-swap with folding single-image strategy.\n"); printstat(" -radixk Use the radix-k single-image strategy.\n"); + printstat(" -radixkr Use the radix-kr single-image strategy.\n"); printstat(" -tree Use the tree single-image strategy.\n"); printstat(" -magic-k-study Use the radix-k single-image strategy and repeat for\n" - " multiple values of k, up to , doubling each time.\n"); + " multiple values of k, up to , doubling each time.\n"); printstat(" -max-image-split-study Repeat the test for multiple maximum image\n" - " splits starting at and doubling each time.\n"); - printstat(" -h, -help Print this help message.\n"); + " splits starting at and doubling each time.\n"); + printstat(" -scaling-study-factor-2 Perform a scaling study for all process counts\n" + " that are a factor of 2.\n"); + printstat(" -scaling-study-factor-2-3 Perform a scaling study that includes all\n" + " process counts that are a factor of 2 plus all process\n" + " counts that are a factor of 3 plus most process counts\n" + " that have factors of 2 and 3.\n"); + printstat(" -scaling-study-random Picks a random number to bifurcate the\n" + " processes and runs the compositing on each of them. This\n" + " experiment is run times. Run enough times this test\n" + " should give performance over scales at odd process counts.\n"); + printstat(" -h, -help Print this help message.\n"); printstat("\nFor general testing options, try -h or -help before test name.\n"); } @@ -131,11 +172,14 @@ static void parse_arguments(int argc, char *argv[]) g_num_tiles_y = 1; g_num_frames = 2; g_seed = (IceTInt)time(NULL); + g_zoom = (IceTFloat)1.0; g_transparent = ICET_FALSE; g_colored_background = ICET_FALSE; - g_sync_render = ICET_FALSE; g_no_interlace = ICET_FALSE; g_no_collect = ICET_FALSE; + g_use_callback = ICET_FALSE; + g_dense_images = ICET_FALSE; + g_sync_render = ICET_FALSE; g_write_image = ICET_FALSE; g_strategy = ICET_STRATEGY_REDUCE; g_single_image_strategy = ICET_SINGLE_IMAGE_STRATEGY_AUTOMATIC; @@ -143,6 +187,9 @@ static void parse_arguments(int argc, char *argv[]) g_max_magic_k = 0; g_do_image_split_study = ICET_FALSE; g_min_image_split = 0; + g_do_scaling_study_factor_2 = ICET_FALSE; + g_do_scaling_study_factor_2_3 = ICET_FALSE; + g_num_scaling_study_random = 0; for (arg = 1; arg < argc; arg++) { if (strcmp(argv[arg], "-tilesx") == 0) { @@ -157,6 +204,9 @@ static void parse_arguments(int argc, char *argv[]) } else if (strcmp(argv[arg], "-seed") == 0) { arg++; g_seed = atoi(argv[arg]); + } else if (strcmp(argv[arg], "-zoom") == 0) { + arg++; + g_zoom = (IceTFloat)atof(argv[arg]); } else if (strcmp(argv[arg], "-transparent") == 0) { g_transparent = ICET_TRUE; } else if (strcmp(argv[arg], "-colored-background") == 0) { @@ -165,6 +215,12 @@ static void parse_arguments(int argc, char *argv[]) g_no_interlace = ICET_TRUE; } else if (strcmp(argv[arg], "-no-collect") == 0) { g_no_collect = ICET_TRUE; + } else if (strcmp(argv[arg], "-use-callback") == 0) { + g_use_callback = ICET_TRUE; + } else if (strcmp(argv[arg], "-dense-images") == 0) { + g_dense_images = ICET_TRUE; + /* Turn of interlacing. It won't help here. */ + g_no_interlace = ICET_TRUE; } else if (strcmp(argv[arg], "-sync-render") == 0) { g_sync_render = ICET_TRUE; } else if (strcmp(argv[arg], "-write-image") == 0) { @@ -177,20 +233,31 @@ static void parse_arguments(int argc, char *argv[]) g_strategy = ICET_STRATEGY_SEQUENTIAL; } else if (strcmp(argv[arg], "-bswap") == 0) { g_single_image_strategy = ICET_SINGLE_IMAGE_STRATEGY_BSWAP; + } else if (strcmp(argv[arg], "-bswapfold") == 0) { + g_single_image_strategy = ICET_SINGLE_IMAGE_STRATEGY_BSWAP_FOLDING; } else if (strcmp(argv[arg], "-radixk") == 0) { g_single_image_strategy = ICET_SINGLE_IMAGE_STRATEGY_RADIXK; + } else if (strcmp(argv[arg], "-radixkr") == 0) { + g_single_image_strategy = ICET_SINGLE_IMAGE_STRATEGY_RADIXKR; } else if (strcmp(argv[arg], "-tree") == 0) { g_single_image_strategy = ICET_SINGLE_IMAGE_STRATEGY_TREE; } else if (strcmp(argv[arg], "-magic-k-study") == 0) { g_do_magic_k_study = ICET_TRUE; - g_single_image_strategy = ICET_SINGLE_IMAGE_STRATEGY_RADIXK; + g_single_image_strategy = ICET_SINGLE_IMAGE_STRATEGY_RADIXKR; arg++; g_max_magic_k = atoi(argv[arg]); } else if (strcmp(argv[arg], "-max-image-split-study") == 0) { g_do_image_split_study = ICET_TRUE; - g_single_image_strategy = ICET_SINGLE_IMAGE_STRATEGY_RADIXK; + g_single_image_strategy = ICET_SINGLE_IMAGE_STRATEGY_RADIXKR; arg++; g_min_image_split = atoi(argv[arg]); + } else if (strcmp(argv[arg], "-scaling-study-factor-2") == 0) { + g_do_scaling_study_factor_2 = ICET_TRUE; + } else if (strcmp(argv[arg], "-scaling-study-factor-2-3") == 0) { + g_do_scaling_study_factor_2_3 = ICET_TRUE; + } else if (strcmp(argv[arg], "-scaling-study-random") == 0) { + arg++; + g_num_scaling_study_random = atoi(argv[arg]); } else if ( (strcmp(argv[arg], "-h") == 0) || (strcmp(argv[arg], "-help")) ) { usage(argv); @@ -302,8 +369,8 @@ static void draw(const IceTDouble *projection_matrix, IceTBoolean success; int planeIdx; struct hexahedron transformed_box; - IceTInt screen_width; - IceTInt screen_height; + IceTInt width; + IceTInt height; IceTFloat *colors_float = NULL; IceTUByte *colors_byte = NULL; IceTFloat *depths = NULL; @@ -311,11 +378,14 @@ static void draw(const IceTDouble *projection_matrix, IceTInt pixel_y; IceTDouble ray_origin[3]; IceTDouble ray_direction[3]; + IceTFloat background_depth; + IceTFloat background_alpha; icetMatrixMultiply(transform, projection_matrix, modelview_matrix); success = icetMatrixInverseTranspose((const IceTDouble *)transform, inverse_transpose_transform); + if (!success) { printrank("ERROR: Inverse failed.\n"); } @@ -329,8 +399,8 @@ static void draw(const IceTDouble *projection_matrix, original_plane); } - icetGetIntegerv(ICET_PHYSICAL_RENDER_WIDTH, &screen_width); - icetGetIntegerv(ICET_PHYSICAL_RENDER_HEIGHT, &screen_height); + width = icetImageGetWidth(result); + height = icetImageGetHeight(result); if (g_transparent) { colors_float = icetImageGetColorf(result); @@ -339,13 +409,46 @@ static void draw(const IceTDouble *projection_matrix, depths = icetImageGetDepthf(result); } + if (!g_dense_images) { + background_depth = 1.0f; + background_alpha = background_color[3]; + } else { + IceTSizeType pixel_index; + + /* To fake dense images, use a depth and alpha for the background that + * IceT will not recognize as background. */ + background_depth = 0.999f; + background_alpha + = (background_color[3] == 0) ? 0.001 : background_color[3]; + + /* Clear out the the images to background so that pixels outside of + * the contained viewport have valid values. */ + for (pixel_index = 0; pixel_index < width*height; pixel_index++) { + if (g_transparent) { + IceTFloat *color_dest = colors_float + 4*pixel_index; + color_dest[0] = background_color[0]; + color_dest[1] = background_color[1]; + color_dest[2] = background_color[2]; + color_dest[3] = background_alpha; + } else { + IceTUByte *color_dest = colors_byte + 4*pixel_index; + IceTFloat *depth_dest = depths + pixel_index; + color_dest[0] = (IceTUByte)(background_color[0]*255); + color_dest[1] = (IceTUByte)(background_color[1]*255); + color_dest[2] = (IceTUByte)(background_color[2]*255); + color_dest[3] = (IceTUByte)(background_alpha*255); + depth_dest[0] = background_depth; + } + } + } + ray_direction[0] = ray_direction[1] = 0.0; ray_direction[2] = 1.0; ray_origin[2] = -1.0; for (pixel_y = readback_viewport[1]; pixel_y < readback_viewport[1] + readback_viewport[3]; pixel_y++) { - ray_origin[1] = (2.0*pixel_y)/screen_height - 1.0; + ray_origin[1] = (2.0*pixel_y)/height - 1.0; for (pixel_x = readback_viewport[0]; pixel_x < readback_viewport[0] + readback_viewport[2]; pixel_x++) { @@ -356,7 +459,7 @@ static void draw(const IceTDouble *projection_matrix, IceTFloat color[4]; IceTFloat depth; - ray_origin[0] = (2.0*pixel_x)/screen_width - 1.0; + ray_origin[0] = (2.0*pixel_x)/width - 1.0; intersect_ray_hexahedron(ray_origin, ray_direction, @@ -382,6 +485,7 @@ static void draw(const IceTDouble *projection_matrix, /* Modify color by an opacity determined by thickness. */ IceTDouble thickness = far_distance - near_distance; IceTDouble opacity = QUICK_OPACITY(4.0*thickness); + if (opacity < 0.001) { opacity = 0.001; } color[0] *= (IceTFloat)opacity; color[1] *= (IceTFloat)opacity; color[2] *= (IceTFloat)opacity; @@ -391,22 +495,22 @@ static void draw(const IceTDouble *projection_matrix, color[0] = background_color[0]; color[1] = background_color[1]; color[2] = background_color[2]; - color[3] = background_color[3]; - depth = 1.0f; + color[3] = background_alpha; + depth = background_depth; } if (g_transparent) { IceTFloat *color_dest - = colors_float + 4*(pixel_y*screen_width + pixel_x); + = colors_float + 4*(pixel_y*width + pixel_x); color_dest[0] = color[0]; color_dest[1] = color[1]; color_dest[2] = color[2]; color_dest[3] = color[3]; } else { IceTUByte *color_dest - = colors_byte + 4*(pixel_y*screen_width + pixel_x); + = colors_byte + 4*(pixel_y*width + pixel_x); IceTFloat *depth_dest - = depths + pixel_y*screen_width + pixel_x; + = depths + pixel_y*width + pixel_x; color_dest[0] = (IceTUByte)(color[0]*255); color_dest[1] = (IceTUByte)(color[1]*255); color_dest[2] = (IceTUByte)(color[2]*255); @@ -593,10 +697,264 @@ static void find_composite_order(const IceTDouble *projection, free(process_ranks); } +/* Finds the viewport of the bounds of the locally rendered geometry. */ +/* This code is stolen from drawFindContainedViewport in draw.c. */ +static void find_contained_viewport(IceTInt contained_viewport[4], + const IceTDouble projection_matrix[16], + const IceTDouble modelview_matrix[16]) +{ + IceTDouble total_transform[16]; + IceTDouble left, right, bottom, top; + IceTDouble *transformed_verts; + IceTInt global_viewport[4]; + IceTInt num_bounding_verts; + int i; + + icetGetIntegerv(ICET_GLOBAL_VIEWPORT, global_viewport); + + { + IceTDouble viewport_matrix[16]; + IceTDouble tmp_matrix[16]; + + /* Strange projection matrix that transforms the x and y of normalized + screen coordinates into viewport coordinates that may be cast to + integers. */ + viewport_matrix[ 0] = global_viewport[2]; + viewport_matrix[ 1] = 0.0; + viewport_matrix[ 2] = 0.0; + viewport_matrix[ 3] = 0.0; + + viewport_matrix[ 4] = 0.0; + viewport_matrix[ 5] = global_viewport[3]; + viewport_matrix[ 6] = 0.0; + viewport_matrix[ 7] = 0.0; + + viewport_matrix[ 8] = 0.0; + viewport_matrix[ 9] = 0.0; + viewport_matrix[10] = 2.0; + viewport_matrix[11] = 0.0; + + viewport_matrix[12] = global_viewport[2] + global_viewport[0]*2.0; + viewport_matrix[13] = global_viewport[3] + global_viewport[1]*2.0; + viewport_matrix[14] = 0.0; + viewport_matrix[15] = 2.0; + + icetMatrixMultiply(tmp_matrix, + (const IceTDouble *)projection_matrix, + (const IceTDouble *)modelview_matrix); + icetMatrixMultiply(total_transform, + (const IceTDouble *)viewport_matrix, + (const IceTDouble *)tmp_matrix); + } + + icetGetIntegerv(ICET_NUM_BOUNDING_VERTS, &num_bounding_verts); + transformed_verts = icetGetStateBuffer( + ICET_TRANSFORMED_BOUNDS, + sizeof(IceTDouble)*num_bounding_verts*4); + + /* Transform each vertex to find where it lies in the global viewport and + normalized z. Leave the results in homogeneous coordinates for now. */ + { + const IceTDouble *bound_vert + = icetUnsafeStateGetDouble(ICET_GEOMETRY_BOUNDS); + for (i = 0; i < num_bounding_verts; i++) { + IceTDouble bound_vert_4vec[4]; + bound_vert_4vec[0] = bound_vert[3*i+0]; + bound_vert_4vec[1] = bound_vert[3*i+1]; + bound_vert_4vec[2] = bound_vert[3*i+2]; + bound_vert_4vec[3] = 1.0; + icetMatrixVectorMultiply(transformed_verts + 4*i, + (const IceTDouble *)total_transform, + (const IceTDouble *)bound_vert_4vec); + } + } + + /* Set absolute mins and maxes. */ + left = global_viewport[0] + global_viewport[2]; + right = global_viewport[0]; + bottom = global_viewport[1] + global_viewport[3]; + top = global_viewport[1]; + + /* Now iterate over all the transformed verts and adjust the absolute mins + and maxs to include them all. */ + for (i = 0; i < num_bounding_verts; i++) + { + IceTDouble *vert = transformed_verts + 4*i; + + /* Check to see if the vertex is in front of the near cut plane. This + is true when z/w >= -1 or z + w >= 0. The second form is better just + in case w is 0. */ + if (vert[2] + vert[3] >= 0.0) { + /* Normalize homogeneous coordinates. */ + IceTDouble invw = 1.0/vert[3]; + IceTDouble x = vert[0]*invw; + IceTDouble y = vert[1]*invw; + + /* Update contained region. */ + if (left > x) left = x; + if (right < x) right = x; + if (bottom > y) bottom = y; + if (top < y) top = y; + } else { + /* The vertex is being clipped by the near plane. In perspective + mode, vertices behind the near clipping plane can sometimes give + misleading projections. Instead, find all the other vertices on + the other side of the near plane, compute the intersection of the + segment between the two points and the near plane (in homogeneous + coordinates) and use that as the projection. */ + int j; + for (j = 0; j < num_bounding_verts; j++) { + IceTDouble *vert2 = transformed_verts + 4*j; + double t; + IceTDouble x, y, invw; + if (vert2[2] + vert2[3] < 0.0) { + /* Ignore other points behind near plane. */ + continue; + } + /* Let the two points in question be v_i and v_j. Define the + segment between them with the parametric equation + p(t) = (vert - vert2)t + vert2. First, find t where the z and + w coordinates of p(t) sum to zero. */ + t = (vert2[2]+vert2[3])/(vert2[2]-vert[2] + vert2[3]-vert[3]); + /* Use t to find the intersection point. While we are at it, + normalize the resulting coordinates. We don't need z because + we know it is going to be -1. */ + invw = 1.0/((vert[3] - vert2[3])*t + vert2[3] ); + x = ((vert[0] - vert2[0])*t + vert2[0] ) * invw; + y = ((vert[1] - vert2[1])*t + vert2[1] ) * invw; + + /* Update contained region. */ + if (left > x) left = x; + if (right < x) right = x; + if (bottom > y) bottom = y; + if (top < y) top = y; + } + } + } + + left = floor(left); + right = ceil(right); + bottom = floor(bottom); + top = ceil(top); + + /* Clip bounds to global viewport. */ + if (left < global_viewport[0]) left = global_viewport[0]; + if (right > global_viewport[0] + global_viewport[2]) + right = global_viewport[0] + global_viewport[2]; + if (bottom < global_viewport[1]) bottom = global_viewport[1]; + if (top > global_viewport[1] + global_viewport[3]) + top = global_viewport[1] + global_viewport[3]; + + /* Use this information to build a containing viewport. */ + contained_viewport[0] = (IceTInt)left; + contained_viewport[1] = (IceTInt)bottom; + contained_viewport[2] = (IceTInt)(right - left); + contained_viewport[3] = (IceTInt)(top - bottom); +} + +static void SimpleTimingCollectAndPrintLog() +{ + IceTInt rank; + IceTInt num_proc; + IceTInt *log_sizes; + + icetGetIntegerv(ICET_RANK, &rank); + icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc); + + /* Collect the number of log entries each process has. */ + log_sizes = malloc(num_proc*sizeof(IceTInt)); + icetCommGather(&g_timing_log_size, 1, ICET_SIZE_TYPE, log_sizes, 0); + + if (rank == 0) { + timings_type *all_logs; + IceTSizeType *data_sizes; + IceTSizeType *offsets; + IceTInt total_logs; + IceTInt proc_index; + IceTInt log_index; + + data_sizes = malloc(num_proc*sizeof(IceTSizeType)); + offsets = malloc(num_proc*sizeof(IceTSizeType)); + + total_logs = 0; + for (proc_index = 0; proc_index < num_proc; proc_index++) { + data_sizes[proc_index] = log_sizes[proc_index]*sizeof(timings_type); + offsets[proc_index] = total_logs*sizeof(timings_type); + total_logs += log_sizes[proc_index]; + } + + all_logs = malloc(total_logs*sizeof(timings_type)); + icetCommGatherv(g_timing_log, + g_timing_log_size*sizeof(timings_type), + ICET_BYTE, + all_logs, + data_sizes, + offsets, + 0); + + for (log_index = 0; log_index < total_logs; log_index++) { + timings_type *timing = all_logs + log_index; + printf("LOG,%d,%s,%s,%d,%d,%d,%d,%0.1f,%s,%s,%s,%s,%d,%d,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%ld,%lg\n", + timing->num_proc, + timing->strategy_name, + timing->si_strategy_name, + timing->num_tiles_x, + timing->num_tiles_y, + timing->screen_width, + timing->screen_height, + timing->zoom, + timing->transparent ? "yes" : "no", + timing->no_interlace ? "no" : "yes", + timing->no_collect ? "no" : "yes", + timing->dense_images ? "yes" : "no", + timing->max_image_split, + timing->frame_number, + timing->render_time, + timing->buffer_read_time, + timing->buffer_write_time, + timing->compress_time, + timing->interlace_time, + timing->blend_time, + timing->draw_time, + timing->composite_time, + timing->collect_time, + (long int)timing->bytes_sent, + timing->frame_time); + } + + free(data_sizes); + free(offsets); + free(all_logs); + } else /* rank != 0 */ { + icetCommGatherv(g_timing_log, + g_timing_log_size*sizeof(timings_type), + ICET_BYTE, + NULL, + NULL, + NULL, + 0); + } + + free(log_sizes); + + if (g_timing_log_size > 0) { + free(g_timing_log); + g_timing_log = NULL; + g_timing_log_size = 0; + } + + /* This is to prevent a non-root from printing while the root is writing + the log. */ + icetCommBarrier(); +} + static int SimpleTimingDoRender() { IceTInt rank; IceTInt num_proc; + const char *strategy_name; + const char *si_strategy_name; + IceTInt max_image_split; float aspect = ( (float)(g_num_tiles_x*SCREEN_WIDTH) / (float)(g_num_tiles_y*SCREEN_HEIGHT) ); @@ -608,12 +966,15 @@ static int SimpleTimingDoRender() IceTDouble projection_matrix[16]; IceTFloat background_color[4]; + IceTImage pre_rendered_image = icetImageNull(); + void *pre_rendered_image_buffer = NULL; + timings_type *timing_array; /* Normally, the first thing that you do is set up your communication and * then create at least one IceT context. This has already been done in the - * calling function (i.e. icetTests_mpi.c). See the init_mpi_comm in - * mpi_comm.h for an example. + * calling function (i.e. icetTests_mpi.c). See the init_mpi in + * test_mpi.h for an example. */ init_opacity_lookup(); @@ -663,9 +1024,9 @@ static int SimpleTimingDoRender() icetEnable(ICET_COLLECT_IMAGES); } - /* Give IceT the bounds of the polygons that will be drawn. Note that IceT - * will take care of any transformation that gets passed to - * icetDrawFrame. */ + /* Give IceT the bounds of the polygons that will be drawn. Note that + * IceT will take care of any transformation that gets passed to + * icetDrawFrame. */ icetBoundingBoxd(-0.5f, 0.5f, -0.5, 0.5, -0.5, 0.5); /* Determine the region we want the local geometry to be in. This will be @@ -695,11 +1056,27 @@ static int SimpleTimingDoRender() return TEST_FAILED; } + if (!g_use_callback) { + IceTInt global_viewport[4]; + IceTInt width, height; + IceTInt buffer_size; + + icetGetIntegerv(ICET_GLOBAL_VIEWPORT, global_viewport); + width = global_viewport[2]; height = global_viewport[3]; + + buffer_size = icetImageBufferSize(width, height); + pre_rendered_image_buffer = malloc(buffer_size); + pre_rendered_image = + icetImageAssignBuffer(pre_rendered_image_buffer, width, height); + } + icetStrategy(g_strategy); icetSingleImageStrategy(g_single_image_strategy); /* Set up the projection matrix. */ - icetMatrixFrustum(-0.65*aspect, 0.65*aspect, -0.65, 0.65, 3.0, 5.0, + icetMatrixFrustum(-0.65*aspect/g_zoom, 0.65*aspect/g_zoom, + -0.65/g_zoom, 0.65/g_zoom, + 3.0, 5.0, projection_matrix); if (rank%10 < 7) { @@ -729,16 +1106,32 @@ static int SimpleTimingDoRender() timing_array = malloc(g_num_frames * sizeof(timings_type)); + strategy_name = icetGetStrategyName(); + if (g_single_image_strategy == ICET_SINGLE_IMAGE_STRATEGY_RADIXK) { + static char name_buffer[256]; + IceTInt magic_k; + + icetGetIntegerv(ICET_MAGIC_K, &magic_k); + sprintf(name_buffer, "radix-k %d", (int)magic_k); + si_strategy_name = name_buffer; + } else if (g_single_image_strategy == ICET_SINGLE_IMAGE_STRATEGY_RADIXKR) { + static char name_buffer[256]; + IceTInt magic_k; + + icetGetIntegerv(ICET_MAGIC_K, &magic_k); + sprintf(name_buffer, "radix-kr %d", (int)magic_k); + si_strategy_name = name_buffer; + } else { + si_strategy_name = icetGetSingleImageStrategyName(); + } + + icetGetIntegerv(ICET_MAX_IMAGE_SPLIT, &max_image_split); + for (frame = 0; frame < g_num_frames; frame++) { IceTDouble elapsed_time; IceTDouble modelview_matrix[16]; IceTImage image; - /* Get everyone to start at the same time. */ - icetCommBarrier(); - - elapsed_time = icetWallTime(); - /* We can set up a modelview matrix here and IceT will factor this in * determining the screen projection of the geometry. */ icetMatrixIdentity(modelview_matrix); @@ -774,20 +1167,79 @@ static int SimpleTimingDoRender() bounds_max[2] - bounds_min[2]); icetMatrixMultiplyTranslate(modelview_matrix, 0.5, 0.5, 0.5); - /* Instead of calling draw() directly, call it indirectly through - * icetDrawFrame(). IceT will automatically handle image - * compositing. */ - g_first_render = ICET_TRUE; - image = icetDrawFrame(projection_matrix, - modelview_matrix, - background_color); + if (!g_use_callback) { + /* Draw the image for the frame. */ + IceTInt contained_viewport[4]; + find_contained_viewport(contained_viewport, + projection_matrix, + modelview_matrix); + if (g_transparent) { + IceTFloat black[4] = { 0.0, 0.0, 0.0, 0.0 }; + draw(projection_matrix, + modelview_matrix, + black, + contained_viewport, + pre_rendered_image); + } else { + draw(projection_matrix, + modelview_matrix, + background_color, + contained_viewport, + pre_rendered_image); + } + } + + if (g_dense_images) { + /* With dense images, we want IceT to load in all pixels, so clear + * out the bounding box/vertices. */ + icetBoundingVertices(0, ICET_VOID, 0, 0, NULL); + } + + /* Get everyone to start at the same time. */ + icetCommBarrier(); + + elapsed_time = icetWallTime(); + + if (g_use_callback) { + /* Instead of calling draw() directly, call it indirectly through + * icetDrawFrame(). IceT will automatically handle image + * compositing. */ + g_first_render = ICET_TRUE; + image = icetDrawFrame(projection_matrix, + modelview_matrix, + background_color); + } else { + image = icetCompositeImage( + icetImageGetColorConstVoid(pre_rendered_image,NULL), + g_transparent ? NULL : icetImageGetDepthConstVoid(pre_rendered_image,NULL), + NULL, + projection_matrix, + modelview_matrix, + background_color); + } /* Let everyone catch up before finishing the frame. */ icetCommBarrier(); elapsed_time = icetWallTime() - elapsed_time; - /* Print timings to logging. */ + /* Record timings to logging. */ + timing_array[frame].num_proc = num_proc; + strncpy(timing_array[frame].strategy_name, strategy_name, NAME_SIZE); + timing_array[frame].strategy_name[NAME_SIZE-1] = '\0'; + strncpy(timing_array[frame].si_strategy_name, si_strategy_name, NAME_SIZE); + timing_array[frame].si_strategy_name[NAME_SIZE-1] = '\0'; + timing_array[frame].num_tiles_x = g_num_tiles_x; + timing_array[frame].num_tiles_y = g_num_tiles_y; + timing_array[frame].screen_width = SCREEN_WIDTH; + timing_array[frame].screen_height = SCREEN_HEIGHT; + timing_array[frame].zoom = g_zoom; + timing_array[frame].transparent = g_transparent; + timing_array[frame].no_interlace = g_no_interlace; + timing_array[frame].no_collect = g_no_collect; + timing_array[frame].dense_images = g_dense_images; + timing_array[frame].max_image_split = max_image_split; + timing_array[frame].frame_number = frame; icetGetDoublev(ICET_RENDER_TIME, &timing_array[frame].render_time); icetGetDoublev(ICET_BUFFER_READ_TIME, @@ -796,6 +1248,8 @@ static int SimpleTimingDoRender() &timing_array[frame].buffer_write_time); icetGetDoublev(ICET_COMPRESS_TIME, &timing_array[frame].compress_time); + icetGetDoublev(ICET_INTERLACE_TIME, + &timing_array[frame].interlace_time); icetGetDoublev(ICET_BLEND_TIME, &timing_array[frame].blend_time); icetGetDoublev(ICET_TOTAL_DRAW_TIME, @@ -804,8 +1258,8 @@ static int SimpleTimingDoRender() &timing_array[frame].composite_time); icetGetDoublev(ICET_COLLECT_TIME, &timing_array[frame].collect_time); - icetGetIntegerv(ICET_BYTES_SENT, - &timing_array[frame].bytes_sent); + timing_array[frame].bytes_sent + = icetUnsafeStateGetInteger(ICET_BYTES_SENT)[0]; timing_array[frame].frame_time = elapsed_time; /* Write out image to verify rendering occurred correctly. */ @@ -822,27 +1276,20 @@ static int SimpleTimingDoRender() } } - /* Print logging header. */ + /* Collect max times and log. */ { timings_type *timing_collection = malloc(num_proc*sizeof(timings_type)); - const char *strategy_name; - const char *si_strategy_name; - IceTInt max_image_split; - strategy_name = icetGetStrategyName(); - if (g_single_image_strategy == ICET_SINGLE_IMAGE_STRATEGY_RADIXK) { - static char name_buffer[256]; - IceTInt magic_k; - - icetGetIntegerv(ICET_MAGIC_K, &magic_k); - sprintf(name_buffer, "radix-k %d", (int)magic_k); - si_strategy_name = name_buffer; - } else { - si_strategy_name = icetGetSingleImageStrategyName(); + if (rank == 0) { + if (g_timing_log_size == 0) { + g_timing_log = malloc(g_num_frames*sizeof(timings_type)); + } else { + g_timing_log = realloc(g_timing_log, + (g_timing_log_size+g_num_frames) + *sizeof(timings_type)); + } } - icetGetIntegerv(ICET_MAX_IMAGE_SPLIT, &max_image_split); - for (frame = 0; frame < g_num_frames; frame++) { timings_type *timing = &timing_array[frame]; @@ -862,38 +1309,18 @@ static int SimpleTimingDoRender() UPDATE_MAX(buffer_read_time); UPDATE_MAX(buffer_write_time); UPDATE_MAX(compress_time); + UPDATE_MAX(interlace_time); UPDATE_MAX(blend_time); UPDATE_MAX(draw_time); UPDATE_MAX(composite_time); UPDATE_MAX(collect_time); - UPDATE_MAX(bytes_sent); UPDATE_MAX(frame_time); total_bytes_sent += timing_collection[p].bytes_sent; } + timing->bytes_sent = total_bytes_sent; - printf("LOG,%d,%s,%s,%d,%d,%d,%d,%s,%s,%s,%d,%d,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%lg,%ld,%lg\n", - num_proc, - strategy_name, - si_strategy_name, - g_num_tiles_x, - g_num_tiles_y, - SCREEN_WIDTH, - SCREEN_HEIGHT, - g_transparent ? "yes" : "no", - g_no_interlace ? "no" : "yes", - g_no_collect ? "no" : "yes", - max_image_split, - frame, - timing->render_time, - timing->buffer_read_time, - timing->buffer_write_time, - timing->compress_time, - timing->blend_time, - timing->draw_time, - timing->composite_time, - timing->collect_time, - (long int)total_bytes_sent, - timing->frame_time); + g_timing_log[g_timing_log_size] = *timing; + g_timing_log_size++; } } @@ -903,45 +1330,16 @@ static int SimpleTimingDoRender() free_region_divide(region_divisions); free(timing_array); - /* This is to prevent a non-root from printing while the root is writing - the log. */ - icetCommBarrier(); + pre_rendered_image = icetImageNull(); + if (pre_rendered_image_buffer != NULL) { + free(pre_rendered_image_buffer); + } return TEST_PASSED; } -int SimpleTimingRun() +static int SimpleTimingDoParameterStudies() { - IceTInt rank; - - icetGetIntegerv(ICET_RANK, &rank); - - if (rank == 0) { - printf("HEADER," - "num processes," - "multi-tile strategy," - "single-image strategy," - "tiles x," - "tiles y," - "width," - "height," - "transparent," - "interlacing," - "collection," - "max image split," - "frame," - "render time," - "buffer read time," - "buffer write time," - "compress time," - "blend time," - "draw time," - "composite time," - "collect time," - "bytes sent," - "frame time\n"); - } - if (g_do_magic_k_study) { IceTContext original_context = icetGetContext(); IceTInt magic_k; @@ -986,8 +1384,8 @@ int SimpleTimingRun() icetGetIntegerv(ICET_MAGIC_K, &magic_k); for (image_split = g_min_image_split; - image_split/magic_k < num_proc; - image_split *= magic_k) { + image_split <= num_proc; + image_split *= 2) { char image_split_string[64]; int retval; @@ -1023,6 +1421,349 @@ int SimpleTimingRun() } } +static IceTCommunicator MakeCommSubset(IceTInt size, IceTInt offset) +{ + IceTInt32 *ranks; + IceTInt rank_index; + IceTCommunicator old_comm; + IceTCommunicator new_comm; + + ranks = malloc(size*sizeof(IceTInt32)); + for (rank_index = 0; rank_index < size; rank_index++) { + ranks[rank_index] = rank_index + offset; + } + + old_comm = icetGetCommunicator(); + + new_comm = old_comm->Subset(old_comm, size, ranks); + + free(ranks); + + return new_comm; +} + +static int SimpleTimingDoScalingStudyFactor2() +{ + IceTInt size; + IceTInt rank; + IceTInt max_power_2; + IceTInt min_size = g_num_tiles_x*g_num_tiles_y; + IceTContext original_context = icetGetContext(); + int worst_result = TEST_PASSED; + + { + int result = SimpleTimingDoParameterStudies(); + if (result != TEST_PASSED) { return result; } + } + SimpleTimingCollectAndPrintLog(); + + icetGetIntegerv(ICET_NUM_PROCESSES, &size); + icetGetIntegerv(ICET_RANK, &rank); + max_power_2 = 1; + while (max_power_2 <= size) { max_power_2 *= 2; } + max_power_2 /= 2; + + if ((max_power_2 < size) && (max_power_2 >= min_size)) { + IceTCommunicator new_communicator = MakeCommSubset(max_power_2, 0); + if (rank < max_power_2) { + IceTContext new_context = icetCreateContext(new_communicator); + int result = SimpleTimingDoParameterStudies(); + if (result != TEST_PASSED) { worst_result = result; } + icetSetContext(original_context); + icetDestroyContext(new_context); + new_communicator->Destroy(new_communicator); + } + } + + { + IceTInt power_2 = max_power_2/2; + IceTInt offset = 0; + IceTBoolean has_group = ICET_FALSE; + IceTCommunicator new_comm; + while (power_2 >= min_size) { + IceTCommunicator try_comm = MakeCommSubset(power_2, offset); + if ((rank >= offset) && (rank < offset+power_2)) { + has_group = ICET_TRUE; + new_comm = try_comm; + } + offset += power_2; + power_2 /= 2; + } + if (has_group) { + IceTContext new_context; + int result; + new_context = icetCreateContext(new_comm); + new_comm->Destroy(new_comm); + + result = SimpleTimingDoParameterStudies(); + if (result != TEST_PASSED) { worst_result = result; } + + icetSetContext(original_context); + icetDestroyContext(new_context); + } + } + + return worst_result; +} + +static int SimpleTimingDoScalingStudyFactor2_3() +{ + IceTInt size; + IceTInt rank; + IceTInt max_power_3; + IceTInt min_size = g_num_tiles_x*g_num_tiles_y; + IceTContext original_context = icetGetContext(); + int worst_result = TEST_PASSED; + + worst_result = SimpleTimingDoScalingStudyFactor2(); + SimpleTimingCollectAndPrintLog(); + + icetGetIntegerv(ICET_NUM_PROCESSES, &size); + icetGetIntegerv(ICET_RANK, &rank); + max_power_3 = 1; + while (max_power_3 <= size) { max_power_3 *= 3; } + max_power_3 /= 3; + + if ((max_power_3*2 < size) && (max_power_3*2 >= min_size)) { + IceTCommunicator new_communicator = MakeCommSubset(max_power_3*2, 0); + if (rank < max_power_3*2) { + IceTContext new_context = icetCreateContext(new_communicator); + int result = SimpleTimingDoParameterStudies(); + if (result != TEST_PASSED) { worst_result = result; } + icetSetContext(original_context); + icetDestroyContext(new_context); + new_communicator->Destroy(new_communicator); + } + SimpleTimingCollectAndPrintLog(); + } + + { + // Start with a context with a power of three processes. + IceTCommunicator new_comm = MakeCommSubset(max_power_3, 0); + if (new_comm == ICET_COMM_NULL) { + // This rank is not participating in the rest of the tests. + return worst_result; + } + icetCreateContext(new_comm); + new_comm->Destroy(new_comm); + } + + if (max_power_3 < 3) { + // Corner case where we are running with to few processes to make + // any factors. The code below can break, so just bail. + icetDestroyContext(icetGetContext()); + icetSetContext(original_context); + return worst_result; + } + + if ((max_power_3 < size) && (max_power_3 >= min_size)) { + if (rank < max_power_3) { + int result = SimpleTimingDoParameterStudies(); + if (result != TEST_PASSED) { worst_result = result; } + } + SimpleTimingCollectAndPrintLog(); + } + + // This loop will run in log_3 iterations selecting any factors of 2 and 3 + // it finds. Let us say max_power_3 = 3^N. The iterations of the loop + // break up the processors is partitions of 1/3 and 2/3 as follows. + // (Iteration 0 was just done above.) + // + // Iteration 0: |---------------------------3^N--------------------------| + // Iteration 1: |------3^(N-1)-----|--------------2*3^(N-1)--------------| + // Iteration 2: |3^(N-2)|2*3^(N-2)-|-(removed)-|--------4*3^(N-2)--------| + // ... + // + // Note that some of the partitions are removed because they are repeates. + // In the example above, the removed partition is of size 2*3^(N-2), which + // is the same size of another partition in the tree. In general, when we + // break up a partition that is not a power of 3, we only generate the + // partition that is 2/3 because the 1/3 partition is created elsewhere. + // A partition that is exactly a power of 3 (no factors of 2) has both + // subpartitions created. + // + + while (ICET_TRUE) { + IceTInt last_size; + IceTInt last_rank; + IceTInt this_size; + IceTCommunicator comm_third; + IceTCommunicator comm_two_thirds; + IceTContext old_context = icetGetContext(); + int result; + + icetGetIntegerv(ICET_NUM_PROCESSES, &last_size); + icetGetIntegerv(ICET_RANK, &last_rank); + this_size = last_size/3; + + if (this_size%3 != 0) { + // Next smallest comms have no factors of 3. Must be only + // factors of two, and we have done that. + break; + } + + // By simple factoring, we can split the last communicator into one + // piece a third of its size and another peice 2/3 the size, and + // those combined will use all the processes. + comm_third = MakeCommSubset(this_size, 0); + comm_two_thirds = MakeCommSubset(2*this_size, this_size); + + icetDestroyContext(old_context); + if (last_rank < this_size) { + icetCreateContext(comm_third); + comm_third->Destroy(comm_third); + if (this_size%2 == 0) { + // If this size already has a factor of two, we can drop it. + // See the description above. + break; + } + } else { + icetCreateContext(comm_two_thirds); + comm_two_thirds->Destroy(comm_two_thirds); + this_size *= 2; + } + + if (this_size < min_size) { + // Group has gotten too small to handle these tiles. + break; + } + + result = SimpleTimingDoParameterStudies(); + if (result != TEST_PASSED) { worst_result = result; } + } + + icetDestroyContext(icetGetContext()); + icetSetContext(original_context); + + return worst_result; +} + +static int SimpleTimingDoScalingStudyRandom() +{ + IceTInt size; + IceTInt rank; + IceTInt min_size = g_num_tiles_x*g_num_tiles_y; + IceTContext original_context = icetGetContext(); + int worst_result = TEST_PASSED; + IceTInt trial; + IceTInt *pivots; + + icetGetIntegerv(ICET_NUM_PROCESSES, &size); + icetGetIntegerv(ICET_RANK, &rank); + + /* Choose pivot points to bifurcate processes. Do them all at once here + * so the psudorandom numbers do not interfear with those choosen during + * the rendering. */ + pivots = malloc(sizeof(IceTInt)*g_num_scaling_study_random); + srand(g_seed); + for (trial = 0; trial < g_num_scaling_study_random; trial++) { + pivots[trial] = rand()%size; + } + + for (trial = 0; trial < g_num_scaling_study_random; trial++) { + IceTCommunicator left_comm; + IceTCommunicator right_comm; + IceTInt left_size; + IceTInt right_size; + IceTInt local_size; + int result; + + /* Print out results from last run. */ + SimpleTimingCollectAndPrintLog(); + + left_size = pivots[trial]; + right_size = size-left_size; + + left_comm = MakeCommSubset(left_size, 0); + right_comm = MakeCommSubset(right_size, left_size); + + if (rank < left_size) { + icetCreateContext(left_comm); + left_comm->Destroy(left_comm); + local_size = left_size; + } else { + icetCreateContext(right_comm); + right_comm->Destroy(right_comm); + local_size = right_size; + } + + if (local_size > min_size) { + result = SimpleTimingDoParameterStudies(); + if (result != TEST_PASSED) { worst_result = result; } + } + + icetDestroyContext(icetGetContext()); + icetSetContext(original_context); + } + + free(pivots); + + return worst_result; +} + +static int SimpleTimingDoScalingStudies() +{ + int result; + if (g_do_scaling_study_factor_2_3) { + result = SimpleTimingDoScalingStudyFactor2_3(); + } else if (g_do_scaling_study_factor_2) { + result = SimpleTimingDoScalingStudyFactor2(); + } else { + result = SimpleTimingDoParameterStudies(); + } + + if (g_num_scaling_study_random > 0) { + int new_result = SimpleTimingDoScalingStudyRandom(); + if (new_result != TEST_PASSED) { + result = new_result; + } + } + + SimpleTimingCollectAndPrintLog(); + return result; +} + +int SimpleTimingRun() +{ + IceTInt rank; + + icetGetIntegerv(ICET_RANK, &rank); + + if (rank == 0) { + printf("HEADER," + "num processes," + "multi-tile strategy," + "single-image strategy," + "tiles x," + "tiles y," + "width," + "height," + "zoom," + "transparent," + "interlacing," + "collection," + "dense images," + "max image split," + "frame," + "render time," + "buffer read time," + "buffer write time," + "compress time," + "interlace time," + "blend time," + "draw time," + "composite time," + "collect time," + "bytes sent," + "frame time\n"); + } + + g_timing_log = NULL; + g_timing_log_size = 0; + + return SimpleTimingDoScalingStudies(); +} + int SimpleTiming(int argc, char * argv[]) { parse_arguments(argc, argv); diff --git tests/SparseImageCopy.c tests/SparseImageCopy.c index d4fff22..3837b6e 100644 --- tests/SparseImageCopy.c +++ tests/SparseImageCopy.c @@ -10,7 +10,7 @@ *****************************************************************************/ #include "test_codes.h" -#include "test-util.h" +#include "test_util.h" #include diff --git tests/init.c tests/init.c deleted file mode 100644 index 3399c78..0000000 --- tests/init.c +++ /dev/null @@ -1,434 +0,0 @@ -/* -*- c -*- *******************************************************/ -/* - * Copyright (C) 2003 Sandia Corporation - * Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, - * the U.S. Government retains certain rights in this software. - * - * This source code is released under the New BSD License. - */ - -#include "test-util.h" -#include "test_codes.h" - -#ifdef ICET_TESTS_USE_OPENGL -#include -#endif - -#include - -#ifndef __USE_POSIX -#define __USE_POSIX -#endif - -#include -#include -#include -#include - -#include -#include -#include - -#ifdef ICET_TESTS_USE_OPENGL -#ifndef __APPLE__ -#include -#include -#else -#include -#include -#endif -#endif - -#ifndef WIN32 -#include -#else -#include -#define dup(fildes) _dup(fildes) -#define dup2(fildes, fildes2) _dup2(fildes, fildes2) -#endif - -IceTEnum strategy_list[5]; -int STRATEGY_LIST_SIZE = 5; -/* int STRATEGY_LIST_SIZE = 1; */ - -IceTEnum single_image_strategy_list[4]; -int SINGLE_IMAGE_STRATEGY_LIST_SIZE = 4; -/* int SINGLE_IMAGE_STRATEGY_LIST_SIZE = 1; */ - -IceTSizeType SCREEN_WIDTH; -IceTSizeType SCREEN_HEIGHT; - -#ifdef ICET_TESTS_USE_OPENGL -static int windowId; - -static int (*test_function)(void); -#endif /* ICET_TESTS_USE_OPENGL */ - -#ifdef ICET_TESTS_USE_OPENGL -static void checkOglError(void) -{ - GLenum error = glGetError(); - -#define CASE_ERROR(ename) \ - case ename: printrank("## Current IceT error = " #ename "\n"); break; - - switch (error) { - CASE_ERROR(GL_NO_ERROR); - CASE_ERROR(GL_INVALID_ENUM); - CASE_ERROR(GL_INVALID_VALUE); - CASE_ERROR(GL_INVALID_OPERATION); - CASE_ERROR(GL_STACK_OVERFLOW); - CASE_ERROR(GL_STACK_UNDERFLOW); - CASE_ERROR(GL_OUT_OF_MEMORY); -#ifdef GL_TABLE_TOO_LARGE - CASE_ERROR(GL_TABLE_TOO_LARGE); -#endif - default: - printrank("## UNKNOWN OPENGL ERROR CODE!!!!!!\n"); - break; - } - -#undef CASE_ERROR -} -#endif /* ICET_TESTS_USE_OPENGL */ - -static void checkIceTError(void) -{ - IceTEnum error = icetGetError(); - -#define CASE_ERROR(ename) \ - case ename: printrank("## Current IceT error = " #ename "\n"); break; - - switch (error) { - CASE_ERROR(ICET_NO_ERROR); - CASE_ERROR(ICET_SANITY_CHECK_FAIL); - CASE_ERROR(ICET_INVALID_ENUM); - CASE_ERROR(ICET_BAD_CAST); - CASE_ERROR(ICET_OUT_OF_MEMORY); - CASE_ERROR(ICET_INVALID_OPERATION); - CASE_ERROR(ICET_INVALID_VALUE); - default: - printrank("## UNKNOWN ICET ERROR CODE!!!!!\n"); - break; - } - -#undef CASE_ERROR -} - -/* Just in case I need to actually print stuff out to the screen in the - future. */ -static FILE *realstdout; -#if 0 -static void realprintf(const char *fmt, ...) -{ - va_list ap; - - if (realstdout != NULL) { - va_start(ap, fmt); - vfprintf(realstdout, fmt, ap); - va_end(ap); - fflush(realstdout); - } -} -#endif - -void printstat(const char *fmt, ...) -{ - va_list ap; - IceTInt rank; - - icetGetIntegerv(ICET_RANK, &rank); - - if ((rank == 0) || (realstdout == NULL)) { - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - fflush(stdout); - } -} - -void printrank(const char *fmt, ...) -{ - va_list ap; - IceTInt rank; - - icetGetIntegerv(ICET_RANK, &rank); - - printf("%d> ", rank); - va_start(ap, fmt); - vprintf(fmt, ap); - va_end(ap); - fflush(stdout); -} - -static IceTContext context; - -static void usage(char **argv) -{ - printf("\nUSAGE: %s [options] [-R] testname [testargs]\n", argv[0]); - printf("\nWhere options are:\n"); - printf(" -width Width of window (default n=1024)\n"); - printf(" -height Height of window (default n=768).\n"); - printf(" -display \n"); - printf(" X server each node contacts. Default display=localhost:0\n"); - printf(" -logdebug Add debugging statements. Provides more information, but\n"); - printf(" makes identifying errors, warnings, and statuses harder\n"); - printf(" -redirect Redirect standard output to log.????, where ???? is the rank\n"); - printf(" -- Parse no more arguments.\n"); - printf(" -h, -help This help message.\n"); -} - -void initialize_test(int *argcp, char ***argvp, IceTCommunicator comm) -{ - int arg; - int argc = *argcp; - char **argv = *argvp; - int width = 1024; - int height = 768; - IceTBitField diag_level = ICET_DIAG_ALL_NODES | ICET_DIAG_WARNINGS; - int redirect = 0; - int rank, num_proc; - - rank = (*comm->Comm_rank)(comm); - num_proc = (*comm->Comm_size)(comm); - - /* This is convenient code to attach a debugger to a particular process at the - start of a test. */ - /* if (rank == 0) { */ - /* int i = 0; */ - /* printf("Waiting in process %d\n", getpid()); */ - /* while (i == 0) sleep(1); */ - /* } */ - -#ifdef ICET_TESTS_USE_OPENGL - /* Let Glut have first pass at the arguments to grab any that it can use. */ - glutInit(argcp, *argvp); -#endif - - /* Parse my arguments. */ - for (arg = 1; arg < argc; arg++) { - if (strcmp(argv[arg], "-width") == 0) { - width = atoi(argv[++arg]); - } else if (strcmp(argv[arg], "-height") == 0) { - height = atoi(argv[++arg]); - } else if (strcmp(argv[arg], "-logdebug") == 0) { - diag_level = ICET_DIAG_FULL; - } else if (strcmp(argv[arg], "-redirect") == 0) { - redirect = 1; - } else if ( (strcmp(argv[arg], "-h") == 0) - || (strcmp(argv[arg], "-help") == 0) ) { - usage(argv); - exit(0); - } else if ( (strcmp(argv[arg], "-R") == 0) - || (strncmp(argv[arg], "-", 1) != 0) ) { - break; - } else if (strcmp(argv[arg], "--") == 0) { - arg++; - break; - } else { - printf("Unknown options `%s'. Try -h for help.\n", argv[arg]); - exit(1); - } - } - - /* Fix arguments for next bout of parsing. */ - *argcp = 1; - for ( ; arg < argc; arg++, (*argcp)++) { - argv[*argcp] = argv[arg]; - } - argc = *argcp; - - /* Make sure selected options are consistent. */ - if ((num_proc > 1) && (argc < 2)) { - printf("You must select a test on the command line when using more than one process.\n"); - printf("Try -h for help.\n"); - exit(1); - } - if (redirect && (argc < 2)) { - printf("You must select a test on the command line when redirecting the output.\n"); - printf("Try -h for help.\n"); - exit(1); - } - -#ifdef ICET_TESTS_USE_OPENGL - /* Create a renderable window. */ - glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA); - glutInitWindowPosition(0, 0); - glutInitWindowSize(width, height); - - { - char title[256]; - sprintf(title, "IceT Test %d of %d", rank, num_proc); - windowId = glutCreateWindow(title); - } -#endif /* ICET_TESTS_USE_OPENGL */ - - SCREEN_WIDTH = width; - SCREEN_HEIGHT = height; - - /* Create an IceT context. */ - context = icetCreateContext(comm); - icetDiagnostics(diag_level); -#ifdef ICET_TESTS_USE_OPENGL - icetGLInitialize(); -#endif - - /* Redirect standard output on demand. */ - if (redirect) { - char filename[64]; - int outfd; - if (rank == 0) { - realstdout = fdopen(dup(1), "wt"); - } else { - realstdout = NULL; - } - sprintf(filename, "log.%04d", rank); - outfd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0644); - if (outfd < 0) { - printf("Could not open %s for writing.\n", filename); - exit(1); - } - dup2(outfd, 1); - } else { - realstdout = stdout; - } - - strategy_list[0] = ICET_STRATEGY_DIRECT; - strategy_list[1] = ICET_STRATEGY_SEQUENTIAL; - strategy_list[2] = ICET_STRATEGY_SPLIT; - strategy_list[3] = ICET_STRATEGY_REDUCE; - strategy_list[4] = ICET_STRATEGY_VTREE; - - single_image_strategy_list[0] = ICET_SINGLE_IMAGE_STRATEGY_AUTOMATIC; - single_image_strategy_list[1] = ICET_SINGLE_IMAGE_STRATEGY_BSWAP; - single_image_strategy_list[2] = ICET_SINGLE_IMAGE_STRATEGY_RADIXK; - single_image_strategy_list[3] = ICET_SINGLE_IMAGE_STRATEGY_TREE; -} - -IceTBoolean strategy_uses_single_image_strategy(IceTEnum strategy) -{ - switch (strategy) { - case ICET_STRATEGY_DIRECT: return ICET_FALSE; - case ICET_STRATEGY_SEQUENTIAL: return ICET_TRUE; - case ICET_STRATEGY_SPLIT: return ICET_FALSE; - case ICET_STRATEGY_REDUCE: return ICET_TRUE; - case ICET_STRATEGY_VTREE: return ICET_FALSE; - default: - printrank("ERROR: unknown strategy type."); - return ICET_TRUE; - } -} - -#ifdef ICET_TESTS_USE_OPENGL - -static void no_op() -{ -} - -static void glut_draw() -{ - int result; - - glEnable(GL_DEPTH_TEST); - glViewport(0, 0, (GLsizei)SCREEN_WIDTH, (GLsizei)SCREEN_HEIGHT); - glClear(GL_COLOR_BUFFER_BIT); - swap_buffers(); - - result = test_function(); - - finalize_test(result); - - exit(result); -} - -int run_test(int (*tf)(void)) -{ - /* Record the test function so we can run it in the Glut draw callback. */ - test_function = tf; - - glutDisplayFunc(no_op); - glutIdleFunc(glut_draw); - - /* Glut will reliably create the OpenGL context only after the main loop is - * started. This will create the window and then call our glut_draw function - * to populate it. It will never return, which is why we call exit in - * glut_draw. */ - glutMainLoop(); - - /* We do not expect to be here. Raise an alert to signal that the tests are - * not running as expected. */ - return TEST_NOT_PASSED; -} - -#else /* ICET_TESTS_USE_OPENGL */ - -int run_test(int (*tf)(void)) -{ - int result; - - result = tf(); - - finalize_test(result); - - return result; -} - -#endif /* ICET_TESTS_USE_OPENGL */ - -#ifdef ICET_TESTS_USE_OPENGL -void swap_buffers(void) -{ - glutSwapBuffers(); -} -#endif - -#define TEST_RESULT_TAG 3492 -extern void finalize_communication(void); -void finalize_test(IceTInt result) -{ - IceTInt rank; - IceTInt num_proc; - -#ifdef ICET_TESTS_USE_OPENGL - checkOglError(); -#endif - checkIceTError(); - - icetGetIntegerv(ICET_RANK, &rank); - icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc); - - if (rank == 0) { - IceTInt p_id; - for (p_id = 1; p_id < num_proc; p_id++) { - IceTInt remote_result; - icetCommRecv(&remote_result, 1, ICET_INT, p_id, TEST_RESULT_TAG); - if (remote_result != TEST_PASSED) { - result = remote_result; - } - } - - switch (result) { - case TEST_PASSED: - printf("***Test Passed***\n"); - break; - case TEST_NOT_RUN: - printf("***TEST NOT RUN***\n"); - break; - case TEST_NOT_PASSED: - printf("***TEST NOT PASSED***\n"); - break; - case TEST_FAILED: - default: - printf("***TEST FAILED***\n"); - break; - } - } else { - icetCommSend(&result, 1, ICET_INT, 0, TEST_RESULT_TAG); - } - - icetDestroyContext(context); - finalize_communication(); -#ifdef ICET_TESTS_USE_OPENGL - glutDestroyWindow(windowId); -#endif -} diff --git tests/mpi_comm.h tests/mpi_comm.h deleted file mode 100644 index cedc661..0000000 --- tests/mpi_comm.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -*- c -*- *******************************************************/ -/* - * Copyright (C) 2003 Sandia Corporation - * Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, - * the U.S. Government retains certain rights in this software. - * - * This source code is released under the New BSD License. - */ - -#ifndef _MPI_COMM_H_ -#define _MPI_COMM_H_ - -#include "test-util.h" -#include - -void init_mpi_comm(int *argcp, char ***argvp) -{ - IceTCommunicator comm; - - MPI_Init(argcp, argvp); - comm = icetCreateMPICommunicator(MPI_COMM_WORLD); - - initialize_test(argcp, argvp, comm); - - icetDestroyMPICommunicator(comm); -} - -void finalize_communication(void) -{ - MPI_Finalize(); -} - -#endif /*_MPI_COMM_H_*/ diff --git tests/ppm.c tests/ppm.c index b956457..bcab5c4 100644 --- tests/ppm.c +++ tests/ppm.c @@ -7,7 +7,7 @@ * This source code is released under the New BSD License. */ -#include "test-util.h" +#include "test_util.h" #include #include diff --git tests/test-config.h.in tests/test-config.h.in deleted file mode 100644 index 3cc72ac..0000000 --- tests/test-config.h.in +++ /dev/null @@ -1,10 +0,0 @@ -/* -*- c -*- *******************************************************/ -/* - * Copyright (C) 2010 Sandia Corporation - * Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, - * the U.S. Government retains certain rights in this software. - * - * This source code is released under the New BSD License. - */ - -#cmakedefine ICET_TESTS_USE_OPENGL diff --git tests/test-util.h tests/test-util.h deleted file mode 100644 index 0eaede9..0000000 --- tests/test-util.h +++ /dev/null @@ -1,60 +0,0 @@ -/* -*- c -*- *******************************************************/ -/* - * Copyright (C) 2003 Sandia Corporation - * Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, - * the U.S. Government retains certain rights in this software. - * - * This source code is released under the New BSD License. - */ - -#ifndef _TEST_UTIL_H_ -#define _TEST_UTIL_H_ - -#include "test-config.h" - -#ifdef __cplusplus -extern "C" { -#endif -#if 0 -} -#endif - -#include - -extern IceTEnum strategy_list[]; -extern int STRATEGY_LIST_SIZE; - -extern IceTEnum single_image_strategy_list[]; -extern int SINGLE_IMAGE_STRATEGY_LIST_SIZE; - -extern IceTSizeType SCREEN_WIDTH; -extern IceTSizeType SCREEN_HEIGHT; - -void initialize_test(int *argcp, char ***argvp, IceTCommunicator comm); - -int run_test(int (*test_function)(void)); - -/* Used like printf but prints status only on process 0 or to independent - logs. */ -void printstat(const char *fmt, ...); - -/* Like printf but adds the rank of the local process. */ -void printrank(const char *fmt, ...); - -#ifdef ICET_TESTS_USE_OPENGL -void swap_buffers(void); -#endif - -void finalize_test(IceTInt result); - -void write_ppm(const char *filename, - const IceTUByte *image, - int width, int height); - -IceTBoolean strategy_uses_single_image_strategy(IceTEnum strategy); - -#ifdef __cplusplus -} -#endif - -#endif /*_TEST_UTIL_H_*/ diff --git tests/test_common.c tests/test_common.c new file mode 100644 index 0000000..03eeba5 --- /dev/null +++ tests/test_common.c @@ -0,0 +1,317 @@ +/* -*- c -*- *******************************************************/ +/* + * Copyright (C) 2015 Sandia Corporation + * Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, + * the U.S. Government retains certain rights in this software. + * + * This source code is released under the New BSD License. + */ + +#include "test_util.h" +#include "test_codes.h" + +#include + +#ifndef __USE_POSIX +#define __USE_POSIX +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#ifndef WIN32 +#include +#else +#include +#define dup(fildes) _dup(fildes) +#define dup2(fildes, fildes2) _dup2(fildes, fildes2) +#endif + +IceTEnum strategy_list[5]; +int STRATEGY_LIST_SIZE = 5; +/* int STRATEGY_LIST_SIZE = 1; */ + +IceTEnum single_image_strategy_list[6]; +int SINGLE_IMAGE_STRATEGY_LIST_SIZE = 6; +/* int SINGLE_IMAGE_STRATEGY_LIST_SIZE = 1; */ + +IceTSizeType SCREEN_WIDTH; +IceTSizeType SCREEN_HEIGHT; + +static void checkIceTError(void) +{ + IceTEnum error = icetGetError(); + +#define CASE_ERROR(ename) \ + case ename: printrank("## Current IceT error = " #ename "\n"); break; + + switch (error) { + case ICET_NO_ERROR: break; + CASE_ERROR(ICET_SANITY_CHECK_FAIL); + CASE_ERROR(ICET_INVALID_ENUM); + CASE_ERROR(ICET_BAD_CAST); + CASE_ERROR(ICET_OUT_OF_MEMORY); + CASE_ERROR(ICET_INVALID_OPERATION); + CASE_ERROR(ICET_INVALID_VALUE); + default: + printrank("## UNKNOWN ICET ERROR CODE!!!!!\n"); + break; + } + +#undef CASE_ERROR +} + +/* Just in case I need to actually print stuff out to the screen in the + future. */ +static FILE *realstdout; +#if 0 +static void realprintf(const char *fmt, ...) +{ + va_list ap; + + if (realstdout != NULL) { + va_start(ap, fmt); + vfprintf(realstdout, fmt, ap); + va_end(ap); + fflush(realstdout); + } +} +#endif + +void printstat(const char *fmt, ...) +{ + va_list ap; + IceTInt rank; + + icetGetIntegerv(ICET_RANK, &rank); + + if ((rank == 0) || (realstdout == NULL)) { + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + fflush(stdout); + } +} + +void printrank(const char *fmt, ...) +{ + va_list ap; + IceTInt rank; + + icetGetIntegerv(ICET_RANK, &rank); + + printf("%d> ", rank); + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + fflush(stdout); +} + +static IceTContext context; + +static void usage(char **argv) +{ + printf("\nUSAGE: %s [options] [-R] testname [testargs]\n", argv[0]); + printf("\nWhere options are:\n"); + printf(" -width Width of window (default n=1024)\n"); + printf(" -height Height of window (default n=768).\n"); + printf(" -display \n"); + printf(" X server each node contacts. Default display=localhost:0\n"); + printf(" -logdebug Add debugging statements. Provides more information, but\n"); + printf(" makes identifying errors, warnings, and statuses harder\n"); + printf(" -redirect Redirect standard output to log.????, where ???? is the rank\n"); + printf(" -- Parse no more arguments.\n"); + printf(" -h, -help This help message.\n"); +} + +extern void initialize_render_window(int width, int height); +void initialize_test(int *argcp, char ***argvp, IceTCommunicator comm) +{ + int arg; + int argc = *argcp; + char **argv = *argvp; + int width = 1024; + int height = 768; + IceTBitField diag_level = ICET_DIAG_ALL_NODES | ICET_DIAG_WARNINGS; + int redirect = 0; + int rank, num_proc; + + rank = (*comm->Comm_rank)(comm); + num_proc = (*comm->Comm_size)(comm); + + /* This is convenience code to attach a debugger to a particular process at + the start of a test. */ +#if 0 + if (rank == 0) { + int i = 0; + printf("Waiting in process %d\n", getpid()); + while (i == 0) sleep(1); + } +#endif + + /* Parse my arguments. */ + for (arg = 1; arg < argc; arg++) { + if (strcmp(argv[arg], "-width") == 0) { + width = atoi(argv[++arg]); + } else if (strcmp(argv[arg], "-height") == 0) { + height = atoi(argv[++arg]); + } else if (strcmp(argv[arg], "-logdebug") == 0) { + diag_level = ICET_DIAG_FULL; + } else if (strcmp(argv[arg], "-redirect") == 0) { + redirect = 1; + } else if ( (strcmp(argv[arg], "-h") == 0) + || (strcmp(argv[arg], "-help") == 0) ) { + usage(argv); + exit(0); + } else if ( (strcmp(argv[arg], "-R") == 0) + || (strncmp(argv[arg], "-", 1) != 0) ) { + break; + } else if (strcmp(argv[arg], "--") == 0) { + arg++; + break; + } else { + printf("Unknown options `%s'. Try -h for help.\n", argv[arg]); + exit(1); + } + } + + /* Fix arguments for next bout of parsing. */ + *argcp = 1; + for ( ; arg < argc; arg++, (*argcp)++) { + argv[*argcp] = argv[arg]; + } + argc = *argcp; + + /* Make sure selected options are consistent. */ + if ((num_proc > 1) && (argc < 2)) { + printf("You must select a test on the command line when using more than one process.\n"); + printf("Try -h for help.\n"); + exit(1); + } + if (redirect && (argc < 2)) { + printf("You must select a test on the command line when redirecting the output.\n"); + printf("Try -h for help.\n"); + exit(1); + } + + SCREEN_WIDTH = width; + SCREEN_HEIGHT = height; + + /* Create an IceT context. */ + context = icetCreateContext(comm); + icetDiagnostics(diag_level); + + initialize_render_window(width, height); + + /* Redirect standard output on demand. */ + if (redirect) { + char filename[64]; + int outfd; + if (rank == 0) { + realstdout = fdopen(dup(1), "wt"); + } else { + realstdout = NULL; + } + sprintf(filename, "log.%04d", rank); + outfd = open(filename, O_WRONLY | O_CREAT | O_APPEND, 0644); + if (outfd < 0) { + printf("Could not open %s for writing.\n", filename); + exit(1); + } + dup2(outfd, 1); + } else { + realstdout = stdout; + } + + strategy_list[0] = ICET_STRATEGY_DIRECT; + strategy_list[1] = ICET_STRATEGY_SEQUENTIAL; + strategy_list[2] = ICET_STRATEGY_SPLIT; + strategy_list[3] = ICET_STRATEGY_REDUCE; + strategy_list[4] = ICET_STRATEGY_VTREE; + + single_image_strategy_list[0] = ICET_SINGLE_IMAGE_STRATEGY_AUTOMATIC; + single_image_strategy_list[1] = ICET_SINGLE_IMAGE_STRATEGY_BSWAP; + single_image_strategy_list[2] = ICET_SINGLE_IMAGE_STRATEGY_RADIXK; + single_image_strategy_list[3] = ICET_SINGLE_IMAGE_STRATEGY_RADIXKR; + single_image_strategy_list[4] = ICET_SINGLE_IMAGE_STRATEGY_TREE; + single_image_strategy_list[5] = ICET_SINGLE_IMAGE_STRATEGY_BSWAP_FOLDING; +} + +IceTBoolean strategy_uses_single_image_strategy(IceTEnum strategy) +{ + switch (strategy) { + case ICET_STRATEGY_DIRECT: return ICET_FALSE; + case ICET_STRATEGY_SEQUENTIAL: return ICET_TRUE; + case ICET_STRATEGY_SPLIT: return ICET_FALSE; + case ICET_STRATEGY_REDUCE: return ICET_TRUE; + case ICET_STRATEGY_VTREE: return ICET_FALSE; + default: + printrank("ERROR: unknown strategy type."); + return ICET_TRUE; + } +} + +int run_test_base(int (*test_function)(void)) +{ + int result; + + result = test_function(); + + finalize_test(result); + + return result; +} + +#define TEST_RESULT_TAG 3492 +extern void finalize_rendering(void); +extern void finalize_communication(void); +void finalize_test(IceTInt result) +{ + IceTInt rank; + IceTInt num_proc; + + finalize_rendering(); + + checkIceTError(); + + icetGetIntegerv(ICET_RANK, &rank); + icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc); + + if (rank == 0) { + IceTInt p_id; + for (p_id = 1; p_id < num_proc; p_id++) { + IceTInt remote_result; + icetCommRecv(&remote_result, 1, ICET_INT, p_id, TEST_RESULT_TAG); + if (remote_result != TEST_PASSED) { + result = remote_result; + } + } + + switch (result) { + case TEST_PASSED: + printf("***Test Passed***\n"); + break; + case TEST_NOT_RUN: + printf("***TEST NOT RUN***\n"); + break; + case TEST_NOT_PASSED: + printf("***TEST NOT PASSED***\n"); + break; + case TEST_FAILED: + default: + printf("***TEST FAILED***\n"); + break; + } + } else { + icetCommSend(&result, 1, ICET_INT, 0, TEST_RESULT_TAG); + } + + icetDestroyContext(context); + finalize_communication(); +} diff --git tests/test_config.h.in tests/test_config.h.in new file mode 100644 index 0000000..6f7b6f5 --- /dev/null +++ tests/test_config.h.in @@ -0,0 +1,14 @@ +/* -*- c -*- *******************************************************/ +/* + * Copyright (C) 2010 Sandia Corporation + * Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, + * the U.S. Government retains certain rights in this software. + * + * This source code is released under the New BSD License. + */ + +#cmakedefine ICET_TESTS_USE_OPENGL + +#cmakedefine ICET_TESTS_USE_GLUT + +#cmakedefine ICET_TESTS_USE_GLFW diff --git tests/test_mpi.h tests/test_mpi.h new file mode 100644 index 0000000..cda6e45 --- /dev/null +++ tests/test_mpi.h @@ -0,0 +1,49 @@ +/* -*- c -*- *******************************************************/ +/* + * Copyright (C) 2003 Sandia Corporation + * Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, + * the U.S. Government retains certain rights in this software. + * + * This source code is released under the New BSD License. + */ + +#ifndef _TEST_MPI_H_ +#define _TEST_MPI_H_ + +#include "test_util.h" +#include + +extern int run_test_base(int (*test_function)(void)); + +void init_mpi(int *argcp, char ***argvp) +{ + IceTCommunicator comm; + + MPI_Init(argcp, argvp); + comm = icetCreateMPICommunicator(MPI_COMM_WORLD); + + initialize_test(argcp, argvp, comm); + + icetDestroyMPICommunicator(comm); +} + +void finalize_communication(void) +{ + MPI_Finalize(); +} + +#ifndef ICET_NO_MPI_RENDERING_FUNCTIONS +int run_test(int (*test_function)()) +{ + return run_test_base(test_function); +} +void initialize_render_window(int width, int height) +{ + (void)width; + (void)height; +} +void swap_buffers() { } +void finalize_rendering() { } +#endif /* !ICET_NO_MPI_RENDERING_FUNCTIONS */ + +#endif /*_TEST_MPI_H_*/ diff --git tests/test_mpi_opengl.h tests/test_mpi_opengl.h new file mode 100644 index 0000000..fcda24d --- /dev/null +++ tests/test_mpi_opengl.h @@ -0,0 +1,212 @@ +/* -*- c -*- *******************************************************/ +/* + * Copyright (C) 2015 Sandia Corporation + * Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, + * the U.S. Government retains certain rights in this software. + * + * This source code is released under the New BSD License. + */ + +#ifndef _TEST_MPI_OPENGL_H +#define _TEST_MPI_OPENGL_H + +#define ICET_NO_MPI_RENDERING_FUNCTIONS +#include "test_mpi.h" + +#include "test_config.h" + +#include + +#ifdef ICET_TESTS_USE_GLUT +#ifndef __APPLE__ +#include +#else +#include +#endif +#endif + +#ifdef ICET_TESTS_USE_GLFW +#include +#endif + +#ifdef ICET_TESTS_USE_GLUT +static int windowId; +#endif + +#ifdef ICET_TESTS_USE_GLFW +static GLFWwindow *window; +#endif + +#include "test_codes.h" + +static void checkOglError(void) +{ + GLenum error = glGetError(); + +#define CASE_ERROR(ename) \ + case ename: printrank("## Current IceT error = " #ename "\n"); break; + + switch (error) { + case GL_NO_ERROR: break; + CASE_ERROR(GL_INVALID_ENUM); + CASE_ERROR(GL_INVALID_VALUE); + CASE_ERROR(GL_INVALID_OPERATION); + CASE_ERROR(GL_STACK_OVERFLOW); + CASE_ERROR(GL_STACK_UNDERFLOW); + CASE_ERROR(GL_OUT_OF_MEMORY); +#ifdef GL_TABLE_TOO_LARGE + CASE_ERROR(GL_TABLE_TOO_LARGE); +#endif + default: + printrank("## UNKNOWN OPENGL ERROR CODE!!!!!!\n"); + break; + } + +#undef CASE_ERROR +} + +void init_mpi_opengl(int *argcp, char ***argvp) +{ +#ifdef ICET_TESTS_USE_GLUT + /* Let Glut have first pass at the arguments to grab any that it can use. */ + glutInit(argcp, *argvp); +#endif + +#ifdef ICET_TESTS_USE_GLFW + if (!glfwInit()) { exit(1); } +#endif + + init_mpi(argcp, argvp); +} + +#if defined(ICET_TESTS_USE_GLUT) +static int (*g_test_function)(void); + +static void no_op() +{ +} + +static void glut_draw() +{ + int result; + + glEnable(GL_DEPTH_TEST); + glViewport(0, 0, (GLsizei)SCREEN_WIDTH, (GLsizei)SCREEN_HEIGHT); + glClear(GL_COLOR_BUFFER_BIT); + swap_buffers(); + + result = run_test_base(g_test_function); + + glutDestroyWindow(windowId); + + exit(result); +} + +int run_test(int (*test_function)(void)) +{ + /* Record the test function so we can run it in the Glut draw callback. */ + g_test_function = test_function; + + glutDisplayFunc(no_op); + glutIdleFunc(glut_draw); + + /* Glut will reliably create the OpenGL context only after the main loop is + * started. This will create the window and then call our glut_draw function + * to populate it. It will never return, which is why we call exit in + * glut_draw. */ + glutMainLoop(); + + /* We do not expect to be here. Raise an alert to signal that the tests are + * not running as expected. */ + return TEST_NOT_PASSED; +} + +void initialize_render_window(int width, int height) +{ + IceTInt rank, num_proc; + + icetGetIntegerv(ICET_RANK, &rank); + icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc); + + /* Create a renderable window. */ + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH | GLUT_ALPHA); + glutInitWindowPosition(0, 0); + glutInitWindowSize(width, height); + + { + char title[256]; + sprintf(title, "IceT Test %d of %d", rank, num_proc); + windowId = glutCreateWindow(title); + } + + icetGLInitialize(); +} + +void swap_buffers(void) +{ + glutSwapBuffers(); +} + +#elif defined(ICET_TESTS_USE_GLFW) + +int run_test(int (*test_function)()) +{ + int result; + + glEnable(GL_DEPTH_TEST); + glViewport(0, 0, (GLsizei)SCREEN_WIDTH, (GLsizei)SCREEN_HEIGHT); + glClear(GL_COLOR_BUFFER_BIT); + swap_buffers(); + + result = run_test_base(test_function); + + glfwDestroyWindow(window); + glfwTerminate(); + + return result; +} + +void initialize_render_window(int width, int height) +{ + IceTInt rank, num_proc; + + icetGetIntegerv(ICET_RANK, &rank); + icetGetIntegerv(ICET_NUM_PROCESSES, &num_proc); + + /* Create a renderable window. */ + glfwWindowHint(GLFW_RED_BITS, 8); + glfwWindowHint(GLFW_GREEN_BITS, 8); + glfwWindowHint(GLFW_BLUE_BITS, 8); + glfwWindowHint(GLFW_ALPHA_BITS, 8); + glfwWindowHint(GLFW_DEPTH_BITS, 24); + glfwWindowHint(GLFW_SAMPLES, 0); + + { + char title[256]; + sprintf(title, "IceT Test %d of %d", rank, num_proc); + window = glfwCreateWindow(width, height, title, NULL, NULL); + } + + glfwMakeContextCurrent(window); + + icetGLInitialize(); +} + +void swap_buffers(void) +{ + glfwSwapBuffers(window); + glfwPollEvents(); +} + +#else + +#error "ICET_TESTS_USE_OPENGL defined but no window library is defined." + +#endif + +void finalize_rendering() +{ + checkOglError(); +} + +#endif /* _TEST_MPI_OPENGL_H */ diff --git tests/test_util.h tests/test_util.h new file mode 100644 index 0000000..6428727 --- /dev/null +++ tests/test_util.h @@ -0,0 +1,58 @@ +/* -*- c -*- *******************************************************/ +/* + * Copyright (C) 2003 Sandia Corporation + * Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, + * the U.S. Government retains certain rights in this software. + * + * This source code is released under the New BSD License. + */ + +#ifndef _TEST_UTIL_H_ +#define _TEST_UTIL_H_ + +#include "test_config.h" + +#ifdef __cplusplus +extern "C" { +#endif +#if 0 +} +#endif + +#include + +extern IceTEnum strategy_list[]; +extern int STRATEGY_LIST_SIZE; + +extern IceTEnum single_image_strategy_list[]; +extern int SINGLE_IMAGE_STRATEGY_LIST_SIZE; + +extern IceTSizeType SCREEN_WIDTH; +extern IceTSizeType SCREEN_HEIGHT; + +void initialize_test(int *argcp, char ***argvp, IceTCommunicator comm); + +int run_test(int (*test_function)(void)); + +/* Used like printf but prints status only on process 0 or to independent + logs. */ +void printstat(const char *fmt, ...); + +/* Like printf but adds the rank of the local process. */ +void printrank(const char *fmt, ...); + +void swap_buffers(void); + +void finalize_test(IceTInt result); + +void write_ppm(const char *filename, + const IceTUByte *image, + int width, int height); + +IceTBoolean strategy_uses_single_image_strategy(IceTEnum strategy); + +#ifdef __cplusplus +} +#endif + +#endif /*_TEST_UTIL_H_*/