Sending Vector Winsock Problems - c++

first time asking a question!
I have a small server that sends a vector of objects to a client:
void sendFoo(vector<Foo> &foo){
int num = foo.size();
sSend = accept(sListen, (SOCKADDR*)&addr, &addrLen);
for(int i = 0; i < num; i++){
if(sSend == NULL){
cout << "Not connected" << endl;
} else {
//send vector size
send(sSend, (char*)&num, sizeof(num), NULL);
//send foo(s)
send(sSend, (char*)&foo[i], sizeof(foo[i]), NULL);
}
}
closesocket(sSend);
}
The foo class contains an int id and a double transformation[3][4].
My client app prints out the ids and the transformations it receives:
sRecv = socket(AF_INET, SOCK_STREAM, NULL);
if (connect(sRecv, (SOCKADDR*)&addr, addrLen) != 0) {
cout << "Not connected to server" << endl;
} else {
recv(sRecv, (char*)&num, sizeof(num), NULL);
vector<Foo> foo(num);
for (int i = 0; i < num; i++){
recv(sRecv, (char*)&foo[i], sizeof(foo[i]), NULL);
//prints them out
}
}
If I create 1 Foo and send it across the client correctly prints this:
Foo ID: 1
Foo Transformation:
1.0000 2.0000 3.0000 4.0000
1.0000 2.0000 3.0000 4.0000
1.0000 2.0000 3.0000 4.0000
But when I try to send across more than one I get what look like memory references every other block:
Foo ID: 1
Foo 1 Transformation:
1.0000 2.0000 3.0000 4.0000
1.0000 2.0000 3.0000 4.0000
1.0000 2.0000 3.0000 4.0000
Foo ID: 4
Foo 4 Transformation:
-6.27744e+66 -6.27744e+66 -6.27744e+66 -6.27744e+66
-6.27744e+66 -6.27744e+66 -6.27744e+66 -6.27744e+66
-6.27744e+66 -6.27744e+66 -6.27744e+66 -6.27744e+66
Foo ID: 2
Foo 2 Transformation:
1.0000 2.0000 3.0000 4.0000
1.0000 2.0000 3.0000 4.0000
1.0000 2.0000 3.0000 4.0000
Foo ID: 4
Foo 4 Transformation:
1.70592e-314 5.29981e-315 5.30499e-315 5.30758e-315
5.31017e-315 5.29981e-315 5.30499e-315 5.30758e-315
5.31017e-315 5.29981e-315 5.30499e-315 5.30758e-315
//etc
[SOLVED] I was trying to send the size of the vector multiple times and the client was only set up to receive it once. Thanks for the answers!

Well, I'd say a debugger will be your best friend. I'm also a little surprised the received end gave the printed output you show, perhaps more issues that aren't shown.
Look at the location of the following line:
send(sSend, (char*)&num, sizeof(num), NULL);
And compare to where you have the receiving of that:
recv(sRecv, (char*)&num, sizeof(num), NULL);
Hint, you call send more than recv.

To send your class over a socket you need to serialize it in a raw chunk of memory. you can't send the C++ object directly.
Make a function uint_32_t Foo::exportRaw( void **buffer) ; that will allocate raw memory for a buffer, put you class' members in it, then return the size allocated to send it over the socket.
Don't forget to free your buffer memory when it is sent and useless.
Here is an example :
void *buffer;
uint32_t sizeAlloc;
sizeAlloc = foo[i].exportRaw(&buffer); // serialize object
//send foo(s)
send(sSend, (char*)buffer, sizeAlloc, NULL);
free(buffer);

Related

Retrieving data from af::array via host() results in wrong data

