C++ use TBB and MPI - ERROR

1

Could you please help me with a code? I have two projects for calculation of parallel computing, which use firstly intel TBB in the first project and MPI in the second project. Unfortunately, the first project in TBB debug itself and it does not show in VS2013 any mistakes, but application crashes on the server and the second one in MPI is not possible to debug. It writes following mistake: Error 1 error RC1110: Could not open MPI.rc. Could anyone help me, please? I am the beginner in this field and I do not know, where the mistake is in source code. I saved the code here: http://www.happybaby.funsite.cz/uploads/Parallel_programming_PPR.zip. Thank you for your advice in advance.

Tom

For Intel TBB - class Calculation:

#include "Calculation.h"

using namespace std;
/*
* Constructor
* @param dbPath - database file
* @param typeInterpolation - type interpolation
* @param useTBB - true to use TBB for parallel computation
*/
Calculation::Calculation(char* inDbPath, string inTypeInterpolation, bool inUseTBB){
    dbPath = inDbPath;
    typeInterpolation = inTypeInterpolation;
    useTBB = inUseTBB;
}

/*
* Destructor
*/
Calculation::~Calculation()
{
}

/*
* Run the calculation cubic interpolation
*/
void Calculation::run(){

    Database database;
    database.open(dbPath);
    vector<SSubjectSegment> segments = database.getSubjects();
    const int sizeMask = 254;
    tbb::mutex instanceMutex;

    for (size_t i = 0; i < segments.size(); i++){

        IGlucoseLevels* level = database.getGlucoseLevels(segments[i].segmentId);
        CubicSplineApprox* cubic = new CubicSplineApprox(level);

        if (useTBB){

            tbb::tick_count tbbProcessingStart = tbb::tick_count::now();
            std::cout << "# Proces: " << "0" << std::endl;
            std::cout << "  Message: " << "Calculation using Intel Threading Building Blocks started." << std::endl;
            //calculate of the given equations for all ist values from database, use TBB library for parallelism
            tbb::parallel_for(0, sizeMask, 1, [&](int j) {


                TApproximationParams* params = new TApproximationParams();
                params->ApproximationMethod = 2;
                params->Mask = j;
                cubic->Approximate(params);

                // Print statistics
                instanceMutex.lock();
                cubic->printStatistics();
                instanceMutex.unlock();
            });
        }
        else {
            for (char j = 1; j < 254; j++) {
            TApproximationParams* params = new TApproximationParams();
            params->ApproximationMethod = 2;
            params->Mask = j;
            cubic->Approximate(params);
            cubic->printStatistics();
            }
        }
    }
    // close connection to database
    database.close();
}

For Intel TBB - class CubicSplineApprox:

#include "CubicSplineApprox.h"

/*
* Constructor derived class from base class CommonApprox
*/
CubicSplineApprox::CubicSplineApprox(IGlucoseLevels *levels):CCommonApprox(levels){
}

/*
* Destructor
*/
CubicSplineApprox::~CubicSplineApprox()
{
}

