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 }
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); }
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); }
int graphInit ( Graph * const grafptr) { memSet (grafptr, 0, sizeof (Graph)); /* Initialize graph fields */ grafptr->flagval = GRAPHFREETABS; /* By default, free all arrays */ return (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 */ }
int symbolInit ( SymbolMatrix * const symbptr) { memSet (symbptr, 0, sizeof (SymbolMatrix)); #ifdef STARPU_GET_TASK_CTX symbptr->starpu_subtree_nbr=1; #endif return (0); }
/* ############################################################################# * * 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); }
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; }
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; }
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; }
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); }
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; }
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)); }
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; }
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; };
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; }
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 */ }
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; }
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; }
// проверить характеристику 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); }
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); }
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); }
TexObject::TexObject() { memSet(this, 0, sizeof(TexObject)); data = trash; }
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); } }
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); }
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 }