How to use ragel labels outside the scope of machine instantiation - ragel

When an action is executed I want the action to trigger a jump to another state under certain conditions.
For code readability I'd also like to define the action outside of the machine instantiation.
How can I access the state labels generated by ragel outside the scope of the machine instantiation?
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
static int cs=1;
%%{
machine simpleMachine;
write data;
}%%
//The code for ActionA and ActionB is defined outside the scope
//of the instatiation for readability
void a(void)
{ //Called for ActionA
}
void b(void)
{ //Called for ActionB
int var2=0;
if (var2==0)
{
%%{
fgoto STATE_A;
#This fgoto generates a ragel parse error
#how to use the STATE_A label outside
#of the machine definition?
}%%
}
}
void ExecuteSM(const char *p)
{ const char *pe = p + strlen( p );
int var1=0;
%%{
EVENT1 = 'a';
EVENT2 = 'b';
EVENT3= 'c';
action ActionA
{ a();
if (var1==0)
{
fgoto STATE_B; //This fgoto compiles OK
}
}
action ActionB
{
b();//I'd like to execute an fgoto in the function b() but I get a
//parse error
}
myfsm := (
#STATE EVENT ACTION NEXT_STATE
start:( EVENT1 >ActionA ->STATE_A),
STATE_A:( EVENT2 >ActionB ->STATE_B),
STATE_B:( EVENT3)
);
write init nocs;
write exec;
}%%
}
int main()
{
ExecuteSM("abc");
return 0;
}

fgoto is only available in code blocks, i.e. between { and } in a Ragel FSM specification.
In your example, you have put the fgoto outside of a code block (the %%{ }%% just opens/closes a multi-line FSM specification).
If your objective is to put the action-code where your functions a()/b() currently are, you can just do that - as actions. This would improve code-readability at least as much as your current idea.
Your example thus modified:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
static int cs=0;
%%{
machine simpleMachine;
write data;
action ActionA
{
if (var1 == 0)
fgoto STATE_B; //This fgoto compiles OK
}
action ActionB
{
int var2 = 0;
if (var2 == 0)
fgoto STATE_A;
}
}%%
void ExecuteSM(const char *p)
{
const char *pe = p + strlen(p);
int var1 = 0;
%%{
EVENT1 = 'a';
EVENT2 = 'b';
EVENT3 = 'c';
myfsm := (
#STATE EVENT ACTION NEXT_STATE
start: ( EVENT1 >ActionA ->STATE_A),
STATE_A:( EVENT2 >ActionB ->STATE_B),
STATE_B:( EVENT3)
);
write exec;
}%%
}
int main()
{
%% write init;
ExecuteSM("abc");
return 0;
}
Note that I've also changed your init nocs statement. Custom initialization should only be necessary in very special circumstances - and then it is preferably to use symbolic state names.
I've left the cs declaration at translation unit level, although in that example declaring (and initializing) it locally in ExecuteSM would be more appropriate.

Related

Simple parsing to a tuple fails

Why does this not compile? The marked line gives me: "static assertion failed: The parser expects tuple-like attribute type". I would think that an std::tuple were the essence of "tuple-like"?
#include <string>
#include <tuple>
#include <boost/spirit/home/x3.hpp>
void parseInteger(std::string input) {
namespace x3 = boost::spirit::x3;
auto iter = input.begin();
auto end_iter = input.end();
int result;
x3::parse(iter, end_iter, x3::int_, result);
}
void parseIntegerAndDouble(std::string input) {
namespace x3 = boost::spirit::x3;
auto iter = input.begin();
auto end_iter = input.end();
std::tuple<int, double> result;
x3::parse(iter, end_iter, x3::int_ >> ' ' >> x3::double_, result); //Compile error!
}
int main(int, char **)
{
parseInteger("567");
parseIntegerAndDouble("321 3.1412");
return 0;
}
The trick is to include two additional header files:
#include <boost/fusion/adapted/std_tuple.hpp>
#include <boost/fusion/include/std_tuple.hpp>
This is a bit more magical than I like, but I've got a feeling I really don't want to know how this works!