/*
* Instance derived classes IApproximatedGlucoseLevels, calling method Approximate
*/
HRESULT IfaceCalling CubicSplineApprox::Approximate(TApproximationParams *params) {
    segmentId = params->segmentId;
    subjectId = params->subjectId;
    lastUsedMask = params->Mask;
    size_t count = 0;
    TGlucoseLevel* levels;
    CCommonApprox::mEnumeratedLevels->GetLevelsCount(&count);
    CCommonApprox::mEnumeratedLevels->GetLevels(&levels);
    std::vector<double> xVector;
    std::vector<double> yVector;
    std::vector<double> nonXVector;
    std::vector<double> nonYVector;

    /*
    * Creating vectors datetime and measured values by mask for calculation
    * @param x vector of interpolated parameters datetime values by mask
    * @param y vector of interpolated parameters measured values ist by mask
    */
    for (size_t i = 0; i < count; i++){
        if (isInterpolated(i, params->Mask)){
            xVector.push_back(levels[i].datetime);
            yVector.push_back(levels[i].level);
        }
        else {
            nonXVector.push_back(levels[i].datetime);
            nonYVector.push_back(levels[i].level);
        }
    }

    // Initialize spline - interpolation
    spline.set_points(xVector, yVector, true);

    // Included measurements are part of the spline function
    // Absolute errors
    absoluteIncluded.AverageError = 0;
    absoluteIncluded.MaximalError = 0;
    absoluteIncluded.MinimalError = 0;
    absoluteIncluded.StandardDeviation = 0;
    absoluteIncluded.Median = 0;
    absoluteIncluded.FirstQuartil = 0;
    absoluteIncluded.ThirdQuartil = 0;
    // Relative errors
    relativeIncluded.AverageError = 0;
    relativeIncluded.MaximalError = 0;
    relativeIncluded.MinimalError = 0;
    relativeIncluded.StandardDeviation = 0; 
    relativeIncluded.Median = 0;
    relativeIncluded.FirstQuartil = 0;
    relativeIncluded.ThirdQuartil = 0;

    // All measurement will have minimal error 0, because at leas one point is in the interpolation method
    absolute.MinimalError = 0;
    relative.MinimalError = 0;

    // Definitions limit parameters for statistics and vector statistic errors
    absoluteExcluded.MinimalError = 100000000; //todo - find some const
    absoluteExcluded.MaximalError = 0;
    relativeExcluded.MinimalError = 100000000; //todo - find some const
    relativeExcluded.MaximalError = 0;
    absolute.MaximalError = 0;
    relative.MaximalError = 0;
    std::vector<double> absoluteErr;
    std::vector<double> relativeErr;
    double absoluteSum = 0;
    double absoluteQuadSum = 0;
    double relativeSum = 0;
    double relativeQuadSum = 0;

    /*
    * Calculate statistics interpolated values, absolute error and relative error
    * @param ∆x = x0 - x, absolute error is difference between absolute value and interpolated value 
    * @param  δr = ∆X / Xo, relative error is quotient between absolute error and value of thing measured
    *
    */
    for (size_t i = 0; i < nonXVector.size(); i++){
        double interVal = spline(nonXVector[i]);
        double measVal = nonYVector[i];
        double absErr = std::abs(nonYVector[i] - interVal);
        double relErr = measVal == 0 ? 0 : std::abs(absErr / measVal);
        absoluteErr.push_back(absErr);
        absoluteSum += absErr;
        absoluteQuadSum += absErr * absErr;
        relativeErr.push_back(relErr);
        relativeSum += relErr;
        relativeQuadSum += relErr * relErr;
        if (absoluteExcluded.MinimalError > absErr)
            absoluteExcluded.MinimalError = absErr;
        if (absoluteExcluded.MaximalError < absErr)
            absoluteExcluded.MaximalError = absErr;
        if (absolute.MaximalError < absErr)
            absolute.MaximalError = absErr;
        if (relativeExcluded.MinimalError > relErr && measVal != 0)
            relativeExcluded.MinimalError = relErr;
        if (relativeExcluded.MaximalError < relErr)
            relativeExcluded.MaximalError = relErr;
        if (relative.MaximalError < relErr)
            relative.MaximalError = relErr;
    }
    // Calculate average errors
    absoluteExcluded.AverageError = absoluteSum / absoluteErr.size();
    absolute.AverageError = absoluteSum / (xVector.size() + nonXVector.size());
    relativeExcluded.AverageError = relativeSum / relativeErr.size();
    relative.AverageError = relativeSum / (xVector.size() + nonXVector.size());

    // Calculate standard deviation errors
    absoluteExcluded.StandardDeviation = (absoluteQuadSum - 2 * absoluteExcluded.AverageError * absoluteSum) / absoluteErr.size() + absoluteExcluded.AverageError * absoluteExcluded.AverageError;
    relativeExcluded.StandardDeviation = (relativeQuadSum - 2 * relativeExcluded.AverageError * relativeSum) / relativeErr.size() + relativeExcluded.AverageError * relativeExcluded.AverageError;
    absolute.StandardDeviation = (absoluteQuadSum - 2 * absolute.AverageError * absoluteSum) / (xVector.size() + nonXVector.size()) + absolute.AverageError * absolute.AverageError;
    relative.StandardDeviation = (relativeQuadSum - 2 * relative.AverageError * relativeSum) / (xVector.size() + nonXVector.size()) + relative.AverageError * relative.AverageError;

    // Calculate median, first quartile and third quartile
    std::sort(absoluteErr.begin(), absoluteErr.end());
    std::sort(relativeErr.begin(), relativeErr.end());
    int calcFromTwo = absoluteErr.size() % 2;
    int indexOfMedian = absoluteErr.size() / 2;
    int indexFirstQuartil = indexOfMedian / 2;
    int indexOfThirdQuartil = indexOfMedian + indexFirstQuartil;
    absoluteExcluded.Median = calcFromTwo > 0 ? (absoluteErr[indexOfMedian] + absoluteErr[indexOfMedian + 1]) / 2 : absoluteErr[indexOfMedian];
    absoluteExcluded.FirstQuartil = absoluteErr[indexFirstQuartil]; // it is not clear what to do if median are two numbers!
    absoluteExcluded.ThirdQuartil = absoluteErr[indexOfThirdQuartil]; // it is not clear what to do if median are two numbers!
    relativeExcluded.Median = calcFromTwo > 0 ? (relativeErr[indexOfMedian] + relativeErr[indexOfMedian + 1]) / 2 : relativeErr[indexOfMedian];
    relativeExcluded.FirstQuartil = relativeErr[indexFirstQuartil]; // it is not clear what to do if median are two numbers!
    relativeExcluded.ThirdQuartil = relativeErr[indexOfThirdQuartil]; // it is not clear what to do if median are two numbers!

    // Calculate median for all data
    calcFromTwo = (xVector.size() + nonXVector.size()) % 2;
    indexOfMedian = (xVector.size() + nonXVector.size()) / 2;
    indexFirstQuartil = indexOfMedian / 2;
    indexOfThirdQuartil = indexOfMedian + indexFirstQuartil;
    absolute.Median = indexOfMedian < xVector.size() ? 0 : calcFromTwo > 0 ? (absoluteErr[indexOfMedian - xVector.size()] + absoluteErr[indexOfMedian - xVector.size() + 1]) / 2 : absoluteErr[indexOfMedian - xVector.size()];
    absolute.FirstQuartil = indexFirstQuartil < xVector.size()? 0: absoluteErr[indexFirstQuartil - xVector.size()];
    absolute.ThirdQuartil = indexOfThirdQuartil < xVector.size() ? 0 : absoluteErr[indexOfThirdQuartil - xVector.size()];
    relative.Median = indexOfMedian < xVector.size() ? 0 : calcFromTwo > 0 ? (relativeErr[indexOfMedian - xVector.size()] + relativeErr[indexOfMedian - xVector.size() + 1]) / 2 : relativeErr[indexOfMedian - xVector.size()];
    relative.FirstQuartil = indexFirstQuartil < xVector.size() ? 0 : relativeErr[indexFirstQuartil - xVector.size()];
    relative.ThirdQuartil = indexOfThirdQuartil < xVector.size() ? 0 : relativeErr[indexOfThirdQuartil - xVector.size()];

    return S_OK;
}

