From 4ae0c873e0ce24209ad00324dfc7fea94e22008d Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Mon, 25 Mar 2013 12:35:39 -0500 Subject: [svn-r23446] HDFFV-8344, HDFFV-8346: merge from 1.8 branch --- release_docs/RELEASE.txt | 4 ++++ tools/lib/h5tools_dump.c | 16 +++++++++++++--- tools/testfiles/tfletcher32.ddl | 2 +- tools/testfiles/tshuffle.ddl | 2 +- tools/testfiles/tuserfilter.ddl | 4 ++-- 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/release_docs/RELEASE.txt b/release_docs/RELEASE.txt index 8a54b21..dbd3b75 100644 --- a/release_docs/RELEASE.txt +++ b/release_docs/RELEASE.txt @@ -276,6 +276,10 @@ New Features Tools: ------ + - h5dump: Fixed displaying comporession ratio for unknown or user-defined + filters. HDFFV-8344 (XCAO 2013/03/19) + - h5dump: Changed UNKNOWN_FILTER to USER_DEFINED_FILTER for user defined filter. + HDFFV-8346 (XCAO 2013/03/19) - h5dump: Added capability for "-a" option to show attributes containing "/" by using an escape character. For example, for a dataset "/dset" containing attribute "speed(m/h)", use "h5dump -a "/dset/speed(\/h)" diff --git a/tools/lib/h5tools_dump.c b/tools/lib/h5tools_dump.c index dbb5f98..d6cd0a0 100644 --- a/tools/lib/h5tools_dump.c +++ b/tools/lib/h5tools_dump.c @@ -2958,11 +2958,14 @@ h5tools_dump_dcpl(FILE *stream, const h5tool_format_t *info, int ndims = H5Sget_simple_extent_dims(sid, dims, NULL); /* only print the compression ratio for these filters */ - for(i = 0; i < nfilters; i++) { + for(i = 0; i < nfilters && !ok; i++) { cd_nelmts = NELMTS(cd_values); filtn = H5Pget_filter2(dcpl_id, (unsigned)i, &filt_flags, &cd_nelmts, cd_values, sizeof(f_name), f_name, NULL); - + ok = (filtn>=0); + + /* this following code will not show compression ratio for + user defined filter. For example, see HDFFV-8344 --xcao@hdfgroup.org switch(filtn) { case H5Z_FILTER_DEFLATE: case H5Z_FILTER_SZIP: @@ -2971,6 +2974,7 @@ h5tools_dump_dcpl(FILE *stream, const h5tool_format_t *info, ok = 1; break; } + */ } if(ndims && ok) { @@ -3148,6 +3152,9 @@ h5tools_dump_dcpl(FILE *stream, const h5tool_format_t *info, cd_nelmts = NELMTS(cd_values); filtn = H5Pget_filter2(dcpl_id, (unsigned)i, &filt_flags, &cd_nelmts, cd_values, sizeof(f_name), f_name, NULL); + + if (filtn<0) + continue; /* nothing to print for invalid filter */ ctx->need_prefix = TRUE; h5tools_simple_prefix(stream, info, ctx, curr_pos, 0); @@ -3241,10 +3248,13 @@ h5tools_dump_dcpl(FILE *stream, const h5tool_format_t *info, h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, ncols, 0, 0); break; default: + /* filter do not have to be avaiable for showing registered filter info. + see HDFFV-8346 for details. --xcao@hdfgroup.org if(H5Zfilter_avail(filtn)) h5tools_str_append(&buffer, "%s %s", "USER_REGISTERED_FILTER", BEGIN); else - h5tools_str_append(&buffer, "%s %s", "UNKNOWN_FILTER", BEGIN); + */ + h5tools_str_append(&buffer, "%s %s", "USER_DEFINED_FILTER", BEGIN); h5tools_render_element(stream, info, ctx, &buffer, &curr_pos, ncols, 0, 0); ctx->indent_level++; diff --git a/tools/testfiles/tfletcher32.ddl b/tools/testfiles/tfletcher32.ddl index 072ef23..c341ded 100644 --- a/tools/testfiles/tfletcher32.ddl +++ b/tools/testfiles/tfletcher32.ddl @@ -4,7 +4,7 @@ DATASET "fletcher32" { DATASPACE SIMPLE { ( 20, 10 ) / ( 20, 10 ) } STORAGE_LAYOUT { CHUNKED ( 10, 5 ) - SIZE 816 + SIZE 816 (0.980:1 COMPRESSION) } FILTERS { CHECKSUM FLETCHER32 diff --git a/tools/testfiles/tshuffle.ddl b/tools/testfiles/tshuffle.ddl index cd1b5f8..5c183fe 100644 --- a/tools/testfiles/tshuffle.ddl +++ b/tools/testfiles/tshuffle.ddl @@ -4,7 +4,7 @@ DATASET "shuffle" { DATASPACE SIMPLE { ( 20, 10 ) / ( 20, 10 ) } STORAGE_LAYOUT { CHUNKED ( 10, 5 ) - SIZE 800 + SIZE 800 (1.000:1 COMPRESSION) } FILTERS { PREPROCESSING SHUFFLE diff --git a/tools/testfiles/tuserfilter.ddl b/tools/testfiles/tuserfilter.ddl index 07b478f..24745b9 100644 --- a/tools/testfiles/tuserfilter.ddl +++ b/tools/testfiles/tuserfilter.ddl @@ -4,10 +4,10 @@ DATASET "myfilter" { DATASPACE SIMPLE { ( 20, 10 ) / ( 20, 10 ) } STORAGE_LAYOUT { CHUNKED ( 10, 5 ) - SIZE 800 + SIZE 800 (1.000:1 COMPRESSION) } FILTERS { - UNKNOWN_FILTER { + USER_DEFINED_FILTER { FILTER_ID 405 COMMENT myfilter PARAMS { 5 6 } -- cgit v0.12 From 52d119088373c4aa34cbb0564bcbe452b92044b5 Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Mon, 25 Mar 2013 14:22:10 -0500 Subject: [svn-r23449] Update script for reporting errors from configure, build, test. Tested: jam --- bin/cmakehdf5 | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/bin/cmakehdf5 b/bin/cmakehdf5 index c024ad1..2480497 100755 --- a/bin/cmakehdf5 +++ b/bin/cmakehdf5 @@ -70,6 +70,7 @@ set (CTEST_SOURCE_DIRECTORY "../hdf5") set (CTEST_BINARY_DIRECTORY ".") set (CTEST_CMAKE_GENERATOR "Unix Makefiles") set (CTEST_BUILD_CONFIGURATION "Release") +set (CTEST_MAX_N 8) # -- CDash variables set (LOCAL_NO_SUBMIT TRUE) # No CDash submit. @@ -87,6 +88,9 @@ set (ADD_BUILD_OPTIONS "-DCMAKE_INSTALL_PREFIX:PATH=/usr/local/hdf5.1.8 -DHDF5_A include(ProcessorCount) ProcessorCount(N) if(NOT N EQUAL 0) + if(N GREATER ${CTEST_MAX_N}) + set(N ${CTEST_MAX_N}) + endif(N GREATER ${CTEST_MAX_N}) set(CTEST_BUILD_FLAGS -j${N}) set(ctest_test_args ${ctest_test_args} PARALLEL_LEVEL ${N}) endif() @@ -188,22 +192,31 @@ CTEST_START (${MODEL} TRACK ${MODEL}) if (NOT LOCAL_SKIP_UPDATE) CTEST_UPDATE (SOURCE "${CTEST_SOURCE_DIRECTORY}") endif (NOT LOCAL_SKIP_UPDATE) -CTEST_CONFIGURE (BUILD "${CTEST_BINARY_DIRECTORY}") +CTEST_CONFIGURE (BUILD "${CTEST_BINARY_DIRECTORY}" RETURN_VALUE res) +if(NOT res STREQUAL "0") + message (FATAL_ERROR "Configure FAILED") +endif() message ("Configure DONE") CTEST_READ_CUSTOM_FILES ("${CTEST_BINARY_DIRECTORY}") if (NOT LOCAL_NO_SUBMIT) CTEST_SUBMIT (PARTS Update Configure Notes) endif (NOT LOCAL_NO_SUBMIT) -CTEST_BUILD (BUILD "${CTEST_BINARY_DIRECTORY}" APPEND) +CTEST_BUILD (BUILD "${CTEST_BINARY_DIRECTORY}" APPEND RETURN_VALUE res) if (NOT LOCAL_NO_SUBMIT) CTEST_SUBMIT (PARTS Build) endif (NOT LOCAL_NO_SUBMIT) +if(NOT res STREQUAL "0") + message (FATAL_ERROR "Build FAILED") +endif() message ("build DONE") if (NOT LOCAL_SKIP_TEST) - CTEST_TEST (BUILD "${CTEST_BINARY_DIRECTORY}" APPEND) + CTEST_TEST (BUILD "${CTEST_BINARY_DIRECTORY}" APPEND ${ctest_test_args} RETURN_VALUE res) if (NOT LOCAL_NO_SUBMIT) CTEST_SUBMIT (PARTS Test) endif (NOT LOCAL_NO_SUBMIT) + if(NOT res STREQUAL "0") + message (FATAL_ERROR "Test FAILED") + endif() message ("test DONE") endif (NOT LOCAL_SKIP_TEST) -- cgit v0.12 From 782591cf138d141c5a4acdc01eefa731583d7156 Mon Sep 17 00:00:00 2001 From: Binh-Minh Ribler Date: Tue, 26 Mar 2013 02:20:11 -0500 Subject: [svn-r23456] Description: A "return" was missing from a non-void function. Fixed. Platforms Tested: Linux/32 2.6 (jam) Linux/ppc64 (ostrich) Asked Allen check Windows. --- c++/src/H5Location.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/c++/src/H5Location.cpp b/c++/src/H5Location.cpp index be59f51..98878d7 100644 --- a/c++/src/H5Location.cpp +++ b/c++/src/H5Location.cpp @@ -279,7 +279,7 @@ bool H5Location::attrExists(const char* name) const //-------------------------------------------------------------------------- bool H5Location::attrExists(const H5std_string& name) const { - attrExists(name.c_str()); + return(attrExists(name.c_str())); } //-------------------------------------------------------------------------- -- cgit v0.12 From cb8e3dee9f6703dd22ea12b3344d604baa4deede Mon Sep 17 00:00:00 2001 From: Allen Byrne Date: Tue, 26 Mar 2013 14:26:10 -0500 Subject: [svn-r23460] Add missing infile assignment and error counts --- tools/h5repack/h5repack.sh.in | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/tools/h5repack/h5repack.sh.in b/tools/h5repack/h5repack.sh.in index 14e1d04..ca25183 100644 --- a/tools/h5repack/h5repack.sh.in +++ b/tools/h5repack/h5repack.sh.in @@ -244,8 +244,11 @@ VERIFY_LAYOUT_DSET() shift shift shift - - $RUNSERIAL $H5REPACK_BIN "$@" $infile $outfile + + TESTING $H5REPACK $@ + ( + $RUNSERIAL $H5REPACK_BIN "$@" $infile $outfile + ) RET=$? if [ $RET != 0 ] ; then echo "*FAILED*" @@ -266,6 +269,7 @@ VERIFY_LAYOUT_DSET() echo " PASSED" else echo " FAILED" + nerrors="`expr $nerrors + 1`" fi # clean up tmp files @@ -277,6 +281,7 @@ VERIFY_LAYOUT_DSET() # Verifying layouts from entire file VERIFY_LAYOUT_ALL() { + infile=$2 outfile=$TESTDIR/out-$1.$2 layoutfile=$TESTDIR/layout-$1.$2 expectlayout=$3 @@ -284,7 +289,10 @@ VERIFY_LAYOUT_ALL() shift shift - $RUNSERIAL $H5REPACK_BIN "$@" $infile $outfile + TESTING $H5REPACK $@ + ( + $RUNSERIAL $H5REPACK_BIN "$@" $infile $outfile + ) RET=$? if [ $RET != 0 ] ; then echo "*FAILED*" @@ -300,6 +308,7 @@ VERIFY_LAYOUT_ALL() # check if the other layouts still exsit VERIFY "layouts" ( + echo # if CONTIGUOUS if [ $expectlayout = "CONTIGUOUS" ]; then TESTING $H5DUMP_BIN -pH $outfile @@ -309,10 +318,12 @@ VERIFY_LAYOUT_ALL() $GREP "COMPACT" $layoutfile > /dev/null if [ $? -eq 0 ]; then echo " FAILED" + nerrors="`expr $nerrors + 1`" else $GREP "CHUNKED" $layoutfile > /dev/null if [ $? -eq 0 ]; then echo " FAILED" + nerrors="`expr $nerrors + 1`" else echo " PASSED" fi @@ -327,10 +338,12 @@ VERIFY_LAYOUT_ALL() $GREP "CHUNKED" $layoutfile > /dev/null if [ $? -eq 0 ]; then echo " FAILED" + nerrors="`expr $nerrors + 1`" else $GREP "CONTIGUOUS" $layoutfile > /dev/null if [ $? -eq 0 ]; then echo " FAILED" + nerrors="`expr $nerrors + 1`" else echo " PASSED" fi @@ -345,10 +358,12 @@ VERIFY_LAYOUT_ALL() $GREP "CONTIGUOUS" $layoutfile > /dev/null if [ $? -eq 0 ]; then echo " FAILED" + nerrors="`expr $nerrors + 1`" else $GREP "COMPACT" $layoutfile > /dev/null if [ $? -eq 0 ]; then echo " FAILED" + nerrors="`expr $nerrors + 1`" else echo " PASSED" fi @@ -523,6 +538,7 @@ TOOLTEST_META() else #fail echo "*FAILED*" + nerrors="`expr $nerrors + 1`" fi rm -f $outfile -- cgit v0.12 From d55bfb91a27eb3506c20cb242dd4c8072f13ca05 Mon Sep 17 00:00:00 2001 From: Mohamad Chaarawi Date: Wed, 27 Mar 2013 08:41:44 -0500 Subject: [svn-r23461] add missing static declarations of rotuines. tested on Jam - too minor for committest --- src/H5Dchunk.c | 2 +- src/H5HFsection.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/H5Dchunk.c b/src/H5Dchunk.c index e3f060a..497846b 100644 --- a/src/H5Dchunk.c +++ b/src/H5Dchunk.c @@ -2174,7 +2174,7 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5D__chunk_cinfo_cache_reset(H5D_chunk_cached_t *last) { FUNC_ENTER_PACKAGE_NOERR diff --git a/src/H5HFsection.c b/src/H5HFsection.c index 72ea100..bf779a6 100644 --- a/src/H5HFsection.c +++ b/src/H5HFsection.c @@ -449,7 +449,7 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5HF_sect_node_free(H5HF_free_section_t *sect, H5HF_indirect_t *iblock) { herr_t ret_value = SUCCEED; /* Return value */ -- cgit v0.12 From a1db18bc05d0a5d7ea9dad7701f9265734050f64 Mon Sep 17 00:00:00 2001 From: Scot Breitenfeld Date: Wed, 27 Mar 2013 09:58:41 -0500 Subject: [svn-r23462] Added definition for h5kind_to_type --- fortran/src/hdf5_fortrandll.def.in | 1 + 1 file changed, 1 insertion(+) diff --git a/fortran/src/hdf5_fortrandll.def.in b/fortran/src/hdf5_fortrandll.def.in index 4ce185b..62030f0 100644 --- a/fortran/src/hdf5_fortrandll.def.in +++ b/fortran/src/hdf5_fortrandll.def.in @@ -6,6 +6,7 @@ H5LIB_mp_H5GET_LIBVERSION_F H5LIB_mp_H5CHECK_VERSION_F H5LIB_mp_H5GARBAGE_COLLECT_F H5LIB_mp_H5DONT_ATEXIT_F +H5LIB_mp_H5KIND_TO_TYPE @H5_NOF03EXP@H5LIB_PROVISIONAL_mp_H5OFFSETOF ; H5_DBLE_INTERFACE H5_DBLE_INTERFACE_mp_H5AREAD_DOUBLE_SCALAR -- cgit v0.12 From 881cdef5f8efa09d996aa96592cb5b6844052507 Mon Sep 17 00:00:00 2001 From: Scot Breitenfeld Date: Wed, 27 Mar 2013 10:04:33 -0500 Subject: [svn-r23463] Added dllexport for verify_real_kind_7 --- fortran/test/tf.f90 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fortran/test/tf.f90 b/fortran/test/tf.f90 index d5c32c8..1060747 100644 --- a/fortran/test/tf.f90 +++ b/fortran/test/tf.f90 @@ -30,7 +30,7 @@ !This definition is needed for Windows DLLs !DEC$if defined(BUILD_HDF5_DLL) -!DEC$attributes dllexport :: verify_real +!DEC$attributes dllexport :: verify_real_kind_7 !DEC$endif SUBROUTINE verify_real_kind_7(string,value,correct_value,total_error) USE HDF5 -- cgit v0.12 From 5a14bf5fac8e5228bd3ff96693b789b070874565 Mon Sep 17 00:00:00 2001 From: Mohamad Chaarawi Date: Wed, 27 Mar 2013 10:51:15 -0500 Subject: [svn-r23466] more missed static declarations tested on Jam, to minor for committest --- src/H5AC.c | 6 +++--- src/H5Pfapl.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/H5AC.c b/src/H5AC.c index ed79813..db8446a 100644 --- a/src/H5AC.c +++ b/src/H5AC.c @@ -2998,7 +2998,7 @@ done: *------------------------------------------------------------------------- */ #ifdef H5_HAVE_PARALLEL -herr_t +static herr_t H5AC_construct_candidate_list(H5AC_t * cache_ptr, H5AC_aux_t * aux_ptr, int sync_point_op) @@ -3212,7 +3212,7 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5AC_ext_config_2_int_config(H5AC_cache_config_t * ext_conf_ptr, H5C_auto_size_ctl_t * int_conf_ptr) { @@ -4157,7 +4157,7 @@ done: *------------------------------------------------------------------------- */ #ifdef H5_HAVE_PARALLEL -herr_t +static herr_t H5AC_propagate_flushed_and_still_clean_entries_list(H5F_t * f, hid_t dxpl_id, H5AC_t * cache_ptr) diff --git a/src/H5Pfapl.c b/src/H5Pfapl.c index 4faed4f..befec84 100644 --- a/src/H5Pfapl.c +++ b/src/H5Pfapl.c @@ -2267,7 +2267,7 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5P_file_image_info_del(hid_t UNUSED prop_id, const char UNUSED *name, size_t UNUSED size, void *value) { H5FD_file_image_info_t info; /* Image info struct */ @@ -2321,7 +2321,7 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5P_file_image_info_copy(const char UNUSED *name, size_t UNUSED size, void *value) { herr_t ret_value = SUCCEED; /* Return value */ @@ -2396,7 +2396,7 @@ done: * *------------------------------------------------------------------------- */ -herr_t +static herr_t H5P_file_image_info_close(const char UNUSED *name, size_t UNUSED size, void *value) { herr_t ret_value = SUCCEED; /* Return value */ -- cgit v0.12 From 86f1fce5f7a699e34ff576905fff265fdb08be4e Mon Sep 17 00:00:00 2001 From: Quincey Koziol Date: Wed, 27 Mar 2013 13:11:55 -0500 Subject: [svn-r23469] Description: Change h5diff_exit() routine to always return a zero exit code when running in parallel, since returning a non-zero exit code can cause MPI implementations to print output and that can throw off our "expected output" comparisons. Note that this change only changes the exit code for situations where an incorrect command-line parameter was given - ph5diff was already returning a zero exit code for all "normal" executions, including those where a serial h5diff would return a non-zero exit code. Tested on: Mac OSX/64 10.8.3 (amazon) w/parallel (Too minor to require h5committest) --- tools/h5diff/ph5diff_main.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tools/h5diff/ph5diff_main.c b/tools/h5diff/ph5diff_main.c index 1fc563b..b9bd404 100644 --- a/tools/h5diff/ph5diff_main.c +++ b/tools/h5diff/ph5diff_main.c @@ -275,6 +275,9 @@ void h5diff_exit(int status) if(g_Parallel) MPI_Finalize(); - exit(status); + /* Always exit(0), since MPI implementations do weird stuff when they + * receive a non-zero exit value. - QAK + */ + exit(0); } -- cgit v0.12 From be4198eb4146dbcd7a380b7fb48980c73b518c74 Mon Sep 17 00:00:00 2001 From: Mohamad Chaarawi Date: Wed, 27 Mar 2013 17:06:16 -0500 Subject: [svn-r23470] update INSTALL_parallel with build instructions for Hopper. --- release_docs/INSTALL_parallel | 67 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 67 insertions(+) diff --git a/release_docs/INSTALL_parallel b/release_docs/INSTALL_parallel index eacaf68..03b3ecf 100644 --- a/release_docs/INSTALL_parallel +++ b/release_docs/INSTALL_parallel @@ -186,6 +186,73 @@ TOOLTEST tgroup-1.ls 1 -w80 -r -g tgroup.h5 echo SKIP TOOLTEST tgroup-1.ls 1 -w80 -r -g tgroup.h5 ======== end of bypass ======== +2.5. Hopper (Cray XE6) (for v1.8 and later) +------------------------- + +2.5.1 Building HDF5 for Hopper +------------------------------------------ +The following steps are for building HDF5 for the Hopper compute +nodes. They would probably work for other Cray XE6 systems but have +not been verified. + +Obtain a copy from the HDF ftp server: +http://www.hdfgroup.org/ftp/HDF5/current/src/ +(link might change, so always double check the HDF group website). + +$ wget http://www.hdfgroup.org/ftp/HDF5/current/src/hdf5-x.x.x.tar.gz + +unpack the tarball + +$ cd hdf5-x.x.x/ +$ CC=cc FC=ftn ./configure \ +--prefix=/project/hdf5/hdf5 --enable-parallel --enable-fortran \ +--disable-shared --disable-production +$ make + +Run make check. make check should be run on the compute nodes, not the +front end nodes. So using a PBS batch script, allocate 4 or more +cores. Always consult with the machine's website on how to create PBS +scripts and allocate nodes for your job. For Hopper, all the +information can be found on: +http://www.nersc.gov/systems/hopper-cray-xe6/ + +save the PBS script into your HDF5 build directory. The PBS script +should contain (besides the PBS node allocation requests)the +following: + +-------------------------------------------------------------- +cd $PBS_O_WORKDIR + +##set RUNSERIAL and RUNPARALLEL like this in the PBS script: +export RUNPARALLEL="aprun -n 6" +export RUNSERIAL="aprun -n 1" + +##execute make check: +make check +-------------------------------------------------------------- + +Once the job runs and all is well, install the binary: +$ make install + +2.5.2 Hopper known issues +------------------------------ +Sometimes when building the library with make, you might get this problem: + +LD_LIBRARY_PATH="$LD_LIBRARY_PATH`echo | \ +sed -e 's/-L/:/g' -e 's/ +//g'`" \ +./H5make_libsettings > H5lib_settings.c +|| \ +(test $HDF5_Make_Ignore && echo "*** Error ignored") +|| \ +(rm -f H5lib_settings.c ; exit 1) +/bin/sh: line 4: 9644 Segmentation fault +LD_LIBRARY_PATH="$LD_LIBRARY_PATH`echo | sed -e 's/-L/:/g' -e 's/ +//g'`" ./H5make_libsettings > H5lib_settings.c + +If that happens, you are probable running with make -j . In that +case, you need to cleanup everything and start again as detailed above +but use serial make (do not use -j ). 3. Detail explanation --------------------- -- cgit v0.12