void SpriteSheet::ExtractSpriteFrom( char* Grid, int GridW, int GridH, int StartX, int StartY ) { // Know where we start gridalloc_minx = StartX; gridalloc_miny = StartY; gridalloc_maxx = StartX; gridalloc_maxy = StartY; // Follow the grid around for adjactent [1] cells AllocateGrid( Grid, GridW, GridH, StartX, StartY ); // Add sprite to sheet AddSprite( gridalloc_minx * gridalloc_size, gridalloc_miny * gridalloc_size, ((gridalloc_maxx - gridalloc_minx) + 1) * gridalloc_size, ((gridalloc_maxy - gridalloc_miny) + 1) * gridalloc_size ); }
GridMemStruct* GridMemList_AddGridDesc(GridDesc* pgrid) { GridMemStruct* pnewGridMemStruct; //printf("IN: GridMemList_AddGridDesc\n"); pnewGridMemStruct = (GridMemStruct*) malloc(sizeof(GridMemStruct)); pnewGridMemStruct->pgrid = (GridDesc*) malloc(sizeof(GridDesc)); *(pnewGridMemStruct->pgrid) = *pgrid; strcpy(pnewGridMemStruct->pgrid->chr_type, pgrid->chr_type); strcpy(pnewGridMemStruct->pgrid->title, pgrid->title); pnewGridMemStruct->buffer = AllocateGrid(pnewGridMemStruct->pgrid); pnewGridMemStruct->array = CreateGridArray(pnewGridMemStruct->pgrid); pnewGridMemStruct->active = 1; pnewGridMemStruct->grid_read = 0; GridMemList_AddElement(pnewGridMemStruct); return(pnewGridMemStruct); }
void SpriteSheet::AllocateGrid( char* Grid, int GridW, int GridH, int StartX, int StartY ) { // Allocate tile Grid[ (StartY * GridW) + StartX ] = 2; if( StartX < gridalloc_minx ) { gridalloc_minx = StartX; } if( StartY < gridalloc_miny ) { gridalloc_miny = StartY; } if( StartX > gridalloc_maxx ) { gridalloc_maxx = StartX; } if( StartY > gridalloc_maxy ) { gridalloc_maxy = StartY; } for( int y = -1; y < 2; y++ ) { for( int x = -1; x < 2; x++ ) { if( y != 0 || x != 0 ) { if( StartX + x >= 0 && StartX + x < GridW && StartY + y >= 0 && StartY + y < GridH ) { // Adjacent tile exists, is it for allocating? if( Grid[ ((StartY + y) * GridW) + (StartX + x) ] == 1 ) { AllocateGrid( Grid, GridW, GridH, StartX + x, StartY + y ); } } } } } }
void* NLL_AllocateGrid(GridDesc* pgrid) { int index, nactive, ngrid_read, n; void* fptr = NULL; GridMemStruct* pGridMemStruct = NULL; //printf("IN: NLL_AllocateGrid\n"); if (USE_GRID_LIST) { if ((index = GridMemList_IndexOfGridDesc(0, pgrid)) >= 0){ // already in list pGridMemStruct = GridMemList_ElementAt(index); pGridMemStruct->active = 1; fptr = pGridMemStruct->buffer; if (message_flag >= GRIDMEM_MESSAGE) printf("GridMemManager: Grid exists in mem (%d/%d): %s\n", index, GridMemListNumElements, pGridMemStruct->pgrid->title); return(fptr); } else { // check number of active grids in list nactive = 0; ngrid_read = 0; for (n = 0; n < GridMemList_NumElements(); n++) { pGridMemStruct = GridMemList_ElementAt(n); nactive += pGridMemStruct->active; ngrid_read += pGridMemStruct->grid_read; } // list already full of active grids, do normal allocation if (MaxNum3DGridMemory > 0 && nactive >= MaxNum3DGridMemory) { fptr = AllocateGrid(pgrid); if (message_flag >= GRIDMEM_MESSAGE) printf("GridMemManager: Memory full (%d/%d): %s\n", index, GridMemListNumElements, pGridMemStruct->pgrid->title); return(fptr); } // ok // remove an inactive grid if necessary if (MaxNum3DGridMemory > 0 && ngrid_read >= MaxNum3DGridMemory) { for (n = GridMemList_NumElements() - 1; n >= 0; n--) { pGridMemStruct = GridMemList_ElementAt(n); if (!pGridMemStruct->active && pGridMemStruct->grid_read) { GridMemList_RemoveElementAt(n); break; } } } // create new list element pGridMemStruct = GridMemList_AddGridDesc(pgrid); fptr = pGridMemStruct->buffer; if (fptr == NULL) { // error allocating grid memory or out of memory GridMemList_RemoveElementAt(GridMemList_NumElements() -1); } return(fptr); } } else { fptr = AllocateGrid(pgrid); return(fptr); } }
int Rotate90CW(int argc, char *argv[]) { int istat, narg; char fn_grid_in[FILENAME_MAX]; char fn_grid_out[FILENAME_MAX]; FILE *fp_grid_in; FILE *fp_grid_in_hdr; GridDesc grid_in, grid_out; int ix, iy, iz; float val; // open input grid file strcpy(fn_grid_in, argv[2]); if ((istat = OpenGrid3dFile(fn_grid_in, &fp_grid_in, &fp_grid_in_hdr, &grid_in, "", NULL)) < 0) { puterr("ERROR opening input grid file."); return(-1); } // cread and initialize output grid // output file name strcpy(fn_grid_out, argv[3]); // create output grid description grid_out = grid_in; grid_out.numx = grid_in.numy; grid_out.numy = grid_in.numx; // allocate grid grid_out.buffer = AllocateGrid(&grid_out); if (grid_out.buffer == NULL) { puterr("ERROR: allocating memory for output grid buffer.\n"); return(-1); } // create grid array access pointers grid_out.array = CreateGridArray(&grid_out); if (grid_out.array == NULL) { puterr("ERROR: creating array for accessing output grid buffer.\n"); return(-1); } // rotate input grid file into output grid for (ix = 0; ix < grid_in.numx; ix++) { printf("ix = %d/%d\r", ix, grid_in.numx); for (iy = 0; iy < grid_in.numy; iy++) { for (iz = 0; iz < grid_in.numz; iz++) { val = ReadGrid3dValue(fp_grid_in, ix, iy, iz, &grid_in); grid_out.array[iy][grid_out.numy - ix - 1][iz] = val; } } } printf("\n"); // save sum grid to disk if ((istat = WriteGrid3dBuf(&grid_out, NULL, fn_grid_out, "rot90CW")) < 0) { puterr("ERROR: writing rotated grid to disk.\n"); return(-1); } close(fp_grid_in); close(fp_grid_in_hdr); return(0); }
/** * Loads elevation from a USGS DEM file. * * Some non-standard variations of the DEM format are supported. * * You should call SetupLocalCS() after loading if you will be doing * heightfield operations on this grid. * * \returns \c true if the file was successfully opened and read. */ bool vtElevationGrid::LoadFromDEM(const char *szFileName, bool progress_callback(int), vtElevError *err) { // Free buffers to prepare to receive new data FreeData(); if (progress_callback != NULL) progress_callback(0); FILE *fp = vtFileOpen(szFileName,"rb"); if (!fp) // Cannot Open File { SetError(err, vtElevError::FILE_OPEN, "Couldn't open file '%s'", szFileName); return false; } // check for version of DEM format int iRow, iColumn; char buffer[158]; fseek(fp, 864, 0); if (fread(buffer, 144, 1, fp) != 1) { SetError(err, vtElevError::READ_DATA, "Couldn't read DEM data from '%s'", szFileName); return false; } bool bOldFormat = (strncmp(buffer, " 1 1", 12) == 0); bool bNewFormat = false; bool bFixedLength = true; int iDataStartOffset = 1024; // set here to avoid compiler warning int i, j; if (bOldFormat) iDataStartOffset = 1024; // 1024 is record length else { fseek(fp, 1024, 0); // Check for New Format IConvert(fp, 6, iRow); IConvert(fp, 6, iColumn); if (iRow==1 && iColumn==1) // File OK? { bNewFormat = true; iDataStartOffset = 1024; } else { // might be the Non-fixed-length record format // Record B can start anywhere from 865 to 1023 // Record B is identified by starting with the row/column // of its first profile, " 1 1" fseek(fp, 865, 0); if (fread(buffer, 158, 1, fp) != 1) { SetError(err, vtElevError::READ_DATA, "Couldn't read DEM data from '%s'", szFileName); fclose(fp); return false; } for (i = 0; i < 158-12; i++) { if (!strncmp(buffer+i, " 1 1", 12)) { // Found it bFixedLength = false; iDataStartOffset = 865+i; break; } } if (i == 158-12) { // Not a DEM file SetError(err, vtElevError::READ_DATA, "Couldn't read DEM data from '%s'", szFileName); fclose(fp); return false; } } } // Read the embedded DEM name char szName[41]; fseek(fp, 0, 0); if (fgets(szName, 41, fp) == NULL) return false; int len = strlen(szName); // trim trailing whitespace while (len > 0 && szName[len-1] == ' ') { szName[len-1] = 0; len--; } m_strOriginalDEMName = szName; fseek(fp, 156, 0); int iCoordSystem, iUTMZone; IConvert(fp, 6, iCoordSystem); IConvert(fp, 6, iUTMZone); fseek(fp, 168, 0); double dProjParams[15]; for (i = 0; i < 15; i++) { if (!DConvert(fp, 24, dProjParams[i], DEBUG_DEM)) return false; } int iDatum = EPSG_DATUM_NAD27; // default // OLD format header ends at byte 864 (0x360); new format has Datum if (bNewFormat) { // year of data compilation char szDateBuffer[5]; fseek(fp, 876, 0); // 0x36C if (fread(szDateBuffer, 4, 1, fp) != 1) return false; szDateBuffer[4] = 0; // Horizontal datum // 1=North American Datum 1927 (NAD 27) // 2=World Geodetic System 1972 (WGS 72) // 3=WGS 84 // 4=NAD 83 // 5=Old Hawaii Datum // 6=Puerto Rico Datum fseek(fp, 890, 0); // 0x37A int datum; IConvert(fp, 2, datum); VTLOG("DEM Reader: Read Datum Value %d\n", datum); switch (datum) { case 1: iDatum = EPSG_DATUM_NAD27; break; case 2: iDatum = EPSG_DATUM_WGS72; break; case 3: iDatum = EPSG_DATUM_WGS84; break; case 4: iDatum = EPSG_DATUM_NAD83; break; case 5: iDatum = EPSG_DATUM_OLD_HAWAIIAN; break; case 6: iDatum = EPSG_DATUM_PUERTO_RICO; break; } } fseek(fp, 528, 0); int iGUnit, iVUnit; IConvert(fp, 6, iGUnit); IConvert(fp, 6, iVUnit); // Ground (Horizontal) Units in meters double fGMeters; switch (iGUnit) { case 0: fGMeters = 1.0; break; // 0 = radians (never encountered) case 1: fGMeters = 0.3048; break; // 1 = feet case 2: fGMeters = 1.0; break; // 2 = meters case 3: fGMeters = 30.922; break; // 3 = arc-seconds } // Vertical Units in meters double fVertUnits; switch (iVUnit) { case 1: fVertUnits = 0.3048; break; // feet to meter conversion case 2: fVertUnits = 1.0; break; // meters == meters default: fVertUnits = 1.0; break; // anything else, assume meters } fseek(fp, 816, 0); double dxdelta, dydelta, dzdelta; DConvert(fp, 12, dxdelta, DEBUG_DEM); // dxdelta (unused) DConvert(fp, 12, dydelta, DEBUG_DEM); DConvert(fp, 12, dzdelta, DEBUG_DEM); m_bFloatMode = false; // Read the coordinates of the 4 corners VTLOG("DEM corners:\n"); DPoint2 corners[4]; // SW, NW, NE, SE fseek(fp, 546, 0); for (i = 0; i < 4; i++) { DConvert(fp, 24, corners[i].x, DEBUG_DEM); DConvert(fp, 24, corners[i].y, DEBUG_DEM); } for (i = 0; i < 4; i++) VTLOG(" (%lf, %lf)", corners[i].x, corners[i].y); VTLOG("\n"); // Set up the projection and corners bool bGeographic = (iCoordSystem == 0); if (bGeographic) { for (i = 0; i < 4; i++) { // convert arcseconds to degrees m_Corners[i].x = corners[i].x / 3600.0; m_Corners[i].y = corners[i].y / 3600.0; } } else { // some linear coordinate system for (i = 0; i < 4; i++) m_Corners[i] = corners[i]; } // Special case. Some old DEMs claim to be NAD27, but they are of Hawai'i, // and Hawai'i has no NAD27, it is actually OHD. if (iDatum == EPSG_DATUM_NAD27) { DRECT Hawaii(0,0,0,0); if (bGeographic) Hawaii.SetRect(-164, 24, -152, 17); else if (iCoordSystem == 1) // UTM { if (iUTMZone == 4) Hawaii.SetRect(240000, 2600000, 1000000, 2000000); else if (iUTMZone == 5) Hawaii.SetRect(-400000, 2600000, 400000, 2000000); } for (i = 0; i < 4; i++) { if (Hawaii.ContainsPoint(m_Corners[i])) iDatum = EPSG_DATUM_OLD_HAWAIIAN; } } bool bSuccessfulCRS = true; switch (iCoordSystem) { case 0: // geographic (lat-lon) iUTMZone = -1; bSuccessfulCRS = m_proj.SetProjectionSimple(false, iUTMZone, iDatum); break; case 1: // utm m_proj.SetProjectionSimple(true, iUTMZone, iDatum); break; case 3: // Albers Conical Equal Area { // The Official DEM documentation says: // "Note: All angles (latitudes, longitudes, or azimuth) are // required in degrees, minutes, and arc seconds in the packed // real number format +DDDOMMOSS.SSSSS." // However, what i've actually seen is values like: // 0.420000000000000D+06' -> 420000 // for 42 degrees, which is off by a decimal point from the DEM docs. // So, intepret the values with factor of 10000 to convert to degrees: // double semi_major = dProjParams[0]; // unused // double eccentricity = dProjParams[1]; // unused double lat_1st_std_parallel = dProjParams[2] / 10000; double lat_2nd_std_parallel = dProjParams[3] / 10000; double lon_central_meridian = dProjParams[4] / 10000; double lat_origin = dProjParams[5] / 10000; double false_easting = dProjParams[6]; double false_northing = dProjParams[7]; m_proj.SetGeogCSFromDatum(iDatum); m_proj.SetACEA(lat_1st_std_parallel, lat_2nd_std_parallel, lat_origin, lon_central_meridian, false_easting, false_northing); } break; case 2: // State Plane (!) case 4: // Lambert Conformal case 5: // Mercator case 6: // Polar Stereographic case 7: // Polyconic case 8: // Equidistant Conic Type A / B case 9: // Transverse Mercator case 10: // Stereographic case 11: // Lambert Azimuthal Equal-Area case 12: // Azimuthal Equidistant case 13: // Gnomonic case 14: // Orthographic case 15: // General Vertical Near-Side Perspective case 16: // Sinusoidal (Plate Caree) case 17: // Equirectangular case 18: // Miller Cylindrical case 19: // Van Der Grinten I case 20: // Oblique Mercator VTLOG("Warning! We don't yet support DEM coordinate system %d.\n", iCoordSystem); break; } // We must have a functional CRS, or it will sebsequently fail if (!bSuccessfulCRS) { SetError(err, vtElevError::READ_CRS, "Couldn't determine CRS of DEM file"); return false; } double dElevMin, dElevMax; DConvert(fp, 24, dElevMin, DEBUG_DEM); DConvert(fp, 24, dElevMax, DEBUG_DEM); fseek(fp, 852, 0); int iRows, iProfiles; IConvert(fp, 6, iRows); // This "Rows" value will always be 1 IConvert(fp, 6, iProfiles); VTLOG("DEM profiles: %d\n", iProfiles); m_iSize.x = iProfiles; // values we'll need while scanning the elevation profiles int iProfileRows, iProfileCols; int iElev; double dLocalDatumElev, dProfileMin, dProfileMax; int ygap; double dMinY; DPoint2 start; if (bGeographic) { // If it's in degrees, it's flush square, so we can simply // derive the extents (m_EarthExtents) from the quad corners (m_Corners) ComputeExtentsFromCorners(); dMinY = std::min(corners[0].y, corners[3].y); } else { VTLOG("DEM scanning to compute extents\n"); m_EarthExtents.SetInsideOut(); if (!bFixedLength) fseek(fp, iDataStartOffset, 0); // Need to scan over all the profiles, accumulating the TRUE // extents of the actual data points. int record = 0; int data_len; for (i = 0; i < iProfiles; i++) { if (progress_callback != NULL) progress_callback(i*49/iProfiles); if (bFixedLength) fseek(fp, iDataStartOffset + (record * 1024), 0); // We cannot use IConvert here, because there *might* be a spurious LF // after the number - seen in some rare files. if (fscanf(fp, "%d", &iRow) != 1) { SetError(err, vtElevError::READ_DATA, "Error reading DEM at profile %d of %d", i, iProfiles); return false; } IConvert(fp, 6, iColumn); // assert(iColumn == i+1); IConvert(fp, 6, iProfileRows); IConvert(fp, 6, iProfileCols); DConvert(fp, 24, start.x); DConvert(fp, 24, start.y); m_EarthExtents.GrowToContainPoint(start); start.y += ((iProfileRows-1) * dydelta); m_EarthExtents.GrowToContainPoint(start); if (bFixedLength) { record++; data_len = 144 + (iProfileRows * 6); while (data_len > 1020) // max bytes in a record { data_len -= 1020; record++; } } else { DConvert(fp, 24, dLocalDatumElev); DConvert(fp, 24, dProfileMin); DConvert(fp, 24, dProfileMax); for (j = 0; j < iProfileRows; j++) { // We cannot use IConvert here, because there *might* be a spurious LF // after the number - seen in some rare files. if (fscanf(fp, "%d", &iElev) != 1) return false; } } } dMinY = m_EarthExtents.bottom; } VTLOG("DEM extents LRTB: %lf, %lf, %lf, %lf\n", m_EarthExtents.left, m_EarthExtents.right, m_EarthExtents.top, m_EarthExtents.bottom); // Compute number of rows double fRows; if (bGeographic) { // degrees fRows = m_EarthExtents.Height() / dydelta * 3600.0f; m_iSize.y = (int)fRows + 1; // 1 more than quad spacing } else { // some linear coordinate system fRows = m_EarthExtents.Height() / dydelta; m_iSize.y = (int)(fRows + 0.5) + 1; // round to the nearest integer } // safety check if (m_iSize.y > 20000) return false; if (!AllocateGrid(err)) return false; // jump to start of actual data fseek(fp, iDataStartOffset, 0); for (i = 0; i < iProfiles; i++) { if (progress_callback != NULL) progress_callback(50+i*49/iProfiles); // We cannot use IConvert here, because there *might* be a spurious LF // after the number - seen in some rare files. if (fscanf(fp, "%d", &iRow) != 1) return false; IConvert(fp, 6, iColumn); //assert(iColumn == i+1); IConvert(fp, 6, iProfileRows); IConvert(fp, 6, iProfileCols); DConvert(fp, 24, start.x); DConvert(fp, 24, start.y); DConvert(fp, 24, dLocalDatumElev); DConvert(fp, 24, dProfileMin); DConvert(fp, 24, dProfileMax); ygap = (int)((start.y - dMinY)/dydelta); for (j = ygap; j < (ygap + iProfileRows); j++) { //assert(j >=0 && j < m_iSize.y); // useful safety check // We cannot use IConvert here, because there *might* be a spurious LF // after the number - seen in some rare files. if (fscanf(fp, "%d", &iElev) != 1) return false; if (iElev == -32767 || iElev == -32768) SetValue(i, j, INVALID_ELEVATION); else { // The DEM spec says: // "A value in this array would be multiplied by the "z" spatial // resolution (data element 15, record type A) and added to the // "Elevation of local datum for the profile" (data element 4, record // type B) to obtain the elevation for the point." SetValue(i, j, (short) iElev + (short) dLocalDatumElev); } } } fclose(fp); m_fVMeters = (float) (fVertUnits * dzdelta); ComputeHeightExtents(); if (m_fMinHeight != dElevMin || m_fMaxHeight != dElevMax) VTLOG("DEM Reader: elevation extents in .dem (%.1f, %.1f) don't match data (%.1f, %.1f).\n", dElevMin, dElevMax, m_fMinHeight, m_fMaxHeight); return true; }
int main(int argc, char *argv[]) { int errs = 0; int wrank, wsize; int gsizes[3], distribs[3], dargs[3], psizes[3]; int px, py, nx, ny, rx, ry, bx, by; int *srcArray, *destArray; int i, j, ii, jj, loc; MPI_Datatype darraytype; MTest_Init(0, 0); MPI_Comm_rank(MPI_COMM_WORLD, &wrank); MPI_Comm_size(MPI_COMM_WORLD, &wsize); /* Test 1: Simple, 1-D cyclic decomposition */ if (AllocateGrid(1, 3 * wsize, &srcArray, &destArray)) { MPI_Abort(MPI_COMM_WORLD, 1); } /* Simple cyclic with 1-dim global array */ gsizes[0] = 3 * wsize; distribs[0] = MPI_DISTRIBUTE_CYCLIC; dargs[0] = 1; psizes[0] = wsize; MPI_Type_create_darray(wsize, wrank, 1, gsizes, distribs, dargs, psizes, MPI_ORDER_C, MPI_INT, &darraytype); /* Check the created datatype. Because cyclic, should represent * a strided type */ if (PackUnpack(darraytype, srcArray, destArray, 3)) { fprintf(stderr, "Error in pack/unpack check\n"); MPI_Abort(MPI_COMM_WORLD, 1); } /* Now, check for correct data */ for (i = 0; i < 3; i++) { if (destArray[i] != wrank + i * wsize) { fprintf(stderr, "1D: %d: Expected %d but saw %d\n", i, wrank + i * wsize, destArray[i]); errs++; } } free(destArray); free(srcArray); MPI_Type_free(&darraytype); /* Test 2: Simple, 1-D cyclic decomposition, with block size=2 */ if (AllocateGrid(1, 4 * wsize, &srcArray, &destArray)) { MPI_Abort(MPI_COMM_WORLD, 1); } /* Simple cyclic with 1-dim global array */ gsizes[0] = 4 * wsize; distribs[0] = MPI_DISTRIBUTE_CYCLIC; dargs[0] = 2; psizes[0] = wsize; MPI_Type_create_darray(wsize, wrank, 1, gsizes, distribs, dargs, psizes, MPI_ORDER_C, MPI_INT, &darraytype); /* Check the created datatype. Because cyclic, should represent * a strided type */ if (PackUnpack(darraytype, srcArray, destArray, 4)) { fprintf(stderr, "Error in pack/unpack check\n"); MPI_Abort(MPI_COMM_WORLD, 1); } loc = 0; /* for each cyclic element */ for (i = 0; i < 2; i++) { /* For each element in block */ for (j = 0; j < 2; j++) { if (destArray[loc] != 2 * wrank + i * 2 * wsize + j) { fprintf(stderr, "1D(2): %d: Expected %d but saw %d\n", i, 2 * wrank + i * 2 * wsize + j, destArray[loc]); errs++; } loc++; } } free(destArray); free(srcArray); MPI_Type_free(&darraytype); /* 2D: Create some 2-D decompositions */ px = wsize / 2; py = 2; rx = wrank % px; ry = wrank / px; if (px * py != wsize) { fprintf(stderr, "An even number of processes is required\n"); MPI_Abort(MPI_COMM_WORLD, 1); } /* Cyclic/Cyclic */ if (AllocateGrid(5 * px, 7 * py, &srcArray, &destArray)) { MPI_Abort(MPI_COMM_WORLD, 1); } /* Simple cyclic/cyclic. Note in C order, the [1] index varies most * rapidly */ gsizes[0] = ny = 7 * py; gsizes[1] = nx = 5 * px; distribs[0] = MPI_DISTRIBUTE_CYCLIC; distribs[1] = MPI_DISTRIBUTE_CYCLIC; dargs[0] = 1; dargs[1] = 1; psizes[0] = py; psizes[1] = px; MPI_Type_create_darray(wsize, wrank, 2, gsizes, distribs, dargs, psizes, MPI_ORDER_C, MPI_INT, &darraytype); /* Check the created datatype. Because cyclic, should represent * a strided type */ if (PackUnpack(darraytype, srcArray, destArray, 5 * 7)) { fprintf(stderr, "Error in pack/unpack check\n"); MPI_Abort(MPI_COMM_WORLD, 1); } loc = 0; for (j = 0; j < 7; j++) { for (i = 0; i < 5; i++) { int expected = rx + ry * nx + i * px + j * nx * py; if (destArray[loc] != expected) { errs++; fprintf(stderr, "2D(cc): [%d,%d] = %d, expected %d\n", i, j, destArray[loc], expected); } loc++; } } free(srcArray); free(destArray); MPI_Type_free(&darraytype); /* Cyclic(2)/Cyclic(3) */ if (AllocateGrid(6 * px, 4 * py, &srcArray, &destArray)) { MPI_Abort(MPI_COMM_WORLD, 1); } /* Block cyclic/cyclic. Note in C order, the [1] index varies most * rapidly */ gsizes[0] = ny = 4 * py; gsizes[1] = nx = 6 * px; distribs[0] = MPI_DISTRIBUTE_CYCLIC; distribs[1] = MPI_DISTRIBUTE_CYCLIC; dargs[0] = by = 2; dargs[1] = bx = 3; psizes[0] = py; psizes[1] = px; MPI_Type_create_darray(wsize, wrank, 2, gsizes, distribs, dargs, psizes, MPI_ORDER_C, MPI_INT, &darraytype); /* Check the created datatype. Because cyclic, should represent * a strided type */ if (PackUnpack(darraytype, srcArray, destArray, 4 * 6)) { fprintf(stderr, "Error in pack/unpack check\n"); MPI_Abort(MPI_COMM_WORLD, 1); } loc = 0; for (j = 0; j < 4 / by; j++) { for (jj = 0; jj < by; jj++) { for (i = 0; i < 6 / bx; i++) { for (ii = 0; ii < bx; ii++) { int expected = rx * bx + ry * by * nx + i * bx * px + ii + (j * by * py + jj) * nx; if (destArray[loc] != expected) { errs++; fprintf(stderr, "2D(c(2)c(3)): [%d,%d] = %d, expected %d\n", i * bx + ii, j * by + jj, destArray[loc], expected); } loc++; } } } } free(srcArray); free(destArray); MPI_Type_free(&darraytype); MTest_Finalize(errs); return MTestReturnValue(errs); }
int main(int argc, char* argv[]) { int** grid; // grid containing the cells and whether they are alive or dead // set up curses for displaying the grid #ifdef USE_CURSES initscr(); if(has_colors()) { start_color(); init_pair(1, COLOR_BLACK, COLOR_WHITE); init_pair(2, COLOR_WHITE, COLOR_CYAN); } #endif // allocate the grid grid = AllocateGrid(); if(grid == NULL) { printf("ERROR: Could not allocate memory for grid\n"); return -1; } // initialize and print the grid InitGrid(grid); #ifdef PRINT_GRID PrintGrid(grid); #endif for(int time = 1; time <= TIME_STEPS; ++time) { // sleep to observe updates #ifdef PRINT_GRID usleep(SLEEP_TIME); #endif // allocate temporary grid for storing the simultaneous update int** tempGrid = AllocateGrid(); if(tempGrid == NULL) { printf("ERROR: Could not allocate memory for grid\n"); return -1; } for(int i = 0; i < GRID_SIZE; ++i) { for(int j = 0; j < GRID_SIZE; ++j) { int numNeighborAlive = 0; for(int k = -1; k <= 1; ++k) { for(int l = -1; l <= 1; ++l) { int row = (i + k) % GRID_SIZE; int col = (j + l) % GRID_SIZE; if(row == -1) row = GRID_SIZE - 1; if(col == -1) col = GRID_SIZE - 1; if( (row != i) || (col != j) ) numNeighborAlive += grid[row][col]; } } switch(numNeighborAlive) { case 2: tempGrid[i][j] = grid[i][j]; break; case 3: tempGrid[i][j] = 1; break; default: tempGrid[i][j] = 0; } } } free(grid); grid = tempGrid; #ifdef USE_CURSES move(0, 0); #endif #ifdef PRINT_GRID PrintGrid(grid); #endif } CountLive(grid); #ifdef USE_CURSES printw("\nPress any key to continue..."); refresh(); getchar(); #endif free(grid); #ifdef USE_CURSES endwin(); #endif return 0; }