/*
* Method print statistics data
*/
void CubicSplineApprox::printStatistics(){
    std::cout << subjectId << ";" << segmentId << ";" << lastUsedMask << ";" <<\
        absolute.MinimalError << ";" << absolute.AverageError << ";" << absolute.MaximalError << ";" << absolute.Median << ";" << absolute.FirstQuartil << ";" << absolute.ThirdQuartil << ";" << absolute.StandardDeviation << \
        absoluteIncluded.MinimalError << ";" << absoluteIncluded.AverageError << ";" << absoluteIncluded.MaximalError << ";" << absoluteIncluded.Median << ";" << absoluteIncluded.FirstQuartil << ";" << absoluteIncluded.ThirdQuartil << ";" << absoluteIncluded.StandardDeviation << \
        absoluteExcluded.MinimalError << ";" << absoluteExcluded.AverageError << ";" << absoluteExcluded.MaximalError << ";" << absoluteExcluded.Median << ";" << absoluteExcluded.FirstQuartil << ";" << absoluteExcluded.ThirdQuartil << ";" << absoluteExcluded.StandardDeviation << std::endl;
}

/*
* Instance derived classes IApproximatedGlucoseLevels, calling method GetLevels
*/
HRESULT IfaceCalling CubicSplineApprox::GetLevels(floattype desiredtime, floattype stepping, size_t count, floattype *levels, size_t *filled, size_t derivationorder){
    return S_OK;
}


