Commit 8365d7ca authored by Michael Tesch's avatar Michael Tesch
Browse files

- readme updates

- fixed bug in the fmt "comma" format, ie (x,y)
- added benchmarks for fmt vs iostreams
- still fumbling with packaging
parent 3683b19d
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -81,5 +81,7 @@ publish:
  before_script:
  - dnf install -y python3-requests
  script:
  - tar czvf cppduals-${CI_BUILD_TAG#v}.tgz duals CMakeLists.txt
  - ./doc/gitlab-release --message "Release ${CI_BUILD_TAG}" cppduals-${CI_BUILD_TAG#v}.tgz
#  - ln -s cppduals-h-${CI_BUILD_TAG#v} .
#  - tar czvhf cppduals-h-${CI_BUILD_TAG#v}.tgz cppduals-h-${CI_BUILD_TAG#v}/duals cppduals-h-${CI_BUILD_TAG#v}/CMakeLists.txt
  - tar czvf cppduals-h-${CI_BUILD_TAG#v}.tgz duals CMakeLists.txt
  - ./doc/gitlab-release --message "Release ${CI_BUILD_TAG}" cppduals-h-${CI_BUILD_TAG#v}.tgz
+29 −11
Original line number Diff line number Diff line
@@ -84,8 +84,8 @@ to specify library dependencies:
  include(FetchContent)

  # Have CMake download the library
  set (CPPDUALS_TAG v0.1.2)
  set (CPPDUALS_MD5 48d9276482e5f07a768875ef692d14cd)
  set (CPPDUALS_TAG v0.3.1)
  set (CPPDUALS_MD5 5d22b2f3456b7c59347aa332d9738506)
  FetchContent_Declare (cppduals
    URL https://gitlab.com/tesch1/cppduals/-/archive/${CPPDUALS_TAG}/cppduals-${CPPDUALS_TAG}.tar.bz2
    URL_HASH MD5=${CPPDUALS_MD5}
@@ -102,10 +102,10 @@ family of commands and modifying the global preprocessor search path:
```cmake
  include(ExternalProject)

  # Have CMake download the library
  set (CPPDUALS_MD5 2c4049fa5738ba82bb6c4ba13a77ff43)
  # Have CMake download the library headers only
  set (CPPDUALS_MD5 )
  ExternalProject_Add (cppduals
    URL https://gitlab.com/tesch1/cppduals/uploads/f2e1f3490fcbe862124c89394097eae3/cppduals-0.2.0.tgz
    URL https://gitlab.com/tesch1/cppduals/-/archive/${CPPDUALS_TAG}/cppduals-${CPPDUALS_TAG}.tar.bz2
    URL_HASH MD5=${CPPDUALS_MD5}
    CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" )

@@ -177,13 +177,14 @@ operations (nominally matrix multiplication) on `duals::dual<>`-valued
Eigen matrices with highly optimtimized BLAS implementations of
equivalent operations on complex-valued matrices.  This can be done by
running the [./tests/bench_gemm](./tests/bench_gemm.cpp) program.  In
the ideal case, the results of the `B_MatMat<dual{f,d}>` type should
the *ideal* case, the results of the `B_MatMat<dual{f,d}>` type should
be nearly as fast, or faster than equivalently sized
`B_MatMat<complex{f,d}>`, and double-sized
`B_MatMatBLAS<{float,double}>` operations.  This is very difficult to
achieve in reality, as the BLAS libraries typically use hand-coded
achieve in reality, as the BLAS libraries typically use hand-tuned
assembly, where the Eigen libraries must strive to express the
calculation is a form that the compiler can turn into optimal code.
calculation in a general form that the compiler can turn into optimal
code.

Comparing Eigen 3.3.7 and OpenBLAS 0.3.6 on an `Intel(R) Core(TM)
i7-7700 CPU @ 3.60GHz` is still sub-optimal, only achieving about half
@@ -221,9 +222,9 @@ measures are `B_MatMat<cdual{f,d}>` and `B_MatMatBLAS<complex{f,d}>`
of twice the size.

On the same machine as above, using `std::complex<duals::dual<float>>`
(`cdualf`) shows an advantage over the BLAS approach, (although
nothing that the advantage decreases as the matrices get larger, which
ideally would not be the case):
(`cdualf`) shows a speed advantage over the BLAS approach, while using
only half the memory.  However, notice that the advantage decreases as
the matrices get larger, which ideally should not happen:

    B_MatMat<cdualf,cdualf>/16             2810 ns         2808 ns
    B_MatMat<cdualf,cdualf>/32            19900 ns        19878 ns
@@ -251,6 +252,7 @@ Contributors
------------

- [Nestor Demeure](https://gitlab.com/nestordemeure)
- [Jeff](https://github.com/flying-tiger)

Compiler notes
==============
@@ -294,6 +296,22 @@ thus licensed under [MPL-2](http://www.mozilla.org/MPL/2.0/FAQ.html) .
ChangeLog
=========

v0.3.3+
=======

- ignore these, will be, trying to cleanup release tarballs, next stable will be v0.4.0

v0.3.2
======

- fixed a bug in the `{fmt}` support, added docs for the same.
- added benchmarking for `{fmt}` vs iostreams.

v0.3.1
======

- forgot to bump the CMakeLists package version number in 0.3.0.

v0.3.0
======

+24 −1
Original line number Diff line number Diff line
@@ -81,6 +81,19 @@ class GitlabRelease:
        res = self.request('post', url, files=files)
        return res.json()['markdown']

    def fetch_links(self):
        url = '/'.join((self.api_project_url, 'releases', self.get_tag(), 'assets/links'))
        headers = {'Content-Type': 'application/json'}
        res = self.request('get', url, headers=headers)
        return res.json()

    def set_links(self, links, update=False):
        url = '/'.join((self.api_project_url, 'releases', self.get_tag(), 'assets/links'))
        headers = {'Content-Type': 'application/json'}
        method = 'put' if update else 'post'
        res = self.request(method, url, headers=headers, json=links)
        return res.json()

    def set_release(self, message, update=False):
        url = '/'.join((self.api_project_url, 'repository/tags', self.get_tag(), 'release'))
        headers = {'Content-Type': 'application/json'}
@@ -89,7 +102,6 @@ class GitlabRelease:
        res = self.request(method, url, headers=headers, json=body)
        return res.json()


    def fetch_release(self):
        url = '/'.join((self.api_project_url, 'repository/tags', self.get_tag()))
        res = self.request('get', url)
@@ -167,9 +179,20 @@ the previous step.
                        help='Files to link in the release.')
    parser.add_argument('-d', '--debug', action='store_true',
                        help='Print debug messages')
    parser.add_argument('-l', '--links', action='store_true',
                        help='Print project links')
    args = parser.parse_args()
    #os.environ['CI_PROJECT_ID'] = 'tesch1%2Fcppduals'
    #os.environ['CI_BUILD_TAG'] = 'v0.3.1'
    #os.environ['CI_COMMIT_TAG'] = 'v0.3.1'
    #os.environ['CI_PROJECT_URL'] = 'https://gitlab.com'
    #os.environ['CI_SERVER_VERSION'] = '9.0.0'
    #os.environ['GITLAB_ACCESS_TOKEN'] = ''
    try:
        release = GitlabRelease(args.debug)
        #if args.links:
        #    print(release.fetch_links())
        #    sys.exit(0)
        info = release.create_release(args.message, args.files)
        print("Release: {tag_name} created.\n{description}".format_map(info))
    except GitlabReleaseError as err:
+53 −30
Original line number Diff line number Diff line
@@ -94,10 +94,10 @@ ddf(2.) = 958.755

How this works can be seen by inspecting the infinite [Taylor
series](https://en.wikipedia.org/wiki/Taylor_series) expansion of a
function \f$ f(x) \f$ at $a$ with $x = a + b\epsilon$.  The series
truncates itself due to the property \f$ \epsilon^2 = 0 \f$, leaving
the function's derivative at \f$ a \f$ in the "dual part" of the
result (when \f$ b = 1 \f$):
function \f$ f(x) \f$ at \f$ a \f$ with \f$ x = a + b\epsilon \f$.
The series truncates itself due to the property \f$ \epsilon^2 = 0
\f$, leaving the function's derivative at \f$ a \f$ in the "dual part"
of the result (when \f$ b = 1 \f$):

\f[
\begin{split}
@@ -248,6 +248,27 @@ duald y = 3 + 4_e;
dualld z = 3 + 4_el;
```

And in case you dislike iostreams, there are some formatters for the
[`{fmt}`](https://github.com/fmtlib/fmt) formatting library.  These
are disabled by default, but can be enabled by `#define
CPPDUALS_LIBFMT` for the `dual<>` formatter, and/or `#define
CPPDUALS_LIBFMT_COMPLEX` for the std::complex<> formatter. There are
three custom formatting flags that control how the dual numbers are
printed, these must come before the normal `{fmt}` formatting spec:
'$', '*', ','.  For me these are about 3x faster than iostreams.

```
#define CPPDUALS_LIBFMT
#define CPPDUALS_LIBFMT_COMPLEX
#inlcude <duals/dual>
using namespace duals::literals;
  ...
  string s = fmt::format("{:}",  1 + 2_e); // s = "(1.0+2.0_e)"
  string s = fmt::format("{:g}", 1 + 2_e); // s = "(1+2_e)"
  string s = fmt::format("{:*}", 1 + 2_e); // s = "(1.0+2.0*e)"
  string s = fmt::format("{:,}", 1 + 2_e); // s = "(1.0,2.0)"
  string s = fmt::format("{:*,g}", complexd(1,2_e)); // s = "((1)+(0,2)*i)"
```

The "archaic Greek epsilon" logo is from [Wikimedia
commons](https://commons.wikimedia.org/wiki/File:Greek_Epsilon_archaic.svg)
@@ -1228,16 +1249,18 @@ struct fmt::formatter<duals::dual<T>,Char> : public fmt::formatter<T,Char>
  template <typename FormatCtx>
  auto format(const duals::dual<T> & x, FormatCtx & ctx) -> decltype(ctx.out()) {
    format_to(ctx.out(), "(");
    if (style_ == style::pair) {
      base::format(x.rpart(), ctx);
      format_to(ctx.out(), ",");
      base::format(x.dpart(), ctx);
      return format_to(ctx.out(), ")");
    }
    if (x.rpart() || !x.dpart())
      base::format(x.rpart(), ctx);
    if (x.dpart()) {
      if (style_ == style::pair)
        format_to(ctx.out(), ",");
      else
      if (x.rpart() && x.dpart() >= 0 && specs_.sign != sign::plus)
        format_to(ctx.out(), "+");
      base::format(x.dpart(), ctx);
      if (style_ != style::pair) {
      if (style_ == style::star)
        format_to(ctx.out(), "*e");
      else
@@ -1245,7 +1268,6 @@ struct fmt::formatter<duals::dual<T>,Char> : public fmt::formatter<T,Char>
      if (std::is_same<typename std::decay<T>::type,float>::value)       format_to(ctx.out(), "f");
      if (std::is_same<typename std::decay<T>::type,long double>::value) format_to(ctx.out(), "l");
    }
    }
    return format_to(ctx.out(), ")");
  }
};
@@ -1300,16 +1322,18 @@ struct fmt::formatter<std::complex<T>,Char> : public fmt::formatter<T,Char>
  template <typename FormatCtx>
  auto format(const std::complex<T> & x, FormatCtx & ctx) -> decltype(ctx.out()) {
    format_to(ctx.out(), "(");
    if (style_ == style::pair) {
      base::format(x.real(), ctx);
      format_to(ctx.out(), ",");
      base::format(x.imag(), ctx);
      return format_to(ctx.out(), ")");
    }
    if (x.real() || !x.imag())
      base::format(x.real(), ctx);
    if (x.imag()) {
      if (style_ == style::pair)
        format_to(ctx.out(), ",");
      else
      if (x.real() && x.imag() >= 0 && specs_.sign != sign::plus)
        format_to(ctx.out(), "+");
      base::format(x.imag(), ctx);
      if (style_ != style::pair) {
      if (style_ == style::star)
        format_to(ctx.out(), "*i");
      else
@@ -1317,7 +1341,6 @@ struct fmt::formatter<std::complex<T>,Char> : public fmt::formatter<T,Char>
      if (std::is_same<typename std::decay<T>::type,float>::value)       format_to(ctx.out(), "f");
      if (std::is_same<typename std::decay<T>::type,long double>::value) format_to(ctx.out(), "l");
    }
    }
    return format_to(ctx.out(), ")");
  }
};
+6 −2
Original line number Diff line number Diff line
@@ -73,7 +73,7 @@ foreach (TEST_ ${ALL_TESTS})
    string (REPLACE ";" ", " L2 "${CMAKE_CXX_FLAGS}")
    target_compile_options (${TEST} PUBLIC ${PHASE_FLAGS})
    target_compile_definitions (${TEST} PRIVATE "OPT_FLAGS=${L2}")
    target_link_libraries (${TEST} gtest_main cppduals_coverage_config fmt::fmt)
    target_link_libraries (${TEST} gtest_main cppduals_coverage_config)
    #target_link_libraries (${TEST} -lasan)
    add_dependencies (${TEST} eigenX expokitX)
    gtest_discover_tests (${TEST} TEST_LIST ${TEST}_targets)
@@ -82,7 +82,9 @@ foreach (TEST_ ${ALL_TESTS})
  endforeach (PHASE)
endforeach (TEST_)

# special for fmt
target_compile_features (test_fmt_1 PUBLIC cxx_std_14)
target_link_libraries (test_fmt_1 fmt::fmt)

if (CPPDUALS_BENCHMARK)
  #
@@ -186,7 +188,7 @@ if (CPPDUALS_BENCHMARK)
  #set (OPT_FLAGS "${OPT_FLAGS};-DCPPDUALS_DONT_VECTORIZE")
  #set (OPT_FLAGS "${OPT_FLAGS};-DCPPDUALS_DONT_VECTORIZE_CDUAL")

  foreach (BENCH  bench_dual bench_eigen bench_gemm bench_example)
  foreach (BENCH  bench_dual bench_eigen bench_gemm bench_example bench_fmt)
    add_executable (${BENCH} ${BENCH}.cpp)
    target_compile_options (${BENCH} PUBLIC ${OPT_FLAGS})
    #set_target_properties (${BENCH} PROPERTIES LINK_FLAGS -fopenmp)
@@ -197,6 +199,8 @@ if (CPPDUALS_BENCHMARK)
    target_link_libraries (${BENCH} ${BENCHMARK_LIBRARY} -lpthread ${BLAS_LIBRARIES})
  endforeach (BENCH)

  target_link_libraries (bench_fmt fmt::fmt)

endif (CPPDUALS_BENCHMARK)

add_executable (sandbox sandbox.cpp)
Loading