Understanding how to work with derived c++ classes in Openacc? - c++

I'm trying to implement some plasma physics codes on GPUs. However, I have a problem of the following type:
I have two classes: base and derived. The derived class contains an additional pointer that points to a member array of the base class. When I compile the code, there is no problem. However, the following error
FATAL ERROR: variable in data clause is partially present on the device: name=fderived
appears at runtime. I do understand why it occurs: it is due to the member vals1D_ of the derived class (see the code below). My question is how to correctly create vals1D_ on the device, or attach it to vals_ of the base class?
In other words, I want to attach the pointer vals1D_ of the derived class to vals_ of the base class on GPU. I have tried different ways, and all led to the mentioned error.
Here is the code
#include <iostream>
#include <vector>
#include <iomanip>
template <typename U, typename T>
class base
{
public:
U size_;
T *vals_;
base(U size): size_{size}
{
vals_ = new T [size_];
#ifdef _OPENACC
#pragma acc enter data copyin(this)
#pragma acc enter data create(vals_[0:size_])
#endif
}
/* Update self */
void updateSelf()
{
#ifdef _OPENACC
#pragma acc update self(vals_[0:size_])
#endif
}
/* Update device */
void updateDevice()
{
#ifdef _OPENACC
#pragma acc update device(vals_[0:size_])
#endif
}
#ifdef _OPENACC
#pragma acc routine seq
#endif
inline T& operator() (U i)
{
return vals_[i];
}
/* Destructor */
~base()
{
#ifdef _OPENACC
#pragma acc exit data delete(vals_[0:size_])
#endif
if(vals_ != nullptr)
delete [] vals_;
}
};
template <typename U, typename T>
class derived : public base<U, T>
{
public:
T *vals1D_;
derived(U size) : base<U, T>(size)
{
vals1D_ = base<U, T>::vals_;
#ifdef _OPENACC
#endif
}
~derived()
{
}
};
int main()
{
unsigned int s = 10;
derived<unsigned int, double> fderived(s);
for(unsigned int i = 0; i < s; i++)
fderived.vals_[i] = i * i;
fderived.updateDevice();
#pragma acc parallel loop present(fderived)
for(unsigned int i = 0; i < s; i++)
fderived.vals_[i] = 5;
return 0;
}

Related

How can I get rid of the <error-type> type that is appearing in my method template? Both the input to the method and the class are templates

I am getting the error
declaration is incompatible with "void spectrogram<T>::update(<error-type> x)
I don't see any difference between the declaration and the definition of the method, not sure why it is complaining about just this one definition and not the constructor or destructor.
Here is vComplex.hpp
#ifndef VCOMPLEX_H
#define VCOMPLEX_H
template <class T>
class vComplex {
public:
T* realp;
T* imagp;
int length; // for bookkeeping
vComplex(void) { }
vComplex (T* I, T* Q, int len) {
realp = I;
imagp = Q;
length = len;
}
~vComplex(void) {
free(realp);
free(imagp);
}
void put(T* I, T*Q, int len) {
realp = I;
imagp = Q;
length = len;
}
};
#endif
the function declaration for update in spectrogram.hpp, with other members removed:
#ifndef SPECTROGRAM_H
#define SPECTROGRAM_H
template <typename T>
class spectrogram {
public:
void update(vComplex<T> x);
};
#endif
and the function signature (and includes) for update in spectrogram.cpp:
#include <stdio.h>
#include <math.h>
#include "spectrogram.hpp"
#include "vComplex.hpp"
template <typename T>
void spectrogram<T>::update(vComplex<T> x) {
//do stuff
}
In VS 2017, I get the red underline under update and everything inside of it breaks basically. VS is saying T is undefined which I'm assuming is caused by the overall error. I have to use dynamically allocated pointers, I don't have the option of using other types or containers.

Program Error, Due to the use of std::unique_ptr in VS2010?