1>Build succeeded.
1>
1>Time Elapsed 00:00:17.22
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

If running aplication write error - 0xc000007b.

Error in TBB project

For MPI - class Calculation:

#include "Calculation.h"

using namespace std;

/*
* Constructor
* @param dbPath - database file
* @param typeInterpolation - type interpolation
* @param useTBB - true to use TBB for parallel computation
*/
Calculation::Calculation(char* inDbPath, string inTypeInterpolation, bool inUseTBB){
    dbPath = inDbPath;
    typeInterpolation = inTypeInterpolation;
    useTBB = inUseTBB;
}

/*
* Destructor
*/
Calculation::~Calculation()
{
}

/*
* Convert data vector to data array
* @remark Creates new memory allocation for result array
*/
floattype* Calculation::convert_to_data(std::vector<TGlucoseLevel> data_vector, int& data_array_size){
    int size = data_vector.size();
    floattype* data = (floattype*)malloc(sizeof(floattype)*size*2);
    for (int i = 0; i < size; i++){
        data[i*2]=data_vector[i].datetime;
        data[i * 2 + 1] = data_vector[i].level;
    }
    return data;
}

/*
* Convert data array to data levels
* @remark Creates new memory allocation for result array
*/
CGlucoseLevels*  Calculation::convert_array_to_levels(double* data_array, int data_array_size){
    CGlucoseLevels* levels = new CGlucoseLevels();
    // iterate the records
    for (int i = 0; i < (data_array_size / 2); i++){
        TGlucoseLevel* newLevel = new TGlucoseLevel();
        newLevel->datetime = data_array[i];
        newLevel->level = data_array[i + 1];
        levels->AddValue(*newLevel);
    }
    return levels;
}

/*
* Send segment id to other process
*/
void  Calculation::send_segment_id(int slave_id, int segment_id){
    int callResult = MPI_Send(&segment_id, 1, MPI_INT, slave_id, DP_SENDRECEIVE_VALUE, MPI_COMM_WORLD);
    if (callResult != MPI_SUCCESS) {
        lastError = "Unable to send segment id to other process";
    }
}

/*
* Receive segment id from main process
*/
int  Calculation::receive_segment_id(){
    int result = 0;
    MPI_Status rcvStatus;
    int callResult = MPI_Recv(&result, 1, MPI_INT, DP_MAIN_PRC_ID, DP_SENDRECEIVE_VALUE, MPI_COMM_WORLD, &rcvStatus);
    if (callResult != MPI_SUCCESS) {
        lastError = "Unable to receive segment id from main process";
        return result;
    }
    return result;
}

/*
* Send subject id to other process
*/
void  Calculation::send_subject_id(int slave_id, int subject_id){
    int callResult = MPI_Send(&subject_id, 1, MPI_INT, slave_id, DP_SENDRECEIVE_VALUE, MPI_COMM_WORLD);
    if (callResult != MPI_SUCCESS) {
        lastError = "Unable to send subject id to other process";
    }
}

/*
* Receive subject id from main process
*/
int  Calculation::receive_subject_id(){
    int result = 0;
    MPI_Status rcvStatus;
    int callResult = MPI_Recv(&result, 1, MPI_INT, DP_MAIN_PRC_ID, DP_SENDRECEIVE_VALUE, MPI_COMM_WORLD, &rcvStatus);
    if (callResult != MPI_SUCCESS) {
        lastError = "Unable to receive subject id from main process";
        return result;
    }
    return result;
}

/*
* Send mask to other process
*/
void  Calculation::send_mask(int slave_id, masktype mask){
    int callResult = MPI_Send(&mask, 1, MPI_CHAR, slave_id, DP_SENDRECEIVE_VALUE, MPI_COMM_WORLD);
    if (callResult != MPI_SUCCESS) {
        lastError = "Unable to send mask to other process";
    }
}

