MPI并行LU分解程序运行崩溃,错误码0xc0000005求助
MPI并行LU分解程序运行崩溃,错误码0xc0000005求助
兄弟,我看了你贴的代码和报错信息,这个0xc0000005是Windows平台下的访问违规(Access Violation),说白了就是程序读写了不属于它的内存区域,大概率是内存越界、野指针或者未初始化变量导致的。咱们一步步排查问题:
1. MPI_Bcast参数错误,导致未初始化内存被使用
看你LuDecomposer.cpp里的Multiplication函数:
if (thread_rank == 0) { interval[0] = 0; interval[1] = subMatrixHeight; cpu_time_start = MPI_Wtime(); } MPI_Bcast(&interval, 1, MPI_INT, 0, MPI_COMM_WORLD);
这里有两个严重问题:
- 首先,
interval变量的定义没看到,如果是类成员变量,那rank0之外的进程根本没初始化它,内存里是垃圾值; - 其次,
MPI_Bcast的count参数写的是1,但interval是两个int的数组,你只广播了第一个元素,第二个元素还是垃圾值!其他进程拿到的interval[1]是随机数,后续计算range的时候必然出错,循环访问数组时直接越界。
修复建议:把interval改成函数内的局部数组,并且广播完整的2个int:
int interval[2]; // 局部数组,每个进程都有自己的实例 if (thread_rank == 0) { interval[0] = 0; interval[1] = subMatrixHeight; cpu_time_start = MPI_Wtime(); } MPI_Bcast(interval, 2, MPI_INT, 0, MPI_COMM_WORLD); // count改为2
2. get_interval函数可能返回野指针
你写的range = get_interval(thread_rank, thread_size, interval);,如果get_interval是返回栈上分配的数组(比如int range[2]; return range;),那这个指针在函数返回后就失效了,访问它就是非法内存操作,直接触发0xc0000005。
修复建议:不要返回栈数组,改成传入一个已分配的数组作为参数:
// 重写get_interval函数 void LuDecomposer::get_interval(int rank, int size, const int interval[], int range[]) { int total_rows = interval[1] - interval[0]; int base_chunk = total_rows / size; int remainder = total_rows % size; // 计算当前rank负责的起始和结束行 range[0] = interval[0] + rank * base_chunk + (rank < remainder ? rank : remainder); range[1] = range[0] + base_chunk + (rank < remainder ? 1 : 0); }
调用的时候:
int range[2]; get_interval(thread_rank, thread_size, interval, range);
3. 矩阵索引计算错误,导致数组越界
看你Multiplication里的循环逻辑,矩阵乘法的索引明显有问题:
u = (range[0] + rowBiasA) * size + colBiasA; for (int j = 0; j < subMatrixWidth; j++) { v = (j + rowBiasB) * size + colBiasB; p = u + j; for (int t = 0; t < subMatrixHeight; t++) { Res[range[0] * subMatrixHeight + t] += A[p] * B[v + t]; } }
矩阵乘法的正确逻辑是Res[i][j] = sum(A[i][t] * B[t][j]),但你的索引计算完全不符合这个逻辑:
p = u + j相当于给A的列索引直接加j,这会超出你要访问的子矩阵范围;Res[range[0] * subMatrixHeight + t]这里用subMatrixHeight作为列数是错的,Res的列数应该是subMatrixWidth,这样索引必然越界。
修复建议:重新梳理矩阵乘法的索引,比如改成:
int current_row = range[0] + rowBiasA; for (int j = 0; j < subMatrixWidth; j++) { int current_col = j + colBiasB; double sum = 0.0; for (int t = 0; t < subMatrixHeight; t++) { int a_idx = current_row * size + (colBiasA + t); int b_idx = (rowBiasB + t) * size + current_col; sum += A[a_idx] * B[b_idx]; } Res[range[0] * subMatrixWidth + j] = sum; }
4. 其他潜在问题
processor_name的分配可以简化:new char[MPI_MAX_PROCESSOR_NAME]就够了,因为char的大小就是1,不用乘sizeof(char);- 确保
decomposer指针在LuTests里是有效的,你在LuTests构造函数里传的是&decomposer,要确认这个对象生命周期覆盖整个测试过程。
先把上面几个核心问题修复,应该就能解决这个崩溃问题了。
备注:内容来源于stack exchange,提问作者KennethRice
相关产品推荐
相关产品推荐

