UFFI - Could not coerce arguments

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

UFFI - Could not coerce arguments

SergeStinckwich
I would like to pass a pointer to an array of pointers to a FFI call and I have problems ...

​I have this method:

runOutputs: aTF_OutputArray size: anInteger
    | status outvalues |
    status := TF_Status create.
    outvalues := FFIExternalArray externalNewType: 'TF_Tensor*' size: anInteger.
    self library
        runSession: self
        options: FFIExternalObject null
        inputs: FFIExternalObject null
        values: FFIExternalObject null
        count: 0
        outputs: aTF_OutputArray getHandle
        values: outvalues getHandle
        count: anInteger
        targets: FFIExternalObject null
        count: 0
        metadata: FFIExternalObject null
        status: status.
    status check.
    ^ outvalues

​the FFI call is like that :

runSession: aTF_Session
    options: opsTF_Buffer
    inputs: inTF_OutputArray values: inTF_TensorArray count: inCount
    outputs: outTF_OutputArray values: outTF_TensorArrayPtr count: outCount
    targets: aTF_OperationArray count: targetCount
    metadata: metaTF_Buffer
    status: aTF_Status
   
    "F_CAPI_EXPORT extern void TF_SessionRun(
    TF_Session* session,
    // RunOptions
    const TF_Buffer* run_options,
    // Input tensors
    const TF_Output* inputs, TF_Tensor* const* input_values, int ninputs,
    // Output tensors
    const TF_Output* outputs, TF_Tensor** output_values, int noutputs,
    // Target operations
    const TF_Operation* const* target_opers, int ntargets,
    // RunMetadata
    TF_Buffer* run_metadata,
    // Output status
     TF_Status*);"
       
        ^ self
        ffiCall: #(void TF_SessionRun #(TF_Session * aTF_Session, TF_Buffer * opsTF_Buffer, TF_Output * inTF_OutputArray, TF_Tensor * inTF_TensorArray, int inCount, TF_Output * outTF_OutputArray, TF_Tensor * outTF_TensorArrayPtr, int outCount, TF_Operation * aTF_OperationArray, int targetCount, TF_Buffer * metaTF_Buffer, TF_Status * aTF_Status))
        module: TensorFlowCAPI

TF_Tensor is an opaque object.

I have an error: "Could not coerce arguments".
I guess this is related to the way I pass arguments to the FFI function ?

--
Serge Stinckwich
UMI UMMISCO 209 (SU/IRD/UY1)
"Programs must be written for people to read, and only incidentally for machines to execute."
http://www.doesnotunderstand.org/
Reply | Threaded
Open this post in threaded view
|

Re: UFFI - Could not coerce arguments

EstebanLM
hi,

it all depends on how you are declaring your types.

here, for example you are passing 

aTF_OutputArray getHandle

that’s a “void*” value (an ExternalAddress or ExternalData object), and in declaration you have (if I read correctly):

TF_Output * 

so, first question is: if TF_Output != void, then you have a coercing problem :).

you can fix that just changing the notation to receive a void * (in C is all the same, but not in pharo :)) 

note that this can be happening in a lot of places, since your function has a lot of arguments, I just put an example of what can be wrong. 

cheers, 
Esteban


On 27 Apr 2018, at 11:23, Serge Stinckwich <[hidden email]> wrote:

I would like to pass a pointer to an array of pointers to a FFI call and I have problems ...

​I have this method:

runOutputs: aTF_OutputArray size: anInteger
    | status outvalues |
    status := TF_Status create.
    outvalues := FFIExternalArray externalNewType: 'TF_Tensor*' size: anInteger.
    self library
        runSession: self
        options: FFIExternalObject null
        inputs: FFIExternalObject null
        values: FFIExternalObject null
        count: 0
        outputs: aTF_OutputArray getHandle
        values: outvalues getHandle
        count: anInteger
        targets: FFIExternalObject null
        count: 0
        metadata: FFIExternalObject null
        status: status.
    status check.
    ^ outvalues

