docs:rtlib:appcreation

Application integration

Here are the first steps towards having a new integrated – and profiled – application. Follow these hands-on tutorials to better understand the Barbeque application developement workflow.

Starting from a template

You don't have to code an application from scratch. The bbque-layapp command allows you to start coding from a template (did you read this tutorial?).

Open a terminal, source the BOSPShell, then type bbque-layapp.

You should definetly add

alias bosp-shell=". /PATH/TO/BOSP/out/etc/bbque/bosp_init.env"

at the end of your ~/.bashrc file. Sourcing the BOSPShell with a single bosp-shell command is priceless.

[BOSPShell Desktop] \> bbque-layapp
 
=== Building a new BBQ application from template ===
Enter application name (use CamelCase, no spaces allowed) [MyApp]: BbqTutorials
Select application type (0: CPP) [0]: 0
 
.:: BarbequeRTRM Template Application Extraction
Application name :  BbqTutorials
Destination path :  /home/slibutti/opt/BOSP/barbeque/../contrib/user/BbqTutorials
Extracing [./Kconfig]...
Extracing [./Doxyfile.in]...
Extracing [./src/MyApp_main.cc]...
Extracing [./src/version.cc.in]...
Extracing [./src/CMakeLists.txt]...
Extracing [./src/MyApp_exc.cc]...
Extracing [./bosp.mk]...
Extracing [./recipes/MyApp.recipe]...
Extracing [./include/version.h]...
Extracing [./include/MyApp_exc.h]...
Extracing [./CMakeLists.txt]...
==== Bootstraping BOSP Building System ====
Looking up for BOSP modules Configurations...
 
.:: External REQUIRED modules:
/home/slibutti/opt/BOSP/external/required/ticpp
/home/slibutti/opt/BOSP/external/required/libcg
/home/slibutti/opt/BOSP/external/required/log4cpp
/home/slibutti/opt/BOSP/external/required/boost
/home/slibutti/opt/BOSP/external/required/sysfsutils
 
.:: External OPTIONAL modules:
/home/slibutti/opt/BOSP/external/optional/v4l-utils
/home/slibutti/opt/BOSP/external/optional/libjpeg
/home/slibutti/opt/BOSP/external/optional/tbb40-u3
/home/slibutti/opt/BOSP/external/optional/argo
/home/slibutti/opt/BOSP/external/optional/opencl
 
.:: External PARTIAL modules:
/home/slibutti/opt/BOSP/external/partial/opencv
 
.:: External TOOLS modules:
/home/slibutti/opt/BOSP/external/tools/feedgnuplot
 
.:: Benchmarks modules:
/home/slibutti/opt/BOSP/benchmarks/parsec-2.1
 
.:: Contrib TESTING applications:
/home/slibutti/opt/BOSP/contrib/testing/rtlib-testapp
/home/slibutti/opt/BOSP/contrib/testing/demoapp
 
.:: Contrib USER applications:
/home/slibutti/opt/BOSP/contrib/user/Membound
/home/slibutti/opt/BOSP/contrib/user/BbqTutorials
/home/slibutti/opt/BOSP/contrib/user/ocvdemo
/home/slibutti/opt/BOSP/contrib/user/rtlib-tutorials
/home/slibutti/opt/BOSP/contrib/user/ocl-samples
/home/slibutti/opt/BOSP/contrib/user/Cpubound
/home/slibutti/opt/BOSP/contrib/user/mview-demo-argo
/home/slibutti/opt/BOSP/contrib/user/ThrPoolTutorial

In this case, the BbqTutorials_exc.cc file will be cleansed from logging stuff and comments, leading to improved readability. Probably you had guessed that our aim, here, is to implement the methods listed in the file.

/**
 *       @file  BbqTutorials_exc.cc
 *      @brief  The BbqTutorials BarbequeRTRM application
 *
 * Description: An application examples for BOSP tutorials
 *
 *     @author  Simone Libutti (slibutti), simone.libutti@polimi.it
 *
 *     Company  Politecnico di Milano
 *   Copyright  Copyright (c) 2014, Simone Libutti
 *
 * This source code is released for free distribution under the terms of the
 * GNU General Public License as published by the Free Software Foundation.
 * =====================================================================================
 */
 
#include "BbqTutorials_exc.h"
 
#include <cstdio>
#include <bbque/utils/utility.h>
 
