Что лучше cuda или opencl
Перейти к содержимому

Что лучше cuda или opencl

  • автор:

В чем различие между OpenGL, DirectX, OpenCL, CUDA?

сразу прошу прощение за очень глупый вопрос, но чем отличается OpenСL от DirectX, OpenGL, CUDA? почему есть сравнение DirectX с OpenGL и OpenCL с CUDA, но нет сравнения допустим OpenCL и DirectX? я догадываюсь что они очень разные, но как я понимаю они все позволяют обращаться к видеокарте и ускорять с помощью нее вычисления. Хотелось бы узнать различие между этими технологиями и что за что отвечает?

Отслеживать
задан 21 апр 2020 в 15:47
Илья Антипанов Илья Антипанов
111 1 1 серебряный знак 9 9 бронзовых знаков
А как вы собираетесь сравнивать сладкое и зелёное?
21 апр 2020 в 16:02

@ArchDemon По идее они не являются «сладким или зеленым», по факту это API для доступа к ресурсам видеокарты. Если бы один обращался к видеокарте, второй к звуковой карте, третий к сетевым параметрам тогда я бы понял что нельзя их сравнивать, но тут все они обращаются к видеокарте и делают на ней просчеты, значит сравнить их можно по скорости работы и применению в разных сферах и где какая технология предпочтительней.

21 апр 2020 в 16:05

Для начала: OpenGL и DirectX предназначены для работы с графикой, а CUDA и OpenCL — для распараллеливания на GPU. Т.е эти внутри этих пар их можно как-то сравнивать, но между — нет.

21 апр 2020 в 16:06

То что сладкое и зелёное принадлежит моему яблоку, ещё не значит эти характеристики можно сравнивать между собой

21 апр 2020 в 16:07

@ArchDemon можно ли с помощью каждой технологии сделать подсчеты с графикой? Если да, то вполне можно сравнить или все таки расписать в чем принципиальное их отличие, где используется одна технология, а где другая. Если обратиться к википедии и сравнить directX и openCL то область применения у них попадает на графику, встает вопрос когда рационально использовать одно а когда другое.

21 апр 2020 в 16:15

1 ответ 1

Сортировка: Сброс на вариант по умолчанию

OpenGL vs DirectX

Это два движка для отрисовки графики.

DirectX — это только для Windows, с C++ и интерфейсами, с закрытым кодом.

OpenGL открытый, есть для многих разных платформ. Внутри код написан в Си стиле.

В принципе любая игра может быть написана на любой из платформ. Да, на них можно сделать расчеты, но неудобно.

OpenCL vs CUDA

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

CUDA — разработка от Nvidia. Закрытые исходники, только для Nvidia. OpenCL — открытое, для разнообразных видеокарт.

Писать на них игры можно, конечно, но эти библиотеки (или это все таки фреймворки?) не предназначены для отрисовки графики.

CUDA vs OpenCL

