Actual source code: sseenabled.c

  1: /* $Id: sseenabled.c,v 1.15 2001/07/20 21:03:24 buschelm Exp $ */
 2:  #include petscsys.h

  4: #ifdef PETSC_HAVE_SSE

  6: #include PETSC_HAVE_SSE
  7: #define SSE_FEATURE_FLAG 0x2000000 /* Mask for bit 25 (from bit 0) */

  9: #include <string.h>

 11: int PetscSSEHardwareTest(PetscTruth *flag) {
 12:   int  ierr;
 13:   char *vendor;
 14:   char Intel[13]="GenuineIntel";
 15:   char AMD[13]  ="AuthenticAMD";

 18:   PetscMalloc(13*sizeof(char),&vendor);
 19:   strcpy(vendor,"************");
 20:   CPUID_GET_VENDOR(vendor);
 21:   if (!strcmp(vendor,Intel) || !strcmp(vendor,AMD)) {
 22:     /* Both Intel and AMD use bit 25 of CPUID_FEATURES */
 23:     /* to denote availability of SSE Support */
 24:     unsigned long myeax,myebx,myecx,myedx;
 25:     CPUID(CPUID_FEATURES,&myeax,&myebx,&myecx,&myedx);
 26:     if (myedx & SSE_FEATURE_FLAG) {
 27:       *flag = PETSC_TRUE;
 28:     } else {
 29:       *flag = PETSC_FALSE;
 30:     }
 31:   }
 32:   PetscFree(vendor);
 33:   return(0);
 34: }

 36: #ifdef PARCH_linux
 37: #include <signal.h>
 38: /* 
 39:    Early versions of the Linux kernel disables SSE hardware because
 40:    it does not know how to preserve the SSE state at a context switch.
 41:    To detect this feature, try an sse instruction in another process.  
 42:    If it works, great!  If not, an illegal instruction signal will be thrown,
 43:    so catch it and return an error code. 
 44: */
 45: #define PetscSSEOSEnabledTest(arg) PetscSSEOSEnabledTest_Linux(arg)

 47: static void PetscSSEDisabledHandler(int sig) {
 48:   signal(SIGILL,SIG_IGN);
 49:   exit(-1);
 50: }

 52: int PetscSSEOSEnabledTest_Linux(PetscTruth *flag) {
 53:   int status, pid = 0;
 55:   signal(SIGILL,PetscSSEDisabledHandler);
 56:   pid = fork();
 57:   if (pid==0) {
 58:     SSE_SCOPE_BEGIN;
 59:       XOR_PS(XMM0,XMM0);
 60:     SSE_SCOPE_END;
 61:     exit(0);
 62:   } else {
 63:     wait(&status);
 64:   }
 65:   if (!status) {
 66:     *flag = PETSC_TRUE;
 67:   } else {
 68:     *flag = PETSC_FALSE;
 69:   }
 70:   return(0);
 71: }

 73: #endif
 74: #ifdef PARCH_win32
 75: /* 
 76:    Windows 95/98/NT4 should have a Windows Update/Service Patch which enables this hardware.
 77:    Windows ME/2000 doesn't disable SSE Hardware 
 78: */
 79: #define PetscSSEOSEnabledTest(arg) PetscSSEOSEnabledTest_TRUE(arg)

 81: int PetscSSEOSEnabledTest_TRUE(PetscTruth *flag) {
 83:   *flag = PETSC_TRUE;
 84:   return(0);
 85: }

 87: #endif 
 88: #else  /* Not defined PETSC_HAVE_SSE */

 90: #define PetscSSEHardwareTest(arg) 0
 91: #define PetscSSEOSEnabledTest(arg) 0

 93: #endif /* defined PETSC_HAVE_SSE */

 95: /*@C
 96:      PetscSSEIsEnabled - Determines if Intel Streaming SIMD Extensions to the x86 instruction 
 97:      set can be used.  Some operating systems do not allow the use of these instructions despite
 98:      hardware availability.

100:      Collective on MPI_Comm

102:      Input Parameter:
103: .    comm - the MPI Communicator

105:      Output Parameters:
106: .    lflag - Local Flag:  PETSC_TRUE if enabled in this process
107: .    gflag - Global Flag: PETSC_TRUE if enabled for all processes in comm

109:      Level: developer
110: @*/
111: int PetscSSEIsEnabled(MPI_Comm comm,PetscTruth *lflag,PetscTruth *gflag) {
114:   *lflag = PETSC_FALSE;
115:   *gflag = PETSC_FALSE;
116:   PetscSSEHardwareTest(lflag);
117:   if (*lflag) {
118:     PetscSSEOSEnabledTest(lflag);
119:   }
120:   MPI_Allreduce(gflag,lflag,1,MPI_INT,MPI_LAND,comm);
121:   return(0);
122: }