Add some functions for Tensorflow

Add some functions for Tensorflow

Postby CharlesKwon » Fri Jan 11, 2019 5:15 pm

Hello.

I adding some functions/method for Tensoflow for Fivewin like following.^^


METHOD GraphNextOperation( nPos )

DLL FUNCTION TF_GraphNextOperation( hGraph AS LONG, @nPos AS LONG ) AS LONG LIB hDLL
DLL FUNCTION TF_OperationName( hOperation AS LONG ) AS LPSTR LIB hDLL
DLL FUNCTION TF_OperationOpType( hOperation AS LONG ) AS LPSTR LIB hDLL
DLL FUNCTION TF_OperationDevice( hOperation AS LONG ) AS LPSTR LIB hDLL
DLL FUNCTION TF_OperationNumOutputs( hOperation AS LONG ) AS LONG LIB hDLL
DLL FUNCTION TF_OperationNumInputs( hOperation AS LONG ) AS LONG LIB hDLL



Code: Select all  Expand view

#include "FiveWin.ch"

#define TF_INT32   3
#define TF_STRING  7
#define TF_INT64   9

static hDLL

function Main()
   local oTF  := TensorFlow():New()
   LOCAL nOp
   LOCAL nCounter := 0
   LOCAL nPos := 1
   LOCAL nOld  := 0

   oTF:ImportGraph( "graph.pb" )

   WHILE .T.
       nOp := oTF:GraphNextOperation( @nPos )

       IF nOp == 0
           EXIT
       ENDIF

       ?TF_OperationName( nOp ),TF_OperationOpType( nOp ), TF_OperationDevice( nOp ), TF_OperationNumOutputs( nOp ), TF_OperationNumInputs( nOp )

       IF nPos == nOld
          EXIT
       ENDIF

   ENDDO



   //MsgInfo( oTF:Version() )

  // oTF:Run( oTF:Mul( oTF:Constant( 5, "Five" ), oTF:Constant( 3, "three" ) ) )

  //   MsgInfo( oTF:Output() )

   oTF:End()

return nil

CLASS TensorFlow

   DATA hGraph
   DATA hOptions
   DATA hStatus
   DATA hSession
   DATA hTensorOutput

   METHOD New()

   METHOD Add( hOperation1, hOperation1, cName )

   METHOD Mul( hOperation1, hOperation2, cName )

   METHOD MatMul( hOperation1, hOperation2, cName )

   METHOD Version() INLINE TF_Version()

   METHOD ImportGraph( cFileName )

   METHOD TensorNum( nValue )

   METHOD TensorString( cString )

   METHOD End()

   METHOD StatusCode() INLINE TF_GetCode( ::hStatus )

   METHOD Variable( cVarName, nDataType )

   METHOD Constant( uValue, cName )

   METHOD Run( hOperation )

   METHOD Output()

   METHOD GraphNextOperation()

ENDCLASS

METHOD New() CLASS TensorFlow

   hDLL = LoadLibrary( "tensorflow.dll" )

   ::hGraph = TF_NewGraph()
   ::hOptions = TF_NewSessionOptions()
   ::hStatus = TF_NewStatus()
   ::hSession = TF_NewSession( ::hGraph, ::hOptions, ::hStatus )

return Self

METHOD End() CLASS TensorFlow

   TF_CloseSession( ::hSession, ::hStatus )
   TF_DeleteSession( ::hSession, ::hStatus )
   TF_DeleteStatus( ::hStatus )
   TF_DeleteSessionOptions( ::hOptions )

   FreeLibrary( hDLL )

return nil

METHOD Add( hOperation1, hOperation2, cName ) CLASS TensorFlow

   local hOperationDescription := TF_NewOperation( ::hGraph, "AddN", If( cName == nil, "AddN", cName ) )
   local hOperation, hOutput

   TF_AddInputList( hOperationDescription, hOutput := TF_Output2( hOperation1, hOperation2 ), 2 )

   hOperation = TF_FinishOperation( hOperationDescription, ::hStatus )

   hb_xfree( hOutput )

   if TF_GetCode( ::hStatus ) != 0
      MsgAlert( TF_Message( ::hStatus ), "Error creating AddN operator: " + Str( TF_GetCode( ::hStatus ) ))
   endif

return hOperation


/*


*/


