void hashMapInsert(Thread* t, object map, object key, object value, uint32_t (*hash)(Thread*, object)) { // note that we reinitialize the array variable whenever an // allocation (and thus possibly a collection) occurs, in case the // array changes due to a table resize. PROTECT(t, map); uint32_t h = hash(t, key); bool weak = objectClass(t, map) == type(t, Machine::WeakHashMapType); object array = hashMapArray(t, map); ++ hashMapSize(t, map); if (array == 0 or hashMapSize(t, map) >= arrayLength(t, array) * 2) { PROTECT(t, key); PROTECT(t, value); hashMapResize(t, map, hash, array ? arrayLength(t, array) * 2 : 16); array = hashMapArray(t, map); } object k = key; if (weak) { PROTECT(t, key); PROTECT(t, value); object r = makeWeakReference(t, 0, 0, 0, 0); jreferenceTarget(t, r) = key; jreferenceVmNext(t, r) = t->m->weakReferences; t->m->weakReferences = r; k = r; array = hashMapArray(t, map); } object n = makeTriple(t, k, value, 0); array = hashMapArray(t, map); unsigned index = h & (arrayLength(t, array) - 1); set(t, n, TripleThird, arrayBody(t, array, index)); set(t, array, ArrayBody + (index * BytesPerWord), n); if (hashMapSize(t, map) <= arrayLength(t, array) / 3) { // this might happen if nodes were removed during GC in which case // we weren't able to resize at the time hashMapResize(t, map, hash, arrayLength(t, array) / 2); } }
int main(int argc, char* argv[]) { int toBeReturned = 0; setbuf(stdout,NULL); if(argc < 5) { std::cerr<<"usage: sor omega nRowsInMatrix nColumnsInMatrix nIterations nRowsInTile nColumnsInTile [-v]\n"; std::cerr<<"nRowsInTile should be a factor of nRowsInMatrix \n"; std::cerr<<"nColumnsInTile should be a factor of nColumnsInMatrix \n"; toBeReturned = 1; } else{ // srand(0xdeadbeef); double omega = atof(argv[1]); int nRowsInMatrix = (int)atoi(argv[2]); int nColumnsInMatrix = (int)atoi(argv[3]); nIterations = (int)atoi(argv[4]); int nRowsInTile = (int)atoi(argv[5]); int nColumnsInTile = (int)atoi(argv[6]); int nElementsInTile = nRowsInTile * nColumnsInTile; //int ceiling( nRowsOfTiles = nRowsInMatrix/ nRowsInTile; //int ceiling( nColumnsOfTiles = nColumnsInMatrix/ nColumnsInTile; bool verbose = argc==8 && !strcmp("-v", argv[7]); double** inputArray = new double*[nRowsInMatrix]; // not the best rand but this is a test program anyway for(int i = 0; i < nRowsInMatrix; ++i) { double* currRow = inputArray[i] = new double[nColumnsInMatrix]; for(int j = 0; j < nColumnsInMatrix; ++j) // currRow[j] = (rand() % 100) *0.01; currRow[j] = ((j*11) % 100) *0.01; } TiledInputArray tiledInputArray(inputArray, nRowsOfTiles, nColumnsOfTiles, nRowsInTile, nColumnsInTile); if(verbose) { printf("omega=%lf, M=%d, N=%d, nIterations=%d, nRowsInTile=%d and nColumnsInTile=%d\n", omega, nRowsInMatrix, nColumnsInMatrix, nIterations, nRowsInTile, nColumnsInTile); printf("before\n"); for(int i = 0; i < nRowsInMatrix; ++i) { for(int j = 0; j < nColumnsInMatrix-1; ++j) printf("%lf, ",inputArray[i][j]); printf("%lf\n",inputArray[i][nColumnsInMatrix-1]); } } tbb::tick_count t0 = tbb::tick_count::now(); sorContext graph;// //CnC::debug::trace_all(graph, "tiled sor"); graph.omega.put(111, omega); graph.nRowsInTile.put(222, nRowsInTile); graph.nColumnsInTile.put(333, nColumnsInTile); #ifndef REVERSE for(int iteration = 0; iteration < nIterations; ++iteration) for(int i = 0; i < nRowsOfTiles; ++i) for(int j = 0; j < nColumnsOfTiles; ++j) { if(iteration == 0) { graph.currTileMatrix.put(makeTriple(i,j,0), *tiledInputArray.getTile(i,j) ); } graph.tileSpace.put(makeTriple(i,j,iteration)); } #else for(int iteration = nIterations-1; iteration >= 0; --iteration) for(int i = nRowsOfTiles-1; i >= 0 ; --i) for(int j = nColumnsOfTiles-1; j >= 0; --j) { if(!iteration) graph.currTileMatrix.put(makeTriple(i,j,0), *tiledInputArray.getTile(i,j) ); graph.tileSpace.put(makeTriple(i,j,iteration)); } #endif graph.wait(); // since execution finished I can now write over **inputArray Tile _tmp; for(int i = 0; i < nRowsOfTiles; ++i) for(int j = 0; j < nColumnsOfTiles; ++j) { graph.currTileMatrix.get(makeTriple(i,j,nIterations), _tmp ); tiledInputArray.replace(i, j, _tmp); } // std::cout<<"loop end"<<std::endl; tbb::tick_count t1 = tbb::tick_count::now(); printf("Computed in %g seconds\n", (t1-t0).seconds()); if(verbose) { printf("after\n"); tiledInputArray.prettyPrint(); } for(int i = 0; i < nRowsInMatrix; ++i) delete [] inputArray[i]; delete [] inputArray; } return toBeReturned; }
int relaxation::execute(intTriple tileIndex3D, sorContext& graph) const { int rowIndexOfTile = getFirst(tileIndex3D); int columnIndexOfTile = getSecond(tileIndex3D); int iterationOfTile = getThird(tileIndex3D); // these are from curr, already computed matrix bool hasAbove = rowIndexOfTile != 0; bool hasLeft = columnIndexOfTile != 0; // these are from prev, input matrix // also these are the corner cases bool hasBelow = rowIndexOfTile != nRowsOfTiles-1; bool hasRight= columnIndexOfTile != nColumnsOfTiles-1; int nRowsInTile; graph.nRowsInTile.get(222, nRowsInTile); int nColumnsInTile; graph.nColumnsInTile.get(333, nColumnsInTile); Tile above, left, below, right; const double *aboveArray = NULL, *leftArray = NULL, *belowArray = NULL, *rightArray = NULL; if(hasAbove) { //above = new Tile(graph.currTileMatrix.get(makeTriple(rowIndexOfTile-1, columnIndexOfTile,iterationOfTile+1))); graph.currTileMatrix.get(makeTriple(rowIndexOfTile-1, columnIndexOfTile,iterationOfTile+1), above); aboveArray = above.getArray(); } if(hasLeft) { //left = new Tile(graph.currTileMatrix.get(makeTriple(rowIndexOfTile, columnIndexOfTile-1,iterationOfTile+1))); graph.currTileMatrix.get(makeTriple(rowIndexOfTile, columnIndexOfTile-1,iterationOfTile+1), left); leftArray = left.getArray(); } if(hasBelow) { //below = new Tile(graph.currTileMatrix.get(makeTriple(rowIndexOfTile+1, columnIndexOfTile,iterationOfTile))); graph.currTileMatrix.get(makeTriple(rowIndexOfTile+1, columnIndexOfTile,iterationOfTile), below); belowArray = below.getArray(); } if(hasRight) { //right = new Tile(graph.currTileMatrix.get(makeTriple(rowIndexOfTile, columnIndexOfTile+1, iterationOfTile))); graph.currTileMatrix.get(makeTriple(rowIndexOfTile, columnIndexOfTile+1, iterationOfTile), right); rightArray = right.getArray(); } Tile tile; graph.currTileMatrix.get(makeTriple(rowIndexOfTile, columnIndexOfTile, iterationOfTile), tile); double* tileArray = tile.getArray(); double omega; graph.omega.get(111, omega); double omegaOver4 = omega * 0.25; double oneMinusOmega = 1-omega; int currRowDist = 0; int indexLastRow = (nRowsInTile-1)*nColumnsInTile; for(int i = 0; i < nRowsInTile; ++i) { double *currRow = tileArray + currRowDist; const double *aboveRow = NULL, *belowRow = NULL; if(i) aboveRow = currRow-nColumnsInTile; //non zero row else if(hasAbove) aboveRow = aboveArray + indexLastRow; //zero row if(i != nRowsInTile-1) belowRow = currRow + nColumnsInTile; //not last row else if(hasBelow) belowRow = belowArray; //zero row if(aboveRow && belowRow) { if(hasLeft && (nColumnsInTile > 1 || hasRight)) { double valueRight; if(nColumnsInTile > 1) valueRight = currRow[1]; else valueRight = rightArray[currRowDist]; currRow[0] = omegaOver4*(belowRow[0]+valueRight+aboveRow[0]+leftArray[currRowDist+nColumnsInTile-1]) + oneMinusOmega*currRow[0]; } for(int j = 1; j < nColumnsInTile-1; ++j) { currRow[j] = omegaOver4*(belowRow[j]+currRow[j+1]+aboveRow[j]+currRow[j-1])+oneMinusOmega*currRow[j]; } if(hasRight && nColumnsInTile > 1) { int j = nColumnsInTile-1; currRow[j] = omegaOver4*(belowRow[j]+rightArray[currRowDist]+aboveRow[j]+currRow[j-1]) + oneMinusOmega*currRow[j]; } } currRowDist += nColumnsInTile; } //if(hasAbove) delete above; //if(hasLeft) delete left; //if(hasBelow) delete below; //if(hasRight) delete right; graph.currTileMatrix.put(makeTriple(rowIndexOfTile, columnIndexOfTile, iterationOfTile+1), tile ); // delete tile; return CnC::CNC_Success; }