Giter Site home page Giter Site logo

bobsteagall / wg21 Goto Github PK

View Code? Open in Web Editor NEW
62.0 18.0 9.0 4.62 MB

Various documents and code related to proposals for WG21

License: University of Illinois/NCSA Open Source License

CMake 1.27% C++ 63.40% Python 0.64% HTML 34.69%
cplusplus-20 cplusplus-23 cplusplus

wg21's Introduction

wg21

CMake Build

Work on revision R7 of linear algebra proposal P1385 is currently underway in the r7y branch. We are targeting C++26.

Support

This reference implementation requires several C++20 capabilities which are only available in newer compiler releases.

Current compiler support is as follows, but will change as new compilers become available and catch up with implementing new language features for C++20. Builds and unit testing have been successful on the following combinations of operating system and compiler:

  • Windows 10

    • Visual Studio 2019, Version 16.5.4 and higher
  • Linux (written and tested on RHEL 8.X)

    • GCC 12.x

Cloning the Repo

After ensuring that git is in your executable path, open a terminal window on Linux, or a Command Prompt on Windows 10, and then:

cd <repo_root>
git clone --recurse-submodules https://github.com/BobSteagall/wg21.git <project_root>

If you do not specify <project_root>, it will default to wg21.

Building with the Visual Studio Solution

