LINUX.ORG.RU

Как создать в константной памяти CUDA объект с нетривиальным конструктором?

 


1

2

В документации сказано что этого делать нельзя (бол-мен понятно почему). Мне нужно сделать глобальными объект с общими параметрами, некоторые из этих параметров имеют нетривиальные конструкторы по умолчанию (но тривиальные конструкторы копирования). В других местах эти конструкторы нужны (например при создании сразу матрицу сделать единичной), так что совсем их убрать не выйдет, или придется как то очень изгаляться с наследованием и еще черти чем.

При создании в константной памяти карты эти конструкторы можно не вызывать - все равно объект создается на CPU и потом копируется на карту байт в байт.

Единственное что в голову приходит - выделить на карте константный массив char нужного размера, скопировать в него объект с хоста и потом на карте каждый раз кастовать указатель. Выглядит костыльно, м.б. есть какой то более Ъ вариант?

★★★★★

Последнее исправление: AntonI (всего исправлений: 1)

Им дали видеокарты числа массивами дробить, а они на них объекты с конструкторами-шмонструкторами давай пихать… Зачем?

t184256 ★★★★★
()
Ответ на: комментарий от t184256
template <int D, typename T=float> struct Matrix{
   T p[D*D];
   Matrix(){ /* тут мы по умолчанию делаем матрицу единичной. Это много где используется, но в __constant__ памяти такой объект разместить нельзя */  }
};

struct GlobalParams{
   Matrix<3> rotate;  // вот это в __constant__ не влезет, потому что нетривиальный конструктор
};

один из примеров.

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI
template <int D, typename T=float> struct MatrixData{
   T p[D*D]; /* lives on the GPU */
};

template <int D, typename T=float> struct Matrix{
   MatrixData data;
   WhateverOther stuff; /* doesn't */
   Matrix(){ /* sure doesn't */  }
};
t184256 ★★★★★
()
Ответ на: комментарий от t184256

Не-а, не выйдет. Мне c матрицей которая в константной памяти всякие вещи надо делать - умножать, складывать и тд. Для матрицы перегружено 100500 операций, ты всерьез предлагаешь увеличить их число втрое?!

Есть отлаженный код, он не должен меняться от того что какие то задействованные переменные ушли вдруг в константную память GPU

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI

Для матрицы перегружено 100500 операций, ты всерьез предлагаешь увеличить их число втрое?!

Где?

Я вообще предлагаю переписать все по человечески на cupy (или что там в 2021) и удивиться отрицательной полезности ручной оптимизации, но ты уже сильно глубоко застрял в чем-то не том.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

Где?

Включи воображение, наверное я матрицу не просто так создавал что бы положить туда унылый массив из флотов? Если их (операции) вешать на твою MatrixData, то посыпется вся алгебра скорее всего. Наверное это можно отладить, но я не хочу этим заниматься.

переписать все по человечески на cupy

Уже смешно.

ты уже сильно глубоко застрял в чем-то не том.

Мдя… не уподобляйся лоровской школоте, которая свой манямирок пытается экстраполировать на весь подлунный мир;-)

AntonI ★★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: комментарий от AntonI

Если их (операции) вешать на твою MatrixData,

Не для того я выделил отдельно MatrixData, чтобы ты напрямую на нее операции вешал.

не уподобляйся лоровской школоте, которая свой манямирок пытается экстраполировать на весь подлунный мир;-)

Заметь, я чинно ждал, пока разговор не дойдет о моих предложениях и какой-то дичи, три коммента терпел =D

t184256 ★★★★★
()
Последнее исправление: t184256 (всего исправлений: 1)
Ответ на: комментарий от t184256

Не для того я выделил отдельно MatrixData, чтобы ты напрямую на нее операции вешал.

В любом случае, операции придется вешать на родительский класс а конструкторы на наследника. Я не знаю насколько это Ъ, выглядит еще более костыльно чем приведение пойнтера.