/*
* Receive mask from main process
*/
masktype Calculation::receive_mask(){
    masktype result = '\0';
    MPI_Status rcvStatus;
    int callResult = MPI_Recv(&result, 1, MPI_CHAR, DP_MAIN_PRC_ID, DP_SENDRECEIVE_VALUE, MPI_COMM_WORLD, &rcvStatus);
    if (callResult != MPI_SUCCESS) {
        lastError = "Unable to receive mask from main process";
        return result;
    }
    return result;
}

/*
* Send data length and data to other process
*/
void  Calculation::send_data(int slave_id, double*  data_array, int data_array_size){
    int callResult = MPI_Send(&data_array_size, 1, MPI_INT, slave_id, DP_SENDRECEIVE_VALUE, MPI_COMM_WORLD);
    if (callResult != MPI_SUCCESS) {
        lastError = "Unable to send data length to other process";
        return;
    }
    callResult = MPI_Send(data_array, data_array_size, MPI_DOUBLE, slave_id, DP_SENDRECEIVE_ARRAY, MPI_COMM_WORLD);
    if (callResult != MPI_SUCCESS) {
        lastError = "Unable to send data to other process";
    }
}

/*
* Receive data length and data from main process
*/
double*  Calculation::receive_data_array(int& data_array_size){
    MPI_Status rcvStatus;
    int dataSize = 0;
    int callResult = MPI_Recv(&dataSize, 1, MPI_INT, DP_MAIN_PRC_ID, DP_SENDRECEIVE_VALUE, MPI_COMM_WORLD, &rcvStatus);
    if (callResult != MPI_SUCCESS) {
        lastError = "Unable to receive source data size value from main process";
        return nullptr;
    }
    double* result = new double[dataSize];
    callResult = MPI_Recv(result, dataSize, MPI_DOUBLE, DP_MAIN_PRC_ID, DP_SENDRECEIVE_ARRAY, MPI_COMM_WORLD, &rcvStatus);
    if (callResult != MPI_SUCCESS) {
        lastError = "Unable to receive source data from main process";
        data_array_size = 0;
        return nullptr;
    }
    data_array_size = dataSize;
    return result;
}

/*
* Send result size value and data from main process
*/
void  Calculation::send_result(double* result, int result_size){
    int callResult = MPI_Send(&result_size, 1, MPI_INT, DP_MAIN_PRC_ID, DP_SENDRECEIVE_VALUE, MPI_COMM_WORLD);
    if (callResult != MPI_SUCCESS) {
        lastError = "Unable to send result size to main process";
        return;
    }
    callResult = MPI_Send(result, result_size, MPI_DOUBLE, DP_MAIN_PRC_ID, DP_SENDRECEIVE_ARRAY, MPI_COMM_WORLD);
    if (callResult != MPI_SUCCESS) {
        lastError = "Unable to send result to main process";
    }
}

/*
* Receive result size value and data from other process
*/
double*  Calculation::receive_result(int& slave_id, int& result_size){
    MPI_Status rcvStatus;
    int resultDataSize = 0;
    int callResult = MPI_Recv(&resultDataSize, 1, MPI_INT, MPI_ANY_SOURCE, DP_SENDRECEIVE_VALUE, MPI_COMM_WORLD, &rcvStatus);
    if (callResult != MPI_SUCCESS) {
        lastError = "Unable to receive result size value from other process";
        slave_id = -1;
        return nullptr;
    }
    slave_id = rcvStatus.MPI_SOURCE;
    double* result = new double[resultDataSize];
    callResult = MPI_Recv(result, resultDataSize, MPI_DOUBLE, slave_id, DP_SENDRECEIVE_ARRAY, MPI_COMM_WORLD, &rcvStatus);
    if (callResult != MPI_SUCCESS) {
        lastError = "Unable to receive result data from other process";
        result_size = 0;
        slave_id = -1;
        return nullptr;
    }
    result_size = resultDataSize;
    return result;
}

