Call a vector in managed C++ from C# - c#

I want to have a vector that has a number of independent variables. In my C++ header(.h) I defined it like this:
private:
// Static data structure holding independent variables
static vector<double>* indVariables;
And in my .cpp file it is defined the same and then I'm going to have to use this vector in some other function like this:
static vector<double>* indVariables;
void fun(int m, int n)
{
for (i = 0; i < m; ++i)
{
ai = indVariables[i];
temp = exp(-n * (ai - 8.0));
}
} /* fun */
Now in C# I want to copy a set of numbers to this vector and call it back to C++ something like this:
var matu = new double[]{ 8.0, 8.0, 10.0, 10.0, 10.0, 10.0};
myCppClass.indVariables = matu;
How can I do it?
The first problem is because it is private I don't see it in C#. Do I have to make it public or are there other ways? And then how can I assign values to this vector?

The fact that it is private does present an issue, but, making it public won't just solve your problem I think. C# doesn't know what an std::vector is, as Richard said. I don't know much about the structure of your code, what its doing, how its being used, etc, but, if all you need is to assign a list/array of numbers to the vector, you could use a List<> in your C# code and wrap the assignment of the vector in something like this in your CLI project/file:
void Assign(Collections::Generic::List<double>^ l )
{
IndVariables->clear();
for each (double i in l)
{
IndVariables->push_back(i);
}
}
Then in your C# program, you'd write (or however you've declared your List<>):
yourCppClass.Assign(new List<double>(){0.0, 42.0, 8.0});
You could also add additional wrapper methods to manipulate or access the vector. Again, this may or may not be suitable depending on the structure of your code.

Quoting the Collections documentation for C++/CX:
In a Visual C++ component extensions (C++/CX) program, you can make
free use of Standard Template Library (STL) containers, or any other
user-defined collection type. However, when you pass collections back
and forth across the Windows Runtime application binary interface
(ABI)—for example, to a XAML control or to a JavaScript client—you
must use Windows Runtime collection types.
So, you can use STL containers as much as you like internally, but you won't be able to pass them between runtime components as they don't cross ABI boundaries.
A quick fix would be to use the Vector class available at the Platform::Collections namespace through <collection.h>.
Change your header declaration to:
public:
static Vector<Double>^ IndVariables;
Your C# component needs to change as well:
var matu = new Double[] { 8.0, 8.0, 10.0, 10.0, 10.0, 10.0};
myCppClass.IndVariables = matu;
This is untested code, so syntax errors or other minor issues should be present in the snippets above.

Related

Is there any C# analogue of C++11 emplace/emplace_back functions?

Starting in C++11, one can write something like
#include <vector>
#include <string>
struct S
{
S(int x, const std::string& s)
: x(x)
, s(s)
{
}
int x;
std::string s;
};
// ...
std::vector<S> v;
// add new object to the vector v
// only parameters of added object's constructor are passed to the function
v.emplace_back(1, "t");
Is there any C# analogue of C++ functions like emplace or emplace_back for container classes (System.Collections.Generic.List)?
Update:
In C# similar code might be written as list.EmplaceBack(1, "t"); instead of list.Add(new S(1, "t"));. It would be nice not to remember a class name and write new ClassName in such situations every time.
In general there is nothing similar in C#, and its need is much less than in C++.
In C# when you have a List<SomeReferenceType> what you really have is a List<ReferenceToSomeType>, so a list of references, with the size of each element of 4 or 8 bytes (see How big is an object reference in .NET?). Copying a reference doesn't cause the underlying object to be duplicated, so it is very fast (you are copying around 4 or 8 bytes, and the processor is optimized for this operation, because that is the size of the native pointer of the processor). So when you someList.Add(someReference) what you are doing is adding a reference to your List<>.
In C++ when you have a std::vector<SomeType> what you have is a vector of SomeType, with the size of each element equal to sizeof(SomeType). Inserting a new element in std::vector<> will cause the element you are inserting to be duplicated (cloned, copied... choose a verb you like). This is an expensive operation.
Quite often the pattern you use is that you create an object just to insert it into a std::vector<>. To optimize this operation in C++11 they added two ways to do it: the std::vector<>::emplace method and support by the std::vector<> of the move semantic. The difference is that the move semantic must be supported by the SomeType type (you need a move constructor with the noexcept specifier), while every type supports the emplace (that in the end simply used placement constructor).
You can a bit improve #Boo variant with extenstion.
You can create object instance with Activator.CreateInstance so it make solution more generic.
public static class ListExtension
{
public static void Emplace<S>(this IList<S> list, params object[] parameters)
{
list.Add((S)Activator.CreateInstance(typeof(S), parameters));
}
}
Note: not checked type and count parameters, so if you do something wrong, you get errors just in run-time
in c# you can use extension method to achive what you want
public static class ListExtension
{
public static void Emplace(this IList<S> list, int x, string s)
{
list.Add(new S(x, s));
}
}
then use it like this
myList.Emplace(1,"t");
It seems you have following problems:
It's longer to type by "new S". But "add" is shorter than "emplace". Type is added for you by intellisense (simply press Enter after typing "new "):
You are afraid to write a wrong type. Well you can't with List<T>. Intellisense will help you to type and compiler will not allow wrong type to be added at compile time anyway.
Performance: see #Xanatos answer.
list.Add(new S(1, "t")); is perfectly fine to use.
Conclusion: we don't need emplace in C#.