When trying to retrieve data from an af::array (arrayfire) from the device via host(), my output data on the host is wrong (i.e. wrong values). For testing that, I wrote a small code sample (based on https://stackoverflow.com/a/29212923/2546099):
int main(void) {
size_t vector_size = 16;
af::array in_test_array = af::constant(1., vector_size), out_test_array = af::constant(0., vector_size);
af_print(in_test_array);
double *local_data_ptr = new double[vector_size]();
for(int i = 0; i < vector_size; ++i)
std::cout << local_data_ptr[i] << '\t';
std::cout << '\n';
in_test_array.host(local_data_ptr);
for(int i = 0; i < vector_size; ++i)
std::cout << local_data_ptr[i] << '\t';
std::cout << '\n';
delete[] local_data_ptr;
out_test_array = in_test_array;
af_print(out_test_array);
return 0;
}
My output is
in_test_array
[16 1 1 1]
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0.007813 0.007813 0.007813 0.007813 0.007813 0.007813 0.007813 0.007813 0 0 0 0 0 0 0 0
out_test_array
[16 1 1 1]
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
1.0000
Why are half the values in the pointer set to 0.007813, and not all values to 1? When changing the default value for in_test_array to 2, half the values are set to 2, and for 3 those values are set to 32. Why does that happen?
The datatypes between arrayfire and C are in conflict.
For float use:
af::array in_test_array = af::constant(1., vector_size),
out_test_array = af::constant(0., vector_size);
float *local_data_ptr = new float[vector_size]();
For double use:
af::array in_test_array = af::constant(1., vector_size, f64),
out_test_array = af::constant(0., vector_size, f64)
double *local_data_ptr = new double[vector_size]();
IN both cases above, you will see that arrayfire will return you 1.0 in the local_data_ptr buffer, although with different data types.

Arrayfire sparse matrix issues

Getting confused with something that should be simple. Spent a bit of time trying to debug this and am not getting too far. Would appreciate if someone could help me out.
I am trying to define a sparse matrix in arrayfire by specifying the value/column/row triples as specified in this function. I want to store the following matrix as sparse:
3 3 4
3 10 0
4 0 3
I code it up as follows:
int row[] = {0,0,0,1,1,2,2};
int col[] = {0,1,2,0,1,0,2};
double values[] = { 3,3, 4,3,10,4,3};
array rr = sparse(3,3,array(7,values),array(7,row),array(7,col));
af_print(rr);
af_print(dense(rr));
I get the following output:
rr
Storage Format : AF_STORAGE_CSR
[3 3 1 1]
rr: Values
[7 1 1 1]
1.0000
2.0000
4.0000
3.0000
10.0000
4.0000
3.0000
rr: RowIdx
[7 1 1 1]
0
0
0
1
1
2
2
rr: ColIdx
[7 1 1 1]
0
1
2
0
1
0
2
dense(rr)
[3 3 1 1]
0.0000 0.0000 0.0000
0.0000 0.0000 3.0000
3.0000 0.0000 0.0000
When printing out stored matrix in dense format, I get something completely different than intended.
How do I make the output of printing the dense version of rr give:
3 3 4
3 10 0
4 0 3
Arrayfire uses (a modified) CSR format, so the rowarray has to be of length number_of_rows + 1. Normally it would be filled with the number of non-zero entries per row, i.e. {0, 3 ,2, 2}. But for Arrayfire, you need to take the cumulative sum, i.e. {0, 3, 5, 7}. So this works for me:
int row[] = {0,3,5,7};
int col[] = {0,1,2,0,1,0,2};
float values[] = {3,3,4,3,10,4,3};
array rr = sparse(3,3,array(7,values),array(4,row),array(7,col));
af_print(rr);
af_print(dense(rr));
However, this is not really convenient, since it is quite different from your input format. As an alternative, you could specify the COO format:
int row[] = {0,0,0,1,1,2,2};
int col[] = {0,1,2,0,1,0,2};
float values[] = { 3,3, 4,3,10,4,3};
array rr = sparse(3,3,array(7,values),array(7,row),array(7,col), AF_STORAGE_COO);
af_print(rr);
af_print(dense(rr));
which produces:
rr
Storage Format : AF_STORAGE_COO
[3 3 1 1]
rr: Values
[7 1 1 1]
3.0000
3.0000
4.0000
3.0000
10.0000
4.0000
3.0000
rr: RowIdx
[7 1 1 1]
0
0
0
1
1
2
2
rr: ColIdx
[7 1 1 1]
0
1
2
0
1
0
2
dense(rr)
[3 3 1 1]
3.0000 3.0000 4.0000
3.0000 10.0000 0.0000
4.0000 0.0000 3.0000
See also https://github.com/arrayfire/arrayfire/issues/2134.

How does arma::find_unique determine unique indices?

I am using arma::find_unique, and I thought it returned the index of the first occurrence of each unique value in a vector, but it appears to return something else.
Here is a toy function:
// [[Rcpp::export]]
arma::uvec test(arma::vec& x_) {
vec x=arma::sort(x_);
return arma::find_unique(x);
}
If I run the function in R with a simple vector test(5:1) I get a vector of all the indices 0,1,2,3,4 which makes sense since each value is unique.
If I try something like:
set.seed(1991)
var=sample(1:8,20,TRUE)
test(var)
OUTPUT:
1,3,6,7,19,12,14,18.
All those values make sense except the first one. Why is the first unique value at index 1 and not 0? Clearly I am misunderstanding what arma::find_unique intends to do so I would appreciate if someone could enlighten me.
EDIT
My session information
Okay, the following is courtesy of #nrussell, the man is amazing, and was given in the comments to this "answer." (I do not deserve the check mark nor upvotes.)
Actually, I'm pretty sure this is all just a misinterpretation of the Armadillo documentation, which never actually guarantees that a stable sort is used, as #Carl was expecting. Underneath, std::sort is being called, which is not guaranteed to be a stable sort by the C++ standard; also stated here:
"The order of equal elements is not guaranteed to be preserved."
I can demonstrate this here, replicating the "packet" structure use in the Armadillo's algorithm. My guess is that libc++ (typically used by OS X) does implement std::sort as a stable sort, while libstdc++ does not.
My turn: The stable sort, or maintaining the relative order of records with equal keys (i.e. values), is the key issue behind this question. For example, consider the following:
dog car pool dig
Sorting by the first letter with a stable sort gives us:
car dog dig pool
Because the word "dog" appeared prior to "dig" in the vector, it therefore must appear before "dig" in the output.
Sorting by the first letter with a unstable sort gives us:
car dig dog pool
or
car dog dig pool
The principal is relevant to numbers since each key generate is literally present elsewhere. So, we have:
2, 3, 2, 4
Thus, when the unique values are found:
2, 3, 4
The 2 can take id either 0 or 2.
As #nrussell explained, macOS since OS X Mavericks (10.9) relies by default on --stdlib=libc++ vs. the traditional --stdlib=libstdc++ flag for compiling. This was likely the reason why I was unable to replicate it as one implementation opts for stability while the other does not.
Original Answer
First, I'm not able to replicate this on macOS... (See end)
It seems as if we are able to repro this on Linux though (#nrussel). Which means at some point, there is an issue given in the linked code.
Secondly, arma::find_unique is implemented here using matrix ops with op_find_unique. The later is the key as it implements the comparators.
Thus, in short, there should be no way that is possible given that you sort the vector and the first item is always considered to be unique.
Test function
#include <RcppArmadillo.h>
using namespace Rcpp;
// [[Rcpp::depends(RcppArmadillo)]]
// [[Rcpp::export]]
arma::uvec test(arma::vec& x_) {
Rcpp::Rcout << "Input:" << x_.t() << std::endl;
arma::vec x = arma::sort(x_);
Rcpp::Rcout << "Sorted:" << x.t() << std::endl;
arma::uvec o = arma::find_unique(x);
Rcpp::Rcout << "Indices:" << o.t() << std::endl;
return o;
}
/*** R
set.seed(1991)
(v=sample(1:8,20,TRUE))
## [1] 2 2 1 5 7 6 7 6 4 1 5 3 1 4 4 2 8 7 7 8
sort(v)
## [1] 1 1 1 2 2 2 3 4 4 4 5 5 6 6 7 7 7 7 8 8
test(v)
### Received
## 2.0000 2.0000 1.0000 5.0000 7.0000 6.0000 7.0000 6.0000 4.0000 1.0000 5.0000 3.0000 1.0000 4.0000 4.0000 2.0000 8.0000 7.0000 7.0000 8.0000
### Sorted
## 1.0000 1.0000 1.0000 2.0000 2.0000 2.0000 3.0000 4.0000 4.0000 4.0000 5.0000 5.0000 6.0000 6.0000 7.0000 7.0000 7.0000 7.0000 8.0000 8.0000
### Output
## 0 3 6 7 10 12 14 18
*/

Complex Number Matrix multiplication Eigen vs Matlab

Can someone explain to me why the results are different.
Code in C++:
MatrixXcd testTest;
testTest.resize(3,3);
testTest.real()(0,0) = 1;
testTest.real()(0,1) = 2;
testTest.real()(0,2) = 3;
testTest.real()(1,0) = 1;
testTest.real()(1,1) = 2;
testTest.real()(1,2) = 3;
testTest.real()(2,0) = 1;
testTest.real()(2,1) = 2;
testTest.real()(2,2) = 3;
testTest.imag()(0,0) = 1;
testTest.imag()(0,1) = 2;
testTest.imag()(0,2) = 3;
testTest.imag()(1,0) = 1;
testTest.imag()(1,1) = 2;
testTest.imag()(1,2) = 3;
testTest.imag()(2,0) = 1;
testTest.imag()(2,1) = 2;
testTest.imag()(2,2) = 3;
cout<< endl << testTest << endl;
cout<< endl << testTest.transpose() << endl;
cout<< endl << testTest*testTest.transpose() << endl;
cout<< endl << testTest << endl;
Results from C++:
(1,1) (2,2) (3,3)
(1,1) (2,2) (3,3)
(1,1) (2,2) (3,3)
(1,1) (1,1) (1,1)
(2,2) (2,2) (2,2)
(3,3) (3,3) (3,3)
(0,28) (0,28) (0,28)
(0,28) (0,28) (0,28)
(0,28) (0,28) (0,28)
(1,1) (2,2) (3,3)
(1,1) (2,2) (3,3)
(1,1) (2,2) (3,3)
And the same thing written in Matlab:
testTest = [ complex(1,1) complex(2,2) complex(3,3);
complex(1,1) complex(2,2) complex(3,3);
complex(1,1) complex(2,2) complex(3,3)];
testTest
testTest'
testTest*testTest'
testTest
Matlab results:
testTest =
1.0000 + 1.0000i 2.0000 + 2.0000i 3.0000 + 3.0000i
1.0000 + 1.0000i 2.0000 + 2.0000i 3.0000 + 3.0000i
1.0000 + 1.0000i 2.0000 + 2.0000i 3.0000 + 3.0000i
ans =
1.0000 - 1.0000i 1.0000 - 1.0000i 1.0000 - 1.0000i
2.0000 - 2.0000i 2.0000 - 2.0000i 2.0000 - 2.0000i
3.0000 - 3.0000i 3.0000 - 3.0000i 3.0000 - 3.0000i
ans =
28 28 28
28 28 28
28 28 28
testTest =
1.0000 + 1.0000i 2.0000 + 2.0000i 3.0000 + 3.0000i
1.0000 + 1.0000i 2.0000 + 2.0000i 3.0000 + 3.0000i
1.0000 + 1.0000i 2.0000 + 2.0000i 3.0000 + 3.0000i
Multiplication of testTest * testTest' in C returns returns complex numbers with real part 0 and imag part 28. Matlab returns just dobule with value 28.
' in Matlab does the transpose and takes the complex conjugate (http://uk.mathworks.com/help/matlab/ref/ctranspose.html). If you want to just do the transpose use .' (with a dot infront).
Thus, if you change your MATLAB test to
testTest*testTest.'
the results should be the same.
If you want the complex transpose in eigen then you can go matrix.adjoint() (or matrix.conjugate().transpose())

opencv accessing color element of CV_32FC3 BGR cv::Mat

i have a kind of problem. i've seen some more similar question but i can't find a solution.
my problem is that i have a CV_32FC3 cv::Mat, where values are stored in range between 0 and 255, let's call it S.
I have to create a matrix, called P, where store BGR values of all pixel.
So P should have as rows number the total element of S pixel, and as cols number the number of channels (3).
this is what i've tried to do:
int n_pixels = S.cols * S.rows;
p = Mat::zeros(n_pixels, 3, CV_32FC1);
for(int i=0; i<n_pixels; i++) {
Scalar pixel = S.at<Scalar>(i); // i've tried also Vec3f, Point3_, etc..
p.at<float>(i,0) = pixel[0];
p.at<float>(i,1) = pixel[1];
p.at<float>(i,2) = pixel[2];
}
i've also tried low level c-api data access like this:
for(int i=0; i<selection.rows; i++) {
p.at<float>(i,0) = S.ptr<float>(i)[0];
p.at<float>(i,1) = S.ptr<float>(i)[1];
p.at<float>(i,2) = S.ptr<float>(i)[2];
}
and also splitting channels (but splitted channels have type CV_8U so i think it is wrong):
vector<Mat> bgr;
cv::split(S, bgr);
for(int i=0; i<n_pixels; i++) {
p.at<float>(i,0) = bgr[0].data[i];
p.at<float>(i,1) = bgr[1].data[i];
p.at<float>(i,2) = bgr[2].data[i];
}
but every time i get really weird result if coutting the pixels, like:
172.2042 0.0000 0.0000
2771.1414 0.0000 0.0000
2939505920.0000 3.3468 0.0000
3079446986752.0000 0.0129 0.0000
192669347217408.0000 0.8367 0.0000
51956177323392237568.0000 16301891256320.0000 0.0509
58314208864123224064.0000 3.3945 0.0029
180449.1406 0.0000 0.0000
0.6531 0.0000 0.0000
0.0100 0.0000 0.0000
2.7373 0.0000 0.0000
10957.3184 0.0000 0.0000
739729604608.0000 3.3778 0.0000
0.0000 0.0000 0.0000
0.0000 0.0000 0.0000
0.0000 0.0000 0.0000
0.0000 0.0000 0.0000
and, in some cases also segfault..
any delucidations? how to resolve it? why my trials are wrong?
EDIT: i think the problems are data types conversion
for(int row = 0; row < resiz.rows; ++row) {
float* p = resiz.ptr<float>(row);
for(int col = 0; col < resiz.cols; ++col,p+=3) {
p[0]=; p[1]=; p[2]=;
}
}
I think you are accessing your matrix elements the wrong way.
S.at<Scalar>(i);
which is the same as
S.at<Scalar>(Point(i,0));
But you need to supply the x and y coordinates.
For me this code gives the expected results:
for(int i=0; i<n_pixels; i++)
{
Vec3f pixel = S.at<Vec3f>(i/S.cols, i%S.cols);
p.at<float>(i,0) = pixel[0];
p.at<float>(i,1) = pixel[1];
p.at<float>(i,2) = pixel[2];
}