export/import hdf5 : management of hypermatrix. 28/15228/7
Cedric Delamarre [Tue, 16 Sep 2014 11:44:36 +0000 (13:44 +0200)]
a=rand(3,2,4)
export_to_hdf5("~/hypermat.sod", "a");
clear a;
import_from_hdf5("~/hypermat.sod");
a

Change-Id: I1931d9b48216268a7dec4f7ccb936430778bec1f

scilab/modules/hdf5/sci_gateway/cpp/sci_export_to_hdf5.cpp
scilab/modules/hdf5/sci_gateway/cpp/sci_import_from_hdf5.cpp

index b7d88ac..50e50c6 100644 (file)
@@ -11,6 +11,9 @@
 */
 
 #include <hdf5.h>
+#include "internal.hxx"
+#include "types.hxx"
+
 extern "C"
 {
 #include <string.h>
@@ -40,6 +43,7 @@ static bool isVarExist(int* pvCtx, int _iFile, char* _pstVarName);
 
 static bool export_data(int* pvCtx, int _iH5File, int *_piVar, char* _pstName);
 static bool export_list(int* pvCtx, int _iH5File, int *_piVar, char* _pstName, int _iVarType);
+static bool export_hypermat(int* pvCtx, int _iH5File, int *_piVar, char* _pstName);
 static bool export_double(int* pvCtx, int _iH5File, int *_piVar, char* _pstName);
 static bool export_poly(int* pvCtx, int _iH5File, int *_piVar, char* _pstName);
 static bool export_boolean(int* pvCtx, int _iH5File, int *_piVar, char* _pstName);
@@ -259,6 +263,8 @@ static bool export_data(int* pvCtx, int _iH5File, int* _piVar, char* _pstName)
 {
     bool bReturn = false;
     int iType = 0;
+    int iDims = 0;
+    types::InternalType* pIT = (types::InternalType*)_piVar;
 
     SciErr sciErr = getVarType(pvCtx, _piVar, &iType);
     if (sciErr.iErr)
@@ -267,91 +273,105 @@ static bool export_data(int* pvCtx, int _iH5File, int* _piVar, char* _pstName)
         return false;
     }
 
-    switch (iType)
+    if (pIT->isGenericType())
     {
-        case sci_matrix :
-        {
-            bReturn = export_double(pvCtx, _iH5File, _piVar, _pstName);
-            break;
-        }
-        case sci_poly :
-        {
-            bReturn = export_poly(pvCtx, _iH5File, _piVar, _pstName);
-            break;
-        }
-        case sci_boolean :
-        {
-            bReturn = export_boolean(pvCtx, _iH5File, _piVar, _pstName);
-            break;
-        }
-        case sci_sparse :
-        {
-            bReturn = export_sparse(pvCtx, _iH5File, _piVar, _pstName);
-            break;
-        }
-        case sci_boolean_sparse :
-        {
-            bReturn = export_boolean_sparse(pvCtx, _iH5File, _piVar, _pstName);
-            break;
-        }
-        case sci_matlab_sparse :
-        {
-            bReturn = export_matlab_sparse(pvCtx, _piVar, _pstName);
-            break;
-        }
-        case sci_ints :
-        {
-            bReturn = export_ints(pvCtx, _iH5File, _piVar, _pstName);
-            break;
-        }
-        case sci_handles :
-        {
-            bReturn = export_handles(pvCtx, _piVar, _pstName);
-            break;
-        }
-        case sci_strings :
-        {
-            bReturn = export_strings(pvCtx, _iH5File, _piVar, _pstName);
-            break;
-        }
-        case sci_u_function :
-        {
-            bReturn = export_u_function(pvCtx, _piVar, _pstName);
-            break;
-        }
-        case sci_c_function :
-        {
-            bReturn = export_c_function(pvCtx, _piVar, _pstName);
-            break;
-        }
-        case sci_lib :
-        {
-            bReturn = export_lib(pvCtx, _piVar, _pstName);
-            break;
-        }
-        case sci_list :
-        case sci_tlist :
-        case sci_mlist :
-        {
-            bReturn = export_list(pvCtx, _iH5File, _piVar, _pstName, iType);
-            break;
-        }
-        case sci_lufact_pointer :
-        {
-            bReturn = export_lufact_pointer(pvCtx, _piVar, _pstName);
-            break;
-        }
-        case 0 : //void case to "null" items in list
-        {
-            bReturn = export_void(pvCtx, _iH5File, _piVar, _pstName);
-            break;
-        }
-        default :
+        types::GenericType* pGT = pIT->getAs<types::GenericType>();
+        iDims = pGT->getDims();
+    }
+
+    if (iDims > 2)
+    {
+        bReturn = export_hypermat(pvCtx, _iH5File, _piVar, _pstName);
+    }
+    else
+    {
+        switch (iType)
         {
-            bReturn = false;
-            break;
+            case sci_matrix :
+            {
+                bReturn = export_double(pvCtx, _iH5File, _piVar, _pstName);
+                break;
+            }
+            case sci_poly :
+            {
+                bReturn = export_poly(pvCtx, _iH5File, _piVar, _pstName);
+                break;
+            }
+            case sci_boolean :
+            {
+                bReturn = export_boolean(pvCtx, _iH5File, _piVar, _pstName);
+                break;
+            }
+            case sci_sparse :
+            {
+                bReturn = export_sparse(pvCtx, _iH5File, _piVar, _pstName);
+                break;
+            }
+            case sci_boolean_sparse :
+            {
+                bReturn = export_boolean_sparse(pvCtx, _iH5File, _piVar, _pstName);
+                break;
+            }
+            case sci_matlab_sparse :
+            {
+                bReturn = export_matlab_sparse(pvCtx, _piVar, _pstName);
+                break;
+            }
+            case sci_ints :
+            {
+                bReturn = export_ints(pvCtx, _iH5File, _piVar, _pstName);
+                break;
+            }
+            case sci_handles :
+            {
+                bReturn = export_handles(pvCtx, _piVar, _pstName);
+                break;
+            }
+            case sci_strings :
+            {
+                bReturn = export_strings(pvCtx, _iH5File, _piVar, _pstName);
+                break;
+            }
+            case sci_u_function :
+            {
+                bReturn = export_u_function(pvCtx, _piVar, _pstName);
+                break;
+            }
+            case sci_c_function :
+            {
+                bReturn = export_c_function(pvCtx, _piVar, _pstName);
+                break;
+            }
+            case sci_lib :
+            {
+                bReturn = export_lib(pvCtx, _piVar, _pstName);
+                break;
+            }
+            case sci_list :
+            case sci_tlist :
+            case sci_mlist :
+            {
+                bReturn = export_list(pvCtx, _iH5File, _piVar, _pstName, iType);
+                break;
+            }
+            case sci_lufact_pointer :
+            {
+                bReturn = export_lufact_pointer(pvCtx, _piVar, _pstName);
+                break;
+            }
+            case 0 : //void case to "null" items in list
+            {
+                bReturn = export_void(pvCtx, _iH5File, _piVar, _pstName);
+                break;
+            }
+            default :
+            {
+                bReturn = false;
+                break;
+            }
         }
     }
+
     return bReturn;
 }
 