I been writing a program in which, an array will dynamically grow when ever the max size is reach. I have used std::unique_ptr, but I'm not sure what is causing the error. I'm using VS2010.
The error is:
error C2027: use of undefined type 'DyArray::Impl' c:\program files (x86)\microsoft visual studio 10.0\vc\include\memory 2067
Here is the code
DyArray.h
#pragma once
#include <iostream>
#include <memory>
class DyArray
{
public:
DyArray(int IntialSize, int IncrementSize)
{
}
~DyArray()
{
}
void Insert(int Data);
void Set(int Position,int Data);
int Get(int Position);
void Print();
private:
DyArray(const DyArray&);
DyArray& operator=(const DyArray&);
struct Impl;
std::unique_ptr<Impl> m_Impl;
};
DyArray.cpp
#include "LinkedList.h"
#include <iostream>
struct DyArray::Impl
{
typedef struct
{
int* array;
size_t used;
size_t size;
}Array;
public:
Array* m_DyArray;
size_t m_InitalSize;
size_t m_IncrementSize;
Impl(Array* DyArray,int IntialSize,int IncrementSize):m_DyArray(DyArray),m_InitalSize(IntialSize),m_IncrementSize(IncrementSize)
{
m_DyArray->array = (int*)malloc(m_InitalSize * sizeof(int));
m_DyArray->used = 0;
m_DyArray->size = m_InitalSize;
}
~Impl()
{
free(m_DyArray->array);
m_DyArray->array = NULL;
m_DyArray->used = m_DyArray->size = 0;
}
void insertArray(int element)
{
if (m_DyArray->used == m_DyArray->size)
{
m_DyArray->size += m_IncrementSize;
m_DyArray->array = (int*)realloc(m_DyArray->array,m_DyArray->size*sizeof(int));
}
m_DyArray->array[m_DyArray->used++] = element;
}
void Display()
{
std::cout<<"\n";
for (int i = 0; i< m_DyArray->used;i++)
{
std::cout<<m_DyArray->array[i]<<" ";
}
}
};
void DyArray::Insert( int Data )
{
m_Impl->insertArray(Data);
}
void DyArray::Print()
{
m_Impl->Display();
}
Main.cpp
#include "DyArray.h"
#include <iostream>
void main()
{
DyArray dyarray(2,3);
dyarray.Insert(12);
dyarray.Insert(14);
dyarray.Insert(55);
dyarray.Insert(23);
dyarray.Insert(444);
dyarray.Insert(23);
dyarray.Print();
}
The destructor of your class needs to destroy the unique pointer, which in turn needs to delete the Impl it manages. It can only do that if Impl is a complete (i.e. fully defined) type.
Define the destructor in the source file, after the definition of Impl, not in the class definition.
You'll also need to define the constructor there, if you want it to create an Impl and initialise the pointer.

Using Pragma and Condition Compilation in C++

I am trying to understand a few examples of pragma and header compilation with include guards
I am not asking about the difference between them. I am asking specifically if based on the example I provided that I am following, am I illustrating it correct in my class?
I can not tell if its working or not when I run my program.
In the examples they show this,
#pragma once
#if !defined(x_header_included)
#define x_header_included
class X { … };
#endif
Which in my c++ ignorance I have translated to this,
#include <iostream>
#pragma once
#if !defined(my_headers)
#define my_headers
#include "npc.h"
#include "pc.h"
#include "health.h"
class game {
private:
npc n;
pc p;
health h;
public:
game(const npc& init_n, const pc& init_p, const health& init_h):
n(init_n),
p(init_p),
h(init_h)
{}
game(std::string gen, std::string abil, bool use, int lvl, int h, int arm) :
n(gen, abil),
p(use, lvl),
h(h, arm)
{
}
friend std::ostream& operator<<(std::ostream& s, const game& g) {
g.n.output(s);
g.p.output(s);
g.h.output(s);
return s;
}
npc get_n() { return n; }
pc get_p() { return p; }
health get_h() { return h; }
void set_n(npc init_n) { n = init_n; }
void set_p(pc init_p) { p = init_p ; }
void set_h(health init_h) { h = init_h; }
};
#endif
Is that all I do or am I missing something? Does anything else need to be added to the .cpp files from here?
The class I am showing is the composite top level class included in my main.cpp and my game.cpp file.

Code compiles on MSVC, but not on GCC [duplicate]

This question already has an answer here:
how to inherit a class with templates? [duplicate]
(1 answer)
Closed 8 years ago.
I'm new to GCC and am trying to port code to Linux which compiled OK with MSVC.
The code below (a small program wich can be copypasted and compiled) produces the error:
"there are no arguments to ‘num_obj_inc’ that depend on a template parameter,
so a declaration of ‘num_obj_inc’ must be available [-fpermissive]"
#include <iostream>
using namespace std;
#define _SPTRDBG
#ifdef _SPTRDBG
#define SPTRDBG(x) x;
#else
#define SPTRDBG(x)
#endif
template<bool>
struct objCounter
{
void num_obj_inc(){}
void num_obj_dec(){}
};
template<>
struct objCounter<true>
{
#ifdef _SPTRDBG
static int num;
void num_obj_inc() { num++; }
void num_obj_dec() { num--; }
#endif
};
template<class C, bool bCnt=false>
class SPtr
: public objCounter<bCnt>
{
C* p;
public:
SPtr(C *_p)
:p(_p)
{
if ( p ) {
SPTRDBG( num_obj_inc() )
}
}
};
int main()
{
return 0;
}
My guess was that GCC somehow optimize out the noop "num_obj_inc(){}", but this code compiles OK:
struct objCounter
{
void num_obj_inc(){}
void num_obj_dec(){}
};
class SPtr
: public objCounter
{
public:
SPtr(int *p)
//:p(_p)
{
if ( p ) {
SPTRDBG( num_obj_inc() )
}
}
};
What can be cause of the compilation error?
You need to use:
this->num_obj_inc();
See Why do I have to access template base class members through the this pointer? for detailed explanation.

Simple Polymorphism cast not working

