PLASMA  2.4.5
PLASMA - Parallel Linear Algebra for Scalable Multi-core Architectures
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
plasmaos.c File Reference
#include <errno.h>
#include <stdlib.h>
#include "common.h"
Include dependency graph for plasmaos.c:

Go to the source code of this file.

Macros

#define PLASMA_GETENV(var, str)   envstr = getenv(var);
#define PLASMA_CLEANENV(str)

Functions

void plasma_topology_init ()
void plasma_topology_finalize ()
int plasma_setaffinity (int rank)
int plasma_unsetaffinity (int rank)
int plasma_yield ()
int plasma_get_numthreads ()
int plasma_get_numthreads_numa ()
int plasma_get_affthreads (int *coresbind)
float cabsf (float _Complex z)
double cabs (double _Complex z)
double cimag (PLASMA_Complex64_t z)
double creal (PLASMA_Complex64_t z)
PLASMA_Complex64_t conj (PLASMA_Complex64_t z)

Detailed Description

This file handles the mapping from pthreads calls to windows threads PLASMA is a software package provided by Univ. of Tennessee, Univ. of California Berkeley and Univ. of Colorado Denver

Version:
2.4.5
Author:
Piotr Luszczek
Mathieu Faverge
Date:
2010-11-15

Definition in file plasmaos.c.


Macro Definition Documentation

#define PLASMA_CLEANENV (   str)

Definition at line 275 of file plasmaos.c.

#define PLASMA_GETENV (   var,
  str 
)    envstr = getenv(var);

Definition at line 274 of file plasmaos.c.


Function Documentation

double cabs ( double _Complex  z)

Definition at line 410 of file plasmaos.c.

References lapack_testing::f.

{
double *zp, x, y;
zp = (double *)&z;
/* first find out the large component */
if (zp[0] > zp[1]) {
x = zp[0];
y = zp[1];
} else {
x = zp[1];
y = zp[0];
}
return fabs(x) * sqrt(1.0f + y / x);
}

Here is the caller graph for this function:

float cabsf ( float _Complex  z)

Definition at line 393 of file plasmaos.c.

References lapack_testing::f.

{
float *zp, x, y;
zp = (float *)&z;
/* first find out the large component */
if (zp[0] > zp[1]) {
x = zp[0];
y = zp[1];
} else {
x = zp[1];
y = zp[0];
}
return fabsf(x) * sqrtf(1.0f + y / x);
}

Here is the caller graph for this function:

double cimag ( PLASMA_Complex64_t  z)

Definition at line 427 of file plasmaos.c.

{
return ((double *)&z)[1];
}

Here is the caller graph for this function:

Definition at line 436 of file plasmaos.c.

{
double *zp, *vp;
zp = (double *)&z;
vp = (double *)&v;
vp[0] = zp[0];
vp[1] = -zp[1];
return v;
}

Here is the caller graph for this function:

double creal ( PLASMA_Complex64_t  z)

Definition at line 431 of file plasmaos.c.

{
return ((double *)&z)[0];
}

Here is the caller graph for this function:

int plasma_get_affthreads ( int *  coresbind)

Definition at line 334 of file plasmaos.c.

References CONTEXT_THREADS_MAX, PLASMA_CLEANENV, plasma_error(), PLASMA_GETENV, and PLASMA_SUCCESS.