​the FFI call is like that :

runSession: aTF_Session
    options: opsTF_Buffer
    inputs: inTF_OutputArray values: inTF_TensorArray count: inCount
    outputs: outTF_OutputArray values: outTF_TensorArrayPtr count: outCount
    targets: aTF_OperationArray count: targetCount
    metadata: metaTF_Buffer
    status: aTF_Status
   
    "F_CAPI_EXPORT extern void TF_SessionRun(
    TF_Session* session,
    // RunOptions
    const TF_Buffer* run_options,
    // Input tensors
    const TF_Output* inputs, TF_Tensor* const* input_values, int ninputs,
    // Output tensors
    const TF_Output* outputs, TF_Tensor** output_values, int noutputs,
    // Target operations
    const TF_Operation* const* target_opers, int ntargets,
    // RunMetadata
    TF_Buffer* run_metadata,
    // Output status
     TF_Status*);"
       
        ^ self
        ffiCall: #(void TF_SessionRun #(TF_Session * aTF_Session, TF_Buffer * opsTF_Buffer, TF_Output * inTF_OutputArray, TF_Tensor * inTF_TensorArray, int inCount, TF_Output * outTF_OutputArray, TF_Tensor * outTF_TensorArrayPtr, int outCount, TF_Operation * aTF_OperationArray, int targetCount, TF_Buffer * metaTF_Buffer, TF_Status * aTF_Status))
        module: TensorFlowCAPI

TF_Tensor is an opaque object.

I have an error: "Could not coerce arguments".
I guess this is related to the way I pass arguments to the FFI function ?

--
Serge Stinckwich
UMI UMMISCO 209 (SU/IRD/UY1)
"Programs must be written for people to read, and only incidentally for machines to execute."
http://www.doesnotunderstand.org/

Reply | Threaded
Open this post in threaded view
|

Re: UFFI - Could not coerce arguments

Ben Coman
In reply to this post by SergeStinckwich


On 27 April 2018 at 17:23, Serge Stinckwich <[hidden email]> wrote:
I would like to pass a pointer to an array of pointers to a FFI call and I have problems ...

​I have this method:

runOutputs: aTF_OutputArray size: anInteger
    | status outvalues |
    status := TF_Status create.
    outvalues := FFIExternalArray externalNewType: 'TF_Tensor*' size: anInteger.
    self library
        runSession: self
        options: FFIExternalObject null
        inputs: FFIExternalObject null
        values: FFIExternalObject null

Sorry I'm (again) not addressing your question :P, 
but please let me piggyback learning something.

@All, What is the advantage of "FFIExternalObject null" ?
I was under the impression that in general "nil" could be used in similar situations.

cheers -ben
 
        count: 0
        outputs: aTF_OutputArray getHandle
        values: outvalues getHandle
        count: anInteger
        targets: FFIExternalObject null
        count: 0
        metadata: FFIExternalObject null
        status: status.
    status check.
    ^ outvalues

​the FFI call is like that :

runSession: aTF_Session
    options: opsTF_Buffer
    inputs: inTF_OutputArray values: inTF_TensorArray count: inCount
    outputs: outTF_OutputArray values: outTF_TensorArrayPtr count: outCount
    targets: aTF_OperationArray count: targetCount
    metadata: metaTF_Buffer
    status: aTF_Status
   
    "F_CAPI_EXPORT extern void TF_SessionRun(
    TF_Session* session,
    // RunOptions
    const TF_Buffer* run_options,
    // Input tensors
    const TF_Output* inputs, TF_Tensor* const* input_values, int ninputs,
    // Output tensors
    const TF_Output* outputs, TF_Tensor** output_values, int noutputs,
    // Target operations
    const TF_Operation* const* target_opers, int ntargets,
    // RunMetadata
    TF_Buffer* run_metadata,
    // Output status
     TF_Status*);"
       
        ^ self
        ffiCall: #(void TF_SessionRun #(TF_Session * aTF_Session, TF_Buffer * opsTF_Buffer, TF_Output * inTF_OutputArray, TF_Tensor * inTF_TensorArray, int inCount, TF_Output * outTF_OutputArray, TF_Tensor * outTF_TensorArrayPtr, int outCount, TF_Operation * aTF_OperationArray, int targetCount, TF_Buffer * metaTF_Buffer, TF_Status * aTF_Status))
        module: TensorFlowCAPI

