MPI gather doesn't work with customized datatype - boost

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.

Related

terminate called after throwing an instance of 'std::logic_error' what(): basic_string::_M_construct null not valid Aborted (core dumped)

#include <iostream>
#include <vector>
using namespace std;
class House {
public:
//default constructor
House(string = "no-style", double = 0.0);
//destructor
~House();
//set the style
void setStyle(string style);
//set the cost
void setCost(double cost);
//get the style
string getStyle() const;
//get the cost
double getCost() const;
//overloaded operator: = (assignment)
House& operator = (const House &other);
//overloaded operator: == (comparison)
bool operator == (const House &other);
//overloaded operator: = (assignment)
friend ostream& operator<<(ostream& out, const House& other);
private:
string* pStyle;
double* pCost;
};
//default constructor
House::House(string style, double cost)
{
pStyle = new string{style};
pCost = new double{cost};
}
//destructor
House::~House()
{
if(pStyle != nullptr)
delete pStyle;
if(pCost != nullptr)
delete pCost;
}
//set the style
void House::setStyle(string style)
{
*pStyle = style;
}
//set the cost
void House::setCost(double cost)
{
*pCost = cost;
}
//get the style
string House::getStyle() const
{
return *pStyle;
}
//get the cost
double House::getCost() const
{
return *pCost;
}
//overloaded operator: = (assignment)
House& House::operator = (const House &other)
{
if(pStyle != nullptr)
delete pStyle;
if(pCost != nullptr)
delete pCost;
pStyle = new string{*other.pStyle};
pCost = new double{*other.pCost};
return *this;
}
//overloaded operator: == (comparison)
bool House::operator == (const House &other)
{
return (*pStyle == *other.pStyle && *pCost == *other.pCost);
}
ostream& operator<<(ostream& out, const House& other)
{
out<<"House " << other.getStyle() <<" costs:" << other.getCost()<<" dollars."<<endl;
return out;
}
void showHouses(vector<House>& houses, int houseCount) {
cout << endl << "Here are your houses: " << endl;
for(int i=0; i<houseCount; i++)
{
cout << houses.at(i);
}
}
int main() {
vector<House> houses;
House currentHouse;
int houseCount = 0; // number of houses
string style;
double cost;
int num;
cout << "Here is the currentHouse: " << currentHouse << endl;
do{
cout<<"How many houses do you want to build? (must be at least 3) ";
cin >> houseCount;
}while(houseCount<3);
cout << endl;
for(int i=0; i<houseCount; i++)
{
cout<<"What is the style for house "<<i+1<<"? ";
cin >> style;
cout<<"What is the cost for house "<<i+1<<"? ";
cin >> cost;
currentHouse.setStyle(style);
currentHouse.setCost(cost);
houses.push_back(currentHouse);
cout<<houses.at(i);
}
showHouses(houses, houseCount);
cout << endl << "Which house do you want to change? ";
cin >>num;
cout<<"What is the new style? ";
cin >> style;
cout<<"What is the new cost? ";
cin >> cost;
currentHouse = House(style, cost);
if(houses.at(num) == currentHouse)
cout<<"The new house is the same as the old house."<<endl;
else
cout<<"The houses are different."<<endl;
cout << "Copying new house to the old house ..." << endl;
houses.at(num) = currentHouse;
showHouses(houses, houseCount);
return 0;
}
The code is not working when put value of houseCount greater than 1. I have received the following error message while execute the code:
Here is the currentHouse: House no-style costs:0 dollars.
How many houses do you want to build? (must be at least 3) 3
What is the style for house 1? e
What is the cost for house 1? 2
What is the style for house 2? f
What is the cost for house 2? 5
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_M_construct null not valid
Aborted (core dumped)

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)

C++11 Lambda custom comparator slows down sorting