Можно конечно сказать что у нас вообще нет конструкторов а есть только порождающие функции. Это по своему логично, но придется перелопачивать много кода что бы убрать оттуда конструкторы.

Заметь, я чинно ждал, пока разговор не дойдет о моих предложениях и какой-то дичи, три коммента терпел =D

Я неимоверно горжусь твоей выдержкой, надо будет взять у тебя автограф;-)))

AntonI ★★★★★
() автор топика
Ответ на: комментарий от AntonI

В любом случае, операции придется вешать на родительский класс а конструкторы на наследника. Я не знаю насколько это Ъ, выглядит еще более костыльно чем приведение пойнтера.

А вот нельзя как я написал, чтобы у инкапсулятора был инициализирующий инкапсулянта как надо конструктор, а у инкапсулянта ничего не было и был он тупой struct?

t184256 ★★★★★
()
Ответ на: комментарий от t184256

А как тогда с инкапсулянтом работать? Кастовать его каждый раз? Зачем он вообще такой нужен?

Смотри, вот есть такой код:

struct GlobalParams{
   Matrix<...> M;
   ...
};
...

GlobalParams gp;
...
 ... gp.M*a ...
...

Все отлажено и работает. Теперь gp уехал в константную память, а Matrix<...> M превратился в MatrixData<...> M.

Во что должно превратиться gp.M*a?

AntonI ★★★★★
() автор топика
Ответ на: комментарий от AntonI

А как тогда с инкапсулянтом работать?

Через инкапсулятор онли.

Зачем он вообще такой нужен?

Чтоб видно было, кто на GPU, а кто нет.

Теперь gp уехал в константную память, а Matrix<…> M превратился в MatrixData<…> M.

В MatrixConst<...> поверх MatrixDataConst<...> же.

Во что должно превратиться gp.M*a?

Ясно, понял, утроение вижу. Да, так придется поверх куды что-то нормальное изобретать.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

Чтоб видно было, кто на GPU, а кто нет.

Так я как раз не хочу этого видеть;-)

Я сейчас только начал с cuda работать и с удивлением обнаружил что большая часть моих библиотек собирается nvcc as is, только спецификаторы host/device надо расставить через макросы. Это очень хорошо, в идеале мне бы хотелось писать код который одинаково компилится и на CPU и на GPU. Но вот эти пляски с константной памятью…

AntonI ★★★★★
() автор топика
Ответ на: комментарий от thunar

Так тоже можно, это уже синтаксический сахар. Проблема в том как объект в конст памяти разместить…

AntonI ★★★★★
() автор топика
Ответ на: комментарий от AntonI

Проблема в том как объект в конст памяти разместить…

Так создать все константные объекты (данные объектов) на хосте, а потом скопировать оттдуа в конст-память. А на gpu переинициализировать сами объекты соответствующими указателями на конст-память (через соответствующий синтаксический сахар). Весь смысл конст-памяти в том что она заполняется извне и со стороны вычислительных ядер никак не меняется и, соответственно, её гарантированно можно закешировать.

thunar ★★★★★
()
Последнее исправление: thunar (всего исправлений: 4)
Ответ на: комментарий от thunar

Так создать все константные объекты (данные объектов) на хосте, а потом скопировать оттдуа в конст-память.

Так тока так и можно сделать. Но вопрос в том как конст память выделить - я пока вижу только вариант с массивом char[sizeof(GlobalParams)].

Еще сейчас вылез косяк, у меня в глоб.параметрах используются указатели на другие глобальные параметры. Тут придется или на хосте химичить (считать какие будут адреса в конст памяти), или вообще немного архитектуру менять…

AntonI ★★★★★
() автор топика

Осиль C++. Хочешь использовать языковую семантику - используешь её. Работает это примерно как constinit. В интернете написано как её получить и заполнить что-то единичками. Это, конечно, не си с классами и тут минимально думать нужно, но всё же.

