एमपीआई संरचनाओं के सरणी के साथ काम करने के लिए डिज़ाइन किया गया है, बजाय सरणी की संरचनाओं के साथ।
MPI_Hindexed
कि @suszterpatt प्रस्तावित एक भयानक हैक है। यह आपको केवल संरचना प्रकार का एक तत्व और केवल उस तत्व को भेजने की अनुमति देगा जिसका उपयोग MPI डेटा प्रकार को परिभाषित करने के लिए किया गया था। उसी संरचना प्रकार के अन्य चर के लिए यह अधिकतर गारंटी है कि गणना किए गए ऑफसेट गलत होंगे। के अलावा हिंदेक्स प्रकार सभी तत्वों के लिए एक और एक ही एमपीआई डेटा प्रकार का उपयोग करते हैं और इस प्रकार आप दोनों स्याही और युगल भेजने की अनुमति नहीं देते हैं।
करने के लिए बुद्धिमान बात संरचनाओं की सरणियों का उपयोग करने के अपने कार्यक्रम को बदलने के लिए है:
typedef struct
{
int i;
double z;
} point;
typedef struct
{
point *A;
int nz;
} column;
अब
आप कर सकते हैं एक MPI संरचित प्रकार point_type
बना सकते हैं और उस प्रकार column.A
के रूप में देने का nz
तत्वों भेजने के लिए इसका इस्तेमाल करते हैं बफर पता:
int lens[3];
MPI_Aint base, disps[2];
MPI_Datatype oldtypes[2], point_struct, point_type;
MPI_Get_address(&point, disps);
MPI_Get_address(&point.z, disps+1);
base = disps[0];
lens[0] = 1; disps[0] = MPI_Aint_diff(disps[0], base); oldtypes[0] = MPI_INT;
lens[1] = 1; disps[1] = MPI_Aint_diff(disps[1], base); oldtypes[1] = MPI_DOUBLE;
MPI_Type_create_struct(2, lens, disps, oldtypes, &point_struct);
MPI_Type_create_resized(point_struct, 0, sizeof(point), &point_type);
MPI_Type_commit(&point_type);
MPI_Send(column.A, column.nz, point_type, ...);
यह पहली एक MPI डेटाप्रकार point_struct
कि संरचना के सदस्यों के लेआउट का वर्णन करता है बनाता है, लेकिन एन पर किसी भी गद्दी के लिए खाते में नहीं है डी और इसलिए विश्वसनीय रूप से ऐसी संरचनाओं की एक सरणी भेजने के लिए उपयोग नहीं किया जा सकता है। इसलिए, MPI_Type_create_resized
का उपयोग करके सही सीमा के साथ एक दूसरा डेटाटाइप point_type
बनाया गया है।
रिसीवर की ओर पर आप MPI_Probe
साथ संदेश झांक सकते हैं, point_type
का एक प्रकार के साथ MPI_Get_count
साथ तत्वों की संख्या निकालने (कि nz
क्षेत्र के लिए सीधे चला जाता है), A
क्षेत्र का आवंटन और MPI_Recv
में उपयोग प्राप्त करने के लिए nz
तत्वों:
MPI_Status status;
MPI_Probe(source, tag, comm, &status);
MPI_Get_count(&status, point_type, &column.nz);
if (nz == MPI_UNDEFINED)
... non-integral message was received, do something
column.A = (point *)malloc(column.nz*sizeof(point));
MPI_Recv(column.A, column.nz, point_type, source, tag, comm, MPI_STATUS_IGNORE);
हैं कि कोड में परिवर्तन करना असंभव आप अभी भी इसे भेजने से पहले अपने संरचना बदलने के मध्यवर्ती चरण के माध्यम से जा सकते हैं, एक प्रक्रिया आम तौर पर कहा जाता है (संयुक्त राष्ट्र) प्रमुखता। रिसीवर तरफ
point *temp = (point *)malloc(nz*sizeof(point));
for (int i = 0; i < column.nz; i++)
{
temp[i].i = column.Ai[i];
temp[i].z = column.Az[i];
}
MPI_Send(temp, nz, point_type, ...);
free(temp);
आप विपरीत कार्य करना होगा:: आपके मामले में (मुझे लगता है कि आप nz
क्षेत्र में दोनों Ai
और Ax
में सरणी तत्वों की संख्या की दुकान) कुछ इस तरह करते हैं पर्याप्त एक बड़े आवंटन बफर जो संरचना को पकड़ सकता है, इसमें संदेश प्राप्त कर सकता है और फिर विपरीत परिवर्तन कर सकता है।
एक बार फिर, आपको nz
के वास्तविक मान को प्रेषित करने की आवश्यकता नहीं है क्योंकि इसे MPI_Get_count
का उपयोग करके संदेश की लंबाई से आसानी से निकाला जा सकता है।
आप कभी भी एमपीआई प्रक्रियाओं के बीच पॉइंटर्स क्यों भेजना चाहते हैं? वे वितरित स्मृति प्रणालियों में गैर पोर्टेबल हैं। – talonmies