@@ -434,6 +454,84 @@ static bool export_list(int* pvCtx, int _iH5File, int *_piVar, char* _pstName, i
     return true;
 }
 
+static bool export_hypermat(int* pvCtx, int _iH5File, int *_piVar, char* _pstName)
+{
+    char* strHypermat[] = {"hm", "dims", "entries"};
+
+    int iVarType    = sci_mlist;
+    int iRet        = 0;
+    bool bReturn    = false;
+    types::GenericType* pGT = (types::GenericType*)_piVar;
+
+    //create groupe name
+    char* pstGroupName = createGroupName(_pstName);
+    iLevel++;
+
+    //open list
+    void *pvList = openList(_iH5File, pstGroupName, 3);
+
+    //export string ["hm" "dims" "entries"]
+    int piStrDims[2] = {1, 3};
+    char* pstPathName = createPathName(pstGroupName, 0);
+    iRet = writeStringMatrix(_iH5File, pstPathName, 2, piStrDims, strHypermat);
+    if (iRet)
+    {
+        return false;
+    }
+
+    iRet = addItemInList(_iH5File, pvList, 0, pstPathName);
+    FREE(pstPathName);
+    if (iRet)
+    {
+        return false;
+    }
+
+    // export size
+    int piSizeDims[2] = {1, 0};
+    piSizeDims[1] = pGT->getDims();
+    pstPathName = createPathName(pstGroupName, 1);
+    iRet = writeInteger32Matrix(_iH5File, pstPathName, 2, piSizeDims, pGT->getDimsArray());
+    if (iRet)
+    {
+        return false;
+    }
+
+    iRet = addItemInList(_iH5File, pvList, 1, pstPathName);
+    FREE(pstPathName);
+    if (iRet)
+    {
+        return false;
+    }
+
+    // export data
+    int iDims = pGT->getDims();
+    int* piDimsArray = new int[iDims];
+    memcpy(piDimsArray, pGT->getDimsArray(), iDims * sizeof(int));
+
+    pstPathName = createPathName(pstGroupName, 2);
+    // reshape to prevent infinite call of export_hypermat
+    // we have to export a colon vector
+    pGT->reshape(pGT->getSize(), 1);
+    bReturn = export_data(pvCtx, _iH5File, _piVar, pstPathName);
+    // after export reshape again to keep variable unchainged.
+    pGT->reshape(piDimsArray, iDims);
+    delete[] piDimsArray;
+
+    iRet = addItemInList(_iH5File, pvList, 2, pstPathName);
+    FREE(pstPathName);
+    if (bReturn == false || iRet)
+    {
+        return false;
+    }
+
+    //close list
+    iLevel--;
+    closeList(_iH5File, pvList, _pstName, 3, iVarType);
+    FREE(pstGroupName);
+
+    return true;
+}
+
 static bool export_double(int* pvCtx, int _iH5File, int *_piVar, char* _pstName)
 {
     int iRet            = 0;
index d13cdcd..767d4cb 100644 (file)
@@ -11,6 +11,8 @@
 */
 
 #include <hdf5.h>
+#include "context.hxx"
+
 extern "C"
 {
 #include <string.h>
@@ -41,6 +43,7 @@ static bool import_sparse(int* pvCtx, int _iDatasetId, int _iItemPos, int *_piAd
 static bool import_boolean_sparse(int* pvCtx, int _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname);
 static bool import_poly(int* pvCtx, int _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname);
 static bool import_list(int* pvCtx, int _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, char *_pstVarname);
+static bool import_hypermat(int* pvCtx, int _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, char *_pstVarname);
 static bool import_void(int* pvCtx, int _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname);
 static bool import_undefined(int* pvCtx, int _iDatasetId, int _iItemPos, int *_piAddress, char *_pstVarname);
 
@@ -232,7 +235,11 @@ static bool import_data(int* pvCtx, int _iDatasetId, int _iItemPos, int *_piAddr
         case sci_tlist:
         case sci_mlist:
         {
-            bRet = import_list(pvCtx, _iDatasetId, iVarType, _iItemPos, _piAddress, _pstVarname);
+            bRet = import_hypermat(pvCtx, _iDatasetId, iVarType, _iItemPos, _piAddress, _pstVarname);
+            if (bRet == false)
+            {
+                bRet = import_list(pvCtx, _iDatasetId, iVarType, _iItemPos, _piAddress, _pstVarname);
+            }
             break;
         }
         case sci_boolean:
@@ -1126,4 +1133,145 @@ static bool import_list(int* pvCtx, int _iDatasetId, int _iVarType, int _iItemPo
     return true;
 }
 
+static bool import_hypermat(int* pvCtx, int _iDatasetId, int _iVarType, int _iItemPos, int *_piAddress, char *_pstVarname)
+{
+    int iRet = 0;
+    int iComplex = 0;
+    int iDims = 0;
+    int iItems = 0;
+    int *piListAddr = NULL;
+    hobj_ref_t *piItemRef = NULL;
+
+    // an hypermatrix is stored in an mlist
+    if (_iVarType != sci_mlist)
+    {
+        return false;
+    }
+
+    iRet = getListDims(_iDatasetId, &iItems);
+    if (iRet)
+    {
+        return false;
+    }
+
+    if (iItems != 3)
+    {
+        // hypermatrix have 3 elements
+        return false;
+    }
+
+    iRet = getListItemReferences(_iDatasetId, &piItemRef);
+    if (iRet)
+    {
+        return false;
+    }
+
+    // get first item
+    int iItemDataset = 0;
+    iRet = getListItemDataset(_iDatasetId, piItemRef, 0, &iItemDataset);
+    if (iRet || iItemDataset == 0)
+    {
+        return false;
+    }
+
+    // get first item type
+    int iItemType = getScilabTypeFromDataSet(iItemDataset);
+    if (iItemType != sci_strings)
+    {
+        return false;
+    }
+
+    // get size of first item
+    iRet = getDatasetInfo(iItemDataset, &iComplex, &iDims, NULL);
+    if (iRet < 0 || iDims != 2)
+    {
+        return false;
+    }
+
+    int* piDims = new int[2];
+    int iSize = getDatasetInfo(iItemDataset, &iComplex, &iDims, piDims);
+    if (iSize != 3)
+    {
+        delete[] piDims;
+        return false;
+    }
+
+    delete[] piDims;
+    piDims = NULL;
+
+    // get data of first item for check the type of mlist
+    char** pstData = new char*[iSize];
+    iRet = readStringMatrix(iItemDataset, pstData);
+    if (iRet || strcmp(pstData[0], "hm") != 0)
+    {
+        delete[] pstData;
+        return false;
+    }
+
+    delete[] pstData;
+    pstData = NULL;
+
+    // get second item, the Size of hypermatrix
+    iRet = getListItemDataset(_iDatasetId, piItemRef, 1, &iItemDataset);
+    if (iRet)
+    {
+        return false;
+    }
+
+    iRet = getDatasetInfo(iItemDataset, &iComplex, &iDims, NULL);
+    if (iRet < 0 || iDims != 2)
+    {
+        return false;
+    }
+
+    piDims = new int[2];
+    iSize = getDatasetInfo(iItemDataset, &iComplex, &iDims, piDims);
+    if (piDims[0] != 1)
+    {
+        delete[] piDims;
+        return false;
+    }
+
+    int* piDimsArray = new int[piDims[1]];
+    iRet = readInteger32Matrix(iItemDataset, piDimsArray);
+    if (iRet)
+    {
+        delete[] piDims;
+        delete[] piDimsArray;
+        return false;
+    }
+
+    // get third item, the Data of hypermatrix
+    // import data like a "type" (Double, Int, ...) instead of mlist
+    iRet = getListItemDataset(_iDatasetId, piItemRef, 2, &iItemDataset);
+    bool bRet = import_data(pvCtx, iItemDataset, 0 /* unused */ , NULL, _pstVarname);
+    if (bRet == false)
+    {
+        delete[] piDims;
+        delete[] piDimsArray;
+        return false;
+    }
+
+    // reshape data with size of hypermatrix
+    wchar_t* pwcsName = to_wide_string(_pstVarname);
+    types::InternalType* pIT = symbol::Context::getInstance()->getCurrentLevel(symbol::Symbol(pwcsName));
+    FREE(pwcsName);
+
+    types::GenericType* pGT = pIT->getAs<types::GenericType>();
+    pGT->reshape(piDimsArray, piDims[1]);
+
+    delete[] piDims;
+    delete[] piDimsArray;
+
+
+    iRet = deleteListItemReferences(_iDatasetId, piItemRef);
+    if (iRet)
+    {
+        return false;
+    }
+
+    return true;
+}
+
+
 /*--------------------------------------------------------------------------*/