METHOD Mul( hOperation1, hOperation2, cName ) CLASS TensorFlow

   local hOperationDescription := TF_NewOperation( ::hGraph, "Mul", If( cName == nil, "Mul", cName ) )
   local hOperation, hOutput1, hOutput2


   TF_AddInput( hOperationDescription, hOutput1 := TF_Output( hOperation1 ) )
   TF_AddInput( hOperationDescription, hOutput2 := TF_Output( hOperation2 ) )


   hOperation = TF_FinishOperation( hOperationDescription, ::hStatus )

   hb_xfree( hOutput1 )
   hb_xfree( hOutput2 )

   if TF_GetCode( ::hStatus ) != 0
      MsgAlert( TF_Message( ::hStatus ), "Error creating AddN operator: " + Str( TF_GetCode( ::hStatus ) ))
   endif

return hOperation


METHOD MatMul( hOperation1, hOperation2, cName ) CLASS TensorFlow

   local hOperationDescription := TF_NewOperation( ::hGraph, "MatMul", If( cName == nil, "MatMul", cName ) )
   local hOperation, hOutput1, hOutput2


   TF_AddInput( hOperationDescription, hOutput1 := TF_Output( hOperation1 ) )
   TF_AddInput( hOperationDescription, hOutput2 := TF_Output( hOperation2 ) )

   hOperation = TF_FinishOperation( hOperationDescription, ::hStatus )

   hb_xfree( hOutput1 )
   hb_xfree( hOutput2 )

   if TF_GetCode( ::hStatus ) != 0
      MsgAlert( TF_Message( ::hStatus ), "Error creating 0perator: " + Str( TF_GetCode( ::hStatus ) ))
   endif

return hOperation

METHOD ImportGraph( cFileName ) CLASS TensorFlow

   local cGraph := MemoRead( cFileName )
   local hGraphDefOptions := TF_NewImportGraphDefOptions()

   LOCAL lOk := .F.

   IF !FILE ( cFileName )
      RETURN lOk
   ENDIF

   TF_GraphImportGraphDef( ::hGraph, TF_NewBufferFromString( cGraph, Len( cGraph ) ), hGraphDefOptions, ::hStatus )

   IF TF_GetCode( ::hStatus ) != 0
      MsgAlert( TF_Message( ::hStatus ), "Error importing a Graph file" )
      lOk := .F.
   ELSE
      lOk := .T.
   ENDIF

   TF_DeleteImportGraphDefOptions( hGraphDefOptions )

return lOk

METHOD TensorNum( nValue ) CLASS TensorFlow

   local hTensor := TF_AllocateTensor( TF_INT32, 0, 0, 8 )

   Memset( TF_TensorData( hTensor ), 0, 8 )
   Memcpy( TF_TensorData( hTensor ), L2Bin( nValue ), Len( L2Bin( nValue ) ) )

return hTensor

METHOD TensorString( cString ) CLASS TensorFlow

   local hTensor := TF_AllocateTensor( TF_STRING, 0, 0, 8 + TF_StringEncodedSize( Len( cString ) ) )

   Memset( TF_TensorData( hTensor ), 0, 8 )

   TF_StringEncode( cString, Len( cString ), 8 + TF_TensorData( hTensor ), TF_StringEncodedSize( Len( cString ) ), ::hStatus )

   if TF_GetCode( ::hStatus ) != 0
      MsgAlert( TF_Message( ::hStatus ), "Error creating a Tensor string" )
   endif

return hTensor

METHOD Variable( cVarName, nDataType ) CLASS TensorFlow

   local hOperationDescription := TF_NewOperation( ::hGraph, "Variable", cVarName )

   TF_SetAttrType( hOperationDescription, "dtype", nDataType )

return TF_FinishOperation( hOperationDescription, ::hStatus )

METHOD Constant( uValue, cName ) CLASS TensorFlow

   local hOperationDescription, hTensor

   do case
      case ValType( uValue ) == "C"
         hTensor = ::TensorString( uValue )

      case ValType( uValue ) == "N"
         hTensor = ::TensorNum( uValue )
   endcase

   hOperationDescription = TF_NewOperation( ::hGraph, "Const", cName )
   TF_SetAttrTensor( hOperationDescription, "value", hTensor, ::hStatus )
   TF_SetAttrType( hOperationDescription, "dtype", TF_TensorType( hTensor ) )

