Add MocapNET

This commit is contained in:
Justin John
2023-12-15 04:22:41 +05:30
parent 8434144ded
commit 65e8934d5e
336 changed files with 100584 additions and 0 deletions
@@ -0,0 +1,16 @@
project( Tensorflow2 )
cmake_minimum_required( VERSION 2.8.7 )
#cmake_minimum_required(VERSION 3.5)
add_executable(Tensorflow2 testtf2.cpp tensorflow2.h )
target_link_libraries(Tensorflow2 rt dl m Tensorflow TensorflowFramework MocapNETLib2 )
set_target_properties(Tensorflow2 PROPERTIES DEBUG_POSTFIX "D")
set_target_properties(Tensorflow2 PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}"
)
@@ -0,0 +1,592 @@
/** @file tensorflow2.h
* @brief A header-only tensorflow 2.x wrapper automization to make your neuralnetwork-lives easier.
* Repository : https://github.com/AmmarkoV/PThreadWorkerPool
* @author Ammar Qammaz (AmmarkoV)
*/
#ifndef TENSORFLOW2_H_INCLUDED
#define TENSORFLOW2_H_INCLUDED
#ifdef __cplusplus
extern "C"
{
#endif
#include <tensorflow/c/c_api.h> // TensorFlow C API header
#include <stdio.h>
#include <stdlib.h>
//#define NORMAL "\033[0m"
//#define BLACK "\033[30m" /* Black */
//#define RED "\033[31m" /* Red */
//#define GREEN "\033[32m" /* Green */
//#define YELLOW "\033[33m" /* Yellow */
typedef unsigned short float16;
/**
* @brief A structure that holds all of the relevant information for a tensorflow instance
* This is used to simplify context switching and reduce the complexity of the library
*/
struct Tensorflow2Instance
{
char modelPath[1025];
//Network instance
//-------------------------
TF_Graph* graph;
TF_Status* status;
TF_Session* session;
TF_SessionOptions* sessionOptions;
//Input
//-------------------------
TF_Output input_operation;
TF_Output* input;
TF_Tensor* inputTensor;
TF_Tensor** inputValues;
char inputIsHalfFloats;
unsigned int inputElements;
int numberOfInputTensors;
//Output
//-------------------------
TF_Output output_operation;
TF_Output* output;
TF_Tensor* outputTensor;
TF_Tensor** outputValues;
char outputIsHalfFloats;
unsigned int outputElements;
int numberOfOutputTensors;
//Buffer for itermediate data
//-------------------------
unsigned int bufferSize;
float * buffer;
};
static void tf2_noOpDeallocator(void* data, size_t a, void* b) {}
static void tf2_deallocateBuffer(void* data, size_t)
{
if (data!=0)
{
fprintf(stderr,"tf2_deallocateBuffer\n");
free(data);
}
}
#if INTEL_OPTIMIZATIONS
#include <immintrin.h>
#include <emmintrin.h>
//https://software.intel.com/content/www/us/en/develop/documentation/cpp-compiler-developer-guide-and-reference/top/compiler-reference/intrinsics/intrinsics-for-converting-half-floats/intrinsics-for-converting-half-floats-1.html
//AVX
//This intrinsic takes a 32-bit float value, x , and converts it to a half-float value, which is returned.
//__m128 _mm_cvtph_ps(__m128i x);
//This intrinsic takes four packed half-float values and converts them to four 32-bit float values, which are returned. The upper 64-bits of x are ignored. The lower 64-bits are taken as four 16-bit float values for conversion.
//__m128i _mm_cvtps_ph(_m128 x, int imm);
static float16 convertFloat32ToFloat16(float f)
{
/*
(_MM_FROUND_TO_NEAREST_INT |_MM_FROUND_NO_EXC) // round to nearest, and suppress exceptions
(_MM_FROUND_TO_NEG_INF |_MM_FROUND_NO_EXC) // round down, and suppress exceptions
(_MM_FROUND_TO_POS_INF |_MM_FROUND_NO_EXC) // round up, and suppress exceptions
(_MM_FROUND_TO_ZERO |_MM_FROUND_NO_EXC) // truncate, and suppress exceptions
_MM_FROUND_CUR_DIRECTION // use MXCSR.RC; see _MM_SET_ROUNDING_MODE
* */
int imm = _MM_FROUND_TO_NEAREST_INT |_MM_FROUND_NO_EXC;
//https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_cvtss_sh&expand=4979,5019,4979,1898
return _cvtss_sh(f,imm);
}
static float convertFloat16ToFloat32(float16 h)
{
//https://software.intel.com/sites/landingpage/IntrinsicsGuide/#text=_cvtsh_ss&expand=4979,5019,4979,1898,1873
return _cvtsh_ss(h);
}
#else
static float16 convertFloat32ToFloat16(float f)
{
//https://en.wikipedia.org/wiki/Half-precision_floating-point_format
//https://en.wikipedia.org/wiki/IEEE_754-2008_revision
//https://stackoverflow.com/questions/3026441/float32-to-float16/3026505
#warning "convertFloat32ToFloat16 is not correctly implemented on non SSE equipped builds"
unsigned int * fltInt32 = ( unsigned int * ) &f;
float16 h;
h = (*fltInt32 >> 31) << 5;
unsigned short tmp = (*fltInt32 >> 23) & 0xff;
tmp = (tmp - 0x70) & ((unsigned int)((int)(0x70 - tmp) >> 4) >> 27);
h = (h | tmp) << 10;
h |= (*fltInt32 >> 13) & 0x3ff;
return h;
}
static float convertFloat16ToFloat32(float16 h)
{
#warning "convertFloat16ToFloat32 is not properly implemented on non SSE equipped builds"
fprintf(stderr,"convertFloat16ToFloat32 not working.. ");
//http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf
float f = ((h&0x8000)<<16) | (((h&0x7c00)+0x1C000)<<13) | ((h&0x03FF)<<13);
return f;
}
#endif
static int tf2_checkModelUsingExternalTool(const char * path)
{
char commandToCheck[4096];
snprintf(commandToCheck,2000,"saved_model_cli show --dir %s --tag_set serve --signature_def serving_default",path);
int i = system(commandToCheck);
return (i==0);
}
static int tf2_setCPUExecutionSessionConfiguration(struct Tensorflow2Instance * tf2i)
{
//How do you end up with this byte array you might ask ?
unsigned char config[] = {0xa,0x7,0xa,0x3,0x43,0x50,0x55,0x10,0x1,0xa,0x7,0xa,0x3,0x47,0x50,0x55,0x10,0x0,0x38,0x1};
//Good Question, you use the python code and extract the configuration bytes and copy paste them here..
//https://github.com/FORTH-ModelBasedTracker/MocapNET/blob/master/src/Tensorflow/createTensorflowConfigurationForC.py
/*net->session = tf.ConfigProto(
device_count={'CPU' : 1, 'GPU' : 0},
allow_soft_placement=True,
log_device_placement=False
);*/
TF_SetConfig(tf2i->sessionOptions, (void*)config, 20 , tf2i->status);
return (TF_GetCode(tf2i->status) == TF_OK);
}
static char tf2_fileExists(const char * filename)
{
FILE *fp = fopen(filename,"r");
if( fp ) { /* exists */ fclose(fp); return 1; }
return 0;
}
//https://github.com/AmmarkoV/AmmarServer/blob/master/src/AmmServerlib/AString/AString.c#L235
static char * tf2_readFileToMem(const char * filename,unsigned int *length )
{
if (length==0) { return 0; }
if (filename==0) { return 0; }
//-----------------------------------------
*length = 0;
FILE * pFile = fopen ( filename , "rb" );
if (pFile==0)
{
fprintf(stderr,"ERROR tf2_readFileToMem: failed\n");
fprintf(stderr,"Could not read file %s \n",filename);
return 0;
}
// obtain file size:
fseek (pFile , 0 , SEEK_END);
unsigned long lSize = ftell (pFile);
rewind (pFile);
// allocate memory to contain the whole file:
unsigned long bufferSize = sizeof(char)*(lSize+1);
char * buffer = (char*) malloc (bufferSize);
if (buffer == 0 )
{
fprintf(stderr,"ERROR tf2_readFileToMem: Could not allocate enough memory for file %s \n",filename);
fclose(pFile);
return 0;
}
// copy the file into the buffer:
size_t result = fread (buffer,1,lSize,pFile);
if (result != lSize)
{
free(buffer);
fprintf(stderr,"ERROR tf2_readFileToMem: Could not read the whole file onto memory %s \n",filename);
fclose(pFile);
return 0;
}
/* the whole file is now loaded in the memory buffer. */
// terminate
fclose (pFile);
buffer[lSize]=0; //Null Terminate Buffer!
*length = (unsigned int) lSize;
return buffer;
}
static int tf2_allocateIOTensors(
struct Tensorflow2Instance * tf2i,
const char * inputTensorName,
const char * outputTensorName,
unsigned int inputElements,
unsigned int outputElements,
unsigned int forceCPU
)
{
//Allocate input tensor
//--------------------------------------------------------------------------------
tf2i->numberOfInputTensors = 1;
tf2i->input = (TF_Output*) malloc(sizeof(TF_Output) * tf2i->numberOfInputTensors);
tf2i->input_operation = {TF_GraphOperationByName(tf2i->graph,inputTensorName), 0};
if(tf2i->input_operation.oper == NULL)
{
fprintf(stderr,"ERROR: Failed TF_GraphOperationByName %s\n",inputTensorName);
return 0;
}
tf2i->input[0] = tf2i->input_operation;
//--------------------------------------------------------------------------------
//Allocate Output tensor
//--------------------------------------------------------------------------------
tf2i->numberOfOutputTensors = 1;
tf2i->output = (TF_Output*) malloc(sizeof(TF_Output) * tf2i->numberOfOutputTensors);
tf2i->output_operation = {TF_GraphOperationByName(tf2i->graph,outputTensorName), 0};
if(tf2i->output_operation.oper == NULL)
{
fprintf(stderr,"ERROR: Failed TF_GraphOperationByName %s\n",outputTensorName);
return 0;
}
tf2i->output[0] = tf2i->output_operation;
//--------------------------------------------------------------------------------
//Allocate memory for input & output data
tf2i->inputValues = (TF_Tensor**) malloc(sizeof(TF_Tensor*)*tf2i->numberOfInputTensors);
tf2i->outputValues = (TF_Tensor**) malloc(sizeof(TF_Tensor*)*tf2i->numberOfOutputTensors);
return ( (tf2i->inputValues!=0) && (tf2i->outputValues!=0) );
}
static int tf2_loadFrozenGraph(
struct Tensorflow2Instance * tf2i,
const char* graphPath,
const char * inputTensorName,
const char * outputTensorName,
unsigned int inputElements,
unsigned int outputElements,
unsigned int forceCPU
)
{
if (graphPath == 0)
{
fprintf(stderr,"Cannot load graph with null path..\n");
return 0;
}
fprintf(stderr,"LoadGraph %s using TensorFlow Version: %s\n",graphPath,TF_Version());
unsigned int graphInMemorySize=0;
char * graphInMemory = tf2_readFileToMem(graphPath,&graphInMemorySize);
if (graphInMemory == 0)
{
fprintf(stderr,"Cannot read buffer from file %s ..\n",graphPath);
return 0;
}
//Remember parameters..
snprintf(tf2i->modelPath,1024,"%s",graphPath);
tf2i->inputElements=inputElements;
tf2i->outputElements=outputElements;
tf2i->graph = TF_NewGraph();
tf2i->status = TF_NewStatus();
TF_ImportGraphDefOptions* opts = TF_NewImportGraphDefOptions();
TF_Buffer* tfBufferWithGraph = TF_NewBuffer();
tfBufferWithGraph->data = graphInMemory;
tfBufferWithGraph->length = graphInMemorySize;
tfBufferWithGraph->data_deallocator = tf2_deallocateBuffer;
TF_GraphImportGraphDef(tf2i->graph,tfBufferWithGraph,opts,tf2i->status);
TF_DeleteImportGraphDefOptions(opts);
if (TF_GetCode(tf2i->status) != TF_OK)
{
fprintf(stderr,"ERROR importing graph definition.. (%u)\n",TF_GetCode(tf2i->status));
switch (TF_GetCode(tf2i->status))
{
case TF_INVALID_ARGUMENT :
fprintf(stderr,"Invalid Argument in graph..\n");
break;
};
TF_DeleteGraph(tf2i->graph);
tf2i->graph = 0;
}
TF_DeleteBuffer(tfBufferWithGraph);
graphInMemorySize=0;
//--------------------------------------------------------------------------------------------------------------
tf2i->sessionOptions = TF_NewSessionOptions();
if (forceCPU) { tf2_setCPUExecutionSessionConfiguration(tf2i); }
tf2i->session = TF_NewSession(tf2i->graph,tf2i->sessionOptions,tf2i->status);
//--------------------------------------------------------------------------------------------------------------
return tf2_allocateIOTensors(
tf2i,
inputTensorName,
outputTensorName,
inputElements,
outputElements,
forceCPU
);
}
static int tf2_loadModel(
struct Tensorflow2Instance * tf2i,
const char * path,
const char * inputTensor,
unsigned int inputElements,
unsigned int outputElements,
unsigned int forceCPU
)
{
//https://medium.com/analytics-vidhya/deploying-tensorflow-2-1-as-c-c-executable-1d090845055c
//Tensorflow boilerplate names, fingers crossed that they don't change them..
char inputTensorName[1025]={0}; //= {"serving_default_input_front"}; //Default input layer
snprintf(inputTensorName,1024,"serving_default_%s",inputTensor);
//snprintf(inputTensorName,1024,"%s",inputTensor);
char outputTensorName[1025]={0}; //= {"StatefulPartitionedCall"}; //Default output layer
snprintf(outputTensorName,1024,"StatefulPartitionedCall");
//--------------------------------------------------------------------------
int ntags = 1;
//char tags[1025]={0}; //= {"StatefulPartitionedCall"}; //Default output layer
//snprintf(tags,1024,"serve");
//const char* tags = "serve"; // default model serving tag; can change in future
const char* tags[] = {"serve"};
//--------------------------------------------------------------------------
//--------------------------------------------------------------------------
fprintf(stderr,"Loading model : %s | Input : %s | Output : %s\n",path,inputTensorName,outputTensorName);
//--------------------------------------------------------------------------
//Remember parameters..
snprintf(tf2i->modelPath,1024,"%s",path);
tf2i->inputElements=inputElements;
tf2i->outputElements=outputElements;
//Allocate stuff..
tf2i->graph = TF_NewGraph();
tf2i->status = TF_NewStatus();
tf2i->sessionOptions = TF_NewSessionOptions();
if (forceCPU) { tf2_setCPUExecutionSessionConfiguration(tf2i); }
TF_Buffer* runOptions = NULL;
//Actual loading from a saved model assuming :
//https://www.tensorflow.org/api_docs/python/tf/saved_model/save
tf2i->session = TF_LoadSessionFromSavedModel(
tf2i->sessionOptions,
runOptions,
path,
tags,
ntags,
tf2i->graph,
NULL,
tf2i->status
);
if(TF_GetCode(tf2i->status) != TF_OK)
{
fprintf(stderr,"Error loading model : %s \n",TF_Message(tf2i->status));
tf2_checkModelUsingExternalTool(tf2i->modelPath);
return 0;
}
return tf2_allocateIOTensors(
tf2i,
inputTensorName,
outputTensorName,
inputElements,
outputElements,
forceCPU
);
}
static int tf2_unloadModel(struct Tensorflow2Instance * tf2i)
{
// //Free memory
TF_DeleteGraph(tf2i->graph);
if(TF_GetCode(tf2i->status) != TF_OK)
{
fprintf(stderr,"tf2_unloadModel: Error deleting graph (%s) \n",TF_Message(tf2i->status));
return 0;
}
TF_DeleteSession(tf2i->session, tf2i->status);
if(TF_GetCode(tf2i->status) != TF_OK)
{
fprintf(stderr,"tf2_unloadModel: Error deleting session (%s) \n",TF_Message(tf2i->status));
return 0;
}
TF_DeleteSessionOptions(tf2i->sessionOptions);
if(TF_GetCode(tf2i->status) != TF_OK)
{
fprintf(stderr,"tf2_unloadModel: Error deleting session options (%s) \n",TF_Message(tf2i->status));
return 0;
}
TF_DeleteStatus(tf2i->status);
//Can't check status having deleted the status ..
if (tf2i->buffer!=0)
{
free(tf2i->buffer);
tf2i->buffer=0;
tf2i->bufferSize=0;
}
return 1;
}
static int tf2_run(
struct Tensorflow2Instance * tf2i,
int64_t * dimensions,
unsigned int dimensionsNumber,
float * data,
unsigned int dataSizeBytes
)
{
int result = 0;
TF_Tensor* int_tensor = NULL;
if (tf2i->inputIsHalfFloats)
{
//In an attempt not to perform unneccessary reallocations
//I rewrite the float array with halfs..
unsigned int dataSizeElements = dataSizeBytes / sizeof(float);
unsigned int convertedDataSizeBytes = sizeof(float16) * dataSizeElements;
float16 * dataAsFloat16 = (float16*) data;
float buffer=0.0;
for (int i=0; i<dataSizeElements; i++)
{
//Have an intermediate location..
buffer = data[i];
dataAsFloat16[i] = convertFloat32ToFloat16(buffer);
}
int_tensor = TF_NewTensor(
TF_HALF,
dimensions,
dimensionsNumber,
dataAsFloat16,
convertedDataSizeBytes,
&tf2_noOpDeallocator,
0
);
} else
{
//Regular floats ready to be transported to the tensor
int_tensor = TF_NewTensor(
TF_FLOAT,
dimensions,
dimensionsNumber,
data,
dataSizeBytes,
&tf2_noOpDeallocator,
0
);
}
//----------------------------------------------------------------
if (int_tensor == NULL)
{
fprintf(stderr,"ERROR tf2_run: Failed TF_NewTensor\n");
fprintf(stderr,"Trying to create a tensor with %u dimensions : ",dimensionsNumber);
fprintf(stderr,"{ ");
for (int i=0; i<dimensionsNumber; i++)
{
fprintf(stderr,"%ld ",dimensions[i]);
}
fprintf(stderr,"}\n");
fprintf(stderr,"Data output size : %u \n",dataSizeBytes);
return 0;
}
else
{
tf2i->inputValues[0] = int_tensor;
//Run the Session
TF_SessionRun(
tf2i->session,
NULL, //run options
tf2i->input, tf2i->inputValues, tf2i->numberOfInputTensors,
tf2i->output, tf2i->outputValues, tf2i->numberOfOutputTensors,
NULL, 0,
NULL, //Metadata
tf2i->status
);
if(TF_GetCode(tf2i->status) != TF_OK)
{
fprintf(stderr,"tf2_run: Error running %s network, %s\n",tf2i->modelPath,TF_Message(tf2i->status));
fprintf(stderr,"dimensionsNumber=%u\n",dimensionsNumber);
fprintf(stderr,"dataSizeBytes=%u\n",dataSizeBytes);
tf2_checkModelUsingExternalTool(tf2i->modelPath);
result = 0;
}
TF_DeleteTensor(int_tensor);
tf2i->inputValues[0] =0;
int_tensor=0;
result=1;
}
return result;
}
#ifdef __cplusplus
}
#endif
#endif
@@ -0,0 +1,315 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <vector>
#include "tensorflow2.h"
#define NORMAL "\033[0m"
#define BLACK "\033[30m" /* Black */
#define RED "\033[31m" /* Red */
#define GREEN "\033[32m" /* Green */
#define YELLOW "\033[33m" /* Yellow */
float rand_FloatRange(float a, float b)
{
return ((b - a) * ((float)rand() / RAND_MAX)) + a;
}
int testFloat16()
{
unsigned int maxErrors = 10000;
unsigned int errors=0;
for (int i=0; i<maxErrors; i++)
{
float r1 = rand_FloatRange(-1000,1000);
float r2 = convertFloat16ToFloat32(convertFloat32ToFloat16(r1));
float distance = sqrt( (r1-r2) * (r1-r2) );
if (distance>0.4)
{
fprintf(stderr,"%f ",distance);
++errors;
}
}
fprintf(stderr,"\n\n%u errors / %0.2f %% \n",errors,(float) errors*100/maxErrors);
return (errors==0);
}
int testUpperBody()
{
const char* savedModelDirectory = "/home/ammar/Documents/Programming/DNNTracker/tensorflow2GPU/src/tmp.pb/";
int runOnCPU=1;
int ndims = 2;
int64_t dims[] = {1,322};
//-----------------------------
float data[1*322];
for(int i=0; i< (1*322); i++)
{
data[i] = 1.00;
}
int ndata = sizeof(float)*1*322 ; //number of bytes not number of element
//-----------------------------
unsigned int numberOfInputElements = 322;
unsigned int numberOfOutputElements = 42;
char inputTensor[]={"input_front"};
char outputTensor[]={"result_front/concat"};
//Tensorflow v2 test..
struct Tensorflow2Instance upperbodyFrontv2={0};
if ( tf2_loadModel(&upperbodyFrontv2,savedModelDirectory,inputTensor,numberOfInputElements,numberOfOutputElements,runOnCPU) )
{
if ( tf2_run(&upperbodyFrontv2,dims,ndims,data,ndata) )
{
void* buff = TF_TensorData(upperbodyFrontv2.outputValues[0]);
float* offsets = (float*)buff;
printf("Result Tensor v2:\n");
for(int i=0;i<upperbodyFrontv2.outputElements;i++)
{
if(i>0) { printf(","); }
printf("%f",offsets[i]);
}
printf("\n");
} else
{
fprintf(stderr,"Failed tf2_run\n");
}
printf("Deallocating v2 \n");
tf2_unloadModel(&upperbodyFrontv2);
} else
{
fprintf(stderr,"Failed tf2_loadModel\n");
}
//Tensorflow v1 test..
struct Tensorflow2Instance upperbodyFrontv1={0};
if ( tf2_loadFrozenGraph(&upperbodyFrontv1,"dataset/combinedModel/mocapnet2/mode5/1.0/upperbody_front.pb",inputTensor,outputTensor,numberOfInputElements,numberOfOutputElements,runOnCPU) )
{
if ( tf2_run(&upperbodyFrontv1,dims,ndims,data,ndata) )
{
fprintf(stderr,"Ready to run..!\n");
tf2_run(&upperbodyFrontv1,dims,ndims,data,ndata);
void* buff = TF_TensorData(upperbodyFrontv1.outputValues[0]);
float* offsets = (float*)buff;
printf("Result Tensor v1:\n");
for(int i=0;i<upperbodyFrontv1.outputElements;i++)
{
if(i>0) { printf(","); }
printf("%f",offsets[i]);
}
printf("\n");
}
printf("Deallocating v1 \n");
tf2_unloadModel(&upperbodyFrontv1);
}
printf("Done\n");
return 0;
}
#include <unistd.h>
int executeCommandLineAndRetreiveAllResults(const char * command , char * what2GetBack , unsigned int what2GetBackMaxSize, unsigned long * what2GetBackSize)
{
/* Open the command for reading. */
FILE * f = popen(command, "r");
if (f == 0)
{
fprintf(stderr,"Failed to run command (%s) \n",command);
return 0;
}
size_t contentSize = fread(what2GetBack, 1 , what2GetBackMaxSize, f);
*what2GetBackSize = contentSize;
/* close */
pclose(f);
return 1;
}
int getInfoFast(const char * field,char * buffer,unsigned int bufferSize,char terminatorCharacter)
{
int fieldOffset = strlen(field);
char * foundAt = strstr(buffer,field);
if (foundAt!=0)
{
foundAt += fieldOffset;
char * termination = strchr(foundAt,terminatorCharacter);
if (termination!=0)
{
char retainOldTerminator = *termination;
*termination = 0;
fprintf(stderr,"Field `%s` => `%s` \n",field,foundAt);
*termination =retainOldTerminator;
}
}
return 0;
}
int testHands()
{
// const char* savedModelDirectory = "/home/ammar/Documents/Programming/DNNTracker/DNNTracker/dataset/combinedModel/mocapnet2/mode1/1.0/rhand_half_all.pb";
const char* savedModelDirectory = "/home/ammar/Documents/Programming/DNNTracker/DNNTracker/dataset/combinedModel/mocapnet2/mode1/1.0/lhand_all.pb";
#define NUMBER_OF_OUTPUTS 52
#define NUMBER_OF_INPUTS 319
int runOnCPU=1;
int ndims = 2;
int64_t dims[] = {1,NUMBER_OF_INPUTS};
//-----------------------------
float data[1*NUMBER_OF_INPUTS];
for(int i=0; i< (1*NUMBER_OF_INPUTS); i++)
{
data[i] = 1.00;
}
int ndata = sizeof(float)*1*NUMBER_OF_INPUTS ; //number of bytes not number of element
//-----------------------------
//Check using external tool and a parser
//-------------------------------------
tf2_checkModelUsingExternalTool(savedModelDirectory);
/*
static int maxOutputLength=4096;
unsigned long outputSize=0;
char output[maxOutputLength]={0};
executeCommandLineAndRetreiveAllResults(commandToCheck,output,maxOutputLength,&outputSize);
fprintf(stderr,"Retrieved.. %s\n",output);
getInfoFast("inputs['",output,outputSize,'\'');
getInfoFast("shape: ",output,outputSize,10);
getInfoFast("name: ",output,outputSize,10);
char * outputTensorsStart = strstr(output,"output(s):");
if (outputTensorsStart!=0)
{
getInfoFast("outputs['",outputTensorsStart,outputSize,'\'');
getInfoFast("shape: ",outputTensorsStart,outputSize,10);
getInfoFast("name: ",output,outputSize,10);
}
//-------------------------------------
*/
unsigned int numberOfInputElements = NUMBER_OF_INPUTS;
unsigned int numberOfOutputElements = NUMBER_OF_OUTPUTS;
//https://medium.com/analytics-vidhya/deploying-tensorflow-2-1-as-c-c-executable-1d090845055c
char inputTensor[]={"input_all"}; //{"input_front"};
char outputTensor[]={"result_all/concat"}; //{"result_front/concat"};
//Tensorflow v2 test..
struct Tensorflow2Instance upperbodyFrontv2={0};
if ( tf2_loadModel(&upperbodyFrontv2,savedModelDirectory,inputTensor,numberOfInputElements,numberOfOutputElements,runOnCPU) )
{
upperbodyFrontv2.inputIsHalfFloats=1;
if ( tf2_run(&upperbodyFrontv2,dims,ndims,data,ndata) )
{
void* buff = TF_TensorData(upperbodyFrontv2.outputValues[0]);
float* offsets = (float*)buff;
printf("Result Tensor v2:\n");
for(int i=0; i<upperbodyFrontv2.outputElements; i++)
{
if(i>0) { printf(","); }
printf("%f",offsets[i]);
}
printf("\n");
} else
{
fprintf(stderr,"Failed tf2_run\n");
}
printf("Deallocating v2 \n");
tf2_unloadModel(&upperbodyFrontv2);
} else
{
fprintf(stderr,RED "Failed tf2_loadModel\n" NORMAL);
}
//Tensorflow v1 test..
struct Tensorflow2Instance upperbodyFrontv1={0};
if ( tf2_loadFrozenGraph(&upperbodyFrontv1,"dataset/combinedModel/mocapnet2/mode1/1.0/_rhand_all.pb",inputTensor,outputTensor,numberOfInputElements,numberOfOutputElements,runOnCPU) )
{
if ( tf2_run(&upperbodyFrontv1,dims,ndims,data,ndata) )
{
fprintf(stderr,"Ready to run..!\n");
tf2_run(&upperbodyFrontv1,dims,ndims,data,ndata);
void* buff = TF_TensorData(upperbodyFrontv1.outputValues[0]);
float* offsets = (float*)buff;
printf("Result Tensor v1:\n");
for(int i=0; i<upperbodyFrontv1.outputElements; i++)
{
if(i>0) { printf(","); }
printf("%f",offsets[i]);
}
printf("\n");
}
printf("Deallocating v1 \n");
tf2_unloadModel(&upperbodyFrontv1);
}
printf("Done\n");
return 0;
}
int main()
{
testFloat16();
return testHands();
//return testUpperBody();
}