Dynamic struct member damaged while passing to function using CUDA/NVCC
I'm experimenting with CUDA and I ran into a very strange bug. I have the following files (tl;dr, skip them):
main.cpp
#include "main.h"
#include "list.hpp"
void print_graph(Graph& g);
void init(Graph& g) {
g.list = new List<int>;
for (int j = 0; j < 5; j++) {
g.list->push_back(j+1);
}
}
int main()
{
Graph g;
init(g);
print_graph(g);
delete g.list;
}
main.h
#include "list.hpp"
#ifndef _MAIN_H_
#define _MAIN_H_
struct Graph {
int foo;
double bar;
List<int> *list;
};
#endif
printer.cu
#include "main.h"
#include "list.hpp"
#include <cstdio>
void print_graph(Graph& g) {
List<int>::iterator it;
for (it = g.list->begin(); it != g.list->end(); it++) {
printf("%d\t", *it);
}
printf("\n\n");
}
list.hpp
Contains a class named List, similar to STL list. Becouse of it's length, code omitted, can be foud here: Custom list sourceIf I compile and run this, I get a segfault. It works as expected, if I issue any of the following changes:
- rename printer.cu to printer.cc, so nvcc is out of the game.
- change the order of definition of foo and bar in
struct Graph
(!) - change the type of
bar
(doesn't work if I change the type offoo
)
Still doesn't wor开发者_运维百科k if I prefix print_graph with __host__
.
The segfault occurs becouse the Graph variable doesn't arrive in print_graph. It's list member contains memory trash, so the listing will fail. (I can't pass any other member value)
So my question is: What did I miss? What the hell is going on? Thanks for the read, any help is appreciated.
The issue of alignment requirements in structures is discussed in some detail in Chapter 3 of the CUDA programming guide. The short answer is passing -malign-double to nvcc should fix the issue.
精彩评论