DyND Release Notes
==================

DyND is a C++ library for array programming with a dynamic
type system. It is currently in a preview state, and nothing
about the API or the ABI is guaranteed to stay the same.

Version 0.6.2
-------------

Commits by author since last release:

   178  Mark Wiebe
   123  Irwin Zaid
     2  Damien Garaud

- Add basic CUDA support via new memory_kind and cuda memory types.
  This support includes copying to/from arrays in CUDA memory.
- Replace use of std::complex with new dynd_complex class which can
  be compiled by CUDA.
- Convert type system to updated datashape grammar. For example
  a 1D int32 array is now "strided * int32" instead of "strided, int32".
- Code for lifting scalar accumulation ckernels to multidimensional
  reductions.
- Add nd::view function which can switch between strided/fixed dimensions,
  view bytes as POD data, and POD data as bytes.
- Add .travis.yml testing of github development, including running the
  tests through valgrind.
- Change the preliminary date/datetime code to a new design, eliminating
  the multiple unit selection, and including a parser which accepts more
  general inputs than just ISO 8601 format. There are now date, time, and
  datetime types, and the evaluation context includes options for how
  to deal with two-digit years and YMD vs MDY vs DMY ordering.
- Add a preprocessor metaprogramming library in the 'pp' subdirectory.
- Add an nd::foreach function which runs a C++ functor (e.g. a C++11
  lambda function) elementwise across provided nd::arrays. This uses
  the preprocessor metaprogramming to generate variants with different
  numbers of nd::array arguments.
- Removed MSVC 2008 as a supported compiler on Windows, MSVC 2010
  or later is required now.
- Add function ndt::type::tcast<>() to simplify code casting to specific
  type objects.
- Rename previous fixed_dim type to cfixed_dim, and introduce a new
  fixed_dim which behaves like the fixed[N] defined in datashape.
  The naming cfixed[N] vs fixed[N] is not ideal, would be nice to find
  a convention for the fixed-layout types (cfixed_dim, cstruct, ctuple)
  vs the variable-layout types (fixed_dim, struct, tuple).
- Code for creating ckernels to do simple windowed function evaluation.
- Change slicing behavior with out-of-bounds indices to match Python.

Version 0.6.1
-------------

- Tweak how some of the dimension types are printed.
- Add a dynd::type_error exception for type-specific errors.
- Some inf and nan-related fixes.
- Add .conj property to the complex type.
- Add a function which returns a ckernel_deferred from a property.
- Fix a segfault bug from groupby on a multidimensional input.

Version 0.6.0
-------------

- Add nd::memmap(filename, ...) to memory map a file as bytes.
- Add "char" data type to represent a single unicode character.
- The start of a 1D typed iterator primitive.
- Replace type "cfloat##" with "complex[float##]".

Version 0.5.0
-------------

- Make default access when constructing an nd::array from
  a value be immutable instead of readwrite.
- Add nd::array_rw(val) constructors to support creating
  readwrite arrays from a value.
- Some datashape printing/parsing tweaks, like "unaligned(...)"
  support, printing the cstruct type using datashape format.
- Add supporting code for ckernel ABI, including a
  ckernel_deferred type, code for lifting ckernel_deferred
  objects to higher dimensions, renaming to more consistent
  naming schemes.

Version 0.4.2
-------------

- Rename "dtype" to "ndt::type". Usage is now that "type"
  refers to the full array type, while "dtype" refers
  to the data type, after stripping away some or all of
  the array dimensions.
- Move many of the type related functions into the ndt::
  namespace, making the C++ interface align better with
  the Python one.
- Add a simple implementation of string.find, modeled after
  the Python string's find method.

Version 0.4.1
-------------

- Switch indexing from a.at(...) to a(...) using operator()
- Change how the step is specified in indexing, as irange().by(step)
  instead of irange() / step.
- Rename the "ndobject" to "nd::array", matching the change
  in the Python bindings.
- Rename "arange" to "nd::range", no need for the prefix "a".
- Change indexing to only affect dimensions directly indexed,
  collapsing leading "var" dims turned out to be problematic.
- Add string concatenation via the + operator.

Version 0.4.0
-------------

- Make some properties of dtypes more self-consistent.
- Add initial datetime type, with some basic functionality.
- Small changes towards renaming ndobject into nd::array

Version 0.3.1
-------------

Version 0.3.0
-------------

Version 0.2.0
-------------

Version 0.1
-----------

This is the first preview release of the library, with the
primary goals of demonstrating some basic computations and
good interoperability with Numpy.

Initial features include:

 - Strided multi-dimensional array primitive, similar to
   Numpy, Boost MultiArray and others. This object is fully
   dynamic, the data type and dimensionality are specified
   at runtime.

 - Initial set of data types comparable to that
   of Numpy, with a few exceptions such as datetime and
   float16.

 - A lazy evaluation computation infrastructure, which builds
   up an expression graph and evaluates it when values are
   requested.

 - Elementwise computation nodes and elementwise reduction
   computation nodes, exposed as "gfuncs" in Python. These
   are similar to Numpy's "ufuncs" and its reduction methods
   like "sum".

 - A preliminary code generation system to adapt simple
   functions to operate as kernels in gfuncs, and a basic
   .dll/.so defining a few simple kernels this way.

 - A proof of concept implementation of data types based on
   array/memory block level references, initially with a
   variable-sized string type.

 - Flexible error checking in data type conversion, raising
   errors dynamically based on values instead of just checking
   data types.

Limitations:

 - The code generation system only supports 64-bit platforms
   presently, and only can adapt unary and binary kernel functions
   for use in gfuncs.

 - Only a subset of the possible expression trees can be evaluated.
   This can be worked around by manually creating temporaries
   using the ndarray.vals() method.
