Problems when using cv::cuda::GpuMat with thrust and testing thrust API - c++

I want to pass cv::cuda::GpuMat to thrust function and I find this function which can be used for creating a thrust iterator that indexes a cv::cuda::GpuMat. I have 2 problems in the following code:
#include <stdio.h>
#include<io.h>
#include <stdlib.h>
#include <fstream>
#include<string>
#include<iostream>
#include <time.h>
#include <vector>
#include <cuda_runtime.h>
#include "device_launch_parameters.h"
#include <thrust/host_vector.h>
#include<thrust/functional.h>
#include <thrust/device_vector.h>
#include <thrust/generate.h>
#include <thrust/sort.h>
#include <thrust/copy.h>
#include<opencv2/opencv.hpp>
#include<cudaimgproc.hpp>
#include<opencv2/cudafilters.hpp>
#include<opencv2/cudaarithm.hpp>
template<typename T>
struct greater_than_value_pred
{
T value;
greater_than_value_pred(T value) : value(value) {}
__host__ __device__
bool operator()(T v) const { return v > value; }
};
using namespace std;
int main()
{
int compare_vari = 20;
cv::cuda::GpuMat d_data_open(1, 100, CV_32SC2);
// Thrust compatible begin and end iterators to channel 0 of this matrix
auto idxBegin = GpuMatBeginItr<int>(d_data_open, 1);
auto idxEnd = GpuMatEndItr<int>(d_data_open, 1);
// Fill the index channel with a sequence of numbers from 0 to 100
thrust::sequence(idxBegin, idxEnd);
d_iter = thrust::find_if(idxBegin, idxEnd, greater_than_value_pred<int>(compare_vari));
/*Use thrust::device_data to test */
thrust::device_vector<int> d_thrust_data;
thrust::device_vector<int>::iterator d_iter;
thrust::sequence(d_thrust_data.begin(), d_thrust_data.end());
d_iter = thrust::find_if(d_thrust_data.begin(), d_thrust_data.end(), greater_than_value_pred<int>(compare_vari));
//std::cout << *d_iter << std::endl;
}
Question 1:
This code cannot complie: d_iter = thrust::find_if(idxBegin, idxEnd, greater_than_value_pred<double>(compare_vari));
Using idxBegin and idxEnd works well with thrust::sequence(), sort() and so on, but when applying them to thrust::find_if(), it will hint "no operator '=' matches these operands".
Question 2:
*//std::cout << *d_iter << std::endl;*
I want to check the result by the above code, but when debugging it says abort() has been called. I wonder if d_iter is in device memory, if so I need to copy it to host memory? But I don't know how to copy iterator to the host memory.
Any help will be appreciated.

