Size: a a a

2020 November 05

JJ

Joshua Jakowlew in pro.cxx
Всем привет, помогите с проблемой. Есть класс, надо реализовать функционал reverse так, чтобы таблица формировалась один раз, и могла вычислять в компайл-тайм. При этом static constexpr поле использовать нельзя, nvcc не позволяет использовать constexpr переменные в коде для gpu

template <std::size_t P>
struct Z
{
   constexpr __host__ __device__ explicit Z(std::size_t x) noexcept:
       x{ x % P }
   {
   }

   [[nodiscard]] static constexpr __host__ __device__ std::size_t reverse(std::size_t x) noexcept
   {
       // https://e-maxx.ru/algo/reverse_element
       constexpr auto r = []{
           std::array<std::size_t, P> r{};
           r[0] = 0;
           r[1] = 1;
           for (std::size_t i = 2; i < P; ++i)
               r[i] = (P - (P / i) * r[P % i] % P) % P;
           return r;
       }();
           
       return r[x];
   }

   std::size_t x{};
};
источник

D

Danya in pro.cxx
Joshua Jakowlew
Всем привет, помогите с проблемой. Есть класс, надо реализовать функционал reverse так, чтобы таблица формировалась один раз, и могла вычислять в компайл-тайм. При этом static constexpr поле использовать нельзя, nvcc не позволяет использовать constexpr переменные в коде для gpu

template <std::size_t P>
struct Z
{
   constexpr __host__ __device__ explicit Z(std::size_t x) noexcept:
       x{ x % P }
   {
   }

   [[nodiscard]] static constexpr __host__ __device__ std::size_t reverse(std::size_t x) noexcept
   {
       // https://e-maxx.ru/algo/reverse_element
       constexpr auto r = []{
           std::array<std::size_t, P> r{};
           r[0] = 0;
           r[1] = 1;
           for (std::size_t i = 2; i < P; ++i)
               r[i] = (P - (P / i) * r[P % i] % P) % P;
           return r;
       }();
           
       return r[x];
   }

   std::size_t x{};
};
А если здесь constexpr поле для хоста, а потом присвоить его в const поле для девайса?
источник

JJ

Joshua Jakowlew in pro.cxx
Сделать два поля, const и constexpr?
источник

D

Danya in pro.cxx
Joshua Jakowlew
Сделать два поля, const и constexpr?
Ага
источник

D

Danya in pro.cxx
const для девайса
источник

JJ

Joshua Jakowlew in pro.cxx
В принципе логично, constexpr код на девайсе один фиг не запустить
источник

JJ

Joshua Jakowlew in pro.cxx
Попробую, отпишусь по результатам, спасибо
источник

DS

Dmitry Sokolov in pro.cxx
Anton Kviatkovskii
Народ, а есть ли какой то профит использовать в этом коде std::string_view вместо const std::string&  ?
struct Foo {
 std::string str;
 std::string_view get_str() const {
   return str;
 }
};
Мне вьюхи обычно симпатичней когда дело доходит до substr всяких, remove prefix/suffix etc. Прям вот иногда хочется даже явных str.view().substr(...) == ...
источник
2020 November 06

JJ

Joshua Jakowlew in pro.cxx
Danya
А если здесь constexpr поле для хоста, а потом присвоить его в const поле для девайса?
Что-то не выходит. Код вот такой:

zp.cuh
namespace detail
{
   template <std::size_t P>
   __device__ std::array<std::size_t, P> rd = []{
       std::array<std::size_t, P> r{};
       r[0] = 0;
       r[1] = 1;
       for (std::size_t i = 2; i < P; ++i)
           r[i] = (P - (P / i) * r[P % i] % P) % P;
       return r;
   }();
} // namespace detail

template <std::size_t P>
class Z
{
private:
   static constexpr std::array<std::size_t, P> r{
       []{
           std::array<std::size_t, P> r{};
           r[0] = 0;
           r[1] = 1;
           for (std::size_t i = 2; i < P; ++i)
               r[i] = (P - (P / i) * r[P % i] % P) % P;
           return r;
       }()
   };
public:
   [[nodiscard]] static constexpr __host__ std::size_t reverse(std::size_t x) noexcept
   {
       return r[x];
   }

