I get a tensor from forward().toTensor in libtorch, how can I covert the data to Eigen::ArrayXXf?
like this
at::Tensor tsr = module.forward(inputs).toTuple()->elements()[0].toTensor();
float* mdata = tsr.data_ptr<float>();
Eigen::ArrayXXf meldata(mdata, tsr.size(0), tsr.size(1));
I get error:
error: no matching function for call to 'Eigen::Array<float, -1, -1>::Array(float*&, int64_t, int64_t)'
Related
I want to read and write from an image that stores unsigned integers. How can I read and write? The standard way to read and write to an image is using imageLoad/imageStore, but when using the format qualifier r32ui, the compiler errors with no matching overloaded function found.
This fails to compile:
#version 450
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(set = 0, binding = 0, r32ui) uniform writeonly uimage3D img;
void main() {
imageStore(img, ivec3(1,2,3), uint(4));
}
This compiles fine:
#version 450
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
layout(set = 0, binding = 0, rgba8ui) uniform writeonly uimage3D img;
void main() {
imageStore(img, ivec3(1,2,3), uvec4(4,5,6,7));
}
I have tried using uvec3 for coordinates instead of ivec3, and uvec4 for the data to write in case I am misunderstanding what the format is storing. Using 2 dimensional images also made no difference.
The error message you get is correct, there simply is no overloaded version of imageStore that takes a single unsigned integer (see specs).
So when using the r32ui qualifier, you still need to pass a 4-component unsigned vector just like in your second example, but instead construct it from a single value:
void main()
{
imageStore(img, ivec3(1,2,3), uvec4(4));
}
I think that I am missing something fundamental with regards to pointers. I have the following code:
alicat_data *data = (alicat_data*)ent.second->get_data();
if(ent.first == "AlicatA"){
ui->ac0_P->setValue(data->pressure);
ui->ac0_T->setValue(data->temperature);
ui->ac0_Q->setValue(data->flow_rate);
ui->ac0_Q0->setValue(data->mass_flow_rate);
ui->ac0_Qsp->setValue(data->setpoint);
}
which references a struct that is defined as follows:
struct alicat_data : Data {
float pressure; /** Pressure in mb */
float temperature; /** Temperature in degC */
float flow_rate; /** Volumetric low rate; units are defined by the model */
float mass_flow_rate; /** Mass flow rate; units are defined by the model */
float setpoint; /** Device setpoint (if it is a controller); units are defined by the model */
gas gas_; /** Enum as defined above representing the gas */
alicat_data(float p = 0, float T = 0, float Q = 0,
float Q0 = 0, float sp = 0, gas g = Air):pressure(p),
temperature(T), flow_rate(Q), mass_flow_rate(Q0),
setpoint(sp), gas_(g){
setTime();
}
virtual std::string serialize2ascii(){return std::to_string(pressure)
+ "\t" + std::to_string(temperature)
+ "\t" + std::to_string(flow_rate) + "\t" + std::to_string(mass_flow_rate)
+ "\t" + std::to_string(setpoint);}
};
When the topmost code is executed, the first reference, data->pressure returns correctly then it looks like everything at that address becomes garbage and data returned subsequent to this first reference (i.e. data->temperature, etc) is not correct.
I can fix this by doing the following
alicat_data data_ = *data;
but would prefer not to do this. What am I doing wrong that is creating the issue that I am seeing?
With get_data() you are getting pointer to block of memory of alicat_data and it is stored into the varable alicat_data *data, that is a pointer.
With alicat_data data_ = *data; you are getting the block of memory of the instance, so you can access its methods and properties with a dot '.'.
You can remove the variable alicat_data data_ = *data; and use the variable alicat_data *data as follow:
for (auto const &ent : alicat_map){
alicat_data *data = (alicat_data*)ent.second->get_data();
if(ent.first == "AlicatA"){
ui->ac0_P->setValue(data->pressure);
ui->ac0_T->setValue(data->temperature);
ui->ac0_Q->setValue(data->flow_rate);
ui->ac0_Q0->setValue(data->mass_flow_rate);
ui->ac0_Qsp->setValue(data->setpoint);
}
}
Update: Check this link to review the theory of pointers http://www.cplusplus.com/doc/tutorial/pointers/
Also I made a program with some of you to show you the tow ways, your and mine:
#include <iostream>
#include <map>
using namespace std;
struct alicat_data {
float pressure; /** Pressure in mb */
float temperature; /** Temperature in degC */
float flow_rate; /** Volumetric low rate; units are defined by the model */
float mass_flow_rate; /** Mass flow rate; units are defined by the model */
float setpoint; /** Device setpoint (if it is a controller); units are defined by the model */
alicat_data(float p = 0, float T = 0, float Q = 0,
float Q0 = 0, float sp = 0) {
pressure = p;
temperature = T;
flow_rate = Q;
mass_flow_rate = Q0;
setpoint = sp;
}
virtual std::string serialize2ascii() {
return "dummy";
}
};
int main()
{
map<string, alicat_data *> alicat_map;
map<string, alicat_data *>::iterator entM;
alicat_map["AlicatA"] = new alicat_data(1.1,2.2,3.3,4.4,5.5);
alicat_map["AlicatB"] = new alicat_data(12.1, 23.2, 34.3, 45.4, 56.5);
//Your Way
for (auto const &ent : alicat_map) {
alicat_data *data = (alicat_data*)ent.second; //Get the alicat_data* (pointer) element
if (ent.first == "AlicatA") {
alicat_data data_ = *data;
float pressure = data_.pressure;
float temp = data_.temperature;
float rate = data_.flow_rate;
float mflowrate = data_.mass_flow_rate;
float setpoint = data_.setpoint;
}
}
//My Way
for (entM = alicat_map.begin(); entM != alicat_map.end(); entM++)
{
alicat_data *data = entM->second; //Get the alicat_data* (pointer) element
if (entM->first == "AlicatA") {
float pressure = data->pressure;
float temp = data->temperature;
float rate = data->flow_rate;
float mflowrate = data->mass_flow_rate;
float setpoint = data->setpoint;
}
}
return 0;
}
Upgrade of Apirl 13:
I was checking the code of your classe alicat and i found it:
Data *alicat::get_data(){
alicat_data* ac_data = new alicat_data(0, 0, 0, 0, 0, Air);
alicat_data addr_data = parse_data(port->async_rw(string(1, address)));
ac_data = &addr_data;
return (Data*) ac_data;
}
I notice that you are returning a address of a local variable, ac_data = &addr_data;, that will be deleted after the method Data *alicat::get_data() is finished. That is the reason that you have a mess with data that you getting after invoke getData.
To fix it you must avoid return local variables because they are destroyed after onece the program get out of the context. Return an instance that is previously reserved with the operator new. At the moment that the object is destroyed you have the symptoms that you describe.
I notice that you have the same problem in the method alicat_data alicat::parse_data(const std::string &msg).
UPDATE: Considere this:
I'm not sure why did you get that behaivor, but i know that the local variable ac_data is delete after the context of getData is over but the memory that you allocate intoparse_data is still there, when you are returning the address of that local variable, return (Data*) ac_data; its memory released (a block of memor that is allocated into the stack and not into the heap) and it could be the reason that you are see garbage but when you use alicat_data data_ = *data; you are rescue the memory Block allocated into parse_data... How!? That si a good question and it coul be depend of compilar but the way you can prove it is debugging and be careful of each memory address that you are getting in:
The addres of memory that is allocated into parse_data
The address
of pointer that is returned to getData from parse_data`.
The
address of memory that is set to local variable alicat_data
addr_data into getData. The address of pointer of the local
variable alicat_data addr_data that is returned from getData.
Once you leave getData, compare the addres of the pointer
alicat_data *data vs the address of pointer that you got in
parse_data and compare the address.
if (RARRAY_LEN(arr) > 0)
{
VALUE str = rb_ary_entry(arr, 0);
abc = some_method(*str);
}
rb_ary_entry(arr, 0) gives me an index value. Then I want to convert that value to a string so I can pass it to the next method. I tried:
rb_str_new2(rb_ary_entry(arr, 0));
but I get error saying:
error: indirection requires pointer operand `('VALUE' (aka 'unsigned long')` `invalid`)`
`ipDict = some_method(*str)`;
Use the StringValueCStr macro to convert a Ruby String into a char* (the rb_str_new functions are for converting in the other direction).
VALUE str = rb_ary_entry(arr, 0); // str is now a Ruby String
char *c_str = StringValueCStr(str);
abc = some_method(c_str);
I want to convert a UINT16 monochrome image to a 8 bits image, in C++.
I have that image in a
char *buffer;
I'd like to give the new converted buffer to a QImage (Qt).
I'm trying with freeImagePlus
fipImage fimage;
if (fimage.loadfromMemory(...) == false)
//error
loadfromMemory needs a fipMemoryIO adress:
loadfromMemory(fipMemoryIO &memIO, int flag = 0)
So I do
fipImage fimage;
BYTE *buf = (BYTE*)malloc(gimage.GetBufferLength() * sizeof(BYTE));
// 'buf' is empty, I have to fill it with 'buffer' content
// how can I do it?
fipMemoryIO memIO(buf, gimage.GetBufferLength());
fimage.loadFromMemory(memIO);
if (fimage.convertTo8Bits() == true)
cout << "Good";
Then I would do something like
fimage.saveToMemory(...
or
fimage.saveToHandle(...
I don't understand what is a FREE_IMAGE_FORMAT, which is the first argument to any of those two functions. I can't find information of those types in the freeImage documentation.
Then I'd finish with
imageQt = new QImage(destiny, dimX, dimY, QImage::Format_Indexed8);
How can I fill 'buf' with the content of the initial buffer?
And get the data from the fipImage to a uchar* data for a QImage?
Thanks.
The conversion is simple to do in plain old C++, no need for external libraries unless they are significantly faster and you care about such a speedup. Below is how I'd do the conversion, at least as a first cut. The data is converted inside of the input buffer, since the output is smaller than the input.
QImage from16Bit(void * buffer, int width, int height) {
int size = width*height*2; // length of data in buffer, in bytes
quint8 * output = reinterpret_cast<quint8*>(buffer);
const quint16 * input = reinterpret_cast<const quint16*>(buffer);
if (!size) return QImage;
do {
*output++ = *input++ >> 8;
} while (size -= 2);
return QImage(output, width, height, QImage::Format_Indexed8);
}
IplImage *img;
img = (IplImage **)malloc(IMAGE_NUM * sizeof(IplImage *));
for(index=0; index<IMAGE_NUM; index++){
sprintf(filename, "preproc/preproc%d.jpg", index);
img = cvLoadImage(filename, 0);
}
Hi! This piece of code here produces the error: cannot convert ‘IplImage** {aka _IplImage*}’ to ‘IplImage {aka _IplImage*}’ in assignment. I am trying to load multiple images here. What am I doing wrong? Thanks!
You declare 'img' to be a pointer to IplImage and then you're trying to convert it into pointer to a pointer. (IplImage**) - This typecast is incorrect for this particular case since you're trying to assign IplImage** to a IplImage*.
Declare img to be : IplImage **img;
try this
IplImage** img;
img = (IplImage**)malloc(IMAGE_NUM * sizeof(IplImage *));
for(index=0; index<IMAGE_NUM; index++){
sprintf(filename, "preproc/preproc%d.jpg", index);
*img = cvLoadImage(filename, 0);
}
by the way, the next error you'll get will be for not advancing the img pointer after each loop iteration
Try declaring IplImage** img;, then img[index] = cvLoadImage(filename, 0), since img is an array of IplImage pointers and cvLoadImage() returns a single image.