Open the lin_alg_test.sln solution file in the <repo_root>/<project_root> directory. Click Build..Build Solution to build the unit test program. (Note: This build method uses the NuGet package manager to download and install Google Test in the <project_root>/packages directory, so you'll need to ensure NuGet is installed.)

Building Manually Via CMake on Windows 10

The unit test program can be built via CMake on Windows 10 by proceeding as follows. First, generate the Visual Studio project files:

cd <project_root>
mkdir build-win
cd build-win
cmake -G "Visual Studio 16 2019" ..

Next, build the Debug configuration and run the unit test:

cmake --build . --config Debug
ctest -C Debug

Finally, build the Release configuration and run the unit test:

cmake --build . --config Release
ctest -C Release

Note: CMake uses a multi-configuration generator for Visual Studio, so there is no need to specify a CMake build type; in fact, CMake will ignore CMAKE_BUILD_TYPE when using the Visual Studio generator.

The following CMake configuration options are available on Windows:

Name Possible Values Description Default Value
BUILD_TESTING ON, OFF Build the test suite ON
LA_BUILD_USING_PCH ON, OFF Build using precompiled headers OFF

Building Manually Via CMake on Linux

The project can be built via CMake on Linux as follows:

cd <project_root>
mkdir build-dir
cd build-dir
cmake [-G <generator>] [configuration options] ..
cmake --build . [--config <build_type>]
ctest [--config <build_type>]

For example, to build and test the Debug configuration, you could do the following:

cd <project_root>
mkdir build-debug
cd build-debug
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Debug ..
cmake --build .
ctest

Likewise, for the Release configuration, you could do this:

cd <project_root>
mkdir build-release
cd build-release
cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE=Release ..
cmake --build .
ctest

Note: CMake uses a single-configuration generator when generating makefiles, so there is no need to use the --config flag with CMake or the -C flag with CTest. When using CMake on Linux, a good practice is to create a separate build directory for each CMake build type.

The following configuration options are available on Linux:

Name Possible Values Description Default Value
BUILD_TESTING ON, OFF Build the test suite ON
CMAKE_BUILD_TYPE Debug, Release, RelWithDebInfo Build type Debug
LA_BUILD_USING_PCH ON, OFF Build using precompiled headers OFF
LA_ENABLE_SANITIZERS ON, OFF Build with address and UB sanitizers OFF
LA_VERBOSE_TEST_OUTPUT ON, OFF Write verbose test results OFF

Installing Via CMake

Installing the project can be performed as follows:

cd <project root>
mkdir build
cd build

cmake [-G <generator>] [configuration options] -DCMAKE_INSTALL_PREFIX=<install_dir> ..
cmake --build . --target install

Packages

The Linear Algebra library is available for integration into your own project via our favorite package manager: Conan.

Getting the Conan package

To add the linear_algebra library to your project as a dependency, you need to add a remote to Conan that points to the location of the package:

pip install conan
conan remote add linear_algebra https://twonington.jfrog.io/artifactory/api/conan/conan-oss

Once this is set, you can add the linear_algebra dependency to you project via the following signature:

linear_algebra/0.7.0@conan-oss/testing

Available versions of the Linear Algebra package can be search via Conan:

conan search linear_algebra

Building the Conan package

The linear_algebra project and package can be built locally via the Conan as such:

cd <project_root>
pip install conan
conan create [conan options] <project_root> [--test-folder None]

wg21's People

Contributors

ablepharus avatar bobsteagall avatar hatcat avatar rbrugo avatar twon avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wg21's Issues

Problems with the initializer_list constructor

The latest version of the 0.7.0/testing Conan package fails to compile such a simple code:

template<typename Rep = double>
using vector = fs_vector<Rep, 3>;

template<units::Unit U = si::metre, units::Scalar Rep = double>
using length_v = si::length<U, vector<Rep>>;

length_v<> v(vector<>{ 1, 2, 3 });

The code compiled fine before but now the following compiler error is being reported:

[build] [1/2  50% :: 7.014] Building CXX object example/CMakeFiles/linear_algebra.dir/linear_algebra.cpp.o
[build] FAILED: example/CMakeFiles/linear_algebra.dir/linear_algebra.cpp.o 
[build] /bin/g++-10   -I../../src/include -isystem /home/mpusz/.conan/data/fmt/6.2.1/_/_/package/1291f461f6832a5b3098e2156f727f267fd98612/include -isystem /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include -g   -Wno-literal-suffix -Wno-non-template-friend -Wall -Wextra -Wpedantic -Wshadow -Wnon-virtual-dtor -Wold-style-cast -Wcast-align -Wunused -Woverloaded-virtual -Wcast-qual -Wconversion -Wsign-conversion -Wnull-dereference -Wdouble-promotion -Wformat=2 -Werror -Wmisleading-indentation -Wduplicated-cond -Wduplicated-branches -Wlogical-op -std=gnu++2a -MD -MT example/CMakeFiles/linear_algebra.dir/linear_algebra.cpp.o -MF example/CMakeFiles/linear_algebra.dir/linear_algebra.cpp.o.d -o example/CMakeFiles/linear_algebra.dir/linear_algebra.cpp.o -c ../../example/linear_algebra.cpp
[build] In file included from /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra.hpp:100,
[build]                  from ../../example/linear_algebra.cpp:27:
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/vector.hpp: In instantiation of ‘constexpr std::math::vector<ET, OT>::vector(std::initializer_list<_Up>) [with U = std::math::vector<std::math::fs_vector_engine<double, 3>, std::math::matrix_operation_traits>; ET2 = std::math::fs_vector_engine<double, 3>; typename std::enable_if<(is_same_v<ET, ET2> && is_initable_engine_v<ET>), bool>::type <anonymous> = true; ET = std::math::fs_vector_engine<double, 3>; OT = std::math::matrix_operation_traits]’:
[build] ../../src/include/units/quantity.h:78:75:   required from ‘constexpr units::quantity<D, U, Rep>::quantity(const Value&) [with Value = std::math::vector<std::math::fs_vector_engine<double, 3>, std::math::matrix_operation_traits>; D = units::physical::si::dim_length; U = units::physical::si::metre; Rep = std::math::vector<std::math::fs_vector_engine<double, 3>, std::math::matrix_operation_traits>]’
[build] ../../example/linear_algebra.cpp:214:35:   required from here
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/vector.hpp:236:18: error: no matching function for call to ‘std::math::fs_vector_engine<double, 3>::fs_vector_engine(std::initializer_list<std::math::vector<std::math::fs_vector_engine<double, 3>, std::math::matrix_operation_traits> >&)’
[build]   236 | :   m_engine(list)
[build]       |                  ^
[build] In file included from /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra.hpp:93,
[build]                  from ../../example/linear_algebra.cpp:27:
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/fixed_size_vector_engine.hpp:120:1: note: candidate: ‘template<class T2, typename std::enable_if<is_convertible_v<T2, double>, bool>::type <anonymous> > constexpr std::math::fs_vector_engine<T, N>::fs_vector_engine(std::initializer_list<_Up>) [with T2 = T2; typename std::enable_if<is_convertible_v<T2, T>, bool>::type <anonymous> = <anonymous>; T = double; long int N = 3]’
[build]   120 | fs_vector_engine<T,N>::fs_vector_engine(initializer_list<T2> rhs)
[build]       | ^~~~~~~~~~~~~~~~~~~~~
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/fixed_size_vector_engine.hpp:120:1: note:   template argument deduction/substitution failed:
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/fixed_size_vector_engine.hpp:46:75: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’
[build]    46 |     template<class T2, detail::enable_if_convertible_element_type<T2,T> = true>
[build]       |                                                                           ^~~~
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/fixed_size_vector_engine.hpp:45:15: note: candidate: ‘template<class ET2, typename std::enable_if<(is_engine_v<ET2> && is_convertible_v<typename ET2::value_type, double>), bool>::type <anonymous> > constexpr std::math::fs_vector_engine<T, N>::fs_vector_engine(const ET2&) [with ET2 = ET2; typename std::enable_if<(is_engine_v<ET2> && is_convertible_v<typename ET2::value_type, T>), bool>::type <anonymous> = <anonymous>; T = double; long int N = 3]’
[build]    45 |     constexpr fs_vector_engine(ET2 const& src);
[build]       |               ^~~~~~~~~~~~~~~~
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/fixed_size_vector_engine.hpp:45:15: note:   template argument deduction/substitution failed:
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/fixed_size_vector_engine.hpp:44:88: error: no type named ‘type’ in ‘struct std::enable_if<false, bool>’
[build]    44 |     template<class ET2, detail::enable_if_engine_has_convertible_element_type<ET2,T> = true>
[build]       |                                                                                        ^~~~
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/fixed_size_vector_engine.hpp:43:15: note: candidate: ‘template<class T2, long int N2> constexpr std::math::fs_vector_engine<T, N>::fs_vector_engine(const std::math::fs_vector_engine<T2, N2>&) [with T2 = T2; long int N2 = N2; T = double; long int N = 3]’
[build]    43 |     constexpr fs_vector_engine(fs_vector_engine<T2, N2> const& src);
[build]       |               ^~~~~~~~~~~~~~~~
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/fixed_size_vector_engine.hpp:43:15: note:   template argument deduction/substitution failed:
[build] In file included from /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra.hpp:100,
[build]                  from ../../example/linear_algebra.cpp:27:
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/vector.hpp:236:18: note:   ‘std::initializer_list<std::math::vector<std::math::fs_vector_engine<double, 3>, std::math::matrix_operation_traits> >’ is not derived from ‘const std::math::fs_vector_engine<T, N>’
[build]   236 | :   m_engine(list)
[build]       |                  ^
[build] In file included from /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra.hpp:93,
[build]                  from ../../example/linear_algebra.cpp:27:
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/fixed_size_vector_engine.hpp:41:15: note: candidate: ‘constexpr std::math::fs_vector_engine<T, N>::fs_vector_engine(const std::math::fs_vector_engine<T, N>&) [with T = double; long int N = 3]’
[build]    41 |     constexpr fs_vector_engine(const fs_vector_engine&) = default;
[build]       |               ^~~~~~~~~~~~~~~~
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/fixed_size_vector_engine.hpp:41:32: note:   no known conversion for argument 1 from ‘std::initializer_list<std::math::vector<std::math::fs_vector_engine<double, 3>, std::math::matrix_operation_traits> >’ to ‘const std::math::fs_vector_engine<double, 3>&’
[build]    41 |     constexpr fs_vector_engine(const fs_vector_engine&) = default;
[build]       |                                ^~~~~~~~~~~~~~~~~~~~~~~
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/fixed_size_vector_engine.hpp:40:15: note: candidate: ‘constexpr std::math::fs_vector_engine<T, N>::fs_vector_engine(std::math::fs_vector_engine<T, N>&&) [with T = double; long int N = 3]’
[build]    40 |     constexpr fs_vector_engine(fs_vector_engine&&) noexcept = default;
[build]       |               ^~~~~~~~~~~~~~~~
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/fixed_size_vector_engine.hpp:40:32: note:   no known conversion for argument 1 from ‘std::initializer_list<std::math::vector<std::math::fs_vector_engine<double, 3>, std::math::matrix_operation_traits> >’ to ‘std::math::fs_vector_engine<double, 3>&&’
[build]    40 |     constexpr fs_vector_engine(fs_vector_engine&&) noexcept = default;
[build]       |                                ^~~~~~~~~~~~~~~~~~
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/fixed_size_vector_engine.hpp:98:1: note: candidate: ‘constexpr std::math::fs_vector_engine<T, N>::fs_vector_engine() [with T = double; long int N = 3]’
[build]    98 | fs_vector_engine<T,N>::fs_vector_engine()
[build]       | ^~~~~~~~~~~~~~~~~~~~~
[build] /home/mpusz/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/8fd2aef8c9b0fa1372485045003b8f6288f6e0c7/include/linear_algebra/fixed_size_vector_engine.hpp:98:1: note:   candidate expects 0 arguments, 1 provided

Do not use `static_assert()` to prevent template instantation errors

Using static_assert() allows great error messages but is a really bad solution for verification of a template instantiation. It does not SFINAE and is harmless to overload resolution.

For example, I just obtained the following error message:

[build] /home/mpusz/.conan2/p/wg21-711143a21ed44/p/include/linear_algebra/op_traits_multiplication.hpp: In instantiation of ‘struct std::experimental::math::detail::multiplication_engine_traits<void, std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major> >’:
[build] /home/mpusz/.conan2/p/wg21-711143a21ed44/p/include/linear_algebra/op_traits_multiplication.hpp:309:24:   required from ‘struct std::experimental::math::detail::multiplication_arithmetic_traits<void, std::experimental::math::matrix<std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, void>, std::experimental::math::matrix<std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, void> >’
[build] /home/mpusz/.conan2/p/wg21-711143a21ed44/p/include/linear_algebra/arithmetic_operators.hpp:60:32:   required from ‘constexpr auto std::experimental::math::operator*(const matrix<ET1, COT1>&, const matrix<ET2, COT2>&) [with ET1 = matrix_storage_engine<int, 3, 1, void, matrix_layout::column_major>; COT1 = void; ET2 = matrix_storage_engine<int, 3, 1, void, matrix_layout::column_major>; COT2 = void]’
[build] /usr/include/c++/12/bits/stl_function.h:286:37:   required by substitution of ‘template<class _Tp, class _Up> constexpr decltype ((forward<_Tp>(__t) * forward<_Up>(__u))) std::multiplies<void>::operator()(_Tp&&, _Up&&) const [with _Tp = std::experimental::math::matrix<std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, void>; _Up = std::experimental::math::matrix<std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, void>]’
[build] /usr/include/c++/12/type_traits:2565:26:   required by substitution of ‘template<class _Fn, class ... _Args> static std::__result_of_success<decltype (declval<_Fn>()((declval<_Args>)()...)), std::__invoke_other> std::__result_of_other_impl::_S_test(int) [with _Fn = std::multiplies<void>; _Args = {std::experimental::math::matrix<std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, void>, std::experimental::math::matrix<std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, void>}]’
[build] /usr/include/c++/12/type_traits:2576:55:   required from ‘struct std::__result_of_impl<false, false, std::multiplies<void>, std::experimental::math::matrix<std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, void>, std::experimental::math::matrix<std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, void> >’
[build] /usr/include/c++/12/type_traits:3038:12:   recursively required by substitution of ‘template<class _Result, class _Ret> struct std::__is_invocable_impl<_Result, _Ret, true, std::__void_t<typename _CTp::type> > [with _Result = std::__invoke_result<std::multiplies<void>, std::experimental::math::matrix<std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, void>, std::experimental::math::matrix<std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, void> >; _Ret = void]’
[build] /usr/include/c++/12/type_traits:3038:12:   required from ‘struct std::is_invocable<std::multiplies<void>, std::experimental::math::matrix<std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, void>, std::experimental::math::matrix<std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, void> >’
[build] /usr/include/c++/12/type_traits:3286:71:   required from ‘constexpr const bool std::is_invocable_v<std::multiplies<void>, std::experimental::math::matrix<std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, void>, std::experimental::math::matrix<std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, void> >’
[build] /usr/include/c++/12/concepts:336:25:   required by substitution of ‘template<class Q>  requires (Quantity<Q>) && (InvokeResultOf<(mp_units::quantity<R, Rep>::quantity_spec * (Q::quantity_spec)).character, std::multiplies<void>, Rep, typename Q::rep>) constexpr auto [requires mp_units::Quantity<<placeholder>, >] mp_units::operator*(const quantity<reference<isq::position_vector(), si::metre()>(), std::experimental::math::matrix<std::experimental::math::matrix_storage_engine<int, 3, 1, void, std::experimental::math::matrix_layout::column_major>, void> >&, const Q&) [with Q = mp_units::reference<mp_units::isq::position_vector(), mp_units::si::metre()>()]’
[build] ../../example/linear_algebra.cpp:103:34:   required from here
[build] /home/mpusz/.conan2/p/wg21-711143a21ed44/p/include/linear_algebra/op_traits_multiplication.hpp:171:61: error: static assertion failed: mis-matched/invalid number of rows and columns for multiplication
[build]   171 |     static_assert((C1 == R2  ||  C1 == std::dynamic_extent  ||  R2 == std::dynamic_extent),
[build]       |                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

After commenting out the static_assert() in op_traits_multiplication.hpp, my code compiled fine because a better overload was found.

Use concepts instead to prevent instantiations of types like multiplication_engine_traits.

Update to use mdspan (not basic_mdspan)

The specification of mdspan has been updated to remove the basic_mdspan identifier in favor of the mdspan. Because of this we've had to pin to an earlier version of the mdspan repo here:

FetchContent_Declare(mdspan GIT_REPOSITORY https://github.com/kokkos/mdspan.git GIT_TAG 9d1acac543053cbe6839273f550b1ece218e9696)

But this was only intended as a temporary work around, and required updating the source to address. All usage of MDspan should be updated the change merged to active branched (r7y)

`constexpr` all the things

LA operators are not constexpr for statically known bounds (literal types). The following code fails to compile:

template<Unit U = si::metre>
using v_length = fs_vector<si::length<U>, 3>;

static_assert(v_length<>{ 1q_m, 2q_m, 3q_m } + v_length<>{ 3q_m, 2q_m, 1q_m } == v_length<>{ 4q_m, 4q_m, 4q_m });

Error in the converting constructor

When I uncomment the following lines: https://github.com/mpusz/units/blob/master/example/linear_algebra.cpp#L132-L133 I get the following compilation error for the latest version of 0.6.0 on Conan:

[build] /home/mpusz/.conan/data/linear_algebra/0.0.1/public-conan/testing/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/linear_algebra/matrix.hpp: In instantiation of ‘constexpr std::experimental::math::matrix<ET, OT>::matrix(const std::experimental::math::matrix<ET2, OT2>&) [with ET2 = std::experimental::math::fs_matrix_engine<units::quantity<units::si::dim_length, units::si::metre, double>, 3, 3>; OT2 = std::experimental::math::matrix_operation_traits; ET = std::experimental::math::fs_matrix_engine<units::quantity<units::si::dim_length, units::si::millimetre, double>, 3, 3>; OT = std::experimental::math::matrix_operation_traits]’:
[build] ../../example/linear_algebra.cpp:132:51:   required from here
[build] /home/mpusz/.conan/data/linear_algebra/0.0.1/public-conan/testing/package/5ab84d6acfe1f23c4fae0ab88f26e3a396351ac9/include/linear_algebra/matrix.hpp:167:11: error: ‘assign’ was not declared in this scope; did you mean ‘asin’?
[build]   167 |     assign(rhs);
[build]       |     ~~~~~~^~~~~
[build]       |     asin

The problem is here:
https://github.com/BobSteagall/wg21/blob/la_r6/linear_algebra/code/include/linear_algebra/matrix.hpp#L167

It seems that there is no implementation of assign() in the case when ET2 and OT2 are different than ET and OT.

cmake fails on windows 10

Using the cmake gui version 3.15.3, I get the following errors during configuration:

Selecting Windows SDK version 10.0.17763.0 to target Windows 10.0.18363.
Microsoft (R) Build Engine version 16.4.0+e901037fe for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.

Checking Build System
Performing download step (git clone) for 'mdspan-populate'
Cloning into 'mdspan-src'...
fatal: unable to access 'https://github.com/kokkos/mdspan.git/': error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
Cloning into 'mdspan-src'...
fatal: unable to access 'https://github.com/kokkos/mdspan.git/': error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
Cloning into 'mdspan-src'...
fatal: unable to access 'https://github.com/kokkos/mdspan.git/': error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version
-- Had to git clone more than once:
CMake Error at mdspan-subbuild/mdspan-populate-prefix/tmp/mdspan-populate-gitclone.cmake:31 (message):
3 times.
Failed to clone repository: 'https://github.com/kokkos/mdspan.git'

C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(231,5): error MSB6006: "cmd.exe" exited with code 1. [C:\temp\Projects\cpp_standard_linear_algebra_deps\mdspan-subbuild\mdspan-populate.vcxproj]

CMake Error at C:/Program Files/CMake/share/cmake-3.15/Modules/FetchContent.cmake:915 (message):
Build step for mdspan failed: 1
Call Stack (most recent call first):
C:/Program Files/CMake/share/cmake-3.15/Modules/FetchContent.cmake:1006 (__FetchContent_directPopulate)
CMakeLists.txt:13 (FetchContent_Populate)

size_tuple vs extents

Back already(!)

My second trivial program is

#include <linear_algebra.hpp>
#include <iostream>
#include <tuple>

int main()
{
        STD_LA::fs_matrix<double, 3, 3> R{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
        STD_LA::fs_vector<double, 3> v{{1, 2, 3}};
        auto x = R * v;
        std::cout << R(1,2) << '\n';
        std::cout << x(2) << '\n';
        std::cout << std::get<0>(R.size()) << '\n';
}

The aim is simply, given a matrix R, how do I find out the number of columns / rows.

According to P1385R7.md

    using size_tuple      = tuple<size_type, size_type>;
    constexpr size_tuple    size() const noexcept;

so I would expect R.size() to return a tuple<size_type,size_type>, and get<0> to return the first size_type.

This fails to compile with g++ 10.3.0:

c++  -O2 -fPIE -g -Werror -std=c++20     -I/usr/src/local/mdspan/include -I/usr/src/local/wg21/include  -c    wg21test.cc
wg21test.cc: In function ‘int main()’:
wg21test.cc:12:35: error: no matching function for call to ‘get<0>(std::math::matrix<std::math::fs_matrix_engine<double, 3, 3>, std::math::matrix_operation_traits>::index_tuple)’
   12 |  std::cout << std::get<0>(R.size()) << '\n';
      |                                   ^
...
/usr/src/local/mdspan/include/experimental/__p0009_bits/extents.hpp:206:3: note: candidate: ‘template<class IndexType>  requires  is_convertible_v<IndexType, std::experimental::extents<Extents ...>::index_type> constexpr std::experimental::extents<Extents>::extents(const std::array<IndexType, std::experimental::extents<Extents>::rank_dynamic()>&) [with IndexType = IndexType; long int ...Extents = {3, 3}]’
  206 |   extents(std::array<IndexType, rank_dynamic()> const& dyn) noexcept
      |   ^~~~~~~

As per #68, this is head wg21, and now 51b291a mdspan.

Have I maybe hit the R5 Feedback to do item

+ Use `extents` instead of `size_tuple`.

or am I missing something?

multiply operations on scalars should be constrained

re compatability with units library ( and indeed other libraries)

https://github.com/mpusz/units

Both units library and la library should constrain operators multiplying by scalars to avoid ambiguous overloads.
LA library should define a scalar concept or use SFINAE version for legacy. Scalar is mentioned barely in the documentation but is an important concept for LA library

See example of the current situation and how to fix

https://godbolt.org/z/K-rWPL

( uncomment one of CONCEPT_CONSTRAINED_S, SFINAE_CONSTRAINED_S ) to get it to work

Below are ( some of) relevant functions

https://github.com/BobSteagall/wg21/blob/master/include/linear_algebra/arithmetic_operators.hpp#L104
https://github.com/BobSteagall/wg21/blob/master/include/linear_algebra/arithmetic_operators.hpp#L116
https://github.com/BobSteagall/wg21/blob/master/include/linear_algebra/arithmetic_operators.hpp#L130
https://github.com/BobSteagall/wg21/blob/master/include/linear_algebra/arithmetic_operators.hpp#L142

(Also incidentally applies to units library) ....

units uses concept but units::Scalar concept is basically Any but quantity. Not really constrained so ambiguous
https://github.com/mpusz/units/blob/master/src/include/units/quantity.h#L325
https://github.com/mpusz/units/blob/master/src/include/units/concepts.h#L292

Currently standard library doesnt have unconstrained binary operators as far as I know

Copy-construction from vectors with different template parameters fails

Compiling the following code:

#include <linear_algebra.hpp>

int main()
{
    auto v = STD_LA::fs_vector<double, 3>{};
    auto u = STD_LA::fs_vector<int, 3>{v};
    auto w = STD_LA::fs_vector<double, 4>{v};
}

Fails with the following error:

[rbrugo@vim ~/test] $ g++ -std=c++2a linear_algebra.cpp 
In file included from /usr/local/include/linear_algebra.hpp:74,
                 from linear_algebra.cpp:1:
/usr/local/include/linear_algebra/vector.hpp: In instantiation of ‘constexpr std::experimental::math::vector<ET, OT>::vector(const std::experimental::math::vector<ET2, OT2>&) [with ET2 = std::experimental::math::fs_vector_engine<double, 3>; OT2 = std::experimental::math::matrix_operation_traits; ET = std::experimental::math::fs_vector_engine<int, 3>; OT = std::experimental::math::matrix_operation_traits]’:
linear_algebra.cpp:6:41:   required from here
/usr/local/include/linear_algebra/vector.hpp:226:26: error: no matching function for call to ‘std::experimental::math::fs_vector_engine<int, 3>::fs_vector_engine(const engine_type&)’
  226 | :   m_engine(rhs.m_engine)
      |                          ^
In file included from /usr/local/include/linear_algebra.hpp:68,
                 from linear_algebra.cpp:1:
/usr/local/include/linear_algebra/fixed_size_engines.hpp:46:15: note: candidate: ‘template<class U> constexpr std::experimental::math::fs_vector_engine<T, N>::fs_vector_engine(std::initializer_list<_Up>)’
   46 |     constexpr fs_vector_engine(initializer_list<U> list);
      |               ^~~~~~~~~~~~~~~~
/usr/local/include/linear_algebra/fixed_size_engines.hpp:46:15: note:   template argument deduction/substitution failed:
In file included from /usr/local/include/linear_algebra.hpp:74,
                 from linear_algebra.cpp:1:
/usr/local/include/linear_algebra/vector.hpp:226:26: note:   ‘std::experimental::math::fs_vector_engine<double, 3>’ is not derived from ‘std::initializer_list<_Tp>’
  226 | :   m_engine(rhs.m_engine)
      |                          ^
In file included from /usr/local/include/linear_algebra.hpp:68,
                 from linear_algebra.cpp:1:
/usr/local/include/linear_algebra/fixed_size_engines.hpp:44:15: note: candidate: ‘constexpr std::experimental::math::fs_vector_engine<T, N>::fs_vector_engine(const std::experimental::math::fs_vector_engine<T, N>&) [with T = int; long unsigned int N = 3]’
   44 |     constexpr fs_vector_engine(fs_vector_engine const&) = default;
      |               ^~~~~~~~~~~~~~~~
/usr/local/include/linear_algebra/fixed_size_engines.hpp:44:32: note:   no known conversion for argument 1 from ‘const engine_type’ {aka ‘const std::experimental::math::fs_vector_engine<double, 3>’} to ‘const std::experimental::math::fs_vector_engine<int, 3>&’
   44 |     constexpr fs_vector_engine(fs_vector_engine const&) = default;
      |                                ^~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/linear_algebra/fixed_size_engines.hpp:43:15: note: candidate: ‘constexpr std::experimental::math::fs_vector_engine<T, N>::fs_vector_engine(std::experimental::math::fs_vector_engine<T, N>&&) [with T = int; long unsigned int N = 3]’
   43 |     constexpr fs_vector_engine(fs_vector_engine&&) noexcept = default;
      |               ^~~~~~~~~~~~~~~~
/usr/local/include/linear_algebra/fixed_size_engines.hpp:43:32: note:   no known conversion for argument 1 from ‘const engine_type’ {aka ‘const std::experimental::math::fs_vector_engine<double, 3>’} to ‘std::experimental::math::fs_vector_engine<int, 3>&&’
   43 |     constexpr fs_vector_engine(fs_vector_engine&&) noexcept = default;
      |                                ^~~~~~~~~~~~~~~~~~
/usr/local/include/linear_algebra/fixed_size_engines.hpp:79:1: note: candidate: ‘constexpr std::experimental::math::fs_vector_engine<T, N>::fs_vector_engine() [with T = int; long unsigned int N = 3]’
   79 | fs_vector_engine<T,N>::fs_vector_engine()
      | ^~~~~~~~~~~~~~~~~~~~~
/usr/local/include/linear_algebra/fixed_size_engines.hpp:79:1: note:   candidate expects 0 arguments, 1 provided
In file included from /usr/local/include/linear_algebra.hpp:74,
                 from linear_algebra.cpp:1:
/usr/local/include/linear_algebra/vector.hpp: In instantiation of ‘constexpr std::experimental::math::vector<ET, OT>::vector(const std::experimental::math::vector<ET2, OT2>&) [with ET2 = std::experimental::math::fs_vector_engine<double, 3>; OT2 = std::experimental::math::matrix_operation_traits; ET = std::experimental::math::fs_vector_engine<double, 4>; OT = std::experimental::math::matrix_operation_traits]’:
linear_algebra.cpp:7:44:   required from here
/usr/local/include/linear_algebra/vector.hpp:226:26: error: no matching function for call to ‘std::experimental::math::fs_vector_engine<double, 4>::fs_vector_engine(const engine_type&)’
  226 | :   m_engine(rhs.m_engine)
      |                          ^
In file included from /usr/local/include/linear_algebra.hpp:68,
                 from linear_algebra.cpp:1:
/usr/local/include/linear_algebra/fixed_size_engines.hpp:46:15: note: candidate: ‘template<class U> constexpr std::experimental::math::fs_vector_engine<T, N>::fs_vector_engine(std::initializer_list<_Up>)’
   46 |     constexpr fs_vector_engine(initializer_list<U> list);
      |               ^~~~~~~~~~~~~~~~
/usr/local/include/linear_algebra/fixed_size_engines.hpp:46:15: note:   template argument deduction/substitution failed:
In file included from /usr/local/include/linear_algebra.hpp:74,
                 from linear_algebra.cpp:1:
/usr/local/include/linear_algebra/vector.hpp:226:26: note:   ‘std::experimental::math::fs_vector_engine<double, 3>’ is not derived from ‘std::initializer_list<_Tp>’
  226 | :   m_engine(rhs.m_engine)
      |                          ^
In file included from /usr/local/include/linear_algebra.hpp:68,
                 from linear_algebra.cpp:1:
/usr/local/include/linear_algebra/fixed_size_engines.hpp:44:15: note: candidate: ‘constexpr std::experimental::math::fs_vector_engine<T, N>::fs_vector_engine(const std::experimental::math::fs_vector_engine<T, N>&) [with T = double; long unsigned int N = 4]’
   44 |     constexpr fs_vector_engine(fs_vector_engine const&) = default;
      |               ^~~~~~~~~~~~~~~~
/usr/local/include/linear_algebra/fixed_size_engines.hpp:44:32: note:   no known conversion for argument 1 from ‘const engine_type’ {aka ‘const std::experimental::math::fs_vector_engine<double, 3>’} to ‘const std::experimental::math::fs_vector_engine<double, 4>&’
   44 |     constexpr fs_vector_engine(fs_vector_engine const&) = default;
      |                                ^~~~~~~~~~~~~~~~~~~~~~~
/usr/local/include/linear_algebra/fixed_size_engines.hpp:43:15: note: candidate: ‘constexpr std::experimental::math::fs_vector_engine<T, N>::fs_vector_engine(std::experimental::math::fs_vector_engine<T, N>&&) [with T = double; long unsigned int N = 4]’
   43 |     constexpr fs_vector_engine(fs_vector_engine&&) noexcept = default;
      |               ^~~~~~~~~~~~~~~~
/usr/local/include/linear_algebra/fixed_size_engines.hpp:43:32: note:   no known conversion for argument 1 from ‘const engine_type’ {aka ‘const std::experimental::math::fs_vector_engine<double, 3>’} to ‘std::experimental::math::fs_vector_engine<double, 4>&&’
   43 |     constexpr fs_vector_engine(fs_vector_engine&&) noexcept = default;
      |                                ^~~~~~~~~~~~~~~~~~
/usr/local/include/linear_algebra/fixed_size_engines.hpp:79:1: note: candidate: ‘constexpr std::experimental::math::fs_vector_engine<T, N>::fs_vector_engine() [with T = double; long unsigned int N = 4]’
   79 | fs_vector_engine<T,N>::fs_vector_engine()
      | ^~~~~~~~~~~~~~~~~~~~~
/usr/local/include/linear_algebra/fixed_size_engines.hpp:79:1: note:   candidate expects 0 arguments, 1 provided

novice usage question

I have a checkout of https://github.com/BobSteagall/wg21.git in /usr/src/local/wg21, and https://github.com/kokkos/mdspan.git in /usr/src/local/mdspan, head from just now. I thought I might start with the staggeringly complex program:

#include <linear_algebra.hpp>

int main() { }

but with g++ 10.3.0, I see:

c++  -O2 -fPIE -g -Werror -std=c++20     -I/usr/src/local/mdspan/include -I/usr/src/local/wg21/include  -c    wg21test.cc
In file included from /usr/src/local/wg21/include/linear_algebra.hpp:62,
                 from wg21test.cc:1:
/usr/src/local/wg21/include/linear_algebra/private_support.hpp:276:27: error: ‘basic_mdspan’ was not declared in this scope
  276 | struct extract_span_types<basic_mdspan<T0, X0, L0, A0>, basic_mdspan<T1, X1, L1, A1>>
      |                           ^~~~~~~~~~~~

What am I missing?

Copy constructor with uniform initialization not working

Currently trying to compile this code

#include <linear_algebra.hpp>

int main()
{
    auto v = STD_LA::fs_vector<double, 3>{};
    auto w{v};
}

gives this output:

[rbrugo@vim ~/test] $ g++ -std=c++2a linear_algebra.cpp 
In file included from /usr/local/include/linear_algebra.hpp:42,
                 from linear_algebra.cpp:1:
/usr/local/include/linear_algebra/fixed_size_engines.hpp: In instantiation of ‘constexpr std::experimental::math::fs_vector_engine<T, N>::fs_vector_engine(std::initializer_list<_Up>) [with U = std::experimental::math::vector<std::experimental::math::fs_vector_engine<double, 3>, std::experimental::math::matrix_operation_traits>; T = double; long unsigned int N = 3]’:
/usr/local/include/linear_algebra/vector.hpp:146:48:   required from ‘constexpr std::experimental::math::vector<ET, OT>::vector(std::initializer_list<_Up>) [with U = std::experimental::math::vector<std::experimental::math::fs_vector_engine<double, 3>, std::experimental::math::matrix_operation_traits>; ET = std::experimental::math::fs_vector_engine<double, 3>; OT = std::experimental::math::matrix_operation_traits]’
linear_algebra.cpp:6:13:   required from here
/usr/local/include/linear_algebra/fixed_size_engines.hpp:106:23: error: invalid static_cast from type ‘const std::experimental::math::vector<std::experimental::math::fs_vector_engine<double, 3>, std::experimental::math::matrix_operation_traits>’ to type ‘double’
  106 |         ma_elems[i] = static_cast<T>( *iter);
      |                       ^~~~~~~~~~~~~~~~~~~~~~

It seems that the initializer_list<U> constructor is a bit too greedy; maybe the U the should be constrained or replaced with the value_type?

Can't build version 0.7.0 with conan

Installing linear_algebra with conan fails with the following error:

$ conan install -r linear_algebra linear_algebra/0.7.0@public-conan/testing --build=missing
Configuration:
[settings]
arch=x86_64
arch_build=x86_64
build_type=Release
compiler=gcc
compiler.cppstd=20
compiler.libcxx=libstdc++11
compiler.version=10.2
os=Linux
os_build=Linux
[options]
[build_requires]
[env]

linear_algebra/0.7.0@public-conan/testing: WARN: Package is corrupted, removing folder: /home/rbrugo/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/ce08cfd0c0f8c5c13a09c972c6737a498d5c23fb
Installing package: linear_algebra/0.7.0@public-conan/testing
Requirements
    linear_algebra/0.7.0@public-conan/testing from 'linear_algebra' - Cache
Packages
    linear_algebra/0.7.0@public-conan/testing:ce08cfd0c0f8c5c13a09c972c6737a498d5c23fb - Build

Installing (downloading, building) binaries...
linear_algebra/0.7.0@public-conan/testing: WARN: Build folder is dirty, removing it: /home/rbrugo/.conan/data/linear_algebra/0.7.0/public-conan/testing/build/ce08cfd0c0f8c5c13a09c972c6737a498d5c23fb
linear_algebra/0.7.0@public-conan/testing: Copying sources to build folder
linear_algebra/0.7.0@public-conan/testing: Building your package in /home/rbrugo/.conan/data/linear_algebra/0.7.0/public-conan/testing/build/ce08cfd0c0f8c5c13a09c972c6737a498d5c23fb
linear_algebra/0.7.0@public-conan/testing: Generator cmake created conanbuildinfo.cmake
linear_algebra/0.7.0@public-conan/testing: Calling build()
-- The C compiler identification is GNU 10.2.0
-- The CXX compiler identification is GNU 10.2.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Conan: called by CMake conan helper
-- Conan: called inside local cache
-- Conan: Adjusting output directories
-- Conan: Using cmake global configuration
-- Conan: Adjusting default RPATHs Conan policies
-- Conan: Adjusting language standard
-- Conan setting CPP STANDARD: 20 WITH EXTENSIONS OFF
-- Conan: Compiler GCC>=5, checking major version 10.2
-- Conan: Checking correct version: 10.2
-- Conan: C++ stdlib: libstdc++11
Scanning dependencies of target mdspan-populate
[ 11%] Creating directories for 'mdspan-populate'
[ 22%] Performing download step (git clone) for 'mdspan-populate'
Cloning into 'mdspan-src'...
fatal: invalid reference: master
CMake Error at mdspan-subbuild/mdspan-populate-prefix/tmp/mdspan-populate-gitclone.cmake:40 (message):
  Failed to checkout tag: 'master'


make[2]: *** [CMakeFiles/mdspan-populate.dir/build.make:111: mdspan-populate-prefix/src/mdspan-populate-stamp/mdspan-populate-download] Error 1
make[1]: *** [CMakeFiles/Makefile2:95: CMakeFiles/mdspan-populate.dir/all] Error 2
make: *** [Makefile:103: all] Error 2

CMake Error at /usr/share/cmake-3.18/Modules/FetchContent.cmake:987 (message):
  Build step for mdspan failed: 2
Call Stack (most recent call first):
  /usr/share/cmake-3.18/Modules/FetchContent.cmake:1082:EVAL:2 (__FetchContent_directPopulate)
  /usr/share/cmake-3.18/Modules/FetchContent.cmake:1082 (cmake_language)
  /usr/share/cmake-3.18/Modules/FetchContent.cmake:1125 (FetchContent_Populate)
  CMakeLists.txt:35 (FetchContent_MakeAvailable)


-- Configuring incomplete, errors occurred!
See also "/home/rbrugo/.conan/data/linear_algebra/0.7.0/public-conan/testing/build/ce08cfd0c0f8c5c13a09c972c6737a498d5c23fb/CMakeFiles/CMakeOutput.log".
linear_algebra/0.7.0@public-conan/testing: 
linear_algebra/0.7.0@public-conan/testing: ERROR: Package 'ce08cfd0c0f8c5c13a09c972c6737a498d5c23fb' build failed
linear_algebra/0.7.0@public-conan/testing: WARN: Build folder /home/rbrugo/.conan/data/linear_algebra/0.7.0/public-conan/testing/build/ce08cfd0c0f8c5c13a09c972c6737a498d5c23fb
ERROR: linear_algebra/0.7.0@public-conan/testing: Error in build() method, line 48
	self.cmake.build()
while calling 'cmake', line 38
	self._cmake.configure()
	ConanException: Error 1 while executing cd '/home/rbrugo/.conan/data/linear_algebra/0.7.0/public-conan/testing/build/ce08cfd0c0f8c5c13a09c972c6737a498d5c23fb' && cmake -G "Unix Makefiles" -DCMAKE_BUILD_TYPE="Release" -DCONAN_CMAKE_CXX_STANDARD="20" -DCONAN_CMAKE_CXX_EXTENSIONS="OFF" -DCONAN_STD_CXX_FLAG="-std=c++2a" -DCONAN_IN_LOCAL_CACHE="ON" -DCONAN_COMPILER="gcc" -DCONAN_COMPILER_VERSION="10.2" -DCONAN_CXX_FLAGS="-m64" -DCONAN_SHARED_LINKER_FLAGS="-m64" -DCONAN_C_FLAGS="-m64" -DCONAN_LIBCXX="libstdc++11" -DCMAKE_INSTALL_PREFIX="/home/rbrugo/.conan/data/linear_algebra/0.7.0/public-conan/testing/package/ce08cfd0c0f8c5c13a09c972c6737a498d5c23fb" -DCMAKE_INSTALL_BINDIR="bin" -DCMAKE_INSTALL_SBINDIR="bin" -DCMAKE_INSTALL_LIBEXECDIR="bin" -DCMAKE_INSTALL_LIBDIR="lib" -DCMAKE_INSTALL_INCLUDEDIR="include" -DCMAKE_INSTALL_OLDINCLUDEDIR="include" -DCMAKE_INSTALL_DATAROOTDIR="share" -DCMAKE_EXPORT_NO_PACKAGE_REGISTRY="ON" -DCONAN_EXPORTED="1" -DLA_BUILD_PACKAGE="True" -DLA_ENABLE_TESTS="False" -Wno-dev '/home/rbrugo/.conan/data/linear_algebra/0.7.0/public-conan/testing/build/ce08cfd0c0f8c5c13a09c972c6737a498d5c23fb'

assignment operator of matrix views

the fact that the assignment operator of matrix views does a shallow copy may come as a surprise to some users who may be used to other linear algebra libraries. i took a look at pre-existing LA libraries and Eigen, Blaze, xtensor, boost::ublas and dlib all do deep assignment. so code like this

#include <cassert>
#include <linear_algebra.hpp>

auto main() -> int {
  std::math::dynamic_matrix<double> m(2, 2);
  m(0, 0) = 1;
  m.column(0) = m.column(1);
  assert(m(0, 0) == 0);
}

is typically expected to modify m, rather than just overwrite the view temporary. we could protect against this specific case by making the copy/move assignment lvalue qualified. which would lead to a compiler error instead of silently doing the wrong thing in this case. but i don't think this is good enough to solve the issue in general, as the same issue would arise in this case

template <typename U, typename V, typename T>
void multiply_by_factor(U &&out, V const &in, T factor) {
  if (factor != 1) { out = factor * in; }
  else { out = in; }
}

where this would fail only if U and V are both views of the same type, and factor is equal to 1, making this potentially difficult to debug.

on the other hand, having copy/move assignment do a deep copy would go against what other stl view types tend to do, as std::string_view and std::span do a shallow copy. and may also potentially inhibit some optimizations since the type would no longer be trivially copyable. so a vector<matrix_view> might be less efficient, but from my experience views tend to be short lived and so this shouldn't matter all that much.

another solution would be to avoid using operator= at all, since it holds a special meaning in c++ that doesn't fit with what a user would expect in all cases. maybe an assign member functions or something like operator<<= would work better, but the syntax would slightly suffer for it.

Add division by a scalar

Right now the library seems to not support the division by a scalar. For example:

fs_vector<si::length<si::metre>, 3> v = { 4q_m, 8q_m, 12q_m };
std::cout << v / 2q_s << "\n";

The expected output would be to print quantities of velocity types.

Multiplication by the inverse value of a scalar really does not work for all cases.

possibility of constructing vectors of matrices with uninitialized dara

dear developers,

i skimmed through the tests and i have the impression that vector and matrices are initialized to zero at construction.

in many cases this initialization is unwanted, as assignement will happen at a later stage.

this is crucial for example if one wants to do first touching on the entries of the vector to ensure numa locality (that's one of the reasons for which std::vector cannot be used in HPC code)

is there any way of avoiding it?

Some early studies of the constraints with the MULTI container library

Hi @BobSteagall and @hatcat ,

I have been testing your reference implementation to use my https://gitlab.com/correaa/boost-multi as a storage engine.

MULTI is a general purpose container of dynamic arrays for arbitrary dimension, focuses only on dense strided memory layouts.
One of the principles of the library is that dimensionality of anything wuth dimension D can be seen also as something of dimension D - 1 of elements of higher dimension; therefore allowing generic programming in multiple dimensions.
It also is agnostic to linear algebra applications.

So, in some aspect is more general than the LA proposal engines (arbitrary dimensionality) and is some aspects it is less ambitious (no linear algebra, no fancy or sparse storage strategies).
The good thing is that I believe the storage and view engine concept should also be independent of the LA operations, so
the intersection of the two projects is the case of D = 2 (and perhaps D = 1).

With this in mind, I added this simple test to verify the constraints and already I find some incompatibilities out of the box (I am using the branch r7z)

#include "test_common.hpp"

#include "linear_algebra/matrix.hpp"

using namespace STD_LA;
using namespace STD_LA::detail;
using namespace MDSPAN_NS;

#include "alf/boost/multi/include/multi/array.hpp"

TEST(MULTI_ENGINE, InitialCheck)
{
	namespace multi = boost::multi;
	STD_LA::matrix< multi::array<double, 2> > v;
}

I get out the box these 3 initial errors which I think can help both improve my library and also the LA proposal, see my comments interleaved:

/home/correaa/prj/wg21/tests/test_multi.cpp: In member function ‘virtual void MULTI_ENGINE_DefaultCtor_Test::TestBody()’:
/home/correaa/prj/wg21/tests/test_multi.cpp:25:49: error: template constraint failure for ‘template<class ET, class COT>  requires (copyable<ET>) && (default_initializable<ET>) && (readable_matrix_engine<ET>) class std::experimental::math::matrix’
   25 |         STD_LA::matrix< multi::array<double, 2> > v;
      |                                                 ^
/home/correaa/prj/wg21/tests/test_multi.cpp:25:49: note: constraints not satisfied
In file included from /home/correaa/prj/wg21/include/matrix:144,
                 from /home/correaa/prj/wg21/tests/test_common.hpp:10,
                 from /home/correaa/prj/wg21/tests/test_multi.cpp:1:
/home/correaa/prj/wg21/include/linear_algebra/engine_support.hpp: In substitution of ‘template<class ET, class COT>  requires (copyable<ET>) && (default_initializable<ET>) && (readable_matrix_engine<ET>) class std::experimental::math::matrix [with ET = boost::multi::array<double, 2>; COT = void]’:
/home/correaa/prj/wg21/tests/test_multi.cpp:25:42:   required from here
/home/correaa/prj/wg21/include/linear_algebra/engine_support.hpp:590:9:   required for the satisfaction of ‘readable_engine_fundamentals<ET>’ [with ET = boost::multi::array<double, 2, std::allocator<double> >]
/home/correaa/prj/wg21/include/linear_algebra/engine_support.hpp:743:9:   required for the satisfaction of ‘readable_matrix_engine<ET>’ [with ET = boost::multi::array<double, 2, std::allocator<double> >]
/home/correaa/prj/wg21/include/linear_algebra/engine_support.hpp:591:5:   in requirements with ‘const ET& eng’ [with ET = boost::multi::array<double, 2, std::allocator<double> >]
/home/correaa/prj/wg21/include/linear_algebra/engine_support.hpp:597:18: note: nested requirement ‘is_convertible_v<typename ET::reference, typename ET::element_type>’ is not satisfied
  597 |         requires std::is_convertible_v<typename ET::reference, typename ET::element_type>;
      |         ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

ok, my arrays have M2D::reference and M2D::element_type typedefs but you expect a different meaning from them.
We have a common meaning for element_type which is the type of the elements, e.g. scalar.
However in my library, reference is an object of lower dimension, not necessarily a scalar.

multi::array<double, 2> A({10, 5});
// multi::array<double, 2>::element_type is double
// multi::array<double, 2>::reference is not double&, it is multi::basic_array<double, 1, double*>, a reference-like object of dimension 1. 

The logic behind this is that I want to view A as a 1D container of arrays of dimension 1D from the point of view of access and iteration.

For example

multi::array<double, 2>::reference A3 = A[3];
assert( A3.size() == 5 )

My suggestion is that reference is renamed to element_ref or element_reference in the proposal, which I can also add to my library (I already use element_ref, element_cref, element_ptr and element_const_ptr.

(My logic also applies to value_type, multi::array<double, 2>::value_type is precisely multi::array<double, 1>, just to give another example. This is consistent because multi::array<double, 2>::reference is convertible to multi::array<double, 2>::value_type)

As far as I see, the engine concept doesn't need to support subviews of views of lower dimension, that is fine, but a clear meaning of "reference" would be helpful.

...
/home/correaa/prj/wg21/include/linear_algebra/engine_support.hpp:598:18: note: nested requirement ‘is_convertible_v<typename ET::const_reference, typename ET::element_type>’ is not satisfied
  598 |         requires std::is_convertible_v<typename ET::const_reference, typename ET::element_type>;
      |         ~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Same argument for const_reference, I suggest to rename it to element_const_reference or element_cref.

...
/home/correaa/prj/wg21/include/linear_algebra/engine_support.hpp:600:23: note: the required expression ‘eng.capacity()’ is invalid
  600 |         { eng.capacity() } -> same_as<typename ET::size_type>;
      |           ~~~~~~~~~~~~^~
cc1plus: note: set ‘-fconcepts-diagnostics-depth=’ to at least 2 for more detail
make[2]: *** [tests/CMakeFiles/la_test.dir/build.make:238: tests/CMakeFiles/la_test.dir/test_multi.cpp.o] Error 1
make[1]: *** [CMakeFiles/Makefile2:959: tests/CMakeFiles/la_test.dir/all] Error 2

Due to constraints and tradeoffs that occur in multiple dimensions (in general) I do not support space reservation.
Therefore the concept of capacity, separated from sizes or the number of elements is non-existent.
Of course I could add a trivial capacity function but that will send the message that my library supports space reservation.

More importantly, how does it concern to a LA library if the storage engine supports capacity or space reservation in general?
I understand that resizing may be supported to perform inplace changes in the extensions of the matrices but I think in that case, "resizing" alone is the required operation.

Incidentally, in my library I call it .reextent({nx, ny, ... }), I don't use the word .resize because I don't provide amortized operations like std::vector does and I don't want to give the impression I do. The only virtue of reextent is doing element preservation.

Ok, that is what I have for now.
Let me know if you want to talk about this points, I am available in Slack too.

To illustrate the reference/element problem I have the following code test:

using NDArrays = std::tuple<
	multi::array<double, 1>,
	multi::array<double, 2>,
	multi::array<double, 3>
>;

BOOST_AUTO_TEST_CASE_TEMPLATE(convertibles, NDArray, NDArrays)
{
	static_assert( std::is_convertible_v<typename NDArray::      reference, typename NDArray::value_type> );
	static_assert( std::is_convertible_v<typename NDArray::const_reference, typename NDArray::value_type> );

	static_assert( std::is_same_v<typename NDArray::element_type, typename multi::array<double, 1>::value_type>);
	static_assert( std::is_same_v<typename NDArray::element_ref , typename multi::array<double, 1>::reference >);

	using NDRef = typename NDArray::ref;

	static_assert( std::is_convertible_v<NDRef, NDArray> );

	static_assert( std::is_convertible_v<typename NDRef::      reference, typename NDRef::value_type> );
	static_assert( std::is_convertible_v<typename NDRef::const_reference, typename NDRef::value_type> );

	static_assert( std::is_same_v<typename NDRef::element_type, typename multi::array<double, 1>::value_type> );
	static_assert( std::is_same_v<typename NDRef::element_ref , typename multi::array<double, 1>::reference > );
}

also available here: https://gitlab.com/correaa/boost-multi/-/blob/master/test/concepts.cpp

is this proposal still on track for c++23?

Just to clarify, i think that the proposed library would be extremely useful, and i am really hoping it will be envtually standardized...just wanted to know if this is still being considered in the standardization process.

Novel `std` definitions

Reading paragraph 1 of [namespace.std], one might conclude that any program using this library is undefined:

Unless otherwise specified, the behavior of a C++ program is undefined if it adds declarations or definitions to namespace std or to a namespace within namespace std.

That looks a lot like what this line does, for instance.

In practice, the code is likely to work just fine. However, it might put people off trying out the library knowing that there is technically no way of using it in a standards-compliant program.

Migrate CI From Travis.Org By 31st May 2021

Travis.org has been planning to shut down for some time now: https://discourse.julialang.org/t/reminder-travis-ci-org-shuts-down-on-december-31-2020/47234

Currently, the Travis CI is displaying a notification saying it will close by the end of May. The CI should be migrated to another CI provider. This may be Travis.com, the commercial version of Travis or Github actions.

Note: The current build failure on Travis looks related to this, as it appears the license for Docker has used too many docker images pulls but from what I can see it is using the Travis account for this (note this works under Appveyor currentl)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.