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.