// Setup logging
#undef  BBQUE_LOG_MODULE
#define BBQUE_LOG_MODULE "aem.bbqtutorials"
#undef  BBQUE_LOG_UID
#define BBQUE_LOG_UID GetChUid()
 
BbqTutorials::BbqTutorials(std::string const & name,
		std::string const & recipe,
		RTLIB_Services_t *rtlib) :
	BbqueEXC(name, recipe, rtlib) {
 
	//TODO: do something
 
}
 
RTLIB_ExitCode_t BbqTutorials::onSetup() {
 
	//TODO: do something
 
	return RTLIB_OK;
}
 
RTLIB_ExitCode_t BbqTutorials::onConfigure(uint8_t awm_id) {
 
	//TODO: do something
 
	return RTLIB_OK;
}
 
RTLIB_ExitCode_t BbqTutorials::onRun() {
 
	//TODO: do something
 
	return RTLIB_OK;
}
 
RTLIB_ExitCode_t BbqTutorials::onMonitor() {
 
	//TODO: do something
 
	return RTLIB_OK;
}
 
RTLIB_ExitCode_t BbqTutorials::onRelease() {
 
	//TODO: do something
 
	return RTLIB_OK;
}

This application will be used during the next tutorials to train on application characterization. Thus, first of all let's add some input parameters:

  1. Number of threads
  2. Number of jobs to perform
  3. A quality of service related parameter in [1..5]
  4. Another quality of service related parameter in [1..5]

Essentially, this is the first and last time you edit BbqTutorials_main.cc and BbqTutorials_exc.h. Later on, we will only focus on the BbqTutorials_exc.cc file. First of all, declare the variables in the BbqTutorials class, and an utility function which will be executed by each thread.

  • To augment clarity, all the added lines will be marked with a //+ comment
  • This implementation of a multithreaded application is quite naive. For an implementation using the ThreadPool facility, see this tutorial

/* File: BbqTutorials_exc.h */
 
#ifndef BBQTUTORIALS_EXC_H_
#define BBQTUTORIALS_EXC_H_
 
#include <bbque/bbque_exc.h>
#include <vector> //+
 
using bbque::rtlib::BbqueEXC;
 
class BbqTutorials : public BbqueEXC {
 
int threads_number; //+
int quality_a; //+
int quality_b; //+
 
int jobs_number; //+
int jobs_done = 0; //+
 
std::vector<std::thread> threads_container; //+
 
public:
 
	BbqTutorials(std::string const & name,
			int thr_n, int qos_a, int qos_b, int jobs, //+
			std::string const & recipe,
			RTLIB_Services_t *rtlib);
 
private:
 
	RTLIB_ExitCode_t onSetup();
	RTLIB_ExitCode_t onConfigure(uint8_t awm_id);
	RTLIB_ExitCode_t onRun();
	RTLIB_ExitCode_t onMonitor();
	RTLIB_ExitCode_t onRelease();
 
	// Each thread will execute this method
	int SomeWork(); //+
 
};
 
#endif // BBQTUTORIALS_EXC_H_

Then, set them as application arguments.

/* File: BbqTutorials_main.cc */
 
// Some pre-existent code
 
int thr_n, qos_a, qos_b, jobs; //+
 
