From 439a4e0f10dd120b563039012d07eb5f1b3c8ded Mon Sep 17 00:00:00 2001 From: Samo Penic <samo.penic@gmail.com> Date: Sun, 24 Nov 2013 11:45:32 +0000 Subject: [PATCH] Change in mutex location. Now in ts_vertex. Tried to lock cell change. Not working. Bug persists. --- src/timestep.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++------ 1 files changed, 100 insertions(+), 12 deletions(-) diff --git a/src/timestep.c b/src/timestep.c index 83e6f9b..e2f89ef 100644 --- a/src/timestep.c +++ b/src/timestep.c @@ -1,34 +1,122 @@ #include<stdlib.h> #include<stdio.h> #include<math.h> +#include<pthread.h> +//#include<unistd.h> //usleep requires it //#include "io.h" #include "general.h" #include "timestep.h" #include "vertexmove.h" #include "bondflip.h" +#include "frame.h" +#include "vertex.h" +#include "io.h" -ts_bool single_timestep(ts_vesicle *vesicle){ - ts_bool retval; +ts_bool run_simulation(ts_vesicle *vesicle, ts_uint mcsweeps, ts_uint inititer, ts_uint iterations){ + 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); + ts_fprintf(stdout, "Starting %d threads\n",vesicle->threads); + + pthread_t *tid=(pthread_t *)malloc(sizeof(pthread_t)*vesicle->threads); + thdata *data=(thdata *)malloc(sizeof(thdata)*vesicle->threads); + pthread_mutex_init(&(vesicle->mutex->vtx_taint),NULL); + pthread_mutex_init(&(vesicle->mutex->vtx_untaint),NULL); + pthread_mutex_init(&(vesicle->mutex->cell_modify),NULL); + + for(i=0;i<vesicle->threads;i++){ + data[i].thread_no=i; + data[i].vesicle=vesicle; + data[i].threads=vesicle->threads; + } + + for(i=0;i<inititer+iterations;i++){ + for(j=0;j<mcsweeps;j++){ + 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); + if(i>inititer){ + write_vertex_xml_file(vesicle,i-inititer); + } + } + + pthread_mutex_destroy(&(vesicle->mutex->vtx_taint)); + pthread_mutex_destroy(&(vesicle->mutex->vtx_untaint)); + pthread_exit(NULL); + return TS_SUCCESS; +} + +void * single_timestep(void *thread_data){ + thdata *data; + data=(thdata *)thread_data; + ts_vesicle *vesicle=data->vesicle; + ts_uint thID=data->thread_no; + ts_uint partition_size=(ts_uint)(vesicle->vlist->n/data->threads); + ts_uint end; + if(thID==data->threads-1){ + end=vesicle->vlist->n; + } else { + end=(thID+1)*partition_size; + } ts_double rnvec[3]; - ts_uint i; - for(i=0;i<vesicle->vlist->n;i++){ + 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(); rnvec[2]=drand48(); - retval=single_verticle_timestep(vesicle,vesicle->vlist->vtx[i],rnvec); +//TODO: you only need to taint (lock) vertices, that could be shared with another partition. You can leave out the rest. How can you test for that? Well, if any of vtx neighbours are in other partition, then you need to lock vertex and that neighbor. Otherwise not! + + /**** THREAD IS POTENTIALLY LOCKED ******/ + pthread_mutex_lock(&vesicle->mutex->vtx_taint); //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. Amount=%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(a=%d) ", vesicle->vlist->vtx[i]->neigh[j]->idx, vesicle->vlist->vtx[i]->neigh[j]->locked); + } + ts_fprintf(stdout, ".\n"); + } + + pthread_mutex_lock(&vesicle->mutex->vtx_untaint); + vertex_taint(vesicle->vlist->vtx[i],1); + pthread_mutex_unlock(&vesicle->mutex->vtx_untaint); + + pthread_mutex_unlock(&vesicle->mutex->vtx_taint); + /**** THREAD IS RELEASING MUTEX RESOURCES ******/ + + single_verticle_timestep(vesicle,vesicle->vlist->vtx[i],rnvec); + pthread_mutex_lock(&vesicle->mutex->vtx_untaint); + vertex_untaint(vesicle->vlist->vtx[i],1); + pthread_mutex_unlock(&vesicle->mutex->vtx_untaint); +// ts_fprintf(stdout, "Vertex %d should be untainted, level=%d.\n", i, vesicle->vlist->vtx[i]->locked); } - for(i=0;i<vesicle->blist->n;i++){ - rnvec[0]=drand48(); - rnvec[1]=drand48(); - rnvec[2]=drand48(); +// ts_int cnt=0; +/* + for(i=0;i<vesicle->vlist->n;i++){ + b=rand() % vesicle->blist->n; //find a bond and return a pointer to a bond... //call single_bondflip_timestep... - retval=single_bondflip_timestep(vesicle,vesicle->blist->bond[i],rnvec); - + retval=single_bondflip_timestep(vesicle,vesicle->blist->bond[b],rnvec); +// if(retval==TS_SUCCESS) cnt++; } - if(retval); +// printf("Bondflip success rate in one sweep: %d/%d=%e\n", cnt,vesicle->blist->n,(double)cnt/(double)vesicle->blist->n); +*/ +/* if(retval); return TS_SUCCESS; +*/ + pthread_exit(0); /* exit */ } -- Gitblit v1.9.3