I'm using SWIG to make C# bindings that are compatible with the compact framework (WinCE). I've got most of the immediate issues worked through, but my next blocker is that some of the functions return a double. Wrappers are generated but they fail at run time because the CF framework will not marshal non-integral datatypes (http://msdn.microsoft.com/en-us/library/aa446536.aspx)
My example failure is an attempt to wrap this function:
double getMaxMagnification() const
{
return m_maxMag;
}
SWIG generates this wrapper:
SWIGEXPORT double SWIGSTDCALL CSharp_LTIImageFilter_getMaxMagnification(void * jarg1) {
double jresult ;
LizardTech::LTIImageFilter *arg1 = (LizardTech::LTIImageFilter *) 0 ;
double result;
arg1 = (LizardTech::LTIImageFilter *)jarg1;
result = (double)((LizardTech::LTIImageFilter const *)arg1)->getMaxMagnification();
jresult = result;
return jresult;
}
which is NG because it requires marshalling a double return value.
I manually changed this to return the double via a passed-in pointer:
SWIGEXPORT void SWIGSTDCALL CSharp_LTIImageFilter_getMaxMagnification(void * jarg1, void *jarg2) {
fprintf(stderr, "CSharp_LTIImageFilter_getMaxMagnification\n");
//double jresult ;
LizardTech::LTIImageFilter *arg1 = (LizardTech::LTIImageFilter *) 0 ;
double result;
arg1 = (LizardTech::LTIImageFilter *)jarg1;
result = (double)((LizardTech::LTIImageFilter const *)arg1)->getMaxMagnification();
*((double*)jarg2) = result;
//jresult = result ;
//return jresult;
}
After making the corresponding changes in the C# declaration file and implementation class, this works as expected.
That is,
Interop Declaration
NG:
[DllImport("LizardTech_SdkInterop.dll", EntryPoint="CSharp_LTIImageFilter_getMaxMagnification")]
public static extern double LTIImageFilter_getMaxMagnification(IntPtr jarg1);
OK:
[DllImport("LizardTech_SdkInterop.dll", EntryPoint="CSharp_LTIImageFilter_getMaxMagnification")]
public static extern void LTIImageFilter_getMaxMagnification(IntPtr jarg1, ref double jarg2);
Implementation class
NG:
public override double getMaxMagnification() {
double ret = RasterSDKPINVOKE.LTIImageFilter_getMaxMagnification(swigCPtr);
return ret;
}
OK:
public override double getMaxMagnification() {
double ret = 0;
RasterSDKPINVOKE.LTIImageFilter_getMaxMagnification(swigCPtr, ref ret);
return ret;
}
How can I get SWIG to do this for me? I think the tasks are:
(a) change the return type of the wrapper function (only) from double to void
(b) add an argument (pointer to double) to the argument list so that the wrapper can send back the value that way
(c) make the interop declaration reflect the above two changes
(d) make the C# wrapper invoke the new wrapper function.
As always big-picture re-orientation is appreciated.
I'm indebted to David Piepgrass for this. It's not perfect but its good enough for me.
http://sourceforge.net/mailarchive/message.php?msg_id=26952332
////////////////////////////////////////////////////////////////////////////////
// Floating-point value marshalling for .NET Compact Framework:
// All floating-point values must be passed by reference. MULTITHREADING DANGER:
// For return values a pointer to a static variable is returned.
%define %cs_compact_framework_float(FLOAT)
%typemap(ctype, out="FLOAT*") FLOAT "FLOAT*"
%typemap(ctype, out="FLOAT*") FLOAT*, FLOAT&, const FLOAT& "FLOAT*"
%typemap(imtype, out="IntPtr") FLOAT, FLOAT*, FLOAT&, const FLOAT& "ref FLOAT"
%typemap(cstype, out="FLOAT") FLOAT, const FLOAT& "FLOAT"
%typemap(cstype, out="FLOAT") FLOAT*, FLOAT& "ref FLOAT"
%typemap(in) FLOAT %{ $1 = *$input; %}
%typemap(in) FLOAT*, FLOAT&, const FLOAT& %{ $1 = $input; %}
%typemap(out, null="NULL") FLOAT, FLOAT*, FLOAT&, const FLOAT& %{
// Not thread safe! FLOAT must be returned as a pointer in Compact Framework
static FLOAT out_temp;
out_temp = $1;
$result = &out_temp;
%}
%typemap(csin) FLOAT, const FLOAT& "ref $csinput"
%typemap(csin) FLOAT*, FLOAT& "ref $csinput"
%typemap(csout, excode=SWIGEXCODE) FLOAT, FLOAT*, FLOAT&, const FLOAT& {
IntPtr ptr = $imcall;$excode
FLOAT ret = (FLOAT)Marshal.PtrToStructure(ptr, typeof(FLOAT));
return ret;
}
%typemap(csvarout, excode=SWIGEXCODE2) FLOAT, FLOAT*, FLOAT&, const FLOAT&
%{
get {
IntPtr ptr = $imcall;$excode
FLOAT ret = (FLOAT)Marshal.PtrToStructure(ptr, typeof(FLOAT));
return ret;
}
%}
%enddef
%cs_compact_framework_float(float)
%cs_compact_framework_float(double)
Related
C++14 introduces Compare::is_transparent for equivalent find operations in associative containers.
template< class K > iterator find( const K& x );
template< class K > const_iterator find( const K& x ) const;
Finds an element with key that compares equivalent to the value x.
This overload only participates in overload resolution if the
qualified-id Compare::is_transparent is valid and denotes a type. It
allows calling this function without constructing an instance of Key
Since there is no longer temporary instance of Key constructed, these can be more efficient.
There does not seem to be an equivalent for unordered containers.
Why is there no Compare::key_equal / Compare::hash_equal?
I imagine it would be relatively simple to allow efficiently looking up of, eg, string literals in unordered containers?
template<>
struct hash<string>
{
std::size_t operator()(const string& s) const
{
return ...;
}
// hash_equal=true allows hashing string literals
std::size_t operator()(const char* s) const
{
return ...;
}
};
Keys that compare equal should produce the same hash value. Decoupling the hash function and the predicate, and at the same time making one or both heterogeneous, could be too much error prone.
Recent paper, P0919r2, brings up the following example:
std::hash<long>{}(-1L) == 18446744073709551615ULL
std::hash<double>{}(-1.0) == 11078049357879903929ULL
Although -1L and -1.0 compare equal, some heterogeneous hash function, not in line with the selected equality comparison logic, could produce different values. The paper adds heterogeneous lookup-enabled function templates --
find, count, equal_range, and contains -- but makes them available when the below requirements are met [unord.req]/p17:
If the qualified-id Hash::transparent_key_equal is valid and denotes a type ([temp.deduct]), then the program is ill-formed if either:
qualified-id Hash::transparent_key_equal::is_transparent is not valid or does not denote a type, or
Pred is a different type than equal_to<Key> or Hash::transparent_key_equal.
The member function templates find, count, equal_range, and contains shall not participate in overload resolution unless the qualified-id Hash::transparent_key_equal is valid and denotes a type ([temp.deduct]).
In such a case, Hash::transparent_key_equal overwrites the default predicate (std::equal_to<Key>) and is used for (transparent) equality checking, together with Hash itself for (transparent) hashing.
Under these conditions, the below transparent function objects could be used to enable heterogeneous lookup:
struct string_equal
{
using is_transparent = void;
bool operator()(const std::string& l, const std::string& r) const
{
return l.compare(r) == 0;
}
bool operator()(const std::string& l, const char* r) const
{
return l.compare(r) == 0;
}
bool operator()(const char* l, const std::string& r) const
{
return r.compare(l) == 0;
}
};
struct string_hash
{
using transparent_key_equal = string_equal; // or std::equal_to<>
std::size_t operator()(const std::string& s) const
{
return s.size();
}
std::size_t operator()(const char* s) const
{
return std::strlen(s);
}
};
Both -- string_equal and std::equal_to<> -- are transparent comparators and can be used as transparent_key_equal for string_hash.
Having this type alias (or a type definition itself) within the hash function class definition makes it clear that it is a valid predicate that works fine with that particular hashing logic and the two can't diverge. Such an unordered set can be declared as:
std::unordered_set<std::string, string_hash> u;
or:
std::unordered_set<std::string, string_hash, string_hash::transparent_key_equal> u;
Either will use string_hash and string_equal.
If you watch the Grill the committee video from CppCon, they explain why stuff like this happens: nobody fought for it.
C++ is standardized by committee but that committee requires input from the community. Someone has to write papers, respond to criticism, go to the meetings, etc... Then the feature can be voted on. The committee doesn't just sit there inventing language and library features. It only discusses and votes on those that are brought forward to it.
The following example (derived from the accepted answer) compiles on Apple clang version 13.1.6. Note that I had to put is_transparent both in NodeHash and NodeEq.
#include <unordered_set>
struct Node {
int id;
int count;
};
struct NodeEq {
using is_transparent = void;
bool operator() (Node const& a, Node const& b) const { return a.id == b.id; };
bool operator() (Node const& n, int const i) const { return n.id == i; };
bool operator() (int const i, Node const& n) const { return n.id == i; };
};
struct NodeHash {
using is_transparent = void;
using transparent_key_equal = NodeEq;
std::size_t operator() (Node const& n) const noexcept { return n.id; };
std::size_t operator() (int n) const noexcept { return n; };
};
using nodes_t = std::unordered_set< Node, NodeHash, NodeHash::transparent_key_equal >;
int main() {
nodes_t nodes;
nodes.find(1);
}
My problem is in the following code:
The filter function compiles, and runs as it should when the source is not constant (the iterators are adjusted accordingly). However when I change the source to const, the compiler gives me the following error for the first two variables of the copy_if statement:
"the object has type qualifiers that are not compatible with the member function".
I believe there is a const to not const conversion error somewhere but frankly I have no idea where. Any help would be appreciated.
#include "thrust\device_vector.h"
#include "thrust\copy.h"
typedef thrust::device_vector<float>::const_iterator Dc_FloatIterator;
typedef thrust::device_vector<float>::iterator D_FloatIterator;
typedef thrust::device_vector<int>::const_iterator Dc_IntIterator;
typedef thrust::device_vector<int>::iterator D_IntIterator;
typedef thrust::tuple< Dc_IntIterator, Dc_IntIterator, Dc_FloatIterator> Dc_ListIteratorTuple;
typedef thrust::zip_iterator<Dc_ListIteratorTuple> Dc_ListIterator;//type of the class const iterator
typedef thrust::tuple< D_IntIterator, D_IntIterator, D_FloatIterator > D_ListIteratorTuple;
typedef thrust::zip_iterator<D_ListIteratorTuple> D_ListIterator;//type of the class iterator
struct selector{//selector functor for the copy if call
const int val;
selector(int _val) : val(_val) {}
__host__ __device__
bool operator()(const int& x ) {
return ( x == val );
}
};
class Foo{
public:
thrust::device_vector<int> ivec1;
thrust::device_vector<int> ivec2;
thrust::device_vector<float> fvec1;
Foo(){;}
~Foo(){;}
D_ListIterator begin(){//cast of begin iterator
return D_ListIterator(D_ListIteratorTuple( ivec1.begin(), ivec2.begin(), fvec1.begin() ));
}
D_ListIterator end(){//cast of end iterator
return D_ListIterator(D_ListIteratorTuple( ivec1.end(), ivec2.end(), fvec1.end() ));
}
Dc_ListIterator cbegin(){//cast of const begin iterator
return Dc_ListIterator(Dc_ListIteratorTuple( ivec1.cbegin(), ivec2.cbegin(), fvec1.cbegin() ));
}
Dc_ListIterator cend(){//cast of const end iterator
return Dc_ListIterator(Dc_ListIteratorTuple( ivec1.cend(), ivec2.cend(), fvec1.cend() ));
}
void const_filter( const Foo& TheOther, const int& target ){//doesnt work
//This function should copy those member of the vectors where
//the ivec2[i] == target is true
thrust::copy_if(
TheOther.cbegin(),
TheOther.cend(),
TheOther.ivec2.cbegin(),
this->begin(),
selector(target) );
}
void filter( Foo& TheOther, const int& target ){//works
//This function should copy those member of the vectors where
//the ivec2[i] == target is true
thrust::copy_if(
TheOther.begin(),
TheOther.end(),
TheOther.ivec2.cbegin(),
this->begin(),
selector(target) );
}
void insert(const int& one, const int& two,const float& three ){
ivec1.push_back(one);
ivec2.push_back(two);
fvec1.push_back(three);
}
int size(){
return ivec1.size();
}
};
bool CheckIfSublistIsConnected(const Foo& list,const int& sublist_num){
Foo tmp;
tmp.const_filter( list, sublist_num );
return (bool)tmp.size();//for symplicity, othervise here is a function that check if
//the edge list represents a connected graph
}
int main(void){
Foo list;
bool connected;
list.insert(10,2,1.0);
list.insert(11,2,1.0);
list.insert(12,2,1.0);
list.insert(10,3,1.0);
list.insert(10,3,1.0);
connected=CheckIfSublistIsConnected(list,2);
if( connected ) return 0;
else return -1;
}
I've found that replacing TheOther.cbegin() / .cend() with the folowing the compiler accepts it. This means I messed up somewhere in the typedef section, but where?
thrust::make_zip_iterator(
thrust::make_tuple(
TheOther.ivec1.cbegin(),
TheOther.ivec2.cbegin(),
TheOther.fvec1.cbegin() ))
As it comes out I've frogotten to add the const magic word at the definition of cend/cbegin.
Dc_ListIterator cbegin() const {
return Dc_ListIterator(Dc_ListIteratorTuple( ivec1.cbegin(), ivec2.cbegin(), fvec1.cbegin() ));
}
Dc_ListIterator cend() const {
return Dc_ListIterator(Dc_ListIteratorTuple( ivec1.cend(), ivec2.cend(), fvec1.cend() ));
}
In trying to shorted my code for readability, I wound up changing too much and making mistakes. This is still condensed but taken straight from my code.
My problem is that I have a class called "function" and a derived class "pwfunction" which both have the virtual () operator. I'd like to pass an array of pointers to my "function" objects to various actual functions and use the () operator.
Final edit: This is a SSCCE version of what I'm talking about.
#include <iostream>
using namespace std;
class function
{
public:
virtual double operator () (double x) {return 1.5;}
};
class pwfunction : public function
{
public:
virtual double operator() (double x) {return 2.0;}
};
void interface();
void definefuncs (function** funcs, long unsigned numfuncs);
void interpolate(function* infunc);
void solvefuncs(function** funcs, long unsigned numfuncs);
int main()
{
interface();
return 0;
}
void interface()
{
long unsigned numfuncs = 1;
function* funcs[numfuncs];
definefuncs(funcs, numfuncs);
solvefuncs(funcs, numfuncs);
}
void definefuncs (function** funcs, long unsigned numfuncs)
{
interpolate(funcs[0]);
}
void interpolate(function* infunc)
{
infunc = new pwfunction();
cout<< (*infunc)(1.5)<<endl; //works
}
void solvefuncs(function** funcs, long unsigned numfuncs)
{
cout<< (*funcs[0])(1.5); //Error Message: Segmentation fault
}
The problem comes from the following:
void interpolate(function* infunc)
{
infunc = new pwfunction();
cout<< (*infunc)(1.5)<<endl; //works
}
is probably not doing what you want. infunc is allocated locally, and this does not affect anything else outside or this function (and is btw a memory leak). Interpolate should either return infunc, or allocate the original variable, such as
void interpolate(function*& infunc) ...
You don't allocate array for the funclist data in somefunction, so anything can happen. Perhaps you mean
func* funclist[1];
to indicate a one-element array of func pointers.
I have the following class functor in CUDA
class forSecondMax{
private:
int toExclude;
public:
__device__ void setToExclude(int val){
toExclude = val;
}
__device__ bool operator ()
(const DereferencedIteratorTuple& lhs, const DereferencedIteratorTuple& rhs)
{
using thrust::get;
//if you do <=, returns last occurence of largest element. < returns first
if (get<0>(lhs)== get<2>(lhs) /*&& get<0>(rhs) == get<2>(rhs)*/ && get<0>(lhs) != toExclude/* && get<0>(rhs)!= toExclude */) return get<1>(lhs) < get<1>(rhs); else
return true ;
}
};
is there a way to set the value of toExclude from the host?
All you need to do to solve achieve this is to define a constructor for the functor which sets the data member from an argument. So your class would look something like this:
class forSecondMax{
private:
int toExclude;
public:
__device__ __host__ forSecondMax(int x) : toExclude(x) {};
__device__ __host__ bool operator ()
(const DereferencedIteratorTuple& lhs,
const DereferencedIteratorTuple& rhs)
{
using thrust::get;
if (get<0>(lhs)== get<2>(lhs) && get<0>(lhs) != toExclude)
return get<1>(lhs) < get<1>(rhs);
else
return true ;
}
};
[disclaimer: written in browser, never tested or compiled, use at own risk]
To set the value prior to passing the functor to a thrust algorithm, create and instance of the functor and pass it to the thrust call, for example:
forSecondMax op(10);
thrust::remove_if(A.begin(), A.end(), op);
which would set the data member toExclude to a value of 10 in a new instance of the class, and use the instance in the stream compaction call.
I'm trying to set my simulation params in constant memory but without luck (CUDA.NET).
cudaMemcpyToSymbol function returns cudaErrorInvalidSymbol. The first parameter in cudaMemcpyToSymbol is string... Is it symbol name? actualy I don't understand how it could be resolved. Any help appreciated.
//init, load .cubin
float[] arr = new float[1];
arr[0] = 0.0f;
int size = Marshal.SizeOf(arr[0]) * arr.Length;
IntPtr ptr = Marshal.AllocHGlobal(size);
Marshal.Copy(arr, 0, ptr, arr.Length);
var error = CUDARuntime.cudaMemcpyToSymbol("param", ptr, 4, 0, cudaMemcpyKind.cudaMemcpyHostToDevice);
my .cu file contain
__constant__ float param;
Working solution
cuda.LoadModule(Path.Combine(Environment.CurrentDirectory, "name.cubin"));
simParams = cuda.GetModuleGlobal("params");
float[] parameters = new float[N]{...}
cuda.CopyHostToDevice<float>(simParams, parameters);
Unfortunately the __ constant __ must be in the same file scope as the memcpy to the symbol, and in your case your __ constant __ is in a separate .cu file.
The simple way around this is to provide a wrapper function in your .cu file, for example:
__constant__ float param;
// Host function to set the constant
void setParam(float value)
{
cudaMemcpyToSymbol("param", ptr, 4, 0, cudaMemcpyHostToDevice);
}
// etc.
__global__ void ...
If this question is actual you can use cuModuleGetGlobal and next cudaMemcpy like this:
private bool setValueToSymbol(CUmodule module, string symbol, int value)
{
CUdeviceptr devPtr = new CUdeviceptr();
uint lenBytes = 0;
CUResult result = CUDADriver.cuModuleGetGlobal(ref devPtr, ref lenBytes, module, symbol);
if (result == CUResult.Success)
{
int[] src = new int[] { value };
cudaError error = CUDARuntime.cudaMemcpy(devPtr, src, lenBytes, cudaMemcpyKind.cudaMemcpyHostToDevice);
if (error == cudaError.cudaSuccess)
return true;
else
return false;
}
else
{
return false;
}
}
where CUmodule module = cuda.LoadModule("MyCode.cubin");
This code works with NVIDIA GPU Computing SDK 3.1 and CUDA.NET 3.0.
constant memory has implicit local scope linkage.
make sure declaration is in the same file where you use it. it sounds like you have two files.
may also have to declare param to array (or maybe not)