How to measure the execution time of GPU with using Profiling+openCL+Sycl+DPCPP

I read this link
https://github.com/intel/pti-gpu
and I tried to use Device Activity Tracing for OpenCL(TM), but I am confused and I do not know how should I measure the time on the accelerators with using Device Activity documentation.
for measuring the performance of CPU I used chrono, but I am interested in to using profiling for measuring the performance of CPU and GPU in different devices.
my program:
#include <CL/sycl.hpp>
#include <iostream>
#include <tbb/tbb.h>
#include <tbb/parallel_for.h>
#include <vector>
#include <string>
#include <queue>
#include<tbb/blocked_range.h>
#include <tbb/global_control.h>
#include <chrono>
using namespace tbb;
template<class Tin, class Tout, class Function>
class Map {
private:
Function fun;
public:
Map() {}
Map(Function f):fun(f) {}
std::vector<Tout> operator()(bool use_tbb, std::vector<Tin>& v) {
std::vector<Tout> r(v.size());
if(use_tbb){
// Start measuring time
auto begin = std::chrono::high_resolution_clock::now();
tbb::parallel_for(tbb::blocked_range<Tin>(0, v.size()),
[&](tbb::blocked_range<Tin> t) {
for (int index = t.begin(); index < t.end(); ++index){
r[index] = fun(v[index]);
}
});
// Stop measuring time and calculate the elapsed time
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration_cast<std::chrono::nanoseconds>(end - begin);
printf("Time measured: %.3f seconds.\n", elapsed.count() * 1e-9);
return r;
} else {
sycl::queue gpuQueue{sycl::gpu_selector()};
sycl::range<1> n_item{v.size()};
sycl::buffer<Tin, 1> in_buffer(&v[0], n_item);
sycl::buffer<Tout, 1> out_buffer(&r[0], n_item);
gpuQueue.submit([&](sycl::handler& h){
//local copy of fun
auto f = fun;
sycl::accessor in_accessor(in_buffer, h, sycl::read_only);
sycl::accessor out_accessor(out_buffer, h, sycl::write_only);
h.parallel_for(n_item, [=](sycl::id<1> index) {
out_accessor[index] = f(in_accessor[index]);
});
}).wait();
}
return r;
}
};
template<class Tin, class Tout, class Function>
Map<Tin, Tout, Function> make_map(Function f) { return Map<Tin, Tout, Function>(f);}
typedef int(*func)(int x);
//define different functions
auto function = [](int x){ return x; };
auto functionTimesTwo = [](int x){ return (x*2); };
auto functionDivideByTwo = [](int x){ return (x/2); };
auto lambdaFunction = [](int x){return (++x);};
int main(int argc, char *argv[]) {
std::vector<int> v = {1,2,3,4,5,6,7,8,9};
//auto f = [](int x){return (++x);};
//Array of functions
func functions[] =
{
function,
functionTimesTwo,
functionDivideByTwo,
lambdaFunction
};
for(int i = 0; i< sizeof(functions); i++){
auto m1 = make_map<int, int>(functions[i]);
//auto m1 = make_map<int, int>(f);
std::vector<int> r = m1(true, v);
//print the result
for(auto &e:r) {
std::cout << e << " ";
}
}
return 0;
}
First of all, SYCL Kernel wont support function pointers. So, you can change the code accordingly.
One way to achieve profiling in GPU is by following the steps below:
1.Enable profiling mode for the command queue of the target device
2.Introduce the event for the target device activity
3.Set the callback to be notified when the activity is completed
4.Read the profiling data inside the callback
Basically, you need to use CL_PROFILING_COMMAND_START and CL_PROFILING_COMMAND_END (command identified by event start and end execution on the device) inside the call back.
You can find the detailed steps here
https://github.com/intel/pti-gpu/blob/master/chapters/device_activity_tracing/OpenCL.md
I would also advice you to check the samples for pti-gpu using Device Activity Tracing. Check the URL for the same
https://github.com/intel/pti-gpu/tree/master/samples