void ParseCommandLine(int argc, char *argv[]) {
	// Parse command line params
	try {
 
// Some pre-existent code
 
	opts_desc.add_options()
		("help,h", "print this help message")
		("version,v", "print program version")
		("threads,t", po::value<int>(&thr_n)-> default_value(1),"Number of threads to exploit") //+
		("param_a,a", po::value<int>(&qos_a)-> default_value(2),"QoS parameter A [1..5]") //+
		("param_b,b", po::value<int>(&qos_b)-> default_value(2),"QoS parameter B [1..5]") //+
		("jobs,j", po::value<int>(&jobs)-> default_value(100),"Number of jobs to perform") //+
 
		("recipe,r", po::value<std::string>(&recipe)->
			default_value("BbqTutorials"),
			"recipe name (for all EXCs)")
	;
 
// Some pre-existent code
 
	fprintf(stderr, FI("STEP 1. Registering EXC using [%s] recipe...\n"),
			recipe.c_str());
 
	if ( qos_a > 5 ) qos_a = 5; //+
	if ( qos_b > 5 ) qos_b = 5; //+
 
	pexc = pBbqueEXC_t(new BbqTutorials("BbqTutorials",
						thr_n, qos_a, qos_b, jobs, recipe, rtlib)); //+
	if (!pexc->isRegistered())
		return RTLIB_ERROR;
 
// Some pre-existent code

Finally, let's implement the methods. In this example, we only need to implement the onRun and onMonitor methods. The onConfigure method will be implemented after the application characterization.
Basically, the onRun method creates and then waits for the desired number of threads. Each thread performs the SomeWork method, whose duration is a function of the two QoS parameters. The onMonitor method computes a QoS metric, which is also a function of the QoS parameters, and prints it on-screen.

/**
 *       @file  BbqTutorials_exc.cc
 *      @brief  The BbqTutorials BarbequeRTRM application
 *
 * Description: An application examples for BOSP tutorials
 *
 *     @author  Simone Libutti (slibutti), simone.libutti@polimi.it
 *
 *     Company  Politecnico di Milano
 *   Copyright  Copyright (c) 2014, Simone Libutti
 *
 * This source code is released for free distribution under the terms of the
 * GNU General Public License as published by the Free Software Foundation.
 * =====================================================================================
 */
 
#include "BbqTutorials_exc.h"
 
#include <cstdio>
#include <bbque/utils/utility.h>
 
// My libraries
#include <math.h> //+
 
// Setup logging
#undef  BBQUE_LOG_MODULE
#define BBQUE_LOG_MODULE "aem.bbqtutorials"
#undef  BBQUE_LOG_UID
#define BBQUE_LOG_UID GetChUid()
 
BbqTutorials::BbqTutorials(std::string const & name,
		int thr_n, int qos_a, int qos_b, int jobs,
		std::string const & recipe,
		RTLIB_Services_t *rtlib) :
	BbqueEXC(name, recipe, rtlib),
	threads_number(thr_n), //+
	quality_a(qos_a), //+
	quality_b(qos_b), //+
	jobs_number(jobs) {}  //+
 
RTLIB_ExitCode_t BbqTutorials::onSetup() {
 
	// Nothing to do, in this case
 
	return RTLIB_OK;
}
 
RTLIB_ExitCode_t BbqTutorials::onConfigure(uint8_t awm_id) {
 
	// Nothing to do, for now
 
	return RTLIB_OK;
}
 
RTLIB_ExitCode_t BbqTutorials::onRun() {
 
	for ( int i = 0; i < threads_number; ++i ) //+
		threads_container.push_back(std::thread(&BbqTutorials::SomeWork, this)); //+
 
	for ( auto &thread : threads_container )  //+
		thread.join(); //+
 
	threads_container.clear();  //+
 
	return RTLIB_OK;
}
 
RTLIB_ExitCode_t BbqTutorials::onMonitor() {
 
	int quality_of_service = quality_a + quality_b; //+
 
	if ( quality_of_service < 4 ) //+
		logger->Notice("[onMonitor]: Low QoS (%d) on cycle %d", //+
						quality_of_service, Cycles()); //+
	else if ( quality_of_service < 9 )
		logger->Notice("[onMonitor]: Medium QoS (%d) on cycle %d", //+
						quality_of_service, Cycles()); //+
	else
		logger->Notice("[onMonitor]: High QoS (%d) on cycle %d", //+
						quality_of_service, Cycles()); //+
 
	// Return when done
	if ( jobs_done >=jobs_number ) return RTLIB_EXC_WORKLOAD_NONE; //+
 
	// Exploit less threads if less jobs remain //+
	if ( jobs_number - jobs_done < threads_number ) //+
		threads_number = jobs_number - jobs_done; //+
 
	return RTLIB_OK;
 
}
 
RTLIB_ExitCode_t BbqTutorials::onRelease() {
 
	//nothing to do
 
	return RTLIB_OK;
}
 
int BbqTutorials::SomeWork() { //+
 
	int iterations = 100000*quality_a + 500000*quality_b; //+
	int result = 0; //+
 
	for ( int index = 0; index < iterations; ++index ) //+
		result += sqrt( index ); //+
 
	jobs_done++; //+
 
	return result; //+
 
} //+

You just coded your first application. However, if you want it to execute, you must write a suitable recipe. The next tutorials will guide you step by step towards this goal. For now, let's build the application.

Have you enabled the application building from the menuconfig?

[BOSPShell ~] \> cd /PATH/TO/BOSP
[BOSPShell ~] \> make bbqtutorials

You are ready for the next tutorial.

docs/rtlib/appcreation.txt · Last modified: 2017/05/16 22:57 by jumanix

Page Tools