Send yet again...

RFC: Change of API in mpool

WHAT: Remove dependency on ompi_info_t in mca_mpool_base_alloc  

WHY: To be able to move mpool out of the ompi-layer.

WHERE: Changes just in the mpool and in ompi/mpi/c/alloc_mem.c 

WHEN: Open MPI-1.4 

TIMEOUT: February 3, 2009. 

-------------------------------------
Details:
WHY:
With the proposed move of the BTL framework out of the ompi-layer, we 
need to move/copy a few dependant class- and other functionality with it 
(omp_free_list, ompi_bitmap, ompi_rb_tree, common, mpool, allocator, 
rcache).

The only real dependency problem, visible right now, that requires a 
change is the function mca_mpool_base_alloc, which requires ompi_info_t.

WHAT:
In order to make mca_mpool_base_alloc oblivious of MPI, we'd propose 
passing all relevant info as opal_list_t -- and prepare this by the only 
caller ompi/mpi/c/alloc_mem.c, which only copies ("mpool",value)-pairs 
into a list (if there are any).

The patchlet can be applied to trunk / or the branch koenig-btl, however, 
I left out the required (but boring) svn mv and rename of ompi->onet.

Has been tested with the supplied test-program, produces the expected 
results.

Any comments are welcome.

CU,
Rainer
-- 
------------------------------------------------------------------------
Rainer Keller, PhD                  Tel: (865) 241-6293
Oak Ridge National Lab          Fax: (865) 241-4811
PO Box 2008 MS 6164           Email: kel...@ornl.gov
Oak Ridge, TN 37831-2008    AIM/Skype: rusraink



