<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Faktorisierung mit MPI]]></title><description><![CDATA[<p>Hi</p>
<p>Ich habe ein einfaches Programm geschrieben, welches das Message Passing Interface benutzt. Leider erhalte ich immer irgendwelche Debug Assertion.</p>
<pre><code class="language-cpp">#include &quot;mpi.h&quot;
#include &quot;windows.h&quot;
#include &quot;assert.h&quot;
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;cmath&gt;

using namespace std;

typedef unsigned long long ullong;

// Zahl welche es zu faktorisieren gilt
ullong factnum = 12222222222222; 

// MPI Tags, Faktor gefunden
const int tagfactfound = 1;

// Auftragverteilung
const int tagbeginjob = 2;

// Auftrag beendet
const int tagendjob = 3;

int myid;

// Berechnet die Quadratwurzel eine Variable des Typs unsigned long long
ullong ulsqrt(ullong num){

	/*__asm {
		// Double word move (64bit)
		movq mm1,num 
		// Konvertiere two double int (64bit) to double pr. float (128bit)
		cvtpi2pd xmm0,mm1
		// Quadratwurzel ziehen
		sqrtsd xmm0,xmm0
		// Konvertiere double pr. float (128bit) to two double int (64bit)
		cvtpd2pi eax,xmm0
	}*/

	return sqrt((long double)num);
}

// Funktion welche anhand des Sieb des Eratosthenes überprüft ob eine Zahl 
// Primfaktoren besitzt
bool isprime(ullong num){
	assert (num % 2 == 1);

	// Grösster Teiler
	ullong max = ulsqrt(num);

	// Boolsches Array auf dem Heap allozieren
	bool * eratos = new bool[max];

	// Primzahlenspeicher
	ullong * prim = new ullong[max/2];
	ullong count = 0;

	// Primzahlen besimmten
	for (ullong i=2; i &lt;= max; ++i){

		// Zahl ist prim
		if (eratos[i]){
			prim[i] = i;
			count++;
		}

		// Alle Vielfachen als nicht prim markieren
		ullong j = i*i;
		while (j &lt;= max){
			eratos[j] = false;
			j += j;
		}
	}

	// Zahl anhand der vorher berechneten Primzahlen überprüfen
	for (ullong i=0; i &lt; count; ++i){
		if(num % prim[i] == 0)return false;
	}

	return true;
}

// Diese Funktion überprüft ob die Zahl num eine Primzahl ist, falls nicht
// liefert sie die nächstmögliche Primzahl
ullong getnextprime(ullong num){
	if (num == 0 || num == 1) return 2;
	// Nächste Primzahl berechnen wenn num nicht prim ist
	while(!isprime(num)){
		num += 2;
	}
	return num;
}

int main(int argc, char* argv[]) {

	// Message Passing Interface initalisieren
	MPI::Init(argc, argv);

	// Anzahl der Nodes ermitteln
	int numprocs = MPI::COMM_WORLD.Get_size();

	if (numprocs &lt; 2){
		printf(&quot;Need than one process for calculation\n&quot;);	
		return 0;
	}

	// Welcher Node bin ich?
	myid = MPI::COMM_WORLD.Get_rank();

	MPI::Status stat;

	ullong jobmax = ulsqrt(factnum);
	ullong jobsize = ceil((long double)(jobmax)/(long double)(numprocs-1));

	ullong jobcounter = 0;

	std::vector&lt;ullong&gt; fact;

	// Managernode
	if (myid == 0) {
		printf(&quot;Beginning of job distribution for %d workers with candidate %lld\n&quot;,numprocs,factnum);

		// Ausgabe sofort an die Pipe senden
		fflush(stdout);

		// Jedem Workernode einen Auftrag übergeben
		for (int i = 1; i &lt; numprocs; ++i){
			printf(&quot;Distribut job (%lld &quot;,jobcounter);
			jobcounter += jobsize;
			printf(&quot;to %lld) to %d\n&quot;,jobcounter,i);

			fflush(stdout);

			// Jeweiligen Auftrag an den jeweiligen Arbeit schicken
			MPI::COMM_WORLD.Send(&amp;jobcounter, sizeof(ullong), MPI::UNSIGNED_LONG_LONG,i,tagbeginjob);
		}

		do {

			while (MPI::COMM_WORLD.Iprobe(MPI::ANY_SOURCE,tagendjob,stat))
			{
				int b;
				// Leer Benachrichtung aus dem Speicher entferne
				MPI::COMM_WORLD.Recv(&amp;b,sizeof(b),MPI::INT,MPI::ANY_SOURCE,tagendjob,stat);

				// Ein Arbeiter wurde fertig
				--numprocs;

			}

			while (MPI::COMM_WORLD.Iprobe(MPI::ANY_SOURCE,tagfactfound,stat))
			{

				// Ein Arbeiter hat einen Faktor gefunden
				ullong lbuf;

				// Faktor aus Nachrichtenspeicher holen
				MPI::COMM_WORLD.Recv(&amp;lbuf,sizeof(lbuf),MPI::UNSIGNED_LONG_LONG,MPI::ANY_SOURCE,tagfactfound,stat);

				// Zahl minimieren
				factnum /= lbuf;

				// Dem Faktorenvektor hinzufügen
				fact.push_back(lbuf);

			}

		} while (numprocs != 1);

		if (factnum != 1) fact.push_back(factnum);

		// Alle Arbeiter haben ihren Auftrag erledigt
		printf(&quot;Factors: &quot;);
		std::copy(fact.begin(),fact.end(),std::ostream_iterator&lt;ullong&gt;(std::cout,&quot; &quot;));
		printf(&quot;\n&quot;);

	// Workernodes
	} else {

		ullong fbuf;

		// Auftrag empfangen
		MPI::COMM_WORLD.Recv(&amp;fbuf,sizeof(fbuf),MPI::UNSIGNED_LONG_LONG,MPI::ANY_SOURCE,tagbeginjob);

		// Untere Grenze bestimmen;
		ullong minsize = fbuf-jobsize;

		// Alle ungeraden Zahlen werden überprüft
		if (minsize % 2 == 0) ++minsize;
		ullong maxsize = fbuf;

		printf(&quot;Worker %d got Job %lld to %lld\n&quot;,myid,minsize,fbuf);
		fflush(stdout);

		ullong i = getnextprime(minsize);
		ullong g;

		// Auftrag bearbeiten
		while(i &lt; maxsize){

			// Hat ein andere Arbeiter einen Faktor gefunden?
			if (MPI::COMM_WORLD.Iprobe(MPI::ANY_SOURCE,tagfactfound,stat)){
				ullong lbuf;
				// Faktor auslesen
				MPI::COMM_WORLD.Recv(&amp;lbuf,sizeof(lbuf),MPI::UNSIGNED_LONG_LONG,MPI::ANY_SOURCE,tagfactfound);

				// Zahl minimieren
				factnum /= lbuf;
			}
			g = 1;

			// Wir haben einen Faktor gefunden
			if (factnum % i == 0){
				ullong lbuf = i;

				// Zahl minimieren
				factnum = factnum / lbuf;

				for (int l = 0; l &lt; MPI::COMM_WORLD.Get_size(); ++l)
				{
					if (l != myid){

						// Den anderen Arbeitern und dem Manager mitteilen
						MPI::COMM_WORLD.Send(&amp;lbuf, sizeof(lbuf),MPI::UNSIGNED_LONG_LONG,l,tagfactfound);
					}
				}
			} else {

				// Nächste Primzahl generieren
				if (i == 2) i = 3;

				else i = getnextprime(i+2);
				fflush(stdout);
			}
		}

		// Auftrag wurde erledigt
		int b = 1;
		MPI::COMM_WORLD.Send(&amp;b,sizeof(b),MPI::INT,0,tagendjob);
	}

	// Message Passing Interface Umgebung beenden
	MPI::Finalize();
	return 0;
}
</code></pre>
<p>Die Fehler passieren immer bei einem Aufruf von Recv. Ich habe schon diverse MPI Dokumente studiert, jedoch nichts gefunden was ich falsch gemacht habe. Das Programm funktionierte mit unsigned long.</p>
<p>MfG Joe</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/172289/faktorisierung-mit-mpi</link><generator>RSS for Node</generator><lastBuildDate>Thu, 17 Sep 2026 18:00:57 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/172289.rss" rel="self" type="application/rss+xml"/><pubDate>Sat, 03 Feb 2007 13:22:51 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Faktorisierung mit MPI on Sat, 03 Feb 2007 13:22:51 GMT]]></title><description><![CDATA[<p>Hi</p>
<p>Ich habe ein einfaches Programm geschrieben, welches das Message Passing Interface benutzt. Leider erhalte ich immer irgendwelche Debug Assertion.</p>
<pre><code class="language-cpp">#include &quot;mpi.h&quot;
#include &quot;windows.h&quot;
#include &quot;assert.h&quot;
#include &lt;iostream&gt;
#include &lt;vector&gt;
#include &lt;cmath&gt;

using namespace std;

typedef unsigned long long ullong;

// Zahl welche es zu faktorisieren gilt
ullong factnum = 12222222222222; 

// MPI Tags, Faktor gefunden
const int tagfactfound = 1;

// Auftragverteilung
const int tagbeginjob = 2;

// Auftrag beendet
const int tagendjob = 3;

int myid;

// Berechnet die Quadratwurzel eine Variable des Typs unsigned long long
ullong ulsqrt(ullong num){

	/*__asm {
		// Double word move (64bit)
		movq mm1,num 
		// Konvertiere two double int (64bit) to double pr. float (128bit)
		cvtpi2pd xmm0,mm1
		// Quadratwurzel ziehen
		sqrtsd xmm0,xmm0
		// Konvertiere double pr. float (128bit) to two double int (64bit)
		cvtpd2pi eax,xmm0
	}*/

	return sqrt((long double)num);
}

// Funktion welche anhand des Sieb des Eratosthenes überprüft ob eine Zahl 
// Primfaktoren besitzt
bool isprime(ullong num){
	assert (num % 2 == 1);

	// Grösster Teiler
	ullong max = ulsqrt(num);

	// Boolsches Array auf dem Heap allozieren
	bool * eratos = new bool[max];

	// Primzahlenspeicher
	ullong * prim = new ullong[max/2];
	ullong count = 0;

	// Primzahlen besimmten
	for (ullong i=2; i &lt;= max; ++i){

		// Zahl ist prim
		if (eratos[i]){
			prim[i] = i;
			count++;
		}

		// Alle Vielfachen als nicht prim markieren
		ullong j = i*i;
		while (j &lt;= max){
			eratos[j] = false;
			j += j;
		}
	}

	// Zahl anhand der vorher berechneten Primzahlen überprüfen
	for (ullong i=0; i &lt; count; ++i){
		if(num % prim[i] == 0)return false;
	}

	return true;
}

// Diese Funktion überprüft ob die Zahl num eine Primzahl ist, falls nicht
// liefert sie die nächstmögliche Primzahl
ullong getnextprime(ullong num){
	if (num == 0 || num == 1) return 2;
	// Nächste Primzahl berechnen wenn num nicht prim ist
	while(!isprime(num)){
		num += 2;
	}
	return num;
}

int main(int argc, char* argv[]) {

	// Message Passing Interface initalisieren
	MPI::Init(argc, argv);

	// Anzahl der Nodes ermitteln
	int numprocs = MPI::COMM_WORLD.Get_size();

	if (numprocs &lt; 2){
		printf(&quot;Need than one process for calculation\n&quot;);	
		return 0;
	}

	// Welcher Node bin ich?
	myid = MPI::COMM_WORLD.Get_rank();

	MPI::Status stat;

	ullong jobmax = ulsqrt(factnum);
	ullong jobsize = ceil((long double)(jobmax)/(long double)(numprocs-1));

	ullong jobcounter = 0;

	std::vector&lt;ullong&gt; fact;

	// Managernode
	if (myid == 0) {
		printf(&quot;Beginning of job distribution for %d workers with candidate %lld\n&quot;,numprocs,factnum);

		// Ausgabe sofort an die Pipe senden
		fflush(stdout);

		// Jedem Workernode einen Auftrag übergeben
		for (int i = 1; i &lt; numprocs; ++i){
			printf(&quot;Distribut job (%lld &quot;,jobcounter);
			jobcounter += jobsize;
			printf(&quot;to %lld) to %d\n&quot;,jobcounter,i);

			fflush(stdout);

			// Jeweiligen Auftrag an den jeweiligen Arbeit schicken
			MPI::COMM_WORLD.Send(&amp;jobcounter, sizeof(ullong), MPI::UNSIGNED_LONG_LONG,i,tagbeginjob);
		}

		do {

			while (MPI::COMM_WORLD.Iprobe(MPI::ANY_SOURCE,tagendjob,stat))
			{
				int b;
				// Leer Benachrichtung aus dem Speicher entferne
				MPI::COMM_WORLD.Recv(&amp;b,sizeof(b),MPI::INT,MPI::ANY_SOURCE,tagendjob,stat);

				// Ein Arbeiter wurde fertig
				--numprocs;

			}

			while (MPI::COMM_WORLD.Iprobe(MPI::ANY_SOURCE,tagfactfound,stat))
			{

				// Ein Arbeiter hat einen Faktor gefunden
				ullong lbuf;

				// Faktor aus Nachrichtenspeicher holen
				MPI::COMM_WORLD.Recv(&amp;lbuf,sizeof(lbuf),MPI::UNSIGNED_LONG_LONG,MPI::ANY_SOURCE,tagfactfound,stat);

				// Zahl minimieren
				factnum /= lbuf;

				// Dem Faktorenvektor hinzufügen
				fact.push_back(lbuf);

			}

		} while (numprocs != 1);

		if (factnum != 1) fact.push_back(factnum);

		// Alle Arbeiter haben ihren Auftrag erledigt
		printf(&quot;Factors: &quot;);
		std::copy(fact.begin(),fact.end(),std::ostream_iterator&lt;ullong&gt;(std::cout,&quot; &quot;));
		printf(&quot;\n&quot;);

	// Workernodes
	} else {

		ullong fbuf;

		// Auftrag empfangen
		MPI::COMM_WORLD.Recv(&amp;fbuf,sizeof(fbuf),MPI::UNSIGNED_LONG_LONG,MPI::ANY_SOURCE,tagbeginjob);

		// Untere Grenze bestimmen;
		ullong minsize = fbuf-jobsize;

		// Alle ungeraden Zahlen werden überprüft
		if (minsize % 2 == 0) ++minsize;
		ullong maxsize = fbuf;

		printf(&quot;Worker %d got Job %lld to %lld\n&quot;,myid,minsize,fbuf);
		fflush(stdout);

		ullong i = getnextprime(minsize);
		ullong g;

		// Auftrag bearbeiten
		while(i &lt; maxsize){

			// Hat ein andere Arbeiter einen Faktor gefunden?
			if (MPI::COMM_WORLD.Iprobe(MPI::ANY_SOURCE,tagfactfound,stat)){
				ullong lbuf;
				// Faktor auslesen
				MPI::COMM_WORLD.Recv(&amp;lbuf,sizeof(lbuf),MPI::UNSIGNED_LONG_LONG,MPI::ANY_SOURCE,tagfactfound);

				// Zahl minimieren
				factnum /= lbuf;
			}
			g = 1;

			// Wir haben einen Faktor gefunden
			if (factnum % i == 0){
				ullong lbuf = i;

				// Zahl minimieren
				factnum = factnum / lbuf;

				for (int l = 0; l &lt; MPI::COMM_WORLD.Get_size(); ++l)
				{
					if (l != myid){

						// Den anderen Arbeitern und dem Manager mitteilen
						MPI::COMM_WORLD.Send(&amp;lbuf, sizeof(lbuf),MPI::UNSIGNED_LONG_LONG,l,tagfactfound);
					}
				}
			} else {

				// Nächste Primzahl generieren
				if (i == 2) i = 3;

				else i = getnextprime(i+2);
				fflush(stdout);
			}
		}

		// Auftrag wurde erledigt
		int b = 1;
		MPI::COMM_WORLD.Send(&amp;b,sizeof(b),MPI::INT,0,tagendjob);
	}

	// Message Passing Interface Umgebung beenden
	MPI::Finalize();
	return 0;
}
</code></pre>
<p>Die Fehler passieren immer bei einem Aufruf von Recv. Ich habe schon diverse MPI Dokumente studiert, jedoch nichts gefunden was ich falsch gemacht habe. Das Programm funktionierte mit unsigned long.</p>
<p>MfG Joe</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1222197</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1222197</guid><dc:creator><![CDATA[*JoE*]]></dc:creator><pubDate>Sat, 03 Feb 2007 13:22:51 GMT</pubDate></item></channel></rss>