Custom lambda Comparator slower than normal function c++11. I experienced this a few times. But, Still Couldn't figure out the reason why this is so. Does anyone experience this and know the cause behind it?
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 1;
vector<int> v(N);
vector<int> sorted(N);
map<int, int> counts;
long long start;
void startClock() {
start = clock();
}
void stopClock() {
cout << float( clock () - start ) / CLOCKS_PER_SEC << endl;
}
void copyOriginal() {
for (int i = 0; i < N; ++i)
sorted[i] = v[i];
}
void sortWLambda(map<int, int>& counts) {
cout << "sorting with lambda" << endl;
sort(sorted.begin(), sorted.end(), [counts](const int& a, const int& b) {
if (*counts.find(a) != *counts.find(b)) return *counts.find(a) < *counts.find(b);
return a < b;
});
}
bool comparator(const int& a, const int& b) {
if (*counts.find(a) != *counts.find(b)) return *counts.find(a) < *counts.find(b);
return a < b;
}
void sortWoLambda() {
cout << "sorting w/o lambda" << endl;
sort(sorted.begin(), sorted.end(), comparator);
}
int main() {
for (int i = 0; i < N; ++i) {
int num = rand() % 1234;
counts[num]++;
v[i] = num;
}
copyOriginal();
startClock();
sortWLambda(counts);
stopClock();
copyOriginal();
startClock();
sortWoLambda();
stopClock();
return 0;
}
sorting with lambda 6.28 sec
sorting w/o lambda 0.17 sec
pass by reference made the difference for lambda.
I tried this..
sort(sorted.begin(), sorted.end(), [&counts](const int& a, const int& b) {
if (*counts.find(a) != *counts.find(b)) return *counts.find(a) < *counts.find(b);
return a < b;
});
now this takes same time as normal function
Passing by constant reference in the lambda capture list this helped me too!

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?

Run-time error: Debug Assertion Failed when using Classes

I am writing code for an assignment in my college C++ class, the program is meant to create a dynamically allocated array using a class. I am getting a debug assertion failed error when my objects go out of scope, because I am double deleting the pointer to the newly created array. I have no idea where this happens because I only use delete[] twice in the entire class. Here is my source:
#include
using namespace std;
//classes
class IntArray {
private:
int * begin;
int arrSize;
//returns true if n is a valid index inside the array
bool inBounds(int n) {
if (n < 0 || n >= arrSize) {
return false;
}
return true;
}
public:
//default constructor
IntArray() {
begin = new int[1];
begin[0] = 0;
arrSize = 1;
}
//call constructor
IntArray(int n) {
arrSize = n;
begin = new int[n];
for (int i = 0; i < n; i++) {
begin[i] = 0;
}
}
//copy constructor
IntArray(IntArray * in) {
arrSize = in->size();
begin = new int[arrSize];
for (int i = 0; i < arrSize; i++) {
begin[i] = in->begin[i];
}
}
//call constructor for arrays
IntArray(int in[],int s) {
arrSize = s;
begin = new int[arrSize];
for (int i = 0; i < arrSize; i++) {
begin[i] = in[i];
}
}
//method functions
//returns the size of the array
int size() {
return arrSize;
}
//returns the value of the element at position n
int get(int n) {
if (inBounds(n)) {
return begin[n];
}
cout << "Error: Invalid bound entered, returning value at index 0" << endl;
return begin[0];
}
//function that sets the value at position n to the value of input
void put(int n, int input) {
if (inBounds(n)) {
begin[n] = input;
}
else {
cout << "Error: invalid bound entered, no value changed" << endl;
}
}
//overloaded operators
//sets the value at the position n to input value
int & operator[](int n) {
if (inBounds(n)) {
return begin[n];
}
cout << "Error: invalid bound entered, returning index 0" << endl;
return begin[0];
}
//operator = allows copying of one IntArray to another
IntArray & operator=(IntArray source) {
arrSize = source.size();
delete[] begin;
begin = 0;
begin = new int[arrSize];
for (int i = 0; i < arrSize; i++) {
begin[i] = source[i];
}
return *this;
}
//destructor
~IntArray() {
//deallocate memory used by array
if (begin != 0) {
delete[] begin;
}
}
};
int main() {
IntArray arr1(10);
for (int i = 0; i < 10; i++) {
arr1[i] = 11 * i;
cout << arr1[i] << " ";
}
cout << endl;
for (int i = 0; i < 10; i++) {
cout << arr1.get(i) << " ";
}
cout << endl;
arr1.put(6, 16);
arr1.put(4, 10);
IntArray arr2(arr1);
IntArray arr3 = arr1;
for (int i = 0; i < 10; i++) {
cout << arr3.get(i) << " ";
}
cout << endl;
for (int i = 0; i < 10; i++) {
cout << arr2.get(i) << " ";
}
cout << endl;
system("PAUSE");
return 0;
}
And a screenshot of the exact error:
Thanks to #heavyd I realized that the error arose from an improper construction of the class due to a logic error in my class definition. The problem was in the way I was copying data to the new class (improperly) and the way that my copy constructor worked, as well as the return type of one of my member functions.

Resources