TF_Tensor is an opaque object.

I have an error: "Could not coerce arguments".
I guess this is related to the way I pass arguments to the FFI function ?

--
Serge Stinckwich
UMI UMMISCO 209 (SU/IRD/UY1)
"Programs must be written for people to read, and only incidentally for machines to execute."
http://www.doesnotunderstand.org/

Reply | Threaded
Open this post in threaded view
|

Re: UFFI - Could not coerce arguments

EstebanLM
hi,

On 27 Apr 2018, at 13:06, Ben Coman <[hidden email]> wrote:



On 27 April 2018 at 17:23, Serge Stinckwich <[hidden email]> wrote:
I would like to pass a pointer to an array of pointers to a FFI call and I have problems ...

​I have this method:

runOutputs: aTF_OutputArray size: anInteger
    | status outvalues |
    status := TF_Status create.
    outvalues := FFIExternalArray externalNewType: 'TF_Tensor*' size: anInteger.
    self library
        runSession: self
        options: FFIExternalObject null
        inputs: FFIExternalObject null
        values: FFIExternalObject null

Sorry I'm (again) not addressing your question :P, 
but please let me piggyback learning something.

@All, What is the advantage of "FFIExternalObject null" ?
I was under the impression that in general "nil" could be used in similar situations.

nope.
NULL != nil. 
nil = the instance of UndefinedObject
NULL = external address pointing to 0.

cheers,
Esteban


cheers -ben
 
        count: 0
        outputs: aTF_OutputArray getHandle
        values: outvalues getHandle
        count: anInteger
        targets: FFIExternalObject null
        count: 0
        metadata: FFIExternalObject null
        status: status.
    status check.
    ^ outvalues

​the FFI call is like that :

runSession: aTF_Session
    options: opsTF_Buffer
    inputs: inTF_OutputArray values: inTF_TensorArray count: inCount
    outputs: outTF_OutputArray values: outTF_TensorArrayPtr count: outCount
    targets: aTF_OperationArray count: targetCount
    metadata: metaTF_Buffer
    status: aTF_Status
   
    "F_CAPI_EXPORT extern void TF_SessionRun(
    TF_Session* session,
    // RunOptions
    const TF_Buffer* run_options,
    // Input tensors
    const TF_Output* inputs, TF_Tensor* const* input_values, int ninputs,
    // Output tensors
    const TF_Output* outputs, TF_Tensor** output_values, int noutputs,
    // Target operations
    const TF_Operation* const* target_opers, int ntargets,
    // RunMetadata
    TF_Buffer* run_metadata,
    // Output status
     TF_Status*);"
       
        ^ self
        ffiCall: #(void TF_SessionRun #(TF_Session * aTF_Session, TF_Buffer * opsTF_Buffer, TF_Output * inTF_OutputArray, TF_Tensor * inTF_TensorArray, int inCount, TF_Output * outTF_OutputArray, TF_Tensor * outTF_TensorArrayPtr, int outCount, TF_Operation * aTF_OperationArray, int targetCount, TF_Buffer * metaTF_Buffer, TF_Status * aTF_Status))
        module: TensorFlowCAPI

TF_Tensor is an opaque object.

I have an error: "Could not coerce arguments".
I guess this is related to the way I pass arguments to the FFI function ?

--
Serge Stinckwich
UMI UMMISCO 209 (SU/IRD/UY1)
"Programs must be written for people to read, and only incidentally for machines to execute."
http://www.doesnotunderstand.org/


Reply | Threaded
Open this post in threaded view
|

