Member 11638763 Ответов: 1

C++ с использованием MPI и TBB


Привет,
Не могли бы вы пожалуйста помочь мне с кодом? У меня есть два проекта для расчета параллельных вычислений, которые используют, во-первых, intel TBB в первом проекте и MPI во втором проекте. К сожалению, первый проект в TBB отлаживается сам и не показывает в VS2013 никаких ошибок, но приложение вылетает на сервере, а второй в MPI отлаживать невозможно. Он пишет следующую ошибку: Ошибка 1 ошибка RC1110: не удалось открыть MPI. rc. кто-нибудь может мне помочь, пожалуйста? Я новичок в этой области и не знаю, где ошибка в исходном коде. Я сохранил код здесь:
http://www.happybaby.funsite.cz/uploads/Parallel_programming_PPR.zip.
Заранее благодарю вас за совет.

Том

Что я уже пробовал:

I have two projects for calculation of parallel computing, which use firstly intel TBB in the first project and MPI in the second project.

Richard MacCutchan

Вторая ошибка очевидна: компилятор ресурсов не может найти файл. Так что в этом случае приложение еще даже не построено. Первый может быть любым, но вам нужно использовать свой отладчик, чтобы собрать больше информации.

1 Ответов

Рейтинг:
7

Member 11638763

Для расчета Intel TBB-класса:

#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();
}


Для Intel TBB-класса 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.Ave