Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Oakland Martini posted:

I have a function

You're calling diff_evo_gpu without a declaration in scope (or with only an unprototyped declaration, i.e. "uint diff_evo_gpu();"). This forces the caller to use the varargs convention, under which floats are promoted to (and passed as) doubles. The function definition in diff_evo_gpu.cu is compiled with a prototype, so the ABI avoids the unnecessary promotion, which is good! except that it then misinterprets the doubles it's being passed.

The solution is to always, always, always declare your functions. Put uint diff_evo_gpu(uint, uint, uint, uint, float, float, float, float*, float*, float*); in some header which is #included in both files. Since this function is being called from C, you'll need to surround the declaration with "extern "C"" when it's being compiled by a CUDA compiler.

Adbot
ADBOT LOVES YOU

Oakland Martini
Feb 14, 2008

D&D: HASBARA SQUAD
THE APARTHEID ACADEMIC


It's important that institutions never take a stance like "genocide is bad". Now get out there and crack some of my students' skulls.

rjmccall posted:

You're calling diff_evo_gpu without a declaration in scope (or with only an unprototyped declaration, i.e. "uint diff_evo_gpu();"). This forces the caller to use the varargs convention, under which floats are promoted to (and passed as) doubles. The function definition in diff_evo_gpu.cu is compiled with a prototype, so the ABI avoids the unnecessary promotion, which is good! except that it then misinterprets the doubles it's being passed.

The solution is to always, always, always declare your functions. Put uint diff_evo_gpu(uint, uint, uint, uint, float, float, float, float*, float*, float*); in some header which is #included in both files. Since this function is being called from C, you'll need to surround the declaration with "extern "C"" when it's being compiled by a CUDA compiler.

Ah, that does it. For some reason I forgot to make a header file for the GPU version of my code; the CPU version has one (which is why it works fine I guess).

Mr VacBob
Aug 27, 2003
Was yea ra chs hymmnos mea
-Wall in gcc will catch this. -Werror=implicit will catch it even better.

Foiltha
Jun 12, 2008
Why does Mingw choke on this code:
http://codepad.org/6rjZ5tOT

It seems to compile fine under Codepad.org (which uses G++) but QTCreator + Mingw can't seem to figure it out:

code:
Matrix5.h: In static member function 'static Matrix5<T> Matrix5<T>::perspectiveProjection(T, T, T, T)':
Matrix5.h:50: error: expected primary-expression before ')' token
Matrix5.h:50: error: expected primary-expression before ')' token
Matrix5.h:52: error: expected primary-expression before ')' token
Matrix5.h:52: error: expected primary-expression before ')' token
The error lines are the ones related to the following:
code:
        m.data[0] = f / aspect;
        m.data[5] = f;
        m.data[10] = (far + near) / (near - far);
        m.data[11] = -1;
        m.data[14] = (2 * far * near) / (near - far);
I'm pretty stumped with this. That function isn't really doing anything different from the scale and translate functions but the compiler only complains about the projection function.

That Turkey Story
Mar 30, 2003

Foiltha posted:

I'm pretty stumped with this. That function isn't really doing anything different from the scale and translate functions but the compiler only complains about the projection function.

I could be way off, but try renaming your "near" and "far" parameters to something else -- perhaps they are #defined.

That Turkey Story
Mar 30, 2003

Has anyone had to battle with "cc1plus.exe: out of memory allocating some-number-of bytes" when compiling? I've tried compiling with no optimizations to no avail. The code is a single translation unit that's a Boost.MSM state machine with a little over 30 transitions and nothing else. Are there any options I should be aware of to lower the compiler's memory usage (not using MSM is not an "option")? The code itself likely can't be simplified very much and is only going to get more complicated.

Edit: Also tried using MSM's favor_compile_time policy

Edit2: Gonna change it to not use euml... this fixed it

That Turkey Story fucked around with this message at 07:20 on Aug 18, 2010

Foiltha
Jun 12, 2008

That Turkey Story posted:

