This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM5728: TIDL error

Part Number: AM5728

When I use the TIDL, there is  a error which is weird. After the program runing a few seconds, the tiocl fatal error would be shown like following:

recvfrom failed: Link has been severed (67)
rpmsgThreadFxn: transportGet failed on fd 24, returned -20
TIOCL FATAL: Communication to a DSP has been lost (likely due to an MMU fault). Please wait while the DSPs are reset and the runtime attempts to terminate. A reboot may be required before running another OpenCL application if this fails. See the kernel log for fault information.

So, why?

My program is like these.

tidl_set.h

#ifndef TIDL_SET_H
#define TIDL_SET_H

#include <QObject>
#include <QMetaType>
#include <QVariant>

//#include "configuration.h"
//#include "common/object_classes.h"
#include "common/utils.h"
#include "common/video_utils.h"


using namespace std;
using namespace tidl;
using namespace cv;

class Configuration;
class ObjectClasses;

typedef struct Result
{
    cv::Mat image;         //the image
    uint32_t frame_index;
    bool status;            //success or fail
    float time;
    float ratio_xmin[20];
    float ratio_ymin[20];
    float ratio_xmax[20];
    float ratio_ymax[20];
    CvScalar color[20];
    int index; //roi num
}result;

Q_DECLARE_METATYPE(result)

typedef struct Model_size
{
    int width;
    int height;
}model;

class TIDL_SET : public QObject
{
    Q_OBJECT
 public:
    TIDL_SET();
    ~TIDL_SET();

public:
    int dl_initial(int eve_num, int dsp_num, int orighight, int origwidth);
    model dl_config();
    bool dl_run(Mat bgr_frames[], int channel_size);
    result dl_run_img();
    void dl_set_threshold(uint32_t confidece_num);

signals:
    void send_processed_image(QVariant variant);
    //void send_processed_image(result resultdl);

public slots:
    void dl_run_img1();

private:
    bool WriteFrameOutput(const ExecutionObjectPipeline& eop,
                          const Configuration& c, const cmdline_opts_t& opts,
                          float confidence_value);

public:
    // Process arguments
    // Read the TI DL configuration file
    Configuration c;
    //Executor* e_dsp;
    uint32_t pipeline_depth;
    std::vector<ExecutionObjectPipeline *> eops;
    uint32_t num_eops;
    uint32_t frame_idx;

    int orig_width;
    int orig_height;
    int channel_size;
    float img_scale_h,img_scale_w;//to scale the outimage to original image

    Mat bgr_frames[3];

    //yes or not have image to process
    volatile uint32_t have_image;
    //the num of the processing_image for multi DSP
    volatile uint32_t processing_image;

};

#endif // TIDL_SET_H

tild_set.cpp

#include "tidl_set.h"
#include "configuration.h"
#include "common/object_classes.h"

#include "executor.h"
#include "execution_object.h"
#include "execution_object_pipeline.h"

#include <signal.h>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cassert>
#include <functional>
#include <algorithm>
#include <time.h>
#include <unistd.h>

#include <queue>
#include <vector>
#include <cstdio>
#include <string>
#include <chrono>

#define NUM_VIDEO_FRAMES 100
#define DEFAULT_CONFIG "myjdetnet"
#define DEFAULT_INPUT "../test/testvecs/input/horse_768_320.y"
#define DEFAULT_INPUT_FRAMES (1)
#define DEFAULT_OBJECT_CLASSES_LIST_FILE "./barcode_objects.json"
#define DEFAULT_OUTPUT_PROB_THRESHOLD 40

Executor* CreateExecutor(DeviceType dt, uint32_t num, const Configuration& c,
                         int layers_group_id);

std::unique_ptr<ObjectClasses> object_classes;
cmdline_opts_t opts;
//static Executor* e_dsp;
/* Enable this macro to record individual output files and */
/* resized, cropped network input files                    */
//#define DEBUG_FILES

TIDL_SET::TIDL_SET()
{
    orig_height=200;
    orig_width=200;
    frame_idx=0;
    have_image = 0;
    processing_image = 0;
}