boost multi index - loop through key value of specific entry

I have a multi index with 2 indexes(in real code, they are of different type).
class CrUsersKeys{
int IMSI;
int TIMESTAMP;
}
After i find an entry in the multi index, I have the iterator of the entry.
auto it = multi.GetIteratorBy<IMSI_tag>(searchKey);
Now i want to loop through all the indexed members in this specific (*it) and check them. Note that i don't want to iterate through the iterator, but through the the indexed element of CrUsersKeys. How can i do it?
for(key in it)
{
if(isGoodKey(key))
std::cout<<"key "<<key <<" is good key"<<std::endl;
}
So it should check isGoodKey((*it).IMSI) and isGoodKey((*it).TIMESTAMP).
CrUsersKeys is template parameter, so i can't really know the members of CrUsersKeys.
Code example at http://coliru.stacked-crooked.com/a/d97195a6e4bb7ad4
My multi index class is in shared memory.
Your question has little to do with Boost.MultiIndex and basically asks for a way to compile-time iterate over the members of a class. If you're OK with CrUsersKeys being defined as a std::tuple (or a tuple-like class), then you can do something like this (C++17):
Edit: Showed how to adapt a non-tuple class to the framework.
Live On Coliru
#include <tuple>
template<typename Tuple,typename F>
bool all_of_tuple(const Tuple& t,F f)
{
const auto fold=[&](const auto&... x){return (...&&f(x));};
return std::apply(fold,t);
}
#include <iostream>
#include <type_traits>
bool isGoodKey(int x){return x>0;}
bool isGoodKey(const char* x){return x&&x[0]!='\0';}
template<typename Tuple>
bool areAllGoodKeys(const Tuple& t)
{
return all_of_tuple(t,[](const auto& x){return isGoodKey(x);});
}
struct CrUsersKeys
{
int IMSI;
const char* TIMESTAMP;
};
bool areAllGoodKeys(const CrUsersKeys& x)
{
return areAllGoodKeys(std::forward_as_tuple(x.IMSI,x.TIMESTAMP));
}
int main()
{
std::cout<<areAllGoodKeys(std::make_tuple(1,1))<<"\n"; // 1
std::cout<<areAllGoodKeys(std::make_tuple(1,"hello"))<<"\n"; // 1
std::cout<<areAllGoodKeys(std::make_tuple(1,0))<<"\n"; // 0
std::cout<<areAllGoodKeys(std::make_tuple("",1))<<"\n"; // 0
std::cout<<areAllGoodKeys(CrUsersKeys{1,"hello"})<<"\n"; // 1
std::cout<<areAllGoodKeys(CrUsersKeys{0,"hello"})<<"\n"; // 0
std::cout<<areAllGoodKeys(CrUsersKeys{1,""})<<"\n"; // 0
}

How can I stop the program inside the a parent or a child process?

I have this piece of code that I developed just to address a problem that I have in another large program that I am developing.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <cstring>
#include <cstdlib>
#include <sys/types.h>
#include <sys/wait.h>
#include <errno.h>
#include <limits.h>
#include <string>
#include <iostream>
using namespace std;
void processLine (char []);
void readLine(char []);
const int LIMIT = 512;
int main(int argc, char *argv[])
{
char oneLine[LINE_MAX];
readLine(oneLine);
return 0;
}
void readLine(char line[])
{
processLine(line);
//Otherstuff
------------
}
void processLine(char line[])
{
pid_t process;
int child_status;
string input;
cout << "Input: ";
cin >> input;
process = fork();
if(process == 0)
{ // do nothing
}
else
{
//parent
if(input == "quit")
{
printf("Quit command found ! \nExiting ");
for(int i = 0;i < 3;i++)
{
printf(".");
fflush(stdout);
sleep(1);
}
printf("\n");
exit(0);
}
else
{
wait(&child_status);
}
}
}
My goal is simple, When the user enter quit.
I will just display
Quit command found
Exiting ...
And there is a delay of one second between each of these three dots.
However the output that I get is
Quit command found
Exiting . other stuff ..
However, what seems to happen is that the parent process returns and then executes other stuff from the calling function before it continues to print the other two dots. How would I avoid the parent process from doing that ?
Use waitpid() like this:
pid_t childPid;
childPid = fork();
...
int returnStatus;
waitpid(childPid, &returnStatus, 0); // Parent process waits here for child to terminate.
Use it here
if(childPid == 0) // fork succeeded
{
// Do something
exit(0);
}
else // Main (parent) process after fork succeeds
{
int returnStatus;
waitpid(childPid, &returnStatus, 0);
}

