HiveBrain v1.2.0
Get Started
← Back to all entries
patterncppModerate

Eratosthenes sieve and MPI

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
andmpisieveeratosthenes

Problem

I wrote this sieve of Eratosthenes with MPI, but I'm not sure if it's good enough. Should I use MPI_Scatter and MPI_Gather instead of collecting arrays of separate processes in the root process?

Also, I'm not sure if I call

printArray(myArray, (N/size)-1);


right, where myArray is an array of pointers. GCC gives a warning at this point.

#include "mpi.h"
#include 
#include 
#include 
#include 

#define N 60

int main(int argc, char *argv[])
{
long timeCPU;
int rank, size, k, i, v, n, scatterSize;
int **tmpArray, *myArray, firstElement, lastElement;

MPI_Init(&argc,&argv);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);

if(N%size != 0)
{
    MPI_Finalize();
    printf("ERROR!");
    exit(0);
}

firstElement = (rank*N)/size;
lastElement = floor(((rank+1)*N)/size);
myArray = (int*) (malloc(((N/size)-1)*sizeof(int)));

for(i=0, v=firstElement+2; i k)
        return array[i];
}
return -1;
}

void markMultiples(int k, int *array, int n)
{
int i;

for (i=0; i<=n; i++)
{
    if(array[i] % k == 0 && array[i] != k)
    {
        array[i] = -1;
    }
}
}

void printArray(int *array, int n)
{
int i;

for(i=0; i<=n; i++)
{
    printf("array[%d] = %d\n", i, array[i]);
}
}

Solution

Since you tagged this question c++ I assume you would like a C++ approach also.

I would suggest using std::vector rather than an int* and malloc. Using the vector will give you a number of useful advantages over a normal pointer, for example, memory management is greatly simplified, and there is no need to worry about how big an int is. With vector, the order of all elements is guaranteed to be contiguous.

#include 
#include 
#include 
#include 

int nextNumber(int k, const std::vector &array, int n)
{
    std::vector::iterator i = std::find_if(array.begin(), array.begin() + n, std::bind2nd(std::greater(), k));

    return (i == array.end() ? -1 : *i);
}

bool isMultiple(int a, int b)
{
    return (a % k == 0) && (a != k);
}

void markMultiples(int k, std::vector &array, int n)
{
    std::replace_if(array.begin(), array.begin() + n, std::bind2nd(std::ptr_fun(isMultiple), k), -1);
}

void printArray(const std::vector &array)
{
    for(int i = 0; i < array.size(); i++)
        std::cout << "array[" << i << "] = " << array[i] << std::endl;
}


Disclaimer:

I am not very good at C++, so you may want to take this advice with a teaspoon of salt.

Code Snippets

#include <algorithm>
#include <functional>
#include <iostream>
#include <vector>

int nextNumber(int k, const std::vector<int> &array, int n)
{
    std::vector<int>::iterator i = std::find_if(array.begin(), array.begin() + n, std::bind2nd(std::greater<int>(), k));

    return (i == array.end() ? -1 : *i);
}

bool isMultiple(int a, int b)
{
    return (a % k == 0) && (a != k);
}

void markMultiples(int k, std::vector<int> &array, int n)
{
    std::replace_if(array.begin(), array.begin() + n, std::bind2nd(std::ptr_fun(isMultiple), k), -1);
}


void printArray(const std::vector<int> &array)
{
    for(int i = 0; i < array.size(); i++)
        std::cout << "array[" << i << "] = " << array[i] << std::endl;
}

Context

StackExchange Code Review Q#683, answer score: 11

Revisions (0)

No revisions yet.