taco-oopsla2017/src/tensor.cpp
void TensorBase::pack() {
  taco_tassert(getComponentType().getKind() == Type::Float &&
               getComponentType().getNumBits() == 64)
      << "make the packing machinery work with other primitive types later. "
      << "Right now we're specializing to doubles so that we can use a "
      << "resizable vector, but eventually we should use a two pass pack "
      << "algorithm that figures out sizes first, and then packs the data";

  const size_t order = getOrder();


  // Pack scalars
  if (order == 0) {
    char* coordLoc = this->coordinateBuffer->data();
    double scalarValue = *(double*)&coordLoc[this->coordinateSize -
                                             getComponentType().getNumBytes()];
    content->storage.setValues(makeArray({scalarValue}));
    this->coordinateBuffer->clear();
    return;
  }


  /// Permute the coordinates according to the storage dimension ordering.
  /// This is a workaround since the current pack code only packs tensors in the
  /// order of the dimensions.
  const std::vector<int>& dimensions = getDimensions();
  taco_iassert(getFormat().getOrder() == order);
  std::vector<int> permutation = getFormat().getModeOrder();
  std::vector<int> permutedDimensions(order);
  for (size_t i = 0; i < order; ++i) {
    permutedDimensions[i] = dimensions[permutation[i]];
  }

  taco_iassert((this->coordinateBufferUsed % this->coordinateSize) == 0);
  size_t numCoordinates = this->coordinateBufferUsed / this->coordinateSize;
  const size_t coordSize = this->coordinateSize;

  char* coordinatesPtr = coordinateBuffer->data();
  vector<int> permuteBuffer(order);
  for (size_t i=0; i < numCoordinates; ++i) {
    int* coordinate = (int*)coordinatesPtr;
    for (size_t j = 0; j < order; j++) {
      permuteBuffer[j] = coordinate[permutation[j]];
    }
    for (size_t j = 0; j < order; j++) {
      coordinate[j] = permuteBuffer[j];
    }
    coordinatesPtr += this->coordinateSize;
  }
  coordinatesPtr = coordinateBuffer->data();


  // The pack code expects the coordinates to be sorted
  numIntegersToCompare = order;
  qsort(coordinatesPtr, numCoordinates, coordSize, lexicographicalCmp);


  // Move coords into separate arrays and remove duplicates
  std::vector<std::vector<int>> coordinates(order);
  for (size_t i=0; i < order; ++i) {
    coordinates[i] = std::vector<int>(numCoordinates);
  }
  std::vector<double> values(numCoordinates);
  // Copy first coordinate-value pair
  int* lastCoord = (int*)malloc(order * sizeof(int));
  if (numCoordinates >= 1) {
    int* coordComponent = (int*)coordinatesPtr;
    for (size_t d=0; d < order; ++d) {
      coordinates[d][0] = *coordComponent;
      lastCoord[d] = *coordComponent;
      coordComponent++;
    }
    values[0] = *((double*)coordComponent);
  }
  // Copy remaining coordinate-value pairs, removing duplicates
  int j = 1;
  int* coord = (int*)malloc(order * sizeof(int));
  for (size_t i=1; i < numCoordinates; ++i) {
    int* coordLoc = (int*)&coordinatesPtr[i*coordSize];
    for (size_t d=0; d < order; ++d) {
      coord[d] = *coordLoc;;
      coordLoc++;
    }
    double value = *((double*)coordLoc);
    if (memcmp(coord, lastCoord, order*sizeof(int)) != 0) {
      for (size_t d = 0; d < order; d++) {
        coordinates[d][j] = coord[d];
      }
      values[j] = value;
      j++;
    }
    else {
      values[j-1] += value;
    }
  }
  free(coord);
  free(lastCoord);
  if (numCoordinates > 0) {
    for (size_t i=0; i < order; ++i) {
      coordinates[i].resize(j);
    }
    values.resize(j);
  }
  taco_iassert(coordinates.size() > 0);
  this->coordinateBuffer->clear();
  this->coordinateBufferUsed = 0;

  // Pack indices and values
  content->storage = storage::pack(permutedDimensions, getFormat(),
                                   coordinates, values);

//  std::cout << storage::packCode(getFormat()) << std::endl;
}
/// Pack coordinates into a data structure given by the tensor format.
Pack coordinates into a data structure given by the tensor format.
Pack coordinates into a data structure given by the tensor format .
void TensorBase::pack() {
  taco_tassert(getComponentType().getKind() == Type::Float &&
               getComponentType().getNumBits() == 64)
      << "make the packing machinery work with other primitive types later. "
      << "Right now we're specializing to doubles so that we can use a "
      << "resizable vector, but eventually we should use a two pass pack "
      << "algorithm that figures out sizes first, and then packs the data";
  const size_t order = getOrder();
  if (order == 0) {
    char* coordLoc = this->coordinateBuffer->data();
    double scalarValue = *(double*)&coordLoc[this->coordinateSize -
                                             getComponentType().getNumBytes()];
    content->storage.setValues(makeArray({scalarValue}));
    this->coordinateBuffer->clear();
    return;
  }
  const std::vector<int>& dimensions = getDimensions();
  taco_iassert(getFormat().getOrder() == order);
  std::vector<int> permutation = getFormat().getModeOrder();
  std::vector<int> permutedDimensions(order);
  for (size_t i = 0; i < order; ++i) {
    permutedDimensions[i] = dimensions[permutation[i]];
  }
  taco_iassert((this->coordinateBufferUsed % this->coordinateSize) == 0);
  size_t numCoordinates = this->coordinateBufferUsed / this->coordinateSize;
  const size_t coordSize = this->coordinateSize;
  char* coordinatesPtr = coordinateBuffer->data();
  vector<int> permuteBuffer(order);
  for (size_t i=0; i < numCoordinates; ++i) {
    int* coordinate = (int*)coordinatesPtr;
    for (size_t j = 0; j < order; j++) {
      permuteBuffer[j] = coordinate[permutation[j]];
    }
    for (size_t j = 0; j < order; j++) {
      coordinate[j] = permuteBuffer[j];
    }
    coordinatesPtr += this->coordinateSize;
  }
  coordinatesPtr = coordinateBuffer->data();
  numIntegersToCompare = order;
  qsort(coordinatesPtr, numCoordinates, coordSize, lexicographicalCmp);
  std::vector<std::vector<int>> coordinates(order);
  for (size_t i=0; i < order; ++i) {
    coordinates[i] = std::vector<int>(numCoordinates);
  }
  std::vector<double> values(numCoordinates);
  int* lastCoord = (int*)malloc(order * sizeof(int));
  if (numCoordinates >= 1) {
    int* coordComponent = (int*)coordinatesPtr;
    for (size_t d=0; d < order; ++d) {
      coordinates[d][0] = *coordComponent;
      lastCoord[d] = *coordComponent;
      coordComponent++;
    }
    values[0] = *((double*)coordComponent);
  }
  int j = 1;
  int* coord = (int*)malloc(order * sizeof(int));
  for (size_t i=1; i < numCoordinates; ++i) {
    int* coordLoc = (int*)&coordinatesPtr[i*coordSize];
    for (size_t d=0; d < order; ++d) {
      coord[d] = *coordLoc;;
      coordLoc++;
    }
    double value = *((double*)coordLoc);
    if (memcmp(coord, lastCoord, order*sizeof(int)) != 0) {
      for (size_t d = 0; d < order; d++) {
        coordinates[d][j] = coord[d];
      }
      values[j] = value;
      j++;
    }
    else {
      values[j-1] += value;
    }
  }
  free(coord);
  free(lastCoord);
  if (numCoordinates > 0) {
    for (size_t i=0; i < order; ++i) {
      coordinates[i].resize(j);
    }
    values.resize(j);
  }
  taco_iassert(coordinates.size() > 0);
  this->coordinateBuffer->clear();
  this->coordinateBufferUsed = 0;
  content->storage = storage::pack(permutedDimensions, getFormat(),
                                   coordinates, values);
}
void TensorBase :: pack ( ) { taco_tassert ( getComponentType ( ) . getKind ( ) == Type :: Float && getComponentType ( ) . getNumBits ( ) == 64 ) << " " << " " << " " << " " ; const size_t order = getOrder ( ) ; if ( order == 0 ) { char * coordLoc = this -> coordinateBuffer -> data ( ) ; double scalarValue = * ( double * ) & coordLoc [ this -> coordinateSize - getComponentType ( ) . getNumBytes ( ) ] ; content -> storage . setValues ( makeArray ( { scalarValue } ) ) ; this -> coordinateBuffer -> clear ( ) ; return ; } const std :: vector < int > & dimensions = getDimensions ( ) ; taco_iassert ( getFormat ( ) . getOrder ( ) == order ) ; std :: vector < int > permutation = getFormat ( ) . getModeOrder ( ) ; std :: vector < int > permutedDimensions ( order ) ; for ( size_t i = 0 ; i < order ; ++ i ) { permutedDimensions [ i ] = dimensions [ permutation [ i ] ] ; } taco_iassert ( ( this -> coordinateBufferUsed % this -> coordinateSize ) == 0 ) ; size_t numCoordinates = this -> coordinateBufferUsed / this -> coordinateSize ; const size_t coordSize = this -> coordinateSize ; char * coordinatesPtr = coordinateBuffer -> data ( ) ; vector < int > permuteBuffer ( order ) ; for ( size_t i = 0 ; i < numCoordinates ; ++ i ) { int * coordinate = ( int * ) coordinatesPtr ; for ( size_t j = 0 ; j < order ; j ++ ) { permuteBuffer [ j ] = coordinate [ permutation [ j ] ] ; } for ( size_t j = 0 ; j < order ; j ++ ) { coordinate [ j ] = permuteBuffer [ j ] ; } coordinatesPtr += this -> coordinateSize ; } coordinatesPtr = coordinateBuffer -> data ( ) ; numIntegersToCompare = order ; qsort ( coordinatesPtr , numCoordinates , coordSize , lexicographicalCmp ) ; std :: vector < std :: vector < int > > coordinates ( order ) ; for ( size_t i = 0 ; i < order ; ++ i ) { coordinates [ i ] = std :: vector < int > ( numCoordinates ) ; } std :: vector < double > values ( numCoordinates ) ; int * lastCoord = ( int * ) malloc ( order * sizeof ( int ) ) ; if ( numCoordinates >= 1 ) { int * coordComponent = ( int * ) coordinatesPtr ; for ( size_t d = 0 ; d < order ; ++ d ) { coordinates [ d ] [ 0 ] = * coordComponent ; lastCoord [ d ] = * coordComponent ; coordComponent ++ ; } values [ 0 ] = * ( ( double * ) coordComponent ) ; } int j = 1 ; int * coord = ( int * ) malloc ( order * sizeof ( int ) ) ; for ( size_t i = 1 ; i < numCoordinates ; ++ i ) { int * coordLoc = ( int * ) & coordinatesPtr [ i * coordSize ] ; for ( size_t d = 0 ; d < order ; ++ d ) { coord [ d ] = * coordLoc ; ; coordLoc ++ ; } double value = * ( ( double * ) coordLoc ) ; if ( memcmp ( coord , lastCoord , order * sizeof ( int ) ) != 0 ) { for ( size_t d = 0 ; d < order ; d ++ ) { coordinates [ d ] [ j ] = coord [ d ] ; } values [ j ] = value ; j ++ ; } else { values [ j - 1 ] += value ; } } free ( coord ) ; free ( lastCoord ) ; if ( numCoordinates > 0 ) { for ( size_t i = 0 ; i < order ; ++ i ) { coordinates [ i ] . resize ( j ) ; } values . resize ( j ) ; } taco_iassert ( coordinates . size ( ) > 0 ) ; this -> coordinateBuffer -> clear ( ) ; this -> coordinateBufferUsed = 0 ; content -> storage = storage :: pack ( permutedDimensions , getFormat ( ) , coordinates , values ) ; }
Pack coordinates into a data structure given by the tensor format.
Pack coordinates into a data structure given by the tensor format .
// Pack scalars /// Permute the coordinates according to the storage dimension ordering. /// This is a workaround since the current pack code only packs tensors in the /// order of the dimensions. // The pack code expects the coordinates to be sorted // Move coords into separate arrays and remove duplicates // Copy first coordinate-value pair // Copy remaining coordinate-value pairs, removing duplicates // Pack indices and values //  std::cout << storage::packCode(getFormat()) << std::endl;