Решил попробовать CUDA.
Были большие ожидания, мол должен быть клевый язык с фишками, плюшками, интеграцией в VisualStudio.
Но с 2015 где update > 2 не работает, хм, ладно поставил 2013.
Отладка не заработала из коробки ( может ее и нет вообще
И еще был дико возмущен необходимостью писать вот такой код:

__global__ void addKernel(double3 *c, const double3 *a, const double3 *b)

О новое тысячелетие! О космические корабли!((
После этого мираж о суперудобной куде растворился совсем(
Теперь смотрю в сторону брутального OpenCL, уж если брутализировать то шоб прям соусем !

Какие у CUDA нынче плюшки по сравнению с OpenCL?
Пока только одну нашел — студия подсвечивает ошибки в коде
Что еще?

#1
5:59, 12 авг 2016

Куда — это более зрелая технология с достаточно развитым toolchain разработки. Большие научные сообщества как правило предпочитают использовать Куда (не в последнюю очередь ввиду того, что NVIDIA инвестирует в данную технологию и под неё есть вагон библиотек). В OpenCL есть совместимость с устройствами помимо видеокарт NVIDIA и пользоваться ей чуть менее удобно. В целом же, обе технологии очень близки друг к другу. Писать эффективный код и под так, и под другую сложно.

#2
10:15, 12 авг 2016

Arxon
> Какие у CUDA нынче плюшки по сравнению с OpenCL?
Практически никаких 🙂 Возможно может наличие более удобных тулзов. Но Это все спорный момент, для AMD есть CodeXL. С учетом того что возможно новые разработки будут писаться на OpenCL и он на некоторых задачах OpenCL на AMD рвет CUDA на nVidia. Для будущего я бы выбрал OpenCL поддержка всех видеокарт в отличие от nVidia это больший плюс.

#3
12:03, 12 авг 2016

Andrey
> Практически никаких 🙂

Ну да, никаких Tesla в природе не существует. У CUDA R&D поддержка в разы больше, чем у AMD.

> Для будущего я бы выбрал OpenCL поддержка всех видеокарт в отличие от nVidia
> это больший плюс.

CL не только для GPU может быть

#4
12:06, 12 авг 2016

Andrey
> рвет

#5
14:06, 12 авг 2016

CUDA не может компилировать исходники в рантайме, может что-то и добавили, но весьма геморно.
OpenCL не поддерживает перегрузку функций и этот жуткий синтаксис кастов: convert_float, convert_int2 и тд.
Это мои основные претензии, у CUDA вроде с отладкой получше, с интеграцией с GL, с поддержкой фич в отличие от OpenCL на nVidia, но я выбрал OpenCL.
Кстати, OpenCL программы компилируются заметно дольше чем GLSL, возможно они лучше оптимизируются, либо так медленно перегоняются в CUDA ))

#6
21:18, 12 авг 2016

innuendo
> У CUDA R&D поддержка в разы больше, чем у AMD.
неа. У АМД Никак не меньше, и дальше еще будет лучше.
/A\
> OpenCL программы компилируются заметно дольше чем GLSL, возможно они лучше оптимизируются
про оптмизацию врядли, А насчет времени компиляции, то тут предположительно сложность шейдеров иная.

#7
22:11, 12 авг 2016

Andrey
> неа. У АМД Никак не меньше, и дальше еще будет лучше.

У них есть аналог Tesla ?

Напомни, что лично ты делал на compute shaders ?

#8
22:34, 12 авг 2016

Кимпиляция в рантайме это минус для удобства разработки.
В датацентрах сплошная нвидиа.
Вижу что CUDA как технология лучше, думаю спорить никто не будет.
Интересны ее килер фичи.

#9
22:50, 12 авг 2016

Ты что делать хочешь ? Лучше знать оба

#10
23:22, 12 авг 2016

Я вроде слышал, что CUDA быстрее, чем OpenGL и всякие вычислительные кластеры с GPGPU делают с NVidia’вскими карточками.

Но меня возмущает то, что она совместима только с одной IDE, причём её старой версии. Из-за этого я принципиально не буду использовать CUDA без крайней необходимости. Можно конечно наверное и из консоли, но не хочу так красноглазить. На винде это слишком неудобно.

#11
1:49, 13 авг 2016

innuendo
>>Ты что делать хочешь ?
Image processing на сервере

>>Лучше знать оба
Нет смысла знать даже один, главное знать как железка устроена и писать удобно код.

#12
18:38, 13 авг 2016

Arxon
> > > что делать хочешь ?
> Image processing на сервере

Любое железо или только Nvidia ?

Andrey
> про оптмизацию врядли, А насчет времени компиляции, то тут предположительно
> сложность шейдеров иная.

Напомни, что лично ты делал на compute shaders ?

#13
21:34, 13 авг 2016

innuendo
>>Любое железо или только Nvidia ?
Скорее всего нвидиа будет, на амазоне другого нету
Но не в сервере дело, дело в моем личном удобстве при разработке, так как пока нефига не работает расчет и чтоб проверять различные гипотезы не хочется ждать многие минуты. Сейчас не до оптимизаций, брутфорс бы немного скрасил процесс.

Забегая вперед. Есть ли у CUDA движения в сторону Inter Process Communication, всякие темы с шарингом памяти, семфорами?
Копирование туда сюда не впечатляет. Для текущей задачи это совсем не нужно, просто интересно как быстро к гомогенной архитектуре движутся.

#14
10:50, 16 авг 2016

Arxon
> Забегая вперед. Есть ли у CUDA движения в сторону Inter Process Communication,
> всякие темы с шарингом памяти, семфорами?
Ты рамсы попутал? Какие к черту семафоры? На ГПУ используюися барьеры памяти.
Лично я пишу на OpenCl + CodeXL, т.к. на студии уже давно не программирую. В CUDA есть только один плюс — интеграция в студию, где есть встроенный отладчик gpu

OpenCL. Что это такое и зачем он нужен? (если есть CUDA)

Многие, наверное, слышали или читали на хабре об OpenCL – новом стандарте для разработки приложений для гетерогенных систем. Именно так, это не стандарт для разработки приложений для GPU, как многие считают, OpenCL изначально задумывался как нечто большее: единый стандарт для написания приложений, которые должны исполняться в системе, где установлены различные по архитектуре процессоры, ускорители и платы расширения.

Предпосылки появления OpenCL

Основным местом, где можно встретить гетерогенные системы, являются высокопроизводительные вычисления: от моделирования физических процессов в пограничном слое до кодирования видео и рендеринга трехмерных сцен. Раньше подобные задачи решали применяя суперкомпьютеры либо очень мощные настольные системы. С появлением технологий NVidia CUDA/AMD Stream стало возможным относительно просто писать программы, использующие вычислительные возможности GPU.

Стоит отметить, что подобные программы создавались и раньше, но именно NVidiaа CUDA обеспечила рост популярности GPGPU за счет облегчения процесса создания GPGPU приложений. Первые GPGPU приложения в качестве ядер (kernel в CUDA и OpenCL) использовали шейдеры, а данные запаковывались в текстуры. Таким образом необходимо было быть хорошо знакомым OpenGL или DirectX. Чуть позже появился язык Brook, который немного упрощал жизнь программиста (на основе этого языка создавалась AMD Stream (в ней используется Brook+) ).

CUDA стала набирать обороты, а между тем (а точнее несколько ранее) в кузнице, расположенной глубоко под землей, у подножия горы Фуджи (Fuji), японскими инженерами был выкован процессор всевластия Cell (родился он в сотрудничестве IBM, Sony и Toshiba). В настоящее время Cell используется во всех суперкомпьютерах, поставляемых IBM, на его основе постоены самые производительные в мире суперкомпьютеры (по данным top500). Чуть менее года назад компания Toshiba объявила о выпуске платы расширения SpursEngine для PC для ускорения декодирования видео и прочих ресурсоемких операций, используя вычислительные блоки (SPE), разработанные для Cell. В википедии есть статья, в кратце описывающая SpursEngine и его отличия от Cell.
Примерно в то же время (около года назад) оживилась и S3 Graphics (на самом деле VIA), представив на суд общественности свой новый графический адаптер S3 Graphics Chrome 500. По заявлениям самой компании этот адаптер так же умеет ускорять всяческие вычисления. В комплекте с ним поставляется программный продукт (графический редактор), который использует все прелести такого ускорения. Описание технологии на сайте производителя.

Итак, что мы имеем: машина, на которой проводятся вычисления может содержать процессоры x86, x86-64, Itanium, SpursEngine (Cell), NVidia GPU, AMD GPU, VIA (S3 Graphics) GPU. Для каждого из этих типов процессов существует свой SDK (ну кроме разве что VIA), свой язык программирования и программная модель. То есть если Вы захотите чтобы ваш движок рендеринга или программа расчета нагрузок на крыло боинга 787 работала на простой рабочей станции, суперкомпьютере BlueGene, или компьютере оборудованном двумя ускорителями NVidia Tesla – Вам будет необходимо переписывать достаточно большую часть программы, так как каждая из платформ в силу своей архитектуры имеет набор жестких ограничений.
Так как программисты – народ ленивый, и не хотят писать одно и то же для 5 различных платформ с учетом всех особенностей и учиться использовать разные программные средства и модели, а заказчики – народ жадный и не хотят платить за программу для каждой платформы как за отдельный продукт и оплачивать курсы обучения для программистов, было решено создать некий единый стандарт для программ, исполняющихся в гетерогенной среде. Это означает, что программа, вообще говоря, должна быть способна исполняться на компьютере, в котором установлены одновременно GPU NVidia и AMD, Toshiba SpursEngine итд.

Решение проблемы

Для разработки открытого стандарта решили привлечь людей, у которых уже есть опыт (весьма успешный) в разработке подобного стандарта: Khronos Group, на чьей совести уже OpenGL и OpenML и еще много всего. OpenCL является торговой маркой Apple Inc., как сказано на сайте Khronos Group: «OpenCL is a trademark of Apple Inc., and is used under license by Khronos. The OpenCL logo and guidelines for its usage in association with Conformant products can be found here:
http://developer.apple.com/softwarelicensing/agreements/opencl.html»
. В разработке (и финансировании, конечно же), кроме Apple, участвовали такие воротилы IT как AMD, IBM, Activision Blizzard, Intel, NVidia итд. (полный список тут).
Компания NVidia особо не афишировала свое участие в проекте, и быстрыми темпами наращивала функциональность и производительность CUDA. Тем временем несколько ведущих инженеров NVidia участвовали в создании OpenCL. Вероятно, именно участие NVidia в большой мере определило синтаксическую и идеологическую схожесть OpenCL и CUDA. Впрочем программисты от этого только выиграли – проще будет перейти от CUDA к OpenCL при необходимости.

Первая версия стандарта была опубликована в конце 2008 года и с тех пор уже успела претерпеть несколько ревизий.

Почти сразу после того как стандарт был опубликован, компания NVidia заявила что поддержка OpenCL не составит никакой сложности для нее и в скором времени будет реализована в рамках GPU Computing SDK поверх CUDA Driver API. Ничего подобного от главного конкурента NVidia – AMD слышно не было.
Драйвер для OpenCL был выпущен NVidia и прошел проверку на совместимость со стандартом, но все еще доступен только для ограниченного круга людей – зарегистрированных разработчиков (заявку на регистрацию подать может любой желающий, в моем случае рассмотрение заняло 2 недели, после чего по почте пришло приглашение). Ограничения доступа к SDK и драйверам заставляют задуматься о том, что на данный момент существуют какие-то проблемы или ошибки, которые пока не удается исправить, то есть продукт все еще находится в стадии бета-тестирования.
Реализация OpenCL для NVidia была достаточно легкой задачей, так как основные идеи сходны: и CUDA и OpenCL – некоторые расширения языка С, со сходным синтаксисом, использующие одинаковую программную модель в качестве основной: Data Parallel (SIMD), так же OpenCL поддерживает Task Parallel programming model – модель, когда одновременно могут выполняться различные kernel (work-group содержит один элемент). О схожести двух технологий говорит даже то что NVidia выпустила специальный документ о том как писать для CUDA так, чтобы потом легко перейти на OpenCL.

Как обстоят дела на настоящий момент

Основной проблемой реализации OpenCL от NVidia является низкая производительность по сравнению с CUDA, но с каждым новым релизом драйверов производительность OpenCL под управлением CUDA все ближе подбирается к производительности CUDA приложений. По заявлениям разработчиков такой же путь проделала и производительность самих CUDA приложений – от сравнительно невысокой на ранний версиях драйверов до впечатляющей в настоящее время.

А что же делала в этот момент AMD? Ведь именно AMD (как сторонник открытых стандартов – закрытый PhysX vs. открытый Havoc; дорогой Intel Thread Profiler vs. бесплатный AMD CodeAnalyst) делала большие ставки на новую технологию, учитывая что AMD Stream не удавалось хоть сколь-нибудь соревноваться в популярности с NVidia CUDA – виною тому отставание Stream от CUDA в техническом плане.
Летом 2009 года компания AMD сделала заявление о поддержке и соответствии стандарту OpenCL в новой версии Stream SDK. На деле же оказалось, что поддержка была реализована только для CPU. Да, именно так, это ничему не противоречит – OpenCL стандарт для гетерогенных систем и ничего не мешает Вам запустить kernel на CPU, более того – это очень удобно в случае если в системе нет другого OpenCL устройства. В таком случае программа будет продолжать работать, только медленнее. Или же вы можете задействовать все вычислительные мощности, которые есть в компьютере – как GPU так и CPU, хотя на практике это не имеет особого смысла, так как время исполнения kernel’ов которые исполняются на CPU будет намного больше тех что исполняются на GPU – скорость процессора станет узким местом. Зато для отладки приложений это более чем удобно.
Поддержка OpenCL для графических адаптеров AMD так же не заставила себя долго ждать – по последним сообщениям компании версия для графических чипов сейчас находится на стадии подтверждения соответствия спецификациям стандарта. После чего она станет доступна всем желающим.
Так как OpenCL должен работать поверх некоторой специфической для железа оболочки, а значит для того чтобы можно этот стандарт действительно стал единым для различных гетерогенных систем – надо чтобы соответствующие оболочки (драйверы) были выпущены и для IBM Cell и для Intel Larrabie. Пока от этих гигантов IT ничего не слышно, таким образом OpenCL остается еще одним средством разработки для GPU на ряду с CUDA, Stream и DirectX Compute.

  • OpenTK — библиотека-обертка над OpenGL, OpenAL и OpenCL для .Net.
  • PyOpenCL – обертка над OpenCL для Pyton.
  • Java обертка для OpenCL.

Заключение

Технология OpenCL представляет интерес для различных компания IT сферы – от разработчиков игр до производителей чипов, а это означает что у нее большие шансы стать фактическим стандартом для разработки высокопроизводительных вычислений, отобрав этот титул у главенствующей в этом секторе CUDA.

В будущем я планирую более подробную статью о самом OpenCL, описывающую что из себя представляет эта технология, ее особенности, достоинства и недостатки.
Спасибо за внимание.

Визуализация на GPU¶

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

Cycles поддерживает два режима визуализации на GPU: CUDA, который предпочтителен для графических карт Nvidia, и OpenCL, который поддерживает визуализацию на графических картах AMD.

Конфигурирование¶

Для включения визуализации на GPU, откройте окно Параметры и на вкладке Система выберите используемое Устройство расчёта. Затем, для каждой сцены, в панели Визуализация вы сможете настроить использование визуализации на CPU или на GPU.

CUDA¶

Nvidia CUDA is supported for GPU rendering with Nvidia graphics cards. We support graphics cards starting from GTX 4xx (computing capability from 2.0 to 6.1).

Cycles требует установки самых свежих драйверов Nvidia, для всех операционных систем.

OpenCL¶

OpenCL is supported for GPU rendering with AMD graphics cards. (We only support graphics cards with GCN architecture 2.0 and above). To make sure your GPU is supported checkout this Wikipedia page.

Cycles требует установки самых свежих драйверов AMD, для всех операционных систем.

Поддерживаемые возможности и ограничения¶

Обзор поддерживаемых возможностей и сравнение технологий приведены в соответсвующем разделе .

Ограничения CUDA: Максимальное количество индивидуальных текстур ограничено 88 целочисленными текстурами ( PNG , JPEG и так далее) и 5 текстурами с плавающей запятой ( OpenEXR , 16-битный TIFF и прочие) на картах серии GTX 4xx/5xx. Более поздние карты не имеют такого ограничения.

Часто задаваемые вопросы¶

Почему Blender перестаёт отвечать во время визуализации?¶

Когда графическая карта занята визуализацией, она не может перерисовывать пользовательский интерфейс, из-за чего Blender перестаёт отвечать. Мы пытаемся обойти эту проблему, забирая контроль над GPU как можно чаще, но гарантировать полностью гладкую работу мы не можем, особенно на тяжёлых сценах. Это ограничение графических карт и для него не существует стопроцентно работающего решения, хотя мы и постараемся в будущем улучшить этот момент.

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

Почему сцена, которая визуализируется на центральном процессоре, не визуализируется на видеокарте?¶

Для этого существует множество причин, но самая часто встречающаяся — на вашей видеокарте недостаточно памяти. На текущий момент мы можем визуализировать только те сцены, которые влезают в память видеокарты, которая обычно меньше памяти, доступной центральному процессору. Обратите внимание, что, например, изображения текстур размерами 8k, 4k, 2k и 1k занимают, соответственно, 256Мб, 64Мб, 16Мб и 4Мб памяти.

Мы намерены добавить систему для поддержки сцен больших, чем имеющаяся память видеокарты, но это будет не скоро.

Можно ли для визуализации использовать несколько видеокарт?¶

Да, перейдите в Параметры ‣ Система ‣ Устройство расчёта ( User Preferences ‣ System ‣ Compute Device Panel ) и настройте устройства по своему вкусу.

Могут ли несколько видеокарт увеличить доступную память?¶

Нет, каждая видеокарта имеет доступ только к своей собственной памяти.

Какой рендер быстрее: Nvidia или AMD, CUDA или OpenCL?¶

Currently Nvidia with CUDA is rendering fastest, but this really depends on the hardware you buy. Currently, CUDA and OpenCL are about the same in the newest mid-range GPUs. However, CUDA is fastest in the respect of high-end GPUs.

Сообщения об ошибках¶

Unsupported GNU version! gcc 4.7 and up are not supported! (Неподдерживаемая версия GNU! gcc 4.7 и старше не поддерживаются!)¶

On Linux, depending on your GCC version you might get this error. There are two possible solutions:

Use an alternate compiler

If you have an older GCC installed that is compatible with the installed CUDA toolkit version, then you can use it instead of the default compiler. This is done by setting the CYCLES_CUDA_EXTRA_CFLAGS environment variable when starting Blender.

Launch Blender from the command line as follows:

CYCLES_CUDA_EXTRA_CFLAGS="-ccbin gcc-x.x" blender

(Substitute the name or path of the compatible GCC compiler).

Remove compatibility checks

If the above is unsuccessful, delete the following line in /usr/local/cuda/include/host_config.h

#error -- unsupported GNU version! gcc 4.7 and up are not supported! 

This will allow Cycles to successfully compile the CUDA rendering kernel the first time it attempts to use your GPU for rendering. Once the kernel is built successfully, you can launch Blender as you normally would and the CUDA kernel will still be used for rendering.

CUDA Error: Invalid kernel image (Ошибка CUDA: Неверное ядро изображения)¶

Если вы получили эту ошибку на 64-битной MS-Windows, убедитесь, что вы используете 64-битную сборку Blender, а не 32-битную.

CUDA Error: Kernel compilation failed (Ошибка CUDA: Сбой компиляции ядра)¶

Эта ошибка может возникнуть, если у вас новая карта Nvidia, которая пока ещё не поддерживается вашей версией Blender’а, а у вас установлен набор инструментов CUDA. В этом случае Blender может попытаться динамически собрать ядро для вашей графической карты и не преуспеть в этом.

В таком случае вы можете:

  1. Check if the latest Blender version (official or experimental builds) supports your graphics card.
  2. Если вы сами собирали Blender, попробуйте скачать и установить новейший набор инструментов для разработчика CUDA.

Обычным пользователям не требуется устанавливать набор инструментов CUDA, поскольку Blender уже поставляется со скомпилированными ядрами.

CUDA Error: Out of memory (Ошибка CUDA: Не хватает памяти)¶

Обычно эта ошибка означает, что для хранения сцены на видеокарте не хватает памяти. На текущий момент мы можем визуализовывать только те сцены, которые влезают в память видеокарты, которая обычно меньше памяти, доступной центральному процессору. Подробности смотрите выше.

The Nvidia OpenGL driver lost connection with the display driver (Драйвер Nvidia OpenGL потерял соединение с драйвером дисплея)¶

Если видеокарта используется как для обычной работы, так и для визуализации, MS-Windows имеет ограничение на время, которое видеокарта может посвятить вычислению визуализации. Если у вас есть особенно тяжёлые сцены, Cycles может занять слишком много времени видеокарты. Уменьшение размера плиток в панели .*Производительность* может облегчить эту проблему, но единственным реальным решением является использование отдельной видеокарты для визуализации.

Another solution can be to increase the time-out, although this will make the user interface less responsive when rendering heavy scenes. Learn More Here.

CUDA error: Unknown error in cuCtxSynchronize() (Ошибка CUDA: Неизвестная ошибка в cuCtxSynchronize())¶

An unknown error can have many causes, but one possibility is that it is a time-out. See the above answer for solutions.

© Copyright : This page is licensed under a CC-BY-SA 4.0 Int. License.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *