Альтернативы полиморфизму при работе с CUDA на C++C++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Альтернативы полиморфизму при работе с CUDA на C++

Сообщение Anonymous »

Изменить. Из ответов я понял, что мне действительно нужна альтернатива методам виртуальных классов в CUDA C++. Я считаю, что предложенное решение лучше подходит для моего варианта использования, чем предложенное в разделе «Как реализовать виртуальные функции CUDA на стороне устройства?», особенно из-за необходимости обрабатывать вектор виртуальных классов.
Оригинальный вопрос: я пытаюсь написать трассировщик пути на C++ с использованием CUDA. Сейчас я нахожусь на этапе, когда я пытаюсь передать массив фигур в функцию рендеринга, но даже хотя они были скопированы в память устройства, я получаю нелегальное сообщение доступ к памяти при попытке доступа к методам фигур. Возможно, это связано с тем, как я структурирую классы и их наследование.
У меня есть основная функция рендеринга, которая принимает dscriptor сцены и массив изображений
У меня есть функция рендеринга хоста, которая принимает dscriptor сцены и массив изображений
p>

Код: Выделить всё

__host__ void render(const std::shared_ptr &scene, uchar4 *image);
эта функция вызывает функцию renderImage ядра, которая принимает ряд параметров, в частности мой массив фигур

Код: Выделить всё

__global__ void renderImage(const uint16_t width, const uint16_t height,
uchar4 *image, const Vec3 origin,
const Vec3 pixel00, const Vec3 deltaU,
const Vec3 deltaV, const Shape **shapes,
const size_t num_shapes);
Форма определяется как

Код: Выделить всё

// shape.cuh
#pragma once

#include "cuda_path_tracer/ray.cuh"

class Shape {
public:
Shape() = default;
Shape(const Shape &) = default;
__host__ __device__ Shape(Shape &&) = delete;
auto operator=(const Shape &) -> Shape & = default;
__host__ __device__ auto operator=(Shape &&) -> Shape & = delete;
virtual ~Shape() = default;
__host__ __device__ virtual auto hit(const Ray &r) const -> bool = 0;
__host__ __device__ virtual auto getShapeType() const -> ShapeType = 0;
};
Форма, полученная из абстрактного класса, выглядит следующим образом:

Код: Выделить всё

// sphere.cuh
#pragma once

#include "shape.cuh"

class Sphere : public Shape {
public:
__host__ __device__ Sphere(const Vec3 &center, float radius);
__host__ __device__ auto hit(const Ray &r) const -> bool override;
__host__ __device__ auto hitt() const -> bool override;
__host__ __device__ auto getShapeType() const -> ShapeType override;

private:
Vec3 center;
float radius;
};
и реализуется следующим образом

Код: Выделить всё

// sphere.cu
#include "cuda_path_tracer/sphere.cuh"

__host__ Sphere::Sphere(const Vec3 &center, const float radius)
: Shape(), center(center), radius(radius) {}

__host__ __device__ auto Sphere::hit(const Ray &r) const -> bool {
Vec3 const oc = r.getOrigin() - center;
float const a = r.getDirection().dot(r.getDirection());
float const b = 2.0f * oc.dot(r.getDirection());
float const c = oc.dot(oc) - radius * radius;
float const discriminant = b * b - 4 * a * c;
return discriminant > 0;
}
Формы копируются в память устройства с помощью функции рендеринга хоста следующим образом:

Код: Выделить всё

const auto num_shapes = scene->getShapes().size();
const Shape **d_shapes;
CUDA_ERROR_CHECK(
cudaMalloc((void **)&d_shapes, num_shapes * sizeof(Shape *)));

Shape **h_shapes = new Shape *[num_shapes];

for (size_t i = 0; i < num_shapes; i++) {
CUDA_ERROR_CHECK(cudaMalloc((void **)&h_shapes[i], sizeof(Shape)));
CUDA_ERROR_CHECK(cudaMemcpy(h_shapes[i], scene->getShapes()[i],
sizeof(Shape), cudaMemcpyHostToDevice));
}
CUDA_ERROR_CHECK(cudaMemcpy(d_shapes, h_shapes, num_shapes * sizeof(Shape *),
cudaMemcpyHostToDevice));
delete[] h_shapes;
Внутри ядра renderImage у меня есть две вызываемые функции устройства: одна для получения луча, соответствующего пикселю, и одна для цвета, соответствующего лучу, заданному массив фигур, функция getColor выглядит следующим образом

Код: Выделить всё

__device__ auto getColor(const Ray &ray, const Shape *const *shapes,
const size_t num_shapes) -> uchar4 {
// Dummy implementation
for (size_t i = 0; i < num_shapes; i++) {
if (shapes[i]->hit(ray)) {
return make_uchar4(1, 0, 0, UCHAR_MAX);
}
}
return make_uchar4(0, 0, 1, UCHAR_MAX);
}
проблема в том, что shape->hit(ray) генерирует исключение «Незаконный доступ к памяти», почему? И как это исправить?


Подробнее здесь: https://stackoverflow.com/questions/792 ... -cuda-in-c
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»