Question 2:
*//std::cout << d_iter << std::endl;
I want to check the result by the above code, but when debugging it says abort() has been called. I wonder if d_iter is in device memory, if so I need to copy it to host memory? But I don't know how to copy iterator to the host memory.
(You don't want to copy the iterator to host memory, what you desire is to copy what the iterator points to to host memory.)
The issue here is that you are not giving any actual size to the device_vector in question:
thrust::device_vector<int> d_thrust_data;
that creates an empty vector with no allocation. Therefore no iterator referencing that vector will point to anything valid, because there is no allocation associated with that vector. If we modify it to:
thrust::device_vector<int> d_thrust_data(22);
we have now created a vector with 22 elements, and the rest of your code, including your std::cout ... statement, will then be sensible. (21 or larger is also important because your find_if is looking for an element of value 20.)
The following code has the above issues addressed and seems to compile and run correctly for me:
$ cat t100.cu
#include <stdio.h>
#include <stdlib.h>
#include <thrust/host_vector.h>
#include <thrust/functional.h>
#include <thrust/device_vector.h>
#include <thrust/generate.h>
#include <thrust/sort.h>
#include <thrust/copy.h>
template<typename T>
struct greater_than_value_pred
{
T value;
greater_than_value_pred(T value) : value(value) {}
__host__ __device__
bool operator()(T v) const { return v > value; }
};
using namespace std;
int main()
{
int compare_vari = 20;
/*Use thrust::device_data to test */
thrust::device_vector<int> d_thrust_data(22);
thrust::device_vector<int>::iterator d_iter;
thrust::sequence(d_thrust_data.begin(), d_thrust_data.end());
d_iter = thrust::find_if(d_thrust_data.begin(), d_thrust_data.end(), greater_than_value_pred<int>(compare_vari));
std::cout << *d_iter << std::endl;
}
$ nvcc -o t100 t100.cu
$ ./t100
21
$

Related

Iterator on a map never atteins map.end()

why the iteration in the code below doesn't work ? I mean the iterator is incremented but evaluating this expression o!=RateCurve.end() always give true.
i need such a function because i'm using it in a wrapper of a map to contruct an interest rate curve.
#include <iostream>
#include <algorithm>
#include <math.h>
#include <string>
#include <map>
#include <exception>
#include <vector>
#include <stdio.h>
using namespace std;
map<double, double>::iterator getIt(map<double, double> o){
return o.begin();
}
int main ()
{
map<double, double> RateCurve;
RateCurve[3.3 ]=0.034 ;
RateCurve[1.2 ]=0.03 ;
RateCurve[0.2 ]=.001 ;
RateCurve[6.1 ]=.023 ;
map<double, double>::iterator o=getIt(RateCurve);
while (o!=RateCurve.end()){
cout << "RateCurve[" << o->first << "] = " << o->second << endl;
++o;
}
}
getIt(map<double, double> o)
You copy the map, so the iterator returned points into an entirely unrelated map to the one you wanted. Worse, the copy gets destroyed at the end of the function call, and the iterator you try to use is no longer valid, so you have Undefined Behaviour.
Make getIt take a reference, and since you don't actually change the elements, you can make it const too. Then you need to change the return type:
std::map<double, double>::const_iterator
getIt(map<double, double> const& o)
{
return o.begin();
}
Also, please reconsider your use of bad practices using namespace std; and endl.

BOOST_PP_REPEAT with boost::fusion::size

I want to iterate in compile time over struct and write to output number of iteration. Just to mention - in real case I will pass some more parameters in data.
#include <iostream>
#include <string>
#include <vector>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
struct MyStruct
{
int x;
int y;
};
BOOST_FUSION_ADAPT_STRUCT(
MyStruct,
(int, x)
(int, y)
)
#define PRINT(unused, number, data) \
std::cout << number << std::endl;
int main()
{
MyStruct s;
std::cout << boost::fusion::size(s) << std::endl;
//line below works - it iterate and write output
BOOST_PP_REPEAT(2, PRINT, "here I will pass my data")
//this won't compile
//BOOST_PP_REPEAT(boost::fusion::size(s), PRINT, "here i will pass my data")
}
How to fix problematic line so it will work when I will add more members in structure? I need solution for C++03 :(
Instead of using BOOST_PP_REPEAT, you can use the boost::fusion::for_each which goes through every element. example:
#include <iostream>
#include <string>
#include <vector>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/include/size.hpp>
#include <boost/preprocessor/repetition/repeat.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>
struct MyStruct {
int x;
int y;
};
BOOST_FUSION_ADAPT_STRUCT(
MyStruct,
(int, x)
(int, y)
)
template<typename Data>
struct PrintWithData {
PrintWithData(Data data) : data(data) {}
template<typename T>
operator()(const T& thingToBePrinted)
{
std::cout << thingToBePrinted << std::endl;
}
Data data;
};
int main()
{
MyStruct s;
//this will compile
boost::fusion::for_each(s, PrintWithData<std::string>("here I will pass my data"));
}
Here is exact solution for this problem (asked more general question later, and found answear which solve this problem too): https://stackoverflow.com/a/31713778/4555790

Structure with vectors

I have some problems with sending structure to function:
Here is my main.cpp file:
#include "stdafx.h"
#include "vehicles.h"
#include <iostream>
#include "tools.h"
#include <time.h>
#include <vector>
using MAP_GRID = vector<vector<string>>;
using namespace std;
void print_terrain(MAP_GRID);
void set_position(MAP_GRID &, int, int, position &, string);
void random_position(MAP_GRID &, int, string);
MAP_GRID create_terrain();
MAP_GRID MAP = create_terrain();
int _tmain(int argc, _TCHAR* argv[])
{
tanks t34(12, 0.5, 21,6);
srand(time(NULL));
set_position(MAP, 5, 5, player,"[x]");
//[...]
}
Here is another file, with definition of this function:
#include "stdafx.h"
#include <iostream>
#include <vector>
#define MIN_SIZE 6
#define MAX_SIZE 15
using std::vector;
using std::string;
using MAP_GRID = vector<vector<string>>;
int global_size;
struct position{
vector<int> x;
vector<int> y;
};
void set_position(MAP_GRID &MAP, int x, int y, position &pos, string object)
{
if (x <= MAP.size() || y <= MAP.size())
if (MAP[x][y] != "[ ]")
std::cout << "\nPosition is occupied" << std::endl;
else
{
MAP[x][y] = object;
pos.x.push_back(x);
pos.y.push_back(y);
}
else
std::cout << "\Choose correct position" << std::endl;
}
This structure have to hold coordinate of some point (numbers of these points depends of object).
This has nothing at all to do with vectors (as you'd have discovered, had you constructed a minimal testcase during your many days of painstakingly debugging this problem).
You have to at least declare identifiers in every translation unit you want to use them in, before you use them.
You have not done that, so the compilation of main.cpp will fail because, indeed, it has no idea what position is supposed to be. player is, likewise, a complete mystery.
Typically we define types in "header files", making for easy inclusion of these definitions across multiple translation units. In this case, you can at least get away with a forward declaration of position.

implementing map<mpz_t, double> in c++

For some reason, I need to have a map from arbitrary huge number to double and I tried to implement it with c++98 (and I have to) and Xcode but it doesn't work:
#include <iostream>
#include <string>
#include <map>
#include <vector>
#include <set>
#include "gurobi_c++.h"
#include <sstream>
#include "boost/tuple/tuple.hpp"
#include "boost/tuple/tuple_comparison.hpp"
#include "boost/tuple/tuple_io.hpp"
#include <cmath>
#include <gmp.h>
using namespace std;
using namespace ::boost::tuples;
using namespace ::boost;
int main()
{
map<mpz_t, double>J;
mpz_t a,b,c,n;
string tempstring;
int xrange=5,yrange=5,component=5;
mpz_set_str(n,"11", 10);
J[n]=-1;
return 0;
}
The error shown is: Array initializer must be an initializer list. Could someone help me with it? Thank you:)
Here's the detail error page:
I don't know the details of mpz_t. However, it appears to be an array.
You can get around the problem by defining a class to be used as the key in your map.
I am able to create an executable using the following code with g++ 4.8.2.
#include <map>
using namespace std;
typedef int (mpz_t)[2];
struct MyKey
{
// Add a proper implementation of a constructor
// with mpz_t.
MyKey(mpz_t in) {}
// Add a proper implementation of copy constructor.
MyKey(MyKey const& copy) {}
// Add a proper implementation of assignment operator.
MyKey& operator=(MyKey const& rhs)
{
return *this;
}
bool operator<(MyKey const& rhs) const
{
// Add a proper implementation.
return false;
}
mpz_t n;
};
int main()
{
map<MyKey, double> J;
mpz_t n;
J[n] = 1.0;
return 0;
}

possible bug in boost transformed adaptor

Im finding a bug between debug and release builds of the following code.
#include <vector>
#include <iostream>
#include <boost/bind.hpp>
#include <boost/range/algorithm.hpp>
#include <boost/range/adaptors.hpp>
using namespace std;
namespace br = boost::range;
namespace badpt = boost::adaptors;
std::pair<int,int> pr_swap(std::pair<int,int> pr)
{return make_pair(pr.second,pr.first);}
int main()
{
std::vector<pair<int,int> > vec;
vec.push_back(make_pair(1,2));
vec.push_back(make_pair(2,1));
br::copy(vec|badpt::transformed(bind(pr_swap,_1))|badpt::map_keys,std::ostream_iterator<int>(cout," "));
}
With, gcc-4.8.1 -O3, I get
0 0
And without I get as expected
2,1
Any ideas what is going wrong?
I ran into this problem recently.
The implementation of select_first (i.e. which is used by map_keys) in boost/range/adaptor/map.hpp returns a reference. The output of the pr_swap function returns a value. This is undefined behavior, which typically is only exposed when compiler optimizations are enabled.
I do not know why the compiler failed to emit a return-local-addr warning.
I got around the problem in the following manner:
#include <iostream>
#include <vector>
#include "boost/range/algorithm.hpp"
#include "boost/range/adaptors.hpp"
int main()
{
const std::vector<std::pair<int, int>> v{{1,2},{3,4},{5,6}};
auto swap = [](const auto& p) { return std::make_pair(p.second, p.first); };
auto getFirst = [](const auto& p) { return p.first; };
auto rng = v | boost::adaptors::transformed(swap) | boost::adaptors::transformed(getFirst);
boost::copy(rng, std::ostream_iterator<int>(std::cout, ", "));
return 0;
}