I could be way off, but try renaming your "near" and "far" parameters to something else -- perhaps they are #defined.

That was it, thanks! I was convinced I was messing up with the templates.

wasabimilkshake
Aug 21, 2007

North Carolina votes yes.
I have a somewhat trifling C++ question.

This class is a shape which consists of n vertices, each vertex having a 3D position and a pair of UV coordinates. I need to be able to flip those UV coordinates horizontally and vertically, and I need to have independent control over flipping U and flipping V. So, here's a method which flips the UV coordinates horizontally:

code:
void Textured2DShape::FlipUVsHorizontally()
{
	if (mVertices.empty())
		return;

	// Find the horizontal center of the U coordinates
	float leftmost = mVertices[0].uv.x;
	float rightmost = mVertices[0].uv.x;

	for (unsigned int i = 1; i < mVertices.size(); i++)
	{
		if (mVertices[i].uv.x < leftmost)  leftmost = mVertices[i].uv.x;
		if (mVertices[i].uv.x > rightmost) rightmost = mVertices[i].uv.x;
	}	

	float center = leftmost + ((rightmost - leftmost) * 0.5f);

	// Reflect each point about the center in U
	for (unsigned int i = 0; i < mVertices.size(); i++)
		mVertices[i].uv.x = center + (center - mVertices[i].uv.x);
}
Now I need a similar method to flip vertically. In order to do that in the most readily apparent way, I'd copy and paste the previous method and replace every instance of 'uv.x' with 'uv.y'. That'd work fine, but it just feels sloppy (and I hate having to change something in more than one place). My question: what's the best way to refactor this flipping functionality so that the same code can be applied to both axes?

Here's what I've come up with:
code:
void Textured2DShape::FlipUVs(int structOffset /*= 0*/)
{
	if (mVertices.empty())
		return;

	// Find the center of the coordinates
	float leftmost = *((float*)&mVertices[0].uv + structOffset);
	float rightmost = *((float*)&mVertices[0].uv + structOffset);

	for (unsigned int i = 1; i < mVertices.size(); i++)
	{
		float* pCurrentCoordinate = (float*)&mVertices[i].uv + structOffset;

		if (*pCurrentCoordinate < leftmost)	 leftmost = *pCurrentCoordinate;
		if (*pCurrentCoordinate > rightmost) rightmost = *pCurrentCoordinate;
	}	

	float center = leftmost + ((rightmost - leftmost) * 0.5f);

	// Reflect each point about the center
	for (unsigned int i = 0; i < mVertices.size(); i++)
	{
		float* pCurrentCoordinate = (float*)&mVertices[i].uv + structOffset;
		*pCurrentCoordinate = center + (center - *pCurrentCoordinate);
	}
}

void Textured2DShape::FlipUVsHorizontally()
{
	FlipUVs(0);
}

void Textured2DShape::FlipUVsVertically()
{
	FlipUVs(1);
}
Is this a sensible way of doing this? Is there a better, more widely-used method of achieving the same result? Am I splitting hairs and trading an insignificant amount of function-call overhead for an insignificant amount of program memory?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe
The disciplined solution is to use member pointers.

code:
void Textured2DShape::FlipUVs(float UV::*field) {
  float leftmost = mVertices[0].uv.*field;
  ...
}

FlipUVs(&UV::x);
If you decide you can't afford the abstraction penalty, you can even template the method over the member pointer instead of passing it as a parameter:
code:
template <float UV::*field> void Textured2DShape::FlipUVs() { ... }
FlipUVs<&UV::x>();
The less disciplined solution is to use a preprocessor macro.

wasabimilkshake
Aug 21, 2007

North Carolina votes yes.

rjmccall posted:

member pointers.
Oh, cool, that's definitely a cleaner solution -- I wasn't fully aware that member pointers existed. Most of my CS background comes from freely available online lectures, and most of the ones I've watched are more focused on C, so I guess that's where my head was. Thanks for the quick C++ lesson.

functional
Feb 12, 2008