Higher order functions in AleaGPU C#

I am trying to code C# versions (in C# style) of the F# reduce functions found here:
https://github.com/quantalea/AleaGPUTutorial/tree/master/src/fsharp/examples/generic_reduce
More specific to my question, take this function for example:
let multiReduce (opExpr:Expr<'T -> 'T -> 'T>) numWarps =
let warpStride = WARP_SIZE + WARP_SIZE / 2 + 1
let sharedSize = numwarps * warpStride
<# fun tid (x:'T) ->
// stuff
#>
I'm primarily an F# guy, and I'm not quite sure how I should go about coding functions like these in C#. For the C# version, the multiReduce function will be a class member. So if I wanted to do a more direct translation of the F# code, I would return a Func from my MultiReduce member.
The other option would be to "flatten" the multiReduce function, so that my C# member version would have two extra parameters. So...
public T MultiReduce(Func<T,T,T> op, int numWarps, int tid, T x)
{
// stuff
}
But I don't think this would work for AleaGPU coding in all cases because the quoted expression in the F# version is a device function. You need the nested function structure to be able to separate the assignment of certain variables from the actual invocation of the function.
Another way I see to do it would be to make a MultiReduce class and have the opExpr and numWarps as fields, then make the function in the quotation a class member.
So how are higher order functions like these generally implemented in AleaGPU-C#? I don't think it's good to return Func<..> everywhere since I don't see this done much in C# coding. Is AleaGPU a special case where this would be ok?
A basic AleaGPU C# implementation looks like this:
internal class TransformModule<T> : ILGPUModule
{
private readonly Func<T, T> op;
public TransformModule(GPUModuleTarget target, Func<T, T> opFunc)
: base(target)
{
op = opFunc;
}
[Kernel]
public void Kernel(int n, deviceptr<T> x, deviceptr<T> y)
{
var start = blockIdx.x * blockDim.x + threadIdx.x;
var stride = gridDim.x * blockDim.x;
for (var i = start; i < n; i += stride)
y[i] = op(x[i]);
}
public void Apply(int n, deviceptr<T> x, deviceptr<T> y)
{
const int blockSize = 256;
var numSm = this.GPUWorker.Device.Attributes.MULTIPROCESSOR_COUNT;
var gridSize = Math.Min(16 * numSm, Common.divup(n, blockSize));
var lp = new LaunchParam(gridSize, blockSize);
GPULaunch(Kernel, lp, n, x, y);
}
public T[] Apply(T[] x)
{
using (var dx = GPUWorker.Malloc(x))
using (var dy = GPUWorker.Malloc<T>(x.Length))
{
Apply(x.Length, dx.Ptr, dy.Ptr);
return dy.Gather();
}
}
}
Higher-order functions are not nearly as ubiquitous in C# as they are in F#. While there are plenty of examples of accepting functions as arguments, C# code rarely returns functions as results. I guess this is partly because the code comes out very ugly (Func<T,U> everywhere) and partly because C# programmers are not generally used to functional style and gravitate more toward OO ways.
In particular, there is no automatic currying/partial application in C#. You can think of it as if all your F# functions always had tupled parameters. In fact, that's how a multi-parameter C# method would look if you called it from F#.
I must also note that the function in your code is not, in fact, "higher-order". It neither accepts nor returns any functions. Instead, it accepts and returns quotations, which is not at all the same thing. Function is, roughly speaking, a reference to a piece of code, but quotation is a data structure. They look similar, but they're completely different animals.
C# does, too, have its own quotations, represented by the type System.Linq.Expressions.Expression<T> (where T must be a delegate type). However, they are not the same thing as F# quotations. From F# side, you can (sorta) use C# quotation, but not the other way around.
Both F# and C# quotations have their strengths and weaknesses. In particular, C# supports compilation, F# doesn't. F# supports splicing, C# doesn't.
Which brings me to the next point: you probably need splicing. Because you are using opExpr in the body of the returned quotation, aren't you?
And C# doesn't have an out-of-the-box support for it. Yes, it is theoretically possible to implement splicing as a library function, but for some reason there is no de-facto standard, regularly maintained implementation. We, for one, had to roll our own. It's open source, too, and pretty straightforward, so feel free to use it.
Now, having said all the above, I want to express a doubt that you would be able to use C# for this at all. I don't really know how AleaGPU works, but it looks like it expects you to return an F# quotation, which it then, presumably, compiles into GPU code. If that's the case, because C# and F# quotations are two different things, you probably won't be able to return a C# quotation to AleaGPU in lieu of the F# one. Unless it has separate support for it, of course.

Setting C# structure members through IronPython

My application uses IronPython for users to run scripts. One such script is used for setting the members of a structure.
My Structure is as follows:
[StructLayout(LayoutKind.Sequential)]
public struct Data
{
int a;
int b;
}
I have declared a class level public object for this structure like:
public Data data = new data();
I am setting the data object as the scope variable for IronPython:
scope.SetVariable("data", data);
In the python script, I am setting the variables a and b:
data.a = 5
data.b = 10
But the variables are not changing in the C# code. I have noticed that if I use a normal integer or any other type, those variables are setting.
Is there some issue with using structures? How can I set the C# structure members from IronPython?
Use your exposed scope object to provide helper methods to scripts.
When I can't do it in IronPython that is what I do.
IronPython gives me the flexibility of a full language with ifs, fors, and whiles but sometimes the answers for integrating with the C# world are fuzzy so I just build a helper method.
You can even type the parameters because the marshalling works well across function calls.
void SetResult(int a, int b);
The minor comments are probably right you probably are setting the struct but the struct is not a pass by reference it is a pass by value.
You should understand this concept.
Here is a good SO article about it ....
What's the difference between passing by reference vs. passing by value?
You can google the concept more yourself.

How to pass a value to a C# generic?

In C++ templates have the feature that you can pass a value as the argument to the template of a function. How can I do the same in C#?
For instance, I want to do something similar to the following:
template <unsigned n> struct Factorial {
enum {
result = n * Factorial<n - 1>::result;
};
};
template <> struct Factorial<0> {
enum {
result = 1;
};
};
but in C#. How can I do this?
By the way, my actual need for them involves generating classes on demand (with a few static values changed), so the presented code is just an example.
C# generics are not like C++ templates in that way. They only work with types and not values.
but in C#. How can I do this?
By the way, my actual need for them involves generating classes on demand (with a few static values changed), so the presented code is just an example.
As Daniel explained, this is not possible via generics.
One potential alternative is to use T4 Templates. Depending on your needs, you could potentially generate your classes based off the templates at compile time, which sounds like it might meet your needs.
You are trying to make the compiler do stuff that your code should do at runtime.
Yes, this is possible in C++. In C#, It is not. The equivalent of your code in C# would be:
public class Factorial
{
public static ulong Compute(ulong n)
{
if (n == 0)
return 1;
return n * Factorial.Compute(n - 1);
}
}
Note that, while static code is already a bad violation of the OOP principle (but sometimes necessary), using value-based templates is even worse. Your types should depend on other types, which is possible using generics. They should not depend on concrete values.

C# Generic Arrays and math operations on it

I'm currently involved in a project where I have very large image volumes. This volumes have to processed very fast (adding, subtracting, thresholding, and so on). Additionally most of the volume are so large that they event don't fit into the memory of the system.
For that reason I have created an abstract volume class (VoxelVolume) that host the volume and image data and overloads the operators so that it's possible to perform the regular mathematical operations on volumes. Thereby two more questions opened up which I will put into stackoverflow into two additional threads.
Here is my first question. My volume is implemented in a way that it only can contain float array data, but most of the containing data is from an UInt16 image source. Only operations on the volume can create float array images.
When I started implementing such a volume the class looked like following:
public abstract class VoxelVolume<T>
{
...
}
but then I realized that overloading the operators or return values would get more complicated. An example would be:
public abstract class VoxelVolume<T>
{
...
public static VoxelVolume<T> Import<T>(param string[] files)
{
}
}
also adding two overloading operators would be more complicated:
...
public static VoxelVolume<T> operator+(VoxelVolume<T> A, VoxelVolume<T> B)
{
...
}
Let's assume I can overcome the problems described above, nevertheless I have different types of arrays that contain the image data. Since I have fixed my type in the volumes to float the is no problem and I can do an unsafe operation when adding the contents of two image volume arrays. I have read a few threads here and had a look around the web, but found no real good explanation of what to do when I want to add two arrays of different types in a fast way. Unfortunately every math operation on generics is not possible, since C# is not able to calculate the size of the underlying data type. Of course there might by a way around this problem by using C++/CLR, but currently everything I have done so far, runs in 32bit and 64bit without having to do a thing. Switching to C++/CLR seemed to me (pleased correct me if I'm wrong) that I'm bound to a certain platform (32bit) and I have to compile two assemblies when I let the application run on another platform (64bit). Is this true?
So asked shortly: How is it possible to add two arrays of two different types in a fast way. Is it true that the developers of C# haven't thought about this. Switching to a different language (C# -> C++) seems not to be an option.
I realize that simply performing this operation
float []A = new float[]{1,2,3};
byte []B = new byte[]{1,2,3};
float []C = A+B;
is not possible and unnecessary although it would be nice if it would work. My solution I was trying was following:
public static class ArrayExt
{
public static unsafe TResult[] Add<T1, T2, TResult>(T1 []A, T2 []B)
{
// Assume the length of both arrays is equal
TResult[] result = new TResult[A.Length];
GCHandle h1 = GCHandle.Alloc (A, Pinned);
GCHandle h2 = GCHandle.Alloc (B, Pinned);
GCHandle hR = GCHandle.Alloc (C, Pinned);
void *ptrA = h1.ToPointer();
void *ptrB = h2.ToPointer();
void *ptrR = hR.ToPointer();
for (int i=0; i<A.Length; i++)
{
*((TResult *)ptrR) = (TResult *)((T1)*ptrA + (T2)*ptrB));
}
h1.Free();
h2.Free();
hR.Free();
return result;
}
}
Please excuse if the code above is not quite correct, I wrote it without using an C# editor. Is such a solution a shown above thinkable? Please feel free to ask if I made a mistake or described some things incompletely.
Thanks for your help
Martin
This seems a (complicated) version of the "why don't we have an INumerical interface" .
The short answer to the last question is: No, going to unsafe pointers is no solution, the compiler still can't figure out the + in ((T1)*ptrA + (T2)*ptrB)) .
If you have only a few types like float and UInt32, provide all needed conversion functions, for example from VoxelVolume<UInt32> to VoxelVolume<float> and do the math on VoxelVolume<float>. That should be fast enough for most practical cases. You could even provide a generic conversion function from VoxelVolume<T1> to VoxelVolume<T2> (if T1 is convertible to T2). On the other hand, if you really need a
public static VoxelVolume<T2> operator+(VoxelVolume<T1> A,VoxelVolume<T2> B)
with type conversion from T1 to T2 for each array element, what hinders you from writing such operators?
Import, being a member of a generic class, probably doesn't also need to be itself generic. If it does, you definitely shouldn't use the same name T for both the generic parameter to the class and the generic parameter to the function.
What you're probably looking is Marc Gravell's Generic Operators
As for your questions about C++/CLI, yes this could help if you use templates instead of generics because then all the possible values for typename T are controlled at compile time and the compiler looks up the operators for each. Also, you can use /clr:pure or /clr:safe in which case your code will be MSIL, runnable on AnyCPU just like C#.
Admittedly, I didn't read the whole question (it's a quite a bit too long), but:
VoxelVolume<T> where T : ISummand ... T a; a.Add(b)
static float Sum (this VoxelVolume<float> self, VoxelVolume<float> other) {...}
To add float to byte in any meaningful sense you have to convert byte to float. So convert array of bytes to array of floats and then add them, you only lose some memory.

Categories

Resources