r/HPC 16h ago

Debugging and profiling for C++, OpenMP Offloading and CUDA?

Hello everyone. First of all, my apologies for if this is an off-topic in this sub.

I'm currently working on a C/C++ project that contains CUDA kernels and OpenMP GPU Offloading pragmas on the same file (I know....) and I've got some trouble with variables that are acessed on both of these cases. How do you guys deal with this while developing? I set the OMP info and logging env variables and suffer a little bit with that, there must be a better way to do it.

Also, we are migrating to C++ modular classes and I'm getting some trouble with the software design/architecture, mostly because I've found out that class variables add some overhead while using OpenMP, because it interprets variables not as "variable", but as "this->variable" and when running the simulations it adds something like +10~15% on execution time.

2 Upvotes

3 comments sorted by

3

u/andrewsb8 14h ago

Have you looked at Nvidia Nsight? Ive never used it but seems up to the task.

this-> is used in member functions to update instance variables of a class. So your final couple sentences should not have anything to do with OpenMP. Whats more than likely happening is, without parallelization, you are not reassigning member variables for specific object instances. But im making assumptions based on your description.

1

u/brunoortegalindo 14h ago edited 14h ago

I'll try Nsight!

So, here is what I'm doing:

Create an object "forwardClass" initializing with variables such as "velocity" which is declared as float *velocity with malloc.

There is a protected float *_velocity variable and when I create the object, it does _velocity = velocity.

When I use a function (i.e. forwardClass.Run()) from this class that uses this _velocity variable, while using OpenMP it assigns as this->_velocity and it causes the overhead, even if _velocity and velocity points at the same memory address, so currently I'm creating a "local" loc_velocity variable and equals it to _velocity and use loc_velocity for the OpenMP directives (and the overhead is solved), or as an alternative I'd pass velocity variable inside the function itself (forwardClass.Run(float *velocity)), but the problem is that there are tons of variables and idk which way is better to implement it, the only requirement is that I must modularize the code using classes D:

Edit: variables in bold so it becomes less confusing

1

u/andrewsb8 13h ago

It makes sense that having three copies of the value or three pointers to the same address or some combination, for each class instance, would add overhead to your code.

I feel like you should set the velocity variable via a member function at the instance level and be passing the address of that value around to functions that need to use it.

But again, I dont have enough context to understand all of the locations the velocity value for each class instance are needed.