I'm trying to run an TfLite Model on a x86_64 system. It seems that all is working fine. But when I try to get the input or output tensor with typed_input_tensor(0) then I get a null pointer.
My model is a simple HelloWorldNN:
import tensorflow as tf
import numpy as np
from tensorflow import keras
model = tf.keras.Sequential([keras.layers.Dense(units=1, input_shape=[1])])
model.compile(optimizer='sgd', loss='mean_squared_error')
xs = np.array([-1.0, 0.0, 1.0, 2.0, 3.0, 4.0], dtype=float)
ys = np.array([-3.0, -1.0, 1.0, 3.0, 5.0, 7.0], dtype=float)
model.fit(xs, ys, epochs=10)
print(model.predict([10.0]))
model.summary()
converter = tf.lite.TFLiteConverter.from_keras_model(model)
tflite_model = converter.convert()
open("linear.tflite","wb").write(tflite_model)
For the C++ part I cloned the tensorflow git and checked out the commit d855adfc5a0195788bf5f92c3c7352e638aa1109. This is the commit which is neccessary to using Coral hardware which I plan to use. I build the tensorflow-lite.a and linked it to my application.
std::unique_ptr<tflite::FlatBufferModel> model =
tflite::FlatBufferModel::BuildFromFile("linear.tflite");
if (tflite::InterpreterBuilder(*model, resolver)(&interpreter) != kTfLiteOk) {
std::cerr << "Failed to build interpreter." << std::endl;
}
if (interpreter->AllocateTensors() != kTfLiteOk) {
std::cerr << "Failed to allocate tensors." << std::endl;
}
std::cout << "Number of tensors" << interpreter->tensors_size() <<" Num of Inputs "<<
tflite::PrintInterpreterState(interpreter.get());
float* input = interpreter->typed_input_tensor<float>(0);
interpreter->Invoke();
float* output = interpreter->typed_output_tensor<float>(0);
If I run the code then both input and output pointers are null pointers. The output of interpreter.get() is the follow:
Number of tensors8 Num of Inputs 18446732345621392436
Interpreter has 8 tensors and 3 nodes
Inputs: 4
Outputs: 5
Tensor 0 dense/BiasAdd_int8 kTfLiteInt8 kTfLiteArenaRw 1 bytes ( 0.0 MB) 1 1
Tensor 1 dense/MatMul_bias kTfLiteInt32 kTfLiteMmapRo 4 bytes ( 0.0 MB) 1
Tensor 2 dense/kernel/transpose kTfLiteInt8 kTfLiteMmapRo 1 bytes ( 0.0 MB) 1 1
Tensor 3 dense_input_int8 kTfLiteInt8 kTfLiteArenaRw 1 bytes ( 0.0 MB) 1 1
Tensor 4 dense_input kTfLiteFloat32 kTfLiteArenaRw 4 bytes ( 0.0 MB) 1 1
Tensor 5 dense/BiasAdd kTfLiteFloat32 kTfLiteArenaRw 4 bytes ( 0.0 MB) 1 1
Tensor 6 (null) kTfLiteNoType kTfLiteMemNone 0 bytes ( 0.0 MB) (null)
Tensor 7 (null) kTfLiteNoType kTfLiteMemNone 0 bytes ( 0.0 MB) (null)
Node 0 Operator Builtin Code 114 QUANTIZE
Inputs: 4
Outputs: 3
Node 1 Operator Builtin Code 9 FULLY_CONNECTED
Inputs: 3 2 1
Outputs: 0
Node 2 Operator Builtin Code 6 DEQUANTIZE
Inputs: 0
Outputs: 5`
I've no idea where is my mistake. It worked with tensorflow 1.15. But 1.15 I can't use anymore with Coral hardware. I would be grateful for any help
Ok, I found my problem. I hadn't updated the include files. The files were still from 1.15. :-)
Related
*New to Python.
I'm trying to merge multiple text files into 1 csv; example below -
filename.csv
Alpha
0
0.1
0.15
0.2
0.25
0.3
text1.txt
Alpha,Beta
0,10
0.2,20
0.3,30
text2.txt
Alpha,Charlie
0.1,5
0.15,15
text3.txt
Alpha,Delta
0.1,10
0.15,20
0.2,50
0.3,10
Desired output in the csv file: -
filename.csv
Alpha Beta Charlie Delta
0 10 0 0
0.1 0 5 10
0.15 0 15 20
0.2 20 0 50
0.25 0 0 0
0.3 30 0 10
The code I've been working with and others that were provided give me an answer similar to what is at the bottom of the page
def mergeData(indir="Dir Path", outdir="Dir Path"):
dfs = []
os.chdir(indir)
fileList=glob.glob("*.txt")
for filename in fileList:
left= "/Path/Final.csv"
right = filename
output = "/Path/finalMerged.csv"
leftDf = pandas.read_csv(left)
rightDf = pandas.read_csv(right)
mergedDf = pandas.merge(leftDf,rightDf,how='inner',on="Alpha", sort=True)
dfs.append(mergedDf)
outputDf = pandas.concat(dfs, ignore_index=True)
outputDf = pandas.merge(leftDf, outputDf, how='inner', on='Alpha', sort=True, copy=False).fillna(0)
print (outputDf)
outputDf.to_csv(output, index=0)
mergeData()
The answer I get however is instead of the desired result: -
Alpha Beta Charlie Delta
0 10 0 0
0.1 0 5 0
0.1 0 0 10
0.15 0 15 0
0.15 0 0 20
0.2 20 0 0
0.2 0 0 50
0.25 0 0 0
0.3 30 0 0
0.3 0 0 10
IIUC you can create list of all DataFrames - dfs, in loop append mergedDf and last concat all DataFrames to one:
import pandas
import glob
import os
def mergeData(indir="dir/path", outdir="dir/path"):
dfs = []
os.chdir(indir)
fileList=glob.glob("*.txt")
for filename in fileList:
left= "/path/filename.csv"
right = filename
output = "/path/filename.csv"
leftDf = pandas.read_csv(left)
rightDf = pandas.read_csv(right)
mergedDf = pandas.merge(leftDf,rightDf,how='right',on="Alpha", sort=True)
dfs.append(mergedDf)
outputDf = pandas.concat(dfs, ignore_index=True)
#add missing rows from leftDf (in sample Alpha - 0.25)
#fill NaN values by 0
outputDf = pandas.merge(leftDf,outputDf,how='left',on="Alpha", sort=True).fillna(0)
#columns are converted to int
outputDf[['Beta', 'Charlie']] = outputDf[['Beta', 'Charlie']].astype(int)
print (outputDf)
outputDf.to_csv(output, index=0)
mergeData()
Alpha Beta Charlie
0 0.00 10 0
1 0.10 0 5
2 0.15 0 15
3 0.20 20 0
4 0.25 0 0
5 0.30 30 0
EDIT:
Problem is you change parameter how='left' in second merge to how='inner':
def mergeData(indir="Dir Path", outdir="Dir Path"):
dfs = []
os.chdir(indir)
fileList=glob.glob("*.txt")
for filename in fileList:
left= "/Path/Final.csv"
right = filename
output = "/Path/finalMerged.csv"
leftDf = pandas.read_csv(left)
rightDf = pandas.read_csv(right)
mergedDf = pandas.merge(leftDf,rightDf,how='inner',on="Alpha", sort=True)
dfs.append(mergedDf)
outputDf = pandas.concat(dfs, ignore_index=True)
#need left join, not inner
outputDf = pandas.merge(leftDf, outputDf, how='left', on='Alpha', sort=True, copy=False)
.fillna(0)
print (outputDf)
outputDf.to_csv(output, index=0)
mergeData()
Alpha Beta Charlie Delta
0 0.00 10.0 0.0 0.0
1 0.10 0.0 5.0 0.0
2 0.10 0.0 0.0 10.0
3 0.15 0.0 15.0 0.0
4 0.15 0.0 0.0 20.0
5 0.20 20.0 0.0 0.0
6 0.20 0.0 0.0 50.0
7 0.25 0.0 0.0 0.0
8 0.30 30.0 0.0 0.0
9 0.30 0.0 0.0 10.0
import pandas as pd
data1 = pd.read_csv('samp1.csv',sep=',')
data2 = pd.read_csv('samp2.csv',sep=',')
data3 = pd.read_csv('samp3.csv',sep=',')
df1 = pd.DataFrame({'Alpha':data1.Alpha})
df2 = pd.DataFrame({'Alpha':data2.Alpha,'Beta':data2.Beta})
df3 = pd.DataFrame({'Alpha':data3.Alpha,'Charlie':data3.Charlie})
mergedDf = pd.merge(df1, df2, how='outer', on ='Alpha',sort=False)
mergedDf1 = pd.merge(mergedDf, df3, how='outer', on ='Alpha',sort=False)
a = pd.DataFrame(mergedDf1)
print(a.drop_duplicates())
output:
Alpha Beta Charlie
0 0.00 10.0 NaN
1 0.10 NaN 5.0
2 0.15 NaN 15.0
3 0.20 20.0 NaN
4 0.25 NaN NaN
5 0.30 30.0 NaN
I need to write a matrix to a file with this format (i, j, a[i,j]) row by row, but I don't know how to get it. I tried with: np.savetxt(f, A, fmt='%1d', newline='\n'), but it write only matrix values and don't write i, j!
import numpy as np
a = np.arange(12).reshape(4,3)
a_with_index = np.array([idx+(val,) for idx, val in np.ndenumerate(a)])
np.savetxt('/tmp/out', a_with_index, fmt='%d')
writes to /tmp/out the contents
0 0 0
0 1 10
0 2 20
1 0 30
1 1 40
1 2 50
2 0 60
2 1 70
2 2 80
3 0 90
3 1 100
3 2 110
If your array datatype is not a sort of integer, you'll probably have to write your own function to save it along with its indices, since these are integers. For example,
import numpy as np
def savetxt_with_indices(filename, arr, fmt):
nrows, ncols = arr.shape
indexes = np.empty((nrows*ncols, 2))
indexes[:,0] = np.repeat(np.arange(nrows), ncols)
indexes[:,1] = np.tile(np.arange(ncols), nrows)
fmt = '%4d %4d ' + fmt
flat_arr = arr.flatten()
with open(filename, 'w') as fo:
for i in range(nrows*ncols):
print(fmt % (indexes[i, 0], indexes[i, 1], flat_arr[i]), file=fo)
A = np.arange(12.).reshape((4,3))
savetxt_with_indices('test.txt', A, '%6.2f')
0 0 0.00
0 1 1.00
0 2 2.00
1 0 3.00
1 1 4.00
1 2 5.00
2 0 6.00
2 1 7.00
2 2 8.00
3 0 9.00
3 1 10.00
3 2 11.00
I am trying to do a Cholesky decomposition via pdpotrf() of MKL-Intel's library, which uses ScaLAPACK. I am reading the whole matrix in the master node and then distribute it like in this example. Everything works fine when the dimension of the SPD matrix is even. However, when it's odd, pdpotrf() thinks that the matrix is not positive definite.
Could it be because the submatrices are not SPD? I am working with this matrix:
and the submatrices are (with 4 processes and blocks of size 2x2):
A_loc on node 0
4 1 2
1 0.5 0
2 0 16
nrows = 3, ncols = 2
A_loc on node 1
2 0.5
0 0
0 0
nrows = 2, ncols = 3
A_loc on node 2
2 0 0
0.5 0 0
nrows = 2, ncols = 2
A_loc on node 3
3 0
0 0.625
Here, every submatrix is not SPD, however, the overall matrix is SPD (have checked with running with 1 process). What should I do? Or there is nothing I can do and pdpotrf() does not work with matrices of odd size?
Here is how I call the routine:
int iZERO = 0;
int descA[9];
// N, M dimensions of matrix. lda = N
// Nb, Mb dimensions of block
descinit_(descA, &N, &M, &Nb, &Mb, &iZERO, &iZERO, &ctxt, &lda, &info);
...
pdpotrf((char*)"L", &ord, A_loc, &IA, &JA, descA, &info);
I also tried this:
// nrows/ncols is the number of rows/columns a submatrix has
descinit_(descA, &N, &M, &nrows, &ncols, &iZERO, &iZERO, &ctxt, &lda, &info);
but I get an error:
{ 0, 0}: On entry to { 0, 1}: On entry to PDPOTR{ 1,
0}: On entry to PDPOTRF parameter number 605 had an illegal value {
1, 1}: On entry to PDPOTRF parameter number 605 had an illegal
value F parameter number 605 had an illegal value
PDPOTRF parameter number 605 had an illegal value info < 0: If the
i-th argument is an array and the j-entry had an illegal value, then
INFO = -(i*100+j), if the i-th argument is a scalar and had an illegal
value, then INFO = -i. info = -605
From my answer, you can see what the arguments of the function mean.
The code is based on this question. Output:
gsamaras#pythagoras:~/konstantis/check_examples$ ../../mpich-install/bin/mpic++ -o test minor.cpp -I../../intel/mkl/include ../../intel/mkl/lib/intel64/libmkl_scalapack_lp64.a -Wl,--start-group ../../intel/mkl/lib/intel64/libmkl_intel_lp64.a ../../intel/mkl/lib/intel64/libmkl_core.a ../../intel/mkl/lib/intel64/libmkl_sequential.a -Wl,--end-group ../../intel/mkl/lib/intel64/libmkl_blacs_intelmpi_lp64.a -lpthread -lm -ldl
gsamaras#pythagoras:~/konstantis/check_examples$ mpiexec -n 4 ./test
Processes grid pattern:
0 1
2 3
nrows = 3, ncols = 3
A_loc on node 0
4 1 2
1 0.5 0
2 0 16
nrows = 3, ncols = 2
A_loc on node 1
2 0.5
0 0
0 0
nrows = 2, ncols = 3
A_loc on node 2
2 0 0
0.5 0 0
nrows = 2, ncols = 2
A_loc on node 3
3 0
0 0.625
Description init sucesss!
matrix is not positive definte
Matrix A result:
2 1 2 0.5 2
0.5 0.5 0 0 0
1 0 1 0 -0.25
0.25 -1 -0.5 0.625 0
1 -1 -2 -0.5 14
The issue may come from :
MPI_Bcast(&lda, 1, MPI_INT, 0, MPI_COMM_WORLD);
Before this line, lda is different on each process if the dimension of the matrix is odd. Two processes handle 2 rows and two processes handle 3 rows. But after the MPI_Bcast(), lda is the same everywhere (3).
The problem is that the argument lda of the subroutine DESCINIT must be the leading dimension of the local array, that is either 2 or 3.
By commenting MPI_Bcast(), i got:
Description init sucesss!
SUCCESS
Matrix A result:
2 1 2 0.5 2
0.5 0.5 0 0 0
1 -1 1 0 0
0.25 -0.25 -0.5 0.5 0
1 -1 -2 -3 1
At last, it would explain that the program works well for even dimensions and fails for odd dimensions !
I don't understand the result I get when I try to iterate over valuePtr of a sparse matrix. Here is my code.
#include <iostream>
#include <vector>
#include <Eigen/Sparse>
using namespace Eigen;
int main()
{
SparseMatrix<double> sm(4,5);
std::vector<int> cols = {0,1,4,0,4,0,4};
std::vector<int> rows = {0,0,0,2,2,3,3};
std::vector<double> values = {0.2,0.4,0.6,0.3,0.7,0.9,0.2};
for(int i=0; i < cols.size(); i++)
sm.insert(rows[i], cols[i]) = values[i];
std::cout << sm << std::endl;
int nz = sm.nonZeros();
std::cout << "non_zeros : " << nz << std::endl;
for (auto it = sm.valuePtr(); it != sm.valuePtr() + nz; ++it)
std::cout << *it << std::endl;
return 0;
}
Output:
0.2 0.4 0 0 0.6 // The values are in the matrix
0 0 0 0 0
0.3 0 0 0 0.7
0.9 0 0 0 0.2
non_zeros : 7
0.2 // but valuePtr() does not point to them
0.3 // I expected: 0.2, 0.3, 0.9, 0.4, 0.6, 0.7, 0.2
0.9
0
0.4
0
0
I don't understand why I am getting zeros, what's going on here?
According to the documentation for SparseMatrix:
Unlike the compressed format, there might be extra space inbetween the
nonzeros of two successive columns (resp. rows) such that insertion of
new non-zero can be done with limited memory reallocation and copies.
[...]
A call to the function makeCompressed() turns the matrix into the standard compressed format compatible with many library.
For example:
This storage scheme is better explained on an example. The following
matrix
0 3 0 0 0
22 0 0 0 17
7 5 0 1 0
0 0 0 0 0
0 0 14 0 8
and one of its possible sparse, column major representation:
Values: 22 7 _ 3 5 14 _ _ 1 _ 17 8
InnerIndices: 1 2 _ 0 2 4 _ _ 2 _ 1 4
[...]
The "_" indicates available free space to quickly insert new elements.
Since valuePtr() simply return a pointer to the Values array, you'll see the empty spaces (the zeroes that got printed) unless you make the matrix compressed.
When I create a matrix using Eigen, like this:
Eigen::MatrixXd M(3,3);
M<< 1.0, 4.0, 7.0, 2.0, 5.0, 8.0, 3.0, 6.0, 9.0 ;
std::cout<<M<<std::endl;
produces
1 4 7
2 5 8
3 6 9
I can walk with a pointer through the data, printing each element:
double * d = M.data();
for(int i = 0;i<M.size();i++)
{
std::cout<<*d<<" ";
d++;
}
std::cout<<std::endl;
produces
1 2 3 4 5 6 7 8 9
I can also use std::copy to copy it to an array of the same type on the stack, then print the elements of that array:
double data_copy[9];
std::copy(M.data(),M.data()+M.size(),data_copy);
for(int i = 0;i<M.size();i++)
{
std::cout<<data_copy[i]<<" ";
}
std::cout<<std::endl;
produces
1 2 3 4 5 6 7 8 9
However, I can't seem to use memcpy to do the equivalent copy. This only manages to copy the first element:
double data_memcopy[9];
memcpy(data_memcopy,M.data(),M.size());
for(int i = 0;i<M.size();i++)
{
std::cout<<data_memcopy[i]<<" ";
}
std::cout<<std::endl;
produces
1 0 0 0 0 0 0 0 0
Any good reason why memcpy is not doing what I expect it should? (Or am I using it improperly?)
You need to multiply by the size of a double:
memcpy(data_memcopy,M.data(),M.size() * sizeof(double));
Otherwise, you are only copying M.size() bytes, and each double is more than one byte on your machine.
So you were probably only writing to the first and second doubles (they probably are 8 bytes on your system, since you copied the first one successfully, and the second double you only probably copied one byte which was likely zeros).