Re: UFFI - Could not coerce arguments

SergeStinckwich
In reply to this post by EstebanLM


On Fri, Apr 27, 2018 at 10:45 AM, Esteban Lorenzano <[hidden email]> wrote:
hi,

it all depends on how you are declaring your types.

here, for example you are passing 

aTF_OutputArray getHandle

that’s a “void*” value (an ExternalAddress or ExternalData object), and in declaration you have (if I read correctly):

TF_Output * 

so, first question is: if TF_Output != void, then you have a coercing problem :).


​TF_Output != void, because this is a subclass of FFIOpaqueObject
 
you can fix that just changing the notation to receive a void * (in C is all the same, but not in pharo :)) 

note that this can be happening in a lot of places, since your function has a lot of arguments, I just put an example of what can be wrong. 




I try to replace all types by void* here:


TF_Session>>runSession: aTF_Session
    options: opsTF_Buffer
    inputs: inTF_OutputArray values: inTF_TensorArray count: inCount
    outputs: outTF_OutputArray values: outTF_TensorArrayPtr count: outCount
    targets: aTF_OperationArray count: targetCount
    metadata: metaTF_Buffer
    status: aTF_Status
   
    "F_CAPI_EXPORT extern void TF_SessionRun(
    TF_Session* session,
    // RunOptions
    const TF_Buffer* run_options,
    // Input tensors
    const TF_Output* inputs, TF_Tensor* const* input_values, int ninputs,
    // Output tensors
    const TF_Output* outputs, TF_Tensor** output_values, int noutputs,
    // Target operations
    const TF_Operation* const* target_opers, int ntargets,
    // RunMetadata
    TF_Buffer* run_metadata,
    // Output status
     TF_Status*);"
       
        ^ self
        ffiCall: #(void TF_SessionRun #(void* aTF_Session, void* opsTF_Buffer, void* inTF_OutputArray, void* inTF_TensorArray, int inCount, void* outTF_OutputArray, void* outTF_TensorArrayPtr, int outCount, void* aTF_OperationArray, int targetCount, void* metaTF_Buffer, void* aTF_Status))
        module: TensorFlowCAPI

but still have some error: "Could not coerce arguments" ....

First method was called by :

TF_Session>>runOutputs: aTF_OutputArray size: anInteger
    | status outvalues |
    status := TF_Status create.
    outvalues := FFIExternalArray externalNewType: 'TF_Tensor*' size: anInteger.
    self library
        runSession: self getHandle
        options: FFIExternalObject null
        inputs: FFIExternalObject null
        values: FFIExternalObject null
        count: 0
        outputs: aTF_OutputArray getHandle
        values: outvalues getHandle
        count: anInteger
        targets: FFIExternalObject null
        count: 0
        metadata: FFIExternalObject null
        status: status getHandle.
    status check.
    ^ outvalues


called by:

TF_Session>>runOutputs: anArrayOfTF_Outputs
    | outputs |
    outputs := FFIExternalArray externalNewType: 'TF_Output' fromArray: anArrayOfTF_Outputs.
    ^ self runOutputs: outputs size: anArrayOfTF_Outputs size

called by :

TF_Session>>runOutput: aTF_Output
    | results |
    results := self runOutputs: {aTF_Output}.
    ^ results first

called by :

testGraphZeros
    | graph session result zeros values |
    graph := TF_Graph create.
    zeros := graph zerosShaped: #(100 100 10).
    session := TF_Session on: graph.
    result := session runOutput: (zeros output: 0).
    values := result allFloats.
    self assert: #(100 100 10) equals: result shape.
    self assert: 100 * 100 * 10 equals: values size.
    self assert: 0 equals: values min.
    self assert: 0 equals: values max


I'm a bit desperated :-(
And impossible to know where the problem come from ...


--
Serge Stinckwich
UMI UMMISCO 209 (SU/IRD/UY1)
"Programs must be written for people to read, and only incidentally for machines to execute."
http://www.doesnotunderstand.org/