{
char *envstr = NULL;
int i;
/* Env variable does not exist, we search the system number of core */
PLASMA_GETENV("PLASMA_AFF_THREADS", envstr);
if ( envstr == NULL) {
for (i = 0; i < CONTEXT_THREADS_MAX; i++)
coresbind[i] = i % sys_corenbr;
}
else {
char *endptr;
int wrap = 0;
int nbr = 0;
long int val;
/* We use the content of the PLASMA_AFF_THREADS env. variable */
for (i = 0; i < CONTEXT_THREADS_MAX; i++) {
if (!wrap) {
val = strtol(envstr, &endptr, 10);
if (endptr != envstr) {
coresbind[i] = (int)val;
envstr = endptr;
}
else {
/* there must be at least one entry */
if (i < 1) {
plasma_error("plasma_get_affthreads", "PLASMA_AFF_THREADS should have at least one entry => everything will be bind on core 0");
coresbind[i] = 0;
i++;
}
/* there is no more values in the string */
/* the next threads are binded with a round robin policy over this array */
wrap = 1;
nbr = i;
coresbind[i] = coresbind[0];
}
}
else {
coresbind[i] = coresbind[i % nbr];
}
}
}
PLASMA_CLEANENV(envstr);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int plasma_get_numthreads ( )

Check for an integer in an environment variable, returning the integer value or a provided default value

Definition at line 283 of file plasmaos.c.

References PLASMA_CLEANENV, and PLASMA_GETENV.

{
char *envstr = NULL;
char *endptr;
long int thrdnbr = -1;
extern int errno;
/* Env variable does not exist, we search the system number of core */
PLASMA_GETENV("PLASMA_NUM_THREADS", envstr);
if ( envstr == NULL ) {
thrdnbr = sys_corenbr;
} else {
/* Convert to long, checking for errors */
thrdnbr = strtol(envstr, &endptr, 10);
if ((errno == ERANGE) || ((thrdnbr==0) && (endptr==envstr))) {
PLASMA_CLEANENV(envstr);
return -1;
}
}
PLASMA_CLEANENV(envstr);
return (int)thrdnbr;
}

Here is the caller graph for this function:

int plasma_get_numthreads_numa ( )

Definition at line 306 of file plasmaos.c.

References PLASMA_CLEANENV, and PLASMA_GETENV.

{
char *envstr = NULL;
char *endptr;
long int thrdnbr = -1;
extern int errno;
/* Env variable does not exist, we search the system number of core */
PLASMA_GETENV("PLASMA_NUM_THREADS_NUMA", envstr);
if ( envstr != NULL ) {
/* Convert to long, checking for errors */
thrdnbr = strtol(envstr, &endptr, 10);
if ((errno == ERANGE) || ((thrdnbr==0) && (endptr==envstr))) {
PLASMA_CLEANENV(envstr);
return -1;
}
} else {
#ifdef PLASMA_HWLOC
thrdnbr = plasma_getnuma_size();
#else
thrdnbr = 1;
#endif
}
PLASMA_CLEANENV(envstr);
return (int)thrdnbr;
}

Here is the caller graph for this function:

int plasma_setaffinity ( int  rank)

This routine will set affinity for the calling thread that has rank 'rank'. Ranks start with 0.

If there are multiple instances of PLASMA then affinity will be wrong: all ranks 0 will be pinned to core 0.

Also, affinity is not resotred when PLASMA_Finalize() is called.

Definition at line 110 of file plasmaos.c.

References PLASMA_ERR_NOT_SUPPORTED, PLASMA_ERR_UNEXPECTED, and PLASMA_SUCCESS.

{
#ifndef PLASMA_AFFINITY_DISABLE
#if (defined PLASMA_OS_LINUX)
{
cpu_set_t set;
CPU_ZERO( &set );
CPU_SET( rank, &set );
#if (defined HAVE_OLD_SCHED_SETAFFINITY)
if( sched_setaffinity( 0, &set ) < 0 )
#else /* HAVE_OLD_SCHED_SETAFFINITY */
if( sched_setaffinity( 0, sizeof(set), &set) < 0 )
#endif /* HAVE_OLD_SCHED_SETAFFINITY */
{
}
}
#elif (defined PLASMA_OS_MACOS)
{
thread_affinity_policy_data_t ap;
int ret;
ap.affinity_tag = 1; /* non-null affinity tag */
ret = thread_policy_set( mach_thread_self(),
THREAD_AFFINITY_POLICY,
(integer_t*) &ap,
THREAD_AFFINITY_POLICY_COUNT
);
if(ret != 0)
}
#elif (defined PLASMA_OS_WINDOWS)
{
DWORD mask = 1 << rank;
if( SetThreadAffinityMask(GetCurrentThread(), mask) == 0)
}
#elif (defined PLASMA_OS_AIX)
{
tid_t self_ktid = thread_self ();
bindprocessor(BINDTHREAD, self_ktid, rank);
}
#else
#endif
#endif /* PLASMA_AFFINITY_DISABLE */
}

Here is the caller graph for this function:

void plasma_topology_finalize ( )

Definition at line 97 of file plasmaos.c.

References plasma_unsetaffinity().

Here is the call graph for this function:

Here is the caller graph for this function:

void plasma_topology_init ( )

Definition at line 61 of file plasmaos.c.

References pthread_mutex_lock(), and pthread_mutex_unlock().

{
pthread_mutex_lock(&mutextopo);
if ( !topo_initialized ) {
#if (defined PLASMA_OS_LINUX) || (defined PLASMA_OS_AIX)
sys_corenbr = sysconf(_SC_NPROCESSORS_ONLN);
#elif (defined PLASMA_OS_MACOS)
int mib[4];
int cpu;
size_t len = sizeof(cpu);
/* set the mib for hw.ncpu */
mib[0] = CTL_HW;
mib[1] = HW_AVAILCPU;
/* get the number of CPUs from the system */
sysctl(mib, 2, &cpu, &len, NULL, 0);
if( cpu < 1 ) {
mib[1] = HW_NCPU;
sysctl( mib, 2, &cpu, &len, NULL, 0 );
}
if( cpu < 1 ) {
cpu = 1;
}
sys_corenbr = cpu;
#elif (defined PLASMA_OS_WINDOWS)
SYSTEM_INFO sysinfo;
GetSystemInfo(&sysinfo);
sys_corenbr = sysinfo.dwNumberOfProcessors;
#endif
}
pthread_mutex_unlock(&mutextopo);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int plasma_unsetaffinity ( int  rank)

This routine will set affinity for the calling thread that has rank 'rank'. Ranks start with 0.

If there are multiple instances of PLASMA then affinity will be wrong: all ranks 0 will be pinned to core 0.

Also, affinity is not resotred when PLASMA_Finalize() is called.

Definition at line 175 of file plasmaos.c.

References PLASMA_ERR_NOT_SUPPORTED, PLASMA_ERR_UNEXPECTED, PLASMA_SUCCESS, and plasma_warning().

{
#ifndef PLASMA_AFFINITY_DISABLE
#if (defined PLASMA_OS_LINUX)
{
int i;
cpu_set_t set;
CPU_ZERO( &set );
for(i=0; i<sys_corenbr; i++)
CPU_SET( i, &set );
#if (defined HAVE_OLD_SCHED_SETAFFINITY)
if( sched_setaffinity( 0, &set ) < 0 )
#else /* HAVE_OLD_SCHED_SETAFFINITY */
if( sched_setaffinity( 0, sizeof(set), &set) < 0 )
#endif /* HAVE_OLD_SCHED_SETAFFINITY */
{
plasma_warning("plasma_unsetaffinity", "Could not unbind thread");
}
}
#elif (defined PLASMA_OS_MACOS)
{
/* TODO: check how to unbind the main thread if necessary for OpenMP */
/* thread_affinity_policy_data_t ap; */
/* int ret; */
/* ap.affinity_tag = 1; /\* non-null affinity tag *\/ */
/* ret = thread_policy_set( mach_thread_self(), */
/* THREAD_AFFINITY_POLICY, */
/* (integer_t*) &ap, */
/* THREAD_AFFINITY_POLICY_COUNT */
/* ); */
/* if(ret != 0) { */
/* plasma_warning("plasma_unsetaffinity", "Could not unbind thread"); */
/* return PLASMA_ERR_UNEXPECTED; */
/* } */
}
#elif (defined PLASMA_OS_WINDOWS)
{
DWORD mask = 0;
for(i=0; i<sys_corenbr; i++)
mask |= 1 << i;
if( SetThreadAffinityMask(GetCurrentThread(), mask) == 0) {
plasma_warning("plasma_unsetaffinity", "Could not unbind thread");
}
}
#elif (defined PLASMA_OS_AIX)
{
/* TODO: check how to unbind the main thread if necessary for OpenMP */
/* tid_t self_ktid = thread_self (); */
/* bindprocessor(BINDTHREAD, self_ktid, rank); */
}
#else
#endif
#endif /* PLASMA_AFFINITY_DISABLE */
}

Here is the call graph for this function:

int plasma_yield ( )

A thread can unlock the CPU if it has nothing to do to let another thread of less priority running for example for I/O.

Definition at line 248 of file plasmaos.c.

References PLASMA_ERR_NOT_SUPPORTED.

{
#if (defined PLASMA_OS_LINUX) || (defined PLASMA_OS_MACOS) || (defined PLASMA_OS_AIX)
return sched_yield();
#elif PLASMA_OS_WINDOWS
return SleepEx(0,0);
#else
#endif
}