C++ Logo

STD-PROPOSALS

Advanced search

Subject: Re: [std-proposals] Arbitrary dimensional bittensor extending bitset.
From: Jean-Baptiste Vallon Hoarau (jeanbaptiste.vallon_at_[hidden])
Date: 2020-12-17 17:00:14


Hello,

As Arthur said, i don't really see the need for this in the standard
library.
More generally : there is not as of yet a defacto standard for
multidimensional containers, which is why i don't think we're going to get
mdspan anytime soon. Case in point : a very popular md container library in
the scientific C++ community is the xtensor library, and in it dimensions
are handled in a very different way (one type for static shape, one type
for static rank, one type fully dynamic, everything is flatly iterable)
than the mdspan proposal.
AFAIK nothing has been written on the pros and cons of both approaches.

-Jean-Baptiste

Le mar. 15 déc. 2020 à 01:06, Tony V E via Std-Proposals <
std-proposals_at_[hidden]> a écrit :

> Example code using bittensor might both explain the API and show
> motivation for its existence.
>
>
> Sent from my BlackBerry portable Babbage Device
> *From: *Pablo Ruiz via Std-Proposals
> *Sent: *Monday, December 14, 2020 2:23 PM
> *To: *std-proposals_at_[hidden]
> *Reply To: *std-proposals_at_[hidden]
> *Cc: *Pablo Ruiz
> *Subject: *[std-proposals] Arbitrary dimensional bittensor extending
> bitset.
>
> Hi everyone,
>
> These past days I have been playing with some bit manipulation by using
> the c++20 std and extending from it.
> What I have found is the nice templated class std::bitset<N> and the
> utility functions in the numerics library (added in c++20), if there is
> anything more in the standard let me know.
> What I would want to propose is for an extension, you could say a
> generalization, of this std::bitset class to arbitrary dimensions. Namely
> what I have called a bittensor. The idea would be to use the already
> existing std::bitset for storing the data and defining over it an easy to
> use interface for dealing with n-dimensional binary tensors, instead of
> relying in manual bit fiddling (that one should also be able to use) one
> could transform this tensors in a higher-level way, with the same
> performance and size (this would be the ideal).
>
> Here I put a very simple sketch of what I think it should look like:
>
> ___________________________________________________________________________
>
> template<std::size_t... N_i>
> struct bittensor
> {
> std::bitset< (... * N_i) > _data;
> constexpr static std::size_t _dims[] = {N_i ... };
> constexpr bittensor () noexcept {};
> constexpr bittensor (const std::bitset< (... * N_i) >& _val) noexcept
> : _data(_val) {};
> constexpr bittensor (const bittensor< N_i ... >& bt) noexcept :
> _data(bt._data) {};
> template<typename T>
> constexpr bittensor (const T& _val) noexcept
> {_data = std::bitset< (... * N_i) > (_val);}
> //TODO -> specify types of constructor as in bitset or just
> // remain with this general templated constructor that
> // seems to work as expected.
>
> //Now come the operators defined on the class bittensor.
> //Mainly this is a wrapper that just sends the job
> //to the 1d version bitset that we are using as _data.
> constexpr inline bittensor& operator&= (const bittensor& rhs) noexcept
> { _data &= rhs._data; return *this;};
> constexpr inline bittensor& operator|= (const bittensor& rhs) noexcept
> { _data |= rhs._data; return *this;};
> constexpr inline bittensor& operator^= (const bittensor& rhs) noexcept
> { _data ^= rhs._data; return *this;};
> constexpr inline bittensor& operator<<= (std::size_t pos) noexcept {
> _data <<= pos; return *this;};
> constexpr inline bittensor& operator>>= (std::size_t pos) noexcept {
> _data >>= pos; return *this;};
> constexpr inline bittensor operator~() const noexcept { return
> bittensor< N_i ... > (~_data);};
> constexpr inline bittensor operator<< (std::size_t pos) const noexcept
> { return bittensor< N_i ... > (_data << pos);};
> constexpr inline bittensor operator>> (std::size_t pos) const noexcept
> { return bittensor< N_i ... > (_data >> pos);};
> constexpr inline bool operator== (const bittensor& rhs) const noexcept
> { return _data == rhs._data;};
> constexpr inline bool operator!= (const bittensor& rhs) const noexcept
> { return _data != rhs._data;};
>
> //Bit access, mainly the ones given by the bitset class
> constexpr inline bool operator[] (std::size_t pos) const noexcept {
> return _data[pos];};
> constexpr inline std::size_t count () const noexcept { return
> _data.count();};
> constexpr inline std::size_t size () const noexcept { return
> _data.size();};
> constexpr inline bool test (std::size_t pos) const { return
> _data.test(pos);};
> constexpr inline bool any () const noexcept { return _data.any();};
> constexpr inline bool none () const noexcept { return _data.none();};
> constexpr inline bool all () const noexcept { return _data.all();};
>
> //Bit operations, mainly the ones given by the bitset class
> constexpr inline bittensor& set () noexcept { _data.set(); return
> *this;};
> constexpr inline bittensor& set (std::size_t pos, bool val = true) {
> _data.set(pos, val); return *this;};
> constexpr inline bittensor& reset () noexcept { _data.reset(); return
> *this;};
> constexpr inline bittensor& reset (std::size_t pos) {
> _data.reset(pos); return *this;};
> constexpr inline bittensor& flip () noexcept { _data.flip(); return
> *this;};
> constexpr inline bittensor& flip (std::size_t pos) { _data.flip(pos);
> return *this;};
>
> //Type conversions, mainly the ones given by the bitset class
> constexpr inline unsigned long to_ulong () const { return
> _data.to_ulong;};
> constexpr inline unsigned long long to_ullong () const { return
> _data.to_ullong;};
> };
> //non-member functions
> template<std::size_t... N_i>
> bittensor< N_i ... > operator& (const bittensor< N_i ... >& lhs, const
> bittensor< N_i ... >& rhs) noexcept { return bittensor< N_i ... >
> (lhs._data & rhs._data);}
> template<std::size_t... N_i >
> bittensor< N_i ... > operator| (const bittensor< N_i ... >& lhs, const
> bittensor< N_i ... >& rhs) noexcept { return bittensor< N_i ... >
> (lhs._data | rhs._data);}
> template<std::size_t... N_i >
> bittensor< N_i ... > operator^ (const bittensor< N_i ... >& lhs, const
> bittensor< N_i ... >& rhs) noexcept { return bittensor< N_i ... >
> (lhs._data ^ rhs._data);}
> //And now come the iostream inserters and extractors for printing _data
> (for the moment) to a certain stream
> template<class charT, class traits, std::size_t... N_i>
> std::basic_istream<charT, traits>& operator>> (std::basic_istream<charT,
> traits>& is, bittensor< N_i ... >& rhs) { is >> rhs._data; return is;}
> template<class charT, class traits, std::size_t... N_i>
> std::basic_ostream<charT, traits>& operator<< (std::basic_ostream<charT,
> traits>& os, const bittensor< N_i ... >& rhs) { os << rhs._data; return os;}
>
> //Add hashing support (based on the one given by bitset)
> namespace std
> {
> template<std::size_t... N_i>
> struct hash<bittensor< N_i ... >>
> {
> hash () noexcept {};
> size_t operator() (const bittensor< N_i ... >& bt) const noexcept
> { return hash< std::bitset< (... * N_i) > > ()(bt._data);}
> };
> template<>
> struct hash<bittensor<0>>
> {
> hash () noexcept {};
> size_t operator() (const bittensor<0>& bt) const noexcept {return
> static_cast<size_t> (bt[0]);}
> };
> }
>
>
> ___________________________________________________________________________
>
> This is far from something really useful but I thought it may help to
> introduce more explicitly the idea I have in mind. I hope there are not
> much mistakes in the code (which compiles well in g++-10 as a .h file) and
> to receive your thoughts about this extension of the std::bitset. I think
> that it c++ wants to incorporate more math libraries into its standard (as
> it seems to be doing) incorporating something like this is a must (look at
> the numpy arrays for the python case for instance). And something that we
> may further extend by templating on the 1d data structure (here
> std::bitset) to an arbitrary vector-space-like structure, but this seems to
> be a really harder project.
>
>
> Regards,
>
>
> Pablo Ruiz.
>
>
>
>
>
>
>
>
> --
> Std-Proposals mailing list
> Std-Proposals_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-proposals
>



STD-PROPOSALS list run by std-proposals-owner@lists.isocpp.org

Standard Proposals Archives on Google Groups