Omnet ++ sending message from specific node to other specific node - omnet++

following is my .ned file of the network of 3 nodes
simple computer
{
parameters:
gates:
input in1;
output out1;
input in2;
output out2;
}
//
// TODO documentation
//
network Network
{
#display("bgb=538,302");
submodules:
A: computer {
#display("p=30,88");
}
B: computer {
#display("p=344,96");
}
C: computer {
#display("p=209,199");
}
connections:
A.out1 --> B.in1;
B.out1 --> A.in1;
A.out2 --> C.in1;
C.out1 --> A.in2;
C.out2 --> B.in2;
B.out2 --> C.in2;
}
#include <string.h>
#include <omnetpp.h>
#include <string>
int a2b=8; int b2a=8;
int b2c=2; int c2b=2;
int a2c=5; int c2a=5;
char node='x';
int roundd=0;
char rec='A';
int Amatrix[3][3];
int Bmatrix[3][3];
int Cmatrix[3][3];
class computer: public cSimpleModule
{
public:
virtual void initialize();
virtual void handleMessage(cMessage *msg);
void fill()
{
for(int i=0 ; i<3 ; i++)
{
for(int j=0 ; j<3 ; j++)
{
Amatrix[i][j]=Bmatrix[i][j]=Cmatrix[i][j]=0;
}
}
}
void fillA()
{
Amatrix[0][0]=0;Amatrix[0][1]=a2b;Amatrix[0][2]=a2c;
}
void fillB()
{
Bmatrix[1][0]=a2b;Bmatrix[1][1]=0;Bmatrix[1][2]=b2c;
}
void fillC()
{
Cmatrix[2][0]=a2c;Cmatrix[2][1]=b2c;Cmatrix[2][2]=0;
}
};
//----------------------------------------------------------------------
Define_Module(computer);
void computer::initialize()
{
if ((strcmp("A", getName()) == 0)&&(roundd==0))
{
node='A';
fill();
fillA();fillB(); fillC(); roundd=1;node='A';
cMessage *msg = new cMessage("tictocMsg");
cMessage *ww ; ww=msg;
EV << "sending message from node " << node ;
send(msg, "out1");
cMessage *copy = (cMessage *) msg->dup();
send(copy, "out2");
}
}
void computer::handleMessage(cMessage *msg)
{
if((strcmp("B", getName()) == 0 )&&(roundd=1)&&(node=='A'))
{
rec='B';
EV <<"\n NODE AT WHICH THE MESSAGE IS AT CURRENTLY IS " << rec <<endl;
for(int i=0 ; i<3 ; i++)
{
Bmatrix[0][i]=Amatrix[0][i];
}
}
else if((strcmp("C", getName()) == 0)&&(node=='A')&&(roundd==1))
{
rec='C';
EV <<"\n NODE AT WHICH THE MESSAGE IS AT CURRENTLY IS " << rec <<endl;
for(int i=0 ; i<3 ; i++)
{
Cmatrix[0][i]=Amatrix[0][i];
}
roundd=2;
}
if(roundd==2)
{
if((strcmp("C", getName()) == 0 )){EV << " node c ";}
if((strcmp("B", getName()) == 0 )){EV << " node B ";}
}}
Now in the roundd 2
if(roundd==2)
{
if((strcmp("C", getName()) == 0 )){EV << " node c ";}
if((strcmp("B", getName()) == 0 )){EV << " node B ";}
}}
the first if works where strcmp is "C". but the second if does not. I actually want node B to send two messages to node A and C afterwards i want to send messages from c to A and c to B. Basically at initialize A send two messages, one to B and one to C. Now i want to send message from B to A and B to C
similarly from C to A and C to B how do i do that?

Related

MPI gather doesn't work with customized datatype

