Today, I'm trying to launch my CUDA C/C++ program from a C# application.
So, I did some research on the web, but I didn't found that much information. I only saw the "GitHub" but, no...
So I've got a Kernel defined like follow :
(that's an example)
__global__ void kernel(Cartesian a, Cartesian b, Cartesian *c)
With "Cartesian" :
class Cartesian
{
public:
double x;
double y;
double z;
};
With what I understand from managedCUDA. It's like replacing the main function of a CUDA C/C++ program. Using a lib that "do the work for us"
So i followed an example from this page :
https://algoslaves.wordpress.com/2013/08/25/nvidia-cuda-hello-world-in-managed-c-and-f-with-use-of-managedcuda/
And write my C# program like this :
The part that create the context : (dont really get this "notion")
static void InitKernels()
{
CudaContext cntxt = new CudaContext();
CUmodule cumodule = cntxt.LoadModule(#"C:\Users\stage\Documents\Visual Studio 2013\Projects\Cs_link_test\Cs_link_test\x64\Release\kernel.ptx");
addWithCuda = new CudaKernel("kernel", cumodule, cntxt);
}
The part that launch (I guess) the function and get back the modification made by the kernel :
static Func<Cartesian, Cartesian, Cartesian> cudaAdd = (a, b) =>
{
CudaDeviceVariable<Cartesian> result_dev;
Cartesian result_host;
addWithCuda.Run(a, b, result_dev.DevicePointer);
result_dev.CopyToHost(ref result_host);
return result_host;
};
And from this part I don't understand anything from the line :
static Func<Cartesian, Cartesian, Cartesian> cudaAdd = (a, b) =>
I'm not familiar with C# (just saying)
So my problem come from the error caused by result_dev and result_host;
The error says :
Use of unassigned local variable 'result_*'
So, is it because they arren't initialized ?
If so, why result_host cause an error ? It must get the data from result_dev which must be modified by the kernel..
If not, how to fix this ?
And I also wanted to know, is it possible to passe Class parameter through a kernel function ? If so, how to set a CudaDeviceVariable, cause it says that the type must be non-nullable. It's why I change class with struct.
Ok so.. I just figured out how to solve my problem. Read the "discussion" section on https://managedcuda.codeplex.com/discussions/659183 help me to do it. So how to proceed to pass struct parameter to a kernel using managedCUDA ?
First thing I did wrong (I guess) is to use the Func<T, T, T>part.
You must declare your class in your .cu file like follow :
class Cartesian
{
public:
double x;
double y;
double z;
}
And the same in your .cs file like follow :
[StructLayout(LayoutKind.Sequential)]
struct Cartesian
{
public double x;
public double y;
public double z;
public Cartesian(double x, double y, double z) { this.x = x; this.y = y; this.z = z; }
};
Then you can initialize your kernel as you want, I do it like this :
static void InitKernels()
{
CudaContext ctx = new CudaContext();
CUmodule cumodule = ctx.LoadModule(#"C:\Users\stage\Documents\Visual Studio 2013\Projects\Cs_link_test\Cs_link_test\x64\Release\kernel.ptx");
kernel = new CudaKernel("kernelPosGeo", cumodule, ctx);
kernel.BlockDimensions = 1024;
kernel.GridDimensions = 614;
}
And what you need to do is simply call your kernel with the parameters you want.
Cartesian a = new Cartesian(1, 2, 3);
kernel.Run(a);
I guess I had a problem because I used Func<T, T,T> but till I don't use it anymore, it seems easier. And the declaration of Func had at maximum 2 parameter in and 1 out. So I've got a Kernel that have 4 or 5 parameters and I was limited here... But right now, do not have any problem.
Related
In C# 8.0, Static Local Functions are announced
Can anyone help enlighten me as to why you would want to declare a local function as static?
The reason given in in the article:
to ensure that local function doesn't capture (reference) any variables from the enclosing scope
But:
I don't understand why would you want to ensure that?
Is there any other reason or benefits to declare it static? (performance maybe?)
The example code given in the article is:
int M()
{
int y = 5;
int x = 7;
return Add(x, y);
static int Add(int left, int right) => left + right;
}
I don't understand why would you want to ensure that?
Because it prevents you from shooting yourself in the foot. It forces the local function to be a pure function that does not modify the state of the caller.
This returns false, because the function modifies local variables of its caller:
public bool Is42()
{
int i = 42;
Foo();
return i == 42;
void Foo()
{
i = 21;
}
}
And this doesn't, because it doesn't even compile:
public bool Is42()
{
int i = 42;
Foo();
return i == 42;
static void Foo()
{
i = 21;
}
}
It prevents surprises. Of course in these simple examples the benefit isn't immediately clear, because "well it's obvious that Foo() modifies i", but in larger codebases maintained by multiple people and not properly covered by unit tests, this simple modifier prevents grief.
Capturing variables has a small additional cost as it will generate an internally used type where your captured variables are public fields. Consider a slightly modified example:
int M()
{
int y = 5;
int x = 7;
return Add();
int Add() => x + y;
}
It will actually translate to something like this:
int M()
{
int y = 5;
int x = 7;
var capturedVars = new <>c__DisplayClass0_0 { x = x, y = y };
return <M>g__Add|0_0(ref capturedVars);
}
[CompilerGenerated]
private struct <>c__DisplayClass0_0
{
public int x;
public int y;
}
[CompilerGenerated]
internal static int <M>g__Add|0_0(ref <>c__DisplayClass0_0 class_Ref1) =>
(class_Ref1.x + class_Ref1.y);
This answer from CodeCaster and this separate answer from György Kőszeg individually answer different parts of my question, so I'm bringing them both together to form the full picture for the accepted answer:
For Part 1) of my question, #CodeCaster Says:
Because it prevents you from shooting yourself in the foot. It forces the local function to be a pure function that does not modify the state of the caller.
in larger codebases maintained by multiple people and not properly covered by unit tests, this simple modifier prevents grief
So Answer 1 is: Static Local Functions ensure reliable caller method state.
For Part 2) of my question, #György Kőszeg Says:
Capturing variables has a small additional cost as it will generate an internally used type where your captured variables are public fields
And he goes on to give an example of the produced compiler code via reflector.
So Answer 2 is: Static Local Functions prevent variable capturing. Variable capturing comes at a small cost. So there is a small performance boost by declaring the local function static
I think this is just to ensure correct usage of the variables used in the local function, as the documentation says. In large and complex methods, it can prevent accidental usage of enclosing scope variables if there are variables with the same name in the local function.
I have a function written in c++ that I put in a dll and use in c# using DllImport. Everything works; I am able to get the return value from c++ and display it in my c# GUI. Now I want to add to that function and have it return multiple values (3 so far). I've tried the methods given in Return C++ array to C# and How to return two different variable in c++? but neither work.
The code from the first post gives me an access violation error and the code form the second one gives me all 0 values for the struct. For the first one, I even copied the given code exactly and tried to run it but to no avail. What could be causing the errors and wrong values given by these methods? How can I get them to work?
Just in case it is needed, my own code with the implementation of the second post is below.
bisection.h
struct Result
{
double root;
double relError;
double absError;
}result;
extern "C" {__declspec(dllexport) Result bisection( double l, double u, double stoppingError, int maxIter); }
bisection.cpp
Result bisection(double l, double u, double stoppingError, int maxIter) {
//code for this function
result.root = xr;
result.relError = e;
result.absError = 1;
return result;
}
c# code
[StructLayout(LayoutKind.Sequential)]
public struct Result
{
public double root;
public double relError;
public double absError;
}
[DllImport(dllPath)]
private static extern Result bisection(double l, double u, double stoppingError, int maxIter);
Result result = bisection(data[0], data[1], 0.1, 100);
Your code is almost correct. There is a mismatch of calling convention. The C++ code uses cdecl, the C# stdcall. Change one so that they match.
While I realize I'm not being very rigorous, I'm pretty sure the definition of a combinator in simple terms is simply a function with no free variables. For example,
f(x,y) = x + y
would be a combinator and
f(x,y) = x * 2
would not be because y would be free.
So given that understanding would a member variable in a class definition be considered "free"? I'm guessing it would but I wanted to check my assumption. Code like this C# example:
namespace ConsoleApplication1
{
class BoundOrFree
{
private int _i = 0;
public int f(int x, int y)
{
return x + y + _i;
}
}
}
In the BoundOrFree.f member function is _i free? Would f therefore not be a combinator? I'm assuming the answer to both of those questions would be yes but I wanted to confirm my assumption.
would not be because y would be free
you misinterpret the "free" term in this case. Free variable is the one that was captured from the outer scope (via a closure). So f(x,y) = x * 2 is a combinator.
Answering your question
In the BoundOrFree.f member function is _i free? Would f therefore not be a combinator?
the BoundOrFree::f function is not a combinator, since it uses variables other than its only arguments.
I mean
double x=5;
double k=Func(x+3.5,h+1.2);//I send x=8.5
double y=x;//x=5;
I want to change it when I send it.
double x=5;
double k=Func(x+3.5,h+1.2);
double y=x;//x=8.5
Is it possible to do?
Please don't do this. Yes. That's my answer.
It is, however, possible because assignment statements with side-effects by definition can be used as expressions. I have removed the extra code that didn't seem to apply.
void Func (double _x) {
// do nothing
// _x = 8.5 when invoked from below
}
double x = 5;
Func(x = x + 3.5); // or Func(x += 3.5)
// x = 8.5
The above is [almost always] much better written with the assignment -- and thus side-effect -- kept separately from the function call itself: (In most cases, both forms have identical semantics.)
x += 3.5;
Func(x);
Happy coding.
If you do wish to use out/ref, keep in mind that it only makes sense to use variables as the out/ref parameters: the expression x + 3.5 is not a variable -- it cannot be assigned to -- and is thus unsuitable. (I believe VB.NET also allows properties.)
void Add(ref double _y, double s) {
// _y = 5
_y += s;
// _y = 8.5
}
double y = 5;
Add(ref y, 3.5);
// y = 8.5
Maybe something like this:
double x=5;
double k=Func(x+=3.5,h+1.2);
double y=x;//x should be 8.5
This way x evaluates to 8.5 before the function is called.
But, may I ask why the need to do this?
Your problem is that you are passing the x variable by copy not by reference. This is why x is still 5 after your functions finishes. You should change your function h from:
h(int x, int y)
to
h(int * x, int *y)
EDIT :
With pointers you pass the variable x and do all your operations on it. With no pointers, the function creates a copy of the variable x and works on it then destroys it when the functions ends. So the real x is not modified.
Pointers and references work together. You declare the function with pointers and pass the variables with reference
There is a well known issue when it comes to using .NET value types in IronPython. This has recently caused me a headache when trying to use Python as an embedded scripting language in C#. The problem can be summed up as follows:
Given a C# struct such as:
struct Vector {
public float x;
public float y;
}
And a C# class such as:
class Object {
public Vector position;
}
The following will happen in IronPython:
obj = Object()
print obj.position.x # prints ‘0’
obj.position.x = 1
print obj.position.x # still prints ‘0’
As the article states, this means that value types are mostly immutable. However, this is a problem as I was planning on using a vector library that is implemented as seen above. Are there any workarounds for working with existing libraries that rely on value types? Modifying the library would be the very last resort, but I'd rather avoid that.
There's no need to modify the library, just use a proxy.
struct Vector {
public float X;
public float Y;
}
class BetterVector {
public float X;
public float Y;
public Vector Optimized { get { return new Vector(X, Y); } }
}
class Object {
public BetterVector Position { get; set; }
}
Now the Python code can set fields as normal and your code can call Optimized when it needs to feed the data to OpenGL or XNA or whatever you're using.
You can even use implicit coercion if calling Optimized seems like too much work:
class BetterVector {
// ...
public static implicit operator Vector(BetterVector v) {
return v.Optimized;
}
}
When you call
obj.position.x = 1
What you get is that the obj object gets you an instance of the position struct, which it essentially makes a copy of, so, setting the X value doesn't get propogated.
What you're saying is that obj.position = Vector(1,0) is what you should be doing. Similar things happen in C#.
Edit - possible work around.
If you don't want to set up the constructor, I believe this will work:
obj = Object()
pos = obj.position; # gets the object
pos.x = 1
pos.y = 2
obj.position = pos # I'm not sure if this line is necessary
The only way I've found to update structs is to make use of the fact that you can specify any public field/property when creating a struct. The syntax looks like named/optional parameters in Python.
namespace StructExample
{
public struct MyStruct
{
public int x;
public int y { get; set; }
}
public class MyClass
{
public MyStruct a;
}
}
We can use the classes in IronPython like this:
>>> foo = MyClass()
>>> print "%d:%d" % (foo.a.x, foo.a.y)
0:0
>>> foo.a.x = 1 # doesn't work!
>>> print "%d:%d" % (foo.a.x, foo.a.y)
0:0
>>> foo.a = MyStruct(x=1,y=2)
>>> print "%d:%d" % (foo.a.x, foo.a.y)
1:2
It would be nice if Python had a syntax like the F# 'with' for creating a new struct, copying the fields from the old one. Unfortunately we have to specify all the fields when cloning a struct.
Rather puzzling that you ended up in such a corner. In python (tried this on IronPython 2.6.1, .Net 4.0) the equivalent code would be about this:
>>> class a:
... x = 0
... y = 0
...
>>> class b:
... Vector = a()
...
>>> c = b()
>>> c.Vector.x = 1
>>> print c.Vector.x
1
Note there is one difference between my pseudo code and yours - static property is assigned an instance of a class, not just left with type definition. As a side effect, an actual instance of a class is initialized as b.Vector when b is instantiated.
(The pseudo-code is still "broken" - the initialization must go into def init(self), but that's a different story)
The moral of the example, instead of leaving "public Vector position" uninitialized, build initialization of "position" into class Object.