I am implementing a tensorflow::op (https://www.tensorflow.org/versions/r0.12/how_tos/adding_an_op/#verify_it_works).
I want to call a function forward(), which takes float pointer as arguments. On the first argument, I am not able to convert the tensor to a float pointer.
REGISTER_OP("ForwardMatching")
.Input("input0: float32")
.Input("input1: float32")
.Input("disparities: float32")
.Input("output: float32")
.Input("in: int32")
.Input("ic: int32")
.Input("ih: int32")
.Input("iw: int32")
.Input("lendisps: int32")
.Input("memorylayout: int32")
.Input("rectcorr: int32")
.Output("zeroed: int32")
.SetShapeFn([](::tensorflow::shape_inference::InferenceContext* c) {
c->set_output(0, c->input(0));
return Status::OK();
});
class ForwardMatchingOp : public OpKernel {
public:
std::vector<cudnnTensorDescriptor_t> a;
StereoCorrelation* sc = new StereoCorrelation(a);
explicit ForwardMatchingOp(OpKernelConstruction* context) : OpKernel(context) {}
void Compute(OpKernelContext* context) override {
// Grab the input tensor
const Tensor& input0_tensor = context->input(0);
iu::TensorGpu_32f::MemoryLayout ml;
float *i0, *i1, *disp;
int in, ic, ih, iw, lendisps, rectcor;
float *output;
sc->forward(input0,i1,disp, output, in, ic, ih, iw, lendisps, ml, rectcor);
}
};
the error message:
note: no known conversion for argument 1 from ‘Eigen::TensorMap<Eigen::Tensor<const float, 1, 1, long int>, 16, Eigen::MakePointer>’ to ‘float*’
The conversion is
Tensor A;
float *a_data = A.flat<float>().data();
size_t a_len = A.NumElements()
Here flat() returns an Eigen::Tensor:
/// \brief Return the tensor data as an `Eigen::Tensor` of the data type and a
/// specified shape.
template <typename T>
typename TTypes<T>::Flat flat() {
return shaped<T, 1>({NumElements()});
}
and data() is Eigen-specific.
The NumElements() is
/// Convenience accessor for the tensor shape.
int64 NumElements() const { return shape().num_elements(); }
Related
I want to create a generalized heap data structure, and facing an issue with passing template comparator.
template<typename T, typename C = less<T> > class Heap{
vector<T> *heap;
public:
Heap(vector<T> *arr){
heap = new vector<T> (arr->begin(), arr->end());
build_heap();
}
void build_heap(){
size_t n = heap->size();
for (size_t i=(n-1)/2; i>=0; i--){
shiftDown(i);
}
}
void shiftDown(size_t i){ /// heap logic
while(i < heap->size()){
size_t child = 2*i+1;
// int min_ind = 2*i+1;
if(child >= heap->size())
return;
if(child+1 < heap->size()){
if( C(heap->at(child+1),heap->at(child)) ){ // <----- using C as comparator
child++;
}
}
if( C(heap->at(child), heap->at(i)) ){ // <----- using C as comparator
swap(heap->at(child), heap->at(i));
i = child;
}
else
break;
}
}
};
int main(){
vector<int> v={8,7,6,5,4,3,2,1};
Heap<int, less<int> > heap(&v);
}
error
heap.cpp: In instantiation of ‘void Heap<T, C>::shiftDown(size_t) [with T = int; C = std::less<int>; size_t = long unsigned int]’:
heap.cpp:15:4: required from ‘void Heap<T, C>::build_heap() [with T = int; C = std::less<int>]’
heap.cpp:10:3: required from ‘Heap<T, C>::Heap(std::vector<_Tp>*) [with T = int; C = std::less<int>]’
heap.cpp:49:34: required from here
heap.cpp:32:9: error: no matching function for call to ‘std::less<int>::less(__gnu_cxx::__alloc_traits<std::allocator<int>, int>::value_type&, __gnu_cxx::__alloc_traits<std::allocator<int>, int>::value_type&)’
32 | if( C(heap->at(child+1),heap->at(child)) ){
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
...
detailed error
i'm following same syntex of declaration as stl c++ do, still i'm getting error. please help me out.
template<typename T, typename C = less<T> > class Heap;
any help or pointer to help is appreciated. thank you.
template<class T>
class Comparator{
bool operator()(const T &a, const T &b){
...
// returns logic
}
}
template<class T, class Comp >
class AnyClass{
public:
...
void function(){
// code ...
Comp<T>()(obj1, obj2);
}
...
}
calling sytex :
...
AnyClass *obj = new AnyClass<Type , Comparator>();
obj.function()
...
passing Comparator to templated class and when we need to compare objects
we create a functional object and call operator() with args to compare.
In question, that object is less<int>.
Comp<T>()(obj1, obj2);
Good morning everyone.
I am new to C++ 11 multithreading theme and trying to write down a code that add two vectors of equal sizes in asynchronous way.
This means, if I have two vectors:
vector<int> fisrt = {1, 2, 3};
vector<int> second = {3, 2, 1};
first += second; // first = {4, 4, 4}
I wrote Paginator class which splits vector on "pages" with appropriate page_size.
My idea of vectors addition in asynchronous way is next: split vectors on pages with choosen page_size, and add pages of first and second vectors in asynchronous way.
Paginator class implementation
template<class Iter>
class IterRange {
public:
explicit IterRange(Iter first, Iter last) : first_(first), last_(last) {}
Iter begin() { return first_; }
const Iter begin() const { return first_; }
Iter end() { return last_; }
const Iter end() const { return last_; }
private:
Iter first_;
Iter last_;
};
template<class Iter>
IterRange<Iter> MakeIterRange(Iter first, Iter last) {
return IterRange<Iter> {first, last };
}
template<class Iter>
class Paginator {
public:
Paginator(Iter first, Iter last, size_t page_size) : page_size_(page_size) {
size_t pages_count = static_cast<size_t> (floor((double)distance(first, last) / page_size_));
pages_.reserve(pages_count);
size_t page_id = 0u;
Iter begin_page = first;
for (page_id, begin_page; page_id < pages_count; ++page_id, begin_page += page_size_) {
pages_.push_back(MakeIterRange( begin_page, begin_page + page_size ));
}
// If some elements less than page_size_ is left
if (begin_page != last) {
pages_.push_back(MakeIterRange(begin_page, begin_page + distance(begin_page, last)));
}
}
auto begin() { return pages_.begin(); }
auto begin() const { return pages_.begin(); }
auto end() { return pages_.end(); }
auto end() const { return pages_.end(); }
private:
size_t page_size_;
vector<IterRange<Iter>> pages_;
};
template<class Iter>
Paginator<Iter> MakePaginator(Iter first, Iter last, size_t page_size) {
return{ first, last, page_size };
}
template<class Container> // And the same for non constant Container
auto Paginate(const Container & c, size_t page_size) {
return MakePaginator(begin(c), end(c), page_size);
}
This Paginate procedure is used in operator+= in my Matrix class.
Matrix class fields are:
Matrix sizes along Ox and Oy direction respectively: size_t nx_, size_t ny_.
Vector of (nx_ * ny_) size, which stores all elements in matrix: vector body_.
Operator += for Matrix
template
inline Matrix & Matrix::operator+=(const Matrix & other) {
size_t threads_numb = thread::hardware_concurrency();
size_t page_size = static_cast<size_t> (ceil((double)body_.size() / threads_numb));
vector<future<void>> futures;
auto page_1 = page::Paginate(body_, page_size);
auto page_2 = page::Paginate(other.body_, page_size);
auto it_2 = page_2.begin();
for (auto it = page_1.begin(); it != page_1.end(); ++it, ++it_2) {
futures.push_back(
async([it, it_2] { transform(it->begin(), it->end(), it_2->begin(), it->begin(), plus<T>()); })
);
}
return *this;
}
But as a result I get iterator out of range error! How could I fix this?
P.S. Sorry for bad representation of first string in operator +=. Could not fix this problem :(
I am following this code snippet which makes it easier to pass a member function to an interface expecting a C-style callback (that is, the interface expects a function pointer to the callback, and a void* pointer to user data which will in turn be passed to the callback). Effectively I want to convert Helper::M to Helper::V below.
I am trying to modify the snippet to automatically deduce the template parameters. Here is my current attempt.
#include <iostream>
template <typename R, typename T, typename... Args>
struct Helper {
using V = R (*)(void*, Args...);
using M = R (T::*)(Args...);
template <M m>
static R Fn(void* data, Args... args) {
return (static_cast<T*>(data)->*m)(std::forward<Args...>(args...));
}
};
template <typename R, typename T, typename... Args>
typename Helper<R, T, Args...>::V Cast(R (T::*m)(Args...)) {
return Helper<R, T, Args...>::template Fn<m>;
}
int CIntf(void* data, int (*f)(void*, int)) { return f(data, 1); }
struct UserData {
int x;
int Add(int y) { return x + y; }
};
int main(int argv, char** argc) {
UserData data = {4};
// Explicit parameters; works.
std::cout << CIntf(&data, Helper<int, UserData, int>::Fn<&UserData::Add>)
<< "\n";
// Deduced parameters; fails.
std::cout << CIntf(&data, Cast(&UserData::Add)) << "\n";
return 0;
}
I tried to compile with gcc -std=c++11 -lstdc++. The explicit parameters method works fine, but the deduced parameters method gives the following error:
tmp.cc: In instantiation of ‘typename Helper<R, T, Args>::V Cast(R (T::*)(Args ...)) [with R = int; T = UserData; Args = {int}; typename Helper<R, T, Args>::V = int (*)(void*, int)]’:
tmp.cc:30:58: required from here
tmp.cc:15:42: error: no matches converting function ‘Fn’ to type ‘using V = int (*)(void*, int) {aka int (*)(void*, int)}’
return Helper<R, T, Args...>::template Fn<m>;
^~~~~
tmp.cc:8:12: note: candidate is: template<int (UserData::* m)(int)> static R Helper<R, T, Args>::Fn(void*, Args ...) [with R (T::* m)(Args ...) = m; R = int; T = UserData; Args = {int}]
static R Fn(void* data, Args... args) {
Note that it correctly deduced the template parameters, but failed to convert Helper<int, UserData, int>::Fn<m> to int (*)(void*, int); why? This same conversion succeeded in the explicit case (unless m is somehow different from &UserData::Add).
Unfortunately you'll have to use a macro for this:
#define makeFunc(method) &Helper<decltype(method)>::Fn<method>
And redefine your helper like this for it to work:
template <typename T>
struct Helper;
template <typename R, typename T, typename... Args>
struct Helper<R(T::*)(Args...)>
The reason why you can't use deduction for this, is that deduction only works on function arguments which are run-time values. And you need to use a method's address as template argument which should be a compile-time value.
So when you do this:
return Helper<R, T, Args...>::template Fn<m>;
you are passing a run-time value m as a template argument which is impossible.
For reference, here is the complete code using the macro. Also note the use of std::forward in the original code was incorrect for multiple arguments (see this answer).
#include <iostream>
#include <utility>
template <typename T>
struct Helper;
template <typename R, typename T, typename... Args>
struct Helper<R (T::*)(Args...)> {
template <R (T::*m)(Args...)>
static R Fn(void* t, Args... args) {
return (static_cast<T*>(t)->*m)(std::forward<Args>(args)...);
}
};
#define VOID_CAST(m) &Helper<decltype(m)>::Fn<m>
struct UserData {
int x;
int Add1(int y) { return x + y; }
int Add2(int y, int z) { return x + y + z; }
};
int Call1(void* data, int (*f)(void*, int)) { return (*f)(data, 1); }
int Call2(void* data, int (*f)(void*, int, int)) { return (*f)(data, 1, 2); }
int main() {
UserData data = {4};
std::cout << Call1(&data, VOID_CAST(&UserData::Add1)) << "\n";
std::cout << Call2(&data, VOID_CAST(&UserData::Add2)) << "\n";
return 0;
}
I have a very simple question i guess but...
I have to sort a vector by it's own member, but I can not.
This is my function for filling the vector with objects from another vector.
I have to sort the vector SortDealers by specific product but I don't know how to send the name of the Stock to my overloading operator<
void CShop::sortVector(const CStock& s1)
{
vector<CDealer> SortDealers;
vector<CDealer* >::iterator it = Dealers.begin();
while (it != Dealers.end())
{
if ((*(*it)).ComapareNameProducts(s1))
{
SortDealers.push_back(*(*it));
}
it++;
}
sort(SortDealers.begin(), SortDealers.end());
copy(SortDealers.begin(), SortDealers.end(), ostream_iterator<CDealer>(cout, "\n"));
}
this is overloading operator<:
I have to sort by unsigned member of the map.
bool CDealer::operator<(const CDealer & o1)
{
unsigned res1 = 0;
unsigned res2= 0;
map<const CStock, pair<unsigned, double>>::const_iterator it = Stock.begin();
map<const CStock, pair<unsigned, double>>::const_iterator iter = o1.Stock.begin();
while (it != Stock.end())
{
res1 += it->second.first;
it++;
}
while (iter != o1.Stock.end())
{
res2 += iter->second.first;
iter++;
}
return (res1 < res2);
}
You can use functor:
class less_than
{
const string stockname;
public:
less_than(string s) : stockname(s) {}
inline bool operator() const (const CDealer& a, const CDealer& b)
{
// use stockname here
}
};
sort(SortDealers.begin(), SortDealers.end(), less_than("name"));
Also you can use lambda expression providing stock name in its capture.
Related answer.
I have a number of C++ structs with a number of methods. The C++ structs have a
"default" instance, and I would like to expose a "c" wrapper functions that uses
this default instance. But I would also like to avoid repeating all the
prototyles.
Alkind of C++11/14/17 and/or macro tricks are welcome, but I do not want to use
code-generators.
I have something that almost works, but I'm still struggling with a few
details.
// C++ class that have a "default-instance" ///////////////////////////////////
struct Foo {
int a() { return 1; }
int b(int) { return 2; }
int c(int, int) { return 3; }
};
Foo *FOO = nullptr;
// emulating existing c code that can not be changed //////////////////////////
typedef int (*ptr_a_t)();
ptr_a_t ptr_a = nullptr;
typedef int (*ptr_b_t)(int);
ptr_b_t ptr_b = nullptr;
typedef int (*ptr_c_t)(int, int);
ptr_c_t ptr_c = nullptr;
// Wrapper code (almost generic) //////////////////////////////////////////////
template <typename T, T>
struct Proxy;
// Wrapper class that will use the defualt instance if initialized (FOO is
// hardcoded).
template <typename T, typename R, typename... Args, R (T::*mf)(Args...)>
struct Proxy<R (T::*)(Args...), mf> {
static R call(Args... args) {
if (FOO) {
// ^^^
return ((*FOO).*mf)(args...);
// HARD-CODED ^^^^
} else {
return -1;
}
}
};
// Helper function to deduce the Proxy-class (method 'b' is hardcoded)
template <typename T, typename R, typename... Args>
auto deduce_args(R (T::*mf)(Args...)) -> Proxy<R (T::*)(Args...), &T::b> {
// HARD-CODED ^
return Proxy<R (T::*)(Args...), &T::b>();
// HARD-CODED ^
}
// Wrap the methods ////////////////////////////////////////////////////////
//#define wrap_a decltype(deduce_args(&Foo::a))::call
#define wrap_b decltype(deduce_args(&Foo::b))::call
//#define wrap_c decltype(deduce_args(&Foo::c))::call
int main() {
// Test that it works
//ptr_a = &wrap_a; // does not work due to hard-coded method
ptr_b = &wrap_b;
//ptr_c = &wrap_c; // does not work due to hard-coded method
return ptr_b(0);
}
I can live with the hard-coded "FOO" in the proxy, as I only need one proxy per class, but it would be cool if the instance pointer could be passed as a
template argument.
The hard-coded method in "deduce_args" is really anoying, how can I eliminate
that??
Is there a better way to do this (the function pointers can not be replaced with std::function).
Using C++14 alias turned out to be a much easier way of achieving what I wanted.
// compile using the "-std=c++14" flag
// C++ class that have a "default-instance" ///////////////////////////////////
struct Foo {
int a() { return 1; }
int b(int) { return 2; }
int c(int, int) { return 3; }
};
Foo *FOO = nullptr;
// emulating existing c code that can not be changed //////////////////////////
typedef int (*ptr_a_t)();
ptr_a_t ptr_a = nullptr;
typedef int (*ptr_b_t)(int);
ptr_b_t ptr_b = nullptr;
typedef int (*ptr_c_t)(int, int);
ptr_c_t ptr_c = nullptr;
// Wrapper code ///////////////////////////////////////////////////////////////
template <typename T, T, typename P, P>
struct Proxy;
template <typename T, typename R, typename... Args, R (T::*mf)(Args...),
typename P, P p>
struct Proxy<R (T::*)(Args...), mf, P, p> {
static R call(Args... args) {
if (*p) {
return ((*(*p)).*mf)(args...);
} else {
return -1;
}
}
};
// Wrap the methods ///////////////////////////////////////////////////////////
#define WRAP(n, obj, m, ptr) \
const auto &n = Proxy<decltype(&obj::m), &obj::m, obj **, &ptr>::call
WRAP(wrap_a, Foo, a, FOO);
WRAP(wrap_b, Foo, b, FOO);
WRAP(wrap_c, Foo, c, FOO);
int main() {
// Test that it works
ptr_a = &wrap_a;
ptr_b = &wrap_b;
ptr_c = &wrap_c;
return ptr_b(0);
}