I tried two ways for the same issue, one works and the other doesn't. The following version works, returning a value of 4.
int gather_list()
{
mpi::environment env;
mpi::communicator world;
std::srand(time(0) + world.rank());
int my_number = std::rand();
std::vector<int> tmp_vec;
tmp_vec.push_back(my_number);
tmp_vec.push_back(my_number + 1);
if (world.rank() == 0)
{
std::vector<int> all_numbers;
gather(world, &tmp_vec[0], tmp_vec.size(), all_numbers, 0);
std::cout << all_numbers.size() << std::endl;
} else
{
gather(world, &tmp_vec[0], tmp_vec.size(), 0);
}
return 0;
}
The following version doesn't work, returning a value of 2.
class ArchivableVecInt : public std::vector<int>
{
public:
ArchivableVecInt() = default;
explicit ArchivableVecInt(const std::vector<int> &vec)
{
auto base_ptr = static_cast<std::vector<int> *>(this);
*base_ptr = vec;
}
template<class Archiver>
void serialize(Archiver &ar, unsigned int)
{
for (auto i: *this)
{
ar & i;
}
}
protected:
};
int gather_list()
{
mpi::environment env;
mpi::communicator world;
std::srand(time(0) + world.rank());
int my_number = std::rand();
std::vector<int> tmp_vec;
tmp_vec.push_back(my_number);
tmp_vec.push_back(my_number + 1);
ArchivableVecInt my_vec(tmp_vec);
if (world.rank() == 0)
{
std::vector<ArchivableVecInt> all_numbers;
gather(world, my_vec, all_numbers, 0);
for (int proc = 0; proc < world.size(); ++proc)
std::cout << "Process #" << proc << " thought of "
<< all_numbers[proc].size() << std::endl;
} else
{
gather(world, my_vec, 0);
}
return 0;
}
I tried 2 processes, while rank 0 returns a value of 2, rank 1 returns zero. Seems the gather(world, my_vec, 0) didn't work, why?
result as below.
Thanks in advance.
In your second example your receive buffer is a vector<vector<int>> meaning that the data is not contiguous. MPI needs contiguous buffers.

Unhandled exception at 0x006A549C in myApplication.exe: 0xC00000FD: Stack overflow (parameters: 0x00000001, 0x01202FFC)

I am writing a program with C++ that needs to read a CSV file and store it in a binary search tree. But, when the program is reading the file, it fails in the library debugger.jmc.c and in the method void __fastcall __CheckForDebuggerJustMyCode(unsigned char *JMC_flag). Could someone help me? Thanks!
#include <algorithm>
#include <iostream>
#include <ctime>
#include <string>
#include "CSVparser.hpp"
using namespace std;
using namespace std;
struct Bid {
string bidId;
string title;
string fund;
double amount;
Bid() {
amount = 0.0;
}
};
struct Node {
Bid bid;
Node* left;
Node* right;
Node() {
left = nullptr;
right = nullptr;
}
Node(Bid aBid) : Node() {
this->bid = aBid;
}
};
class BinarySearchTree {
private:
Node* root;
void addNode(Node* node, Bid bid);
void inOrder(Node* node);
Node* removeNode(Node* node, string bidId);
public:
BinarySearchTree();
virtual ~BinarySearchTree();
void InOrder();
void Insert(Bid bid);
void Remove(string bidId);
Bid Search(string bidId);
Node* SearchNode(Node* node, string bidId);
};
BinarySearchTree::BinarySearchTree() {
root = nullptr;
}
/**
* Destructor
*/
BinarySearchTree::~BinarySearchTree() {
// recurse from root deleting every node
}
/**
* Traverse the tree in order
*/
void BinarySearchTree::InOrder() {
}
/**
* Insert a bid
*/
void BinarySearchTree::Insert(Bid bid) {
// FIXME (2a) Implement inserting a bid into the tree
if (root == nullptr) {
root = new Node(bid);
}
else {
addNode(root, bid);
}
}
/**
* Remove a bid
*/
void BinarySearchTree::Remove(string bidId) {
// FIXME (4a) Implement removing a bid from the tree
Node* nodePtr = SearchNode(root, bidId);
if (nodePtr == nullptr) {
return;
}
else {
//not yet implemented
}
}
/**
* Search for a bid
*/
Bid BinarySearchTree::Search(string bidId) {
// FIXME (3) Implement searching the tree for a bid
}
void BinarySearchTree::addNode(Node* node, Bid bid) {
// FIXME (2b) Implement inserting a bid into the tree))
//if node is larger than the bid add to the left subtree
if (stoi(node->bid.bidId) > stoi(bid.bidId)) {
if (node->left == nullptr) {
node->left = new Node(bid);
}
else {
addNode(node->left, bid);
}
}
//add to right subtree
else {
if (node->right == nullptr) {
node->right = new Node(bid);
}
else {
addNode(node->right, bid);
}
}
return;
}
void displayBid(Bid bid) {
cout << bid.bidId << ": " << bid.title << " | " << bid.amount << " | "
<< bid.fund << endl;
return;
}
/**
* Load a CSV file containing bids into a container
*
* #param csvPath the path to the CSV file to load
* #return a container holding all the bids read
*/
void loadBids(string csvPath, BinarySearchTree* bst) {
cout << "Loading CSV file " << csvPath << endl;
// initialize the CSV Parser using the given path
csv::Parser file = csv::Parser(csvPath);
try {
for (unsigned int i = 0; i < file.rowCount(); i++) {
// Create a data structure and add to the collection of bids
Bid bid;
bid.bidId = file[i][1];
bid.title = file[i][0];
bid.fund = file[i][8];
bid.amount = strToDouble(file[i][4], '$');
// push this bid to the end
bst->Insert(bid);
}
}
catch (csv::Error& e) {
std::cerr << e.what() << std::endl;
}
}
double strToDouble(string str, char ch) {
str.erase(remove(str.begin(), str.end(), ch), str.end());
return atof(str.c_str());
}
int main(int argc, char* argv[]) {
// process command line arguments
string csvPath, bidKey;
switch (argc) {
case 2:
csvPath = argv[1];
bidKey = "98105";
break;
case 3:
csvPath = argv[1];
bidKey = argv[2];
break;
default:
csvPath = "eBid_Monthly_Sales_Dec_2016.csv";
bidKey = "98105";
}
clock_t ticks;
// Define a binary search tree to hold all bids
BinarySearchTree* bst = nullptr;
Bid bid;
int choice = 0;
while (choice != 9) {
cout << "Menu:" << endl;
cout << " 1. Load Bids" << endl;
cout << " 2. Display All Bids" << endl;
cout << " 3. Find Bid" << endl;
cout << " 4. Remove Bid" << endl;
cout << " 9. Exit" << endl;
cout << "Enter choice: ";
cin >> choice;
switch (choice) {
case 1:
bst = new BinarySearchTree();
ticks = clock();
loadBids("eBid_Monthly_Sales.csv", bst);
//cout << bst->Size() << " bids read" << endl;
// Calculate elapsed time and display result
ticks = clock() - ticks;
cout << "time: " << ticks << " clock ticks" << endl;
cout << "time: " << ticks * 1.0 / CLOCKS_PER_SEC << " seconds" << endl;
break;
case 2:
bst->InOrder();
break;
case 3:
ticks = clock();
bid = bst->Search(bidKey);
ticks = clock() - ticks; // current clock ticks minus starting clock ticks
if (!bid.bidId.empty()) {
displayBid(bid);
}
else {
cout << "Bid Id " << bidKey << " not found." << endl;
}
cout << "time: " << ticks << " clock ticks" << endl;
cout << "time: " << ticks * 1.0 / CLOCKS_PER_SEC << " seconds" << endl;
break;
case 4:
bst->Remove(bidKey);
break;
}
}
cout << "Good bye." << endl;
return 0;
}