return TF_FinishOperation( hOperationDescription, ::hStatus )

METHOD Run( hOperation ) CLASS TensorFlow

   local hTensorOutput := 0, hOutput

   TF_SessionRun( ::hSession, 0,;
                  0, 0, 0,;  // Inputs
                  hOutput := TF_Output( hOperation, 0 ), @hTensorOutput, 1,;  // Outputs
                  hOperation, 1,;  // Operations
                  0, ::hStatus )

   hb_xfree( hOutput )

   ::hTensorOutput = hTensorOutput

return nil

METHOD Output() CLASS TensorFlow

   local nType := TF_TensorType( ::hTensorOutput )
   local uValue

   do case
      case nType == TF_STRING
         uValue = TF_TensorString( TF_TensorData( ::hTensorOutput ) )

      case nType == TF_INT64 .or. nType == TF_INT32
         uValue = TF_TensorNum( TF_TensorData( ::hTensorOutput ) )

      otherwise
         MsgAlert( "type not supported in Method Output yet", nType )
   endcase

return uValue

/*
  2019-01-12 by. Charles Kwon
*/


METHOD GraphNextOperation( nPos ) CLASS TensorFlow
   LOCAL nOp  := TF_GraphNextOperation( ::hGraph, @nPos )

RETURN nOp




DLL FUNCTION TF_Version() AS LPSTR LIB hDLL

DLL FUNCTION TF_NewGraph() AS LONG LIB hDLL

DLL FUNCTION TF_NewSessionOptions() AS LONG LIB hDLL

DLL FUNCTION TF_NewStatus() AS LONG LIB hDLL

DLL FUNCTION TF_NewSession( hGraph AS LONG, hOptions AS LONG, hStatus AS LONG ) AS LONG LIB hDLL

DLL FUNCTION TF_CloseSession( hSession AS LONG, hStatus AS LONG ) AS VOID LIB hDLL

DLL FUNCTION TF_DeleteSession( hSession AS LONG, hStatus AS LONG ) AS VOID LIB hDLL

DLL FUNCTION TF_DeleteStatus( hStatus AS LONG ) AS VOID LIB hDLL

DLL FUNCTION TF_DeleteSessionOptions( hOptions AS LONG ) AS VOID LIB hDLL

DLL FUNCTION TF_NewImportGraphDefOptions() AS LONG LIB hDLL

DLL FUNCTION TF_GraphImportGraphDef( hGraph AS LONG, hBuffer AS LONG, hGraphDefOptions AS LONG, hStatus AS LONG ) AS LONG LIB hDLL

DLL FUNCTION TF_NewBufferFromString( cString AS LPSTR, nLegth AS LONG ) AS LONG LIB hDLL

DLL FUNCTION TF_GetCode( hStatus AS LONG ) AS LONG LIB hDLL

DLL FUNCTION TF_DeleteImportGraphDefOptions( hGraphDefOptions AS LONG ) AS LONG LIB hDLL

DLL FUNCTION TF_NewTensor( nType AS LONG, @pDims AS LONG, nDims AS LONG, @pData AS LONG, nLength AS LONG, pDeallocator AS LONG,;
                           pDeallocatorArgs AS LONG ) AS LONG LIB hDLL

DLL FUNCTION TF_AllocateTensor( nType AS LONG, pDims AS LONG, nDims AS LONG, nLegth AS LONG ) AS LONG LIB hDLL

DLL FUNCTION TF_StringEncodedSize( nLength AS LONG ) AS LONG LIB hDLL

DLL FUNCTION TF_TensorData( hTensor AS LONG ) AS LONG LIB hDLL

DLL FUNCTION TF_StringEncode( cString AS LPSTR, nLength AS LONG, pDest AS LONG, nDestLength AS LONG, hStatus AS LONG ) AS LONG LIB hDLL

DLL FUNCTION TF_SessionRun( hSession AS LONG, hRunOptions AS LONG, hInputs AS LONG, @hInputValues AS LONG, nInputs AS LONG,;
                            hOutputs AS LONG, @hOutputValues AS LONG, nOutputs AS LONG, @hTargetOperations AS LONG, nTargets AS LONG,;
                            hRunMetadata AS LONG, hStatus AS LONG ) AS VOID LIB hDLL

DLL FUNCTION TF_Message( hStatus AS LONG ) AS LPSTR LIB hDLL

