예제 #1
0
파일: os.cpp 프로젝트: Tauwasser/mame
	void* exec(const char* const* _argv)
	{
#if BX_PLATFORM_LINUX || BX_PLATFORM_HURD
		pid_t pid = fork();

		if (0 == pid)
		{
			int result = execvp(_argv[0], const_cast<char *const*>(&_argv[1]) );
			BX_UNUSED(result);
			return NULL;
		}

		return (void*)uintptr_t(pid);
#elif BX_PLATFORM_WINDOWS
		STARTUPINFO si;
		memSet(&si, 0, sizeof(STARTUPINFO) );
		si.cb = sizeof(STARTUPINFO);

		PROCESS_INFORMATION pi;
		memSet(&pi, 0, sizeof(PROCESS_INFORMATION) );

		int32_t total = 0;
		for (uint32_t ii = 0; NULL != _argv[ii]; ++ii)
		{
			total += (int32_t)strnlen(_argv[ii]) + 1;
		}

		char* temp = (char*)alloca(total);
		int32_t len = 0;
		for(uint32_t ii = 0; NULL != _argv[ii]; ++ii)
		{
			len += snprintf(&temp[len], bx::uint32_imax(0, total-len)
						, "%s "
						, _argv[ii]
						);
		}

		bool ok = !!CreateProcessA(_argv[0]
					, temp
					, NULL
					, NULL
					, false
					, 0
					, NULL
					, NULL
					, &si
					, &pi
					);
		if (ok)
		{
			return pi.hProcess;
		}

		return NULL;
#else
		BX_UNUSED(_argv);
		return NULL;
#endif // BX_PLATFORM_LINUX || BX_PLATFORM_HURD
	}
예제 #2
0
int
SCOTCH_graphMapInit (
const SCOTCH_Graph * const  grafptr,              /*+ Graph to map                    +*/
SCOTCH_Mapping * const      mappptr,              /*+ Mapping structure to initialize +*/
const SCOTCH_Arch * const   archptr,              /*+ Target architecture used to map +*/
SCOTCH_Num * const          parttab)              /*+ Mapping array                   +*/
{
  LibMapping * restrict lmapptr;

#ifdef SCOTCH_DEBUG_LIBRARY1
  if (sizeof (SCOTCH_Mapping) < sizeof (LibMapping)) {
    errorPrint ("SCOTCH_graphMapInit: internal error");
    return     (1);
  }
#endif /* SCOTCH_DEBUG_LIBRARY1 */

  lmapptr = (LibMapping *) mappptr;

  lmapptr->grafptr = (Graph *) grafptr;
  lmapptr->archptr = (Arch *)  archptr;
  lmapptr->flagval = LIBMAPPINGNONE;              /* No options set */
  if (parttab == NULL) {
    if ((lmapptr->parttab = (Gnum *) memAlloc (lmapptr->grafptr->vertnbr * sizeof (Gnum))) == NULL) {
      errorPrint ("SCOTCH_graphMapInit: out of memory");
      return     (1);
    }
    memSet (lmapptr->parttab, 0, lmapptr->grafptr->vertnbr * sizeof (Anum)); /* All vertices mapped to first domain    */
    lmapptr->flagval |= LIBMAPPINGFREEPART;       /* The user did not provided the partition array, so we will free it */
  }
  else
    lmapptr->parttab = (Gnum *) parttab;

  return (0);
}
예제 #3
0
파일: rsidengine.c 프로젝트: mstramb/websid
static void resetIO(unsigned long cyclesPerScreen, unsigned char isRsid) {
    memSet(&io_area[0], 0x0, IO_AREA_SIZE);

	// Master_Blaster_intro.sid actually checks this:
	io_area[0x0c01]= 0xff;	 	// Port B, keyboard matrix rows and joystick #1

	// CIA 1 defaults	(by default C64 is configured with CIA1 timer / not raster irq)
	setIO(0xdc0d, 0x81);	// interrupt control	(interrupt through timer A)
	setIO(0xdc0e, 0x01); 	// control timer A: start - must already be started (e.g. Phobia, GianaSisters, etc expect it)
	setIO(0xdc0f, 0x08); 	// control timer B (start/stop) means auto-restart
	setIO(0xdc04, cyclesPerScreen&0xff); 	// timer A (1x pro screen refresh)
	setIO(0xdc05, cyclesPerScreen>>8);
	
	if (isRsid) {	
		// by default C64 is configured with CIA1 timer / not raster irq
		setIO(0xd01a, 0x00); 	// raster irq not active
		setIO(0xd011, 0x1B);
		setIO(0xd012, 0x00); 	// raster at line x

		// CIA 2 defaults
		setIO(0xdd0e, 0x08); 	// control timer 2A (start/stop)
		setIO(0xdd0f, 0x08); 	// control timer 2B (start/stop)		
	}

	resetCiaTimer();
	resetVic();
	
	io_area[0x0418]= 0xf;					// turn on full volume	
	sidPoke(0x18, 0xf);  
}
예제 #4
0
int
graphInit (
Graph * const               grafptr)
{
  memSet (grafptr, 0, sizeof (Graph));            /* Initialize graph fields     */
  grafptr->flagval = GRAPHFREETABS;               /* By default, free all arrays */

  return (0);
}
예제 #5
0
void
graphExit (
Graph * const               grafptr)
{
  graphFree (grafptr);                            /* Free graph data */

#ifdef SCOTCH_DEBUG_GRAPH2
  memSet (grafptr, ~0, sizeof (Graph));           /* Purge graph fields */
#endif /* SCOTCH_DEBUG_GRAPH2 */
}
예제 #6
0
int
symbolInit (
SymbolMatrix * const        symbptr)
{
  memSet (symbptr, 0, sizeof (SymbolMatrix));
#ifdef STARPU_GET_TASK_CTX
  symbptr->starpu_subtree_nbr=1;
#endif
  return (0);
}
예제 #7
0
파일: memory.c 프로젝트: phaidros7/cpm
/* #############################################################################
 *
 * Description    free the given memory block
 * Author         Harry Brueckner
 * Date           2005-03-17
 * Arguments      char* ptr   - pointer to the given area
 *                size_t size - size of the area to free
 * Return         void
 */
void memRealFree(void* ptr, size_t size)
  {
    if (!ptr)
      { return; }

    /* update the memory counter */
    memorycounter -= size;

    memSet(ptr, 0, size);

    free(ptr);
  }
예제 #8
0
파일: math.cpp 프로젝트: fluffyfreak/bx
	void mtxRotateX(float* _result, float _ax)
	{
		const float sx = sin(_ax);
		const float cx = cos(_ax);

		memSet(_result, 0, sizeof(float)*16);
		_result[ 0] = 1.0f;
		_result[ 5] = cx;
		_result[ 6] = -sx;
		_result[ 9] = sx;
		_result[10] = cx;
		_result[15] = 1.0f;
	}
예제 #9
0
파일: math.cpp 프로젝트: fluffyfreak/bx
	void mtxRotateY(float* _result, float _ay)
	{
		const float sy = sin(_ay);
		const float cy = cos(_ay);

		memSet(_result, 0, sizeof(float)*16);
		_result[ 0] = cy;
		_result[ 2] = sy;
		_result[ 5] = 1.0f;
		_result[ 8] = -sy;
		_result[10] = cy;
		_result[15] = 1.0f;
	}
예제 #10
0
파일: math.cpp 프로젝트: fluffyfreak/bx
	void mtxRotateZ(float* _result, float _az)
	{
		const float sz = sin(_az);
		const float cz = cos(_az);

		memSet(_result, 0, sizeof(float)*16);
		_result[ 0] = cz;
		_result[ 1] = -sz;
		_result[ 4] = sz;
		_result[ 5] = cz;
		_result[10] = 1.0f;
		_result[15] = 1.0f;
	}
예제 #11
0
int
readMMHeader(
	     SCOTCH_Num * vertnbr,
	     SCOTCH_Num * edgenbr,
FILE * const stream)
{
  int c;
  SCOTCH_Num vertnum0, vertnum1;
  int symmetric = 0;
  char firstline[1024];
  int pos = 0;

  memSet(firstline, '\0', 1024);
  fgets(firstline, 16, stream);

  if (strcmp(firstline, "%%MatrixMarket "))
    return (-1);

  while (((c = fgetc(stream)) != '\n') && (c != EOF)) {
    firstline[pos++] = toupper(c);
    if (pos == 1024)
      return (-1);
  }
  firstline[pos] = '\0';

  if (strstr(firstline, "SYMMETRIC"))
    symmetric = 1;

  while ((c = fgetc(stream)) == '%') {
    if (skipLine(stream) != 0)
      return (-1);                                /* End of file reached */
  }
  ungetc (c, stream);

  if (intLoad (stream, &vertnum0) != 1) {         /* Read row number */
    return (-1);
  }
  if (intLoad (stream, &vertnum1) != 1) {         /* Read col number */
    return (-1);
  }
  if (vertnum0 != vertnum1) {                     /* Non square matrix */
      return (-1);
  }
  *vertnbr = vertnum1;
  if (intLoad (stream, edgenbr) != 1) { /* Read edge number */
    return (-1);
  }
  *edgenbr -= *vertnbr;           /* No loop in graph */
  return (symmetric);
}
예제 #12
0
파일: math.cpp 프로젝트: fluffyfreak/bx
	void mtxProjXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, float _far, bool _oglNdc)
	{
		const float diff = _far-_near;
		const float aa = _oglNdc ? (     _far+_near)/diff : _far/diff;
		const float bb = _oglNdc ? (2.0f*_far*_near)/diff : _near*aa;

		memSet(_result, 0, sizeof(float)*16);
		_result[ 0] = _width;
		_result[ 5] = _height;
		_result[ 8] = (Handness::Right == HandnessT) ?    _x :  -_x;
		_result[ 9] = (Handness::Right == HandnessT) ?    _y :  -_y;
		_result[10] = (Handness::Right == HandnessT) ?   -aa :   aa;
		_result[11] = (Handness::Right == HandnessT) ? -1.0f : 1.0f;
		_result[14] = -bb;
	}