My integer insertion program in a chaining transforms integers from 16: (2,4,6,8,10,12,14,875311656,942421548,741355820)

Here is my insert method of a chaining class that I implement, the data type is integer (typedef int TELEM).By displaying the numbers stored, from 16 shows me other values too big
include
typedef int TELEM;
// liste d'éléments de type TELEM
class liste {
public:
liste::liste() : m_nb(0) ,m_tetefile(0)
{
m_tetefile = new TELEM[m_nb+1] ;
}
liste::~liste()
{
m_nb = 0;
delete m_tetefile;
}
bool liste::est_vide() const
{
return m_nb == 0;
}
int liste::taille() const
{
return m_nb;
}
const TELEM& liste::operator[](int i) const
{
assert((i>=1) && (i<=m_nb));
return (m_tetefile[i]);
}
void liste::inserer(const TELEM& e, int i)
{
assert((i>=1) && (i<=m_nb+1));
for (int k = m_nb ; k >= i ; --k)
m_tetefile[k+1] = m_tetefile[k];
m_tetefile[i] = e;
std::cout << e <<std::endl;
std::cout << m_tetefile[i] <<std::endl;
m_nb++;
}
private:
TELEM m_nb ;
TELEM *m_tetefile;
};
std::ostream& operator<<(std::ostream& os, const liste& l)
{
os << '(';
if (!l.est_vide())
os << l[1];
for (int i=2; i<=l.taille(); ++i)
os << ',' << l[i];
os << ')';
return os;
}
from 16 ca gives me this
(2,4,6,8,10,12,14,875311656,942421548,741355820)
instead
(2,4,6,8,10,12,14,16,18,20)

Getting an error - "undefined reference to 'logOn(int, int &)'"