Index: onet/mca/mpool/mpool.h
===================================================================
--- onet/mca/mpool/mpool.h	(revision 20371)
+++ onet/mca/mpool/mpool.h	(working copy)
@@ -51,6 +51,20 @@
 OMPI_DECLSPEC OBJ_CLASS_DECLARATION(mca_mpool_base_registration_t); 

 /**
+ * \internal
+ * Used to pass Info from the ompi-layer down.
+ */
+struct mca_mpool_base_info_entry_t {
+    opal_list_item_t super;
+    char * value;
+};
+
+typedef struct mca_mpool_base_info_entry_t mca_mpool_base_info_entry_t;
+
+OMPI_DECLSPEC OBJ_CLASS_DECLARATION(mca_mpool_base_info_entry_t);
+
+
+/**
  * component initialize
  */
 typedef struct mca_mpool_base_module_t* (*mca_mpool_base_component_init_fn_t)(
@@ -208,7 +222,7 @@
  * @retval pointer to the allocated memory
  * @retval NULL on failure
  */
-OMPI_DECLSPEC void * mca_mpool_base_alloc(size_t size, struct ompi_info_t * info);
+OMPI_DECLSPEC void * mca_mpool_base_alloc(size_t size, opal_list_t *info_list);

 /**
  * Function to free memory previously allocated by mca_mpool_base_alloc
Index: onet/mca/mpool/base/mpool_base_alloc.c
===================================================================
--- onet/mca/mpool/base/mpool_base_alloc.c	(revision 20371)
+++ onet/mca/mpool/base/mpool_base_alloc.c	(working copy)
@@ -23,13 +23,36 @@
 #if HAVE_STRING_H
 #include <string.h>
 #endif  /* HAVE_STRING_H */
-#include "ompi/mca/mpool/mpool.h"
+#include "opal/threads/mutex.h" 
+#include "onet/mca/mpool/mpool.h"
 #include "base.h"
 #include "mpool_base_tree.h"
-#include "opal/threads/mutex.h" 
 #include "mpool_base_mem_cb.h"

 /**
+ * Pass information from the ompi-layer to the mpool
+ */
+static void mca_mpool_base_info_constructor(mca_mpool_base_info_entry_t * entry);
+static void mca_mpool_base_info_destructor(mca_mpool_base_info_entry_t *entry);
+
+OBJ_CLASS_INSTANCE(mca_mpool_base_info_entry_t,
+                   opal_list_item_t,
+                   mca_mpool_base_info_constructor,
+                   mca_mpool_base_info_destructor);
+
+static void mca_mpool_base_info_constructor(mca_mpool_base_info_entry_t * entry)
+{
+}
+
+static void mca_mpool_base_info_destructor(mca_mpool_base_info_entry_t *entry)
+{
+    if (NULL != entry->value) {
+        free (entry->value);
+    }
+}
+
+
+/**
  * Memory Pool Registration
  */

@@ -93,7 +116,7 @@
  * @retval pointer to the allocated memory
  * @retval NULL on failure
  */
-void *mca_mpool_base_alloc(size_t size, ompi_info_t *info)
+void *mca_mpool_base_alloc(size_t size, opal_list_t *info_list)
 {
     opal_list_item_t * item;
     int num_modules = opal_list_get_size(&mca_mpool_base_modules);
@@ -107,8 +130,9 @@
     mca_mpool_base_module_t *mpool;
     void * mem = NULL;
     int flag = 0;
-    bool match_found = false;
+    bool mpool_matched = false;
     bool mpool_requested = false;
+    int info_list_size;

     if(num_modules > 0) {
         has_reg_function = (mca_mpool_base_selected_module_t **)
@@ -125,7 +149,9 @@
     mpool_tree_item->num_bytes = size;
     mpool_tree_item->count = 0;

-    if(&ompi_mpi_info_null == info)
+    info_list_size = opal_list_get_size (info_list);
+
+    if(0 == info_list_size)
     {
         for(item = opal_list_get_first(&mca_mpool_base_modules);
             item != opal_list_get_end(&mca_mpool_base_modules);
@@ -143,33 +169,24 @@
     }
     else
     {
-        int num_keys;
-        char key[MPI_MAX_INFO_KEY + 1];
-        char value[MPI_MAX_INFO_VAL + 1];
+        mca_mpool_base_info_entry_t * info_list_item;
+        char * value;

-        ompi_info_get_nkeys(info, &num_keys);
-        for(i = 0; i < num_keys; i++)
-        {
-            ompi_info_get_nthkey(info, i, key);
-            if ( 0 != strcmp(key, "mpool") ) {
-                continue;
-            }
+        for(info_list_item = opal_list_get_first(info_list);
+            info_list_item != opal_list_get_end(info_list);
+            info_list_item = opal_list_get_next(info_list_item)) {
+
             mpool_requested = true;
-            ompi_info_get(info, key, MPI_MAX_INFO_VAL, value, &flag);
-            if ( !flag ) {
-                continue;
-            }
-
-            match_found = false;
+            mpool_matched = false;
             for(item = opal_list_get_first(&mca_mpool_base_modules);
                 item != opal_list_get_end(&mca_mpool_base_modules);
-                item = opal_list_get_next(item)) 
+                item = opal_list_get_next(item))
             {
                 current = ((mca_mpool_base_selected_module_t *)item);
-                if(0 == strcmp(value, 
+                if(0 == strcmp(info_list_item->value,
                        current->mpool_module->mpool_component->mpool_version.mca_component_name))
                 {
-                    match_found = true;
+                    mpool_matched = true;
                     if(NULL == current->mpool_module->mpool_register)
                     {
                         if(NULL != no_reg_function)
@@ -186,7 +203,7 @@
                     }
                 }
             }
-            if(!match_found)
+            if(!mpool_matched)
             {
                 /* one of the keys given to us by the user did not match any
                  * mpools, so return an error */
Index: ompi/mpi/c/alloc_mem.c
===================================================================
--- ompi/mpi/c/alloc_mem.c	(revision 20383)
+++ ompi/mpi/c/alloc_mem.c	(working copy)
@@ -10,6 +10,7 @@
  * Copyright (c) 2004-2005 The Regents of the University of California.
  *                         All rights reserved.
  * Copyright (c) 2007      Cisco Systems, Inc.  All rights reserved.
+ * Copyright (c) 2009      Oak Ridge National Labs.  All rights reserved.
  * $COPYRIGHT$
  * 
  * Additional copyrights may follow
@@ -24,7 +25,8 @@

 #include "ompi/mpi/c/bindings.h"
 #include "ompi/info/info.h"
-#include "ompi/mca/mpool/mpool.h"
+#include "onet/mca/mpool/mpool.h"
+#include "opal/class/opal_list.h"

 #if OMPI_HAVE_WEAK_SYMBOLS && OMPI_PROFILING_DEFINES
 #pragma weak MPI_Alloc_mem = PMPI_Alloc_mem
@@ -39,6 +41,10 @@

 int MPI_Alloc_mem(MPI_Aint size, MPI_Info info, void *baseptr)
 {
+    int rc = MPI_SUCCESS;
+    int i;
+    int num_keys;
+    opal_list_t info_list;

     if (MPI_PARAM_CHECK) {
         OMPI_ERR_INIT_FINALIZE(FUNC_NAME);
@@ -65,14 +71,44 @@

     OPAL_CR_ENTER_LIBRARY();

-    *((void **) baseptr) = mca_mpool_base_alloc((size_t) size, info);
+    ompi_info_get_nkeys(info, &num_keys);
+
+    OBJ_CONSTRUCT(&info_list, opal_list_t);
+
+    for(i = 0; i < num_keys; i++) {
+        int flag;
+        char key[MPI_MAX_INFO_KEY + 1];
+        char value[MPI_MAX_INFO_VAL + 1];
+        mca_mpool_base_info_entry_t * val;
+
+        ompi_info_get_nthkey(info, i, key);
+        if ( 0 != strcmp(key, "mpool") ) {
+            continue;
+        }
+
+        ompi_info_get(info, key, MPI_MAX_INFO_VAL, value, &flag);
+ 
+        /* Well, if the key mpool was set, there should be a value to be found! */
+        assert (1 == flag);
+
+        val = OBJ_NEW(ompi_info_entry_t);
+        if (NULL == val) {
+            rc = MPI_ERR_NO_MEM;
+            goto out;            
+        }
+        val->value = strdup (value);
+
+        opal_list_prepend (&info_list, (opal_list_item_t*)val);
+    }
+ 
+    *((void **) baseptr) = mca_mpool_base_alloc((size_t) size, &info_list);
     OPAL_CR_EXIT_LIBRARY();
+
     if (NULL == *((void **) baseptr)) {
-        return OMPI_ERRHANDLER_INVOKE(MPI_COMM_WORLD, MPI_ERR_NO_MEM, 
-                                      FUNC_NAME);
+        rc = MPI_ERR_NO_MEM;
     }

-    /* All done */
-    return MPI_SUCCESS;
+out:
+    OBJ_DESTRUCT (&info_list);
+    OMPI_ERRHANDLER_RETURN(rc, MPI_COMM_WORLD, rc, FUNC_NAME);
 }
-
#include <stdio.h>
#include <stdint.h>

#include "mpi.h"

int main (int argc, char * argv[])
{
    int comm_size, comm_rank;
    char processor_name[MPI_MAX_PROCESSOR_NAME];
    int len;
    int rc;
    MPI_Info info;
    char * ptr;

    MPI_Init (&argc, &argv);
    MPI_Comm_size (MPI_COMM_WORLD, &comm_size);
    MPI_Comm_rank (MPI_COMM_WORLD, &comm_rank);

    MPI_Get_processor_name (processor_name, &len);


    MPI_Info_create (&info);

    if (0 == comm_rank) {
        printf ("1. MPI_Allocmem w/ MPI_INFO_NULL\n");
        rc = MPI_Alloc_mem (1024, MPI_INFO_NULL, &ptr);
        if (MPI_SUCCESS != rc || ptr == NULL)
          printf ("(Rank:%d) Error:%d after MPI_Alloc_mem\n",
                  comm_rank, rc);

        printf ("2. MPI_Allocmem w/ rubbish key\n");
        rc = MPI_Info_set (info, "zipp", "nada");
        if (MPI_SUCCESS != rc)
          printf ("(Rank:%d) Error:%d after MPI_Info_set\n",
                  comm_rank, rc);
        rc = MPI_Alloc_mem (1024, info, &ptr);
        if (MPI_SUCCESS != rc || ptr == NULL)
          printf ("(Rank:%d) Error:%d after MPI_Alloc_mem\n",
                  comm_rank, rc);

        printf ("3. MPI_Allocmem w/ mpool and good value\n");
        rc = MPI_Info_set (info, "mpool", "sm");
        if (MPI_SUCCESS != rc)
          printf ("(Rank:%d) Error:%d after MPI_Info_set\n",
                  comm_rank, rc);
        rc = MPI_Alloc_mem (1024, info, &ptr);
        if (MPI_SUCCESS != rc || ptr == NULL)
          printf ("(Rank:%d) Error:%d after MPI_Alloc_mem\n",
                  comm_rank, rc);

        printf ("4. MPI_Allocmem w/ mpool but rubbish value, EXPECT FAILURE\n");
        rc = MPI_Info_set (info, "mpool", "kjsahdfk");
        if (MPI_SUCCESS != rc)
          printf ("(Rank:%d) Error:%d after MPI_Info_set\n",
                  comm_rank, rc);
        rc = MPI_Alloc_mem (1024, info, &ptr);
        if (MPI_SUCCESS != rc || ptr == NULL)
          printf ("(Rank:%d) Error:%d after MPI_Alloc_mem\n",
                  comm_rank, rc);
    }

    MPI_Finalize ();

    return 0;
}

Reply via email to