예제 #13
0
void
SCOTCH_graphMapExit (
const SCOTCH_Graph * const  grafptr,
SCOTCH_Mapping * const      mappptr)
{
  LibMapping * restrict lmapptr;

  lmapptr = (LibMapping *) mappptr;
  
  if (((lmapptr->flagval & LIBMAPPINGFREEPART) != 0) && /* If parttab must be freed */
      (lmapptr->parttab != NULL))                 /* And if exists                   */
    memFree (lmapptr->parttab);                   /* Free it                         */

  memSet (lmapptr, 0, sizeof (LibMapping));
}
예제 #14
0
파일: math.cpp 프로젝트: fluffyfreak/bx
	void mtxRotateXY(float* _result, float _ax, float _ay)
	{
		const float sx = sin(_ax);
		const float cx = cos(_ax);
		const float sy = sin(_ay);
		const float cy = cos(_ay);

		memSet(_result, 0, sizeof(float)*16);
		_result[ 0] = cy;
		_result[ 2] = sy;
		_result[ 4] = sx*sy;
		_result[ 5] = cx;
		_result[ 6] = -sx*cy;
		_result[ 8] = -cx*sy;
		_result[ 9] = sx;
		_result[10] = cx*cy;
		_result[15] = 1.0f;
	}
예제 #15
0
파일: math.cpp 프로젝트: fluffyfreak/bx
	void mtxRotateZYX(float* _result, float _ax, float _ay, float _az)
	{
		const float sx = sin(_ax);
		const float cx = cos(_ax);
		const float sy = sin(_ay);
		const float cy = cos(_ay);
		const float sz = sin(_az);
		const float cz = cos(_az);

		memSet(_result, 0, sizeof(float)*16);
		_result[ 0] = cy*cz;
		_result[ 1] = cz*sx*sy-cx*sz;
		_result[ 2] = cx*cz*sy+sx*sz;
		_result[ 4] = cy*sz;
		_result[ 5] = cx*cz + sx*sy*sz;
		_result[ 6] = -cz*sx + cx*sy*sz;
		_result[ 8] = -sy;
		_result[ 9] = cy*sx;
		_result[10] = cx*cy;
		_result[15] = 1.0f;
	};
예제 #16
0
파일: math.cpp 프로젝트: fluffyfreak/bx
	void mtxOrthoImpl(float* _result, float _left, float _right, float _bottom, float _top, float _near, float _far, float _offset, bool _oglNdc)
	{
		const float aa = 2.0f/(_right - _left);
		const float bb = 2.0f/(_top - _bottom);
		const float cc = (_oglNdc ? 2.0f : 1.0f) / (_far - _near);
		const float dd = (_left + _right )/(_left   - _right);
		const float ee = (_top  + _bottom)/(_bottom - _top  );
		const float ff = _oglNdc
			? (_near + _far)/(_near - _far)
			:  _near        /(_near - _far)
			;

		memSet(_result, 0, sizeof(float)*16);
		_result[ 0] = aa;
		_result[ 5] = bb;
		_result[10] = (Handness::Right == HandnessT) ? -cc : cc;
		_result[12] = dd + _offset;
		_result[13] = ee;
		_result[14] = ff;
		_result[15] = 1.0f;
	}
예제 #17
0
void
graphFree (
Graph * const               grafptr)
{
  if (((grafptr->flagval & GRAPHFREEEDGE) != 0) && /* If edgetab must be freed */
      (grafptr->edgetax != NULL))                 /* And if it exists          */
    memFree (grafptr->edgetax + grafptr->baseval); /* Free it                  */

  if ((grafptr->flagval & GRAPHFREEVERT) != 0) {  /* If verttab/vendtab must be freed                            */
    if ((grafptr->vendtax != NULL) &&             /* If vendtax is distinct from verttab                         */
        (grafptr->vendtax != grafptr->verttax + 1) && /* (if vertex arrays grouped, vendtab not distinct anyway) */
        ((grafptr->flagval & GRAPHVERTGROUP) == 0))
      memFree (grafptr->vendtax + grafptr->baseval); /* Then free vendtax                                 */
    if (grafptr->verttax != NULL)                 /* Free verttab anyway, as it is the array group leader */
      memFree (grafptr->verttax + grafptr->baseval);
  }
  if ((grafptr->flagval & GRAPHFREEVNUM) != 0) {  /* If vnumtab must be freed         */
    if ((grafptr->vnumtax != NULL) &&             /* And is not in vertex array group */
        ((grafptr->flagval & GRAPHVERTGROUP) == 0))
      memFree (grafptr->vnumtax + grafptr->baseval);
  }
  if ((grafptr->flagval & GRAPHFREEOTHR) != 0) {  /* If other arrays must be freed */
    if ((grafptr->velotax != NULL) &&             /* Free graph tables             */
        ((grafptr->flagval & GRAPHVERTGROUP) == 0))
      memFree (grafptr->velotax + grafptr->baseval);
    if ((grafptr->vlbltax != NULL) &&
        ((grafptr->flagval & GRAPHVERTGROUP) == 0))
      memFree (grafptr->vlbltax + grafptr->baseval);
    if ((grafptr->edlotax != NULL) &&
        ((grafptr->flagval & GRAPHEDGEGROUP) == 0))
      memFree (grafptr->edlotax + grafptr->baseval);
  }

#ifdef SCOTCH_DEBUG_GRAPH2
  memSet (grafptr, ~0, sizeof (Graph));           /* Purge graph fields */
#endif /* SCOTCH_DEBUG_GRAPH2 */
  grafptr->flagval = GRAPHNONE;                   /* Allow to double-call graphFree or call graphExit */
}
예제 #18
0
파일: math.cpp 프로젝트: fluffyfreak/bx
	void mtxProjInfXYWH(float* _result, float _x, float _y, float _width, float _height, float _near, bool _oglNdc)
	{
		float aa;
		float bb;
		if (BX_ENABLED(NearFar::Reverse == NearFarT) )
		{
			aa = _oglNdc ?       -1.0f :   0.0f;
			bb = _oglNdc ? -2.0f*_near : -_near;
		}
		else
		{
			aa = 1.0f;
			bb = _oglNdc ? 2.0f*_near : _near;
		}

		memSet(_result, 0, sizeof(float)*16);
		_result[ 0] = _width;
		_result[ 5] = _height;
		_result[ 8] = (Handness::Right == HandnessT) ?    _x :  -_x;
		_result[ 9] = (Handness::Right == HandnessT) ?    _y :  -_y;
		_result[10] = (Handness::Right == HandnessT) ?   -aa :   aa;
		_result[11] = (Handness::Right == HandnessT) ? -1.0f : 1.0f;
		_result[14] = -bb;
	}
예제 #19
0
파일: math.cpp 프로젝트: fluffyfreak/bx
	void mtxLookAtImpl(float* _result, const float* _eye, const float* _view, const float* _up)
	{
		float up[3] = { 0.0f, 1.0f, 0.0f };
		if (NULL != _up)
		{
			up[0] = _up[0];
			up[1] = _up[1];
			up[2] = _up[2];
		}

		float tmp[4];
		vec3Cross(tmp, up, _view);

		float right[4];
		vec3Norm(right, tmp);

		vec3Cross(up, _view, right);

		memSet(_result, 0, sizeof(float)*16);
		_result[ 0] = right[0];
		_result[ 1] = up[0];
		_result[ 2] = _view[0];

		_result[ 4] = right[1];
		_result[ 5] = up[1];
		_result[ 6] = _view[1];

		_result[ 8] = right[2];
		_result[ 9] = up[2];
		_result[10] = _view[2];

		_result[12] = -vec3Dot(right, _eye);
		_result[13] = -vec3Dot(up, _eye);
		_result[14] = -vec3Dot(_view, _eye);
		_result[15] = 1.0f;
	}
