0

I was trying to implement the Unified Vidrtual Memory example given on the CUDA blog: http://devblogs.nvidia.com/parallelforall/unified-memory-in-cuda-6/

Visual Studio 2013 gives me an error : no default constructor exists for class "Term"

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <stdio.h>
#include <iostream>

#define NUM_ATTRIBUTES 10

class Managed {
public:
    void *operator new(size_t len) {
      void *ptr;
      cudaMallocManaged(&ptr, len);
      std::cout << "custom new for size " << len << '\n';
      return ptr;
    }
    void *operator new[] (size_t len) {
      void *ptr;
      cudaMallocManaged(&ptr, len);
      std::cout << "custom new for size " << len << '\n';
      return ptr;
    }
    void operator delete(void *ptr) {
        cudaFree(ptr);
    }
};

class Attribute : public Managed {
public:
    int num_levels;
    int num_active_levels;
    int active_levels;
};

class Term : public Managed {
public:
    int num_active_attributes;
    int active_attributes;
    Attribute attribute[NUM_ATTRIBUTES];

    // Unified memory copy constructor allows pass-by-value
    Term (const Term &orig) {
        num_active_attributes = orig.num_active_attributes;
        active_attributes = orig.active_attributes;
        cudaMallocManaged((void **)&attribute,NUM_ATTRIBUTES * sizeof(Attribute));
        memcpy(attribute, orig.attribute, NUM_ATTRIBUTES * sizeof(Attribute));
    }
};

int main()
{
    Term * A = new Term[10];
    getchar();
    return 0;
}

Doesn't the class Term inherit from the new operator defined in the parent class Managed ?

mkj
  • 2,761
  • 5
  • 24
  • 28
RemiDav
  • 463
  • 3
  • 16

2 Answers2

1

This is unrelated to CUDA. The compiler isn't generating a default constructor because you have already provided another constructor (the copy one).

Just explicitly request for a default constructor:

class Term : public Managed {
public:
    ...

    // C++11
    Term() = default;

    // Pre C++11 alternative (although not strictly equivalent)
    Term() {}
    ...
};

Also note that operator new and constructors are two different things: new is for allocating storage, constructors are for initializing that storage into a meaningful state (roughly).

user703016
  • 37,307
  • 8
  • 87
  • 112
  • Thanks a lot. I guess this is not supported in Visual Studio 2012 and only appeared in VS2013. error : badly-formed pure specifier (only "= 0" is allowed) Unfortunately CUDA is not supported by VS 2013. Is there any alternative ? – RemiDav Jun 02 '14 at 14:49
  • @RemiDav is this C++11? – 4pie0 Jun 02 '14 at 14:50
  • @RemiDav VS2012 doesn't fully support C++11. I have added a pre-C++11 way of achieving what you want. – user703016 Jun 02 '14 at 14:51
  • @WilliamAndrewMontgomery note also that there are some differences between Term() = default; and Term() {} - they are not equal when value initialization is considered – 4pie0 Jun 02 '14 at 14:52
0

You need to define a default constructor which is required for elements of arrays

class Term : public Managed {
public:
    //...
    Term () {}  // default c-tor
    Term() = default;  // since C++11, note however that there are some 
                       // differences between Term() = default; and Term() {}
                       // they are not equal when value initialization 
                       // is considered
};

You don't have one because explicitly defined copy-ctor Term( const Term&) prohibited generation of default constructor by compiler. Regarding differences between =default and {} in terms of default constructor you may look at this:

https://stackoverflow.com/a/23698999/1141471

Community
  • 1
  • 1
4pie0
  • 29,204
  • 9
  • 82
  • 118