How do I reuse pthreads in C? Or create something like a thread pool? I'm performing a large number of parallelizable tasks and I don't want the overhead of recreating my threads every time. I have not been able to find good documentation online.

functional fucked around with this message at 00:37 on Aug 19, 2010

litghost
May 26, 2004
Builder

functional posted:

How do I reuse pthreads in C? Or create something like a thread pool? I'm performing a large number of parallelizable tasks and I don't want the overhead of recreating my threads every time. I have not been able to find good documentation online.

Message queue + function pointers?

Something like (types made up on the fly):
code:
typedef void(*work_fun_t)();
void thread_entrypoint(void * p)
{
   queue_t * workqueue = (queue_t*)p;

   while(1)
   {
       work_fun_t *work = wait_for_work(workqueue);

       work();
   }

}
There are probably ready made solutions you could use too.

litghost fucked around with this message at 03:25 on Aug 19, 2010

MrMoo
Sep 14, 2000

litghost posted:

There are probably ready made solutions you could use too.

Picking one at random: http://code.google.com/p/pthread-lib/

You could also use GLib which has thread pool support: http://library.gnome.org/devel/glib/unstable/glib-Thread-Pools.html

Blotto Skorzany
Nov 7, 2008

He's a PSoC, loose and runnin'
came the whisper from each lip
And he's here to do some business with
the bad ADC on his chip
bad ADC on his chiiiiip
One of the first google results for 'thread pool pthreads' is a sample implementation by Sun

litghost
May 26, 2004
Builder

MrMoo posted:

Picking one at random: http://code.google.com/p/pthread-lib/

You could also use GLib which has thread pool support: http://library.gnome.org/devel/glib/unstable/glib-Thread-Pools.html

Worth noting that pthread-lib hasn't had any work done on it since 2008. Of course it could have zero bugs! Oh and has little documents, and no examples.

Glib stuff looks like a safer bet.

MrMoo
Sep 14, 2000

litghost posted:

Worth noting that pthread-lib hasn't had any work done on it since 2008. Of course it could have zero bugs! Oh and has little documents, and no examples.

I saw a March 2010 update and thought it was still going, but that was a performance improvement suggestion.

Rocko Bonaparte
Mar 12, 2002

Every day is Friday!

rjmccall posted:

The disciplined solution is to use member pointers.
Just wanted to say I was following along and have been chewing on that concept now that you mentioned it. I think I have some similarly duplicated code that could benefit from that too.

Vinterstum
Jul 30, 2003

functional posted:

How do I reuse pthreads in C? Or create something like a thread pool? I'm performing a large number of parallelizable tasks and I don't want the overhead of recreating my threads every time. I have not been able to find good documentation online.

You could do worse than http://www.threadingbuildingblocks.org/

FamDav
Mar 29, 2008

rjmccall posted:

The disciplined solution is to use member pointers.

code:
void Textured2DShape::FlipUVs(float UV::*field) {
  float leftmost = mVertices[0].uv.*field;
  ...
}

FlipUVs(&UV::x);

Probably a silly question, but why is it "UV::*field" but not "UV::&x" (or vice versa)?

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

FamDav posted:

Probably a silly question, but why is it "UV::*field" but not "UV::&x" (or vice versa)?

Because they behave like pointers, not like references: you can have null member pointers, the syntax to use them involves a star, etc.

FamDav
Mar 29, 2008
EDIT: Got it.

FamDav fucked around with this message at 11:24 on Aug 20, 2010

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

I'm stuck using this particular C++ graph library for part of this research project, which has the unfortunate corollary that I have to buckle down and familiarize myself with the drat language. :smith:

I'm implementing a visitor class that operates over a templated digraph class. Now, all graph classes in this library have a Node inner class. So with that in mind,

code:
 
 13 template <class DG>
 14 void ContractionVisitor<DG>::start(const DG::Node &n)     
 15 {
...
 17 }
 18 
 19 template <class DG>
 20 void ContractionVisitor<DG>::reach(const DG::Node &n)
 21 {   
...
 33 }
 34 