DLL FUNCTION TF_NewOperation( hGraph AS LONG, cOperationType AS LPSTR, cOperationName AS LPSTR ) AS LONG LIB hDLL

DLL FUNCTION TF_SetAttrTensor( hOperationDescription AS LONG, cAttributeName AS LPSTR, hTensor AS LONG, hStatus AS LONG ) AS VOID LIB hDLL

DLL FUNCTION TF_TensorType( hTensor AS LONG ) AS LONG LIB hDLL

DLL FUNCTION TF_SetAttrType( hOperationDescription AS LONG, cAttributeName AS LPSTR, nDataType AS LONG ) AS VOID LIB hDLL

DLL FUNCTION TF_FinishOperation( hOperationDescription AS LONG, hStatus AS LONG ) AS LONG LIB hDLL

DLL FUNCTION TF_AddInput( hOperationDescription AS LONG, nInput AS LONG ) AS VOID LIB hDLL

DLL FUNCTION TF_AddInputList( hOperationDescription AS LONG, hInputs AS LONG, nInputs AS LONG ) AS VOID LIB hDLL

DLL FUNCTION TF_GraphSetTensorShape( hGraph AS LONG, hOutput AS LONG, @pDims AS LONG, nDims AS LONG, hStatus AS LONG ) AS VOID LIB hDLL

DLL FUNCTION TF_SetAttrShape( hOperationDescription AS LONG, cAttributeName AS LPSTR, @pDims AS LONG, nDims AS LONG ) AS VOID LIB hDLL

/*
  2019-01-12 by. Charles Kwon
*/

DLL FUNCTION TF_GraphNextOperation( hGraph AS LONG, @nPos AS LONG ) AS LONG LIB hDLL
DLL FUNCTION TF_OperationName( hOperation AS LONG ) AS LPSTR LIB hDLL
DLL FUNCTION TF_OperationOpType( hOperation AS LONG ) AS LPSTR LIB hDLL
DLL FUNCTION TF_OperationDevice( hOperation AS LONG ) AS LPSTR LIB hDLL
DLL FUNCTION TF_OperationNumOutputs( hOperation AS LONG ) AS LONG LIB hDLL
DLL FUNCTION TF_OperationNumInputs( hOperation AS LONG ) AS LONG LIB hDLL




#pragma BEGINDUMP

#include <hbapi.h>

typedef struct TF_Output {
  void * oper;
  int index;
} TF_Output;

HB_FUNC( TF_OUTPUT )
{
   TF_Output * hOutput = ( TF_Output * ) hb_xgrab( sizeof( TF_Output ) );

   hOutput->oper = ( void * ) hb_parnll( 1 );
   hOutput->index = hb_parnl( 2 );

   hb_retnll( ( HB_LONGLONG ) hOutput );
}

HB_FUNC( TF_OUTPUT2 )
{
   TF_Output * hOutput = ( TF_Output * ) hb_xgrab( sizeof( TF_Output ) * 2 );

   hOutput[ 0 ].oper = ( void * ) hb_parnll( 1 );
   hOutput[ 0 ].index = 0;
   hOutput[ 1 ].oper = ( void * ) hb_parnll( 2 );
   hOutput[ 1 ].index = 0;

   hb_retnll( ( HB_LONGLONG ) hOutput );
}

HB_FUNC( TF_TENSORSTRING )
{
   hb_retc( ( ( char * ) hb_parnll( 1 ) ) + 9 );
}

HB_FUNC( TF_TENSORNUM )
{
   hb_retnl( * ( int * ) hb_parnll( 1 ) );
}

HB_FUNC( MEMSET )
{
   hb_retnll( ( HB_LONGLONG ) memset( ( void * ) hb_parnll( 1 ), hb_parnl( 2 ), hb_parnll( 3 ) ) );
}

HB_FUNC( MEMCPY )
{
   hb_retnll( ( HB_LONGLONG ) memcpy( ( void * ) hb_parnll( 1 ), ( void * ) hb_parc( 2 ), hb_parnll( 3 ) ) );
}

HB_FUNC( HB_XFREE )
{
   hb_xfree( ( void * ) hb_parnll( 1 ) );
}

#pragma ENDDUMP
User avatar
CharlesKwon
 
Posts: 28
Joined: Sun Nov 02, 2014 7:03 am

Re: Add some functions for Tensorflow