I have a class SourceComponent, and its derived class, PeriodicSourceComponent.
Implementations are:
class SourceComponent : public Component
{
protected:
friend class UserInterface;
friend void readInput();
public:
virtual int returnType();
virtual int propagateLogic();
virtual void sourcePropagation(float);
virtual void accept(VisitorSources&);
SourceComponent();
};
and
#include "source_component.h"
class PeriodicSourceComponent : public SourceComponent
{
private:
int frequency;
friend void main();
friend void readInput();
friend class UserInterface;
public:
void sourcePropagation(float);
int returnType();
PeriodicSourceComponent();
};
When I try in some different class/method to do:
SourceComponent* s = new PeriodicSourceComponent;
it won't let me, sayin "a value of type periodicblabla cant be assigned to value of type sourceblabla". Why?
Edit:
Ok, in my main it looks lke this:
#include "source_component.h"
#include "periodic_source_component.h"
void main()
{
SourceComponent* s = new PeriodicSourceComponent;
}
And implementations of both classes:
source.cpp:
#include "source_component.h"
SourceComponent::SourceComponent()
{
outputState = -1;
}
int SourceComponent::propagateLogic()
{
return 1;
}
int SourceComponent::returnType()
{
return 5;
}
and periodic.cpp
#include "periodic_source_component.h"
PeriodicSourceComponent::PeriodicSourceComponent()
{
outputState = 0;
}
int PeriodicSourceComponent::returnType()
{
return 3;
}
void PeriodicSourceComponent::sourcePropagation(float time)
{
float t = time, period;
period = 1000000/frequency;
if(t > period)
{
while(t >= period)
t -= period;
}
if(t <= (period/2))
outputState = 0;
else
outputState = 1;
}
and its not working... (outputState is a member of class Component, base class of SourceComponent)
and the error message: A value of type "PeriodicSourceComponent*" cannot be assigned to a value of type "SourceComponent*".
Important Edit
When I try to compile, the actual compiler error is at PeriodicSourceComponent declaration, it says: "Base class undefined".
and also, I have two other derived classes from SourceComponent, but I don't see how they could interfere with this one..
EDIT 4
Ok so I figured out what causes the error, you were right of course, it something else I didn't post. I have class VisitorSources, heres definition:
#ifndef __VISITOR_SOURCES_H__
#define __VISITOR_SOURCES_H__
#include "component.h"
#include "impulse_source_component.h"
#include "arbitrary_source_component.h"
#include "periodic_source_component.h"
class VisitorSources
{
protected:
VisitorSources();
public:
virtual void visitImpulseSource(ImpulseSourceComponent*);
virtual void visitArbitrarySource(ArbitrarySourceComponent*);
virtual void visitPeriodicSource(PeriodicSourceComponent*);
void visitSource(int, float);
};
#endif
And its implementation is not yet written:
#include "visitor_sources.h"
void visitSource(int type, float time)
{
}
void VisitorSources::visitArbitrarySource(ArbitrarySourceComponent* a)
{
}
When I comment out the entire Visitor class and implementation, the above-mentioned errors are gone for some reason. I have no idea why...
The only error that remains is that when I try to use s->frequency, it says that frequency is not a member of SourceComponent, which is true, but it is a member of PeriodicSourceComponent, which is why I used the cast in the first place..
Finally, here's the Component class, the main class for all almost all other classes in the project :P
#ifndef __COMPONENT_H__
#define __COMPONENT_H__
#include <iostream>
#include <vector>
class Component
{
friend class UserInterface;
friend void readAndSimulate();
protected:
Component();
int numOfInputs;
int numOfOutputs;
std::vector<Component*> inputs;
std::vector<Component*> outputs;
friend void main();
float lengthOfSimulation;
int typeIfSource;
public:
int outputState;
virtual int propagateLogic() = 0;
virtual int returnType();
int beginPropagation();
virtual void sourcePropagation(float);
~Component();
};
#endif
And implementation:
#include "component.h"
#include <conio.h>
Component::Component()
{
}
int Component::beginPropagation()
{
std::vector<Component*>::const_iterator iter = outputs.begin();
for(;iter<outputs.end();++iter)
{
if ((*iter)->outputState == -2)
{
(*iter)->outputState = outputState;
return (*iter)->outputState;
}
}
std::vector<Component*>::const_iterator it = outputs.begin();
int finishedCycle, x;
while(1)
{
finishedCycle = 1;
for(; it < outputs.end(); ++it)
{
x = (*it)->propagateLogic();
if(!x)
finishedCycle = 0;
}
if(finishedCycle) break;
it = outputs.begin();
}
it = outputs.begin();
for(;it<outputs.end();++it)
(*it)->beginPropagation();
}
int Component::returnType()
{
return 0;
}
void Component::sourcePropagation(float)
{
}
Component::~Component()
{
std::vector<Component*>::const_iterator it = inputs.begin();
for(; it < inputs.end(); ++it)
{
if((*it) != NULL)
{
delete *it;
Component* p = *it;
p = NULL;
}
}
it = outputs.begin();
for(; it < inputs.end(); ++it)
{
if((*it) != NULL)
{
delete *it;
Component* p = *it;
p = NULL;
}
}
}
Are you using include guards in all your header files?
Not having them can cause the kinds of problems you're seeing.
Three guesses:
You copied and pasted code between header files and forgot to change the #include guards.
You use precompiled headers and included something before the #include "stdafx.h".
If you use precompiled headers, try deleting the .pch file.