yields


g++ -g -I./include/ -c -Wall src/bb_visitor.cpp -o src/bb_visitor.o
src/bb_visitor.cpp:14: error: expected unqualified-id before ‘&’ token
src/bb_visitor.cpp:14: error: expected ‘)’ before ‘&’ token
src/bb_visitor.cpp:14: error: expected initializer before ‘&’ token
src/bb_visitor.cpp:20: error: expected unqualified-id before ‘&’ token
src/bb_visitor.cpp:20: error: expected ‘)’ before ‘&’ token
src/bb_visitor.cpp:20: error: expected initializer before ‘&’ token


So, is it not the case that "DG::Node" implicitly puts the constraint on class DG that the inner Node class exists? Or am I just doing this outright incorrectly?

OddObserver
Apr 3, 2009
I think you need to use 'typename DG::Node' and not 'DG::Node' in this sort of a templated context to help disambiguate some parsing complications.

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

OddObserver posted:

I think you need to use 'typename DG::Node' and not 'DG::Node' in this sort of a templated context to help disambiguate some parsing complications.
:suicide: Yep, that was it. Thanks.

Irving
Jun 21, 2003
I've been banging my head against the wall about this for about a day, and I need some fresh eyes from people who actually know what the gently caress in C++. So, here's the setup:

thing.h:

code:
class NestedObject{

public:
    //two values is just a template that makes a pair of whatever type is input,
    //in this case a pair of floats.
    sps::vector<<TwoValues<float> > list;

    sps::vector<float> annotate;

    char *info;

    NestedObject() {
        list.resize(0);
        annotate.resize(0);
        info = (char *) 0;
    }
    ~NestedObject();

    unsigned int resize(unsigned int newSize) {
    	annotate.resize(newSize);
        list.resize(newSize);
        return list.size();
    }

   TwoValues<float> &operator[](unsigned int i) {
        return list[i];
    }

    const TwoValues<float> &operator[](unsigned int i) const {
        return list[i];
    }

    unsigned int size() const {
        return peakList.size();
    }

    NestedObject &operator=(const NestedObject &other);

}

class Object {
    sps::vector<NestedObject> objects;

 
    Object(unsigned int sz = 0) {
        objects.resize(sz);
   }
   
    NestedObject &operator[](unsigned int i) {
        return objects[i];
    }

    const NestedObject & operator[](unsigned int i) const {
        return objects[i];
    }

    unsigned int size() {
        return objects.size();
    }

    unsigned int resize(unsigned int newSize) {
        objects.resize(newSize);
        return objects.size();
    }
}
thing.cpp

code:
NestedObject::~NestedObject() {
  if(info!=(char *)0) free(info); info=(char *)0;
  list.clear();
  annotate.clear();
}

NestedObject &NestedObject::operator=(const NestedObject &other) {
    list.resize(other.list.size());
    for (unsigned int i=0; i<other.list.size(); i++) list[i]=other.list[i];
    for (unsigned int i=0; i<other.annotate.size(); i++) annotate[i]=other.annotate[i];
    return(*this);
}

unsigned int Object::LoadNestedObject(const char *filename) {
   //a bunch of unimportant file processing stuff happens here.
    objects.resize(7000); //<------ SEGMENTATION ERROR!
}
I've tried to trim down the code as much as possible, so if there's some essential information that's missing, let me know. Basically, I have a class with two vectors and other class that has members of that class as a vector. When I try to resize the vector that contains the nested class, I get a segmentation fault.

It's very frustrating because when I just have the "list" vector, everything works fine. It's only when I add the "annotate" vector that everything goes pear shaped. Is it something to do with how I'm initializing NestedObject? Am I missing something really simple here?

OddObserver
Apr 3, 2009
NestedObject &NestedObject::operator=(const NestedObject &other)
doesn't resize annotate.