How to print using g++ with printf correctly?

I am compiling this code with g++:
#include <pthread.h>
#include <iostream>
#include <cstdlib>
#include <string>
#include <stdio.h>
using namespace std;
#define num_threads 3
#define car_limit 4
pthread_mutex_t mutex; // mutex lock
pthread_t cid; // thread id
pthread_attr_t attr; // thread attrubutes
void *OneCar(void *dir);
void ArriveBridge(int *direction);
void CrossBridge();
void ExitBridge(int *direction);
int main()
{
int dir[3] = {0,1,1};
pthread_mutex_init(&mutex, NULL);
pthread_attr_init(&attr);
//cout<< "Pthread Create" << endl;
printf("Pthread Create\n");
for(int i = 0; i < num_threads; i++)
{
pthread_create(&cid, &attr, OneCar, (void *)&dir[i]);
}
return 0;
}
void ArriveBridge(int *direction)
{
//cout<<"Arrive"<<*direction << endl;
int dr;
if(*direction == 0)
dr=0;
else
dr=1;
printf("Arrive%d", dr);
}
void CrossBridge(int *dir)
{
char d;
if(*dir == 0)
d = 'N';
else
d = 'S';
//cout<<"Crossing Bridge going:"<<d<<endl;
printf("Crossing Bridge going %c", d);
}
void ExitBridge(int *direction)
{
//cout<<"Exit" <<*direction<<endl;
int dr;
if(*direction == 0)
dr=0;
else
dr=1;
printf("Exit%d\n", dr);
}
void *OneCar(void *dir)
{
int *cardir;
cardir = (int *) dir;
//cout<<*cardir;
ArriveBridge(cardir);
CrossBridge(cardir);
ExitBridge(cardir);
return 0;
}
and I am expecting this result printed to the screen:
> Pthread Create
> Arrive0Crossing Bridge going NExit0
> Arrive1Crossing Bridge going SExit1
> Arrive1Crossing Bridge going NExit1
But i get this instead:
Pthread Create
Arrive0Crossing Bridge going NExit0
Why doesnt it print the rest out?
You need to use "pthread_join" in main to wait for all threads to exit before your program terminates. You should also use an array to hold the id of each thread that you create:
pthread_t cid[num_threads]; // thread id`
You'll then want to call join on every thread you create:
for(int i = 0; i < num_threads; i++)
{
pthread_create(&cid[i], &attr, OneCar, (void *)&dir[i]);
}
for(int i = 0; i < num_threads; ++i)
{
pthread_join(cid[i], NULL);
};
Running the modified code now gives:
Pthread Create
Arrive0Crossing Bridge going NExit0
Arrive1Crossing Bridge going SExit1
Arrive1Crossing Bridge going SExit1
Have you tried joining your threads at the end of main? It could be that the program is terminating before the other threads are completely finished.
You missed the newlines ("\n"):
printf("Arrive%d\n", dr);
printf("Crossing Bridge going %c\n", d);
Because of that, the streams are probably not flushed. Additionally, if you don't wait for your threads (pthread_join) your program will exit before the threads could do their work.