예제 #20
0
파일: stamp.c 프로젝트: agievich/bee2
// проверить характеристику
void stampCheck(const char* name)
{
	HANDLE hFile;
	DWORD size;
	HANDLE hMapping;
	octet* image;
	DWORD offset;
	octet stamp[STAMP_SIZE];
	void* hash_state;
	bool_t success;
	// открыть файл
	hFile = CreateFileA(name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 
		FILE_ATTRIBUTE_NORMAL, NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		printf("File \"%s\" was not found or could not be open.\n", name);
		return;
	}
	// длина файла
	size = SetFilePointer(hFile, 0, NULL, FILE_END);
	if (size == INVALID_SET_FILE_POINTER)
	{
		CloseHandle(hFile);
		printf("Error processing the file \"%s\".\n", name);
		return;
	}
	// проецировать файл в память
	hMapping = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
	if (hMapping == NULL)
	{
		CloseHandle(hFile);
		printf("Error processing the file \"%s\".\n", name);
		return;
	}
	// отобразить файл в память
	image = (octet*)MapViewOfFile(hMapping, FILE_MAP_READ, 0, 0, 0);
	if (image == NULL)
	{
		CloseHandle(hMapping);
		CloseHandle(hFile);
		printf("Error processing the file \"%s\".\n", name);
		return;
	}
	// найти смещение контрольной характеристики
	offset = stampFindOffset(image, size);
	if (offset == (DWORD)-1)
	{
		UnmapViewOfFile(image);
		CloseHandle(hMapping);
		CloseHandle(hFile);
		printf("Control stamp of \"%s\" was not found or corrupted.\n", name);
		return;
	}
	// подготовить место для контрольной характеристики
	CASSERT(STAMP_SIZE >= 32);
	memSet(stamp, 0, STAMP_SIZE);
	// состояние хэширования
	hash_state = blobCreate(beltHash_keep());
	if (hash_state)
	{
		// хэшировать
		beltHashStart(hash_state);
		beltHashStepH(image, offset, hash_state);
		beltHashStepH(image + offset + STAMP_SIZE, 
			size - offset - STAMP_SIZE, hash_state);
		beltHashStepG(stamp, hash_state);
		blobClose(hash_state);
		// сравнить
		success = memEq(image + offset, stamp, STAMP_SIZE);
		printf("Integrity of \"%s\"... %s\n", name, success ? "OK" : "Failed");
		if (success)
			stampPrint(image + offset, "stamp");
		else
			stampPrint(image + offset, "read_stamp"),
			stampPrint(stamp, "calc_stamp");
	}
	else
		printf("Insufficient memory.\n");
	// очистка
	UnmapViewOfFile(image);
	CloseHandle(hMapping);
	CloseHandle(hFile);
}
예제 #21
0
void
METISNAMEU(METIS_PartGraphVKway) (
const int * const           n,
const int * const           xadj,
const int * const           adjncy,
const int * const           vwgt,
const int * const           vsize,
const int * const           wgtflag,
const int * const           numflag,
const int * const           nparts,
const int * const           options,
int * const                 volume,
int * const                 part)
{
  int                   baseval;
  const int *           vwgt2;
  const int *           vsize2;
  int                   vsizval;                  /* Communication volume of current vertex */
  int                   vertnbr;
  int                   vertnum;
  int                   edgenum;
  const int * restrict  edgetax;
  const int * restrict  parttax;
  int * restrict        nghbtab;
  int                   commvol;

  vsize2  = ((*wgtflag & 1) != 0) ? vsize : NULL;
  vwgt2   = ((*wgtflag & 2) != 0) ? vwgt  : NULL;
  baseval = *numflag;
  vertnbr = *n;
  edgetax = adjncy - baseval;

  if (vsize2 == NULL)                             /* If no communication load data provided */
    _SCOTCH_METIS_PartGraph (n, xadj, adjncy, vwgt2, NULL, numflag, nparts, part);
  else {                                          /* Will have to turn communication volumes into edge loads */
    const int * restrict  vsiztax;
    int                   edgenbr;
    int * restrict        edlotax;
    int                   o;

    edgenbr = xadj[vertnbr] - baseval;
    if ((edlotax = memAlloc (edgenbr * sizeof (int))) == NULL)
      return;
    edlotax -= baseval;                           /* Base access to edlotax */
    vsiztax  = vsize2 - baseval;

    for (vertnum = 0, edgenum = baseval;          /* Un-based scan of vertex array xadj */
         vertnum < vertnbr; vertnum ++) {
      int                 vsizval;                /* Communication size of current vertex */
      int                 edgennd;

      vsizval = vsize2[vertnum];
      for (edgennd = xadj[vertnum + 1]; edgenum < edgennd; edgenum ++) { /* Based traversal of edge array adjncy */
        int                 vertend;              /* Based end vertex number                                     */

        vertend = edgetax[edgenum];
        edlotax[edgenum] = vsizval + vsiztax[vertend];
      }
    }

    o = _SCOTCH_METIS_PartGraph (n, xadj, adjncy, vwgt2, edlotax + baseval, numflag, nparts, part);

    memFree (edlotax + baseval);

    if (o != 0)
      return;
  }

  if ((nghbtab = memAlloc (*nparts * sizeof (int))) == NULL)
    return;
  memSet (nghbtab, ~0, *nparts * sizeof (int));

  parttax = part - baseval;
  vsizval = 1;                                      /* Assume no vertex communication sizes */
  for (vertnum = 0, edgenum = baseval, commvol = 0; /* Un-based scan of vertex array xadj   */
       vertnum < vertnbr; vertnum ++) {
    int                 partval;
    int                 edgennd;

    partval = part[vertnum];
    nghbtab[partval] = vertnum;                   /* Do not count local neighbors in communication volume */
    if (vsize2 != NULL)
      vsizval = vsize2[vertnum];

    for (edgennd = xadj[vertnum + 1]; edgenum < edgennd; edgenum ++) { /* Based traversal of edge array adjncy */
      int                 vertend;                /* Based end vertex number                                   */
      int                 partend;

      vertend = edgetax[edgenum];
      partend = parttax[vertend];
      if (nghbtab[partend] != vertnum) {          /* If first neighbor in this part */
        nghbtab[partend] = vertnum;               /* Set part as accounted for      */
        commvol += vsizval;
      }
    }
  }
  *volume = commvol;

  memFree (nghbtab);
}
예제 #22
0
static
int
graphMapCompute2 (
SCOTCH_Graph * const        grafptr,              /*+ Graph to order                  +*/
SCOTCH_Mapping * const      mappptr,              /*+ Mapping to compute              +*/
SCOTCH_Mapping * const      mapoptr,              /*+ Old mapping                     +*/
const double                emraval,              /*+ Edge migration ratio            +*/ 
const SCOTCH_Num *          vmlotab,              /*+ Vertex migration cost array     +*/
Gnum                        vfixval,              /*+ Equal to 0 if no fixed vertices +*/
SCOTCH_Strat * const        straptr)              /*+ Mapping strategy                +*/
{
  Kgraph                mapgrafdat;               /* Effective mapping graph              */
  const Strat *         mapstraptr;               /* Pointer to mapping strategy          */
  LibMapping * restrict lmapptr;
  LibMapping * restrict lmaoptr;
  Anum *                pfixtax;
  Gnum                  baseval;
  Anum *                parttax;                  /* Partition array                      */
  Anum *                parotax;                  /* Old partition array                  */
  Gnum                  crloval;                  /* Coefficient load for regular edges   */
  Gnum                  cmloval;                  /* Coefficient load for migration edges */
  const Gnum *          vmlotax;                  /* Vertex migration cost array          */
  Gnum                  vertnum;
  Gnum                  vertnnd;
  Gnum                  vertnbr;
  int                   o;

  lmapptr = (LibMapping *) mappptr;
#ifdef SCOTCH_DEBUG_GRAPH2
  if ((Graph *) grafptr != lmapptr->grafptr) {
    errorPrint ("graphMapCompute2: output mapping does not correspond to input graph");
    return     (1);
  }
  if (graphCheck ((Graph *) grafptr) != 0) {      /* Vertex loads can be 0 if we have fixed vertices */
    errorPrint ("graphMapCompute2: invalid input graph");
    return     (1);
  }
#endif /* SCOTCH_DEBUG_GRAPH2 */

  if (*((Strat **) straptr) == NULL) {            /* Set default mapping strategy if necessary */
    ArchDom             archdomnorg;

    archDomFrst (lmapptr->archptr, &archdomnorg);
    SCOTCH_stratGraphMapBuild (straptr, SCOTCH_STRATDEFAULT, archDomSize (lmapptr->archptr, &archdomnorg), 0.01);
  }

  mapstraptr = *((Strat **) straptr);
  if (mapstraptr->tabl != &kgraphmapststratab) {
    errorPrint ("graphMapCompute2: not a graph mapping strategy");
    return     (1);
  }

  baseval = lmapptr->grafptr->baseval;
  vertnbr = lmapptr->grafptr->vertnbr;
  if (mapoptr != NULL) {                          /* We are doing a repartitioning */
    LibMapping *        lmaoptr;
    Gnum                numeval;
    Gnum                denoval;

    lmaoptr = (LibMapping *) mapoptr;
#ifdef SCOTCH_DEBUG_GRAPH2
    if (lmapptr->grafptr != lmaoptr->grafptr) {
      errorPrint ("graphMapCompute2: output and old mapping must correspond to the same graph");
      return     (1);
    }
    if (lmapptr->archptr != lmaoptr->archptr) {
      errorPrint ("graphMapCompute2: output and old mapping must correspond to the same architecture");
      return     (1);
    }
#endif /* SCOTCH_DEBUG_GRAPH2 */

    parotax = lmaoptr->parttab - baseval;
    vmlotax = (vmlotab != NULL) ? vmlotab - baseval : NULL;
    numeval = (INT) ((emraval * 100.0) + 0.5);
    denoval = intGcd (numeval, 100);
    cmloval = numeval / denoval;
    crloval = 100     / denoval;
  }
  else {
    parotax = NULL;
    vmlotax = NULL;
    cmloval =
    crloval = 1;
  }

  parttax = NULL;
  if (vfixval != 0) {                             /* We have fixed vertices */
#ifdef SCOTCH_DEBUG_GRAPH2
    if (lmapptr->parttab == NULL) {               /* We must have fixed vertices information */
      errorPrint ("graphMapCompute2: missing output mapping part array");
      return     (1);
    }
#endif /* SCOTCH_DEBUG_GRAPH2 */
    pfixtax = lmapptr->parttab - baseval;
    if ((parttax = (Anum *) memAlloc (vertnbr * sizeof (Anum))) == NULL) {
      errorPrint ("graphMapCompute2: out of memory (1)");
      return     (1);
    }
    memSet (parttax, 0, vertnbr * sizeof (Anum)); /* All vertices mapped to first domain */
    parttax -= baseval;
  } else {
    pfixtax = NULL;
    if (lmapptr->parttab == NULL) {               /* If user mapping not initialized */
      errorPrint ("graphMapCompute2: invalid user mapping");
      return     (1);
    }
    parttax = lmapptr->parttab - baseval;
  }

  intRandInit ();                                 /* Check that random number generator is initialized */

  if (kgraphInit (&mapgrafdat, (Graph *) grafptr, lmapptr->archptr, NULL, parttax, parotax, crloval, cmloval, vmlotax, pfixtax) != 0)
    return (1);

  o = 0;
  if (mapgrafdat.vfixnbr != mapgrafdat.s.vertnbr) { /* Perform mapping if not all fixed vertices */
    o = kgraphMapSt (&mapgrafdat, mapstraptr);

    lmapptr->parttab -= baseval;
    for (vertnum = baseval, vertnnd = vertnum + lmapptr->grafptr->vertnbr;
        vertnum < vertnnd; vertnum ++)
      lmapptr->parttab[vertnum] = archDomNum (lmapptr->archptr, &mapgrafdat.m.domntab[mapgrafdat.m.parttax[vertnum]]);
    lmapptr->parttab += baseval;
  }

  if (vfixval != 0)                               /* We have fixed vertices */
    memFree (parttax + baseval);

  kgraphExit (&mapgrafdat);

  return (o);
}
예제 #23
0
TexObject::TexObject()
{
	memSet(this, 0, sizeof(TexObject));
	data = trash;
}
예제 #24
0
int
bdgraphBipartBd (
Bdgraph * const                     orggrafptr,   /*+ Distributed graph +*/
const BdgraphBipartBdParam * const  paraptr)      /*+ Method parameters +*/
{
  Bdgraph                 bndgrafdat;             /* Bipartitioning band graph structure                          */
  Gnum                    bndvertancnnd;          /* End of local vertex array, without anchors                   */
  Gnum                    bndvertlocnbr1;         /* Number of band graph vertices in part 1 except anchor 1      */
  Gnum                    bndvertlocnum;
  Gnum                    bndvertlvlnum;          /* Based number of first band vertex in last layer              */
  Gnum                    bndvertlocancadj;       /* Flag set when anchor(s) represent unexistent vertices        */
  Gnum                    bndvertglbancadj;       /* Global adjustment of anchor vertices                         */
  Gnum                    bndveexlocsum;          /* Local sum of veexloctax array cells for band graph           */
  Gnum                    bndveexlocsum0;         /* Local sum of veexloctax array cells in part 0 for band graph */
  Gnum                    bndedlolocval;
  Gnum                    bndfronlocnum;
  Gnum                    orgfronlocnum;
  int * restrict          orgflagloctab;
  Gnum                    orgvertlocnum;
  Gnum                    orgedlolocval;
  const int * restrict    orgprocsidtab;
  int                     orgprocsidnbr;
  int                     orgprocsidnum;
  int                     orgprocsidval;
  Gnum                    complocsizeadj0;
  Gnum                    commlocloadintn;
  Gnum                    commlocloadintn2;       /* Twice twice (4 times) the internal communication load of last layer */
  Gnum                    commlocloadextn;
  Gnum                    commlocgainextn;
  Gnum                    reduloctab[7];
  Gnum                    reduglbtab[7];
  DgraphHaloRequest       requdat;

  if (orggrafptr->fronglbnbr == 0)                /* If no separator vertices, apply strategy to full (original) graph */
    return (bdgraphBipartSt (orggrafptr, paraptr->stratorg));

  if (dgraphBand (&orggrafptr->s, orggrafptr->fronlocnbr, orggrafptr->fronloctab, orggrafptr->partgsttax,
                  orggrafptr->complocload0, orggrafptr->s.velolocsum - orggrafptr->complocload0, paraptr->distmax,
                  &bndgrafdat.s, &bndgrafdat.fronloctab, &bndgrafdat.partgsttax,
                  &bndvertlvlnum, &bndvertlocnbr1, &bndvertlocancadj) != 0) {
    errorPrint ("bdgraphBipartBd: cannot create band graph");
    return     (1);
  }
  bndvertancnnd = bndgrafdat.s.vertlocnnd - 2;

  reduloctab[0]  = 0;                             /* Assume no memory allocation problem */
  bndveexlocsum  =
  bndveexlocsum0 = 0;
  bndgrafdat.veexloctax = NULL;                   /* Assume no external gains */
  if (orggrafptr->veexloctax != NULL) {
    if ((bndgrafdat.veexloctax = memAlloc (bndgrafdat.s.vertlocnbr * sizeof (Gnum))) == NULL) {
      errorPrint ("bdgraphBipartBd: out of memory (1)");
      reduloctab[0] = 1;                         /* Memory error */
    }
    else {
      Gnum                bndvertlocnum;

      bndgrafdat.veexloctax -= bndgrafdat.s.baseval;

      for (bndvertlocnum = bndgrafdat.s.baseval; bndvertlocnum < bndvertancnnd; bndvertlocnum ++) {
        Gnum                veexval;

        veexval = orggrafptr->veexloctax[bndgrafdat.s.vnumloctax[bndvertlocnum]];
        bndgrafdat.veexloctax[bndvertlocnum] = veexval;
        bndveexlocsum  += veexval;
        bndveexlocsum0 += veexval & (((Gnum) bndgrafdat.partgsttax[bndvertlocnum]) - 1);
      }
    }
  }
  reduloctab[1] = bndgrafdat.s.vendloctax[bndvertancnnd]     - bndgrafdat.s.vertloctax[bndvertancnnd]     - (orggrafptr->s.procglbnbr - 1); /* Anchor degrees */
  reduloctab[2] = bndgrafdat.s.vendloctax[bndvertancnnd + 1] - bndgrafdat.s.vertloctax[bndvertancnnd + 1] - (orggrafptr->s.procglbnbr - 1);

  bndgrafdat.complocsize0 = bndgrafdat.s.vertlocnbr - (bndvertlocnbr1 + 1); /* Add 1 for anchor vertex 1 */
  complocsizeadj0 = orggrafptr->complocsize0 - bndgrafdat.complocsize0; /* -1 less because of anchor 0   */
  reduloctab[3] = bndgrafdat.complocsize0;
  reduloctab[4] = bndvertlocancadj;               /* Sum increases in size and load */
  reduloctab[5] = bndveexlocsum;
  reduloctab[6] = bndveexlocsum0;
  if (MPI_Allreduce (reduloctab, reduglbtab, 7, GNUM_MPI, MPI_SUM, orggrafptr->s.proccomm) != MPI_SUCCESS) {
    errorPrint ("bdgraphBipartBd: communication error (1)");
    return     (1);
  }
  if (reduglbtab[0] != 0) {
    bdgraphExit (&bndgrafdat);
    return      (1);
  }
  if ((reduglbtab[1] == 0) ||                     /* If graph is too small to have any usable anchors */
      (reduglbtab[2] == 0)) {
    bdgraphExit (&bndgrafdat);
    return      (bdgraphBipartSt (orggrafptr, paraptr->stratorg));
  }

  bndvertglbancadj            = reduglbtab[4];
  bndgrafdat.veexglbsum       = orggrafptr->veexglbsum; /* All external gains preserved                  */
  bndgrafdat.fronlocnbr       = orggrafptr->fronlocnbr; /* All separator vertices are kept in band graph */
  bndgrafdat.fronglbnbr       = orggrafptr->fronglbnbr;
  bndgrafdat.complocload0     = orggrafptr->complocload0    + bndvertlocancadj; /* All loads are kept in band graph */
  bndgrafdat.compglbload0     = orggrafptr->compglbload0    + bndvertglbancadj;
  bndgrafdat.compglbload0min  = orggrafptr->compglbload0min + bndvertglbancadj; /* Tilt extrema loads according to adjustments */
  bndgrafdat.compglbload0max  = orggrafptr->compglbload0max + bndvertglbancadj;
  bndgrafdat.compglbload0avg  = orggrafptr->compglbload0avg + bndvertglbancadj; /* Tilt average load according to adjustments */
  bndgrafdat.compglbload0dlt  = orggrafptr->compglbload0dlt;
  bndgrafdat.compglbsize0     = reduglbtab[3];
  bndgrafdat.commglbload      = orggrafptr->commglbload;
  bndgrafdat.commglbgainextn  = orggrafptr->commglbgainextn;
  bndgrafdat.commglbloadextn0 = orggrafptr->commglbloadextn0;
  bndgrafdat.commglbgainextn0 = orggrafptr->commglbgainextn0;
  bndgrafdat.bbalglbval       = orggrafptr->bbalglbval;
  bndgrafdat.domndist         = orggrafptr->domndist;
  bndgrafdat.domnwght[0]      = orggrafptr->domnwght[0];
  bndgrafdat.domnwght[1]      = orggrafptr->domnwght[1];
  bndgrafdat.levlnum          = orggrafptr->levlnum;

  if (bndgrafdat.veexloctax != NULL) {
    Gnum                bndveexglbanc0;
    Gnum                bndveexglbanc1;

    bndveexglbanc0 = (orggrafptr->veexglbsum + orggrafptr->commglbgainextn) / 2 - reduglbtab[6]; /* Compute global external gains of anchors */
    bndveexglbanc1 = (orggrafptr->veexglbsum - bndveexglbanc0) - reduglbtab[5];

    bndgrafdat.veexloctax[bndvertancnnd]     = DATASIZE (bndveexglbanc0, bndgrafdat.s.procglbnbr, bndgrafdat.s.proclocnum); /* Spread gains across local anchors */
    bndgrafdat.veexloctax[bndvertancnnd + 1] = DATASIZE (bndveexglbanc1, bndgrafdat.s.procglbnbr, bndgrafdat.s.proclocnum);
  }

#ifdef SCOTCH_DEBUG_BDGRAPH2
  if (bdgraphCheck (&bndgrafdat) != 0) {
    errorPrint ("bdgraphBipartBd: internal error (1)");
    return     (1);
  }
#endif /* SCOTCH_DEBUG_BDGRAPH2 */

  if (bdgraphBipartSt (&bndgrafdat, paraptr->stratbnd) != 0) { /* Separate distributed band graph */
    errorPrint  ("bdgraphBipartBd: cannot separate band graph");
    bdgraphExit (&bndgrafdat);
    return      (1);
  }

  reduloctab[0] = (Gnum) bndgrafdat.partgsttax[bndvertancnnd]; /* Check if anchor vertices remain in their parts */
  reduloctab[1] = (Gnum) bndgrafdat.partgsttax[bndvertancnnd + 1];
  reduloctab[2] = complocsizeadj0;
  reduloctab[3] = 0;                              /* Assume memory allocation is all right */
  if ((orgflagloctab = memAlloc (flagSize (orggrafptr->s.vertlocnnd) * sizeof (int))) == NULL) { /* Eventually keep space for based indices */
    errorPrint ("bdgraphBipartBd: out of memory (2)");
    reduloctab[3] = 1;
  }

  if (MPI_Allreduce (&reduloctab[0], &reduglbtab[0], 4, GNUM_MPI, MPI_SUM, orggrafptr->s.proccomm) != MPI_SUCCESS) {
    errorPrint ("bdgraphBipartBd: communication error (2)");
    return     (1);
  }

  if (((reduglbtab[0] + reduglbtab[1]) != orggrafptr->s.procglbnbr)         || /* If not all anchors of initial same parts in same parts */
      ((reduglbtab[0] != 0) && (reduglbtab[0] != orggrafptr->s.procglbnbr)) ||
      (reduglbtab[3] != 0)) {
    if (orgflagloctab != NULL)
      memFree (orgflagloctab);
    bdgraphExit (&bndgrafdat);                    /* Apply original strategy to full graph */
    return      (bdgraphBipartSt (orggrafptr, paraptr->stratorg));
  }

  if (dgraphGhst (&bndgrafdat.s) != 0) {          /* Compute ghost edge array if not already present */
    errorPrint ("bdgraphBipartBd: cannot compute ghost edge array");
    return     (1);
  }

  if (reduglbtab[0] == orggrafptr->s.procglbnbr) { /* If all anchors swapped parts, swap all parts of original vertices */
    Gnum                orgvertnum;

    orggrafptr->complocsize0 = orggrafptr->s.vertlocnbr - reduloctab[2] - bndgrafdat.s.vertlocnbr + bndgrafdat.complocsize0;
    orggrafptr->compglbsize0 = orggrafptr->s.vertglbnbr - reduglbtab[2] - bndgrafdat.s.vertglbnbr + bndgrafdat.compglbsize0;

    for (orgvertnum = orggrafptr->s.baseval; orgvertnum < orggrafptr->s.vertlocnnd; orgvertnum ++)
      orggrafptr->partgsttax[orgvertnum] ^= 1;
  }
  else {
    orggrafptr->complocsize0 = reduloctab[2] + bndgrafdat.complocsize0;
    orggrafptr->compglbsize0 = reduglbtab[2] + bndgrafdat.compglbsize0;
  }

  for (bndvertlocnum = bndgrafdat.s.baseval; bndvertlocnum < bndvertancnnd; bndvertlocnum ++) /* Update part array of all vertices except anchors */
    orggrafptr->partgsttax[bndgrafdat.s.vnumloctax[bndvertlocnum]] = bndgrafdat.partgsttax[bndvertlocnum];

  dgraphHaloAsync (&orggrafptr->s, (byte *) (orggrafptr->partgsttax + orggrafptr->s.baseval), GRAPHPART_MPI, &requdat); /* Share part array of full graph */

  commlocloadintn =
  commlocloadextn =
  commlocgainextn = 0;
  bndedlolocval   = 1;                            /* Assume no edge loads */
  for (bndvertlocnum = bndgrafdat.s.baseval; bndvertlocnum < bndvertlvlnum; bndvertlocnum ++) { /* For all vertices of band graph save for last layer */
    Gnum                bndedgelocnum;
    Gnum                bndedgelocnnd;
    Gnum                bndpartval;

    bndpartval = (Gnum) bndgrafdat.partgsttax[bndvertlocnum];
    if (bndgrafdat.veexloctax != NULL) {
      commlocloadextn += bndgrafdat.veexloctax[bndvertlocnum] * bndpartval;
      commlocgainextn += bndgrafdat.veexloctax[bndvertlocnum] * (1 - bndpartval * 2);
    }
    for (bndedgelocnum = bndgrafdat.s.vertloctax[bndvertlocnum], bndedgelocnnd = bndgrafdat.s.vendloctax[bndvertlocnum];
         bndedgelocnum < bndedgelocnnd; bndedgelocnum ++) {
      Gnum                bndvertlocend;
      Gnum                bndpartend;

      bndvertlocend = bndgrafdat.s.edgegsttax[bndedgelocnum];
      bndpartend    = bndgrafdat.partgsttax[bndvertlocend];

      if (bndgrafdat.s.edloloctax != NULL)
        bndedlolocval = bndgrafdat.s.edloloctax[bndedgelocnum];
      commlocloadintn += (bndpartval ^ bndpartend) * bndedlolocval; /* Internal load is accounted for twice */
    }
  }
  for ( ; bndvertlocnum < bndvertancnnd; bndvertlocnum ++) { /* For all vertices of last layer, remove internal loads to band vertices once */
    Gnum                bndedgelocnum;
    Gnum                bndedgelocnnd;
    Gnum                bndpartval;

    bndpartval = (Gnum) bndgrafdat.partgsttax[bndvertlocnum];
    if (bndgrafdat.veexloctax != NULL) {
      commlocloadextn += bndgrafdat.veexloctax[bndvertlocnum] * bndpartval;
      commlocgainextn += bndgrafdat.veexloctax[bndvertlocnum] * (1 - bndpartval * 2);
    }
    for (bndedgelocnum = bndgrafdat.s.vertloctax[bndvertlocnum], bndedgelocnnd = bndgrafdat.s.vendloctax[bndvertlocnum] - 1; /* "-1" to avoid anchor edges */
         bndedgelocnum < bndedgelocnnd; bndedgelocnum ++) {
      Gnum                bndvertlocend;
      Gnum                bndpartend;

      bndvertlocend = bndgrafdat.s.edgegsttax[bndedgelocnum];
      bndpartend    = bndgrafdat.partgsttax[bndvertlocend];

      if (bndgrafdat.s.edloloctax != NULL)
        bndedlolocval = bndgrafdat.s.edloloctax[bndedgelocnum];
      commlocloadintn -= (bndpartval ^ bndpartend) * bndedlolocval; /* Remove internal loads to band graph vertices once because afterwards they will be accounted for twice */
    }
  }

  memSet (orgflagloctab, 0, flagSize (orggrafptr->s.vertlocnnd) * sizeof (int)); /* Set vertices as not already considered */

  for (bndfronlocnum = orgfronlocnum = 0; bndfronlocnum < bndgrafdat.fronlocnbr; bndfronlocnum ++) { /* Project back separator except for last layer */
    Gnum                bndvertlocnum;

    bndvertlocnum = bndgrafdat.fronloctab[bndfronlocnum];
    if (bndvertlocnum < bndvertlvlnum) {          /* If vertex does not belong to last layer */
      Gnum                orgvertlocnum;

      orgvertlocnum = bndgrafdat.s.vnumloctax[bndvertlocnum];
      flagSet (orgflagloctab, orgvertlocnum);     /* Set vertex as processed */
      orggrafptr->fronloctab[orgfronlocnum ++] = orgvertlocnum;
    }
  }

  if (dgraphHaloWait (&requdat) != 0) {
    errorPrint ("bdgraphBipartBd: cannot complete asynchronous halo exchange");
    return     (1);
  }

  orgedlolocval    = 1;                           /* Assume no edge loads */
  commlocloadintn2 = 0;
  for (bndvertlocnum = bndvertlvlnum; bndvertlocnum < bndvertancnnd; bndvertlocnum ++) { /* For all vertices of last layer */
    Gnum                orgedgelocnum;
    Gnum                orgedgelocnnd;
    Gnum                orgvertlocnum;
    GraphPart           orgpartval;
    Gnum                orgflagval;

    orgvertlocnum = bndgrafdat.s.vnumloctax[bndvertlocnum];
    orgpartval    = bndgrafdat.partgsttax[bndvertlocnum];

    orgflagval = 0;                               /* Assume vertex does not belong to the frontier */
    for (orgedgelocnum = orggrafptr->s.vertloctax[orgvertlocnum], orgedgelocnnd = orggrafptr->s.vendloctax[orgvertlocnum];
         orgedgelocnum < orgedgelocnnd; orgedgelocnum ++) {
      Gnum                orgvertlocend;
      Gnum                orgpartend;
      Gnum                orgflagtmp;

      orgvertlocend = orggrafptr->s.edgegsttax[orgedgelocnum];
      orgpartend    = orggrafptr->partgsttax[orgvertlocend];

      orgflagtmp = orgpartval ^ orgpartend;
      if (bndgrafdat.s.edloloctax != NULL)
        orgedlolocval = orggrafptr->s.edloloctax[orgedgelocnum];
      orgflagval       |= orgflagtmp;
      commlocloadintn2 += orgflagtmp * orgedlolocval; /* Internal load to band and original graph vertices are accounted for twice */
      if ((orgflagtmp != 0) && (orgvertlocend < orggrafptr->s.vertlocnnd) && (flagVal (orgflagloctab, orgvertlocend) == 0)) {
        orggrafptr->fronloctab[orgfronlocnum ++] = orgvertlocend;
        flagSet (orgflagloctab, orgvertlocend);
      }
    }
    if ((orgflagval != 0) && (flagVal (orgflagloctab, orgvertlocnum) == 0))
      orggrafptr->fronloctab[orgfronlocnum ++] = orgvertlocnum;

    flagSet (orgflagloctab, orgvertlocnum);       /* Set vertex as processed anyway */
  }
  commlocloadintn += 2 * commlocloadintn2;        /* Add twice the internal load of original graph edges and once the one of band edges (one removed before) */

  orggrafptr->complocload0    = bndgrafdat.complocload0 - bndvertlocancadj;
  orggrafptr->compglbload0    = bndgrafdat.compglbload0 - bndvertglbancadj;
  orggrafptr->compglbload0dlt = orggrafptr->compglbload0 - orggrafptr->compglbload0avg;

  orgprocsidnbr = orggrafptr->s.procsidnbr;
  if (orgprocsidnbr == 0)
    goto loop_exit;
  orgvertlocnum = orggrafptr->s.baseval;
  orgprocsidnum = 0;
  orgprocsidtab = orggrafptr->s.procsidtab;
  orgprocsidval = orgprocsidtab[orgprocsidnum ++];  
  while (1) {             /* Scan all vertices which have foreign neighbors */
    while (orgprocsidval < 0) {
      orgvertlocnum -= (Gnum) orgprocsidval;
      orgprocsidval  = orgprocsidtab[orgprocsidnum ++];  
    }

    if (flagVal (orgflagloctab, orgvertlocnum) == 0) { /* If vertex not already processed */
      Gnum                orgedgelocnum;
      Gnum                orgedgelocnnd;
      GraphPart           orgpartval;

      orgpartval = orggrafptr->partgsttax[orgvertlocnum];
      for (orgedgelocnum = orggrafptr->s.vertloctax[orgvertlocnum], orgedgelocnnd = orggrafptr->s.vendloctax[orgvertlocnum];
           orgedgelocnum < orgedgelocnnd; orgedgelocnum ++) {
        if (orggrafptr->partgsttax[orggrafptr->s.edgegsttax[orgedgelocnum]] != orgpartval) {
          orggrafptr->fronloctab[orgfronlocnum ++] = orgvertlocnum;
          break;
        }
      }
    }

    do {
      if (orgprocsidnum >= orgprocsidnbr)
        goto loop_exit;
    } while ((orgprocsidval = orgprocsidtab[orgprocsidnum ++]) >= 0);
  }
loop_exit :
  memFree (orgflagloctab);

  reduloctab[0] = commlocloadintn;                /* Twice the internal load; sum globally before dividing by two */
  reduloctab[1] = commlocloadextn;
  reduloctab[2] = commlocgainextn;
  reduloctab[3] = orgfronlocnum;
  if (MPI_Allreduce (&reduloctab[0], &reduglbtab[0], 4, GNUM_MPI, MPI_SUM, orggrafptr->s.proccomm) != MPI_SUCCESS) {
    errorPrint ("bdgraphBipartBd: communication error (3)");
    return     (1);
  }
  orggrafptr->fronlocnbr      = orgfronlocnum;
  orggrafptr->fronglbnbr      = reduglbtab[3];
  orggrafptr->commglbload     = (reduglbtab[0] / 2) * orggrafptr->domndist + reduglbtab[1];
  orggrafptr->commglbgainextn = reduglbtab[2];
  orggrafptr->bbalglbval      = (double) ((orggrafptr->compglbload0dlt < 0) ? (- orggrafptr->compglbload0dlt) : orggrafptr->compglbload0dlt) / (double) orggrafptr->compglbload0avg;

#ifdef SCOTCH_DEBUG_BDGRAPH2
  if (bdgraphCheck (orggrafptr) != 0) {
    errorPrint ("bdgraphBipartBd: internal error (2)");
    return     (1);
  }
#endif /* SCOTCH_DEBUG_BDGRAPH2 */

  bdgraphExit (&bndgrafdat);

  return (0);
}
void
METISNAMEU(ParMETIS_V3_NodeND) (
const int * const           vtxdist,
int * const                 xadj,
int * const                 adjncy,
const int * const           numflag,
const int * const           options,              /* Not used */
int * const                 order,
int * const                 sizes,                /* Of size twice the number of processors ; not used */
MPI_Comm *                  comm)
{
  MPI_Comm            proccomm;
  int                 procglbnbr;
  int                 proclocnum;
  SCOTCH_Num          baseval;
  SCOTCH_Dgraph       grafdat;                    /* Scotch distributed graph object to interface with libScotch    */
  SCOTCH_Dordering    ordedat;                    /* Scotch distributed ordering object to interface with libScotch */
  SCOTCH_Strat        stradat;
  SCOTCH_Num          vertlocnbr;
  SCOTCH_Num          edgelocnbr;

  if (sizeof (SCOTCH_Num) != sizeof (int)) {
    SCOTCH_errorPrint ("ParMETIS_V3_NodeND (as of SCOTCH): SCOTCH_Num type should equate to int");
    return;
  }

  proccomm = *comm;
  if (SCOTCH_dgraphInit (&grafdat, proccomm) != 0)
    return;

  MPI_Comm_size (proccomm, &procglbnbr);
  MPI_Comm_rank (proccomm, &proclocnum);
  baseval    = *numflag;
  vertlocnbr = vtxdist[proclocnum + 1] - vtxdist[proclocnum];
  edgelocnbr = xadj[vertlocnbr] - baseval;

  if (sizes != NULL)
    memSet (sizes, ~0, (2 * procglbnbr - 1) * sizeof (int)); /* Array not used if procglbnbr is not a power of 2 or if error */

  if (SCOTCH_dgraphBuild (&grafdat, baseval,
                          vertlocnbr, vertlocnbr, xadj, xadj + 1, NULL, NULL,
                          edgelocnbr, edgelocnbr, adjncy, NULL, NULL) == 0) {
    SCOTCH_stratInit (&stradat);
#ifdef SCOTCH_DEBUG_ALL
    if (SCOTCH_dgraphCheck (&grafdat) == 0)       /* TRICK: next instruction called only if graph is consistent */
#endif /* SCOTCH_DEBUG_ALL */
    {
      if (SCOTCH_dgraphOrderInit (&grafdat, &ordedat) == 0) {
        int                 levlmax;
        int                 bitsnbr;
        SCOTCH_Num          proctmp;

        SCOTCH_dgraphOrderCompute (&grafdat, &ordedat, &stradat);
        SCOTCH_dgraphOrderPerm    (&grafdat, &ordedat, order);

        for (levlmax = -1, bitsnbr = 0, proctmp = procglbnbr; /* Count number of bits set to 1 in procglbnbr */
             proctmp != 0; levlmax ++, proctmp >>= 1)
          bitsnbr += proctmp & 1;

        if (bitsnbr == 1) {
          SCOTCH_Num          cblkglbnbr;

          if ((cblkglbnbr = SCOTCH_dgraphOrderCblkDist (&grafdat, &ordedat)) >= 0) {
            SCOTCH_Num *        treeglbtab;
            SCOTCH_Num *        sizeglbtab;
            SCOTCH_Num *        sepaglbtab;

            if (memAllocGroup ((void **) (void *)
                               &treeglbtab, (size_t) (cblkglbnbr * sizeof (SCOTCH_Num)),
                               &sizeglbtab, (size_t) (cblkglbnbr * sizeof (SCOTCH_Num)),
                               &sepaglbtab, (size_t) (cblkglbnbr * sizeof (SCOTCH_Num) * 3), NULL) != NULL) {
              if (SCOTCH_dgraphOrderTreeDist (&grafdat, &ordedat, treeglbtab, sizeglbtab) == 0) {
                SCOTCH_Num          rootnum;
                SCOTCH_Num          cblknum;

                memSet (sepaglbtab, ~0, cblkglbnbr * sizeof (SCOTCH_Num) * 3);
                
                for (rootnum = -1, cblknum = 0; cblknum < cblkglbnbr; cblknum ++) {
                  SCOTCH_Num          fathnum;

                  fathnum = treeglbtab[cblknum] - baseval; /* Use un-based indices  */
                  if (fathnum < 0) {              /* If father index indicates root */
                    if (rootnum != -1) {          /* If another root already found  */
                      rootnum = -1;               /* Indicate an error              */
                      break;
                    }
                    rootnum = cblknum;            /* Record index of root node */
                  }
                  else {
                    int                 i;

                    for (i = 0; i < 3; i ++) {
                      int                 j;

                      j = 3 * fathnum + i;        /* Slot number of prospective son  */
                      if (sepaglbtab[j] < 0) {    /* If potentially empty slot found */
                        if (sepaglbtab[j] == -1)  /* If we don't have too many sons  */
                          sepaglbtab[j] = cblknum; /* Add link to son in slot        */
                        break;
                      }
                    }
                    if (i == 3) {                 /* If no empty slot found             */
                      sepaglbtab[3 * fathnum] = -2; /* Indicate there are too many sons */
                      break;
                    }
                  }
                }

                if ((rootnum >= 0) && (sizes != NULL)) { /* If no error above, go on processing separator tree  */
                  memSet (sizes, 0, (2 * procglbnbr - 1) * sizeof (int)); /* Set array of sizes to 0 by default */
                  _SCOTCH_ParMETIS_V3_NodeNDTree (sizes + (2 * procglbnbr - 1), sizeglbtab, sepaglbtab, levlmax, 0, rootnum, 1);
                }
              }

              memFree (treeglbtab);               /* Free group leader */
            }
          }
        }

        SCOTCH_dgraphOrderExit (&grafdat, &ordedat);
      }
    }
예제 #26
0
int
SCOTCH_graphMapView (
const SCOTCH_Graph * const    libgrafptr,
const SCOTCH_Mapping * const  libmappptr,
FILE * const                  stream)
{
  const Graph * restrict    grafptr;
  const Mapping * restrict  mappptr;
  Anum * restrict           parttax;              /* Part array                                   */
  MappingSort * restrict    domntab;              /* Pointer to domain sort array                 */
  ArchDom                   domnfrst;             /* Largest domain in architecture               */
  Anum                      tgtnbr;               /* Number of processors in target topology      */
  Anum                      mapnbr;               /* Number of processors effectively used        */
  Anum                      mapnum;
  double                    mapavg;               /* Average mapping weight                       */
  Gnum                      mapmin;
  Gnum                      mapmax;
  Gnum                      mapsum;               /* (Partial) sum of vertex loads                */
  double                    mapdlt;
  double                    mapmmy;               /* Maximum / average ratio                      */
  Anum * restrict           nghbtab;              /* Table storing neighbors of current subdomain */
  Anum                      nghbnbr;
  Anum                      nghbmin;
  Anum                      nghbmax;
  Anum                      nghbsum;
  Gnum                      vertnum;
  Gnum                      veloval;
  Gnum                      edloval;
  Gnum                      commdist[256];        /* Array of load distribution */
  Gnum                      commload;             /* Total edge load (edge sum) */
  Gnum                      commdilat;            /* Total edge dilation        */
  Gnum                      commexpan;            /* Total edge expansion       */
  Anum                      distmax;
  Anum                      distval;
  Gnum                      diammin;
  Gnum                      diammax;
  Gnum                      diamsum;

  const Gnum * restrict const verttax = ((Graph *) libgrafptr)->verttax;
  const Gnum * restrict const vendtax = ((Graph *) libgrafptr)->vendtax;
  const Gnum * restrict const velotax = ((Graph *) libgrafptr)->velotax;
  const Gnum * restrict const edgetax = ((Graph *) libgrafptr)->edgetax;
  const Gnum * restrict const edlotax = ((Graph *) libgrafptr)->edlotax;

  grafptr = (Graph *) libgrafptr;
  mappptr = &((LibMapping *) libmappptr)->m;

  if ((grafptr->vertnbr == 0) ||                  /* Return if nothing to do */
      (grafptr->edgenbr == 0))
    return (0);

  if (memAllocGroup ((void **) (void *)
                     &domntab, (size_t) ((grafptr->vertnbr + 1) * sizeof (MappingSort)),
                     &parttax, (size_t) (grafptr->vertnbr       * sizeof (Anum)),
                     &nghbtab, (size_t) ((grafptr->vertnbr + 2) * sizeof (Anum)), NULL) == NULL) {
    errorPrint ("SCOTCH_graphMapView: out of memory");
    return     (1);
  }

  memSet (parttax, ~0, grafptr->vertnbr * sizeof (Anum));

  for (vertnum = 0; vertnum < grafptr->vertnbr; vertnum ++) {
    parttax[vertnum]      =
    domntab[vertnum].labl = archDomNum (&mappptr->archdat, mapDomain (mappptr, vertnum + grafptr->baseval));
    domntab[vertnum].peri = vertnum + grafptr->baseval; /* Build inverse permutation */
  }
  domntab[grafptr->vertnbr].labl = ARCHDOMNOTTERM; /* TRICK: avoid testing (i+1)   */
  domntab[grafptr->vertnbr].peri = ~0;            /* Prevent Valgrind from yelling */
  parttax -= grafptr->baseval;                    /* From now on, base part array  */

  intSort2asc2 (domntab, grafptr->vertnbr);       /* Sort domain label array by increasing target labels */

  archDomFrst (&mappptr->archdat, &domnfrst);     /* Get architecture domain    */
  tgtnbr = archDomSize (&mappptr->archdat, &domnfrst); /* Get architecture size */

  mapsum  = 0;
  mapnbr  = 0;
  veloval = 1;                                    /* Assume unweighted vertices */
  for (vertnum = 0; domntab[vertnum].labl != ARCHDOMNOTTERM; vertnum ++) {
    parttax[domntab[vertnum].peri] = mapnbr;      /* Build map of partition parts starting from 0  */
    if (domntab[vertnum].labl != domntab[vertnum + 1].labl) /* TRICK: if new (or end) domain label */
      mapnbr ++;
    if (velotax != NULL)
      veloval = velotax[domntab[vertnum].peri];
    mapsum += veloval;
  }
  mapavg = (mapnbr == 0) ? 0.0L : (double) mapsum / (double) mapnbr;

  mapsum = 0;
  mapmin = GNUMMAX;
  mapmax = 0;
  mapdlt = 0.0L;
  for (vertnum = 0; domntab[vertnum].labl != ARCHDOMNOTTERM; vertnum ++) {
    if (velotax != NULL)
      veloval = velotax[domntab[vertnum].peri];
    mapsum += veloval;

    if (domntab[vertnum].labl != domntab[vertnum + 1].labl) { /* TRICK: if new (or end) domain label */
      if (mapsum < mapmin)
        mapmin = mapsum;
      if (mapsum > mapmax)
        mapmax = mapsum;
      mapdlt += fabs ((double) mapsum - mapavg);
      mapsum = 0;                                 /* Reset domain load sum */
    }
  }
  mapdlt = (mapnbr != 0) ? mapdlt / ((double) mapnbr * mapavg) : 0.0L;
  mapmmy = (mapnbr != 0) ? (double) mapmax / (double) mapavg : 0.0L;

  if (mapnbr > tgtnbr) {                          /* If more subdomains than architecture size */
#ifdef SCOTCH_DEBUG_MAP2
    if (! archVar (&mappptr->archdat)) {          /* If not a variable-sized architecture */
      errorPrint ("SCOTCH_graphMapView: invalid mapping");
      memFree    (domntab);                       /* Free group leader */
      return     (1);
    }
#endif /* SCOTCH_DEBUG_MAP2 */
    tgtnbr = mapnbr;                              /* Assume it is a variable-sized architecture */
  }

  fprintf (stream, "M\tProcessors " GNUMSTRING "/" GNUMSTRING " (%g)\n",
           (Gnum) mapnbr,
           (Gnum) tgtnbr,
           (double) mapnbr / (double) tgtnbr);
  fprintf (stream, "M\tTarget min=" GNUMSTRING "\tmax=" GNUMSTRING "\tavg=%g\tdlt=%g\tmaxavg=%g\n",
           (Gnum) mapmin,
           (Gnum) mapmax,
           mapavg,
           mapdlt,
           mapmmy);

  nghbnbr = 0;
  nghbmin = ANUMMAX;
  nghbmax = 0;
  nghbsum = 0;
  nghbnbr = 0;
  nghbtab[0] = -2;
  for (vertnum = 0; domntab[vertnum].labl != ARCHDOMNOTTERM; vertnum ++) {
    Gnum                edgenum;
    Gnum                edgennd;
    Anum                partnum;

    partnum = parttax[domntab[vertnum].peri];
    for (edgenum = verttax[domntab[vertnum].peri],
         edgennd = vendtax[domntab[vertnum].peri];
         edgenum < edgennd; edgenum ++) {
      Anum                partend;

      partend = parttax[edgetax[edgenum]];
      if ((partend != partnum) &&                 /* If edge is not internal                                      */
          (partend != nghbtab[nghbnbr])) {        /* And neighbor is not sole neighbor or has not just been found */
        Anum                partmin;
        Anum                partmax;

        partmin = 0;
        partmax = nghbnbr;
        while ((partmax - partmin) > 1) {
          Anum                partmed;

          partmed = (partmax + partmin) >> 1;
          if (nghbtab[partmed] > partend)
            partmax = partmed;
          else
            partmin = partmed;
        }
        if (nghbtab[partmin] == partend)          /* If neighboring part found, skip to next neighbor */
          continue;

#ifdef SCOTCH_DEBUG_MAP2
        if (nghbnbr >= (grafptr->vertnbr + 1)) {
          errorPrint ("SCOTCH_graphMapView: internal error");
          return (1);
        }
#endif /* SCOTCH_DEBUG_MAP2 */

        nghbnbr ++;
        for (partmax = nghbnbr; partmax > (partmin + 1); partmax --)
          nghbtab[partmax] = nghbtab[partmax - 1];
        nghbtab[partmin + 1] = partend;           /* Add new neighbor part in the right place */
      }
    }
    if (domntab[vertnum].labl != domntab[vertnum + 1].labl) { /* TRICK: if new (or end) domain label */
      if (nghbnbr < nghbmin)
        nghbmin = nghbnbr;
      if (nghbnbr > nghbmax)
        nghbmax = nghbnbr;
      nghbsum += nghbnbr;

      nghbnbr = 0;
    }
  }
int
SCOTCH_dgraphMapView (
SCOTCH_Dgraph * const         libgrafptr,
const SCOTCH_Dmapping * const libmappptr,
FILE * const                  stream)
{
  Dgraph * restrict             grafptr;
  const LibDmapping * restrict  mappptr;
  ArchDom                       domnfrst;         /* Largest domain in architecture          */
  unsigned int * restrict       nmskloctab;       /* Local neighbor bitfield                 */
  unsigned int * restrict       nmskglbtab;       /* Local neighbor bitfield                 */
  int                           nmskidxnbr;       /* Size of bitfield; int since sent by MPI */
  Gnum * restrict               tgloloctab;       /* Local array of terminal domain loads    */
  Gnum * restrict               tgloglbtab;       /* Global array of terminal domain loads   */
  Gnum * restrict               termgsttax;       /* Terminal domain ghost mapping array     */
  Anum                          tgtnbr;           /* Number of processors in target topology */
  Anum                          tgtnum;
  Anum                          mapnbr;           /* Number of processors effectively used   */
  double                        mapavg;           /* Average mapping weight                  */
  Gnum                          mapmin;
  Gnum                          mapmax;
  Gnum                          mapsum;           /* (Partial) sum of vertex loads           */
  double                        mapdlt;
  double                        mapmmy;           /* Maximum / average ratio                 */
  Anum                          ngbsum;
  Anum                          ngbmin;
  Anum                          ngbmax;
  Gnum                          vertlocnum;
  Gnum                          veloval;
  Gnum                          edloval;
  Gnum                          commlocdist[256 + 3]; /* Array of local load distribution    */
  Gnum                          commglbdist[256 + 3];
  Gnum                          commlocload;      /* Total local edge load (edge sum)        */
  Gnum                          commlocdilat;     /* Total edge dilation                     */
  Gnum                          commlocexpan;     /* Total edge expansion                    */
  Anum                          distmax;
  Anum                          distval;
  int                           cheklocval;
  int                           chekglbval;
  DgraphHaloRequest             requdat;

  grafptr = (Dgraph *) libgrafptr;
  mappptr = (LibDmapping *) libmappptr;

  if ((grafptr->vertglbnbr == 0) ||               /* Return if nothing to do */
      (grafptr->edgeglbnbr == 0))
    return (0);

  archDomFrst (&mappptr->m.archdat, &domnfrst);   /* Get architecture domain      */
  tgtnbr = archDomSize (&mappptr->m.archdat, &domnfrst); /* Get architecture size */

  if (archVar (&mappptr->m.archdat)) {
    errorPrint ("SCOTCH_dgraphMapView: not implemented");
    return     (1);
  }

  if (dgraphGhst (grafptr) != 0) {                /* Compute ghost edge array if not already present */
    errorPrint ("SCOTCH_dgraphMapView: cannot compute ghost edge array");
    return     (1);
  }

  nmskidxnbr = (tgtnbr + 1 + ((sizeof (int) << 3) - 1)) / (sizeof (int) << 3); /* Size of neighbor subdomain bitfield; TRICK: "+1" to have a "-1" cell for unmapped vertices */

  cheklocval = 0;
  if (memAllocGroup ((void **) (void *)
                     &nmskloctab, (size_t) (nmskidxnbr          * sizeof (unsigned int)),
                     &nmskglbtab, (size_t) (nmskidxnbr          * sizeof (unsigned int)),
                     &tgloloctab, (size_t) ((tgtnbr + 1)        * sizeof (Gnum)), /* TRICK: "+1" to have a "-1" cell for unmapped vertices */
                     &tgloglbtab, (size_t) (tgtnbr              * sizeof (Gnum)),
                     &termgsttax, (size_t) (grafptr->vertgstnbr * sizeof (Gnum)), NULL) == NULL) {
    cheklocval = 1;
  }
  if (MPI_Allreduce (&cheklocval, &chekglbval, 1, MPI_INT, MPI_MAX, grafptr->proccomm) != MPI_SUCCESS) {
    errorPrint ("SCOTCH_dgraphMapView: communication error (1)");
    return     (1);
  }
  if (chekglbval != 0) {
    if (nmskloctab != NULL)
      memFree (nmskloctab);
    errorPrint ("SCOTCH_dgraphMapView: out of memory");
    return     (1);
  }

  if (dmapTerm (&mappptr->m, grafptr, termgsttax) != 0) {
    errorPrint ("SCOTCH_dgraphMapView: cannot build local terminal array");
    memFree    (nmskloctab);
    return     (1);
  }
  dgraphHaloAsync (grafptr, termgsttax, GNUM_MPI, &requdat);
  termgsttax -= grafptr->baseval;

  memSet (tgloloctab, 0, (tgtnbr + 1) * sizeof (Gnum));
  tgloloctab ++;                                  /* TRICK: trim array for "-1" cell */

  veloval = 1;
  for (vertlocnum = grafptr->baseval; vertlocnum < grafptr->vertlocnnd; vertlocnum ++) {
#ifdef SCOTCH_DEBUG_DMAP2
    if ((termgsttax[vertlocnum] < -1) || (termgsttax[vertlocnum] >= tgtnbr)) {
      errorPrint ("SCOTCH_dgraphMapView: invalid local terminal array");
      memFree    (nmskloctab);                      /* Free group leader */
      return     (1);
    }
#endif /* SCOTCH_DEBUG_DMAP2 */
    if (grafptr->veloloctax != NULL)
      veloval = grafptr->veloloctax[vertlocnum];
    tgloloctab[termgsttax[vertlocnum]] += veloval; /* One more vertex of given weight assigned to this target */
  }

  if (MPI_Allreduce (tgloloctab, tgloglbtab, tgtnbr, GNUM_MPI, MPI_SUM, grafptr->proccomm) != MPI_SUCCESS) {
    errorPrint ("SCOTCH_dgraphMapView: communication error (2)");
    memFree    (nmskloctab);                      /* Free group leader */
    return     (1);
  }

  mapmin = GNUMMAX;
  mapmax = 0;
  mapsum = 0;
  mapnbr = 0;
  for (tgtnum = 0; tgtnum < tgtnbr; tgtnum ++) {
    Gnum                tgtsum;

    tgtsum = tgloglbtab[tgtnum];
    if (tgtsum != 0) {
      mapnbr ++;
      mapsum += tgtsum;
      if (tgtsum < mapmin)
        mapmin = tgtsum;
      if (tgtsum > mapmax)
        mapmax = tgtsum;
    }
  }
  mapavg = (mapnbr == 0) ? 0.0L : ((double) mapsum / (double) mapnbr);

  mapdlt = 0.0L;
  for (tgtnum = 0; tgtnum < tgtnbr; tgtnum ++)
    mapdlt += fabs ((double) tgloglbtab[tgtnum] - mapavg);
  mapdlt = (mapnbr != 0) ? mapdlt / ((double) mapnbr * mapavg) : 0.0L;
  mapmmy = (mapnbr != 0) ? (double) mapmax / (double) mapavg : 0.0L;

  if (stream != NULL) {
    fprintf (stream, "M\tProcessors " GNUMSTRING "/" GNUMSTRING "(%g)\n",
             (Gnum) mapnbr,
             (Gnum) tgtnbr,
             (double) mapnbr / (double) tgtnbr);
    fprintf (stream, "M\tTarget min=" GNUMSTRING "\tmax=" GNUMSTRING "\tavg=%g\tdlt=%g\tmaxavg=%g\n",
             (Gnum) mapmin,
             (Gnum) mapmax,
             mapavg,
             mapdlt,
             mapmmy);
  }

  if (dgraphHaloWait (&requdat) != 0) {           /* Wait for ghost terminal data to be exchanged */
    errorPrint ("SCOTCH_dgraphMapView: cannot complete asynchronous halo exchange");
    memFree    (nmskloctab);                      /* Free group leader */
    return     (1);
  }

  ngbmin = ANUMMAX;
  ngbmax = 0;
  ngbsum = 0;
  for (tgtnum = 0; tgtnum < tgtnbr; tgtnum ++) {  /* For all subdomain indices */
    int                 nmskidxnum;
    Gnum                vertlocnum;
    Anum                ngbnbr;

    if (tgloglbtab[tgtnum] <= 0)                  /* If empty subdomain, skip it */
      continue;

    memSet (nmskloctab, 0, nmskidxnbr * sizeof (int)); /* Reset neighbor bit mask */

    for (vertlocnum = grafptr->baseval; vertlocnum < grafptr->vertlocnnd; vertlocnum ++) { /* For all local vertices */
      Gnum                termnum;
      Gnum                edgelocnum;
      Gnum                edgelocnnd;

      termnum = termgsttax[vertlocnum];
      if (termnum != tgtnum)                      /* If vertex does not belong to current part or is not mapped, skip it */
        continue;

      for (edgelocnum = grafptr->vertloctax[vertlocnum], edgelocnnd = grafptr->vendloctax[vertlocnum];
           edgelocnum < edgelocnnd; edgelocnum ++) {
        Gnum                termend;

        termend = termgsttax[grafptr->edgegsttax[edgelocnum]];
        if (termend != tgtnum) {                  /* If edge is not internal             */
          termend ++;                             /* TRICK: turn unmapped to 0 and so on */
          nmskloctab[termend / (sizeof (int) << 3)] |= 1 << (termend & ((sizeof (int) << 3) - 1)); /* Flag neighbor in bit array */
        }
      }
    }
    nmskloctab[0] &= ~1;                          /* Do not account for unmapped vertices (terminal domain 0 because of "+1") */

    if (MPI_Allreduce (nmskloctab, nmskglbtab, nmskidxnbr, MPI_INT, MPI_BOR, grafptr->proccomm) != MPI_SUCCESS) {
      errorPrint ("SCOTCH_dgraphMapView: communication error (3)");
      memFree    (nmskloctab);                    /* Free group leader */
      return     (1);
    }

    for (nmskidxnum = 0, ngbnbr = 0; nmskidxnum < nmskidxnbr; nmskidxnum ++) {
      unsigned int        nmskbitval;

      for (nmskbitval = nmskglbtab[nmskidxnum]; nmskbitval != 0; nmskbitval >>= 1)
        ngbnbr += nmskbitval & 1;
    }

    ngbsum += ngbnbr;
    if (ngbnbr < ngbmin)
      ngbmin = ngbnbr;
    if (ngbnbr > ngbmax)
      ngbmax = ngbnbr;
  }

  if (stream != NULL) {
    fprintf (stream, "M\tNeighbors min=" GNUMSTRING "\tmax=" GNUMSTRING "\tsum=" GNUMSTRING "\n",
             (Gnum) ngbmin,
             (Gnum) ngbmax,
             (Gnum) ngbsum);
  }

  memSet (commlocdist, 0, 256 * sizeof (Gnum));   /* Initialize the data */
  commlocload  =
  commlocdilat =
  commlocexpan = 0;

  edloval = 1;
  for (vertlocnum = grafptr->baseval; vertlocnum < grafptr->vertlocnnd; vertlocnum ++) { /* For all local vertices */
    Gnum                termlocnum;
    ArchDom             termdomdat;
    Gnum                edgelocnum;
    Gnum                edgelocnnd;

    termlocnum = termgsttax[vertlocnum];
    if (termlocnum == ~0)                         /* Skip unmapped vertices */
      continue;

    archDomTerm (&mappptr->m.archdat, &termdomdat, termlocnum);

    for (edgelocnum = grafptr->vertloctax[vertlocnum], edgelocnnd = grafptr->vendloctax[vertlocnum];
         edgelocnum < edgelocnnd; edgelocnum ++) {
      ArchDom             termdomend;
      Gnum                termgstend;
      Anum                distval;

      termgstend = termgsttax[grafptr->edgegsttax[edgelocnum]];
      if (termgstend == ~0)                       /* Skip unmapped end vertices */
        continue;

      distval = 0;
      if (grafptr->edloloctax != NULL)            /* Get edge weight if any */
        edloval = grafptr->edloloctax[edgelocnum];
      if (termgstend != termlocnum) {             /* If not same domain, compute distance */
        archDomTerm (&mappptr->m.archdat, &termdomend, termgstend);
        distval = archDomDist (&mappptr->m.archdat, &termdomdat, &termdomend);
      }
      commlocdist[(distval > 255) ? 255 : distval] += edloval;
      commlocload  += edloval;
      commlocdilat += distval;
      commlocexpan += distval * edloval;
    }
  }
  commlocdist[256]     = commlocload;
  commlocdist[256 + 1] = commlocdilat;
  commlocdist[256 + 2] = commlocexpan;

  if (MPI_Allreduce (commlocdist, commglbdist, 256 + 3, GNUM_MPI, MPI_SUM, grafptr->proccomm) != MPI_SUCCESS) {
    errorPrint ("SCOTCH_dgraphMapView: communication error (4)");
    memFree    (nmskloctab);                      /* Free group leader */
    return     (1);
  }

  if (stream != NULL) {
    Gnum                commglbload;

    commglbload = commglbdist[256];
    fprintf (stream, "M\tCommDilat=%f\t(" GNUMSTRING ")\n", /* Print expansion parameters */
           (double) commglbdist[256 + 1] / grafptr->edgeglbnbr,
           (Gnum) (commglbdist[256 + 1] / 2));
    fprintf (stream, "M\tCommExpan=%f\t(" GNUMSTRING ")\n",
             ((commglbload == 0) ? (double) 0.0L
                                 : (double) commglbdist[256 + 2] / (double) commglbload),
             (Gnum) (commglbdist[256 + 2] / 2));
    fprintf (stream, "M\tCommCutSz=%f\t(" GNUMSTRING ")\n",
             ((commglbload == 0) ? (double) 0.0L
                                 : (double) (commglbload - commglbdist[0]) / (double) commglbload),
             (Gnum) ((commglbload - commglbdist[0]) / 2));
    fprintf (stream, "M\tCommDelta=%f\n",
             (((double) commglbload  * (double) commglbdist[256 + 1]) == 0.0L)
             ? (double) 0.0L
             : ((double) commglbdist[256 + 2] * (double) grafptr->edgeglbnbr) /
               ((double) commglbload * (double) commglbdist[256 + 2]));

    for (distmax = 255; distmax != -1; distmax --)  /* Find longest distance */
      if (commglbdist[distmax] != 0)
        break;
    for (distval = 0; distval <= distmax; distval ++) /* Print distance histogram */
      fprintf (stream, "M\tCommLoad[" ANUMSTRING "]=%f\n",
               (Anum) distval,
               (double) commglbdist[distval] / (double) commglbload);
  }

  memFree (nmskloctab);                           /* Free group leader */

  return (0);
}
예제 #28
0
static void kHeap1_execute(void) 
{
	int i;
	void* pMem[5];

	// Test 0 
	pMem[0] = CoKmalloc(0);
	testAssert((pMem[0] == NULL),"#0.0");

	// Test 1 malloc all the heap
	pMem[0] = CoKmalloc(TEST_HEAP_SIZE-SYS_HEAP_RESVD_SIZE);
	testAssert((pMem[0] != NULL),"#0");
	
	memSet(pMem[0],TEST_HEAP_SIZE-SYS_HEAP_RESVD_SIZE);

	// Test 2 free the Mem alloced
	CoKfree(pMem[0]);

	// Can if malloc all the heap successful
	pMem[0] = CoKmalloc(TEST_HEAP_SIZE-SYS_HEAP_RESVD_SIZE);
	testAssert((pMem[0] != NULL),"#1");
	memSet(pMem[0],TEST_HEAP_SIZE-SYS_HEAP_RESVD_SIZE);
	CoKfree(pMem[0]);


	// Test 3 Free in positive sequence
	for(i = 0; i < 5; i++)
	{
		pMem[i] = CoKmalloc((10*i) + 1);
		testAssert((pMem[i] != NULL),"#2");
		//memSet(pMem[i],10*i);
	}


	for(i = 0; i < 5; i++) 
	{
	 	CoKfree(pMem[i]);	
	}
	// Can if malloc all the heap successful(if there is mem fragmentation)
	pMem[0] = CoKmalloc(TEST_HEAP_SIZE-SYS_HEAP_RESVD_SIZE);
	testAssert((pMem[0] != NULL),"#3");	
	memSet(pMem[0],TEST_HEAP_SIZE-SYS_HEAP_RESVD_SIZE);
	CoKfree(pMem[0]);

	// Test 4 Free in inverted sequence
   	for(i = 0; i < 5; i++)
	{
		pMem[i] = CoKmalloc(10*i + 1);
		testAssert((pMem[i] != NULL),"#4");
		memSet(pMem[i],10*i);
	}
	for(i = 0; i < 5; i++) 
	{
	 	CoKfree(pMem[4-i]);	
	}
	// Can if malloc all the heap successful(if there is mem fragmentation)
	pMem[0] = CoKmalloc(TEST_HEAP_SIZE-SYS_HEAP_RESVD_SIZE);
	testAssert((pMem[0] != NULL),"#5");	
	memSet(pMem[0],TEST_HEAP_SIZE-SYS_HEAP_RESVD_SIZE);
	CoKfree(pMem[0]);

	// Test 5 Free in custom sequence
	for(i = 0; i < 5; i++)
	{
		pMem[i] = CoKmalloc(10*i + 1);
		testAssert((pMem[i] != NULL),"#6");
		memSet(pMem[i],10*i);
	}
	// Free the most left block
	CoKfree(pMem[0]);

	// Free the most right block
	CoKfree(pMem[4]);

	// Free the center block
	CoKfree(pMem[2]);

	CoKfree(pMem[3]);
	CoKfree(pMem[1]);

	// Can if malloc all the heap successful(if there is mem fragmentation)
	pMem[0] = CoKmalloc(TEST_HEAP_SIZE-SYS_HEAP_RESVD_SIZE);
	testAssert((pMem[0] != NULL),"#7");	
	memSet(pMem[0],TEST_HEAP_SIZE-SYS_HEAP_RESVD_SIZE);
	CoKfree(pMem[0]);






}
//内存管理初始化  
//memx:所属内存块
void memInit(void)  
{  
  memSet(mallco_dev.memmap, 0,memtblsize*2);//内存状态表数据清零  
	memSet(mallco_dev.membase, 0,memsize);	//内存池所有数据清零  
	mallco_dev.memrdy=1;								//内存管理初始化OK  
}