#include "hdia_conv.h" #include "stdlib.h" #include "string.h" #include #include int getHdiaHacksCount(int hackSize, int rowsCount) { return (rowsCount + hackSize - 1)/hackSize; } void computeHdiaHackOffsets( int *allocationHeight, int *hackOffsets, int hackSize, const void* diaValues, int diaValuesPitch, int diagonals, int rowsCount, spgpuType_t valuesType ) { int i,r,s, hack; int hackCount = getHdiaHacksCount(hackSize, rowsCount); size_t elementSize = spgpuSizeOf(valuesType); int hackHeight = 0; hackOffsets[0] = 0; for (hack=0; hack= rowsCount) break; const char* val = (char*)diaValues + elementSize*(row + i*diaValuesPitch); for (s=0; s= rowsCount) break; const char* val = (const char*)diaValues + elementSize*(row + i*diaValuesPitch); for (s=0; s= rowsCount) break; char* dest = (char*)hdiaValues + elementSize*((posOffset + i)*hackSize + r); const char* src = (const char*)diaValues + elementSize*(row + diagPosInsideDia*diaValuesPitch); memcpy(dest, src, elementSize); } } } } void computeHdiaHackOffsetsFromCoo( int *allocationHeight, int *hackOffsets, int hackSize, int rowsCount, int columnsCount, int nonZerosCount, const int* cooRowIndices, const int* cooColsIndices, int cooBaseIndex ) { int i,j,h; int hackCount = getHdiaHacksCount(hackSize, rowsCount); // Find rows per hack std::vector *rowsPerHack = new std::vector [hackCount]; for (i=0; i diagIdsToPos; hackOffsets[0] = 0; for (h=0; h *hackRows = &rowsPerHack[h]; int hackRowsSize = hackRows->size(); for (j=0; jat(j); int rowIdx = cooRowIndices[i]; int colIdx = cooColsIndices[i]; int diagId = (colIdx-cooBaseIndex) - ((rowIdx-cooBaseIndex) % hackSize); int diagPos = hackSize - 1 + diagId; std::map::iterator it = diagIdsToPos.find(diagPos); if(it == diagIdsToPos.end()) { diagIdsToPos[diagPos] = 1; ++diagonalsCount; } } hackOffsets[h+1] = hackOffsets[h] + diagonalsCount; } *allocationHeight = hackOffsets[hackCount]; delete[] rowsPerHack; } void cooToHdia_size( void *hdiaValues, int *hdiaOffsets, const int *hackOffsets, int hackSize, int rowsCount, int columnsCount, int nonZerosCount, const int* cooRowIndices, const int* cooColsIndices, const void* cooValues, int cooBaseIndex, size_t elementSize ) { int i,j,h; int hackCount = getHdiaHacksCount(hackSize, rowsCount); // Find rows per hack std::vector *rowsPerHack = new std::vector [hackCount]; for (i=0; i hackDiagIdsToPos; for (h=0; h *hackRows = &rowsPerHack[h]; int hackRowsSize = hackRows->size(); for (j=0; jat(j); int rowIdx = cooRowIndices[i]; int colIdx = cooColsIndices[i]; int globalDiagId = colIdx - rowIdx; int diagId = (colIdx - cooBaseIndex) - ((rowIdx - cooBaseIndex) % hackSize); int diagPos = hackSize - 1 + diagId; std::map::iterator it = hackDiagIdsToPos.find(diagPos); if(it == hackDiagIdsToPos.end()) { hackDiagIdsToPos[diagPos] = globalDiagId; } } // Reorder diags for (std::map::iterator it = hackDiagIdsToPos.begin(); it != hackDiagIdsToPos.end(); ++it) { int i = it->first; int globalDiagId = it->second; int diagPosInsideOffsets; int diagId = i - hackSize + 1; hackDiagIdsToPos[i] = diagPosInsideOffsets = diagonalsCount++; hdiaOffsets[diagPosInsideOffsets] = globalDiagId; } hdiaOffsets += diagonalsCount; for (j=0; jat(j); int rowIdx = cooRowIndices[i]; int colIdx = cooColsIndices[i]; int diagId = (colIdx - cooBaseIndex) - ((rowIdx - cooBaseIndex) % hackSize); int diagPosInsideOffsets = hackDiagIdsToPos[hackSize - 1 + diagId]; char* valAddr = (char*)hdiaValues + elementSize*(((rowIdx - cooBaseIndex) % hackSize) + hackSize* (hackOffsets[h] + diagPosInsideOffsets)); memcpy(valAddr, (const char*)cooValues + i*elementSize, elementSize); } } delete[] rowsPerHack; } void cooToHdia( void *hdiaValues, int *hdiaOffsets, const int *hackOffsets, int hackSize, int rowsCount, int columnsCount, int nonZerosCount, const int* cooRowIndices, const int* cooColsIndices, const void* cooValues, int cooBaseIndex, spgpuType_t valuesType ) { size_t elementSize = spgpuSizeOf(valuesType); cooToHdia_size(hdiaValues, hdiaOffsets, hackOffsets, hackSize, rowsCount, columnsCount, nonZerosCount, cooRowIndices, cooColsIndices, cooValues, cooBaseIndex, elementSize); } void bcooToBhdia( void *hdiaValues, int *hdiaOffsets, const int *hackOffsets, int hackSize, int rowsCount, int columnsCount, int nonZerosCount, const int* cooRowIndices, const int* cooColsIndices, const void* cooValues, int cooBaseIndex, spgpuType_t valuesType, int blockSize ) { size_t elementSize = blockSize*spgpuSizeOf(valuesType); cooToHdia_size(hdiaValues, hdiaOffsets, hackOffsets, hackSize, rowsCount, columnsCount, nonZerosCount, cooRowIndices, cooColsIndices, cooValues, cooBaseIndex, elementSize); }