endif(HAVE_PROCESSOR_NUMBER)
endif(THREAD_WINDOWS)
-
+# option to set affinity
+option(THREAD_MPI_SET_AFFINITY "Set thread affinity to a core if number of threads equal to number of hardware threads." ON)
+mark_as_advanced(THREAD_MPI_SET_AFFINITY)
+if (THREAD_MPI_SET_AFFINITY)
+ add_definitions(-DTMPI_SET_AFFINITY)
+else (THREAD_MPI_SET_AFFINITY)
+ add_definitions()
+endif (THREAD_MPI_SET_AFFINITY)
include(CheckFunctionExists)
if (THREAD_PTHREADS)
check_function_exists(sysconf HAVE_SYSCONF)
# this runs on windows
#check_include_files(windows.h HAVE_WINDOWS_H)
-#check_function_exists(GetSystemInfo HAVE_SYSTEM_INFO)
+
test_tmpi_atomics(TMPI_ATOMICS)
{
volatile int ret=b;
__asm__ __volatile__("\txchgl %0, %1;"
- :"=r"(ret)
- :"m"(a->value), "0"(ret)
+ :"+r"(ret), "+m"(a->value)
+ :
:"memory");
return (int)ret;
}
:"memory");
*/
__asm__ __volatile__("\txchgl %0, %1;"
- :"=r"(ret)
- :"m"(a->value), "0"(ret)
+ :"+r"(ret), "+m"(a->value)
+ :
:"memory");
#else
__asm__ __volatile__("\txchgq %0, %1;"
- :"=r"(ret)
- :"m"(a->value), "0"(ret)
+ :"+r"(ret), "+m"(a->value)
+ :
:"memory");
#endif
return (void*)ret;
value with 0 */
"\tjne 1b" /* jump backward if we didn't
just lock */
- : "=m" (x->lock) /* input & output var */
+ : "+m" (x->lock) /* input & output var */
:
: "%eax", "memory"/* we changed memory */
);
static inline int tMPI_Spinlock_trylock(tMPI_Spinlock_t *x)
{
- int old_value;
+ int old_value=1;
- __asm__ __volatile__("\tmovl $1, %0\n" /* set eax to 1, the locked
+ __asm__ __volatile__("\tmovl %2, %0\n" /* set eax to 1, the locked
value of the lock */
"\txchgl %0, %1\n" /* atomically exchange
eax with the address in
rdx. */
- :"=r" (old_value), "=m" (x->lock)
- : : "memory");
+ : "+r"(old_value), "+m" (x->lock)
+ : "i" (1)
+ : "memory");
return (old_value);
}
"\tjmp 1b\n" /* and jump back */
"2:\tnop\n" /* jump target for end
of wait */
- : "=m"(x->lock) /* input & output var */
+ : "+m"(x->lock) /* input & output var */
:
: "memory"/* we changed memory */
);
/* mutex for initializing barriers */
static pthread_mutex_t barrier_init=PTHREAD_MUTEX_INITIALIZER;
-
-/* lock & variable for setting main thread affinity */
-static tMPI_Spinlock_t main_thread_aff_lock=TMPI_SPINLOCK_INITIALIZER;
-static tMPI_Atomic_t main_thread_aff_set={ 0 };
-static tMPI_Atomic_t aff_thread_number;
-
-
+/* mutex for initializing barriers */
+static pthread_mutex_t aff_init=PTHREAD_MUTEX_INITIALIZER;
+static int aff_thread_number=0;
/* TODO: this needs to go away! (there's another one in winthreads.c)
if(ret!=0)
{
/* Cannot use tMPI_error() since messages use threads for locking */
- tMPI_Fatal_error(TMPI_FARGS,"Failed to create POSIX thread, rc=%d",ret);
+ tMPI_Fatal_error(TMPI_FARGS,"Failed to create POSIX thread:%s, rc=%d",
+ strerror(errno), ret);
/* Use system memory allocation routines */
return -1;
}
{
int ret;
+#ifdef TMPI_SET_AFFINITY
/* set the calling thread's affinity mask */
- if (tMPI_Atomic_get(&main_thread_aff_set) == 0)
+ pthread_mutex_lock( &(aff_init) );
+ if (aff_thread_number==0)
{
-#ifdef HAVE_PTHREAD_SETAFFINITY
- cpu_set_t set;
-#endif
- /* this can be a spinlock because the chances of collision are low. */
- tMPI_Spinlock_lock( &main_thread_aff_lock );
- tMPI_Atomic_set( &aff_thread_number, 0);
-#ifdef HAVE_PTHREAD_SETAFFINITY
- CPU_ZERO(&set);
- CPU_SET(0, &set);
- pthread_setaffinity_np(pthread_self(), sizeof(set), &set);
- /*fprintf(stderr, "Setting affinity.\n");*/
-#endif
- tMPI_Atomic_set( &main_thread_aff_set, 1);
- tMPI_Spinlock_unlock( &main_thread_aff_lock );
+ tMPI_Set_affinity(aff_thread_number++);
}
-
+ pthread_mutex_unlock( &(aff_init) );
+#endif
if(thread==NULL)
{
if(ret!=0)
{
/* Cannot use tMPI_error() since messages use threads for locking */
- tMPI_Fatal_error(TMPI_FARGS,"Failed to create POSIX thread, rc=%d",ret);
+ tMPI_Fatal_error(TMPI_FARGS,"Failed to create POSIX thread:%s, rc=%d",
+ strerror(errno), ret);
/* Use system memory allocation routines */
return -1;
}
else
{
-#ifdef HAVE_PTHREAD_SETAFFINITY
- int n;
- cpu_set_t set;
+#ifdef TMPI_SET_AFFINITY
+ /* now set the affinity of the new thread */
+ int ret;
- n=tMPI_Atomic_add_return(&aff_thread_number, 1);
- CPU_ZERO(&set);
- CPU_SET(n, &set);
- return pthread_setaffinity_np((*thread)->th, sizeof(set), &set);
+ pthread_mutex_lock( &(aff_init) );
+ ret=tMPI_Set_affinity(aff_thread_number++);
+ pthread_mutex_unlock( &(aff_init) );
+ /* failure is non-fatal, so we won't check the result */
+ return 0;
#else
return 0;
#endif
bSumEkinhOld = FALSE;
compute_globals(fplog,gstat,cr,ir,fr,ekind,state,state_global,mdatoms,nrnb,vcm,
- wcycle,enerd,force_vir,shake_vir,total_vir,pres,mu_tot,
+ NULL,enerd,force_vir,shake_vir,total_vir,pres,mu_tot,
constr,NULL,FALSE,state->box,
top_global,&pcurr,top_global->natoms,&bSumEkinhOld,cglo_flags);
if (ir->eI == eiVVAK) {
perhaps loses some logic?*/
compute_globals(fplog,gstat,cr,ir,fr,ekind,state,state_global,mdatoms,nrnb,vcm,
- wcycle,enerd,force_vir,shake_vir,total_vir,pres,mu_tot,
+ NULL,enerd,force_vir,shake_vir,total_vir,pres,mu_tot,
constr,NULL,FALSE,state->box,
top_global,&pcurr,top_global->natoms,&bSumEkinhOld,
cglo_flags &~ CGLO_PRESSURE);
}
}
- gmx_fatal(FARGS,"Group %s not found in index file.\nGroup names must match either [moleculetype] names\nor custom index group names,in which case you\nmust supply an index file to the '-n' option of grompp.",s);
+ gmx_fatal(FARGS,
+ "Group %s referenced in the .mdp file was not found in the index file.\n"
+ "Group names must match either [moleculetype] names or custom index group\n"
+ "names, in which case you must supply an index file to the '-n' option\n"
+ "of grompp.",
+ s);
return -1;
}
fprintf(dist,"\n");
if (num)
fprintf(num,"\n");
- if ( bMin?min1:max1 != -1 )
+ if ( (bMin?min1:max1) != -1 )
if (atm)
fprintf(atm,"%12e %12d %12d\n",
output_env_conv_time(oenv,t),1+(bMin ? min1 : max1),