How can I use static const members in CUDA? - c++

I am currently porting my ray tracer to the GPU by using CUDA, and to get my feet wet I am modifying the example CUDA 6.5 project (adding an array of integers) to use a custom Color struct instead of integer. However, I am getting various errors whenever I compile my code.
I have all of my class's member functions declared with the __host__ and __device__ attributes, and I have all of the definition code in a .cu file. In my color struct, I have a Darken method that interpolates the given color to black by the given amount. I also have a static definition for black that the Darken function uses.
For example, here is a trimmed down version of the struct:
// **********************
// .hpp file
// **********************
struct Color
{
float R;
float G;
float B;
__host__ __device__ static Color Darken(const Color& c, float amount);
static Color Black;
};
// **********************
// .cu file
// **********************
const Color Color::Black( 1.0f, 1.0f, 1.0f );
Color Color::Darken(const Color& c, float amount)
{
return Color( Math::Lerp( c.R, Black.R, amount ),
Math::Lerp( c.G, Black.G, amount ),
Math::Lerp( c.B, Black.B, amount ) );
}
However, whenever I go to compile the code, I get the following error:
error : identifier "rex::Color::Black" is undefined in device code
I have tried adding __device__, __host__, __global__, and various combinations of those specifiers to the colors, but the CUDA compiler tells me that they are not applicable. Also, after I add any of the specifiers to the static colors, I get the same error for the color's R, G, and B components.
Does anyone know how I can use the static color definitions in CUDA?

As per the documentation, the CUDA object model does not support static data members, so there is no direct way to do what you are trying to do.
As pointed out by Robert Crovella in comments, you could use a __constant__ memory declaration to achieve similar functionality, and you can also use namespace tricks to get around duplicate definitions when using whole compilation, or use extern with a single definition in separate compilation.
[This answer was added as a community wiki entry to get this question off the unanswered question list]

Related

C++ Using classes in other classes failing