   [[nodiscard]] static __device__ std::size_t reverse(std::size_t x) noexcept
   {
       return detail::rd<P>[x];
   }

   template <std::size_t P>
   constexpr __host__ __device__ friend const Z<P> operator + (Z<P> const& lhs, Z<P> const& rhs) noexcept;

   std::size_t x{};
};

template <std::size_t P>
constexpr __host__ __device__ const Z<P> operator + (Z<P> const& lhs, Z<P> const& rhs) noexcept
{
   return Z<P>{(lhs.x % P + rhs.x % P) % P};
}


vectorAdd.cu:
int main()
{
constexpr auto z = x + y;
std::cout << z << '\n';
}
источник

JJ

Joshua Jakowlew in pro.cxx
Ошибка:
zp.cuh(106): error: invalid redeclaration of member function "Z<P>::reverse(size_t) noexcept"

"zp.cuh(193): note: attempt to access run-time storage"
источник

JJ

Joshua Jakowlew in pro.cxx
Что не так, оператор сложения же от reverse вообще не зависит никак
источник

ГП

Глеб Пушкарев... in pro.cxx
Привет, кто может подсказать на какой структуре лучше реализовать bimap(мапа где можно бегать по правым и левым значениям, ну левый и правый итераторы и тп), вариант использовать внутри 2 мапы плохой, нужно без лишних аллокаций памяти и время работы должно быть +- как у обычной мапы
источник

ГП

Глеб Пушкарев... in pro.cxx
могу интерфэйс скинуть
источник

JJ

Joshua Jakowlew in pro.cxx
Подкрутил, пофиксил, воткнул условную компиляцию там, где надо - все работает, спасибо, идея оказалась годной
источник

O

Oleksandr in pro.cxx
Глеб Пушкарев
Привет, кто может подсказать на какой структуре лучше реализовать bimap(мапа где можно бегать по правым и левым значениям, ну левый и правый итераторы и тп), вариант использовать внутри 2 мапы плохой, нужно без лишних аллокаций памяти и время работы должно быть +- как у обычной мапы
Буст мультииндекс случайно не то что вы ищете?

https://www.boost.org/doc/libs/1_62_0/libs/multi_index/doc/index.html
источник

ГП

Глеб Пушкарев... in pro.cxx
Oleksandr
Буст мультииндекс случайно не то что вы ищете?

https://www.boost.org/doc/libs/1_62_0/libs/multi_index/doc/index.html
а можно в 2 словах как он работает?
источник

O

Oleksandr in pro.cxx
Глеб Пушкарев
а можно в 2 словах как он работает?
Честно говоря понятия не имею :) Ни разу не пользовался, но в этом чате пару паз эту либу обсуждали.
источник

O

Oleksandr in pro.cxx
Если вдруг нужно с нуля такую структуру сделать - я бы смотрел в сторону:
- хранить данные парами по значению в векторе + две мапы с указателями на ключи и значения + ремап при расширении вектора
- хранить данные парами по указателю на хипе, в векторе + две мапы с указателями
- какая-то своя структура данных на основе самобалансирующегося дерева, где у каждой ноды не два указателя, а четыре, два для ключа и два для значения
источник

ГП

Глеб Пушкарев... in pro.cxx
я пытался сделать что-то вроде left_node и right_node которые хранят сам элемент и ссылку друг на друга и хранил их в сете, но возникла проблема с поиском их в сете, так как есть классы без конструктора копирования(их мувают в мапу), а в дальнейшем когда нам приходит lvalue мы не можем от нее создать node так как ее нельзя скопировать(и помувать естественно тоже иначе исходный обьект испортится)
источник

ГП

Глеб Пушкарев... in pro.cxx
Oleksandr
Если вдруг нужно с нуля такую структуру сделать - я бы смотрел в сторону:
- хранить данные парами по значению в векторе + две мапы с указателями на ключи и значения + ремап при расширении вектора
- хранить данные парами по указателю на хипе, в векторе + две мапы с указателями
- какая-то своя структура данных на основе самобалансирующегося дерева, где у каждой ноды не два указателя, а четыре, два для ключа и два для значения
с парами та же проблема
источник