diff --git a/src/docs/sphinx/t_conduit_docs_tutorial_numeric_out.txt b/src/docs/sphinx/t_conduit_docs_tutorial_numeric_out.txt index ea27797f2..8e0595177 100644 --- a/src/docs/sphinx/t_conduit_docs_tutorial_numeric_out.txt +++ b/src/docs/sphinx/t_conduit_docs_tutorial_numeric_out.txt @@ -1,7 +1,7 @@ -Running main() from /Users/harrison37/Work/github/llnl/conduit/src/blt/thirdparty_builtin/googletest-master-2020-01-07/googletest/src/gtest_main.cc -[==========] Running 9 tests from 1 test suite. +Running main() from C:\Users\capps2\Documents\projects\axom\src\cmake\blt\thirdparty_builtin\googletest\googletest\src\gtest_main.cc +[==========] Running 12 tests from 1 test suite. [----------] Global test environment set-up. -[----------] 9 tests from conduit_tutorial +[----------] 12 tests from conduit_tutorial [ RUN ] conduit_tutorial.numeric_as_dtype BEGIN_EXAMPLE("numeric_as_dtype") 100 @@ -35,6 +35,33 @@ my_vals[1] = 300 [100, 300] END_EXAMPLE("numeric_strided_data_array") [ OK ] conduit_tutorial.numeric_strided_data_array (0 ms) +[ RUN ] conduit_tutorial.numeric_data_accessor_start +BEGIN_EXAMPLE("numeric_data_accessor") +[ OK ] conduit_tutorial.numeric_data_accessor_start (0 ms) +[ RUN ] conduit_tutorial.numeric_data_accessor +int64 case: +[100.0, 300.0] +Some stats: + min: 100 + max: 300 + sum: 400 + mean: 200 +vals[0] = 100 +vals[1] = 300 +float64 case: +[2.2, 4.4, 6.6] +Some stats: + min: 2.2 + max: 6.6 + sum: 13.2 + mean: 4.4 +vals[0] = 2.2 +vals[1] = 4.4 +vals[2] = 6.6 +[ OK ] conduit_tutorial.numeric_data_accessor (0 ms) +[ RUN ] conduit_tutorial.numeric_data_accessor_end +END_EXAMPLE("numeric_data_accessor") +[ OK ] conduit_tutorial.numeric_data_accessor_end (0 ms) [ RUN ] conduit_tutorial.numeric_double_conversion_start BEGIN_EXAMPLE("numeric_double_conversion") [ OK ] conduit_tutorial.numeric_double_conversion_start (0 ms) @@ -65,8 +92,8 @@ BEGIN_EXAMPLE("numeric_cxx11_init") [1.0, 2.0, 3.0] END_EXAMPLE("numeric_cxx11_init") [ OK ] conduit_tutorial.numeric_cxx11_init (0 ms) -[----------] 9 tests from conduit_tutorial (0 ms total) +[----------] 12 tests from conduit_tutorial (2 ms total) [----------] Global test environment tear-down -[==========] 9 tests from 1 test suite ran. (0 ms total) -[ PASSED ] 9 tests. +[==========] 12 tests from 1 test suite ran. (3 ms total) +[ PASSED ] 12 tests. diff --git a/src/docs/sphinx/tutorial_cpp_numeric.rst b/src/docs/sphinx/tutorial_cpp_numeric.rst index 4661eb033..02d95bd98 100644 --- a/src/docs/sphinx/tutorial_cpp_numeric.rst +++ b/src/docs/sphinx/tutorial_cpp_numeric.rst @@ -7,11 +7,15 @@ Accessing Numeric Data ======================= -Accessing Scalars and Arrays --------------------------------- - You can access leaf types (numeric scalars or arrays) using Node's *as_{type}* -methods. +methods. You can let Conduit handle striding with the DataArray class, and +additionally type conversion with the DataAccessor class. + +Accessing Scalars +----------------- + +The call to *Node::as_int64()* gives you the numeric value. Make sure the +Node does actually contain an int64, or Conduit will throw an error. .. # from t_conduit_docs_tutorial_numeric: numeric_as_dtype @@ -25,8 +29,9 @@ methods. :start-after: BEGIN_EXAMPLE("numeric_as_dtype") :end-before: END_EXAMPLE("numeric_as_dtype") -Or you can use Node::value(), which can infer the correct return type via a -cast. +Or you can use *Node::value()*, which can infer the correct return type via a +cast. As with the *as_{type}* methods, make sure to ask for the type of data +that the Node actually contains. .. # from t_conduit_docs_tutorial_numeric: numeric_via_value @@ -41,8 +46,14 @@ cast. :end-before: END_EXAMPLE("numeric_via_value") -Accessing array data via pointers works the same way, using Node's *as_{type}* -methods. +Accessing Arrays +---------------- + +You can get numeric array data out of Conduit as a pointer; as a DataArray, +which handles striding; or as a DataAccessor, which handles striding and +type conversion. + +Access array data via pointers using Node's *as_{type}* methods. .. # from t_conduit_docs_tutorial_numeric: numeric_ptr_as_dtype @@ -89,21 +100,10 @@ indexing for all types of arrays. :start-after: BEGIN_EXAMPLE("numeric_strided_data_array") :end-before: END_EXAMPLE("numeric_strided_data_array") -C++11 Initializer Lists ------------------------------------ -You can set Node values using C++11 style initializer lists of numeric literals. - -.. literalinclude:: ../../tests/docs/t_conduit_docs_tutorial_numeric.cpp - :start-after: BEGIN_EXAMPLE("numeric_cxx11_init") - :end-before: END_EXAMPLE("numeric_cxx11_init") - :language: cpp - :dedent: 4 - - -.. literalinclude:: t_conduit_docs_tutorial_numeric_out.txt - :start-after: BEGIN_EXAMPLE("numeric_cxx11_init") - :end-before: END_EXAMPLE("numeric_cxx11_init") +The DataAccessor class lets you write code to gracefully handle data +of varying type, such as user input data. See the next section for +an example of DataAccessor use. Using Introspection and Conversion @@ -127,3 +127,45 @@ double array. :start-after: BEGIN_EXAMPLE("numeric_double_conversion") :end-before: END_EXAMPLE("numeric_double_conversion") +Alternately, we can use a DataAccessor to do the conversion as needed. + +.. # from t_conduit_docs_tutorial_numeric: numeric_data_accessor + +.. literalinclude:: ../../tests/docs/t_conduit_docs_tutorial_numeric.cpp + :start-after: BEGIN_EXAMPLE("numeric_data_accessor") + :end-before: END_EXAMPLE("numeric_data_accessor") + :language: cpp + :dedent: 4 + +.. literalinclude:: t_conduit_docs_tutorial_numeric_out.txt + :start-after: BEGIN_EXAMPLE("numeric_data_accessor") + :end-before: END_EXAMPLE("numeric_data_accessor") + +The first version examines the data type of the Node passed to +*process_doubles()* and converts the entire array if needed. The worker +function *must_have_doubles_function()* works with a pointer, as is the case +with much existing code, giving speed of access with no guard-rails. The second +version constructs a float64_accessor from its Node argument and passes that to +the worker function *takes_float64_accessor()*. That worker function shows how +to use the summary methods of DataAccessor and then prints the values in the +array passed to it. The DataAccessor casts each value as needed on access, thus +incurring a small cost at each access. The DataAccessor is also safer and +simpler to use. + + +C++11 Initializer Lists +----------------------------------- + +You can set Node values using C++11 style initializer lists of numeric literals. + +.. literalinclude:: ../../tests/docs/t_conduit_docs_tutorial_numeric.cpp + :start-after: BEGIN_EXAMPLE("numeric_cxx11_init") + :end-before: END_EXAMPLE("numeric_cxx11_init") + :language: cpp + :dedent: 4 + + +.. literalinclude:: t_conduit_docs_tutorial_numeric_out.txt + :start-after: BEGIN_EXAMPLE("numeric_cxx11_init") + :end-before: END_EXAMPLE("numeric_cxx11_init") + diff --git a/src/tests/docs/t_conduit_docs_tutorial_numeric.cpp b/src/tests/docs/t_conduit_docs_tutorial_numeric.cpp index 13b78750c..410e49559 100644 --- a/src/tests/docs/t_conduit_docs_tutorial_numeric.cpp +++ b/src/tests/docs/t_conduit_docs_tutorial_numeric.cpp @@ -99,6 +99,70 @@ TEST(conduit_tutorial, numeric_strided_data_array) END_EXAMPLE("numeric_strided_data_array"); } +//----------------------------------------------------------------------------- +TEST(conduit_tutorial, numeric_data_accessor_start) +{ + BEGIN_EXAMPLE("numeric_data_accessor"); +} + +// _conduit_tutorial_cpp_numeric_data_accessor_start +//----------------------------------------------------------------------------- +void takes_float64_accessor(float64_accessor vals) +{ + std::cout << "Some stats:\n\t min: " << vals.min() << + "\n\t max: " << vals.max() << + "\n\t sum: " << vals.sum() << + "\n\t mean: " << vals.mean() << + std::endl; + for(int i = 0; i < vals.number_of_elements(); i++) + { + std::cout << "vals[" << i << "] = " << vals[i] << std::endl; + } +} + +//----------------------------------------------------------------------------- +void process_doubles_with_accessor(Node & n) +{ + float64_accessor vals = n.value(); + vals.print(); + takes_float64_accessor(vals); +} + +//----------------------------------------------------------------------------- +TEST(conduit_tutorial, numeric_data_accessor) +{ + int64 i_vals[4] = {100,200,300,400}; + + Node n; + n.set(i_vals,2, // # of elements + 0, // offset in bytes + sizeof(int64)*2); // stride in bytes + + // Process values as float64, even though they're integers + std::cout << "int64 case: " << std::endl; + process_doubles_with_accessor(n); + + + float64 dvals[6] = {1.1,2.2,3.3,4.4,5.5,6.6}; + + Node dn; + dn.set(dvals,3, // # of elements + 8, // offset in bytes + sizeof(float64)*2); // stride in bytes + + // Process values as float64 + std::cout << "float64 case: " << std::endl; + process_doubles_with_accessor(dn); +} +// _conduit_tutorial_cpp_numeric_data_accessor_end + + +//----------------------------------------------------------------------------- +TEST(conduit_tutorial, numeric_data_accessor_end) +{ + END_EXAMPLE("numeric_data_accessor"); +} + //----------------------------------------------------------------------------- TEST(conduit_tutorial, numeric_double_conversion_start) {