keras2c icon indicating copy to clipboard operation
keras2c copied to clipboard

Error undefined reference to `lstm(k2c_tensor*, k2c_tensor*)'

Open javimg140 opened this issue 3 years ago • 1 comments

Hello,

I am trying to convert a LSTM NN to C. I was able to generate the C files using your library but when I try to run the example in C I get the error "lstm(k2c_tensor*, k2c_tensor*)". Do you know what can be the cause of this? I attached the code. Thank you

#include <stdio.h>
#include <math.h>
#include <time.h>
#include "./keras2c/include/k2c_include.h"
#include "./lstm.h"

float maxabs(k2c_tensor *tensor1, k2c_tensor *tensor2);
struct timeval GetTimeStamp();

float test1_lstm_input_input_array[12] = {
    -1.13245840e+00f,
    -1.88968293e+00f,
    -1.01585267e-01f,
    -5.98125538e-01f,
    -1.60964425e+00f,
    +1.75511004e+00f,
    -1.52169081e+00f,
    -1.57987595e+00f,
    +1.23946883e+00f,
    -1.41191308e+00f,
    +8.65569771e-01f,
    +7.68581566e-01f,
};
k2c_tensor test1_lstm_input_input = {&test1_lstm_input_input_array[0], 2, 12, {4, 3, 1, 1, 1}};
float keras_dense_test1_array[1] = {
    -5.31204462e-01f,
};
k2c_tensor keras_dense_test1 = {&keras_dense_test1_array[0], 1, 1, {1, 1, 1, 1, 1}};
float c_dense_test1_array[1] = {0};
k2c_tensor c_dense_test1 = {&c_dense_test1_array[0], 1, 1, {1, 1, 1, 1, 1}};
float test2_lstm_input_input_array[12] = {
    +3.94249042e-01f,
    -4.07409747e-01f,
    -6.77222531e-01f,
    +1.97063872e+00f,
    +1.23045506e+00f,
    +1.39234612e+00f,
    -8.36423398e-01f,
    -3.03802024e-01f,
    -1.03085725e+00f,
    +1.14633289e+00f,
    +7.20393857e-01f,
    -1.17798856e+00f,
};
k2c_tensor test2_lstm_input_input = {&test2_lstm_input_input_array[0], 2, 12, {4, 3, 1, 1, 1}};
float keras_dense_test2_array[1] = {
    +3.58893424e-01f,
};
k2c_tensor keras_dense_test2 = {&keras_dense_test2_array[0], 1, 1, {1, 1, 1, 1, 1}};
float c_dense_test2_array[1] = {0};
k2c_tensor c_dense_test2 = {&c_dense_test2_array[0], 1, 1, {1, 1, 1, 1, 1}};
float test3_lstm_input_input_array[12] = {
    -4.65610290e-01f,
    -1.75561958e+00f,
    +1.29821420e+00f,
    -4.74955731e-01f,
    -1.47081012e+00f,
    +1.50551550e+00f,
    +4.28652033e-02f,
    -7.00394754e-01f,
    -1.58612456e+00f,
    +3.65025042e-01f,
    +1.90088424e+00f,
    -1.15637390e-01f,
};
k2c_tensor test3_lstm_input_input = {&test3_lstm_input_input_array[0], 2, 12, {4, 3, 1, 1, 1}};
float keras_dense_test3_array[1] = {
    -2.32015252e-02f,
};
k2c_tensor keras_dense_test3 = {&keras_dense_test3_array[0], 1, 1, {1, 1, 1, 1, 1}};
float c_dense_test3_array[1] = {0};
k2c_tensor c_dense_test3 = {&c_dense_test3_array[0], 1, 1, {1, 1, 1, 1, 1}};
float test4_lstm_input_input_array[12] = {
    +7.78019686e-01f,
    +1.14394216e+00f,
    +1.47736387e+00f,
    +1.13235781e+00f,
    -8.92344912e-03f,
    -1.03233765e-01f,
    -1.40811364e+00f,
    -7.14377063e-01f,
    +1.53193782e+00f,
    -1.51097806e-01f,
    +1.73710253e-01f,
    -1.31863513e+00f,
};
k2c_tensor test4_lstm_input_input = {&test4_lstm_input_input_array[0], 2, 12, {4, 3, 1, 1, 1}};
float keras_dense_test4_array[1] = {
    +5.08163869e-03f,
};
k2c_tensor keras_dense_test4 = {&keras_dense_test4_array[0], 1, 1, {1, 1, 1, 1, 1}};
float c_dense_test4_array[1] = {0};
k2c_tensor c_dense_test4 = {&c_dense_test4_array[0], 1, 1, {1, 1, 1, 1, 1}};
float test5_lstm_input_input_array[12] = {
    +1.74445294e+00f,
    +3.46498525e-01f,
    +1.30536050e+00f,
    +9.16105772e-01f,
    -9.29711491e-01f,
    -5.63974734e-01f,
    +1.72561155e+00f,
    +1.68685380e+00f,
    -4.14265337e-01f,
    +4.03739047e-01f,
    -5.95306724e-01f,
    -5.11684715e-01f,
};
k2c_tensor test5_lstm_input_input = {&test5_lstm_input_input_array[0], 2, 12, {4, 3, 1, 1, 1}};
float keras_dense_test5_array[1] = {
    +8.75042528e-02f,
};
k2c_tensor keras_dense_test5 = {&keras_dense_test5_array[0], 1, 1, {1, 1, 1, 1, 1}};
float c_dense_test5_array[1] = {0};
k2c_tensor c_dense_test5 = {&c_dense_test5_array[0], 1, 1, {1, 1, 1, 1, 1}};

int main()
{
    float errors[5];
    size_t num_tests = 5;
    size_t num_outputs = 1;
    lstm_initialize();
    clock_t t0 = clock();
    lstm(&test1_lstm_input_input, &c_dense_test1);
    lstm(&test2_lstm_input_input, &c_dense_test2);
    lstm(&test3_lstm_input_input, &c_dense_test3);
    lstm(&test4_lstm_input_input, &c_dense_test4);
    lstm(&test5_lstm_input_input, &c_dense_test5);

    clock_t t1 = clock();
    printf("Average time over 5 tests: %e s \n",
           ((double)t1 - t0) / (double)CLOCKS_PER_SEC / (double)5);
    errors[0] = maxabs(&keras_dense_test1, &c_dense_test1);
    errors[1] = maxabs(&keras_dense_test2, &c_dense_test2);
    errors[2] = maxabs(&keras_dense_test3, &c_dense_test3);
    errors[3] = maxabs(&keras_dense_test4, &c_dense_test4);
    errors[4] = maxabs(&keras_dense_test5, &c_dense_test5);
    float maxerror = errors[0];
    for (size_t i = 1; i < num_tests * num_outputs; i++)
    {
        if (errors[i] > maxerror)
        {
            maxerror = errors[i];
        }
    }
    printf("Max absolute error for 5 tests: %e \n", maxerror);
    lstm_terminate();
    if (maxerror > 1e-05)
    {
        return 1;
    }
    return 0;
}

float maxabs(k2c_tensor *tensor1, k2c_tensor *tensor2)
{

    float x = 0;

    float y = 0;

    for (size_t i = 0; i < tensor1->numel; i++)
    {

        y = fabsf(tensor1->array[i] - tensor2->array[i]);
        if (y > x)
        {
            x = y;
        }
    }
    return x;
}

javimg140 avatar Jun 08 '22 08:06 javimg140

Not sure what lstm.h is, all of the keras2c stuff starts with k2c_, is that a custom wrapper or something?

f0uriest avatar Jul 11 '22 15:07 f0uriest