RowMatrix(int rows, int cols) : Matrix<T>(rows, cols) { data_ = new T *[rows]; for (int i = 0; i < rows; i++) { data_[i] = &this->linear_[i * cols]; } }
T GetElement(int i, int j)constoverride { if(i<0 || j<0 || i>=this->rows_ || j>= this->cols_) { throwException(ExceptionType::OUT_OF_RANGE, "RowMatrix::GetElement(i, j) out of range."); } return data_[i][j]; }
voidSetElement(int i, int j, T val)override { if(i<0 || j<0 || i>=this->rows_ || j>= this->cols_) { throwException(ExceptionType::OUT_OF_RANGE, "RowMatrix::SetElement(i, j, val) out of range."); } data_[i][j] = val; }
矩阵基类还需要实现一个从容器中获取数据对矩阵进行填充的函数
tips: Vector.size() 返回的是无符号整数
1 2 3 4 5 6 7 8 9 10 11 12
voidFillFrom(const std::vector<T> &source)override { int size = static_cast<int>(source.size()); if (size != this->rows_ * this->cols_) { throwException(ExceptionType::OUT_OF_RANGE, "RowMatrix::FillFrom(source) out of range."); } for (int i = 0; i < size; i++) { this->linear_[i] = source[i]; } }
static std::unique_ptr<RowMatrix<T>> Add(const RowMatrix<T> *matrixA, const RowMatrix<T> *matrixB) { int left; int right; int rows = matrixA->GetRowCount(); int cols = matrixB->GetColumnCount(); if (rows != matrixB->GetRowCount() || matrixA->GetColumnCount() != cols) { return std::unique_ptr<RowMatrix<T>>(nullptr); } std::unique_ptr<RowMatrix<T>> res(newRowMatrix<T>(rows, cols)); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { left = matrixA->GetElement(i, j); right = matrixB->GetElement(i, j); res->SetElement(i, j, left + right); } } return res; }
static std::unique_ptr<RowMatrix<T>> Multiply(const RowMatrix<T> *matrixA, const RowMatrix<T> *matrixB) { int left; int right; int rows = matrixA->GetRowCount(); int cols = matrixB->GetColumnCount(); if (matrixA->GetColumnCount() != matrixB->GetRowCount()) { return std::unique_ptr<RowMatrix<T>>(nullptr); } T element; int temp = matrixA->GetColumnCount(); std::unique_ptr<RowMatrix<T>> res(newRowMatrix<T>(rows, cols)); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { element = 0; for (int k = 0; k < temp; k++) { left = matrixA->GetElement(i, k); right = matrixB->GetElement(k, j); element += left * right; } res->SetElement(i, j, element); } } return res; }
static std::unique_ptr<RowMatrix<T>> GEMM(const RowMatrix<T> *matrixA, const RowMatrix<T> *matrixB, const RowMatrix<T> *matrixC) { int left; int right; int rows = matrixA->GetRowCount(); int cols = matrixB->GetColumnCount(); if (rows != matrixC->GetRowCount() || cols != matrixC->GetColumnCount()) { return std::unique_ptr<RowMatrix<T>>(nullptr); } T element; int temp = matrixA->GetColumnCount(); std::unique_ptr<RowMatrix<T>> res(newRowMatrix<T>(rows, cols)); for (int i = 0; i < rows; i++) { for (int j = 0; j < cols; j++) { element = matrixC->GetElement(i, j); for (int k = 0; k < temp; k++) { left = matrixA->GetElement(i, k); right = matrixB->GetElement(k, j); element += left * right; } res->SetElement(i, j, element); } } return res; }
Test and Format
build目录下 用 make starter_test 和 ./test/start_test 进行测试,需要去除test目录下相应的cpp文件中函数参数中的 disable 前缀 用 make format 和 make check-lint 还有 make check-clang-tidy 进行格式检查 check-clang-tidy 比较慢,可以不做,上传测试网站后可以复制错误报告查看错误详情 一般本地测试过了代码就没啥问题了,有问题都是因为格式问题
/** * Flushes the target page to disk. * @param page_id id of page to be flushed, cannot be INVALID_PAGE_ID * @return false if the page could not be found in the page table, true otherwise */
BufferPoolManager *ParallelBufferPoolManager::GetBufferPoolManager(page_id_t page_id){ // Get BufferPoolManager responsible for handling given page id. You can use this method in your other methods. return instances_[page_id % num_instances_]; }
Page *ParallelBufferPoolManager::NewPgImp(page_id_t *page_id){ // create new page. We will request page allocation in a round robin manner from the underlying // BufferPoolManagerInstances // 1. From a starting index of the BPMIs, call NewPageImpl until either 1) success and return 2) looped around to // starting index and return nullptr // 2. Bump the starting index (mod number of instances) to start search at a different BPMI each time this function // is called Page *res; for (size_t i = 0; i < num_instances_; i++) { size_t index = (start_idx_ + i) % num_instances_; if ((res = instances_[index]->NewPage(page_id)) != nullptr) { start_idx_ = (*page_id + 1) % num_instances_; return res; } } start_idx_++; returnnullptr; }