I have a Display class that uses SDL to write pixels to the screen. I'd like another class (Triangle) to be able to use this already existent class object, so I've been trying to pass the object by address.
It's sort of working, in the sense that it is actually calling the methods. However, I was getting a segmentation fault in the DrawPixel function. After checking gdb and checking what values are in the function, I figured out that the color_buffer array does not exist (note that when DrawPixel is called directly from the display class in main it works fine).
After a little more testing, I determined that window_width, window_height etc are not set in the Triangle's version of the Display object. But they do exist in the original Display object.
So I'm assuming that I am not properly passing in my object, but I'm uncertain how to fix this issue as I thought passing by address would work just fine. How can I pass an already existing/instantiated class to another class?
I've also tried putting color_buffer into public variables in case private was causing it, but that didn't help.
Example:
main.cpp
int main() {
Display display;
Triangle triangle(&display);
// This doesn't work
triangle.DrawTriangle(300, 500, 0xFFFFFF00);
// This does work
display.DrawPixel(300, 500, 0xFFFFFF00);
return 0;
}
triangle.hpp
class Triangle {
private:
Display* display;
public:
DrawTriangle(int x, int y, uint32_t color);
};
triangle.cpp
Triangle::Triangle(Display* display) {
display=display;
}
Triangle::DrawTriangle(int x, int y, uint32_t color) {
display->DrawPixel(x, y, color);
}
display.hpp
class Display {
private:
// SDL Stuff defined here
uint32_t* color_buffer;
int window_width = 1920;
int window_height = 1080;
public:
Display();
DrawPixel(int x, int y, uint32_t color);
};
display.cpp
Display::Display() {
// SDL Stuff declared
color_buffer = new uint32_t[window_width * window_height];
}
Display::DrawPixel(int x, int y, uint32_t color) {
// This is receiving the correct values, but doesn't allow me to access
// any index of color_buffer.
color_buffer[(y * window_width) + x] = color;
}
Triangle::Triangle(Display* display) {
display=display;
}
the display is not the member of your class.Use this->display = display instead
You have to use "this" in Triangle constructor. That should solve the problem.
Triangle(Display* display) {
this->display=display;
}
A couple of things to add to the answers above:
use a different naming convention for member variables - this way it is very easy to avoid typos. _display, m_display, Display_ (Clang style =) )
class members are private by default so if you are following convention where attributes are defined on top, there's no need to add private:
Some prefer references (e.g. Display&), mostly to save typing ->, since if `Display goes out of scope it will have the same hilarious effect as passing a pointer.
static analyzers look down on pointer arithmetic(due to possible out-of-bounds writes).
You can use std::array from header:
static constexpr int WIDTH = 1920;
static constexpr int HEIGHT = 1080;
std::array<uint32_t, WIDTH* HEIGHT> m_color_buffer{};
and then either use m_color_buffer[index] = color (no bounds checking, random memory gets written if you write out of bounds in release and normally an exception in debug), or use m_color_buffer.at(index) - slower but this way you get an exception in release mode, but the compiler may complain about the stack size, as the definition is essentially the same as uint32_t buffer[WIDTH*HEIGHT]. std::vector is a better alternative - it hides buffer allocation, manages memory (no need to delete) at expense of the 2 extra pointers for begin and the end of the vector.
The code example lacked a destructor. Every new should have an accompanying delete hence either add it or just switch to a standard library container to avoid the headache =)
Last but not least - both classes override constructors. Display also manages resources. What happens when you copy Display instances? Move them? It is a bit of a headache and leads to a bit of a boilerplate, but it is best to implement Rule of 5 members and avoid accidental surprises =)
PS. C++ is a beautiful language =)

Equivalent in C++ of Java static class of objects [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Coming from a Java background, I am used to the concept of making a class A, then creating class B to hold specific static instantiations of class A to use throughout the program. Some example Java code:
public class Color {
public int r;
public int g;
public int b;
public Color(int r, int g, int b) {
this.r = r;
this.g = g;
this.b = b;
}
}
public class Colors {
public static final Color WHITE = new Color(255, 255, 255);
public static final Color BLACK = new Color(0, 0, 0);
}
I have tried a class Color, with a struct Colors named colors, but I get linker errors as colors is reinstantiated in every file I include it in. What is the best way to do this in C++? Or am I trying to solve the problem in the wrong way?
Assuming that your problem is actually the color thing you presented, this would probably be the easiest way to achieve it:
struct Color
{
int r, g, b;
Color(int r, int g, int b)
{
this->r = r;
this->g = g;
this->b = b;
}
static Color WHITE() { return {255, 255, 255}; }
static Color BLACK() { return {0, 0, 0}; }
};
https://godbolt.org/g/DBrM1C
If you for some reason need to be able to reference the static objects (i.e. there should be exactly one static object instance for every named color), you could declare them in the header (Colors.h) and initialize them in the associated compilation unit (Colors.cpp), but that is somewhat cumbersome and also means your compile time constants cannot be inlined/constant folded etc. by the compiler (without link-time optimization at least). It does protect you from recompilations of files that include Colors.h if the constants change though.
This method would be a (not much better) middle ground where there is still one static object instance per color but you can keep it to the header: https://godbolt.org/g/13krNc
Note however that, despite optimizations, the compiler cannot figure out that bar() should always return 255. Instead, it has to check in every call whether the static constants were initialized already and, if not, initialize them (which requires a lock for thread safety!).
In C++ an include is an actual include. That means, in contrast to Java imports, the code is actually copied.
When you now include your file multiple times, you have multiple occurrences of your code. That is why you need to protect your header code from being copied twice.
Solution 1: Write the following as the first line of your header file:
#pragma once
Solution 2 (more portable and widely recommended):
#ifndef MYHEADERFILENAME_H
#define MYHEADERFILENAME_H
// your header code goes here
#endif /* MYHEADERFILENAME_H */
Some more thoughts about your problem:
Do not use a class for encapsulating constexpr values. This is not necessary in C++. In Java there cannot be something outside a class, but in C++ this is perfectly legal. Just declare your symbol and define it in your source file outside a class. You should declare it in your own namespace, though, to avoid name clashes.
Maybe an enum class aka scoped enumeration comes closer to what you really want.

How do I pass vertices[] to a constructor?

I am using C++ and OpenGL. I'm trying to do some mock design of a model loader and renderer.
Here is where I'm getting stuck:
I have been drawing to the screen with my renderer class and window class, no problems there.
I'm using a generic model class that until now was hard coded to take vertices[108] and colors[108] and draw a cube. This works and I could instance hundreds of cubes just fine. However, I was always creating the model(s) by using vertices[108] and colors[108].
Now I want to ditch the [108] and just pass vertices and colors of any sizes into the model constructor.
Right now it looks like in pseudo code:
//this is in main.cpp
GLfloat vertices[108] = {
//vertices here
};
GLfloat colors[108] = {
//colors
};
mynamespace::Model::cube(vertices,colors);
That is how I a have been using this and within the model class:
`//this is in model class declaration
GLfloat vertices_[108];
GLfloat colors_[108];
//then in the constructor definition
Model::Model(vertices,colors) {
//loop through, i<108, and assign vertices,colors to vertices_,colors_
}
`
This has worked fine for learning purposes. I now would like to start creating various size vertices[] and sending them along to the Model constructor. (The number of vertices and colors will match - will check that). But I am having a hard time removing that hard coded index, e.g. vertices[108], and just sending along vertices[unknown until it arrives].
I thought, worst case, I could send a vertices[] through and then in the constructor defn, receive the vertices, check the sizeof() and divide by 4 and assign values by loop if nothing else would work. However, when I send any size vertices[] through and print out the sizeof() to check it, I always get 4 bytes...and nothing draws of course.
To be clear, I'm not getting errors in my code and I don't have a particular code I want to debug so I'm not pasting an existing code sample to solve anything. This is meant to be here is what I'm trying to do, what are some recommendations from experienced folks.
What is a good practice for doing this type of thing?
After this, I want to start loading mesh from files but first I want to understand how I am supposed to pass along various amounts of vertices and make a model so I can send models to the renderer.
Just use std::vector (you'll need to include <vector> first).
//this is in model class declaration
std::vector<GLfloat> vertices_;
std::vector<GLfloat> colors_;
//then in the constructor definition
Model::Model(const std::vector<GLfloat> &vertices, const std::vector<GLfloat> &colors) {
vertices_ = vertices;
colors_ = colors;
}
and then:
std::vector<GLfloat> vertices = {
//vertices here
};
std::vector<GLfloat> colors = {
//colors
};
mynamespace::Model cube(vertices,colors);
Of course, you can remove all the std::s if you have using std::vector; or using namespace std;
You get 4 bytes because when u pass the array to a function, the array degenerate into a Type * pointer. So u didn't get the length of array, instead u got the size of the pointer.
Since u have said u are new to both.
A simple way to work around is to def your fun
fun(Type array,int n)
When u invoke, you call like this:
fun(array,sizeof(array))
This should solve your problem.

C++: Strange multiple definition errors and problems with

My first, immediate problem is with many strange errors that look like this:
In function ZN6BeingC2Ev:
multiple definition of 'area'
first defined here
I am writing a basic pathfinding system and I have two classes:
-Area: Areas describe the 2D grid of walls and open spaces that beings navigate through.
-Graph: Every being capable of pathfinding has its own Graph, and each of those graph objects need to get a part of the layout of the world grid from the currently active Area.
So all Graph objects need to know about *area, which in main() is allocated by the usual area = new Area();
But I can't declare Area *area in main.cpp because Graphs wouldn't be able to see it, and its methods won't be able to read it.
So I tried to declare *area in area.h (shown below). My intention was that because Graph #includes "area.h", area would be known to Graph. This causes my my multiple definitions problem.
I am unsure what exactly the problem is, since I am sure I did not define Area in any way outside of its own header file, and partly because my IDE points me to seemingly unrelated functions when I click the error message for the source of the multiple definition.
So my second question: In the interest of avoiding such an error, is there a better structure that will give Graph knowledge of Area objects and access to their contents?
Below is code which I hope demonstrates my intentions, please let me know if anything necessary has been omitted.
area.h
#ifndef AREA_H_INCLUDED
#define AREA_H_INCLUDED
class Area
{
std::vector<int>wallmap;
...
} *area;
#endif // AREA_H_INCLUDED
graph.h
#ifndef GRAPH_H_INCLUDED
#define GRAPH_H_INCLUDED
#include "area.h"
class Graph
{
...
};
#endif // GRAPH_H_INCLUDED
graph.cpp (The problem is in the switch part)
std::vector<Node*>Graph::RequestPath(int startX, int startY, int destX, int destY);
{
for(std::vector<Node*>::iterator it = nodeGraph.begin(); it != nodeGraph.end(); ++it)
{
(*it)->heuristic = std::abs(destX-startX) + std::abs(destY-startY);
switch(area->wallmap[(*it)->id]) // **I need Graphs to know about the wallmap vector in Area, here for example.**
{
....
}
(*it)->fValue = (*it)->heuristic + (*it)->moveCost;
}
}
main.cpp
#include "area.h"
int main()
{
...
area = new Area();
area->Init();
...
delete area;
...
}
Thanks for your assistance!
As pointed out in a comment by #GManNickG, the problem lies with the use of area as a variable in:
class Area
{
std::vector<int>wallmap;
...
} *area;
Every compilation unit that #includes the .h file will define that variable, which leads to the multiple definition error at link time.
I suggest using a function to get the necessary pointer instead of using a global variable.
class Area
{
std::vector<int>wallmap;
...
};
Area* getArea();
Implement it in the .cpp file that implements the member functions of Area, just to keep related definitions together
Then, you can use the function wherever you were using the global variable.
If you must use a global variable, which I strongly advise against, you can use:
class Area
{
std::vector<int>wallmap;
...
};
extern Area* area;
and make sure that area is defined in the .cpp file that implements the member functions of Area, just to keep related definitions together.

Static variables in the scope of a draw function in OpenGL?

As an example, I have the following draw function in some OpenGL application:
void Terrain::Draw(float ox, float oy, float oz) {
float terrainWidth = stepWidth * (width - 1.0f);
float terrainLength = stepLength * (length - 1.0f);
float startWidth = (terrainWidth / 2.0f) - terrainWidth;
float startLength = (terrainLength / 2.0f) - terrainLength;
(...)
}
Terrain is a class and I'm sure that the step and terrain width/length instance variables will never change during the lifetime of the object (they are initialized before the first call to the draw function).
Assuming my application runs at a steady 25fps, the function will be called 25 times a second. The values will never change, they will always be the same.
Would I gain anything in declaring those function variables as static? To prevent them from being destroyed and declared every time the function is called?
Compilers are so good at micro optimizations these days that it would be nearly impossible to make a definitive statement on whether it would improve or slow down your program.
You will have to benchmark to really be sure.
Would I gain anything in declaring those function variables as static?
it's really a small amount of data: don't bother, unless you have a ton of instances.
To prevent them from being destroyed and declared every time the function is called?
this typically takes the form:
class Terrain {
public:
// interface
protected:
// more stuff
private:
// ... existing variables
const float d_terrainWidth;
const float d_terrainLength;
const float d_startWidth;
const float d_startLength;
};
then you can use the precalculated invariants from your Draw implementation.
Yes, and while you are there, make them const too. Both of these can be hints to the compiler to optimize these function variables.
Though the difference would be so mininal you'd need at least 25,000 calls per second to make this worthwhile.