/*
* Method print statistics data
*/
void  Calculation::print_result_data(int segment_id, int subject_id, masktype mask, double* result_array, int result_array_size){
    if (result_array_size != 21){
        lastError = "Unexpected size of result!";
        return;
    }
    std::cout << subject_id << ";" << segment_id << ";" << mask << ";" << \
        result_array[0] << ";" << result_array[1] << ";" << result_array[2] << ";" << result_array[3] << ";" << result_array[4] << ";" << result_array[5] << ";" << result_array[6] << \
        result_array[7] << ";" << result_array[8] << ";" << result_array[9] << ";" << result_array[10] << ";" << result_array[11] << ";" << result_array[12] << ";" << result_array[13] << \
        result_array[14] << ";" << result_array[15] << ";" << result_array[16] << ";" << result_array[17] << ";" << result_array[18] << ";" << result_array[19] << ";" << result_array[20] << std::endl;
}


/*
* Run the calculation cubic interpolation
*/
void Calculation::run(int argc, char** argv){

    Database database;
    const int sizeMask = 254;
    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &numprocs); 
    MPI_Comm_rank(MPI_COMM_WORLD, &procid);


    // MASTER PROCESS CODE
    if (procid == 0) {
        int* segmentMap = new int[numprocs];
        int* subjectMap = new int[numprocs];
        masktype* maskMap = new masktype[numprocs];

        int slave_id = 0;
        database.open(dbPath);
        vector<SSubjectSegment> segments = database.getSubjects();
        for (size_t i = 0; i < segments.size(); i++){
            int segment_id = segments[i].segmentId;
            int subject_id = segments[i].subjectId;
            std::vector<TGlucoseLevel> data_vector = database.getMeasuredValues(segment_id);
            int data_array_size = 0;
            floattype* data_array = convert_to_data(data_vector, data_array_size);
            int result_array_size = 0;
            double* result_array;
            masktype mask = 1;
            int active_proc = 0;
            for (slave_id = 1; slave_id < numprocs; slave_id++)
            {
                segmentMap[slave_id] = segment_id;
                send_segment_id(slave_id, segment_id);
                subjectMap[slave_id] = subject_id;
                send_subject_id(slave_id, subject_id);
                send_data(slave_id, data_array, data_array_size);
                maskMap[slave_id] = mask;
                send_mask(slave_id, mask++);
                active_proc++;
            }
            while (active_proc > 0)
            {
                result_array = receive_result(slave_id, result_array_size);
                print_result_data(segmentMap[slave_id], subjectMap[slave_id], maskMap[slave_id], result_array, result_array_size);
                if (mask<255)
                {
                    maskMap[slave_id] = mask;
                    send_mask(slave_id, mask++);
                }
                else
                {
                    maskMap[slave_id] = 0;
                    send_mask(slave_id, 0);
                    active_proc--;
                }
            }
        }
        for (slave_id = 1; slave_id < numprocs; slave_id++)
        {
            segmentMap[slave_id] = 0;
            send_segment_id(slave_id, 0);
            subjectMap[slave_id] = 0;
            send_subject_id(slave_id, 0);
        }
        database.close();
    }
    else
    {
        int segment_id = receive_segment_id();
        int subject_id = receive_subject_id();

        while (segment_id>0)
        {
            int data_array_size;
            floattype* data_array = receive_data_array(data_array_size);
            IGlucoseLevels* level = convert_array_to_levels(data_array, data_array_size);
            masktype mask = receive_mask();
            CubicSplineApprox* cubic = new CubicSplineApprox(level);

            while (mask > 0)
            {
                TApproximationParams* params = new TApproximationParams();
                params->ApproximationMethod = 2;
                params->Mask = mask;
                cubic->Approximate(params);
                int result_size = 0;
                double* result = cubic->getStatistics(result_size);
                send_result(result, result_size);
                mask = receive_mask();
            }
            segment_id = receive_segment_id();
            subject_id = receive_subject_id();
        }
    }
    MPI_Finalize();
}

If debugging aplication write error -

1>Build FAILED.
1>
1>Time Elapsed 00:00:11.97
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Error 19 error RC1110: could not open MPI.rc D:\ ...\POC\PPR\MPI\RC MPI

c++
c++11
compiler-errors
mpi
tbb
asked on Stack Overflow Feb 4, 2017 by TomDark • edited Feb 5, 2017 by TomDark

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0