I am working on this program (below) and keep getting the "undefined reference to 'logOn(int, int &)'". It also does this when I am calling the functions for logOn, logOff, and search when they are called. My code is not 100% correct, but I am trying to figure out my error before I can move on with the rest of the project.
#include <iostream>#include <iostream>
int menu(int &);
void logOn(int, int &);
int getUserID(int &);
int getLabNum(int &);
int getStation(int &, int &);
void logOff(int, int &);
void search(int, int &);
int main()
{
int userChoice = 0;
menu(userChoice);
int userID = 0;
int lab[4][6];
if (userChoice == 1)
{
logOn(lab[4][6], userID);
}
else if (userChoice == 2)
{
logOff(lab[4][6], userID);
}
else if (userChoice == 3)
{
search(lab[4][6], userID);
}
return 0;
}
And here are the three functions:
void logOn(int lab[4][6], int &userID)
{
int labNum, station = 0;
getUserID(userID);
getLabNum(labNum);
getStation(station, labNum);
int *lab_ptr = &labNum;
int *station_ptr = &station;
int *user_ptr = &userID;
for (int i = 1; i < 5; i++)
{
std::cout << "Lab " << i << ": ";
if (i == 1)
{
for (int j = 1; j < 6; j++)
{
lab[*lab_ptr][*station_ptr] = {*user_ptr};
}
}
}
}
void logOff(int lab[4][6], int &userID)
{
std::cout << "Please enter your student ID: ";
std::cin >> userID;
std::cout << std::endl;
for(int i = 1; i < 5; i++)
{
for(int j = 1; j < 7; j++)
{
if(lab[i][j] == userID)
{
lab[i][j] = 0;
}
}
}
}
void search(int lab[4][6], int &userID)
{
std::cout << "Please enter the User ID you would like to find: ";
std::cin >> userID;
for(int i = 1; i < 5; i++)
{
if (i == 1)
{
for(int j = 1; j < 6; j++)
{
if(lab[i][j] == userID)
{
std::cout << "This user is in lab " << i << " and at station " << j << std::endl;
return;
}
}
}
etc....
I think it has something to do with the lab[4][6] in the headers, but I saw another program with it and it ran with no problem. Any help would be appreciated!

Converting Infix to Postfix Using Stack

I'm having trouble creating a program that will convert infix to postfix. My code is as follows:
#include <iostream>
#include <string>
#include <sstream>
using namespace std;
#define DEFAULT_SIZE 20
/*
*
*/
class Stack {
char *arr;
int tos, capacity;
public:
//Constructors
Stack();
Stack(int size);
//Destructor
~Stack();
//Methods
void push(char a);
char pop();
int get_size();
bool is_empty();
bool is_full();
void display();
char get_top();
};
Stack::Stack() {
arr = new char[DEFAULT_SIZE];
tos = 0;
capacity = DEFAULT_SIZE;
}
Stack::Stack(int size) {
arr = new char[size];
tos = 0;
capacity = size;
}
Stack::~Stack() {
delete[] arr;
}
void Stack::push(char a) {
if (!is_full())
arr[tos++] = a;
else
cout << "Sorry, the stack is full. Push failed!" << endl;
}
char Stack::pop() {
if (!is_empty())
return arr[--tos];
else {
cout << "Sorry, the stack is empty. Pop failed!" << endl;
return -1;
}
}
char Stack::get_top() {
if (!is_empty())
return arr[tos - 1];
else {
cout << "Sorry, the stack is empty. Pop failed!" << endl;
return 'E';
}
}
int Stack::get_size() {
return tos;
}
bool Stack::is_empty() {
if (tos == 0)
return true;
else
return false;
}
bool Stack::is_full() {
if (tos == capacity)
return true;
else
return false;
}
void Stack::display() {
if (tos == 0)
cout << "The stack is empty" << endl;
else {
for (int i = 0; i<tos;i++)
cout << arr[i] << " ";
cout << endl;
}
}
int main() {
Stack stack(50);
string infix = "(1+3)*2/(6-4)^2";
stringstream ss;
for (char c : infix) {
if ('0' <= c && c <= '9') {
ss << c;
}
else if (c == '(') {
continue;
}
else if (c == ')') {
ss << stack.pop();
stack.pop();
}
else if (c == '^' || c == '*' || c == '/' || c == '+' || c == '-') {
stack.push(c);
}
}
string postfix = ss.str();
cout << postfix;
I know what my issue is, I just dont understand or comprehend how to solve it. This code currently outputs 13+264-2. It needs to output 13+2*64-2^/. I know my issues is with my last else if statement in int main(). I dont understand how to rearrange the operators behind the operands.
Anything in parentheses is passed into the stream correctly, because I can wait until the closing parenthesis is hit to add in the operator. I can't visualize how to make that work for things not in parentheses though. Can anyone offer any advice?

Resources