Prompt Title: nlhdh

Created 1 year ago
Votes 0
Views 45 times
0
Human: Xét hai ma trận A và B trong đó A là ma trận M hàng và K cột; và B là ma trận K hàng và N cột. Tích của hai ma trận A và B là ma trận C có M hàng và N cột trong đó giá trị phần tử tại hàng i cột j là Ci,j được tính theo công thức: Ci,j = Tổng ( Ai,n * Bn,j ) (for i = 1; i < K; i++) . Ví dụ, nếu A có 3 hàng 2 cột và B có 2 hàng và 3 cột, thì phần tử C3,1 được tính là tổng của A3,1 * B1,1 và A3,2 * B2,1. Yêu cầu: - Bạn phải tạo ra M * N tuyến để tính toán. Mỗi tuyến tính toán một phần tử Ci,j của ma trận kết quả. - Các ma trận A và B phải được đọc từ file data.dat trong đó các số nguyên dương M, K và N được ghi ở dòng đầu tiên; M dòng sau là các hàng của ma trận A; và K dòng tiếp theo ghi các hàng của ma trận B. Gợi ý: - Tuyến cha sẽ tạo ra M * N tuyến con để tính toán, các tuyến này sẽ nhận tham số đầu vào là dòng i và cột j, tính toán phần tử Ci,j của ma trận kết quả. - Khi tất cả các tuyến đã tính toán xong, tuyến cha sẽ in ra màn hình ma trận kết quả C. Để làm điều này, tuyến cha phải đợi mọi tuyến tính toán kết thúc trước khi in ra kết quả. viết lại bằng ngôn ngữ C giúp tôi nhé
ChatGPT:

Để giải quyết bài toán, chúng ta có thể sử dụng mô hình đồng bộ hóa dữ liệu (data parallelism) trong lập trình song song. Ta có thể sử dụng OpenMP để tạo ra các tiểu trình để tính toán một phần tử của ma trận kết quả.

Đầu tiên, ta cần định nghĩa số hàng và số cột của ma trận kết quả. Sau đó, ta sẽ đọc vào ma trận A và ma trận B từ tệp dữ liệu data.dat.

Tiếp theo, ta sử dụng các vòng lặp để tạo ra M * N tiểu trình để tính toán một phần tử của ma trận kết quả. Mỗi tiểu trình sẽ tính toán một phần tử của ma trận kết quả theo công thức đã cho và lưu vào một mảng.

Cuối cùng, tuyến chính sẽ đợi tất cả các tiểu trình tính toán xong, sau đó in ra ma trận kết quả.

Dưới đây là mã nguồn cho bài toán trên:

C
#include <stdio.h> #include <stdlib.h> #include <omp.h> int main() { int M, K, N, i, j, n; double sum; // Đọc vào số hàng, số cột của ma trận A và ma trận B FILE *fp = fopen("data.dat", "r"); fscanf(fp, "%d %d %d", &M, &K, &N); // Tạo ma trận A và đọc vào từ tệp dữ liệu double **A = (double **)malloc(M * sizeof(double *)); for (i = 0; i < M; i++) A[i] = (double *)malloc(K * sizeof(double)); for (i = 0; i < M; i++) for (j = 0; j < K; j++) fscanf(fp, "%lf", &A[i][j]); // Tạo ma trận B và đọc vào từ tệp dữ liệu double **B = (double **)malloc(K * sizeof(double *)); for (i = 0; i < K; i++) B[i] = (double *)malloc(N * sizeof(double)); for (i = 0; i < K; i++) for (j = 0; j < N; j++) fscanf(fp, "%lf", &B[i][j]); // Tạo ma trận C và tính toán giá trị của từng phần tử double **C = (double **)malloc(M * sizeof(double *)); for (i = 0; i < M; i++) C[i] = (double *)malloc(N * sizeof(double)); #pragma omp parallel for private(j, n, sum) for (i = 0; i < M; i++) { for (j = 0; j < N; j++) { sum = 0.0; for (n = 0; n < K; n++) sum += A[i][n] * B[n][
Human: tiếp tục
ChatGPT:

Đây là phần tiếp theo của code:

css
int main() { // Đọc file và lưu ma trận AB vào các mảng FILE* fp; fp = fopen("data.dat", "r"); int M, K, N; fscanf(fp, "%d %d %d", &M, &K, &N); int A[M][K], B[K][N]; for (int i = 0; i < M; i++) { for (int j = 0; j < K; j++) { fscanf(fp, "%d", &A[i][j]); } } for (int i = 0; i < K; i++) { for (int j = 0; j < N; j++) { fscanf(fp, "%d", &B[i][j]); } } fclose(fp); // Tạo các tuyến con để tính toán phần tử Ci,j của ma trận kết quả #pragma omp parallel num_threads(M*N) { int tid = omp_get_thread_num(); int i = tid / N; int j = tid % N; int sum = 0; for (int n = 0; n < K; n++) { sum += A[i][n] * B[n][j]; } #pragma omp critical { C[i][j] = sum; } } // In ra ma trận kết quả C for (int i = 0; i < M; i++) { for (int j = 0; j < N; j++) { printf("%d ", C[i][j]); } printf("\n"); } return 0; }

Trong hàm main, đầu tiên chúng ta đọc file data.dat và lưu ma trận A và B vào các mảng AB tương ứng. Sau đó, chúng ta tạo các tuyến con để tính toán phần tử Ci,j của ma trận kết quả. Mỗi tuyến con tính toán một phần tử và lưu vào mảng C. Ở đây, chúng ta sử dụng num_threads(M*N) để tạo ra M*N tuyến con, và sử dụng hàm omp_get_thread_num() để lấy ra ID của tuyến con hiện tại. Tiếp theo, chúng ta tính toán phần tử C[i][j] của ma trận kết quả bằng cách sử dụng công thức đã cho. Cuối cùng, chúng ta sử dụng #pragma omp critical để đảm bảo rằng chỉ có một tuyến con được phép thực hiện lệnh ghi vào mảng C một lúc.

Sau khi tất cả các tuyến con đã tính toán xong, chúng ta in ra ma trận kết quả C bằng cách duyệt qua mảng C và in từng phần tử ra màn hình.

avatar
Nguyễn Hồng Đức
Shared 2 prompts
Created 1 year ago

Leave a Comment