From 9796d0ae22439e4f941af2d8257dd2e1470d88a1 Mon Sep 17 00:00:00 2001 From: Hal Finkel <hfinkel@anl.gov> Date: Mon, 25 Sep 2017 19:20:08 -0500 Subject: [PATCH] Add support for float4 (and similar) to Python bindings --- python/example.py | 11 +++++++++-- python/genericio.py | 35 +++++++++++++++++++++------------- python/lib/gio.cxx | 46 ++++++++++++++++++++++++++++++++------------- python/lib/gio.h | 20 +++++++++++--------- 4 files changed, 75 insertions(+), 37 deletions(-) diff --git a/python/example.py b/python/example.py index d4c2d9e..fb5240a 100644 --- a/python/example.py +++ b/python/example.py @@ -38,11 +38,18 @@ # ***************************************************************************** import sys +import numpy as np import genericio as gio name = sys.argv[1] gio.gio_inspect(name) -x = gio.gio_read(name, "x") -print x +if gio.gio_has_variable(name, "x"): + x = gio.gio_read(name, "x") + y = gio.gio_read(name, "y") + z = gio.gio_read(name, "z") + print np.column_stack((x, y, z)) +else: + pos = gio.gio_read(name, "pos") + print pos diff --git a/python/genericio.py b/python/genericio.py index 7e94614..c9685e6 100644 --- a/python/genericio.py +++ b/python/genericio.py @@ -52,17 +52,20 @@ libpygio.get_elem_num.argtypes=[ct.c_char_p] libpygio.get_variable_type.restype=ct.c_int libpygio.get_variable_type.argtypes=[ct.c_char_p,ct.c_char_p] +libpygio.get_variable_field_count.restype=ct.c_int +libpygio.get_variable_field_count.argtypes=[ct.c_char_p,ct.c_char_p] + libpygio.read_gio_int32.restype=None -libpygio.read_gio_int32.argtypes=[ct.c_char_p,ct.c_char_p,ct.POINTER(ct.c_int)] +libpygio.read_gio_int32.argtypes=[ct.c_char_p,ct.c_char_p,ct.POINTER(ct.c_int),ct.c_int] libpygio.read_gio_int64.restype=None -libpygio.read_gio_int64.argtypes=[ct.c_char_p,ct.c_char_p,ct.POINTER(ct.c_int64)] +libpygio.read_gio_int64.argtypes=[ct.c_char_p,ct.c_char_p,ct.POINTER(ct.c_int64),ct.c_int] libpygio.read_gio_float.restype=None -libpygio.read_gio_float.argtypes=[ct.c_char_p,ct.c_char_p,ct.POINTER(ct.c_float)] +libpygio.read_gio_float.argtypes=[ct.c_char_p,ct.c_char_p,ct.POINTER(ct.c_float),ct.c_int] libpygio.read_gio_double.restype=None -libpygio.read_gio_double.argtypes=[ct.c_char_p,ct.c_char_p,ct.POINTER(ct.c_double)] +libpygio.read_gio_double.argtypes=[ct.c_char_p,ct.c_char_p,ct.POINTER(ct.c_double),ct.c_int] libpygio.inspect_gio.restype=None libpygio.inspect_gio.argtypes=[ct.c_char_p] @@ -70,6 +73,7 @@ libpygio.inspect_gio.argtypes=[ct.c_char_p] def gio_read(file_name,var_name): var_size = libpygio.get_elem_num(file_name) var_type = libpygio.get_variable_type(file_name,var_name) + field_count = libpygio.get_variable_field_count(file_name,var_name) if(var_type==10): print "Variable not found" return @@ -77,25 +81,30 @@ def gio_read(file_name,var_name): print "variable type not known (not int32/int64/float/double)" elif(var_type==0): #float - result = np.ndarray(var_size,dtype=np.float32) - libpygio.read_gio_float(file_name,var_name,result.ctypes.data_as(ct.POINTER(ct.c_float))) + result = np.ndarray((var_size,field_count),dtype=np.float32) + libpygio.read_gio_float(file_name,var_name,result.ctypes.data_as(ct.POINTER(ct.c_float)),field_count) return result elif(var_type==1): #double - result = np.ndarray(var_size,dtype=np.float64) - libpygio.read_gio_double(file_name,var_name,result.ctypes.data_as(ct.POINTER(ct.c_double))) + result = np.ndarray((var_size,field_count),dtype=np.float64) + libpygio.read_gio_double(file_name,var_name,result.ctypes.data_as(ct.POINTER(ct.c_double)),field_count) return result elif(var_type==2): #int32 - result = np.ndarray(var_size,dtype=np.int32) - libpygio.read_gio_int32(file_name,var_name,result.ctypes.data_as(ct.POINTER(ct.c_int32))) + result = np.ndarray((var_size,field_count),dtype=np.int32) + libpygio.read_gio_int32(file_name,var_name,result.ctypes.data_as(ct.POINTER(ct.c_int32)),field_count) return result elif(var_type==3): #int64 - result = np.ndarray(var_size,dtype=np.int64) - libpygio.read_gio_int64(file_name,var_name,result.ctypes.data_as(ct.POINTER(ct.c_int64))) + result = np.ndarray((var_size,field_count),dtype=np.int64) + libpygio.read_gio_int64(file_name,var_name,result.ctypes.data_as(ct.POINTER(ct.c_int64)),field_count) return result - + +def gio_has_variable(file_name,var_name): + var_size = libpygio.get_elem_num(file_name) + var_type = libpygio.get_variable_type(file_name,var_name) + return var_type!=10 + def gio_inspect(file_name): libpygio.inspect_gio(file_name) diff --git a/python/lib/gio.cxx b/python/lib/gio.cxx index 82cebd4..26ea8e3 100644 --- a/python/lib/gio.cxx +++ b/python/lib/gio.cxx @@ -42,17 +42,17 @@ #include "gio.h" #include <iostream> - void read_gio_float(char* file_name, char* var_name, float* data){ - read_gio<float>(file_name,var_name,data); + void read_gio_float(char* file_name, char* var_name, float* data, int field_count){ + read_gio<float>(file_name,var_name,data,field_count); } - void read_gio_double(char* file_name, char* var_name, double* data){ - read_gio<double>(file_name,var_name,data); + void read_gio_double(char* file_name, char* var_name, double* data, int field_count){ + read_gio<double>(file_name,var_name,data,field_count); } - void read_gio_int32(char* file_name, char* var_name, int* data){ - read_gio<int>(file_name,var_name,data); + void read_gio_int32(char* file_name, char* var_name, int* data, int field_count){ + read_gio<int>(file_name,var_name,data,field_count); } - void read_gio_int64(char* file_name, char* var_name, int64_t* data){ - read_gio<int64_t>(file_name,var_name,data); + void read_gio_int64(char* file_name, char* var_name, int64_t* data, int field_count){ + read_gio<int64_t>(file_name,var_name,data,field_count); } int64_t get_elem_num(char* file_name){ @@ -76,13 +76,13 @@ for(int i =0;i<num;++i){ gio::GenericIO::VariableInfo vinfo = VI[i]; if(vinfo.Name == var_name){ - if(vinfo.IsFloat && vinfo.Size == 4) + if(vinfo.IsFloat && vinfo.ElementSize == 4) return float_type; - else if(vinfo.IsFloat && vinfo.Size == 8) + else if(vinfo.IsFloat && vinfo.ElementSize == 8) return double_type; - else if(!vinfo.IsFloat && vinfo.Size == 4) + else if(!vinfo.IsFloat && vinfo.ElementSize == 4) return int32_type; - else if(!vinfo.IsFloat && vinfo.Size == 8) + else if(!vinfo.IsFloat && vinfo.ElementSize == 8) return int64_type; else return type_not_found; @@ -92,6 +92,22 @@ } + int get_variable_field_count(char* file_name,char* var_name){ + gio::GenericIO reader(file_name); + std::vector<gio::GenericIO::VariableInfo> VI; + reader.openAndReadHeader(gio::GenericIO::MismatchAllowed); + reader.getVariableInfo(VI); + + int num =VI.size(); + for(int i =0;i<num;++i){ + gio::GenericIO::VariableInfo vinfo = VI[i]; + if(vinfo.Name == var_name) { + return vinfo.Size/vinfo.ElementSize; + } + } + return 0; + } + extern "C" void inspect_gio(char* file_name){ int64_t size = get_elem_num(file_name); gio::GenericIO reader(file_name); @@ -109,7 +125,11 @@ extern "C" void inspect_gio(char* file_name){ std::cout<<"[f"; else std::cout<<"[i"; - std::cout<<" "<<vinfo.Size*8<<"] "; + int NumElements = vinfo.Size/vinfo.ElementSize; + std::cout<<" "<<vinfo.ElementSize*8; + if (NumElements > 1) + std::cout<<"x"<<NumElements; + std::cout<<"] "; std::cout<<vinfo.Name<<std::endl; } std::cout<<"\n(i=integer,f=floating point, number bits size)"<<std::endl; diff --git a/python/lib/gio.h b/python/lib/gio.h index fcfa8cf..2a150ce 100644 --- a/python/lib/gio.h +++ b/python/lib/gio.h @@ -45,7 +45,7 @@ #include <sstream> template <class T> -void read_gio(char* file_name, std::string var_name, T*& data){ +void read_gio(char* file_name, std::string var_name, T*& data, int field_count){ gio::GenericIO reader(file_name); reader.openAndReadHeader(gio::GenericIO::MismatchAllowed); int num_ranks = reader.readNRanks(); @@ -56,23 +56,24 @@ void read_gio(char* file_name, std::string var_name, T*& data){ if(max_size < rank_size[i]) max_size = rank_size[i]; } - T* rank_data = new T[max_size+reader.requestedExtraSpace()/sizeof(T)]; + T* rank_data = new T[max_size*field_count+reader.requestedExtraSpace()/sizeof(T)]; int64_t offset =0; - reader.addVariable(var_name,rank_data,true); + reader.addScalarizedVariable(var_name,rank_data,field_count, + gio::GenericIO::VarHasExtraSpace); for(int i=0;i<num_ranks;++i){ reader.readData(i,false); - std::copy(rank_data,rank_data+rank_size[i],data+offset); - offset +=rank_size[i]; + std::copy(rank_data,rank_data+rank_size[i]*field_count,data+offset); + offset +=rank_size[i]*field_count; } delete [] rank_data; reader.close(); } extern "C" int64_t get_elem_num(char* file_name); -extern "C" void read_gio_float (char* file_name, char* var_name, float* data); -extern "C" void read_gio_double(char* file_name, char* var_name, double* data); -extern "C" void read_gio_int32 (char* file_name, char* var_name, int* data); -extern "C" void read_gio_int64 (char* file_name, char* var_name, int64_t* data); +extern "C" void read_gio_float (char* file_name, char* var_name, float* data, int field_count); +extern "C" void read_gio_double(char* file_name, char* var_name, double* data, int field_count); +extern "C" void read_gio_int32 (char* file_name, char* var_name, int* data, int field_count); +extern "C" void read_gio_int64 (char* file_name, char* var_name, int64_t* data, int field_count); enum var_type{ float_type=0, double_type=1, @@ -82,4 +83,5 @@ enum var_type{ var_not_found=10 }; extern "C" var_type get_variable_type(char* file_name,char* var_name); +extern "C" int get_variable_field_count(char* file_name,char* var_name); extern "C" void inspect_gio(char* file_name); -- GitLab