Beyond that, use a memory debugger --- if you're on Linux or OS X, use Valgrind.
It's quite possible that the "unimportant stuff" you cut out is what's actually
screwing up.

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

Valgrind is probably overkill in this case; simply compiling with debuginfo, running it in gdb and looking at the backtrace should track the problem down pretty quickly.

Sabotaged
Jul 6, 2004

As Dijkstracula mentions, a stack trace would help. Also why are you using free()?

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
I have a debugging situation I've never really encountered before, and, thinking ahead, a similar situation will probably arise after my thing is in beta.

So, what's going on is that I have a multithreaded networked game, in Windows. In order to test the network stuff I obviously have to run (at least) two instances. That means one under the debugger and one not. If I put a breakpoint in the debugger one, the other one crashes. That's fine and expected at this stage, and I could probably find the problem and fix it without too much effort, but it leads to my question - how do you make it so a program running not under the debugger will, upon crashing, dump a state that can be used to find the error?

Once it's in beta I'm sure other people will find ways to crash it, and I'd really like reports to be more useful than "hey it crashed when I did something". Ideally automatic crash reports, but I'm not willing to do it the Windows way that appears to require an annual $500 payment to Verisign.

It looks like SetUnhandledExceptionFilter would be the way to go about this, and possibly MiniDumpWriteDump, but I'm having trouble finding a coherent "here is how to get the file and line number of your crash". (I'm assuming I could either include the debug info with beta versions, or have the dump provide something that can be sent to me and can then be cross-referenced against the debug info generated by Visual Studio to give a file and line number.)

tldr; how do you make a program crash-dump info in a form that can be turned into a file and line number (and ideally but not necessarily also stack trace)?

Irving
Jun 21, 2003

Sabotaged posted:

As Dijkstracula mentions, a stack trace would help. Also why are you using free()?

I took a look at the stacktrace and it wasn't particularly helpful, but after changing something it seems to have fixed the problem. Frustrating. As for why I'm using free...it's because someone else gave me the code and that line was already there. It didn't make any sense to me either, but it was in the code.

pseudorandom name
May 6, 2007

roomforthetuna posted:

tldr; how do you make a program crash-dump info in a form that can be turned into a file and line number (and ideally but not necessarily also stack trace)?

http://code.google.com/p/google-breakpad/

roomforthetuna
Mar 22, 2005

I don't need to know anything about virii! My CUSTOM PROGRAM keeps me protected! It's not like they'll try to come in through the Internet or something!
Thanks, that looks like pretty much what I was looking for (and also suggests that the way I was thinking of implementing it was right, hooray!)

I even saw that mentioned in the "how does your company do bug reports" thread, but it was mentioned amongst such contenders as Bugzilla so I didn't parse it as being an auto-reporting thing. Cheers.

Edit: what the gently caress is all this bullshit with having outdated install instructions -> now requiring gyp contrary to instructions -> which in turn has poo poo install instructions -> requires python. I'm sure this is all perfectly fine in Linux but in Windows it's no fun at all. Oh, and both gyp and breakpad only downloading with svn, so there's another stupid requirement too.

roomforthetuna fucked around with this message at 02:45 on Aug 23, 2010

Jose Cuervo
Aug 25, 2004
I am trying to write a little program that reads in data from a file with a specific structure to it so that I can then analyze it.

The code can be found here and here, and a test file to be read in is located here. My code compiles, but the problem is when the function readInData is done the pointers lbLmaxVals, lmaxVals, fmaxVals, and numAllocsSearched all still point to NULL.

I know I am probably doing something stupid and that there is a simple fix for this, but I cannot figure it out.

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

Jose Cuervo posted:

I am trying to write a little program that reads in data from a file with a specific structure to it so that I can then analyze it.

The code can be found here and here, and a test file to be read in is located here. My code compiles, but the problem is when the function readInData is done the pointers lbLmaxVals, lmaxVals, fmaxVals, and numAllocsSearched all still point to NULL.

