From 50f10f120936a429dc450f58a40951fa5d59458a Mon Sep 17 00:00:00 2001
From: Samo Penic <samo.penic@gmail.com>
Date: Sat, 23 Nov 2013 21:11:15 +0000
Subject: [PATCH] Somewhat evolved paralelism.

---
 src/timestep.c   |   74 ++++++++++++++++++++-----------------
 src/io.c         |   13 ++++--
 src/taint_test.c |    4 +-
 src/tape         |    2 
 src/timestep.h   |    4 +
 src/general.h    |    1 
 src/vertexmove.c |    1 
 7 files changed, 57 insertions(+), 42 deletions(-)

diff --git a/src/general.h b/src/general.h
index 1dfb3a7..b4ce974 100644
--- a/src/general.h
+++ b/src/general.h
@@ -239,6 +239,7 @@
     ts_double cm[3];
     ts_double volume;
     ts_spharm *sphHarmonics;
+	ts_uint threads;
 } ts_vesicle;
 
 
diff --git a/src/io.c b/src/io.c
index 9e278ec..4a36f88 100644
--- a/src/io.c
+++ b/src/io.c
@@ -297,7 +297,8 @@
 ts_vesicle *parsetape(ts_uint *mcsweeps, ts_uint *inititer, ts_uint *iterations){
     long int nshell=17,ncxmax=60, ncymax=60, nczmax=60;  // THIS IS DUE TO CONFUSE BUG!
     char *buf=malloc(255*sizeof(char));
-    long int brezveze0=1;
+	buf[0]=0;
+    long int smps=1;
     long int brezveze1=1;
     long int brezveze2=1;
     ts_double xk0=25.0, dmax=1.67,stepsize=0.15;
@@ -314,8 +315,8 @@
 	CFG_SIMPLE_INT("mcsweeps",&mcsw),
 	CFG_SIMPLE_INT("inititer", &init),
         CFG_SIMPLE_BOOL("quiet",&quiet),
-        CFG_SIMPLE_STR("multiprocessing",buf),
-        CFG_SIMPLE_INT("smp_cores",&brezveze0),
+        CFG_SIMPLE_STR("multiprocessing",&buf),
+        CFG_SIMPLE_INT("smp_cores",&smps),
         CFG_SIMPLE_INT("cluster_nodes",&brezveze1),
         CFG_SIMPLE_INT("distributed_processes",&brezveze2),
         CFG_END()
@@ -343,7 +344,11 @@
     vesicle->clist->ncmax[1]=ncymax;
     vesicle->clist->ncmax[2]=nczmax;
     vesicle->clist->max_occupancy=8;
-
+	if(strcmp(buf,"smp")==0){	
+	vesicle->threads=smps;
+	} else {
+	vesicle->threads=1;
+	}
     cfg_free(cfg);
 	free(buf);
   //  fprintf(stderr,"NSHELL=%u\n",vesicle->nshell);
diff --git a/src/taint_test.c b/src/taint_test.c
index 9898fba..07b53c1 100644
--- a/src/taint_test.c
+++ b/src/taint_test.c
@@ -25,7 +25,7 @@
 for(i=0;i<vesicle->vlist->n;i++){
 	vertex_taint(vesicle->vlist->vtx[i],1);
 	vertex_untaint(vesicle->vlist->vtx[i],1);
-	printf("%d taint level %d\n",i,vesicle->vlist->vtx[i]->locked);
+	printf("%d taint amount %d\n",i,vesicle->vlist->vtx[i]->locked);
 	if(vertex_tainted(vesicle->vlist->vtx[i], 0, 1)) printf("Ooops, Main  %d is tainted!\n",i);
 	for(j=0;j<vesicle->vlist->vtx[i]->neigh_no;j++){
 		if(vertex_tainted(vesicle->vlist->vtx[i]->neigh[j], 0, 1)){
@@ -37,7 +37,7 @@
 }
 
 
-printf("At the end you should see no Ooopses and all taint levels should be 0!\n");
+printf("At the end you should see no Ooopses and all taint amounts should be 0!\n");
 vesicle_free(vesicle);
 return 0;
 }
diff --git a/src/tape b/src/tape
index d6e814d..2d86c6e 100644
--- a/src/tape
+++ b/src/tape
@@ -29,7 +29,7 @@
 
 #what type of multiprocessing? (*none, smp, cluster, distributed, cuda, auto)
 #currently only none makes sense.
-multiprocessing=none
+multiprocessing=smp
 #how many cores are allowed to process in SMP?
 smp_cores=2
 #how many nodes in cluster?
diff --git a/src/timestep.c b/src/timestep.c
index 3290184..30d6406 100644
--- a/src/timestep.c
+++ b/src/timestep.c
@@ -13,42 +13,36 @@
 #include "io.h"
 
 ts_bool run_simulation(ts_vesicle *vesicle, ts_uint mcsweeps, ts_uint inititer, ts_uint iterations){
-	ts_uint i, j;
+	ts_uint i, j,k ;
 
 	centermass(vesicle);
 	cell_occupation(vesicle);
 	ts_fprintf(stdout, "Starting simulation (first %d x %d MC sweeps will not be recorded on disk)\n", inititer, mcsweeps);
-	pthread_t tid1,tid2, tid3, tid4;
-	thdata data1, data2, data3, data4;
-	pthread_mutex_t mutex;
-	data1.thread_no=0;
-	data2.thread_no=1;
-	data1.vesicle=vesicle;
-	data2.vesicle=vesicle;
-       	data3.thread_no=2;
-	data4.thread_no=3;
-	data3.vesicle=vesicle;
-	data4.vesicle=vesicle;
+	ts_fprintf(stdout, "Starting %d threads\n",vesicle->threads);
 
-	data1.vtx_tainting_lock=&mutex;
-	data2.vtx_tainting_lock=&mutex;
-	data3.vtx_tainting_lock=&mutex;
-	data4.vtx_tainting_lock=&mutex;
+	pthread_t *tid=(pthread_t *)malloc(sizeof(pthread_t)*vesicle->threads);
+	thdata *data=(thdata *)malloc(sizeof(thdata)*vesicle->threads);
+	pthread_mutex_t mutex_taint, mutex_untaint;
+	pthread_mutex_init(&mutex_taint,NULL);
+	pthread_mutex_init(&mutex_untaint,NULL);
 
-	pthread_mutex_init(&mutex,NULL);
+	for(i=0;i<vesicle->threads;i++){
+		data[i].thread_no=i;
+		data[i].vesicle=vesicle;
+		data[i].threads=vesicle->threads;
+		data[i].vtx_tainting_lock=&mutex_taint;
+		data[i].vtx_untainting_lock=&mutex_untaint;
+	}
 
  	for(i=0;i<inititer+iterations;i++){
 		for(j=0;j<mcsweeps;j++){
-			pthread_create(&tid1,NULL,single_timestep,(void *)&data1);
-        		pthread_create(&tid2,NULL,single_timestep,(void *)&data2);
-        		pthread_create(&tid3,NULL,single_timestep,(void *)&data3);
-        		pthread_create(&tid4,NULL,single_timestep,(void *)&data4);
-		        pthread_join(tid1,NULL);
-		        pthread_join(tid2,NULL);
-		        pthread_join(tid3,NULL);
-		        pthread_join(tid4,NULL);
-
-//	single_timestep(vesicle);
+			for(k=0;k<vesicle->threads;k++){
+				pthread_create(&tid[k], NULL, single_timestep, (void *)&data[k]);
+			}
+			for(k=0;k<vesicle->threads;k++){
+		        	pthread_join(tid[k],NULL);
+			}
+		//	single_timestep(vesicle);
 		}
 		centermass(vesicle);
 		cell_occupation(vesicle);
@@ -57,7 +51,8 @@
 		}
 	}
 
-	pthread_mutex_destroy(&mutex);
+	pthread_mutex_destroy(&mutex_taint);
+	pthread_mutex_destroy(&mutex_untaint);
 	pthread_exit(NULL);
 	return TS_SUCCESS;
 }
@@ -67,15 +62,16 @@
 	data=(thdata *)thread_data;
 	ts_vesicle *vesicle=data->vesicle;
 	ts_uint thID=data->thread_no;
-	ts_uint partition_size=(ts_uint)(vesicle->vlist->n/4);
+	ts_uint partition_size=(ts_uint)(vesicle->vlist->n/data->threads);
 	ts_uint end;
-	if(thID==3){
+	if(thID==data->threads-1){
 		end=vesicle->vlist->n;
 	} else {
 		end=(thID+1)*partition_size;
 	}
     ts_double rnvec[3];
-    ts_uint i; //b;
+    ts_uint i,j; //b;
+//	ts_fprintf(stdout,"Thread thID=%d report for duty. My vtxes are in range from %d to %d.\n",thID,thID*partition_size, end-1);
     for(i=thID*partition_size;i<end;i++){
         rnvec[0]=drand48();
         rnvec[1]=drand48();
@@ -84,15 +80,25 @@
 	/**** THREAD IS POTENTIALLY LOCKED ******/
 	pthread_mutex_lock(data->vtx_tainting_lock); //taint if no other process is tainting or wait until you can taint
 	//	ts_fprintf(stdout, "thID=%d:: Tainting vertex %d, level=%d. Waiting....\n",thID, i, vesicle->vlist->vtx[i]->locked);
+
 	while(vertex_tainted(vesicle->vlist->vtx[i],1,1)){
-		ts_fprintf(stdout, "thID=%d:: Vertex %d is tainted, so I cannot try vertexmove. Level=%d. WAITING!\n",thID, i, vesicle->vlist->vtx[i]->locked);
+		ts_fprintf(stdout, "thID=%d:: Vertex %d is tainted, so I cannot try vertexmove. Level=%d. BU(H)TELJ!\n   neigh. vtxs: ",thID, i, vesicle->vlist->vtx[i]->locked);
+		for(j=0; j<vesicle->vlist->vtx[i]->neigh_no; j++){
+			ts_fprintf(stdout, "%d ", vesicle->vlist->vtx[i]->neigh[j]->idx);
+		}
+		ts_fprintf(stdout, ".\n");
 	}
-	vertex_taint(vesicle->vlist->vtx[i],1);
+	pthread_mutex_lock(data->vtx_untainting_lock);
+	vertex_taint(vesicle->vlist->vtx[i],2);
+	pthread_mutex_unlock(data->vtx_untainting_lock);
+
 	pthread_mutex_unlock(data->vtx_tainting_lock);
 	/**** THREAD IS RELEASING MUTEX RESOURCES ******/
 
         single_verticle_timestep(vesicle,vesicle->vlist->vtx[i],rnvec);
-	vertex_untaint(vesicle->vlist->vtx[i],1);
+	pthread_mutex_lock(data->vtx_untainting_lock);
+	vertex_untaint(vesicle->vlist->vtx[i],2);
+	pthread_mutex_unlock(data->vtx_untainting_lock);
 //		ts_fprintf(stdout, "Vertex %d should be untainted, level=%d.\n", i, vesicle->vlist->vtx[i]->locked);
     }
 
diff --git a/src/timestep.h b/src/timestep.h
index 15ad6d1..8cc79e8 100644
--- a/src/timestep.h
+++ b/src/timestep.h
@@ -4,9 +4,11 @@
 
 typedef struct str_thdata
 {
-    int thread_no;
+    ts_uint thread_no;
+	ts_uint threads;
     ts_vesicle *vesicle;
     pthread_mutex_t *vtx_tainting_lock;
+    pthread_mutex_t *vtx_untainting_lock;
 } thdata;
 
 
diff --git a/src/vertexmove.c b/src/vertexmove.c
index a79b2f0..2cb6550 100644
--- a/src/vertexmove.c
+++ b/src/vertexmove.c
@@ -108,6 +108,7 @@
 	}
 	
     //update the normals of triangles that share bead i.
+	//TODO: check if we could backup that too?
    for(i=0;i<vtx->tristar_no;i++) triangle_normal_vector(vtx->tristar[i]);
 
     return TS_FAIL; 

--
Gitblit v1.9.3