TIDL_SET::~TIDL_SET()
{
    //FreeMemory(eops);
    //for (auto eop : eops)  delete eop;
    //delete e_dsp;
    //delete e_eve;
}

int TIDL_SET::dl_initial(int eve_num, int dsp_num, int orighight, int origwidth)
{
    // Process arguments
    //cmdline_opts_t opts;
    opts.config = DEFAULT_CONFIG;
    opts.object_classes_list_file = DEFAULT_OBJECT_CLASSES_LIST_FILE;
    opts.num_eves = eve_num;
    opts.num_dsps = dsp_num;
    opts.output_prob_threshold = DEFAULT_OUTPUT_PROB_THRESHOLD;
    opts.num_frames=1;
    opts.is_camera_input=0;
    opts.is_video_input=0;
    opts.is_preprocessed_input=0;

    orig_width = origwidth;
    orig_height = orighight;
    // Get object classes list

    object_classes = std::unique_ptr<ObjectClasses>(new ObjectClasses(opts.object_classes_list_file));
    if (object_classes->GetNumClasses() == 0)
    {
        cout << "the file path is "<<opts.object_classes_list_file<<endl;
        cout << "No object classes defined for this config." << endl;
        return EXIT_FAILURE;
    }

    return 0;
}

model TIDL_SET::dl_config()
{
    //read the config file
    model model_size;
    std::string config_file = "./tidl_config.txt";
    bool status = c.ReadFromFile(config_file);
    if (!status)
    {
        cerr << "Error in configuration file: " << config_file << endl;
        model_size.height = -1;
        model_size.width  = -1;
        return model_size;
    }
    img_scale_h = 1.0 / c.inHeight;
    img_scale_w = 1.0 / c.inWidth;
    channel_size = c.inHeight * c.inWidth;
    qDebug("Scale_h = %f     scale_w =%f",img_scale_h,img_scale_w);

    model_size.height = c.inHeight;
    model_size.width  = c.inWidth;

    return model_size;
}


void TIDL_SET::dl_run_img1()
{

    try
    {
        Executor* e_dsp = CreateExecutor(DeviceType::DSP, opts.num_dsps,c,1);
        std::vector<ExecutionObjectPipeline *> eops;
        //set the depth of the pipeline
        pipeline_depth = 1;
        for (uint32_t j = 0; j < pipeline_depth; j++)
        {
            for (uint32_t i = 0; i < opts.num_dsps; i++)
            {
                eops.push_back(new ExecutionObjectPipeline({(*e_dsp)[i]}));
            }
        }
        qDebug("lalalla");
        num_eops = eops.size();
        // Allocate input/output memory for each EOP
        AllocateMemory(eops);
        while(1)
        {
            if(have_image == 0 && processing_image == 0)
            {
                //qDebug("there isn't a image");
                sleep(0.05);
                continue;
            }else{
                qDebug("have_imgae = %d  processing_image = %d", have_image, processing_image);
            }
            chrono::time_point<chrono::steady_clock> tloop0, tloop1,tloop2;
            tloop0 = chrono::steady_clock::now();

            result result_img;
            result_img.index=0;

            tloop2 = chrono::steady_clock::now();
            // Process frames with available eops in a pipelined manner
            // additional num_eops iterations to flush pipeline (epilogue)
            ExecutionObjectPipeline* eop = eops[frame_idx % num_eops];

            // Wait for previous frame on the same eop to finish processing
            Mat frame, bgr[3];
            qDebug("1111");
            if (processing_image > 0)
            {
                if (eop->ProcessFrameWait())
                {
                    qDebug("2222");
                    //WriteFrameOutput(*eop, c, opts, opts.output_prob_threshold);
                    //Mat frame, bgr[3];
                    int height= c.inHeight;
                    int width = c.inWidth;

                    unsigned char *in = (unsigned char *) eop->GetInputBufferPtr();
                    bgr[0] = Mat(height, width, CV_8UC(1), in);
                    bgr[1] = Mat(height, width, CV_8UC(1), in + channel_size);
                    bgr[2] = Mat(height, width, CV_8UC(1), in + channel_size*2);
                    cv::merge(bgr, 3, frame);

                    // Draw boxes around classified objects
                    float *out = (float *) eop->GetOutputBufferPtr();
                    int num_floats = eop->GetOutputBufferSizeInBytes() / sizeof(float);
                    for (int i = 0; i < num_floats / 7; i++)
                    {
                        int index = (int)    out[i * 7 + 0];
                        if (index < 0)  break;

                        float score =        out[i * 7 + 2];
                        if (score * 100 < opts.output_prob_threshold)  continue;

                        int   label = (int)  out[i * 7 + 1];
                        int   xmin  = (int) (out[i * 7 + 3] * width);
                        int   ymin  = (int) (out[i * 7 + 4] * height);
                        int   xmax  = (int) (out[i * 7 + 5] * width);
                        int   ymax  = (int) (out[i * 7 + 6] * height);

                        const ObjectClass& object_class = object_classes->At(label);

                        if(opts.verbose) {
                            printf("%2d: (%d, %d) -> (%d, %d): %s, score=%f\n",
                                i, xmin, ymin, xmax, ymax, object_class.label.c_str(), score);
                    }

                        if (xmin < 0)       xmin = 0;
                        if (ymin < 0)       ymin = 0;
                        if (xmax > width)   xmax = width;
                        if (ymax > height)  ymax = height;
                        cv::rectangle(frame, Point(xmin, ymin), Point(xmax, ymax),
                                  Scalar(object_class.color.blue,
                                         object_class.color.green,
                                         object_class.color.red), 2);
                        result_img.ratio_xmin[result_img.index] = xmin * img_scale_w;//0.00390625;
                        result_img.ratio_ymin[result_img.index] = ymin * img_scale_h;//0.00390625;
                        result_img.ratio_xmax[result_img.index] = xmax * img_scale_w;//0.00390625;
                        result_img.ratio_ymax[result_img.index] = ymax * img_scale_h;//0.00390625;
                        result_img.color     [result_img.index] = Scalar(object_class.color.blue,object_class.color.green,object_class.color.red);
                        result_img.index++;
                    }
                    result_img.image = frame;
                    result_img.frame_index = eop->GetFrameIndex();
                    result_img.status = true;
                    cv::imwrite("out.jpg",frame);

                    std::string name = eop->GetDeviceName();
                    qDebug("the name is %s", name.c_str());
                    QVariant variant;
                    variant.setValue(result_img);

                    tloop1 = chrono::steady_clock::now();
                    chrono::duration<float> elapsed = tloop1 - tloop0;
                    chrono::duration<float> elapsed1 = tloop1 - tloop2;
                    cout << "Loop total time (including read/write/opencv/print/etc): "
                          << setw(6) << setprecision(4)
                          << (elapsed.count() * 1000) << "ms" << endl;
                    cout << "run time: "
                          << setw(6) << setprecision(4)
                          << (elapsed1.count() * 1000) << "ms" << endl;
                    result_img.time = elapsed1.count()*1000;
                    emit send_processed_image(variant);
                }
                processing_image--;
            }
            if (have_image > 0)
            {
                char* frame_buffer = eop->GetInputBufferPtr();
                memcpy(frame_buffer,                bgr_frames[0].ptr(), channel_size);
                memcpy(frame_buffer+1*channel_size, bgr_frames[1].ptr(), channel_size);
                memcpy(frame_buffer+2*channel_size, bgr_frames[2].ptr(), channel_size);

                eop->SetFrameIndex(frame_idx);
                eop->ProcessFrameStartAsync();

                frame_idx++;
                processing_image++;
                have_image--;
            }
        }//for while
        FreeMemory(eops);
        for (auto eop : eops)  delete eop;
        delete e_dsp;
    }
    catch (tidl::Exception &e)
    {
        cerr << e.what() << endl;
        //result_img.status = false;
    }
}

// Create frame with boxes drawn around classified objects
bool TIDL_SET::WriteFrameOutput(const ExecutionObjectPipeline& eop,
                      const Configuration& c, const cmdline_opts_t& opts,
                      float confidence_value)
{
    // Asseembly original frame
    int width  = c.inWidth;
    int height = c.inHeight;
    int channel_size = width * height;
    Mat frame, bgr[3];

    unsigned char *in = (unsigned char *) eop.GetInputBufferPtr();
    bgr[0] = Mat(height, width, CV_8UC(1), in);
    bgr[1] = Mat(height, width, CV_8UC(1), in + channel_size);
    bgr[2] = Mat(height, width, CV_8UC(1), in + channel_size*2);
    cv::merge(bgr, 3, frame);

    int frame_index = eop.GetFrameIndex();
    char outfile_name[64];

    // Draw boxes around classified objects
    float *out = (float *) eop.GetOutputBufferPtr();
    int num_floats = eop.GetOutputBufferSizeInBytes() / sizeof(float);
    for (int i = 0; i < num_floats / 7; i++)
    {
        int index = (int)    out[i * 7 + 0];
        if (index < 0)  break;

        float score =        out[i * 7 + 2];
        if (score * 100 < confidence_value)  continue;

        int   label = (int)  out[i * 7 + 1];
        int   xmin  = (int) (out[i * 7 + 3] * width);
        int   ymin  = (int) (out[i * 7 + 4] * height);
        int   xmax  = (int) (out[i * 7 + 5] * width);
        int   ymax  = (int) (out[i * 7 + 6] * height);

        const ObjectClass& object_class = object_classes->At(label);

        if(opts.verbose) {
            printf("%2d: (%d, %d) -> (%d, %d): %s, score=%f\n",
               i, xmin, ymin, xmax, ymax, object_class.label.c_str(), score);
        }

        if (xmin < 0)       xmin = 0;
        if (ymin < 0)       ymin = 0;
        if (xmax > width)   xmax = width;
        if (ymax > height)  ymax = height;
        cv::rectangle(frame, Point(xmin, ymin), Point(xmax, ymax),
                      Scalar(object_class.color.blue,
                             object_class.color.green,
                             object_class.color.red), 2);
    }

    if (opts.is_camera_input || opts.is_video_input)
    {
        cv::imshow("SSD_Multibox", frame);
#ifdef DEBUG_FILES
        // Image files can be converted into video using, example script
        // (on desktop Ubuntu, with ffmpeg installed):
        // ffmpeg -i multibox_%04d.png -vf "scale=(iw*sar)*max(768/(iw*sar)\,320/ih):ih*max(768/(iw*sar)\,320/ih), crop=768:320" -b:v 4000k out.mp4
        // Update width 768, height 320, if necessary
        snprintf(outfile_name, 64, "multibox_%04d.png", frame_index);
        cv::imwrite(outfile_name, r_frame);
#endif
        waitKey(1);
    }
    else
    {
        // Resize to output width/height, keep aspect ratio
        Mat r_frame;
        uint32_t output_width = opts.output_width;
        if (output_width == 0)  output_width = orig_width;
        uint32_t output_height = (output_width*1.0f) / orig_width * orig_height;
        cv::resize(frame, r_frame, Size(output_width, output_height));

        snprintf(outfile_name, 64, "multibox_%d.png", frame_index);
        cv::imwrite(outfile_name, frame);
        printf("Saving frame %d with SSD multiboxes to: %s\n",
               frame_index, outfile_name);
    }

    return true;
}

void TIDL_SET::dl_set_threshold(uint32_t confidece_num)
{
    opts.output_prob_threshold = confidece_num;
}

// Create an Executor with the specified type and number of EOs
Executor* CreateExecutor(DeviceType dt, uint32_t num, const Configuration& c,
                         int layers_group_id)
{
    if (num == 0) return nullptr;

    DeviceIds ids;
    for (uint32_t i = 0; i < num; i++)
        ids.insert(static_cast<DeviceId>(i));

    //return new Executor(dt, ids, c, layers_group_id);
    printf("2222 \n");
    return new Executor(dt, ids, c);
}

I wil use the dl_run_img1() function to process the image after the dl_initial() and dl_config. Please help me and my project has stuck here for a long time.