c++cudavariant

initialize subclass of cuda::std::variant


I'm implementing polymorphism on GPU with std::cuda::variant, so far it's working with Circle, Square, Shape:

struct Circle;
struct Square;
using Shape = cuda::std::variant<Circle, Square>;

auto shape = gpu_allocate<Shape>(1);
*shape = Circle(); //initialize Shape with Circle

But when it comes to multiple inheritance, I could'nt find a way to initialize the variable:

struct Color {
  enum Type { red, blue };
  Type type;
};

struct ColoredShape : Color, cuda::std::variant<Circle, Square> {};

auto colored_shape = gpu_allocate<ColoredShape>(1);
colored_shape->type = Color::red;

// *colored_shape = Circle(); // error

So my question is: How do I initialize ColoredShape varaible with Circle?

full code:

#include <cuda/std/variant>

struct Circle {
  double radius = 0.9;
  void init() { radius = 0.3; }
};

struct Square {
  double x = -0.1;
  double y = -0.3;

  void init() {
    x = 0.1;
    y = 0.3;
  }
};

struct Color {
  enum Type { red, blue };
  Type type;
};

using Shape = cuda::std::variant<Circle, Square>;

struct ColoredShape : Color, cuda::std::variant<Circle, Square> {};

template <typename T> T *gpu_allocate(const size_t num = 1) {
  T *data;
  const auto size = sizeof(T) * num;
  cudaMallocManaged(&data, size);

  return data;
}

int main() {
  auto shape = gpu_allocate<Shape>(1);
  *shape = Circle();

  auto colored_shape = gpu_allocate<ColoredShape>(1);
  colored_shape->type = Color::red;

  // *colored_shape = Circle(); // error

  return 0;
}


Solution

  • I would say that

    1. ColoredShape is a Shape so inheritance is ok here
    2. ColoredShape has a Color so use composition instead of inheritance.
    #include <variant>
    
    struct Circle {};
    struct Square {};
    
    using Shape = std::variant<Circle, Square>;
    
    struct Color {};
    
    struct ColoredShape : Shape  // inheritance for ColoredShape
    {
        using Shape::Shape; // usage of Shape constructor
    
        Color color; // composition for Color
    };
    
    int main()
    {
        ColoredShape shape;
        shape = Circle();
        shape = Square();
    }
    

    Demo

    Note how the constructor of Shape is made available in ColoredShape with the help of using Shape::Shape; (you could do something similar on your example).