Единственное что в голову приходит - выделить на карте константный массив char нужного размера, скопировать в него объект с хоста и потом на карте каждый раз кастовать указатель. Выглядит костыльно, м.б. есть какой то более Ъ вариант?

Пример из мануала? Есть api, которым можно рулить памятью. Это совершенно ортогональные механизмы существующие вне языка. Никаким костылём не являются и не могут быть решением.

Решение в рамках языка я дал. Нужно осилить тот язык на котором пытаешься писать, а не сидеть на си с классами и жаловаться «я не знаю как через язык решить проблему».

nonedi18
()
Ответ на: комментарий от AntonI

Откуда ты взял эту «константную память»? Если у тебя что-то там собирается из си с классами скалярной лапши и ты считаешь это «работает», то никакая «константная память» тебе не поможет. Не используй - всё будет работать. В любом случае, чтобы получить производительность какую-нибудь всю эту лапшу нужно выкидывать, либо заменять на блобы от нвидии.

nonedi18
()
Ответ на: комментарий от t184256

Я вообще предлагаю переписать все по человечески на cupy (или что там в 2021) и удивиться отрицательной полезности ручной оптимизации

Эти куллстори. Эта вера. Бедные идиоты вокруг, которые руками оптимизируют. Бедны идиоты в нвидии, которые держат всю индустрию на своих блобах руками оптимизированных.

Да, именно так это и работает. cupy и погнал. Жаль в нвидии до этого не додумались. Срочно сообщи им об этом.

nonedi18
()
Ответ на: комментарий от nonedi18

Тебе смешно, а я, мысленно готовясь пожертвовать 30% производительности в угоду читаемости, при переходе от numba к cupy огреб +100500. И это ещё cupy совсем чахлый тогда был.

t184256 ★★★★★
()
Ответ на: комментарий от nonedi18

Это, конечно, не си с классами и тут минимально думать нужно, но всё же.

Золотые слова.

А если бы при зачатии и «развитии» плюсов можно было думать неминимально, вообще мог бы нормальный язык получиться.

t184256 ★★★★★
()
Ответ на: комментарий от t184256

Никаких +30% там не будет. Это фантазии. Кто тому же 30% от 100500 - это 30000 и уже не так мало. Это у тебя там будут 30%.

В любом случае никакая нумба-хренумба тебе не поможет. Никакое скалярное дерьмо не может работать быстро. Неважно на чём оно у тебя написано. Тебе так же руками его нужно будет адаптировать, либо ты просто используешь блобы готовые.

nonedi18
()
Ответ на: комментарий от t184256

А если бы при зачатии и «развитии» плюсов можно было думать неминимально, вообще мог бы нормальный язык получиться.

Используя настоящие плюсы нужно думать не минимально. Проблема только в том, что думать - это не про здесь. И как следствие «не думать» появилось всё остальное, да и сами си с классами.

C++ это просто случайность, которая зародилась в си с классами. Это совершенно другой язык. Совершенно другой подход. Ничего более нормального, нежели истинный цпп - не существует. В принципе не существует живого языка могущего в полиморфизм, а не в его огрызок. Здесь цпп не с чем сравнивать.

nonedi18
()
Ответ на: комментарий от t184256

А вот и Царь пришел, его неповторимый стиль виден сразу.

@nonedi18, Ромочка, осильте читать и понимать написанное прежде чем советы давать.

AntonI ★★★★★
() автор топика
Ответ на: комментарий от AntonI

Прочитать что? Подробнее. Тебе дали ответ. Ты опять начал оправдываться и нести херню. Вместо этого бы гуглил по ключевому слову, которой я тебе дал и не спрашивал подобной очевидной херни.

nonedi18
()
Ответ на: комментарий от t184256

огреб +100500

Это как? Твои страдания записали на видео, показали на шоу того видеоблогера, и ржали всем интернетом?

pathfinder ★★★★
()
Последнее исправление: pathfinder (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.