I know I am probably doing something stupid and that there is a simple fix for this, but I cannot figure it out.
You're not passing the address of lbLmaxVals, lmaxVals, fmaxVals, etc to readInData, so those variables in main() aren't ever going to be changed.

Jose Cuervo
Aug 25, 2004

Dijkstracula posted:

You're not passing the address of lbLmaxVals, lmaxVals, fmaxVals, etc to readInData, so those variables in main() aren't ever going to be changed.

Any advice on how to pass the address of the four variables to readInData so that they will be changed?

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

Jose Cuervo posted:

Any advice on how to pass the address of the four variables to readInData so that they will be changed?
Why, the addressof operator!

Sounds to me like you're in need of a proper C book. this or this.

Jose Cuervo
Aug 25, 2004

Dijkstracula posted:

Why, the addressof operator!

Sounds to me like you're in need of a proper C book. this or this.

I changed the call to readInData in the function main to the following:

code:
readInData(numRuns, &lbLmaxVals, &lmaxVals, &fmaxVals, &numAllocsSearched);
but now I get the following error:
error C2664: 'readInData' : cannot convert parameter 2 from 'long ***__w64 ' to 'long **' main.cpp 25

I do not understand how to fix this problem either, or if I was trying to fix the problem in the correct way.

Mustach
Mar 2, 2003

In this long line, there's been some real strange genes. You've got 'em all, with some extras thrown in.
If you don't know what else needs to change to make that work, you really do need to pick up a book and/or the standard. Your life will be filled with pain if you try to learn the fundamentals of C++ via the Internet and rearranging your program in ways that probably seem completely random to someone of your knowledge level.

When you want write a function that modifies a variable of type T, you have two options, a function that takes a pointer to the variable or a function that takes a reference to the variable:
code:
void mutate_via_ref(T &t){ t = whatever; }
void mutate_via_ptr(T *t){ *t = whatever; }

...

T var;
mutate_via_ref(var);
mutate_via_ptr(&var);
readInData is already using a reference to int, runNumber. It's the same idea for the remaining arguments (where T is long** and then long*).

Mustach fucked around with this message at 16:10 on Aug 23, 2010

Dijkstracula
Mar 18, 2003

You can't spell 'vector field' without me, Professor!

I was also going to say: this mixing of C and C++ idioms (ie. runNumber is being passed by reference, but you're also using raw pointers instead of STL containers) is bad. Choose one language and stick with it. (If it's C++ you decide on, Accelerated C++ is the book everyone uses)

Adbot
ADBOT LOVES YOU

Jose Cuervo
Aug 25, 2004

Mustach posted:

If you don't know what else needs to change to make that work, you really do need to pick up a book and/or the standard. Your life will be filled with pain if you try to learn the fundamentals of C++ via the Internet and rearranging your program in ways that probably seem completely random to someone of your knowledge level.

When you want write a function that modifies a variable of type T, you have two options, a function that takes a pointer to the variable or a function that takes a reference to the variable:
code:
void mutate_via_ref(T &t){ t = whatever; }
void mutate_via_ptr(T *t){ *t = whatever; }

...

T var;
mutate_via_ref(var);
mutate_via_ptr(&var);
readInData is already using a reference to int, runNumber. It's the same idea for the remaining arguments (where T is long** and then long*).

I agree with you with regards to picking up a book. Just to make sure I am understanding this, this is what I did:

code:
void readInData(int &runNumber, long int* *&lbLmaxVals, long int* *&lmaxVals, long int* *&fmaxVals, int *&numAllocsSearched)
and the call to readInData in main to

code:
readInData(runNumber, lbLmaxVals, lmaxVals, fmaxVals, numAllocsSearched)
which compiles and works.
Is the following reasoning correct:
The code long int* *&lbLmaxVals tells the function readInData that lbLmaxVals is a reference to a pointer to a pointer to long int? Whereas before the code long int* *lbLmaxVals just told the function readInData that lbLmaxVals was just a pointer to a pointer to long int, and a copy was made of this pointer to a pointer to long int?

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply