FFI BoxedFloat64 bug?

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
14 messages Options
Reply | Threaded
Open this post in threaded view
|

FFI BoxedFloat64 bug?

Aliaksei Syrel
We have two identical bloc images built on ci with one day difference and no changes to bloc
https://ci.inria.fr/pharo-contribution/job/Bloc/26/  - works
https://ci.inria.fr/pharo-contribution/job/Bloc/27/ - drawing crashes with the following error:

Inline image 1

Looks like fix to issue https://pharo.fogbugz.com/f/cases/17564 in #50579 causes bug.

Cheers,
Alex

Reply | Threaded
Open this post in threaded view
|

Re: FFI BoxedFloat64 bug?

EstebanLM
Oops… I didn’t implemented #pointer for floats… it should be something like this:

Float>>#pointer 
^ (ByteArray new: FFIExternalType pointerSize)
floatAt: 1 put: self;
yourself

can you test it?
(and you can commit it to Pharo/NB-FFI repo… I’m taking a plane now and I do not have the time until thursday :( )

Esteban

On 12 Feb 2016, at 16:46, Aliaksei Syrel <[hidden email]> wrote:

We have two identical bloc images built on ci with one day difference and no changes to bloc
https://ci.inria.fr/pharo-contribution/job/Bloc/26/  - works
https://ci.inria.fr/pharo-contribution/job/Bloc/27/ - drawing crashes with the following error:

<Screen Shot 2016-02-12 at 16.33.51.png>

Looks like fix to issue https://pharo.fogbugz.com/f/cases/17564 in #50579 causes bug.

Cheers,
Alex


Reply | Threaded
Open this post in threaded view
|

Re: FFI BoxedFloat64 bug?

Aliaksei Syrel
On Fri, Feb 12, 2016 at 5:45 PM, Esteban Lorenzano <[hidden email]> wrote:
Float>>#pointer 
^ (ByteArray new: FFIExternalType pointerSize)
floatAt: 1 put: self;
yourself

Yes it does the trick :) Thanks!
Reply | Threaded
Open this post in threaded view
|

Re: FFI BoxedFloat64 bug?

Aliaksei Syrel
(and you can commit it to Pharo/NB-FFI repo… I’m taking a plane now and I do not have the time until thursday :( )

done

Cheers,
Alex

On Fri, Feb 12, 2016 at 5:50 PM, Aliaksei Syrel <[hidden email]> wrote:
On Fri, Feb 12, 2016 at 5:45 PM, Esteban Lorenzano <[hidden email]> wrote:
Float>>#pointer 
^ (ByteArray new: FFIExternalType pointerSize)
floatAt: 1 put: self;
yourself

Yes it does the trick :) Thanks!

Reply | Threaded
Open this post in threaded view
|

Re: FFI BoxedFloat64 bug?

EstebanLM
In reply to this post by Aliaksei Syrel

On 12 Feb 2016, at 17:50, Aliaksei Syrel <[hidden email]> wrote:

On Fri, Feb 12, 2016 at 5:45 PM, Esteban Lorenzano <[hidden email]> wrote:
Float>>#pointer 
^ (ByteArray new: FFIExternalType pointerSize)
floatAt: 1 put: self;
yourself

Yes it does the trick :) Thanks!

yes and no (I made a mistake): that works because incidentally pointers and floats have same size (4 bytes)… but can happen that it is not (doubles have 8 bytes)… but is ok for now :)
I will fix it correctly next week. 

Esteban
Reply | Threaded
Open this post in threaded view
|

Re: FFI BoxedFloat64 bug?

Clément Béra
I don't understand. All BoxedFloat have 8 bytes, that's why they are called BoxedFloat64. There are no 4-bytes floats in Pharo. Even in 32 bits.

2016-02-12 18:06 GMT+01:00 Esteban Lorenzano <[hidden email]>:

On 12 Feb 2016, at 17:50, Aliaksei Syrel <[hidden email]> wrote:

On Fri, Feb 12, 2016 at 5:45 PM, Esteban Lorenzano <[hidden email]> wrote:
Float>>#pointer 
^ (ByteArray new: FFIExternalType pointerSize)
floatAt: 1 put: self;
yourself

Yes it does the trick :) Thanks!

yes and no (I made a mistake): that works because incidentally pointers and floats have same size (4 bytes)… but can happen that it is not (doubles have 8 bytes)… but is ok for now :)
I will fix it correctly next week. 

Esteban

Reply | Threaded
Open this post in threaded view
|

Re: FFI BoxedFloat64 bug?

abergel
> I don't understand. All BoxedFloat have 8 bytes, that's why they are called BoxedFloat64. There are no 4-bytes floats in Pharo. Even in 32 bits.

I have some code that involve FFI and floats that was working before Spur.
I got the error mentioned by Alex.
Defining this pointer method gives a weird behavior.

It would be great to have this fixed.

Alexandre

>
> 2016-02-12 18:06 GMT+01:00 Esteban Lorenzano <[hidden email]>:
>
>> On 12 Feb 2016, at 17:50, Aliaksei Syrel <[hidden email]> wrote:
>>
>> On Fri, Feb 12, 2016 at 5:45 PM, Esteban Lorenzano <[hidden email]> wrote:
>> Float>>#pointer
>> ^ (ByteArray new: FFIExternalType pointerSize)
>> floatAt: 1 put: self;
>> yourself
>>
>> Yes it does the trick :) Thanks!
>
> yes and no (I made a mistake): that works because incidentally pointers and floats have same size (4 bytes)… but can happen that it is not (doubles have 8 bytes)… but is ok for now :)
> I will fix it correctly next week.
>
> Esteban
>

--
_,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
Alexandre Bergel  http://www.bergel.eu
^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.




Reply | Threaded
Open this post in threaded view
|

Re: FFI BoxedFloat64 bug?

EstebanLM
In reply to this post by Clément Béra
but in C (32bits) floats are 4 bytes, so when you do: 

ByteArray new 
floatAt: 1 put: somePharoFloat;

it will cast it to 4 bytes (if it fits which is most of the cases).

but as I said… it is an error I need to fix :)

Esteban

On 12 Feb 2016, at 20:50, Clément Bera <[hidden email]> wrote:

I don't understand. All BoxedFloat have 8 bytes, that's why they are called BoxedFloat64. There are no 4-bytes floats in Pharo. Even in 32 bits.

2016-02-12 18:06 GMT+01:00 Esteban Lorenzano <[hidden email]>:

On 12 Feb 2016, at 17:50, Aliaksei Syrel <[hidden email]> wrote:

On Fri, Feb 12, 2016 at 5:45 PM, Esteban Lorenzano <[hidden email]> wrote:
Float>>#pointer 
^ (ByteArray new: FFIExternalType pointerSize)
floatAt: 1 put: self;
yourself

Yes it does the trick :) Thanks!

yes and no (I made a mistake): that works because incidentally pointers and floats have same size (4 bytes)… but can happen that it is not (doubles have 8 bytes)… but is ok for now :)
I will fix it correctly next week. 

Esteban


Reply | Threaded
Open this post in threaded view
|

Re: FFI BoxedFloat64 bug?

EstebanLM
In reply to this post by abergel

> On 17 Feb 2016, at 19:35, Alexandre Bergel <[hidden email]> wrote:
>
>> I don't understand. All BoxedFloat have 8 bytes, that's why they are called BoxedFloat64. There are no 4-bytes floats in Pharo. Even in 32 bits.
>
> I have some code that involve FFI and floats that was working before Spur.
> I got the error mentioned by Alex.
> Defining this pointer method gives a weird behavior.
>
> It would be great to have this fixed.

probably because of what I just described… I will commit a fix.

>
> Alexandre
>
>>
>> 2016-02-12 18:06 GMT+01:00 Esteban Lorenzano <[hidden email]>:
>>
>>> On 12 Feb 2016, at 17:50, Aliaksei Syrel <[hidden email]> wrote:
>>>
>>> On Fri, Feb 12, 2016 at 5:45 PM, Esteban Lorenzano <[hidden email]> wrote:
>>> Float>>#pointer
>>> ^ (ByteArray new: FFIExternalType pointerSize)
>>> floatAt: 1 put: self;
>>> yourself
>>>
>>> Yes it does the trick :) Thanks!
>>
>> yes and no (I made a mistake): that works because incidentally pointers and floats have same size (4 bytes)… but can happen that it is not (doubles have 8 bytes)… but is ok for now :)
>> I will fix it correctly next week.
>>
>> Esteban
>>
>
> --
> _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
> Alexandre Bergel  http://www.bergel.eu
> ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
>
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: FFI BoxedFloat64 bug?

abergel
Thanks Esteban!

Alexandre


> On Feb 18, 2016, at 8:11 AM, Esteban Lorenzano <[hidden email]> wrote:
>
>
>> On 17 Feb 2016, at 19:35, Alexandre Bergel <[hidden email]> wrote:
>>
>>> I don't understand. All BoxedFloat have 8 bytes, that's why they are called BoxedFloat64. There are no 4-bytes floats in Pharo. Even in 32 bits.
>>
>> I have some code that involve FFI and floats that was working before Spur.
>> I got the error mentioned by Alex.
>> Defining this pointer method gives a weird behavior.
>>
>> It would be great to have this fixed.
>
> probably because of what I just described… I will commit a fix.
>
>>
>> Alexandre
>>
>>>
>>> 2016-02-12 18:06 GMT+01:00 Esteban Lorenzano <[hidden email]>:
>>>
>>>> On 12 Feb 2016, at 17:50, Aliaksei Syrel <[hidden email]> wrote:
>>>>
>>>> On Fri, Feb 12, 2016 at 5:45 PM, Esteban Lorenzano <[hidden email]> wrote:
>>>> Float>>#pointer
>>>> ^ (ByteArray new: FFIExternalType pointerSize)
>>>> floatAt: 1 put: self;
>>>> yourself
>>>>
>>>> Yes it does the trick :) Thanks!
>>>
>>> yes and no (I made a mistake): that works because incidentally pointers and floats have same size (4 bytes)… but can happen that it is not (doubles have 8 bytes)… but is ok for now :)
>>> I will fix it correctly next week.
>>>
>>> Esteban
>>>
>>
>> --
>> _,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
>> Alexandre Bergel  http://www.bergel.eu
>> ^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.
>>
>>
>>
>>
>
>

--
_,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:
Alexandre Bergel  http://www.bergel.eu
^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;._,.;:~^~:;.




Reply | Threaded
Open this post in threaded view
|

Re: FFI BoxedFloat64 bug?

Clément Béra
In reply to this post by EstebanLM
I don't understand.

In 32 bits in C, there are 32 bits float called "float" or "single precision float" but its usage is very uncommon. People always use "double" as every 32 bits processors supports 64 bits float nowadays. When I look at the Cairo reference manual, only double are used, so I don't understand why you need to cast BoxedFloat64 to single precision float for FFI. The ThreadedIA32FFIPlugin has both #ffiPushDoubleFloat:in: and ffiPushSingleFloat:in: so all the support seems to be available. 

Can you explain why by default you reduce the precision of float to 32 bits ? Is it because the library used expects a single precision float to be passed ?



2016-02-18 11:57 GMT+01:00 Esteban Lorenzano <[hidden email]>:
but in C (32bits) floats are 4 bytes, so when you do: 

ByteArray new 
floatAt: 1 put: somePharoFloat;

it will cast it to 4 bytes (if it fits which is most of the cases).

but as I said… it is an error I need to fix :)

Esteban


On 12 Feb 2016, at 20:50, Clément Bera <[hidden email]> wrote:

I don't understand. All BoxedFloat have 8 bytes, that's why they are called BoxedFloat64. There are no 4-bytes floats in Pharo. Even in 32 bits.

2016-02-12 18:06 GMT+01:00 Esteban Lorenzano <[hidden email]>:

On 12 Feb 2016, at 17:50, Aliaksei Syrel <[hidden email]> wrote:

On Fri, Feb 12, 2016 at 5:45 PM, Esteban Lorenzano <[hidden email]> wrote:
Float>>#pointer 
^ (ByteArray new: FFIExternalType pointerSize)
floatAt: 1 put: self;
yourself

Yes it does the trick :) Thanks!

yes and no (I made a mistake): that works because incidentally pointers and floats have same size (4 bytes)… but can happen that it is not (doubles have 8 bytes)… but is ok for now :)
I will fix it correctly next week. 

Esteban



Reply | Threaded
Open this post in threaded view
|

Re: FFI BoxedFloat64 bug?

Clément Béra
OK nevermind I got it now. I talked with Esteban. I had misunderstood.

2016-02-18 14:57 GMT+01:00 Clément Bera <[hidden email]>:
I don't understand.

In 32 bits in C, there are 32 bits float called "float" or "single precision float" but its usage is very uncommon. People always use "double" as every 32 bits processors supports 64 bits float nowadays. When I look at the Cairo reference manual, only double are used, so I don't understand why you need to cast BoxedFloat64 to single precision float for FFI. The ThreadedIA32FFIPlugin has both #ffiPushDoubleFloat:in: and ffiPushSingleFloat:in: so all the support seems to be available. 

Can you explain why by default you reduce the precision of float to 32 bits ? Is it because the library used expects a single precision float to be passed ?



2016-02-18 11:57 GMT+01:00 Esteban Lorenzano <[hidden email]>:
but in C (32bits) floats are 4 bytes, so when you do: 

ByteArray new 
floatAt: 1 put: somePharoFloat;

it will cast it to 4 bytes (if it fits which is most of the cases).

but as I said… it is an error I need to fix :)

Esteban


On 12 Feb 2016, at 20:50, Clément Bera <[hidden email]> wrote:

I don't understand. All BoxedFloat have 8 bytes, that's why they are called BoxedFloat64. There are no 4-bytes floats in Pharo. Even in 32 bits.

2016-02-12 18:06 GMT+01:00 Esteban Lorenzano <[hidden email]>:

On 12 Feb 2016, at 17:50, Aliaksei Syrel <[hidden email]> wrote:

On Fri, Feb 12, 2016 at 5:45 PM, Esteban Lorenzano <[hidden email]> wrote:
Float>>#pointer 
^ (ByteArray new: FFIExternalType pointerSize)
floatAt: 1 put: self;
yourself

Yes it does the trick :) Thanks!

yes and no (I made a mistake): that works because incidentally pointers and floats have same size (4 bytes)… but can happen that it is not (doubles have 8 bytes)… but is ok for now :)
I will fix it correctly next week. 

Esteban




Reply | Threaded
Open this post in threaded view
|

Re: FFI BoxedFloat64 bug?

Henrik Sperre Johansen
I must admit, I don't get it either...
When you have a signature with a pointer to a primitive type, it's usually because
a) The method replaces the value
b) The method expects a pointer to an array with items of the primitive type.

In neither case is automatic marshalling from Smalltalk type very useful.

On Thu, Feb 18, 2016 at 4:33 PM, Clément Bera <[hidden email]> wrote:
OK nevermind I got it now. I talked with Esteban. I had misunderstood.

2016-02-18 14:57 GMT+01:00 Clément Bera <[hidden email]>:
I don't understand.

In 32 bits in C, there are 32 bits float called "float" or "single precision float" but its usage is very uncommon. People always use "double" as every 32 bits processors supports 64 bits float nowadays. When I look at the Cairo reference manual, only double are used, so I don't understand why you need to cast BoxedFloat64 to single precision float for FFI. The ThreadedIA32FFIPlugin has both #ffiPushDoubleFloat:in: and ffiPushSingleFloat:in: so all the support seems to be available. 

Can you explain why by default you reduce the precision of float to 32 bits ? Is it because the library used expects a single precision float to be passed ?



2016-02-18 11:57 GMT+01:00 Esteban Lorenzano <[hidden email]>:
but in C (32bits) floats are 4 bytes, so when you do: 

ByteArray new 
floatAt: 1 put: somePharoFloat;

it will cast it to 4 bytes (if it fits which is most of the cases).

but as I said… it is an error I need to fix :)

Esteban


On 12 Feb 2016, at 20:50, Clément Bera <[hidden email]> wrote:

I don't understand. All BoxedFloat have 8 bytes, that's why they are called BoxedFloat64. There are no 4-bytes floats in Pharo. Even in 32 bits.

2016-02-12 18:06 GMT+01:00 Esteban Lorenzano <[hidden email]>:

On 12 Feb 2016, at 17:50, Aliaksei Syrel <[hidden email]> wrote:

On Fri, Feb 12, 2016 at 5:45 PM, Esteban Lorenzano <[hidden email]> wrote:
Float>>#pointer 
^ (ByteArray new: FFIExternalType pointerSize)
floatAt: 1 put: self;
yourself

Yes it does the trick :) Thanks!

yes and no (I made a mistake): that works because incidentally pointers and floats have same size (4 bytes)… but can happen that it is not (doubles have 8 bytes)… but is ok for now :)
I will fix it correctly next week. 

Esteban





Reply | Threaded
Open this post in threaded view
|

Re: FFI BoxedFloat64 bug?

EstebanLM
Floats and doubles in C have different size, regardless the size of floats in pharo who are always 64bits. 
But a call to a function(float a) expects a 32bits float and not a 64bit so a cast needs to be done (automatically in FFI), now if you are calling a function(float *a) and you have a float=42.0 you have to pass an address with place to store 32bits, not 64bits… so

(ByteArray new: 4)
floatAt: 1 put: 42.0

… will do the job. 
But if you have a function(double *a), you need to do: 

(ByteArray new: 8)
doubleAt: 1 put: 42.0

Now… old nativeboost was prepared to do that conversion for you (if this was a good idea or not, is another story and needs to be told in another moment, and thread).
So, to allow operations style: 

UNIXTime localTime: (UNIXTime getTime: nil)

where: 

UNIXTime>>localTime: time
^ self ffiCall: #(tm* localtime(time_t* time) ) 
 module: LibC

and:  

getTime: t
^self ffiCall: #(time_t time(time_t* t) ) 
module: LibC
options: #(+ optCoerceNilToNull)

(from OS-Unix package)

To work fine, I need to reproduce that behaviour… which is what the #rollToArity: method does.

So yes, is useful… very useful.
 

On 18 Feb 2016, at 17:51, Henrik Sperre Johansen <[hidden email]> wrote:

I must admit, I don't get it either...
When you have a signature with a pointer to a primitive type, it's usually because
a) The method replaces the value
b) The method expects a pointer to an array with items of the primitive type.

In neither case is automatic marshalling from Smalltalk type very useful.

On Thu, Feb 18, 2016 at 4:33 PM, Clément Bera <[hidden email]> wrote:
OK nevermind I got it now. I talked with Esteban. I had misunderstood.

2016-02-18 14:57 GMT+01:00 Clément Bera <[hidden email]>:
I don't understand.

In 32 bits in C, there are 32 bits float called "float" or "single precision float" but its usage is very uncommon. People always use "double" as every 32 bits processors supports 64 bits float nowadays. When I look at the Cairo reference manual, only double are used, so I don't understand why you need to cast BoxedFloat64 to single precision float for FFI. The ThreadedIA32FFIPlugin has both #ffiPushDoubleFloat:in: and ffiPushSingleFloat:in: so all the support seems to be available. 

Can you explain why by default you reduce the precision of float to 32 bits ? Is it because the library used expects a single precision float to be passed ?



2016-02-18 11:57 GMT+01:00 Esteban Lorenzano <[hidden email]>:
but in C (32bits) floats are 4 bytes, so when you do: 

ByteArray new 
floatAt: 1 put: somePharoFloat;

it will cast it to 4 bytes (if it fits which is most of the cases).

but as I said… it is an error I need to fix :)

Esteban


On 12 Feb 2016, at 20:50, Clément Bera <[hidden email]> wrote:

I don't understand. All BoxedFloat have 8 bytes, that's why they are called BoxedFloat64. There are no 4-bytes floats in Pharo. Even in 32 bits.

2016-02-12 18:06 GMT+01:00 Esteban Lorenzano <[hidden email]>:

On 12 Feb 2016, at 17:50, Aliaksei Syrel <[hidden email]> wrote:

On Fri, Feb 12, 2016 at 5:45 PM, Esteban Lorenzano <[hidden email]> wrote:
Float>>#pointer 
^ (ByteArray new: FFIExternalType pointerSize)
floatAt: 1 put: self;
yourself

Yes it does the trick :) Thanks!

yes and no (I made a mistake): that works because incidentally pointers and floats have same size (4 bytes)… but can happen that it is not (doubles have 8 bytes)… but is ok for now :)
I will fix it correctly next week. 

Esteban