Postby richard-service » Sat Jan 12, 2019 12:10 am

Hi Charles,

Good job.
Best Regards,

Richard

Harbour 3.2.0dev (r2402101027) => Borland C++ v7.7 32bit
MySQL v8.0 /ADS v10
Harbour 3.2.0dev (r2011030937) => Borland C++ v7.4 64bit
User avatar
richard-service
 
Posts: 803
Joined: Tue Oct 16, 2007 8:57 am
Location: New Taipei City, Taiwan

Re: Add some functions for Tensorflow

Postby CharlesKwon » Sat Jan 12, 2019 2:03 am

Hello Richard,
I already add a Tensorflow graph browser^^


Code: Select all  Expand view

function Main()
   local oTF  := TensorFlow():New()
   LOCAL nOp
   LOCAL nCounter := 0

   LOCAL nPos := 1
   LOCAL nOld := 0

   LOCAL aInfo := {}
   LOCAL aGraphInfo := {}

   oTF:ImportGraph( "graph.pb" )

   WHILE .T.
       nOp := oTF:GraphNextOperation( @nPos )

       IF nOp == 0
           EXIT
       ENDIF

       aInfo := { TF_OperationName( nOp ),TF_OperationOpType( nOp ), TF_OperationDevice( nOp ), TF_OperationNumOutputs( nOp ), TF_OperationNumInputs( nOp ) }

       AADD ( aGraphInfo, aInfo )

       IF nPos == nOld
          EXIT
       ENDIF

   ENDDO

   Show_TFGraphInfo( aGraphInfo )



   //  MsgInfo( oTF:Version() )
   // oTF:Run( oTF:Mul( oTF:Constant( 5, "Five" ), oTF:Constant( 3, "three" ) ) )
   // MsgInfo( oTF:Output() )

   oTF:End()

return nil

STATIC FUNCTION Show_TFGraphInfo( aGraphInfo )
   LOCAL oWnd, oBar, oBrw

   DEFINE WINDOW oWnd TITLE "Tensorflow Graph information" FROM 0,0 TO 40, 100

   DEFINE BUTTONBAR OBAR OF oWnd SIZE 100,32 2007

   DEFINE BUTTON OF oBar PROMPT "Open"   ACTION oWnd:End() GROUP
   DEFINE BUTTON OF oBar PROMPT "Close"   ACTION oWnd:End() GROUP

   SET MESSAGE OF oWnd TO "c)Charles Kwon" 2007

   @ 0,0 XBROWSE oBrw OF oWnd               ;
      COLUMNS 1, 2, 3, 4,5                  ;
      HEADERS "Operation Name","Type","Device","Output", "Inpout"   ;
      COLSIZES 200, 100, 100, 100,100           ;
      ARRAY aGraphInfo CELL

   WITH OBJECT oBrw
      :CreateFromCode()
   END

   oWnd:oClient := oBrw

   ACTIVATE WINDOW oWnd




RETURN NIL



 
User avatar
CharlesKwon
 
Posts: 28
Joined: Sun Nov 02, 2014 7:03 am

Re: Add some functions for Tensorflow

Postby MOISES » Sat Jan 12, 2019 8:30 pm

Thank you.

Can you please share graph.pb and tensorflow.dll?.
Saludos / Regards,

FWH 20.04, Harbour 3.2.0 dev (r1909261630) y BCC 7.40
MOISES
 
Posts: 838
Joined: Wed Aug 22, 2007 10:09 am

Re: Add some functions for Tensorflow

Postby MOISES » Thu Jan 17, 2019 6:47 pm

Up
Saludos / Regards,

FWH 20.04, Harbour 3.2.0 dev (r1909261630) y BCC 7.40
MOISES
 
Posts: 838
Joined: Wed Aug 22, 2007 10:09 am

Re: Add some functions for Tensorflow

Postby Otto » Thu Jan 17, 2019 8:20 pm

Hello Charles,
thank you so much for your work.
I am very interested in this new techniques.
Would you be so kind to advice a novice some basic literature where to start.

Best regards
Otto
********************************************************************
mod harbour - Vamos a la conquista de la Web
modharbour.org
https://www.facebook.com/groups/modharbour.club
********************************************************************
User avatar
Otto
 
Posts: 6331
Joined: Fri Oct 07, 2005 7:07 pm


Return to FiveWin for Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 71 guests